diff --git a/package.json b/package.json index eb34ec17..22334907 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yudao-ui-admin-vue3", - "version": "1.8.1-snapshot", + "version": "1.8.2-snapshot", "description": "基于vue3、vite4、element-plus、typesScript", "author": "xingyu", "private": false, diff --git a/src/api/bpm/task/index.ts b/src/api/bpm/task/index.ts index 3177eefc..ccd5c4ee 100644 --- a/src/api/bpm/task/index.ts +++ b/src/api/bpm/task/index.ts @@ -42,20 +42,14 @@ export const exportTask = async (params) => { return await request.download({ url: '/bpm/task/export', params }) } -/** - * 获取所有可回退的节点 - * @param params - */ +// 获取所有可回退的节点 export const getReturnList = async (params) => { return await request.get({ url: '/bpm/task/get-return-list', params }) } -/** - * 确认回退 - * @param params - */ -export const okRollback = async (data) => { - return await request.put({ url: '/bpm/task/rollback', data }) +// 回退 +export const returnTask = async (data) => { + return await request.put({ url: '/bpm/task/return', data }) } /** diff --git a/src/api/mall/product/spu.ts b/src/api/mall/product/spu.ts index 2ad9bc60..6c476b8c 100644 --- a/src/api/mall/product/spu.ts +++ b/src/api/mall/product/spu.ts @@ -20,8 +20,8 @@ export interface Sku { stock?: number // 库存 weight?: number // 商品重量,单位:kg 千克 volume?: number // 商品体积,单位:m^3 平米 - subCommissionFirstPrice?: number | string // 一级分销的佣金 - subCommissionSecondPrice?: number | string // 二级分销的佣金 + firstBrokerageRecord?: number | string // 一级分销的佣金 + secondBrokerageRecord?: number | string // 二级分销的佣金 salesCount?: number // 商品销量 } diff --git a/src/api/mall/trade/brokerage/record/index.ts b/src/api/mall/trade/brokerage/record/index.ts new file mode 100644 index 00000000..7df9a225 --- /dev/null +++ b/src/api/mall/trade/brokerage/record/index.ts @@ -0,0 +1,11 @@ +import request from '@/config/axios' + +// 查询佣金记录列表 +export const getBrokerageRecordPage = async (params: any) => { + return await request.get({ url: `/trade/brokerage-record/page`, params }) +} + +// 查询佣金记录详情 +export const getBrokerageRecord = async (id: number) => { + return await request.get({ url: `/trade/brokerage-record/get?id=` + id }) +} diff --git a/src/api/mall/trade/brokerage/user/index.ts b/src/api/mall/trade/brokerage/user/index.ts new file mode 100644 index 00000000..1fed3bfa --- /dev/null +++ b/src/api/mall/trade/brokerage/user/index.ts @@ -0,0 +1,39 @@ +import request from '@/config/axios' + +export interface BrokerageUserVO { + id: number + bindUserId: number + bindUserTime: Date + brokerageEnabled: boolean + brokerageTime: Date + price: number + frozenPrice: number + + nickname: string + avatar: string +} + +// 查询分销用户列表 +export const getBrokerageUserPage = async (params: any) => { + return await request.get({ url: `/trade/brokerage-user/page`, params }) +} + +// 查询分销用户详情 +export const getBrokerageUser = async (id: number) => { + return await request.get({ url: `/trade/brokerage-user/get?id=` + id }) +} + +// 修改推广员 +export const updateBindUser = async (data: any) => { + return await request.put({ url: `/trade/brokerage-user/update-bind-user`, data }) +} + +// 清除推广员 +export const clearBindUser = async (data: any) => { + return await request.put({ url: `/trade/brokerage-user/clear-bind-user`, data }) +} + +// 修改推广资格 +export const updateBrokerageEnabled = async (data: any) => { + return await request.put({ url: `/trade/brokerage-user/update-brokerage-enable`, data }) +} diff --git a/src/api/mall/trade/brokerage/withdraw/index.ts b/src/api/mall/trade/brokerage/withdraw/index.ts new file mode 100644 index 00000000..c93286a9 --- /dev/null +++ b/src/api/mall/trade/brokerage/withdraw/index.ts @@ -0,0 +1,39 @@ +import request from '@/config/axios' + +export interface BrokerageWithdrawVO { + id: number + userId: number + price: number + feePrice: number + totalPrice: number + type: number + name: string + accountNo: string + bankName: string + bankAddress: string + accountQrCodeUrl: string + status: number + auditReason: string + auditTime: Date + remark: string +} + +// 查询佣金提现列表 +export const getBrokerageWithdrawPage = async (params: any) => { + return await request.get({ url: `/trade/brokerage-withdraw/page`, params }) +} + +// 查询佣金提现详情 +export const getBrokerageWithdraw = async (id: number) => { + return await request.get({ url: `/trade/brokerage-withdraw/get?id=` + id }) +} + +// 佣金提现 - 通过申请 +export const approveBrokerageWithdraw = async (id: number) => { + return await request.put({ url: `/trade/brokerage-withdraw/approve?id=` + id }) +} + +// 审核佣金提现 - 驳回申请 +export const rejectBrokerageWithdraw = async (data: BrokerageWithdrawVO) => { + return await request.put({ url: `/trade/brokerage-withdraw/reject`, data }) +} diff --git a/src/api/mall/trade/config/index.ts b/src/api/mall/trade/config/index.ts new file mode 100644 index 00000000..3a1771d8 --- /dev/null +++ b/src/api/mall/trade/config/index.ts @@ -0,0 +1,24 @@ +import request from '@/config/axios' + +export interface ConfigVO { + brokerageEnabled: boolean + brokerageEnabledCondition: number + brokerageBindMode: number + brokeragePostUrls: string + brokerageFirstPercent: number + brokerageSecondPercent: number + brokerageWithdrawMinPrice: number + brokerageBankNames: string + brokerageFrozenDays: number + brokerageWithdrawType: string +} + +// 查询交易中心配置详情 +export const getTradeConfig = async () => { + return await request.get({ url: `/trade/config/get` }) +} + +// 保存交易中心配置 +export const saveTradeConfig = async (data: ConfigVO) => { + return await request.put({ url: `/trade/config/save`, data }) +} diff --git a/src/api/mall/trade/order/index.ts b/src/api/mall/trade/order/index.ts index d4a22944..80669c57 100644 --- a/src/api/mall/trade/order/index.ts +++ b/src/api/mall/trade/order/index.ts @@ -51,12 +51,13 @@ export interface OrderVO { avatar?: string } // 订单操作日志 - orderLog: orderLog[] + logs?: OrderLogRespVO[] } -export interface orderLog { +export interface OrderLogRespVO { content?: string createTime?: Date + userType?: number } export interface OrderItemRespVO { diff --git a/src/api/member/experience-record/index.ts b/src/api/member/experience-record/index.ts new file mode 100644 index 00000000..6d40a48d --- /dev/null +++ b/src/api/member/experience-record/index.ts @@ -0,0 +1,22 @@ +import request from '@/config/axios' + +export interface ExperienceRecordVO { + id: number + userId: number + bizId: string + bizType: number + title: string + description: string + experience: number + totalExperience: number +} + +// 查询会员经验记录列表 +export const getExperienceRecordPage = async (params) => { + return await request.get({ url: `/member/experience-record/page`, params }) +} + +// 查询会员经验记录详情 +export const getExperienceRecord = async (id: number) => { + return await request.get({ url: `/member/experience-record/get?id=` + id }) +} diff --git a/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue b/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue index dd4c8456..e2cd4679 100644 --- a/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue +++ b/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue @@ -11,6 +11,7 @@ import BpmnViewer from 'bpmn-js/lib/Viewer' import DefaultEmptyXML from './plugins/defaultEmpty' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { formatDate } from '@/utils/formatTime' +import { isEmpty } from '@/utils/is' defineOptions({ name: 'MyProcessViewer' }) @@ -85,6 +86,7 @@ const createNewDiagram = async (xml) => { // console.error(`[Process Designer Warn]: ${e?.message || e}`); } } + /* 高亮流程图 */ // TODO 芋艿:如果多个 endActivity 的话,目前的逻辑可能有一定的问题。https://www.jdon.com/workflow/multi-events.html const highlightDiagram = async () => { @@ -97,6 +99,9 @@ const highlightDiagram = async () => { let canvas = bpmnModeler.get('canvas') let todoActivity: any = activityList.find((m: any) => !m.endTime) // 找到待办的任务 let endActivity: any = activityList[activityList.length - 1] // 获得最后一个任务 + let findProcessTask = false //是否已经高亮了进行中的任务 + //进行中高亮之后的任务 key 集合,用于过滤掉 taskList 进行中后面的任务,避免进行中后面的数据 Hover 还有数据 + let removeTaskDefinitionKeyList = [] // debugger bpmnModeler.getDefinitions().rootElements[0].flowElements?.forEach((n: any) => { let activity: any = activityList.find((m: any) => m.key === n.id) // 找到对应的活动 @@ -110,9 +115,17 @@ const highlightDiagram = async () => { if (!task) { return } + //进行中的任务已经高亮过了,则不高亮后面的任务了 + if (findProcessTask) { + removeTaskDefinitionKeyList.push(n.id) + return + } // 高亮任务 canvas.addMarker(n.id, getResultCss(task.result)) - + //标记是否高亮了进行中任务 + if (task.result === 1) { + findProcessTask = true + } // 如果非通过,就不走后面的线条了 if (task.result !== 2) { return @@ -212,6 +225,11 @@ const highlightDiagram = async () => { } } }) + if (!isEmpty(removeTaskDefinitionKeyList)) { + taskList.value = taskList.value.filter( + (item) => !removeTaskDefinitionKeyList.includes(item.definitionKey) + ) + } } const getActivityHighlightCss = (activity) => { return activity.endTime ? 'highlight' : 'highlight-todo' @@ -231,7 +249,7 @@ const getResultCss = (result) => { return 'highlight-cancel' } else if (result === 5) { // 退回 - return 'highlight-rollback' + return 'highlight-return' } return '' } @@ -276,9 +294,9 @@ const elementHover = (element) => { console.log(element.value, 'element.value') const activity = activityLists.value.find((m) => m.key === element.value.id) console.log(activity, 'activityactivityactivityactivity') - // if (!activity) { - // return - // } + if (!activity) { + return + } if (!elementOverlayIds.value[element.value.id] && element.value.type !== 'bpmn:Process') { let html = `

Elemet id: ${element.value.id}

@@ -568,41 +586,41 @@ watch( } /** 回退 */ -.highlight-rollback.djs-shape .djs-visual > :nth-child(1) { +.highlight-return.djs-shape .djs-visual > :nth-child(1) { fill: #e6a23c !important; stroke: #e6a23c !important; fill-opacity: 0.2 !important; } -.highlight-rollback.djs-shape .djs-visual > :nth-child(2) { +.highlight-return.djs-shape .djs-visual > :nth-child(2) { fill: #e6a23c !important; } -.highlight-rollback.djs-shape .djs-visual > path { +.highlight-return.djs-shape .djs-visual > path { fill: #e6a23c !important; fill-opacity: 0.2 !important; stroke: #e6a23c !important; } -.highlight-rollback.djs-connection > .djs-visual > path { +.highlight-return.djs-connection > .djs-visual > path { stroke: #e6a23c !important; } -.highlight-rollback:not(.djs-connection) .djs-visual > :nth-child(1) { +.highlight-return:not(.djs-connection) .djs-visual > :nth-child(1) { fill: #e6a23c !important; /* color elements as green */ } -:deep(.highlight-rollback.djs-shape .djs-visual > :nth-child(1)) { +:deep(.highlight-return.djs-shape .djs-visual > :nth-child(1)) { fill: #e6a23c !important; stroke: #e6a23c !important; fill-opacity: 0.2 !important; } -:deep(.highlight-rollback.djs-shape .djs-visual > :nth-child(2)) { +:deep(.highlight-return.djs-shape .djs-visual > :nth-child(2)) { fill: #e6a23c !important; } -:deep(.highlight-rollback.djs-shape .djs-visual > path) { +:deep(.highlight-return.djs-shape .djs-visual > path) { fill: #e6a23c !important; fill-opacity: 0.2 !important; stroke: #e6a23c !important; } -:deep(.highlight-rollback.djs-connection > .djs-visual > path) { +:deep(.highlight-return.djs-connection > .djs-visual > path) { stroke: #e6a23c !important; } diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 8d783635..6f3ded5c 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -272,3 +272,89 @@ export const PromotionDiscountTypeEnum = { name: '折扣' } } + +/** + * 分销关系绑定模式枚举 + */ +export const BrokerageBindModeEnum = { + ANYTIME: { + mode: 0, + name: '没有推广人' + }, + REGISTER: { + mode: 1, + name: '新用户' + } +} +/** + * 分佣模式枚举 + */ +export const BrokerageEnabledConditionEnum = { + ALL: { + condition: 0, + name: '人人分销' + }, + ADMIN: { + condition: 1, + name: '指定分销' + } +} +/** + * 佣金记录业务类型枚举 + */ +export const BrokerageRecordBizTypeEnum = { + ORDER: { + type: 1, + name: '获得推广佣金' + }, + WITHDRAW: { + type: 2, + name: '提现申请' + } +} +/** + * 佣金提现状态枚举 + */ +export const BrokerageWithdrawStatusEnum = { + AUDITING: { + status: 0, + name: '审核中' + }, + AUDIT_SUCCESS: { + status: 10, + name: '审核通过' + }, + AUDIT_FAIL: { + status: 20, + name: '审核不通过' + }, + WITHDRAW_SUCCESS: { + status: 11, + name: '提现成功' + }, + WITHDRAW_FAIL: { + status: 21, + name: '提现失败' + } +} +/** + * 佣金提现类型枚举 + */ +export const BrokerageWithdrawTypeEnum = { + WALLET: { + type: 1, + name: '钱包' + }, + BANK: { + type: 2, + name: '银行卡' + }, + WECHAT: { + type: 3, + name: '微信' + }, + ALIPAY: { + type: 4, + name: '支付宝' + } +} diff --git a/src/utils/dict.ts b/src/utils/dict.ts index 6b163628..aa948594 100644 --- a/src/utils/dict.ts +++ b/src/utils/dict.ts @@ -60,13 +60,19 @@ export const getBoolDictOptions = (dictType: string) => { return dictOption } -export const getDictObj = (dictType: string, value: any) => { +/** + * 获取指定字典类型的指定值对应的字典对象 + * @param dictType 字典类型 + * @param value 字典值 + * @return DictDataType 字典对象 + */ +export const getDictObj = (dictType: string, value: any): DictDataType | undefined => { const dictOptions: DictDataType[] = getDictOptions(dictType) - dictOptions.forEach((dict: DictDataType) => { - if (dict.value === value.toString()) { + for (const dict of dictOptions) { + if (dict.value === value + '') { return dict } - }) + } } /** @@ -74,12 +80,13 @@ export const getDictObj = (dictType: string, value: any) => { * * @param dictType 字典类型 * @param value 字典数据的值 + * @return 字典名称 */ -export const getDictLabel = (dictType: string, value: any) => { +export const getDictLabel = (dictType: string, value: any): string => { const dictOptions: DictDataType[] = getDictOptions(dictType) const dictLabel = ref('') dictOptions.forEach((dict: DictDataType) => { - if (dict.value === value) { + if (dict.value === value + '') { dictLabel.value = dict.label } }) @@ -131,7 +138,7 @@ export enum DICT_TYPE { BPM_OA_LEAVE_TYPE = 'bpm_oa_leave_type', // ========== PAY 模块 ========== - PAY_CHANNEL_CODE = 'pay_channel_code_type', // 支付渠道编码类型 + PAY_CHANNEL_CODE = 'pay_channel_code', // 支付渠道编码类型 PAY_ORDER_STATUS = 'pay_order_status', // 商户支付订单状态 PAY_REFUND_STATUS = 'pay_refund_status', // 退款订单状态 PAY_NOTIFY_STATUS = 'pay_notify_status', // 商户支付回调状态 @@ -143,6 +150,7 @@ export enum DICT_TYPE { // ========== MALL - 会员模块 ========== MEMBER_POINT_BIZ_TYPE = 'member_point_biz_type', // 积分的业务类型 + MEMBER_EXPERIENCE_BIZ_TYPE = 'member_experience_biz_type', // 会员经验业务类型 // ========== MALL - 商品模块 ========== PRODUCT_UNIT = 'product_unit', // 商品单位 @@ -157,6 +165,13 @@ export enum DICT_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', // 优惠类型 diff --git a/src/utils/formatter.ts b/src/utils/formatter.ts new file mode 100644 index 00000000..7c6e39ff --- /dev/null +++ b/src/utils/formatter.ts @@ -0,0 +1,12 @@ +import { fenToYuan } from '@/utils' +import { TableColumnCtx } from 'element-plus' + +// 格式化金额【分转元】 +export const fenToYuanFormat = ( + row: any, + column: TableColumnCtx, + cellValue: any, + index: number +) => { + return `¥${fenToYuan(cellValue)}` +} diff --git a/src/views/Login/components/LoginForm.vue b/src/views/Login/components/LoginForm.vue index 49742f00..a4eb0b92 100644 --- a/src/views/Login/components/LoginForm.vue +++ b/src/views/Login/components/LoginForm.vue @@ -230,6 +230,7 @@ const getCookie = () => { } } } +const loading = ref() // ElLoading.service 返回的实例 // 登录 const handleLogin = async (params) => { loginLoading.value = true @@ -244,7 +245,7 @@ const handleLogin = async (params) => { if (!res) { return } - ElLoading.service({ + loading.value = ElLoading.service({ lock: true, text: '正在加载系统中...', background: 'rgba(0, 0, 0, 0.7)' @@ -264,13 +265,9 @@ const handleLogin = async (params) => { } else { push({ path: redirect.value || permissionStore.addRouters[0].path }) } - } catch { - loginLoading.value = false } finally { - setTimeout(() => { - const loadingInstance = ElLoading.service() - loadingInstance.close() - }, 400) + loginLoading.value = false + loading.value.close() } } diff --git a/src/views/bpm/processInstance/detail/TaskRollbackDialogForm.vue b/src/views/bpm/processInstance/detail/TaskReturnDialogForm.vue similarity index 95% rename from src/views/bpm/processInstance/detail/TaskRollbackDialogForm.vue rename to src/views/bpm/processInstance/detail/TaskReturnDialogForm.vue index 168fd1a8..f93bf2c5 100644 --- a/src/views/bpm/processInstance/detail/TaskRollbackDialogForm.vue +++ b/src/views/bpm/processInstance/detail/TaskReturnDialogForm.vue @@ -11,9 +11,9 @@ @@ -68,7 +68,7 @@ const submitForm = async () => { // 提交请求 formLoading.value = true try { - await TaskApi.okRollback(formData.value) + await TaskApi.returnTask(formData.value) message.success('回退成功') dialogVisible.value = false // 发送操作成功的事件 diff --git a/src/views/bpm/processInstance/detail/index.vue b/src/views/bpm/processInstance/detail/index.vue index d513bbbd..585c60db 100644 --- a/src/views/bpm/processInstance/detail/index.vue +++ b/src/views/bpm/processInstance/detail/index.vue @@ -92,7 +92,7 @@ - + @@ -107,7 +107,7 @@ import * as TaskApi from '@/api/bpm/task' import TaskUpdateAssigneeForm from './TaskUpdateAssigneeForm.vue' import ProcessInstanceBpmnViewer from './ProcessInstanceBpmnViewer.vue' import ProcessInstanceTaskList from './ProcessInstanceTaskList.vue' -import TaskRollbackDialog from './TaskRollbackDialogForm.vue' +import TaskReturnDialog from './TaskReturnDialogForm.vue' import TaskDelegateForm from './taskDelegateForm.vue' import { registerComponent } from '@/utils/routerHelper' @@ -179,10 +179,10 @@ const handleDelegate = async (task) => { } //回退弹框组件 -const taskRollbackRef = ref() +const taskReturnDialogRef = ref() /** 处理审批退回的操作 */ const handleBack = async (task) => { - taskRollbackRef.value.open(task.id) + taskReturnDialogRef.value.open(task.id) } /** 获得详情 */ diff --git a/src/views/infra/server/index.vue b/src/views/infra/server/index.vue index 06c35d97..b9a157a5 100644 --- a/src/views/infra/server/index.vue +++ b/src/views/infra/server/index.vue @@ -16,6 +16,9 @@ const src = ref(import.meta.env.VITE_BASE_URL + '/admin/applications') /** 初始化 */ onMounted(async () => { try { + // 友情提示:如果访问出现 404 问题: + // 1)boot 参考 https://doc.iocoder.cn/server-monitor/ 解决; + // 2)cloud 参考 https://cloud.iocoder.cn/server-monitor/ 解决 const data = await ConfigApi.getConfigKey('url.spring-boot-admin') if (data && data.length > 0) { src.value = data diff --git a/src/views/mall/product/spu/components/SkuList.vue b/src/views/mall/product/spu/components/SkuList.vue index f64e4a98..7a4605c6 100644 --- a/src/views/mall/product/spu/components/SkuList.vue +++ b/src/views/mall/product/spu/components/SkuList.vue @@ -80,7 +80,7 @@