From c92f531f1bcf2528aaf359c969ad69a1abdc01b2 Mon Sep 17 00:00:00 2001 From: yys <47@gamerwa.com> Date: Fri, 17 Apr 2026 17:47:25 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E9=83=A8=E9=97=A8=E4=BD=99?= =?UTF-8?q?=E9=A2=9D=E5=8F=98=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin-ui/src/api/ai/dept.js | 8 + admin-ui/src/api/system/dept.js | 9 + admin-ui/src/utils/westernNumberFormat.js | 76 ++++++++ admin-ui/src/views/system/dept/index.vue | 184 +++++++++++++++++- .../web/controller/ai/AiDeptController.java | 4 +- .../controller/system/SysDeptController.java | 19 ++ .../system/DeptChargeRefundRequest.java | 47 +++++ .../ai/service/IDeptChargeRefundService.java | 16 ++ .../impl/DeptChargeRefundServiceImpl.java | 122 ++++++++++++ .../ruoyi/system/mapper/SysDeptMapper.java | 18 ++ .../ruoyi/system/service/ISysDeptService.java | 15 ++ .../service/impl/SysDeptServiceImpl.java | 15 ++ .../resources/mapper/system/SysDeptMapper.xml | 16 ++ 13 files changed, 544 insertions(+), 5 deletions(-) create mode 100644 admin-ui/src/utils/westernNumberFormat.js create mode 100644 web-api/ruoyi-common/src/main/java/com/ruoyi/common/core/request/system/DeptChargeRefundRequest.java create mode 100644 web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/IDeptChargeRefundService.java create mode 100644 web-api/ruoyi-system/src/main/java/com/ruoyi/ai/service/impl/DeptChargeRefundServiceImpl.java diff --git a/admin-ui/src/api/ai/dept.js b/admin-ui/src/api/ai/dept.js index 415856b..c8a3b98 100644 --- a/admin-ui/src/api/ai/dept.js +++ b/admin-ui/src/api/ai/dept.js @@ -44,3 +44,11 @@ export function delDept(deptId) { method: 'delete' }) } + +export function chargeRefundDept(data) { + return request({ + url: '/ai/dept/charge-refund', + method: 'post', + data: data + }) +} diff --git a/admin-ui/src/api/system/dept.js b/admin-ui/src/api/system/dept.js index fc943cd..1bed996 100644 --- a/admin-ui/src/api/system/dept.js +++ b/admin-ui/src/api/system/dept.js @@ -49,4 +49,13 @@ export function delDept(deptId) { url: '/system/dept/' + deptId, method: 'delete' }) +} + +// 部门充值/退款 +export function chargeRefundDept(data) { + return request({ + url: '/system/dept/charge-refund', + method: 'post', + data: data + }) } \ No newline at end of file diff --git a/admin-ui/src/utils/westernNumberFormat.js b/admin-ui/src/utils/westernNumberFormat.js new file mode 100644 index 0000000..fd216df --- /dev/null +++ b/admin-ui/src/utils/westernNumberFormat.js @@ -0,0 +1,76 @@ +/** + * 西式千分位(en-US):金额最多两位小数,积分为整数。 + * 用于输入/粘贴后即时格式化展示。 + */ + +export const WESTERN_MONEY_MAX = 10000000 +export const WESTERN_INT_MAX = 100000000 + +const MONEY_MAX = WESTERN_MONEY_MAX +const INT_MAX = WESTERN_INT_MAX + +/** 只保留数字与至多一个小数点,小数位最多 2 位 */ +export function sanitizeMoneyDigits(raw) { + let s = String(raw == null ? '' : raw).replace(/,/g, '').replace(/[^\d.]/g, '') + const firstDot = s.indexOf('.') + if (firstDot !== -1) { + s = s.slice(0, firstDot + 1) + s.slice(firstDot + 1).replace(/\./g, '').slice(0, 2) + } + return s +} + +/** 将规范化后的金额字符串格式化为 9,999,999.99 形式(输入过程中允许末尾为小数点) */ +export function formatMoneyWesternDisplay(sanitized) { + if (!sanitized) return '' + const s = sanitized + const dot = s.indexOf('.') + const intRaw = dot === -1 ? s : s.slice(0, dot) + const decRaw = dot === -1 ? '' : s.slice(dot + 1).slice(0, 2) + const intNum = intRaw === '' ? 0 : parseInt(intRaw, 10) + const intFmt = (isNaN(intNum) ? 0 : intNum).toLocaleString('en-US') + if (dot === -1) return intFmt + if (s.endsWith('.') && decRaw === '') return intFmt + '.' + return intFmt + '.' + decRaw +} + +/** 规范化字符串 -> 金额数值(undefined 表示空) */ +export function moneyStringToNumber(sanitized) { + if (sanitized === '' || sanitized === '.' || sanitized == null) return undefined + const n = parseFloat(sanitized) + if (isNaN(n)) return undefined + const rounded = Math.round(n * 100) / 100 + if (rounded > MONEY_MAX) return MONEY_MAX + if (rounded < 0) return 0 + return rounded +} + +/** 失焦时金额固定两位小数展示 */ +export function formatMoneyWesternFinal(n) { + if (n === undefined || n === null || isNaN(n)) return '' + const v = Math.min(MONEY_MAX, Math.max(0, Math.round(Number(n) * 100) / 100)) + return v.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) +} + +/** 积分:仅数字,并限制范围 */ +export function sanitizeIntDigits(raw) { + let d = String(raw == null ? '' : raw).replace(/,/g, '').replace(/\D/g, '') + if (d === '') return '' + let n = parseInt(d, 10) + if (isNaN(n)) return '' + n = Math.min(INT_MAX, Math.max(0, n)) + return String(n) +} + +export function formatIntWesternDisplay(digits) { + if (!digits) return '' + const n = parseInt(digits, 10) + if (isNaN(n)) return '' + return n.toLocaleString('en-US') +} + +export function intStringToNumber(digits) { + if (!digits) return undefined + const n = parseInt(digits, 10) + if (isNaN(n)) return undefined + return n +} diff --git a/admin-ui/src/views/system/dept/index.vue b/admin-ui/src/views/system/dept/index.vue index b28b1c5..383c677 100644 --- a/admin-ui/src/views/system/dept/index.vue +++ b/admin-ui/src/views/system/dept/index.vue @@ -57,19 +57,31 @@ :tree-props="{children: 'children', hasChildren: 'hasChildren'}" > - + + + + - + @@ -244,7 +304,17 @@