diff --git a/README.md b/README.md index 56683973..aa498ce2 100644 --- a/README.md +++ b/README.md @@ -39,14 +39,14 @@ | 框架 | 说明 | 版本 | |----------------------------------------------------------------------|------------------|--------| | [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.3.4 | -| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.4.9 | -| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.14 | +| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.4.11 | +| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.4.0 | | [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 5.2.2 | -| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.1.6 | -| [vueuse](https://vueuse.org/) | 常用工具集 | 10.4.1 | -| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.4.1 | +| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.1.7 | +| [vueuse](https://vueuse.org/) | 常用工具集 | 10.5.0 | +| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.5.0 | | [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.2.5 | -| [unocss](https://uno.antfu.me/) | 原子 css | 0.56.1 | +| [unocss](https://uno.antfu.me/) | 原子 css | 0.56.5 | | [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.1.1 | | [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.23 | diff --git a/package.json b/package.json index 5bbf4fd8..37801eef 100644 --- a/package.json +++ b/package.json @@ -31,31 +31,31 @@ "@form-create/element-ui": "^3.1.24", "@iconify/iconify": "^3.1.1", "@videojs-player/vue": "^1.0.0", - "@vueuse/core": "^10.4.1", + "@vueuse/core": "^10.5.0", "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "^5.1.10", "@zxcvbn-ts/core": "^3.0.4", "animate.css": "^4.1.1", - "axios": "^1.5.0", + "axios": "^1.5.1", "benz-amr-recorder": "^1.1.5", "bpmn-js-token-simulation": "^0.10.0", "camunda-bpmn-moddle": "^7.0.1", "cropperjs": "^1.6.1", "crypto-js": "^4.1.1", "dayjs": "^1.11.10", - "diagram-js": "^12.3.0", + "diagram-js": "^12.4.0", "echarts": "^5.4.3", "echarts-wordcloud": "^2.1.0", - "element-plus": "2.3.14", - "fast-xml-parser": "^4.3.0", - "highlight.js": "^11.8.0", + "element-plus": "2.4.0", + "fast-xml-parser": "^4.3.2", + "highlight.js": "^11.9.0", "intro.js": "^7.2.0", "jsencrypt": "^3.3.2", "lodash-es": "^4.17.21", "min-dash": "^4.1.1", "mitt": "^3.0.1", "nprogress": "^0.2.0", - "pinia": "^2.1.6", + "pinia": "^2.1.7", "qrcode": "^1.5.3", "qs": "^6.11.2", "sortablejs": "^1.15.0", @@ -64,7 +64,7 @@ "video.js": "^7.21.5", "vue": "^3.3.4", "vue-dompurify-html": "^4.1.4", - "vue-i18n": "^9.4.1", + "vue-i18n": "^9.5.0", "vue-router": "^4.2.5", "vue-types": "^5.1.1", "vuedraggable": "^4.1.0", @@ -72,15 +72,15 @@ "xml-js": "^1.6.11" }, "devDependencies": { - "@commitlint/cli": "^17.7.1", - "@commitlint/config-conventional": "^17.7.0", - "@iconify/json": "^2.2.119", - "@intlify/unplugin-vue-i18n": "^1.2.0", + "@commitlint/cli": "^17.8.0", + "@commitlint/config-conventional": "^17.8.0", + "@iconify/json": "^2.2.129", + "@intlify/unplugin-vue-i18n": "^1.4.0", "@purge-icons/generated": "^0.9.0", - "@types/intro.js": "^5.1.1", + "@types/intro.js": "^5.1.2", "@types/lodash-es": "^4.17.9", - "@types/node": "^20.6.0", - "@types/nprogress": "^0.2.0", + "@types/node": "^20.8.6", + "@types/nprogress": "^0.2.1", "@types/qrcode": "^1.5.2", "@types/qs": "^6.9.8", "@types/sortablejs": "^1.15.4", @@ -88,39 +88,43 @@ "@typescript-eslint/parser": "^6.7.2", "@unocss/eslint-config": "^0.56.1", "@unocss/transformer-variant-group": "^0.56.1", + "@typescript-eslint/eslint-plugin": "^6.7.5", + "@typescript-eslint/parser": "^6.7.5", + "@unocss/transformer-variant-group": "^0.56.5", + "@unocss/eslint-config": "^0.56.5", "@vitejs/plugin-legacy": "^4.1.1", - "@vitejs/plugin-vue": "^4.3.4", + "@vitejs/plugin-vue": "^4.4.0", "@vitejs/plugin-vue-jsx": "^3.0.2", - "@vue-macros/volar": "^0.14.3", + "@vue-macros/volar": "^0.17.0", "autoprefixer": "^10.4.16", "bpmn-js": "8.9.0", "bpmn-js-properties-panel": "0.46.0", "consola": "^3.2.3", - "eslint": "^8.49.0", + "eslint": "^8.51.0", "eslint-config-prettier": "^9.0.0", - "eslint-define-config": "^1.23.0", - "eslint-plugin-prettier": "^5.0.0", + "eslint-define-config": "^1.24.1", + "eslint-plugin-prettier": "^5.0.1", "eslint-plugin-vue": "^9.17.0", - "lint-staged": "^14.0.1", - "postcss": "^8.4.30", + "lint-staged": "^15.0.1", + "postcss": "^8.4.31", "postcss-html": "^1.5.0", - "postcss-scss": "^4.0.8", + "postcss-scss": "^4.0.9", "prettier": "^3.0.3", - "rimraf": "^5.0.1", - "rollup": "^3.29.2", - "sass": "^1.68.0", + "rimraf": "^5.0.5", + "rollup": "^4.1.4", + "sass": "^1.69.3", "stylelint": "^15.10.3", "stylelint-config-html": "^1.1.0", "stylelint-config-recommended": "^13.0.0", "stylelint-config-standard": "^34.0.0", "stylelint-order": "^6.0.3", - "terser": "^5.20.0", + "terser": "^5.21.0", "typescript": "5.2.2", - "unocss": "^0.56.1", + "unocss": "^0.56.5", "unplugin-auto-import": "^0.16.6", "unplugin-element-plus": "^0.8.0", "unplugin-vue-components": "^0.25.2", - "vite": "4.4.9", + "vite": "4.4.11", "vite-plugin-compression": "^0.5.1", "vite-plugin-ejs": "^1.6.4", "vite-plugin-eslint": "^1.8.1", @@ -128,8 +132,8 @@ "vite-plugin-purge-icons": "^0.9.2", "vite-plugin-svg-icons": "^2.0.1", "vite-plugin-top-level-await": "^1.3.1", - "vue-eslint-parser": "^9.3.1", - "vue-tsc": "^1.8.13" + "vue-eslint-parser": "^9.3.2", + "vue-tsc": "^1.8.19" }, "license": "MIT", "repository": { diff --git a/src/api/bpm/task/index.ts b/src/api/bpm/task/index.ts index ccd5c4ee..f1359194 100644 --- a/src/api/bpm/task/index.ts +++ b/src/api/bpm/task/index.ts @@ -58,3 +58,24 @@ export const returnTask = async (data) => { export const delegateTask = async (data) => { return await request.put({ url: '/bpm/task/delegate', data }) } + +/** + * 加签 + */ +export const taskAddSign = async (data) => { + return await request.put({ url: '/bpm/task/add-sign', data }) +} + +/** + * 获取减签任务列表 + */ +export const getChildrenTaskList = async (id: string) => { + return await request.get({ url: '/bpm/task/get-children-task-list?taskId=' + id }) +} + +/** + * 减签 + */ +export const taskSubSign = async (data) => { + return await request.put({ url: '/bpm/task/sub-sign', data }) +} diff --git a/src/api/login/index.ts b/src/api/login/index.ts index b65a90cf..1ffb38d6 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -47,6 +47,18 @@ export const smsLogin = (data: SmsLoginVO) => { return request.post({ url: '/system/auth/sms-login', data }) } +// 社交快捷登录,使用 code 授权码 +export function socialLogin(type: string, code: string, state: string) { + return request.post({ + url: '/system/auth/social-login', + data: { + type, + code, + state + } + }) +} + // 社交授权的跳转 export const socialAuthRedirect = (type: number, redirectUri: string) => { return request.get({ diff --git a/src/api/login/types.ts b/src/api/login/types.ts index b2173f72..fff81225 100644 --- a/src/api/login/types.ts +++ b/src/api/login/types.ts @@ -2,6 +2,9 @@ export type UserLoginVO = { username: string password: string captchaVerification: string + socialType?: string + socialCode?: string + socialState?: string } export type TokenType = { diff --git a/src/api/mall/promotion/article/index.ts b/src/api/mall/promotion/article/index.ts index c2941d05..824958ad 100644 --- a/src/api/mall/promotion/article/index.ts +++ b/src/api/mall/promotion/article/index.ts @@ -40,8 +40,3 @@ export const updateArticle = async (data: ArticleVO) => { export const deleteArticle = async (id: number) => { return await request.delete({ url: `/promotion/article/delete?id=` + id }) } - -// 导出文章管理 Excel -export const exportArticle = async (params) => { - return await request.download({ url: `/promotion/article/export-excel`, params }) -} diff --git a/src/api/mall/promotion/articleCategory/index.ts b/src/api/mall/promotion/articleCategory/index.ts index 2950d759..47f5e934 100644 --- a/src/api/mall/promotion/articleCategory/index.ts +++ b/src/api/mall/promotion/articleCategory/index.ts @@ -37,8 +37,3 @@ export const updateArticleCategory = async (data: ArticleCategoryVO) => { export const deleteArticleCategory = async (id: number) => { return await request.delete({ url: `/promotion/article-category/delete?id=` + id }) } - -// 导出文章分类 Excel -export const exportArticleCategory = async (params) => { - return await request.download({ url: `/promotion/article-category/export-excel`, params }) -} diff --git a/src/api/mall/statistics/common.ts b/src/api/mall/statistics/common.ts new file mode 100644 index 00000000..3d964392 --- /dev/null +++ b/src/api/mall/statistics/common.ts @@ -0,0 +1,5 @@ +/** 数据对照 Response VO */ +export interface DataComparisonRespVO { + value: T + reference: T +} diff --git a/src/api/mall/statistics/member.ts b/src/api/mall/statistics/member.ts index d4680d3d..92af031e 100644 --- a/src/api/mall/statistics/member.ts +++ b/src/api/mall/statistics/member.ts @@ -1,6 +1,6 @@ import request from '@/config/axios' import dayjs from 'dayjs' -import { TradeStatisticsComparisonRespVO } from '@/api/mall/statistics/trade' +import { DataComparisonRespVO } from '@/api/mall/statistics/common' import { formatDate } from '@/utils/formatTime' /** 会员分析 Request VO */ @@ -10,17 +10,17 @@ export interface MemberAnalyseReqVO { /** 会员分析 Response VO */ export interface MemberAnalyseRespVO { - visitorCount: number + visitUserCount: number orderUserCount: number payUserCount: number atv: number - comparison: TradeStatisticsComparisonRespVO + comparison: DataComparisonRespVO } /** 会员分析对照数据 Response VO */ export interface MemberAnalyseComparisonRespVO { - userCount: number - activeUserCount: number + registerUserCount: number + visitUserCount: number rechargeUserCount: number } @@ -29,8 +29,8 @@ export interface MemberAreaStatisticsRespVO { areaId: number areaName: string userCount: number - orderCreateCount: number - orderPayCount: number + orderCreateUserCount: number + orderPayUserCount: number orderPayPrice: number } @@ -54,6 +54,20 @@ export interface MemberTerminalStatisticsRespVO { userCount: number } +/** 会员数量统计 Response VO */ +export interface MemberCountRespVO { + /** 用户访问量 */ + visitUserCount: string + /** 注册用户数量 */ + registerUserCount: number +} + +/** 会员注册数量 Response VO */ +export interface MemberRegisterCountRespVO { + date: string + count: number +} + // 查询会员统计 export const getMemberSummary = () => { return request.get({ @@ -72,20 +86,38 @@ export const getMemberAnalyse = (params: MemberAnalyseReqVO) => { // 按照省份,查询会员统计列表 export const getMemberAreaStatisticsList = () => { return request.get({ - url: '/statistics/member/get-area-statistics-list' + url: '/statistics/member/area-statistics-list' }) } // 按照性别,查询会员统计列表 export const getMemberSexStatisticsList = () => { return request.get({ - url: '/statistics/member/get-sex-statistics-list' + url: '/statistics/member/sex-statistics-list' }) } // 按照终端,查询会员统计列表 export const getMemberTerminalStatisticsList = () => { return request.get({ - url: '/statistics/member/get-terminal-statistics-list' + url: '/statistics/member/terminal-statistics-list' + }) +} + +// 获得用户数量量对照 +export const getUserCountComparison = () => { + return request.get>({ + url: '/statistics/member/user-count-comparison' + }) +} + +// 获得会员注册数量列表 +export const getMemberRegisterCountList = ( + beginTime: dayjs.ConfigType, + endTime: dayjs.ConfigType +) => { + return request.get({ + url: '/statistics/member/register-count-list', + params: { times: [formatDate(beginTime), formatDate(endTime)] } }) } diff --git a/src/api/mall/statistics/pay.ts b/src/api/mall/statistics/pay.ts new file mode 100644 index 00000000..f5d14c9d --- /dev/null +++ b/src/api/mall/statistics/pay.ts @@ -0,0 +1,12 @@ +import request from '@/config/axios' + +/** 支付统计 */ +export interface PaySummaryRespVO { + /** 充值金额,单位分 */ + rechargePrice: number +} + +/** 获取钱包充值金额 */ +export const getWalletRechargePrice = async () => { + return await request.get({ url: `/statistics/pay/summary` }) +} diff --git a/src/api/mall/statistics/trade.ts b/src/api/mall/statistics/trade.ts index f7829ccb..94052597 100644 --- a/src/api/mall/statistics/trade.ts +++ b/src/api/mall/statistics/trade.ts @@ -1,12 +1,7 @@ import request from '@/config/axios' import dayjs from 'dayjs' import { formatDate } from '@/utils/formatTime' - -/** 交易统计对照 Response VO */ -export interface TradeStatisticsComparisonRespVO { - value: T - reference: T -} +import { DataComparisonRespVO } from '@/api/mall/statistics/common' /** 交易统计 Response VO */ export interface TradeSummaryRespVO { @@ -24,46 +19,100 @@ export interface TradeTrendReqVO { /** 交易状况统计 Response VO */ export interface TradeTrendSummaryRespVO { time: string - turnover: number + turnoverPrice: number orderPayPrice: number rechargePrice: number expensePrice: number - balancePrice: number + walletPayPrice: number brokerageSettlementPrice: number - orderRefundPrice: number + afterSaleRefundPrice: number +} + +/** 交易订单数量 Response VO */ +export interface TradeOrderCountRespVO { + /** 待发货 */ + undelivered?: number + /** 待核销 */ + pickUp?: number + /** 退款中 */ + afterSaleApply?: number + /** 提现待审核 */ + auditingWithdraw?: number +} + +/** 交易订单统计 Response VO */ +export interface TradeOrderSummaryRespVO { + /** 支付订单商品数 */ + orderPayCount?: number + /** 总支付金额,单位:分 */ + orderPayPrice?: number +} + +/** 订单量趋势统计 Response VO */ +export interface TradeOrderTrendRespVO { + /** 日期 */ + date: string + /** 订单数量 */ + orderPayCount: number + /** 订单支付金额 */ + orderPayPrice: number } // 查询交易统计 export const getTradeStatisticsSummary = () => { - return request.get>({ + return request.get>({ url: '/statistics/trade/summary' }) } // 获得交易状况统计 export const getTradeTrendSummary = (params: TradeTrendReqVO) => { - return request.get>({ + return request.get>({ url: '/statistics/trade/trend/summary', params: formatDateParam(params) }) } // 获得交易状况明细 -export const getTradeTrendList = (params: TradeTrendReqVO) => { +export const getTradeStatisticsList = (params: TradeTrendReqVO) => { return request.get({ - url: '/statistics/trade/trend/list', + url: '/statistics/trade/list', params: formatDateParam(params) }) } // 导出交易状况明细 -export const exportTradeTrend = (params: TradeTrendReqVO) => { +export const exportTradeStatisticsExcel = (params: TradeTrendReqVO) => { return request.download({ - url: '/statistics/trade/trend/export-excel', + url: '/statistics/trade/export-excel', params: formatDateParam(params) }) } +// 获得交易订单数量 +export const getOrderCount = async () => { + return await request.get({ url: `/statistics/trade/order-count` }) +} + +// 获得交易订单数量对照 +export const getOrderComparison = async () => { + return await request.get>({ + url: `/statistics/trade/order-comparison` + }) +} + +// 获得订单量趋势统计 +export const getOrderCountTrendComparison = ( + type: number, + beginTime: dayjs.ConfigType, + endTime: dayjs.ConfigType +) => { + return request.get[]>({ + url: '/statistics/trade/order-count-trend', + params: { type, beginTime: formatDate(beginTime), endTime: formatDate(endTime) } + }) +} + /** 时间参数需要格式化, 确保接口能识别 */ const formatDateParam = (params: TradeTrendReqVO) => { return { times: [formatDate(params.times[0]), formatDate(params.times[1])] } as TradeTrendReqVO diff --git a/src/api/mall/trade/order/index.ts b/src/api/mall/trade/order/index.ts index ea78275f..364483b8 100644 --- a/src/api/mall/trade/order/index.ts +++ b/src/api/mall/trade/order/index.ts @@ -1,6 +1,7 @@ import request from '@/config/axios' export interface OrderVO { + // ========== 订单基本信息 ========== id?: number | null // 订单编号 no?: string // 订单流水号 createTime?: Date | null // 下单时间 @@ -15,35 +16,43 @@ export interface OrderVO { cancelTime?: Date | null // 订单取消时间 cancelType?: number | null // 取消类型 remark?: string // 商家备注 + + // ========== 价格 + 支付基本信息 ========== payOrderId?: number | null // 支付订单编号 - payed?: boolean // 是否已支付 + payStatus?: boolean // 是否已支付 payTime?: Date | null // 付款时间 payChannelCode?: string // 支付渠道 totalPrice?: number | null // 商品原价(总) - orderPrice?: number | null // 订单原价(总) discountPrice?: number | null // 订单优惠(总) deliveryPrice?: number | null // 运费金额 adjustPrice?: number | null // 订单调价(总) payPrice?: number | null // 应付金额(总) + // ========== 收件 + 物流基本信息 ========== deliveryType?: number | null // 发货方式 + pickUpStoreId?: number // 自提门店编号 + pickUpVerifyCode?: string // 自提核销码 deliveryTemplateId?: number | null // 配送模板编号 - logisticsId?: number | null | null // 发货物流公司编号 + logisticsId?: number | null // 发货物流公司编号 logisticsNo?: string // 发货物流单号 - deliveryStatus?: number | null // 发货状态 deliveryTime?: Date | null // 发货时间 receiveTime?: Date | null // 收货时间 receiverName?: string // 收件人名称 receiverMobile?: string // 收件人手机 - receiverAreaId?: number | null // 收件人地区编号 receiverPostCode?: number | null // 收件人邮编 + receiverAreaId?: number | null // 收件人地区编号 + receiverAreaName?: string //收件人地区名字 receiverDetailAddress?: string // 收件人详细地址 + + // ========== 售后基本信息 ========== afterSaleStatus?: number | null // 售后状态 refundPrice?: number | null // 退款金额 + + // ========== 营销基本信息 ========== couponId?: number | null // 优惠劵编号 couponPrice?: number | null // 优惠劵减免金额 - vipPrice?: number | null // VIP 减免金额 pointPrice?: number | null // 积分抵扣的金额 - receiverAreaName?: string //收件人地区名字 + vipPrice?: number | null // VIP 减免金额 + items?: OrderItemRespVO[] // 订单项列表 // 下单用户信息 user?: { @@ -99,11 +108,28 @@ export interface ProductPropertiesVO { valueName?: string // 属性值的名称 } +/** 交易订单统计 */ +export interface TradeOrderSummaryRespVO { + /** 订单数量 */ + orderCount?: number + /** 订单金额 */ + orderPayPrice?: string + /** 退款单数 */ + afterSaleCount?: number + /** 退款金额 */ + afterSalePrice?: string +} + // 查询交易订单列表 -export const getOrderPage = async (params) => { +export const getOrderPage = async (params: any) => { return await request.get({ url: `/trade/order/page`, params }) } +// 查询交易订单统计 +export const getOrderSummary = async (params: any) => { + return await request.get({ url: `/trade/order/summary`, params }) +} + // 查询交易订单详情 export const getOrder = async (id: number | null) => { return await request.get({ url: `/trade/order/get-detail?id=` + id }) @@ -142,5 +168,21 @@ export const updateOrderAddress = async (data: any) => { // 订单核销 export const pickUpOrder = async (id: number) => { - return await request.put({ url: `/trade/order/pick-up?id=${id}` }) + return await request.put({ url: `/trade/order/pick-up-by-id?id=${id}` }) +} + +// 订单核销 +export const pickUpOrderByVerifyCode = async (pickUpVerifyCode: string) => { + return await request.put({ + url: `/trade/order/pick-up-by-verify-code`, + params: { pickUpVerifyCode } + }) +} + +// 查询核销码对应的订单 +export const getOrderByPickUpVerifyCode = async (pickUpVerifyCode: string) => { + return await request.get({ + url: `/trade/order/get-by-pick-up-verify-code`, + params: { pickUpVerifyCode } + }) } diff --git a/src/api/pay/wallet/index.ts b/src/api/pay/wallet/balance/index.ts similarity index 77% rename from src/api/pay/wallet/index.ts rename to src/api/pay/wallet/balance/index.ts index b57deeb0..e5f4a1cd 100644 --- a/src/api/pay/wallet/index.ts +++ b/src/api/pay/wallet/balance/index.ts @@ -20,3 +20,8 @@ export interface WalletVO { export const getWallet = async (params: PayWalletUserReqVO) => { return await request.get({ url: `/pay/wallet/get`, params }) } + +// 查询会员钱包列表 +export const getWalletPage = async (params) => { + return await request.get({ url: `/pay/wallet/page`, params }) +} diff --git a/src/api/pay/wallet/transaction/index.ts b/src/api/pay/wallet/transaction/index.ts new file mode 100644 index 00000000..3377ffaa --- /dev/null +++ b/src/api/pay/wallet/transaction/index.ts @@ -0,0 +1,14 @@ +import request from '@/config/axios' + +export interface WalletTransactionVO { + id: number + walletId: number + title: string + price: number + balance: number +} + +// 查询会员钱包流水列表 +export const getWalletTransactionPage = async (params) => { + return await request.get({ url: `/pay/wallet-transaction/page`, params }) +} diff --git a/src/components/ShortcutDateRangePicker/index.vue b/src/components/ShortcutDateRangePicker/index.vue new file mode 100644 index 00000000..d7fa90cb --- /dev/null +++ b/src/components/ShortcutDateRangePicker/index.vue @@ -0,0 +1,89 @@ + + diff --git a/src/views/mall/statistics/trade/components/TradeTrendValue.vue b/src/components/SummaryCard/index.vue similarity index 95% rename from src/views/mall/statistics/trade/components/TradeTrendValue.vue rename to src/components/SummaryCard/index.vue index 10fa9517..52da6da9 100644 --- a/src/views/mall/statistics/trade/components/TradeTrendValue.vue +++ b/src/components/SummaryCard/index.vue @@ -35,8 +35,8 @@ import { propTypes } from '@/utils/propTypes' import { toNumber } from 'lodash-es' -/** 交易状况统计值组件 */ -defineOptions({ name: 'TradeTrendValue' }) +/** 统计卡片 */ +defineOptions({ name: 'SummaryCard' }) defineProps({ title: propTypes.string.def(''), diff --git a/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue b/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue index e2cd4679..a7958adb 100644 --- a/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue +++ b/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue @@ -250,6 +250,12 @@ const getResultCss = (result) => { } else if (result === 5) { // 退回 return 'highlight-return' + } else if (result === 6) { + // 委派 + return 'highlight-return' + } else if (result === 7 || result === 8 || result === 9) { + // 待后加签任务完成/待前加签任务完成/待前置任务完成 + return 'highlight-return' } return '' } @@ -362,7 +368,7 @@ const elementHover = (element) => { } } console.log(html, 'html111111111111111') - elementOverlayIds.value[element.value.id] = toRaw(overlays.value).add(element.value, { + elementOverlayIds.value[element.value.id] = toRaw(overlays.value)?.add(element.value, { position: { left: 0, bottom: 0 }, html: `
${html}
` }) @@ -591,14 +597,17 @@ watch( stroke: #e6a23c !important; fill-opacity: 0.2 !important; } + .highlight-return.djs-shape .djs-visual > :nth-child(2) { fill: #e6a23c !important; } + .highlight-return.djs-shape .djs-visual > path { fill: #e6a23c !important; fill-opacity: 0.2 !important; stroke: #e6a23c !important; } + .highlight-return.djs-connection > .djs-visual > path { stroke: #e6a23c !important; } @@ -612,14 +621,17 @@ watch( stroke: #e6a23c !important; fill-opacity: 0.2 !important; } + :deep(.highlight-return.djs-shape .djs-visual > :nth-child(2)) { fill: #e6a23c !important; } + :deep(.highlight-return.djs-shape .djs-visual > path) { fill: #e6a23c !important; fill-opacity: 0.2 !important; stroke: #e6a23c !important; } + :deep(.highlight-return.djs-connection > .djs-visual > path) { stroke: #e6a23c !important; } diff --git a/src/layout/components/Breadcrumb/src/Breadcrumb.vue b/src/layout/components/Breadcrumb/src/Breadcrumb.vue index 1852a59b..4079a066 100644 --- a/src/layout/components/Breadcrumb/src/Breadcrumb.vue +++ b/src/layout/components/Breadcrumb/src/Breadcrumb.vue @@ -114,6 +114,7 @@ $prefix-cls: #{$elNamespace}-breadcrumb; } } } + :deep(&__item):last-child { .#{$prefix-cls}__inner { display: flex; diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index cc4bb47e..4f95852f 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -141,6 +141,7 @@ export default { }, router: { login: '登录', + socialLogin: '社交登录', home: '首页', analysis: '分析页', workplace: '工作台' diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index d8172d27..aa260cf1 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -195,6 +195,16 @@ const remainingRouter: AppRouteRecordRaw[] = [ noTagsView: true } }, + { + path: '/social-login', + component: () => import('@/views/Login/SocialLogin.vue'), + name: 'SocialLogin', + meta: { + hidden: true, + title: t('router.socialLogin'), + noTagsView: true + } + }, { path: '/403', component: () => import('@/views/Error/403.vue'), @@ -333,6 +343,7 @@ const remainingRouter: AppRouteRecordRaw[] = [ { path: '/mall/product', // 商品中心 component: Layout, + name: 'ProductCenter', meta: { hidden: true }, @@ -394,6 +405,7 @@ const remainingRouter: AppRouteRecordRaw[] = [ { path: '/mall/trade', // 交易中心 component: Layout, + name: 'TradeCenter', meta: { hidden: true }, @@ -415,7 +427,7 @@ const remainingRouter: AppRouteRecordRaw[] = [ { path: '/member', component: Layout, - name: 'member', + name: 'MemberCenter', meta: { hidden: true }, children: [ { diff --git a/src/utils/index.ts b/src/utils/index.ts index 6c9a5df2..d5301ddb 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -205,6 +205,9 @@ export const floatToFixed2 = (num: number | string | undefined): string => { case 1: str = f.toString() + '0' break + case 2: + str = f.toString() + break } return str } @@ -233,3 +236,16 @@ export const yuanToFen = (amount: string | number): number => { export const fenToYuan = (price: string | number): number => { return formatToFraction(price) } + +/** + * 计算环比 + * + * @param value 当前数值 + * @param reference 对比数值 + */ +export const calculateRelativeRate = (value?: number, reference?: number) => { + // 防止除0 + if (!reference) return 0 + + return ((100 * ((value || 0) - reference)) / reference).toFixed(0) +} diff --git a/src/utils/is.ts b/src/utils/is.ts index 37529859..eec86a93 100644 --- a/src/utils/is.ts +++ b/src/utils/is.ts @@ -19,6 +19,9 @@ export const isObject = (val: any): val is Record => { } export const isEmpty = (val: T): val is T => { + if (val === null) { + return true + } if (isArray(val) || isString(val)) { return val.length === 0 } @@ -103,3 +106,12 @@ export const isUrl = (path: string): boolean => { export const isDark = (): boolean => { return window.matchMedia('(prefers-color-scheme: dark)').matches } + +// 是否是图片链接 +export const isImgPath = (path: string): boolean => { + return /(https?:\/\/|data:image\/).*?\.(png|jpg|jpeg|gif|svg|webp|ico)/gi.test(path) +} + +export const isEmptyVal = (val: any): boolean => { + return val === '' || val === null || val === undefined +} diff --git a/src/utils/propTypes.ts b/src/utils/propTypes.ts index fb8f84e7..863f55cc 100644 --- a/src/utils/propTypes.ts +++ b/src/utils/propTypes.ts @@ -1,12 +1,10 @@ -import { createTypes, VueTypesInterface, VueTypeValidableDef } from 'vue-types' +import { VueTypeValidableDef, VueTypesInterface, createTypes, toValidableType } from 'vue-types' import { CSSProperties } from 'vue' -// 自定义扩展vue-types type PropTypes = VueTypesInterface & { readonly style: VueTypeValidableDef } - -const propTypes = createTypes({ +const newPropTypes = createTypes({ func: undefined, bool: undefined, string: undefined, @@ -15,14 +13,12 @@ const propTypes = createTypes({ integer: undefined }) as PropTypes -// 需要自定义扩展的类型 -// see: https://dwightjack.github.io/vue-types/advanced/extending-vue-types.html#the-extend-method -// propTypes.extend([ -// { -// name: 'style', -// getter: true, -// type: [String, Object], -// default: undefined -// } -// ]) +class propTypes extends newPropTypes { + static get style() { + return toValidableType('style', { + type: [String, Object] + }) + } +} + export { propTypes } diff --git a/src/utils/routerHelper.ts b/src/utils/routerHelper.ts index a6825653..d9fe42aa 100644 --- a/src/utils/routerHelper.ts +++ b/src/utils/routerHelper.ts @@ -93,7 +93,10 @@ export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecord meta.alwaysShow = true const childrenData: AppRouteRecordRaw = { path: '', - name: toCamelCase(route.path, true), + name: + route.componentName && route.componentName.length > 0 + ? route.componentName + : toCamelCase(route.path, true), redirect: route.redirect, meta: meta } diff --git a/src/views/Login/SocialLogin.vue b/src/views/Login/SocialLogin.vue new file mode 100644 index 00000000..6bbfc1df --- /dev/null +++ b/src/views/Login/SocialLogin.vue @@ -0,0 +1,343 @@ + + + + + diff --git a/src/views/Login/components/LoginForm.vue b/src/views/Login/components/LoginForm.vue index a4eb0b92..9bee2523 100644 --- a/src/views/Login/components/LoginForm.vue +++ b/src/views/Login/components/LoginForm.vue @@ -284,8 +284,13 @@ const doSocialLogin = async (type: number) => { }) } // 计算 redirectUri + // tricky: type、redirect需要先encode一次,否则钉钉回调会丢失。 + // 配合 Login/SocialLogin.vue#getUrlValue() 使用 const redirectUri = - location.origin + '/social-login?type=' + type + '&redirect=' + (redirect.value || '/') + location.origin + + '/social-login?' + + encodeURIComponent(`type=${type}&redirect=${redirect.value || '/'}`) + // 进行跳转 const res = await LoginApi.socialAuthRedirect(type, encodeURIComponent(redirectUri)) window.location.href = res diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceChildrenTaskList.vue b/src/views/bpm/processInstance/detail/ProcessInstanceChildrenTaskList.vue new file mode 100644 index 00000000..f162d1fb --- /dev/null +++ b/src/views/bpm/processInstance/detail/ProcessInstanceChildrenTaskList.vue @@ -0,0 +1,99 @@ + + diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceTaskList.vue b/src/views/bpm/processInstance/detail/ProcessInstanceTaskList.vue index 6f4557ae..97287e99 100644 --- a/src/views/bpm/processInstance/detail/ProcessInstanceTaskList.vue +++ b/src/views/bpm/processInstance/detail/ProcessInstanceTaskList.vue @@ -12,7 +12,18 @@ :icon="getTimelineItemIcon(item)" :type="getTimelineItemType(item)" > -

任务:{{ item.name }}

+

+ 任务:{{ item.name }} + + + + 子任务 + +

diff --git a/src/views/bpm/processInstance/detail/TaskAddSignDialogForm.vue b/src/views/bpm/processInstance/detail/TaskAddSignDialogForm.vue new file mode 100644 index 00000000..4b91c9b9 --- /dev/null +++ b/src/views/bpm/processInstance/detail/TaskAddSignDialogForm.vue @@ -0,0 +1,97 @@ + + diff --git a/src/views/bpm/processInstance/detail/TaskSubSignDialogForm.vue b/src/views/bpm/processInstance/detail/TaskSubSignDialogForm.vue new file mode 100644 index 00000000..61f7d68c --- /dev/null +++ b/src/views/bpm/processInstance/detail/TaskSubSignDialogForm.vue @@ -0,0 +1,85 @@ + + diff --git a/src/views/bpm/processInstance/detail/index.vue b/src/views/bpm/processInstance/detail/index.vue index 585c60db..f9c5452b 100644 --- a/src/views/bpm/processInstance/detail/index.vue +++ b/src/views/bpm/processInstance/detail/index.vue @@ -49,6 +49,10 @@ 委派 + + + 加签 + 回退 @@ -95,6 +99,8 @@ + + diff --git a/src/views/mall/home/components/MemberStatisticsCard.vue b/src/views/mall/home/components/MemberStatisticsCard.vue new file mode 100644 index 00000000..2f9d7ab5 --- /dev/null +++ b/src/views/mall/home/components/MemberStatisticsCard.vue @@ -0,0 +1,91 @@ + + diff --git a/src/views/mall/home/components/OperationDataCard.vue b/src/views/mall/home/components/OperationDataCard.vue new file mode 100644 index 00000000..b905203b --- /dev/null +++ b/src/views/mall/home/components/OperationDataCard.vue @@ -0,0 +1,92 @@ + + diff --git a/src/views/mall/home/components/ShortcutCard.vue b/src/views/mall/home/components/ShortcutCard.vue new file mode 100644 index 00000000..9fdd5cd4 --- /dev/null +++ b/src/views/mall/home/components/ShortcutCard.vue @@ -0,0 +1,79 @@ + + diff --git a/src/views/mall/home/components/TradeTrendCard.vue b/src/views/mall/home/components/TradeTrendCard.vue new file mode 100644 index 00000000..a8cab828 --- /dev/null +++ b/src/views/mall/home/components/TradeTrendCard.vue @@ -0,0 +1,208 @@ + + diff --git a/src/views/mall/home/index.vue b/src/views/mall/home/index.vue new file mode 100644 index 00000000..feaa46a9 --- /dev/null +++ b/src/views/mall/home/index.vue @@ -0,0 +1,111 @@ + + + diff --git a/src/views/mall/promotion/article/ArticleForm.vue b/src/views/mall/promotion/article/ArticleForm.vue index 2f99fa38..80248f6a 100644 --- a/src/views/mall/promotion/article/ArticleForm.vue +++ b/src/views/mall/promotion/article/ArticleForm.vue @@ -8,6 +8,11 @@ label-width="110px" > + + + + + @@ -20,11 +25,6 @@ - - - - - @@ -40,6 +40,7 @@ + @@ -58,6 +59,7 @@ + diff --git a/src/views/mall/promotion/article/category/ArticleCategoryForm.vue b/src/views/mall/promotion/article/category/ArticleCategoryForm.vue index 39b1fc0f..ac7e9f38 100644 --- a/src/views/mall/promotion/article/category/ArticleCategoryForm.vue +++ b/src/views/mall/promotion/article/category/ArticleCategoryForm.vue @@ -37,6 +37,7 @@ + diff --git a/src/views/mall/statistics/member/components/MemberTerminalCard.vue b/src/views/mall/statistics/member/components/MemberTerminalCard.vue new file mode 100644 index 00000000..7bbab76c --- /dev/null +++ b/src/views/mall/statistics/member/components/MemberTerminalCard.vue @@ -0,0 +1,69 @@ + + diff --git a/src/views/mall/statistics/member/index.vue b/src/views/mall/statistics/member/index.vue index e76e861c..2390be5e 100644 --- a/src/views/mall/statistics/member/index.vue +++ b/src/views/mall/statistics/member/index.vue @@ -2,7 +2,7 @@
- - - - - - -
-
-
-
-
- 注册用户数量:{{ analyseData?.comparison?.value?.userCount || 0 }} -
-
- 环比增长率:{{ - calculateRelativeRate( - analyseData?.comparison?.value?.userCount, - analyseData?.comparison?.reference?.userCount - ) - }}% -
-
-
-
- {{ analyseData?.visitorCount || 0 }} - 访客 -
-
-
-
-
-
- 活跃用户数量:{{ analyseData?.comparison?.value?.activeUserCount || 0 }} -
-
- 环比增长率:{{ - calculateRelativeRate( - analyseData?.comparison?.value?.activeUserCount, - analyseData?.comparison?.reference?.activeUserCount - ) - }}% -
-
-
-
- {{ analyseData?.orderUserCount || 0 }} - 下单 -
-
-
-
-
-
-
- 充值用户数量:{{ analyseData?.comparison?.value?.rechargeUserCount || 0 }} -
-
- 环比增长率:{{ - calculateRelativeRate( - analyseData?.comparison?.value?.rechargeUserCount, - analyseData?.comparison?.reference?.rechargeUserCount - ) - }}% -
-
-
-
客单价:{{ fenToYuan(analyseData?.atv || 0) }}
-
-
-
-
- {{ analyseData?.payUserCount || 0 }} - 成交用户 -
-
-
-
+ +
- - - + +
- + + @@ -180,14 +82,14 @@ /> - + + @@ -214,62 +119,33 @@
diff --git a/src/views/mall/trade/brokerage/withdraw/index.vue b/src/views/mall/trade/brokerage/withdraw/index.vue index ce4f8768..b14a7767 100644 --- a/src/views/mall/trade/brokerage/withdraw/index.vue +++ b/src/views/mall/trade/brokerage/withdraw/index.vue @@ -122,7 +122,7 @@ diff --git a/src/views/mall/trade/config/index.vue b/src/views/mall/trade/config/index.vue index 7905871b..48d04e08 100644 --- a/src/views/mall/trade/config/index.vue +++ b/src/views/mall/trade/config/index.vue @@ -16,9 +16,9 @@ + + + + + + + + + + + + + + + + + + + + 搜索 + + + + 重置 + + + + 核销 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/views/mall/trade/order/detail/index.vue b/src/views/mall/trade/order/detail/index.vue index 58939dbc..38b9342e 100644 --- a/src/views/mall/trade/order/detail/index.vue +++ b/src/views/mall/trade/order/detail/index.vue @@ -54,7 +54,7 @@
@@ -235,6 +235,7 @@ import * as DeliveryExpressApi from '@/api/mall/trade/delivery/express' import { useTagsViewStore } from '@/store/modules/tagsView' import { DeliveryTypeEnum, TradeOrderStatusEnum } from '@/utils/constants' import * as DeliveryPickUpStoreApi from '@/api/mall/trade/delivery/pickUpStore' +import { propTypes } from '@/utils/propTypes' defineOptions({ name: 'TradeOrderDetail' }) @@ -294,8 +295,12 @@ const handlePickUp = async () => { /** 获得详情 */ const { params } = useRoute() // 查询参数 +const props = defineProps({ + id: propTypes.number.def(undefined), // 订单ID + showPickUp: propTypes.bool.def(true) // 显示核销按钮 +}) +const id = (params.id || props.id) as unknown as number const getDetail = async () => { - const id = params.id as unknown as number if (id) { const res = (await TradeOrderApi.getOrder(id)) as TradeOrderApi.OrderVO // 没有表单信息则关闭页面返回 @@ -395,27 +400,27 @@ onMounted(async () => { background-color: #f7f8fa; &::before { - content: ''; /* 必须设置 content 属性 */ position: absolute; top: 10px; left: 13px; /* 将伪元素水平居中 */ - border-width: 8px; /* 调整尖角大小 */ - border-style: solid; border-color: transparent #f7f8fa transparent transparent; /* 尖角颜色,左侧朝向 */ + border-style: solid; + border-width: 8px; /* 调整尖角大小 */ + content: ''; /* 必须设置 content 属性 */ } } .dot-node-style { - width: 20px; - height: 20px; position: absolute; left: -5px; display: flex; + width: 20px; + height: 20px; + font-size: 10px; + color: #fff; + border-radius: 50%; justify-content: center; align-items: center; - border-radius: 50%; - color: #fff; - font-size: 10px; } } diff --git a/src/views/mall/trade/order/form/OrderPickUpForm.vue b/src/views/mall/trade/order/form/OrderPickUpForm.vue new file mode 100644 index 00000000..529263c4 --- /dev/null +++ b/src/views/mall/trade/order/form/OrderPickUpForm.vue @@ -0,0 +1,108 @@ + + diff --git a/src/views/mall/trade/order/index.vue b/src/views/mall/trade/order/index.vue index 94cd8c17..e08715df 100644 --- a/src/views/mall/trade/order/index.vue +++ b/src/views/mall/trade/order/index.vue @@ -128,6 +128,7 @@ class="!w-280px" clearable placeholder="请输入" + :type="queryType.queryParam === 'userId' ? 'number' : 'text'" >