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 @@
+
+
+
+
+
+ {{ item.processInstanceName }}
+ 查看详情
+
+
+ 单行文本:54354455465465465xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+
+ 单行文本:543544554654654584864
+
+
+
+
+
+ {{ item.creatorName }}{{
+ formatTimestamp(item.createTime)
+ }}
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+ {{ item.processInstance.name }}已通过 不通过
+
+
+
+ 单行文本:54354455465465465xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+
+ 单行文本:543544554654654584864
+
+
+
+
+
+ {{
+ item.processInstance.startUser.nickname
+ }}{{
+ formatTimestamp(item.createTime)
+ }}
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+ {{
+ item.name
+ }}
+ 审批中
+ 已通过
+ 不通过
+
+
+ 单行文本:54354455465465465xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+
+ 单行文本:543544554654654584864
+
+
+
+
+
+
+ {{ user?.nickname }}
+
+ {{
+ formatTimestamp(item.startTime)
+ }}
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+ {{
+ item.processInstance.name
+ }}
+ 查看详情
+
+
+ 单行文本:54354455465465465xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+
+ 单行文本:543544554654654584864
+
+
+
+
+
+
+ {{
+ item.processInstance.startUser.nickname
+ }}
+
+ {{ getTimeDifference(item.createTime) }}以前到达
+
+
+
+
+ 拒绝
+
+
+ 同意
+
+
+
+
+
+
+
+
+
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 }}
+ 审批中
+ 已通过 已通过
+ 不通过
-
+ >不通过
+ 已取消
不通过
+ 已取消