From 4ad30e043548a1a6106de34490b500837141984e Mon Sep 17 00:00:00 2001 From: alwayssuper <12851801+alwayssuper@user.noreply.gitee.com> Date: Tue, 22 Oct 2024 21:16:25 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=BA=86?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E5=88=97=E8=A1=A8=E5=92=8Cdict=E5=AD=97?= =?UTF-8?q?=E5=85=B8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pnpm-lock.yaml | 22 ++ src/interceptors/route.ts | 11 +- src/pages.json | 8 + src/pages/login/components/LoginForm.vue | 6 +- src/pages/task/components/CopyList.vue | 57 +++++ src/pages/task/components/DoneList.vue | 63 +++++ src/pages/task/components/MyTaskList.vue | 76 ++++++ src/pages/task/components/TodoList.vue | 80 +++++++ src/pages/task/index.vue | 282 +++++++++++++++++++++++ src/service/category/CategoryApi.ts | 16 ++ src/service/dict/DictAPI.ts | 18 ++ src/service/task/TaskApi.ts | 19 ++ src/store/dict.ts | 67 ++++++ src/store/index.ts | 7 +- src/types/uni-pages.d.ts | 1 + src/utils/dateUtil.ts | 71 ++++++ src/utils/dict.ts | 181 +++++++++++++++ src/utils/listUtil.ts | 37 +++ 18 files changed, 1014 insertions(+), 8 deletions(-) create mode 100644 src/pages/task/components/CopyList.vue create mode 100644 src/pages/task/components/DoneList.vue create mode 100644 src/pages/task/components/MyTaskList.vue create mode 100644 src/pages/task/components/TodoList.vue create mode 100644 src/pages/task/index.vue create mode 100644 src/service/category/CategoryApi.ts create mode 100644 src/service/dict/DictAPI.ts create mode 100644 src/service/task/TaskApi.ts create mode 100644 src/store/dict.ts create mode 100644 src/utils/dateUtil.ts create mode 100644 src/utils/dict.ts create mode 100644 src/utils/listUtil.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 576f4d6..582da66 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,9 +26,15 @@ importers: '@dcloudio/uni-mp-weixin': specifier: 3.0.0-alpha-4010520240507001 version: 3.0.0-alpha-4010520240507001(postcss@8.4.38)(rollup@4.18.0)(vue@3.4.21(typescript@5.5.4)) + '@iconify/json': + specifier: ^2.2.260 + version: 2.2.262 dayjs: specifier: 1.11.10 version: 1.11.10 + mockjs: + specifier: ^1.1.0 + version: 1.1.0 pinia: specifier: 2.0.36 version: 2.0.36(typescript@5.5.4)(vue@3.4.21(typescript@5.5.4)) @@ -1191,6 +1197,9 @@ packages: '@iconify-json/ic@1.2.1': resolution: {integrity: sha512-UjL/bjJP/T5EV881+hTzcfTKVo0KEUjhnMiJcLtPzNgPtU2KZZmRx8BSKKR61H4CN/5FTEbyawGyG0aEt3SwGQ==} + '@iconify/json@2.2.262': + resolution: {integrity: sha512-h7zMbLxsKohKXvf2Lpq6Xob7dxkqXxrUVR58ZvZBgCSrHcE69QJmcFG/KaAwM1eGuKToWvgPWeb1xE6zy7juqg==} + '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -4013,6 +4022,10 @@ packages: mlly@1.7.1: resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + mockjs@1.1.0: + resolution: {integrity: sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==} + hasBin: true + module-alias@2.2.3: resolution: {integrity: sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==} @@ -6897,6 +6910,11 @@ snapshots: dependencies: '@iconify/types': 2.0.0 + '@iconify/json@2.2.262': + dependencies: + '@iconify/types': 2.0.0 + pathe: 1.1.2 + '@iconify/types@2.0.0': {} '@iconify/utils@2.1.24': @@ -10452,6 +10470,10 @@ snapshots: pkg-types: 1.1.1 ufo: 1.5.3 + mockjs@1.1.0: + dependencies: + commander: 12.1.0 + module-alias@2.2.3: {} mrmime@2.0.0: {} diff --git a/src/interceptors/route.ts b/src/interceptors/route.ts index 252855b..073969d 100644 --- a/src/interceptors/route.ts +++ b/src/interceptors/route.ts @@ -22,7 +22,7 @@ } */ -import { useUserStore } from '@/store' +import { useUserStore, useDictStore } from '@/store' import { getNeedLoginPages, needLoginPages as _needLoginPages } from '@/utils' import { getAccessToken } from '@/utils/auth' @@ -70,6 +70,11 @@ const navigateToInterceptor = { // 获取用户的相关信息 const userStore = useUserStore() + // 获取字典数据并保存到本地 + const dictStore = useDictStore() + if (!dictStore.dictInfo.isSetDict) { + await dictStore.setDictMap() + } if (!userStore.userInfo.isSetUser) { // todo 显示加载状态 await userStore.setUserInfoAction() @@ -83,7 +88,7 @@ const navigateToInterceptor = { uni.navigateTo({ url: '/pages/login/index' }) return option } - }, + } } export const routeInterceptor = { @@ -91,5 +96,5 @@ export const routeInterceptor = { uni.addInterceptor('navigateTo', navigateToInterceptor) uni.addInterceptor('reLaunch', navigateToInterceptor) uni.addInterceptor('redirectTo', navigateToInterceptor) - }, + } } diff --git a/src/pages.json b/src/pages.json index ea0be42..f121aa6 100644 --- a/src/pages.json +++ b/src/pages.json @@ -65,6 +65,14 @@ "navigationBarTitleText": "工作台" } }, + { + "path": "pages/task/index", + "type": "home", + "layout": "tabbar", + "style": { + "navigationBarTitleText": "审批" + } + }, { "path": "pages/colab/index", "type": "page", diff --git a/src/pages/login/components/LoginForm.vue b/src/pages/login/components/LoginForm.vue index 6ac0595..a55617d 100644 --- a/src/pages/login/components/LoginForm.vue +++ b/src/pages/login/components/LoginForm.vue @@ -60,7 +60,7 @@ import { ref, reactive } from 'vue' import { useToast } from 'wot-design-uni' import { login, getTenantIdByName } from '@/service/login/LoginAPI' - import { useUserStore } from '@/store' + import { useUserStore, useDictStore } from '@/store' import * as authUtil from '@/utils/auth' const props = defineProps({ @@ -124,7 +124,9 @@ // 获取用户信息,保存到 store const userStore = useUserStore() await userStore.setUserInfoAction() - + // todo 后续审批在黑名单拦截器内可删除下列两行代码 黑名单拦截器未配置情况下测试时 获取字典信息,保存到 store + const dictStore = useDictStore() + await dictStore.setDictMap() // 暂时先跳到首页 uni.switchTab({ url: '/pages/work/index' diff --git a/src/pages/task/components/CopyList.vue b/src/pages/task/components/CopyList.vue new file mode 100644 index 0000000..f800801 --- /dev/null +++ b/src/pages/task/components/CopyList.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/src/pages/task/components/DoneList.vue b/src/pages/task/components/DoneList.vue new file mode 100644 index 0000000..df3190f --- /dev/null +++ b/src/pages/task/components/DoneList.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/src/pages/task/components/MyTaskList.vue b/src/pages/task/components/MyTaskList.vue new file mode 100644 index 0000000..8e99492 --- /dev/null +++ b/src/pages/task/components/MyTaskList.vue @@ -0,0 +1,76 @@ + + + + diff --git a/src/pages/task/components/TodoList.vue b/src/pages/task/components/TodoList.vue new file mode 100644 index 0000000..68cc25c --- /dev/null +++ b/src/pages/task/components/TodoList.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/src/pages/task/index.vue b/src/pages/task/index.vue new file mode 100644 index 0000000..12987b9 --- /dev/null +++ b/src/pages/task/index.vue @@ -0,0 +1,282 @@ + + +{ + layout: 'tabbar', + style: { + navigationBarTitleText: '审批' + } +} + + + + + + diff --git a/src/service/category/CategoryApi.ts b/src/service/category/CategoryApi.ts new file mode 100644 index 0000000..2fff5dc --- /dev/null +++ b/src/service/category/CategoryApi.ts @@ -0,0 +1,16 @@ +import { http, httpGet, httpPost } from '@/utils/http' + +// BPM 流程分类 VO +export interface CategoryVO { + id: number // 分类编号 + name: string // 分类名 + code: string // 分类标志 + status: number // 分类状态 + sort: number // 分类排序 +} + +// 查询流程分类列表 +// todo 测试使用 拒绝anysripe +export const getCategorySimpleList = (): Promise => { + return httpGet('/bpm/category/simple-list') +} diff --git a/src/service/dict/DictAPI.ts b/src/service/dict/DictAPI.ts new file mode 100644 index 0000000..882f73e --- /dev/null +++ b/src/service/dict/DictAPI.ts @@ -0,0 +1,18 @@ +import { http, httpGet, httpPost } from '@/utils/http' + +export type DictDataVO = { + id: number | undefined + sort: number | undefined + label: string + value: string + dictType: string + status: number + colorType: string + cssClass: string + remark: string + createTime: Date +} + +export const getSimpleDictDataList = (): Promise => { + return httpGet('/system/dict-data/simple-list') +} diff --git a/src/service/task/TaskApi.ts b/src/service/task/TaskApi.ts new file mode 100644 index 0000000..d73b608 --- /dev/null +++ b/src/service/task/TaskApi.ts @@ -0,0 +1,19 @@ +import { http, httpGet, httpPost } from '@/utils/http' + +// todo 测试使用 拒绝anysripe +// 查询待办流程分页列表 +export const getTaskTodoPage = (params: any): Promise => { + return httpGet('/bpm/task/todo-page', params) +} +// 查询已办流程分页列表 +export const getTaskDonePage = (params: any): Promise => { + return httpGet('/bpm/task/done-page', params) +} +// 查询抄送我的流程分页列表 +export const getProcessInstanceCopyPage = (params: any): Promise => { + return httpGet('/bpm/process-instance/copy/page', params) +} +// 查询我的流程分页列表 +export const getProcessInstanceMyPage = (params: any): Promise => { + return httpGet('/bpm/process-instance/my-page', params) +} diff --git a/src/store/dict.ts b/src/store/dict.ts new file mode 100644 index 0000000..3f775c7 --- /dev/null +++ b/src/store/dict.ts @@ -0,0 +1,67 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { getSimpleDictDataList, DictDataVO } from '@/service/dict/DictAPI' + +const initState = { + dictMap: new Map(), + isSetDict: false +} + +export const useDictStore = defineStore( + 'dict', + () => { + // dict + + const dictInfo = ref({ ...initState }) + + // actions methods + const setDictMap = async () => { + // 获取字典 + const data = await getSimpleDictDataList() + console.log(data) + // 设置数据 + const dictDataMap = new Map() + data.forEach((dictData: DictDataVO) => { + // 获得 dictType 层级 + const enumValueObj = dictDataMap[dictData.dictType] + if (!enumValueObj) { + dictDataMap[dictData.dictType] = [] + } + // 处理 dictValue 层级 + dictDataMap[dictData.dictType].push({ + value: dictData.value, + label: dictData.label, + colorType: dictData.colorType, + cssClass: dictData.cssClass + }) + }) + dictInfo.value.dictMap = dictDataMap + dictInfo.value.isSetDict = true + console.log(dictInfo.value.dictMap) + } + + const getDictByType = (type: string) => { + if (!dictInfo.value.isSetDict) { + setDictMap() + } + return dictInfo.value.dictMap[type] + } + + const resetDict = async () => { + dictInfo.value = initState + await setDictMap() + } + + // 暴露到外面的方法 + return { + dictInfo, + setDictMap, + getDictByType, + resetDict + } + }, + { + // 持久化 + persist: true + } +) diff --git a/src/store/index.ts b/src/store/index.ts index 74b1b2f..7f0dc42 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -6,12 +6,13 @@ store.use( createPersistedState({ storage: { getItem: uni.getStorageSync, - setItem: uni.setStorageSync, - }, - }), + setItem: uni.setStorageSync + } + }) ) export default store // 模块统一导出 export * from './user' +export * from './dict' diff --git a/src/types/uni-pages.d.ts b/src/types/uni-pages.d.ts index fb48cbd..29ebf90 100644 --- a/src/types/uni-pages.d.ts +++ b/src/types/uni-pages.d.ts @@ -5,6 +5,7 @@ interface NavigateToOptions { url: "/pages/work/index" | + "/pages/task/index" | "/pages/colab/index" | "/pages/contacts/index" | "/pages/login/forget" | diff --git a/src/utils/dateUtil.ts b/src/utils/dateUtil.ts new file mode 100644 index 0000000..1912053 --- /dev/null +++ b/src/utils/dateUtil.ts @@ -0,0 +1,71 @@ +// 获取日期和当前日期的相差的时间 +export const getTimeDifference = (inputTimestamp: number): string => { + // 获取当前日期和时间 + const currentDate = new Date() + // 将输入的时间戳转换为 Date 对象 + const inputDate = new Date(inputTimestamp) + + // 计算两个日期之间的毫秒数差值 + const differenceInMilliseconds = Math.abs( + currentDate.getTime() - inputDate.getTime() + ) + + // 将毫秒数转换为秒数 + const differenceInSeconds = differenceInMilliseconds / 1000 + + // 计算天数、小时数和分钟数 + const days = Math.floor(differenceInSeconds / (60 * 60 * 24)) + const hours = Math.floor((differenceInSeconds % (60 * 60 * 24)) / (60 * 60)) + const minutes = Math.floor((differenceInSeconds % (60 * 60)) / 60) + + // 根据相差的时间长度返回不同的结果 + if (days > 0) { + return `${days}天` + } else if (hours > 0) { + return `${hours}小时` + } else { + return `${minutes}分钟` + } +} +// 将时间戳格式化为“MM-DD HH:MM” +export const formatTimestamp = (timestamp: number): string => { + // 创建一个新的Date对象,使用传入的时间戳(毫秒) + + const date = new Date(timestamp) // 假设时间戳是秒,如果是毫秒则不需要乘以1000 + + // 获取月、日、小时、分钟 + + const month = String(date.getMonth() + 1).padStart(2, '0') // 月份是从0开始的,所以需要加1 + + const day = String(date.getDate()).padStart(2, '0') + + const hours = String(date.getHours()).padStart(2, '0') + + const minutes = String(date.getMinutes()).padStart(2, '0') + + // 按照要求的格式组合字符串 + + return `${month}-${day} ${hours}:${minutes}` +} +// 将时间戳格式化为“YY-MM-DD HH:MM” +export const formatTimestampToymd = (timestamp: number): string => { + // 创建一个新的 Date 对象 + const date = new Date(timestamp) + + // 获取各个部分的时间 + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') // 月份从 0 开始,需要加 1,并且补 0 + const day = String(date.getDate()).padStart(2, '0') // 数字补 0 + const hours = String(date.getHours()).padStart(2, '0') + const minutes = String(date.getMinutes()).padStart(2, '0') + const seconds = String(date.getSeconds()).padStart(2, '0') + console.log(year) + + // 组合成指定格式的字符串 + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` +} +// 将时间戳列表格式化为“YY-MM-DD HH:MM”的列表 +export const formatTimestamps = (timestamps: number[]): string[] => { + // 使用 map 方法遍历时间戳列表,并调用 formatTimestamp 函数来格式化每个时间戳 + return timestamps.map((timestamp) => formatTimestampToymd(timestamp)) +} diff --git a/src/utils/dict.ts b/src/utils/dict.ts new file mode 100644 index 0000000..6519ce6 --- /dev/null +++ b/src/utils/dict.ts @@ -0,0 +1,181 @@ +/** + * 数据字典工具类 + */ +import { useDictStore } from '@/store' + +const dictStore = useDictStore() +/** + * 获取 dictType 对应的数据字典数组 + * + * @param dictType 数据类型 + * @returns {*|Array} 数据字典数组 + */ +export interface DictDataType { + dictType: string + label: string + value: string | number | boolean + colorType: '' + cssClass: string +} + +export interface NumberDictDataType extends DictDataType { + value: number +} + +export interface StringDictDataType extends DictDataType { + value: string +} + +export const getDictOptions = (dictType: string) => { + return dictStore.getDictByType(dictType) || [] +} + +export const getIntDictOptions = (dictType: string): NumberDictDataType[] => { + // 获得通用的 DictDataType 列表 + const dictOptions: DictDataType[] = getDictOptions(dictType) + // 转换成 number 类型的 NumberDictDataType 类型 + // why 需要特殊转换:避免 IDEA 在 v-for="dict in getIntDictOptions(...)" 时,el-option 的 key 会告警 + const dictOption: NumberDictDataType[] = [] + dictOptions.forEach((dict: DictDataType) => { + dictOption.push({ + ...dict, + value: parseInt(dict.value + '') + }) + }) + return dictOption +} + +export enum DICT_TYPE { + USER_TYPE = 'user_type', + COMMON_STATUS = 'common_status', + TERMINAL = 'terminal', // 终端 + DATE_INTERVAL = 'date_interval', // 数据间隔 + + // ========== SYSTEM 模块 ========== + SYSTEM_USER_SEX = 'system_user_sex', + SYSTEM_MENU_TYPE = 'system_menu_type', + SYSTEM_ROLE_TYPE = 'system_role_type', + SYSTEM_DATA_SCOPE = 'system_data_scope', + SYSTEM_NOTICE_TYPE = 'system_notice_type', + SYSTEM_LOGIN_TYPE = 'system_login_type', + SYSTEM_LOGIN_RESULT = 'system_login_result', + SYSTEM_SMS_CHANNEL_CODE = 'system_sms_channel_code', + SYSTEM_SMS_TEMPLATE_TYPE = 'system_sms_template_type', + SYSTEM_SMS_SEND_STATUS = 'system_sms_send_status', + SYSTEM_SMS_RECEIVE_STATUS = 'system_sms_receive_status', + SYSTEM_OAUTH2_GRANT_TYPE = 'system_oauth2_grant_type', + SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status', + SYSTEM_NOTIFY_TEMPLATE_TYPE = 'system_notify_template_type', + SYSTEM_SOCIAL_TYPE = 'system_social_type', + + // ========== INFRA 模块 ========== + INFRA_BOOLEAN_STRING = 'infra_boolean_string', + INFRA_JOB_STATUS = 'infra_job_status', + INFRA_JOB_LOG_STATUS = 'infra_job_log_status', + INFRA_API_ERROR_LOG_PROCESS_STATUS = 'infra_api_error_log_process_status', + INFRA_CONFIG_TYPE = 'infra_config_type', + INFRA_CODEGEN_TEMPLATE_TYPE = 'infra_codegen_template_type', + INFRA_CODEGEN_FRONT_TYPE = 'infra_codegen_front_type', + INFRA_CODEGEN_SCENE = 'infra_codegen_scene', + INFRA_FILE_STORAGE = 'infra_file_storage', + INFRA_OPERATE_TYPE = 'infra_operate_type', + + // ========== BPM 模块 ========== + BPM_MODEL_TYPE = 'bpm_model_type', + BPM_MODEL_FORM_TYPE = 'bpm_model_form_type', + BPM_TASK_CANDIDATE_STRATEGY = 'bpm_task_candidate_strategy', + BPM_PROCESS_INSTANCE_STATUS = 'bpm_process_instance_status', + BPM_TASK_STATUS = 'bpm_task_status', + BPM_OA_LEAVE_TYPE = 'bpm_oa_leave_type', + BPM_PROCESS_LISTENER_TYPE = 'bpm_process_listener_type', + BPM_PROCESS_LISTENER_VALUE_TYPE = 'bpm_process_listener_value_type', + + // ========== PAY 模块 ========== + PAY_CHANNEL_CODE = 'pay_channel_code', // 支付渠道编码类型 + PAY_ORDER_STATUS = 'pay_order_status', // 商户支付订单状态 + PAY_REFUND_STATUS = 'pay_refund_status', // 退款订单状态 + PAY_NOTIFY_STATUS = 'pay_notify_status', // 商户支付回调状态 + PAY_NOTIFY_TYPE = 'pay_notify_type', // 商户支付回调状态 + PAY_TRANSFER_STATUS = 'pay_transfer_status', // 转账订单状态 + PAY_TRANSFER_TYPE = 'pay_transfer_type', // 转账订单状态 + + // ========== MP 模块 ========== + MP_AUTO_REPLY_REQUEST_MATCH = 'mp_auto_reply_request_match', // 自动回复请求匹配类型 + MP_MESSAGE_TYPE = 'mp_message_type', // 消息类型 + + // ========== Member 会员模块 ========== + MEMBER_POINT_BIZ_TYPE = 'member_point_biz_type', // 积分的业务类型 + MEMBER_EXPERIENCE_BIZ_TYPE = 'member_experience_biz_type', // 会员经验业务类型 + + // ========== MALL - 商品模块 ========== + PRODUCT_SPU_STATUS = 'product_spu_status', // 商品状态 + + // ========== MALL - 交易模块 ========== + EXPRESS_CHARGE_MODE = 'trade_delivery_express_charge_mode', // 快递的计费方式 + TRADE_AFTER_SALE_STATUS = 'trade_after_sale_status', // 售后 - 状态 + TRADE_AFTER_SALE_WAY = 'trade_after_sale_way', // 售后 - 方式 + TRADE_AFTER_SALE_TYPE = 'trade_after_sale_type', // 售后 - 类型 + TRADE_ORDER_TYPE = 'trade_order_type', // 订单 - 类型 + TRADE_ORDER_STATUS = 'trade_order_status', // 订单 - 状态 + TRADE_ORDER_ITEM_AFTER_SALE_STATUS = 'trade_order_item_after_sale_status', // 订单项 - 售后状态 + TRADE_DELIVERY_TYPE = 'trade_delivery_type', // 配送方式 + BROKERAGE_ENABLED_CONDITION = 'brokerage_enabled_condition', // 分佣模式 + BROKERAGE_BIND_MODE = 'brokerage_bind_mode', // 分销关系绑定模式 + BROKERAGE_BANK_NAME = 'brokerage_bank_name', // 佣金提现银行 + BROKERAGE_WITHDRAW_TYPE = 'brokerage_withdraw_type', // 佣金提现类型 + BROKERAGE_RECORD_BIZ_TYPE = 'brokerage_record_biz_type', // 佣金业务类型 + BROKERAGE_RECORD_STATUS = 'brokerage_record_status', // 佣金状态 + BROKERAGE_WITHDRAW_STATUS = 'brokerage_withdraw_status', // 佣金提现状态 + + // ========== MALL - 营销模块 ========== + PROMOTION_DISCOUNT_TYPE = 'promotion_discount_type', // 优惠类型 + PROMOTION_PRODUCT_SCOPE = 'promotion_product_scope', // 营销的商品范围 + PROMOTION_COUPON_TEMPLATE_VALIDITY_TYPE = 'promotion_coupon_template_validity_type', // 优惠劵模板的有限期类型 + PROMOTION_COUPON_STATUS = 'promotion_coupon_status', // 优惠劵的状态 + PROMOTION_COUPON_TAKE_TYPE = 'promotion_coupon_take_type', // 优惠劵的领取方式 + PROMOTION_CONDITION_TYPE = 'promotion_condition_type', // 营销的条件类型枚举 + PROMOTION_BARGAIN_RECORD_STATUS = 'promotion_bargain_record_status', // 砍价记录的状态 + PROMOTION_COMBINATION_RECORD_STATUS = 'promotion_combination_record_status', // 拼团记录的状态 + PROMOTION_BANNER_POSITION = 'promotion_banner_position', // banner 定位 + + // ========== CRM - 客户管理模块 ========== + CRM_AUDIT_STATUS = 'crm_audit_status', // CRM 审批状态 + CRM_BIZ_TYPE = 'crm_biz_type', // CRM 业务类型 + CRM_BUSINESS_END_STATUS_TYPE = 'crm_business_end_status_type', // CRM 商机结束状态类型 + CRM_RECEIVABLE_RETURN_TYPE = 'crm_receivable_return_type', // CRM 回款的还款方式 + CRM_CUSTOMER_INDUSTRY = 'crm_customer_industry', // CRM 客户所属行业 + CRM_CUSTOMER_LEVEL = 'crm_customer_level', // CRM 客户级别 + CRM_CUSTOMER_SOURCE = 'crm_customer_source', // CRM 客户来源 + CRM_PRODUCT_STATUS = 'crm_product_status', // CRM 商品状态 + CRM_PERMISSION_LEVEL = 'crm_permission_level', // CRM 数据权限的级别 + CRM_PRODUCT_UNIT = 'crm_product_unit', // CRM 产品单位 + CRM_FOLLOW_UP_TYPE = 'crm_follow_up_type', // CRM 跟进方式 + + // ========== ERP - 企业资源计划模块 ========== + ERP_AUDIT_STATUS = 'erp_audit_status', // ERP 审批状态 + ERP_STOCK_RECORD_BIZ_TYPE = 'erp_stock_record_biz_type', // 库存明细的业务类型 + + // ========== AI - 人工智能模块 ========== + AI_PLATFORM = 'ai_platform', // AI 平台 + AI_IMAGE_STATUS = 'ai_image_status', // AI 图片状态 + AI_MUSIC_STATUS = 'ai_music_status', // AI 音乐状态 + AI_GENERATE_MODE = 'ai_generate_mode', // AI 生成模式 + AI_WRITE_TYPE = 'ai_write_type', // AI 写作类型 + AI_WRITE_LENGTH = 'ai_write_length', // AI 写作长度 + AI_WRITE_FORMAT = 'ai_write_format', // AI 写作格式 + AI_WRITE_TONE = 'ai_write_tone', // AI 写作语气 + AI_WRITE_LANGUAGE = 'ai_write_language', // AI 写作语言 + + // ========== IOT - 物联网模块 ========== + IOT_NET_TYPE = 'iot_net_type', // IOT 联网方式 + IOT_VALIDATE_TYPE = 'iot_validate_type', // IOT 数据校验级别 + IOT_PRODUCT_STATUS = 'iot_product_status', // IOT 产品状态 + IOT_PRODUCT_DEVICE_TYPE = 'iot_product_device_type', // IOT 产品设备类型 + IOT_DATA_FORMAT = 'iot_data_format', // IOT 数据格式 + IOT_PROTOCOL_TYPE = 'iot_protocol_type', // IOT 接入网关协议 + IOT_DEVICE_STATUS = 'iot_device_status', // IOT 设备状态 + IOT_PRODUCT_FUNCTION_TYPE = 'iot_product_function_type', // IOT 产品功能类型 + IOT_DATA_TYPE = 'iot_data_type', // IOT 数据类型 + IOT_UNIT_TYPE = 'iot_unit_type', // IOT 单位类型 + IOT_RW_TYPE = 'iot_rw_type' // IOT 读写类型 +} diff --git a/src/utils/listUtil.ts b/src/utils/listUtil.ts new file mode 100644 index 0000000..36c33fc --- /dev/null +++ b/src/utils/listUtil.ts @@ -0,0 +1,37 @@ +// 根据字段值,归类二维数组 +export const groupByField = ( + items: T[], + fieldName: string +): GroupedItem[][] => { + // 使用一个 Map 来存储归类后的子列表 + const groupedMap = new Map[]>() + + // 遍历每个 item,并将其根据指定的 fieldName 字段归类到对应的子列表中 + items.forEach((item) => { + const fieldValue = item[fieldName] + if (!groupedMap.has(fieldValue)) { + groupedMap.set(fieldValue, []) + } + groupedMap.get(fieldValue)!.push(item) + }) + + // 将 Map 中的值转换为二维数组,并添加额外的信息(子数组长度,布尔值) + const groupedItems: GroupedItem[][] = Array.from(groupedMap.entries()).map( + ([fieldValue, group]) => { + return { + items: group, + length: group.length, + isEmpty: group.length === 0 // 或者根据需要定义其他布尔值逻辑 + } + } + ) + + return groupedItems +} + +// 定义 GroupedItem 类型,使用泛型 T +interface GroupedItem { + items: T[] + length: number + isEmpty: boolean +} -- Gitee From 36590a740ebd52f715b1176193cb2ed5cf8468bc Mon Sep 17 00:00:00 2001 From: alwayssuper <12851801+alwayssuper@user.noreply.gitee.com> Date: Wed, 23 Oct 2024 14:02:26 +0800 Subject: [PATCH 2/2] feat: add tag functionality --- src/pages/task/components/DoneList.vue | 22 +++++++++++++++++----- src/pages/task/components/MyTaskList.vue | 5 +++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/pages/task/components/DoneList.vue b/src/pages/task/components/DoneList.vue index df3190f..9185784 100644 --- a/src/pages/task/components/DoneList.vue +++ b/src/pages/task/components/DoneList.vue @@ -9,15 +9,27 @@ {{ item.processInstance.name }} + 审批中 + 已通过 已通过 + 不通过 - + >不通过 + 已取消 不通过 + 已取消