diff --git a/.workbuddy/memory/2026-09-09.md b/.workbuddy/memory/2026-09-09.md index 419ea76..5ab529a 100644 --- a/.workbuddy/memory/2026-09-09.md +++ b/.workbuddy/memory/2026-09-09.md @@ -1,4 +1,8 @@ +## 付款比例设置提示改为 tooltip(contract-manage / contract-manage-change) +- 需求:将「付款比例设置」区块原有的红色文字提示改为标题右侧的 `?` 图标悬停提示。 +- 改动:编辑弹窗、详情弹窗、合同变更页三处标题后添加 `el-tooltip` + `el-icon-question-filled`,content 为「非必填;配置付款比例时,合计必须等于100%。」;同时移除 contract-manage.vue 中原 `.contract-manage-form__tip` 红色提示文字及对应样式。 + ## 必填星号与 label 首行齐平(全局) - 根因:`element-ui.scss` 中 `.el-form-item--label-right .el-form-item__label { align-items:center }` 使 inline-flex label 的星号 `::before`(独立 flex 子项)在多行折行时被垂直居中。 - 修复:label 改 `align-self:center`(整体仍随行垂直居中)+ `align-items:flex-start`(星号/文字首行齐平),覆盖 label-right/left/top 三种位置;旧 inline-block 注释已修正。 @@ -37,3 +41,17 @@ - 修复:新增 `.el-dialog__title:not(:empty)::before { width:4px; height:16px; border-radius:2px; background:var(--el-color-primary) }`。 - 注意:必须加 `:not(:empty)`,否则无标题弹窗会出现孤立蓝条。 - customer-archive.vue 评分详情弹窗:将「临时额度申请使用期限」区间行(span=12 + 至 连接)拆分为两个 span=6 独立字段「临时申请额度有效期起 / 止」,字段名 tempCreditStartDate/End 不变,删除废弃样式 .score-detail-form__range。 +- temporary-credit-limit 文案调整:option 增加 addTitle/editTitle/viewTitle=「新增/编辑/查看临时额度申请」(覆盖 crud-dialog-title mixin 按菜单名注入的「临时额度管理」);remark label 改「临时额度信息」(hide:true 无表格副作用,rules 同步);projectName 表单 label 用 `#projectName-label` 插槽改「项目额度信息」,列 label 保持「项目名称」不动表格列头/搜索。Avue 支持-{prop}-label / -header / -search 插槽分离表单/表头/搜索文案。 +- temporary-credit-limit「申请有效期至」增加「必须晚于当前日期」校验:common.js 新增通用 `futureDateRule(label)`(trigger: ['change','blur'],空值/非法值放行,按 0 点比较,当天也算过期),temporary-credit-limit.js 的 validUntil rules 追加该规则。已验证 Element Plus 通用 picker 在选中日期时调用 formItem.validate('change'),故选择即刻提示;form.validate() 不带 trigger 时会跑全部规则,提交仍拦截。 +- temporary-credit-limit 搜索占位文案统一:createCrudOption(withSearchPlaceholders([...])),搜索栏 placeholder 变为「请输入/请选择」不带字段名,与 waybill-manage / transport-plan / shipping-template 同一模式。 +- temporary-credit-limit 弹窗表单 placeholder 统一为「请输入/请选择」不带字段名:option 各列加 placeholder(projectCode/undertakeDeptName/projectFundLimit/usedFundLimit/remainingFundLimit/remark=请输入,validUntil=请选择),视图 formslot 自定义控件(projectName select、applyLimit input)placeholder 同步改。 + +## 【项目管理】列表增加「项目资金使用预警」(project-apply) +- 需求:列表新增「资金使用风险」列,高风险红色、中风险黄色;列表头部增加「资金使用风险」快速筛选标签(高风险(数)/中风险(数)),点击筛选。规则 tooltip:中风险≥80%、高风险≥90%,使用率=已使用资金/项目资金使用额度×100%。 +- 前端(已落地,src/views/business/project-apply.vue + src/option/business/project-apply.js + src/api/business/project-apply.js): + - option/project-apply.js 新增列 `fundUseRisk`(slot:true, hide 列表显示) + 导出 `fundUseRiskOptions`(high/medium/none) 与 `fundUseRiskThreshold`{high:90, medium:80}。 + - view 新增 `#header` 插槽:`el-check-tag` 快速筛选(复用 contract-manage 到期标签交互),带数量(fundRiskStats[statKey])与 `?` tooltip 规则;新增 `#fundUseRisk` 插槽渲染彩色 `el-tag`(high→type=danger 红,medium→type=warning 黄,无→"-")。 + - data 加 fundRiskScope/fundRiskStats{high,medium,none}/fundRiskTagOptions;onLoad 追加 `fundUseRisk` 筛选参数 + 成功后 refreshFundRiskStats;新增 changeFundRiskScope(再次点击取消)、refreshFundRiskStats;searchReset 清空风险筛选。 + - api 新增 `getFundRiskStats` → GET /blade-transport/project-apply/fund-risk-stats。 +- 后端契约(未改,待确认数据来源):ProjectApplyVO 补齐 `fundUseRisk`(high/medium/none)、`fundUseRiskName`、`fundUseRate`、`usedFundLimit`/`remainingFundLimit`;列表 selectProjectApplyPage 填充每行风险 + buildQuery 支持 `fundUseRisk` 过滤;新增 `/fund-risk-stats` 返回 {high,medium,none}。 +- ⚠️ 关键阻塞:系统里项目与任何费用表(运输计划/运单/账单/客商)均无关联字段,`usedFundLimit`(已使用资金) 无真实取数来源;临时额度模块的 project-apply/list 返回里 usedFundLimit 实际为空。需业务方确认「已使用资金」口径后才能算风险等级,否则列表风险列全空、统计为 0。 diff --git a/src/api/business/project-apply.js b/src/api/business/project-apply.js index a08c3ea..cf95c97 100644 --- a/src/api/business/project-apply.js +++ b/src/api/business/project-apply.js @@ -9,6 +9,14 @@ export const getDetail = api.getDetail; export const submit = api.submit; export const remove = api.remove; +// 项目资金使用风险统计(高风险 / 中风险数量),供列表头部快速筛选标签使用 +export const getFundRiskStats = params => + request({ + url: `${baseUrl}/fund-risk-stats`, + method: 'get', + params, + }); + export const saveDraft = row => request({ url: `${baseUrl}/save-draft`, diff --git a/src/option/business/common.js b/src/option/business/common.js index 9b15eac..b418ada 100644 --- a/src/option/business/common.js +++ b/src/option/business/common.js @@ -169,6 +169,32 @@ export const nonNegativeRule = label => ({ trigger: 'blur', }); +// 日期必须晚于当前日期(当天不可选):选择后立即校验,trigger 固定为 change +// 取值支持 YYYY-MM-DD / YYYY-MM-DD HH:mm:ss / 时间戳 +export const futureDateRule = label => ({ + validator: (rule, value, callback) => { + if (value === undefined || value === null || value === '') { + callback(); + return; + } + const raw = String(value).trim().replace(/-/g, '/'); + const selected = new Date(raw); + if (Number.isNaN(selected.getTime())) { + callback(); + return; + } + const today = new Date(); + today.setHours(0, 0, 0, 0); + selected.setHours(0, 0, 0, 0); + if (selected.getTime() <= today.getTime()) { + callback(new Error(`${label}必须晚于当前日期`)); + return; + } + callback(); + }, + trigger: ['change', 'blur'], +}); + export const phoneRule = label => ({ pattern: /^1[3-9]\d{9}$/, message: `${label}格式不正确`, diff --git a/src/option/business/project-apply.js b/src/option/business/project-apply.js index c0aacec..f4cfa61 100644 --- a/src/option/business/project-apply.js +++ b/src/option/business/project-apply.js @@ -16,6 +16,18 @@ const projectEffectiveTypeOptions = [ { label: '正式', value: 'formal' }, ]; +export const fundUseRiskOptions = [ + { label: '高风险', value: 'high' }, + { label: '中风险', value: 'medium' }, + { label: '正常', value: 'none' }, +]; + +// 项目资金额度使用率阈值:中风险 ≥ 80%,高风险 ≥ 90% +export const fundUseRiskThreshold = { + high: 90, + medium: 80, +}; + const amountRules = label => [ { required: true, message: `请输入${label}`, trigger: 'blur' }, nonNegativeRule(label), @@ -402,5 +414,14 @@ export const option = createCrudOption([ span: 24, hide: true, }, + { + label: '资金使用风险', + prop: 'fundUseRisk', + slot: true, + minWidth: 130, + addDisplay: false, + editDisplay: false, + hide: false, + }, ...auditColumns.map(column => ({ ...column, hide: true })), ]); diff --git a/src/option/business/temporary-credit-limit.js b/src/option/business/temporary-credit-limit.js index 4e8befd..ac9692b 100644 --- a/src/option/business/temporary-credit-limit.js +++ b/src/option/business/temporary-credit-limit.js @@ -2,8 +2,10 @@ import { approvalStatusOptions, auditColumns, createCrudOption, + futureDateRule, nonNegativeRule, textRule, + withSearchPlaceholders, } from './common'; const listDicFormatter = res => { @@ -118,7 +120,10 @@ export const config = { export const option = { dialogCustomClass: 'temporary-credit-limit-dialog', - ...createCrudOption([ + addTitle: '新增临时额度申请', + editTitle: '编辑临时额度申请', + viewTitle: '查看临时额度申请', + ...createCrudOption(withSearchPlaceholders([ { label: '申请单号', prop: 'applicationNo', @@ -158,6 +163,7 @@ export const option = { prop: 'projectCode', hide: true, disabled: true, + placeholder: '请输入', span: 6, minWidth: 150, rules: textRule('项目编号', 50), @@ -167,6 +173,7 @@ export const option = { prop: 'undertakeDeptName', hide: true, disabled: true, + placeholder: '请输入', span: 6, minWidth: 150, rules: textRule('承办部门', 50, true), @@ -176,6 +183,7 @@ export const option = { prop: 'projectFundLimit', hide: true, disabled: true, + placeholder: '请输入', span: 6, minWidth: 200, rules: [nonNegativeRule('项目资金使用额度')], @@ -185,6 +193,7 @@ export const option = { prop: 'usedFundLimit', hide: true, disabled: true, + placeholder: '请输入', span: 6, minWidth: 220, value: 0, @@ -195,6 +204,7 @@ export const option = { prop: 'remainingFundLimit', hide: true, disabled: true, + placeholder: '请输入', span: 6, minWidth: 230, value: 0, @@ -217,9 +227,13 @@ export const option = { type: 'date', format: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD', + placeholder: '请选择', span: 6, minWidth: 140, - rules: [{ required: true, message: '请选择申请有效期至', trigger: 'change' }], + rules: [ + { required: true, message: '请选择申请有效期至', trigger: 'change' }, + futureDateRule('申请有效期至'), + ], }, { label: '申请部门', @@ -285,15 +299,16 @@ export const option = { editDisplay: false, }, { - label: '备注', + label: '临时额度信息', prop: 'remark', type: 'textarea', span: 24, minRows: 2, hide: true, + placeholder: '请输入', maxlength: 200, showWordLimit: true, - rules: textRule('备注', 200), + rules: textRule('临时额度信息', 200), }, { label: '附件', @@ -303,7 +318,7 @@ export const option = { hide: true, }, ...auditColumns.map(column => ({ ...column, hide: true })), - ]), + ])), dialogWidth: '96%', menuFixed: 'right', menuWidth: 320, diff --git a/src/views/business/contract-manage-change.vue b/src/views/business/contract-manage-change.vue index ca7315b..612a872 100644 --- a/src/views/business/contract-manage-change.vue +++ b/src/views/business/contract-manage-change.vue @@ -63,7 +63,12 @@
-
付款比例设置
+
+ 付款比例设置 + + + +
diff --git a/src/views/business/contract-manage.vue b/src/views/business/contract-manage.vue index c422580..514e742 100644 --- a/src/views/business/contract-manage.vue +++ b/src/views/business/contract-manage.vue @@ -425,10 +425,14 @@
-
付款比例设置
+
+ 付款比例设置 + + + +
添加
-

非必填;配置付款比例时,合计必须等于100%。

@@ -740,7 +744,12 @@
-
付款比例设置
+
+ 付款比例设置 + + + +
@@ -2892,8 +2901,4 @@ export default { white-space: normal; line-height: 1.2; } -.contract-manage-form__tip { - color: #ff0000 !important; - font-size: 12px; -} diff --git a/src/views/business/project-apply.vue b/src/views/business/project-apply.vue index ff02ac0..a176e10 100644 --- a/src/views/business/project-apply.vue +++ b/src/views/business/project-apply.vue @@ -58,6 +58,40 @@ {{ displayStatus(row, 'approvalStatus') }} + + + + + +