commit
						95a51ce4f3
					
				|  | @ -137,7 +137,6 @@ | |||
|     "url": "https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues" | ||||
|   }, | ||||
|   "homepage": "https://gitee.com/yudaocode/yudao-ui-admin-vue3", | ||||
|   "packageManager": "pnpm@8.6.0", | ||||
|   "engines": { | ||||
|     "node": ">= 16.0.0", | ||||
|     "pnpm": ">=8.6.0" | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| import MyFormCreateDesigner from './src/MyFormCreateDesigner.vue' | ||||
| import { useFormCreateDesigner } from './src/useFormCreateDesigner' | ||||
| 
 | ||||
| export { MyFormCreateDesigner, useFormCreateDesigner } | ||||
| export { useFormCreateDesigner } | ||||
|  |  | |||
|  | @ -1,33 +0,0 @@ | |||
| <!-- TODO puhui999: 没啥问题的话准备移除 --> | ||||
| <template> | ||||
|   <FcDesigner ref="designer" height="780px" /> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { useUploadFileRule, useUploadImgRule, useUploadImgsRule } from './config' | ||||
| 
 | ||||
| defineOptions({ name: 'MyFormCreateDesigner' }) | ||||
| 
 | ||||
| const designer = ref() // 表单设计器 | ||||
| const uploadFileRule = useUploadFileRule() | ||||
| const uploadImgRule = useUploadImgRule() | ||||
| const uploadImgsRule = useUploadImgsRule() | ||||
| 
 | ||||
| onMounted(() => { | ||||
|   // 移除自带的上传组件规则 | ||||
|   designer.value?.removeMenuItem('upload') | ||||
|   const components = [uploadFileRule, uploadImgRule, uploadImgsRule] | ||||
|   components.forEach((component) => { | ||||
|     //插入组件规则 | ||||
|     designer.value?.addComponent(component) | ||||
|     //插入拖拽按钮到`main`分类下 | ||||
|     designer.value?.appendMenuItem('main', { | ||||
|       icon: component.icon, | ||||
|       name: component.name, | ||||
|       label: component.label | ||||
|     }) | ||||
|   }) | ||||
| }) | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped></style> | ||||
|  | @ -3,11 +3,13 @@ import { useUploadImgRule } from './useUploadImgRule' | |||
| import { useUploadImgsRule } from './useUploadImgsRule' | ||||
| import { useDictSelectRule } from './useDictSelectRule' | ||||
| import { useUserSelectRule } from './useUserSelectRule' | ||||
| import { useEditorRule } from './useEditorRule' | ||||
| 
 | ||||
| export { | ||||
|   useUploadFileRule, | ||||
|   useUploadImgRule, | ||||
|   useUploadImgsRule, | ||||
|   useDictSelectRule, | ||||
|   useUserSelectRule | ||||
|   useUserSelectRule, | ||||
|   useEditorRule | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,71 @@ | |||
| const selectRule = [ | ||||
|   { type: 'switch', field: 'multiple', title: '是否多选' }, | ||||
|   { | ||||
|     type: 'switch', | ||||
|     field: 'disabled', | ||||
|     title: '是否禁用' | ||||
|   }, | ||||
|   { type: 'switch', field: 'clearable', title: '是否可以清空选项' }, | ||||
|   { | ||||
|     type: 'switch', | ||||
|     field: 'collapseTags', | ||||
|     title: '多选时是否将选中值按文字的形式展示' | ||||
|   }, | ||||
|   { | ||||
|     type: 'inputNumber', | ||||
|     field: 'multipleLimit', | ||||
|     title: '多选时用户最多可以选择的项目数,为 0 则不限制', | ||||
|     props: { min: 0 } | ||||
|   }, | ||||
|   { | ||||
|     type: 'input', | ||||
|     field: 'autocomplete', | ||||
|     title: 'autocomplete 属性' | ||||
|   }, | ||||
|   { type: 'input', field: 'placeholder', title: '占位符' }, | ||||
|   { | ||||
|     type: 'switch', | ||||
|     field: 'filterable', | ||||
|     title: '是否可搜索' | ||||
|   }, | ||||
|   { type: 'switch', field: 'allowCreate', title: '是否允许用户创建新条目' }, | ||||
|   { | ||||
|     type: 'input', | ||||
|     field: 'noMatchText', | ||||
|     title: '搜索条件无匹配时显示的文字' | ||||
|   }, | ||||
|   { | ||||
|     type: 'switch', | ||||
|     field: 'remote', | ||||
|     title: '其中的选项是否从服务器远程加载' | ||||
|   }, | ||||
|   { | ||||
|     type: 'Struct', | ||||
|     field: 'remoteMethod', | ||||
|     title: '自定义远程搜索方法' | ||||
|   }, | ||||
|   { type: 'input', field: 'noDataText', title: '选项为空时显示的文字' }, | ||||
|   { | ||||
|     type: 'switch', | ||||
|     field: 'reserveKeyword', | ||||
|     title: '多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词' | ||||
|   }, | ||||
|   { | ||||
|     type: 'switch', | ||||
|     field: 'defaultFirstOption', | ||||
|     title: '在输入框按下回车,选择第一个匹配项' | ||||
|   }, | ||||
|   { | ||||
|     type: 'switch', | ||||
|     field: 'popperAppendToBody', | ||||
|     title: '是否将弹出框插入至 body 元素', | ||||
|     value: true | ||||
|   }, | ||||
|   { | ||||
|     type: 'switch', | ||||
|     field: 'automaticDropdown', | ||||
|     title: '对于不可搜索的 Select,是否在输入框获得焦点后自动弹出选项菜单' | ||||
|   } | ||||
| ] | ||||
| 
 | ||||
| export default selectRule | ||||
|  | @ -1,6 +1,7 @@ | |||
| import { generateUUID } from '@/utils' | ||||
| import * as DictDataApi from '@/api/system/dict/dict.type' | ||||
| import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' | ||||
| import selectRule from '@/components/FormCreate/src/config/selectRule' | ||||
| 
 | ||||
| export const useDictSelectRule = () => { | ||||
|   const label = '字典选择器' | ||||
|  | @ -51,73 +52,7 @@ export const useDictSelectRule = () => { | |||
|             { label: '布尔值', value: 'bool' } | ||||
|           ] | ||||
|         }, | ||||
|         { type: 'switch', field: 'multiple', title: '是否多选' }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'disabled', | ||||
|           title: '是否禁用' | ||||
|         }, | ||||
|         { type: 'switch', field: 'clearable', title: '是否可以清空选项' }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'collapseTags', | ||||
|           title: '多选时是否将选中值按文字的形式展示' | ||||
|         }, | ||||
|         { | ||||
|           type: 'inputNumber', | ||||
|           field: 'multipleLimit', | ||||
|           title: '多选时用户最多可以选择的项目数,为 0 则不限制', | ||||
|           props: { min: 0 } | ||||
|         }, | ||||
|         { | ||||
|           type: 'input', | ||||
|           field: 'autocomplete', | ||||
|           title: 'autocomplete 属性' | ||||
|         }, | ||||
|         { type: 'input', field: 'placeholder', title: '占位符' }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'filterable', | ||||
|           title: '是否可搜索' | ||||
|         }, | ||||
|         { type: 'switch', field: 'allowCreate', title: '是否允许用户创建新条目' }, | ||||
|         { | ||||
|           type: 'input', | ||||
|           field: 'noMatchText', | ||||
|           title: '搜索条件无匹配时显示的文字' | ||||
|         }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'remote', | ||||
|           title: '其中的选项是否从服务器远程加载' | ||||
|         }, | ||||
|         { | ||||
|           type: 'Struct', | ||||
|           field: 'remoteMethod', | ||||
|           title: '自定义远程搜索方法' | ||||
|         }, | ||||
|         { type: 'input', field: 'noDataText', title: '选项为空时显示的文字' }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'reserveKeyword', | ||||
|           title: '多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词' | ||||
|         }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'defaultFirstOption', | ||||
|           title: '在输入框按下回车,选择第一个匹配项' | ||||
|         }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'popperAppendToBody', | ||||
|           title: '是否将弹出框插入至 body 元素', | ||||
|           value: true | ||||
|         }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'automaticDropdown', | ||||
|           title: '对于不可搜索的 Select,是否在输入框获得焦点后自动弹出选项菜单' | ||||
|         } | ||||
|         ...selectRule | ||||
|       ]) | ||||
|     } | ||||
|   } | ||||
|  |  | |||
|  | @ -0,0 +1,32 @@ | |||
| import { generateUUID } from '@/utils' | ||||
| import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' | ||||
| 
 | ||||
| export const useEditorRule = () => { | ||||
|   const label = '富文本' | ||||
|   const name = 'Editor' | ||||
|   return { | ||||
|     icon: 'icon-editor', | ||||
|     label, | ||||
|     name, | ||||
|     rule() { | ||||
|       return { | ||||
|         type: name, | ||||
|         field: generateUUID(), | ||||
|         title: label, | ||||
|         info: '', | ||||
|         $required: false | ||||
|       } | ||||
|     }, | ||||
|     props(_, { t }) { | ||||
|       return localeProps(t, name + '.props', [ | ||||
|         makeRequiredRule(), | ||||
|         { | ||||
|           type: 'input', | ||||
|           field: 'height', | ||||
|           title: '高度' | ||||
|         }, | ||||
|         { type: 'switch', field: 'readonly', title: '是否只读' } | ||||
|       ]) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -1,5 +1,6 @@ | |||
| import { generateUUID } from '@/utils' | ||||
| import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils' | ||||
| import selectRule from '@/components/FormCreate/src/config/selectRule' | ||||
| 
 | ||||
| export const useUserSelectRule = () => { | ||||
|   const label = '用户选择器' | ||||
|  | @ -18,76 +19,7 @@ export const useUserSelectRule = () => { | |||
|       } | ||||
|     }, | ||||
|     props(_, { t }) { | ||||
|       return localeProps(t, name + '.props', [ | ||||
|         makeRequiredRule(), | ||||
|         { type: 'switch', field: 'multiple', title: '是否多选' }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'disabled', | ||||
|           title: '是否禁用' | ||||
|         }, | ||||
|         { type: 'switch', field: 'clearable', title: '是否可以清空选项' }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'collapseTags', | ||||
|           title: '多选时是否将选中值按文字的形式展示' | ||||
|         }, | ||||
|         { | ||||
|           type: 'inputNumber', | ||||
|           field: 'multipleLimit', | ||||
|           title: '多选时用户最多可以选择的项目数,为 0 则不限制', | ||||
|           props: { min: 0 } | ||||
|         }, | ||||
|         { | ||||
|           type: 'input', | ||||
|           field: 'autocomplete', | ||||
|           title: 'autocomplete 属性' | ||||
|         }, | ||||
|         { type: 'input', field: 'placeholder', title: '占位符' }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'filterable', | ||||
|           title: '是否可搜索' | ||||
|         }, | ||||
|         { type: 'switch', field: 'allowCreate', title: '是否允许用户创建新条目' }, | ||||
|         { | ||||
|           type: 'input', | ||||
|           field: 'noMatchText', | ||||
|           title: '搜索条件无匹配时显示的文字' | ||||
|         }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'remote', | ||||
|           title: '其中的选项是否从服务器远程加载' | ||||
|         }, | ||||
|         { | ||||
|           type: 'Struct', | ||||
|           field: 'remoteMethod', | ||||
|           title: '自定义远程搜索方法' | ||||
|         }, | ||||
|         { type: 'input', field: 'noDataText', title: '选项为空时显示的文字' }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'reserveKeyword', | ||||
|           title: '多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词' | ||||
|         }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'defaultFirstOption', | ||||
|           title: '在输入框按下回车,选择第一个匹配项' | ||||
|         }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'popperAppendToBody', | ||||
|           title: '是否将弹出框插入至 body 元素', | ||||
|           value: true | ||||
|         }, | ||||
|         { | ||||
|           type: 'switch', | ||||
|           field: 'automaticDropdown', | ||||
|           title: '对于不可搜索的 Select,是否在输入框获得焦点后自动弹出选项菜单' | ||||
|         } | ||||
|       ]) | ||||
|       return localeProps(t, name + '.props', [makeRequiredRule(), ...selectRule]) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import { | ||||
|   useDictSelectRule, | ||||
|   useEditorRule, | ||||
|   useUploadFileRule, | ||||
|   useUploadImgRule, | ||||
|   useUploadImgsRule, | ||||
|  | @ -13,8 +14,12 @@ import { Ref } from 'vue' | |||
|  * - 文件上传 | ||||
|  * - 单图上传 | ||||
|  * - 多图上传 | ||||
|  * - 字典选择器 | ||||
|  * - 系统用户选择器 | ||||
|  * - 富文本 | ||||
|  */ | ||||
| export const useFormCreateDesigner = (designer: Ref) => { | ||||
|   const editorRule = useEditorRule() | ||||
|   const uploadFileRule = useUploadFileRule() | ||||
|   const uploadImgRule = useUploadImgRule() | ||||
|   const uploadImgsRule = useUploadImgsRule() | ||||
|  | @ -24,7 +29,10 @@ export const useFormCreateDesigner = (designer: Ref) => { | |||
|   onMounted(() => { | ||||
|     // 移除自带的上传组件规则,使用 uploadFileRule、uploadImgRule、uploadImgsRule 替代
 | ||||
|     designer.value?.removeMenuItem('upload') | ||||
|     // 移除自带的富文本组件规则,使用 editorRule 替代
 | ||||
|     designer.value?.removeMenuItem('fc-editor') | ||||
|     const components = [ | ||||
|       editorRule, | ||||
|       uploadFileRule, | ||||
|       uploadImgRule, | ||||
|       uploadImgsRule, | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ import install from '@form-create/element-ui/auto-import' | |||
| import { UploadFile, UploadImg, UploadImgs } from '@/components/UploadFile' | ||||
| import { DictSelect } from '@/components/DictSelect' | ||||
| import UserSelect from '@/views/system/user/components/UserSelect.vue' | ||||
| import { Editor } from '@/components/Editor' | ||||
| 
 | ||||
| const components = [ | ||||
|   ElAside, | ||||
|  | @ -39,7 +40,8 @@ const components = [ | |||
|   UploadImgs, | ||||
|   UploadFile, | ||||
|   DictSelect, | ||||
|   UserSelect | ||||
|   UserSelect, | ||||
|   Editor | ||||
| ] | ||||
| 
 | ||||
| // 参考 http://www.form-create.com/v3/element-ui/auto-import.html 文档
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import { toNumber } from 'lodash-es' | ||||
| import {toNumber} from 'lodash-es' | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  | @ -418,3 +418,20 @@ export const erpCalculatePercentage = (value: number, total: number) => { | |||
|   if (total === 0) return 0 | ||||
|   return ((value / total) * 100).toFixed(2) | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * 适配 echarts map 的地名 | ||||
|  * | ||||
|  * @param areaName 地区名称 | ||||
|  */ | ||||
| export const areaReplace = (areaName: string) => { | ||||
|   if (!areaName) { | ||||
|     return areaName | ||||
|   } | ||||
|   return areaName | ||||
|     .replace('维吾尔自治区', '') | ||||
|     .replace('壮族自治区', '') | ||||
|     .replace('回族自治区', '') | ||||
|     .replace('自治区', '') | ||||
|     .replace('省', '') | ||||
| } | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ import { | |||
|   CrmStatisticCustomerAreaRespVO, | ||||
|   StatisticsPortraitApi | ||||
| } from '@/api/crm/statistics/portrait' | ||||
| import { areaReplace } from '@/utils' | ||||
| 
 | ||||
| defineOptions({ name: 'PortraitCustomerArea' }) | ||||
| const props = defineProps<{ queryParams: any }>() // 搜索参数 | ||||
|  | @ -106,12 +107,7 @@ const loadData = async () => { | |||
|   areaStatisticsList.value = areaList.map((item: CrmStatisticCustomerAreaRespVO) => { | ||||
|     return { | ||||
|       ...item, | ||||
|       areaName: item.areaName // TODO @puhui999:这里最好注释下原因哈, 🤣 我从 mall copy 过来的;这块看着是适合 ercharts 的地名,要不抽个小的 js 方法,然后把涉及到的地方都替换掉。 | ||||
|       // .replace('维吾尔自治区', '') | ||||
|       // .replace('壮族自治区', '') | ||||
|       // .replace('回族自治区', '') | ||||
|       // .replace('自治区', '') | ||||
|       // .replace('省', '') | ||||
|       areaName: areaReplace(item.areaName) | ||||
|     } | ||||
|   }) | ||||
|   buildLeftMap() | ||||
|  |  | |||
|  | @ -3,44 +3,44 @@ | |||
| 
 | ||||
|   <div class="flex flex-col"> | ||||
|     <el-row :gutter="16" class="summary"> | ||||
|       <el-col :sm="6" :xs="12" v-loading="loading"> | ||||
|       <el-col v-loading="loading" :sm="6" :xs="12"> | ||||
|         <SummaryCard | ||||
|           title="累计会员数" | ||||
|           icon="fa-solid:users" | ||||
|           icon-color="bg-blue-100" | ||||
|           icon-bg-color="text-blue-500" | ||||
|           :value="summary?.userCount || 0" | ||||
|           icon="fa-solid:users" | ||||
|           icon-bg-color="text-blue-500" | ||||
|           icon-color="bg-blue-100" | ||||
|           title="累计会员数" | ||||
|         /> | ||||
|       </el-col> | ||||
|       <el-col :sm="6" :xs="12" v-loading="loading"> | ||||
|       <el-col v-loading="loading" :sm="6" :xs="12"> | ||||
|         <SummaryCard | ||||
|           title="累计充值人数" | ||||
|           icon="fa-solid:user" | ||||
|           icon-color="bg-purple-100" | ||||
|           icon-bg-color="text-purple-500" | ||||
|           :value="summary?.rechargeUserCount || 0" | ||||
|           icon="fa-solid:user" | ||||
|           icon-bg-color="text-purple-500" | ||||
|           icon-color="bg-purple-100" | ||||
|           title="累计充值人数" | ||||
|         /> | ||||
|       </el-col> | ||||
|       <el-col :sm="6" :xs="12" v-loading="loading"> | ||||
|       <el-col v-loading="loading" :sm="6" :xs="12"> | ||||
|         <SummaryCard | ||||
|           title="累计充值金额" | ||||
|           icon="fa-solid:money-check-alt" | ||||
|           icon-color="bg-yellow-100" | ||||
|           icon-bg-color="text-yellow-500" | ||||
|           prefix="¥" | ||||
|           :decimals="2" | ||||
|           :value="fenToYuan(summary?.rechargePrice || 0)" | ||||
|           icon="fa-solid:money-check-alt" | ||||
|           icon-bg-color="text-yellow-500" | ||||
|           icon-color="bg-yellow-100" | ||||
|           prefix="¥" | ||||
|           title="累计充值金额" | ||||
|         /> | ||||
|       </el-col> | ||||
|       <el-col :sm="6" :xs="12" v-loading="loading"> | ||||
|       <el-col v-loading="loading" :sm="6" :xs="12"> | ||||
|         <SummaryCard | ||||
|           title="累计消费金额" | ||||
|           icon="fa-solid:yen-sign" | ||||
|           icon-color="bg-green-100" | ||||
|           icon-bg-color="text-green-500" | ||||
|           prefix="¥" | ||||
|           :decimals="2" | ||||
|           :value="fenToYuan(summary?.expensePrice || 0)" | ||||
|           icon="fa-solid:yen-sign" | ||||
|           icon-bg-color="text-green-500" | ||||
|           icon-color="bg-green-100" | ||||
|           prefix="¥" | ||||
|           title="累计消费金额" | ||||
|         /> | ||||
|       </el-col> | ||||
|     </el-row> | ||||
|  | @ -67,42 +67,42 @@ | |||
|             <el-col :span="14"> | ||||
|               <el-table :data="areaStatisticsList" :height="300"> | ||||
|                 <el-table-column | ||||
|                   label="省份" | ||||
|                   prop="areaName" | ||||
|                   :sort-method="(obj1, obj2) => obj1.areaName.localeCompare(obj2.areaName, 'zh-CN')" | ||||
|                   align="center" | ||||
|                   label="省份" | ||||
|                   min-width="80" | ||||
|                   prop="areaName" | ||||
|                   show-overflow-tooltip | ||||
|                   sortable | ||||
|                   :sort-method="(obj1, obj2) => obj1.areaName.localeCompare(obj2.areaName, 'zh-CN')" | ||||
|                 /> | ||||
|                 <el-table-column | ||||
|                   align="center" | ||||
|                   label="会员数量" | ||||
|                   prop="userCount" | ||||
|                   align="center" | ||||
|                   min-width="105" | ||||
|                   prop="userCount" | ||||
|                   sortable | ||||
|                 /> | ||||
|                 <el-table-column | ||||
|                   align="center" | ||||
|                   label="订单创建数量" | ||||
|                   min-width="135" | ||||
|                   prop="orderCreateUserCount" | ||||
|                   align="center" | ||||
|                   min-width="135" | ||||
|                   sortable | ||||
|                 /> | ||||
|                 <el-table-column | ||||
|                   align="center" | ||||
|                   label="订单支付数量" | ||||
|                   prop="orderPayUserCount" | ||||
|                   align="center" | ||||
|                   min-width="135" | ||||
|                   prop="orderPayUserCount" | ||||
|                   sortable | ||||
|                 /> | ||||
|                 <el-table-column | ||||
|                   label="订单支付金额" | ||||
|                   prop="orderPayPrice" | ||||
|                   align="center" | ||||
|                   min-width="135" | ||||
|                   sortable | ||||
|                   :formatter="fenToYuanFormat" | ||||
|                   align="center" | ||||
|                   label="订单支付金额" | ||||
|                   min-width="135" | ||||
|                   prop="orderPayPrice" | ||||
|                   sortable | ||||
|                 /> | ||||
|               </el-table> | ||||
|             </el-col> | ||||
|  | @ -110,7 +110,7 @@ | |||
|         </el-card> | ||||
|       </el-col> | ||||
|       <el-col :md="6" :sm="24"> | ||||
|         <el-card shadow="never" v-loading="loading"> | ||||
|         <el-card v-loading="loading" shadow="never"> | ||||
|           <template #header> | ||||
|             <CardTitle title="会员性别比例" /> | ||||
|           </template> | ||||
|  | @ -122,16 +122,16 @@ | |||
| </template> | ||||
| <script lang="ts" setup> | ||||
| import * as MemberStatisticsApi from '@/api/mall/statistics/member' | ||||
| import SummaryCard from '@/components/SummaryCard/index.vue' | ||||
| import { EChartsOption } from 'echarts' | ||||
| import china from '@/assets/map/json/china.json' | ||||
| import { fenToYuan } from '@/utils' | ||||
| import { | ||||
|   MemberAreaStatisticsRespVO, | ||||
|   MemberSexStatisticsRespVO, | ||||
|   MemberSummaryRespVO, | ||||
|   MemberTerminalStatisticsRespVO | ||||
| } from '@/api/mall/statistics/member' | ||||
| import SummaryCard from '@/components/SummaryCard/index.vue' | ||||
| import { EChartsOption } from 'echarts' | ||||
| import china from '@/assets/map/json/china.json' | ||||
| import { areaReplace, fenToYuan } from '@/utils' | ||||
| import { DICT_TYPE, DictDataType, getIntDictOptions } from '@/utils/dict' | ||||
| import echarts from '@/plugins/echarts' | ||||
| import { fenToYuanFormat } from '@/utils/formatter' | ||||
|  | @ -246,12 +246,7 @@ const getMemberAreaStatisticsList = async () => { | |||
|   areaStatisticsList.value = list.map((item: MemberAreaStatisticsRespVO) => { | ||||
|     return { | ||||
|       ...item, | ||||
|       areaName: item.areaName | ||||
|         .replace('维吾尔自治区', '') | ||||
|         .replace('壮族自治区', '') | ||||
|         .replace('回族自治区', '') | ||||
|         .replace('自治区', '') | ||||
|         .replace('省', '') | ||||
|       areaName: areaReplace(item.areaName) | ||||
|     } | ||||
|   }) | ||||
|   let min = 0 | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
|       </el-form-item> | ||||
|       <el-form-item label="订单调价"> | ||||
|         <el-input-number v-model="formData.adjustPrice" :precision="2" :step="0.1" class="w-100%" /> | ||||
|         <el-tag class="mt-10px" type="warning">订单调价。 正数,加价;负数,减价</el-tag> | ||||
|         <el-tag class="ml-10px" type="warning">订单调价。 正数,加价;负数,减价</el-tag> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="调价后"> | ||||
|         <el-input v-model="formData.newPayPrice" disabled /> | ||||
|  | @ -38,10 +38,13 @@ const formData = ref({ | |||
| }) | ||||
| watch( | ||||
|   () => formData.value.adjustPrice, | ||||
|   (data: number) => { | ||||
|     const num = formData.value.payPrice!.replace('元', '') | ||||
|     // @ts-ignore | ||||
|     formData.value.newPayPrice = (num * 1 + data).toFixed(2) + '元' | ||||
|   (adjustPrice: number | string) => { | ||||
|     const numMatch = formData.value.payPrice.match(/\d+(\.\d+)?/) | ||||
|     if (numMatch) { | ||||
|       const payPriceNum = parseFloat(numMatch[0]) | ||||
|       adjustPrice = typeof adjustPrice === 'string' ? parseFloat(adjustPrice) : adjustPrice | ||||
|       formData.value.newPayPrice = (payPriceNum + adjustPrice).toFixed(2) + '元' | ||||
|     } | ||||
|   } | ||||
| ) | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 芋道源码
						芋道源码