From 4f65156a9579f8e13f0b010b126c60f6baeacea1 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 25 Aug 2025 09:42:18 +0800 Subject: [PATCH 001/170] =?UTF-8?q?fix:=20[BPM=20=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=B5=81]=20=E6=B5=81=E7=A8=8B=E8=A1=A8=E5=8D=95=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E8=A7=A3=E6=9E=90=E8=B0=83=E6=95=B4=E4=B8=BA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=BA=93=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/utils/formCreate.ts | 7 ++++--- .../views/bpm/processInstance/create/modules/form.vue | 9 +++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/apps/web-antd/src/utils/formCreate.ts b/apps/web-antd/src/utils/formCreate.ts index a653a44bb..070b394ad 100644 --- a/apps/web-antd/src/utils/formCreate.ts +++ b/apps/web-antd/src/utils/formCreate.ts @@ -4,6 +4,7 @@ // TODO @芋艿:后续这些 form-create 的优化;另外需要使用 form-create-helper 会好点 import { isRef } from 'vue'; +import formCreate from '@form-create/ant-design-vue'; // 编码表单 Conf export const encodeConf = (designerRef: any) => { return JSON.stringify(designerRef.value.getOption()); @@ -23,7 +24,7 @@ export const encodeFields = (designerRef: any) => { export const decodeFields = (fields: string[]) => { const rule: object[] = []; fields.forEach((item) => { - rule.push(JSON.parse(item)); + rule.push(formCreate.parseJson(item)); }); return rule; }; @@ -34,7 +35,7 @@ export const setConfAndFields = ( conf: string, fields: string | string[], ) => { - designerRef.value.setOption(JSON.parse(conf)); + designerRef.value.setOption(formCreate.parseJson(conf)); // 处理 fields 参数类型,确保传入 decodeFields 的是 string[] 类型 const fieldsArray = Array.isArray(fields) ? fields : [fields]; designerRef.value.setRule(decodeFields(fieldsArray)); @@ -50,7 +51,7 @@ export const setConfAndFields2 = ( if (isRef(detailPreview)) { detailPreview = detailPreview.value; } - detailPreview.option = JSON.parse(conf); + detailPreview.option = formCreate.parseJson(conf); detailPreview.rule = decodeFields(fields); if (value) { detailPreview.value = value; diff --git a/apps/web-antd/src/views/bpm/processInstance/create/modules/form.vue b/apps/web-antd/src/views/bpm/processInstance/create/modules/form.vue index b91202d1c..29474006e 100644 --- a/apps/web-antd/src/views/bpm/processInstance/create/modules/form.vue +++ b/apps/web-antd/src/views/bpm/processInstance/create/modules/form.vue @@ -7,6 +7,7 @@ import { computed, nextTick, ref, watch } from 'vue'; import { useTabs } from '@vben/hooks'; import { IconifyIcon } from '@vben/icons'; +import formCreate from '@form-create/ant-design-vue'; import { Button, Card, Col, message, Row, Space, Tabs } from 'ant-design-vue'; import { getProcessDefinition } from '#/api/bpm/definition'; @@ -126,11 +127,11 @@ async function initProcessInfo(row: any, formVariables?: any) { // 注意:需要从 formVariables 中,移除不在 row.formFields 的值。 // 原因是:后端返回的 formVariables 里面,会有一些非表单的信息。例如说,某个流程节点的审批人。 // 这样,就可能导致一个流程被审批不通过后,重新发起时,会直接后端报错!!! - const allowedFields = new Set( - decodeFields(row.formFields).map((fieldObj: any) => fieldObj.field), - ); + const formApi = formCreate.create(decodeFields(row.formFields)); + const allowedFields = formApi.fields(); + console.error('allowedFields===>', allowedFields); for (const key in formVariables) { - if (!allowedFields.has(key)) { + if (!allowedFields.includes(key)) { delete formVariables[key]; } } -- Gitee From e43bb989b353806da0b2c6681e275c5b54fbfea3 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 25 Aug 2025 10:17:19 +0800 Subject: [PATCH 002/170] =?UTF-8?q?fix:=20=E5=8E=BB=E6=8E=89=20console=20?= =?UTF-8?q?=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/bpm/processInstance/create/modules/form.vue | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/web-antd/src/views/bpm/processInstance/create/modules/form.vue b/apps/web-antd/src/views/bpm/processInstance/create/modules/form.vue index b818ebf63..43a331aca 100644 --- a/apps/web-antd/src/views/bpm/processInstance/create/modules/form.vue +++ b/apps/web-antd/src/views/bpm/processInstance/create/modules/form.vue @@ -52,7 +52,7 @@ const props = defineProps({ const emit = defineEmits(['cancel']); // 增加表单就绪状态变量 表单就绪后再渲染form-create -const isFormReady = ref(false) +const isFormReady = ref(false); const { closeCurrentTab } = useTabs(); @@ -132,7 +132,6 @@ async function initProcessInfo(row: any, formVariables?: any) { // 这样,就可能导致一个流程被审批不通过后,重新发起时,会直接后端报错!!! const formApi = formCreate.create(decodeFields(row.formFields)); const allowedFields = formApi.fields(); - console.error('allowedFields===>', allowedFields); for (const key in formVariables) { if (!allowedFields.includes(key)) { delete formVariables[key]; @@ -141,7 +140,7 @@ async function initProcessInfo(row: any, formVariables?: any) { setConfAndFields2(detailForm, row.formConf, row.formFields, formVariables); // 设置表单就绪状态 - isFormReady.value = true + isFormReady.value = true; await nextTick(); fApi.value?.btn.show(false); // 隐藏提交按钮 -- Gitee From 705b16b0d1d22b32586c2d4e37a85706b90f5987 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Mon, 20 Oct 2025 11:35:12 +0800 Subject: [PATCH 003/170] fix: sort --- packages/effects/common-ui/src/components/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/effects/common-ui/src/components/index.ts b/packages/effects/common-ui/src/components/index.ts index efba68250..c9a354bab 100644 --- a/packages/effects/common-ui/src/components/index.ts +++ b/packages/effects/common-ui/src/components/index.ts @@ -4,7 +4,6 @@ export * from './col-page'; export * from './content-wrap'; export * from './count-to'; export * from './doc-alert'; -export * from './summary-card'; export * from './ellipsis-text'; export * from './icon-picker'; export * from './iframe'; @@ -12,6 +11,7 @@ export * from './json-viewer'; export * from './loading'; export * from './page'; export * from './resize'; +export * from './summary-card'; export * from './tippy'; export * from './tree'; export * from '@vben-core/form-ui'; -- Gitee From 49b2b40210e964806ab1297a3da24c7162a8f82c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 20 Oct 2025 13:08:56 +0800 Subject: [PATCH 004/170] =?UTF-8?q?feat=EF=BC=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/mall/statistics/trade/index.vue | 25 +++--- .../trade/modules/trade-statistic-card.vue | 77 ------------------- .../trade/modules/trade-trend-card.vue | 4 +- .../effects/common-ui/src/components/index.ts | 1 + .../src/components/statistic-card/index.ts | 4 + .../statistic-card/statistic-card.vue | 71 +++++++++++++++++ .../src/components/statistic-card/types.ts | 17 ++++ 7 files changed, 107 insertions(+), 92 deletions(-) delete mode 100644 apps/web-antd/src/views/mall/statistics/trade/modules/trade-statistic-card.vue create mode 100644 packages/effects/common-ui/src/components/statistic-card/index.ts create mode 100644 packages/effects/common-ui/src/components/statistic-card/statistic-card.vue create mode 100644 packages/effects/common-ui/src/components/statistic-card/types.ts diff --git a/apps/web-antd/src/views/mall/statistics/trade/index.vue b/apps/web-antd/src/views/mall/statistics/trade/index.vue index d2261fe71..dd3a70b88 100644 --- a/apps/web-antd/src/views/mall/statistics/trade/index.vue +++ b/apps/web-antd/src/views/mall/statistics/trade/index.vue @@ -4,14 +4,13 @@ import type { MallTradeStatisticsApi } from '#/api/mall/statistics/trade'; import { onMounted, ref } from 'vue'; -import { DocAlert, Page } from '@vben/common-ui'; +import { DocAlert, Page, StatisticCard } from '@vben/common-ui'; import { fenToYuan } from '@vben/utils'; import { Col, Row } from 'ant-design-vue'; import * as TradeStatisticsApi from '#/api/mall/statistics/trade'; -import TradeStatisticCard from './modules/trade-statistic-card.vue'; import TradeTrendCard from './modules/trade-trend-card.vue'; /** 交易统计 */ @@ -22,17 +21,19 @@ const summary = ref>(); // 交易统计数据 /** 计算环比百分比 */ -const calculateRelativeRate = (value?: number, reference?: number): string => { +function calculateRelativeRate(value?: number, reference?: number): string { const refValue = Number(reference || 0); const curValue = Number(value || 0); - if (!refValue || refValue === 0) return '0.00'; + if (!refValue || refValue === 0) { + return '0.00'; + } return (((curValue - refValue) / refValue) * 100).toFixed(2); -}; +} /** 查询交易统计 */ -const getTradeStatisticsSummary = async () => { +async function getTradeStatisticsSummary() { summary.value = await TradeStatisticsApi.getTradeStatisticsSummary(); -}; +} /** 初始化 */ onMounted(async () => { @@ -51,11 +52,11 @@ onMounted(async () => { /> +
- - { /> - { /> - { /> - -import { computed } from 'vue'; - -import { VbenCountToAnimator } from '@vben/common-ui'; -import { IconifyIcon } from '@vben/icons'; - -import { Card, Tooltip } from 'ant-design-vue'; - -/** 交易统计值组件 */ -defineOptions({ name: 'TradeStatisticCard' }); - -const props = withDefaults(defineProps(), { - tooltip: '', - title: '', - prefix: '', - value: 0, - decimals: 0, - percent: 0, -}); - -interface Props { - tooltip?: string; - title?: string; - prefix?: string; - value?: number | string; - decimals?: number; - percent?: number | string; -} - -/** 计算环比百分比 */ -const percentValue = computed(() => { - return Number(props.percent); -}); - -/** 格式化数值 */ -const formattedValue = computed(() => { - return Number(props.value); -}); - - - diff --git a/apps/web-antd/src/views/mall/statistics/trade/modules/trade-trend-card.vue b/apps/web-antd/src/views/mall/statistics/trade/modules/trade-trend-card.vue index 113ceabfc..572a46176 100644 --- a/apps/web-antd/src/views/mall/statistics/trade/modules/trade-trend-card.vue +++ b/apps/web-antd/src/views/mall/statistics/trade/modules/trade-trend-card.vue @@ -103,6 +103,7 @@ const getTradeStatisticsList = async (times?: [Dayjs, Dayjs]) => { await renderEcharts(getTradeTrendChartOptions(processedList)); }; +// TODO @AI:导出 /** 导出按钮操作 */ const handleExport = async () => { try { @@ -222,7 +223,6 @@ onMounted(async () => { " /> - { " /> - { " /> - +import type { StatisticCardProps } from './types'; + +import { + Card, + CardContent, + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, + VbenCountToAnimator, + VbenIcon, +} from '@vben-core/shadcn-ui'; + +/** 统计卡片 */ +defineOptions({ name: 'StatisticCard' }); + +withDefaults(defineProps(), { + percentLabel: '环比', +}); + + + + diff --git a/packages/effects/common-ui/src/components/statistic-card/types.ts b/packages/effects/common-ui/src/components/statistic-card/types.ts new file mode 100644 index 000000000..2fe168151 --- /dev/null +++ b/packages/effects/common-ui/src/components/statistic-card/types.ts @@ -0,0 +1,17 @@ +export interface StatisticCardProps { + /** 标题 */ + title: string; + /** 提示信息 */ + tooltip?: string; + /** 前缀 */ + prefix?: string; + /** 数值 */ + value?: number; + /** 小数位数 */ + decimals?: number; + /** 环比百分比 */ + percent?: number | string; + /** 环比标签文本 */ + percentLabel?: string; +} + -- Gitee From 7ed34921bcc744cf53232b2e3dd0ede3f7ee6170 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 20 Oct 2025 13:16:41 +0800 Subject: [PATCH 005/170] =?UTF-8?q?feat=EF=BC=9A=E3=80=90mall=20=E5=95=86?= =?UTF-8?q?=E5=9F=8E=E3=80=91=E4=BA=A4=E6=98=93=E7=BB=9F=E8=AE=A1=E3=80=90?= =?UTF-8?q?antd=E3=80=9130%=EF=BC=9A=E4=BC=98=E5=8C=96=20trend-card.vue=20?= =?UTF-8?q?=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/mall/statistics/trade/index.vue | 2 +- .../{trade-trend-card.vue => trend-card.vue} | 141 ++++++++---------- ...hart-options.ts => trend-chart-options.ts} | 4 + 3 files changed, 64 insertions(+), 83 deletions(-) rename apps/web-antd/src/views/mall/statistics/trade/modules/{trade-trend-card.vue => trend-card.vue} (73%) rename apps/web-antd/src/views/mall/statistics/trade/modules/{trade-trend-chart-options.ts => trend-chart-options.ts} (97%) diff --git a/apps/web-antd/src/views/mall/statistics/trade/index.vue b/apps/web-antd/src/views/mall/statistics/trade/index.vue index dd3a70b88..8cc2aa71c 100644 --- a/apps/web-antd/src/views/mall/statistics/trade/index.vue +++ b/apps/web-antd/src/views/mall/statistics/trade/index.vue @@ -11,7 +11,7 @@ import { Col, Row } from 'ant-design-vue'; import * as TradeStatisticsApi from '#/api/mall/statistics/trade'; -import TradeTrendCard from './modules/trade-trend-card.vue'; +import TradeTrendCard from './modules/trend-card.vue'; /** 交易统计 */ defineOptions({ name: 'TradeStatistics' }); diff --git a/apps/web-antd/src/views/mall/statistics/trade/modules/trade-trend-card.vue b/apps/web-antd/src/views/mall/statistics/trade/modules/trend-card.vue similarity index 73% rename from apps/web-antd/src/views/mall/statistics/trade/modules/trade-trend-card.vue rename to apps/web-antd/src/views/mall/statistics/trade/modules/trend-card.vue index 572a46176..03427f85c 100644 --- a/apps/web-antd/src/views/mall/statistics/trade/modules/trade-trend-card.vue +++ b/apps/web-antd/src/views/mall/statistics/trade/modules/trend-card.vue @@ -6,20 +6,25 @@ import type { EchartsUIType } from '@vben/plugins/echarts'; import type { DataComparisonRespVO } from '#/api/mall/statistics/common'; import type { MallTradeStatisticsApi } from '#/api/mall/statistics/trade'; -import { onMounted, ref } from 'vue'; +import { ref } from 'vue'; -import { SummaryCard } from '@vben/common-ui'; +import { confirm, SummaryCard } from '@vben/common-ui'; import { IconifyIcon } from '@vben/icons'; import { EchartsUI, useEcharts } from '@vben/plugins/echarts'; -import { fenToYuan } from '@vben/utils'; +import { + downloadFileFromBlobPart, + fenToYuan, + formatDateTime, + isSameDay, +} from '@vben/utils'; -import { Button, Card, Col, message, Row, Skeleton } from 'ant-design-vue'; +import { Button, Card, Col, Row, Spin } from 'ant-design-vue'; import dayjs from 'dayjs'; import * as TradeStatisticsApi from '#/api/mall/statistics/trade'; import ShortcutDateRangePicker from '#/components/shortcut-date-range-picker/shortcut-date-range-picker.vue'; -import { getTradeTrendChartOptions } from './trade-trend-chart-options'; +import { getTradeTrendChartOptions } from './trend-chart-options'; /** 交易趋势 */ defineOptions({ name: 'TradeTrendCard' }); @@ -28,7 +33,7 @@ const trendLoading = ref(true); // 交易状态加载中 const exportLoading = ref(false); // 导出的加载中 const trendSummary = ref>(); // 交易状况统计数据 -const shortcutDateRangePicker = ref(); +const searchTimes = ref([]); const chartRef = ref(); const { renderEcharts } = useEcharts(chartRef); @@ -37,58 +42,54 @@ const { renderEcharts } = useEcharts(chartRef); const calculateRelativeRate = (value?: number, reference?: number): string => { const refValue = Number(reference || 0); const curValue = Number(value || 0); - if (!refValue || refValue === 0) return '0.00'; + if (!refValue || refValue === 0) { + return '0.00'; + } return (((curValue - refValue) / refValue) * 100).toFixed(2); }; +/** 处理日期范围变化 */ +const handleDateRangeChange = (times?: [Dayjs, Dayjs]) => { + if (times?.length !== 2) { + getTradeTrendData(); + return; + } + // 处理时间: 开始与截止在同一天的, 折线图出不来, 需要延长一天 + let adjustedTimes = times; + if (isSameDay(times[0], times[1])) { + adjustedTimes = [dayjs(times[0]).subtract(1, 'd'), times[1]]; + } + searchTimes.value = [ + formatDateTime(adjustedTimes[0]) as string, + formatDateTime(adjustedTimes[1]) as string, + ]; + + // 查询数据 + getTradeTrendData(); +}; + /** 处理交易状况查询 */ -const getTradeTrendData = async (times?: [Dayjs, Dayjs]) => { +async function getTradeTrendData() { trendLoading.value = true; try { - let queryTimes = times; - if (!queryTimes && shortcutDateRangePicker.value?.times) { - queryTimes = shortcutDateRangePicker.value.times; - } - - // 1. 处理时间: 开始与截止在同一天的, 折线图出不来, 需要延长一天 - if (queryTimes && isSameDay(queryTimes[0], queryTimes[1])) { - // 前天 - queryTimes[0] = dayjs(queryTimes[0]).subtract(1, 'd'); - } - - // 查询数据 - await Promise.all([ - getTradeStatisticsAnalyse(queryTimes), - getTradeStatisticsList(queryTimes), - ]); + await Promise.all([getTradeStatisticsAnalyse(), getTradeStatisticsList()]); } finally { trendLoading.value = false; } -}; - -/** 判断是否同一天 */ -const isSameDay = (date1: Dayjs, date2: Dayjs): boolean => { - return date1.format('YYYY-MM-DD') === date2.format('YYYY-MM-DD'); -}; +} /** 查询交易状况数据统计 */ -const getTradeStatisticsAnalyse = async (times?: [Dayjs, Dayjs]) => { - const queryTimes = times - ? { times: [times[0].toDate(), times[1].toDate()] } - : undefined; - trendSummary.value = await TradeStatisticsApi.getTradeStatisticsAnalyse( - queryTimes as any, - ); -}; +async function getTradeStatisticsAnalyse() { + trendSummary.value = await TradeStatisticsApi.getTradeStatisticsAnalyse({ + times: searchTimes.value.length > 0 ? searchTimes.value : undefined, + }); +} /** 查询交易状况数据列表 */ -const getTradeStatisticsList = async (times?: [Dayjs, Dayjs]) => { - // 查询数据 - const queryTimes = times - ? { times: [times[0].toDate(), times[1].toDate()] } - : undefined; - const list: MallTradeStatisticsApi.TradeTrendSummary[] = - await TradeStatisticsApi.getTradeStatisticsList(queryTimes as any); +async function getTradeStatisticsList() { + const list = await TradeStatisticsApi.getTradeStatisticsList({ + times: searchTimes.value.length > 0 ? searchTimes.value : undefined, + }); // 处理数据 const processedList = list.map((item) => ({ @@ -99,51 +100,30 @@ const getTradeStatisticsList = async (times?: [Dayjs, Dayjs]) => { expensePrice: Number(fenToYuan(item.expensePrice)), })); - // 更新 Echarts 数据 + // 渲染图表 await renderEcharts(getTradeTrendChartOptions(processedList)); -}; +} -// TODO @AI:导出 /** 导出按钮操作 */ -const handleExport = async () => { +async function handleExport() { try { // 导出的二次确认 - await message.confirm({ + await confirm({ content: '确认导出交易状况数据吗?', - okText: '确定', - cancelText: '取消', }); // 发起导出 exportLoading.value = true; - const times = shortcutDateRangePicker.value?.times; - const queryTimes = times - ? { times: [times[0].toDate(), times[1].toDate()] } - : undefined; - const data = await TradeStatisticsApi.exportTradeStatisticsExcel( - queryTimes as any, - ); - - // 处理下载 - const blob = new Blob([data], { - type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + const data = await TradeStatisticsApi.exportTradeStatisticsExcel({ + times: searchTimes.value.length > 0 ? searchTimes.value : undefined, }); - const url = window.URL.createObjectURL(blob); - const link = document.createElement('a'); - link.href = url; - link.download = '交易状况.xlsx'; - link.click(); - window.URL.revokeObjectURL(url); + // 处理下载 + downloadFileFromBlobPart({ fileName: '交易状况.xlsx', source: data }); } catch { // 用户取消导出 } finally { exportLoading.value = false; } -}; - -/** 初始化 */ -onMounted(async () => { - await getTradeTrendData(); -}); +}