Merge remote-tracking branch 'websoft/master'

This commit is contained in:
2026-08-28 18:22:20 +08:00
4 changed files with 109 additions and 43 deletions
+22
View File
@@ -58,3 +58,25 @@
- 根因:`<el-form-item label="业务部门">` 误加 `class="project-apply-form__item--full"`(该类对应样式 `:deep(.project-apply-form__item--full) { grid-column: 1 / -1; ... }` 是横跨整行的:本意只用于"项目由来说明"等多行文本字段)。 - 根因:`<el-form-item label="业务部门">` 误加 `class="project-apply-form__item--full"`(该类对应样式 `:deep(.project-apply-form__item--full) { grid-column: 1 / -1; ... }` 是横跨整行的:本意只用于"项目由来说明"等多行文本字段)。
- 修复:移除该 class,业务部门恢复为半宽(一行两列网格的常规项),仅"项目由来说明"等需要全宽铺开的字段仍保留 full。同时把样式块上方注释由「占满整行的表单项(业务部门 / 项目由来说明)」改为「占满整行的表单项(如项目由来说明等多行文本字段)」,避免再误读。 - 修复:移除该 class,业务部门恢复为半宽(一行两列网格的常规项),仅"项目由来说明"等需要全宽铺开的字段仍保留 full。同时把样式块上方注释由「占满整行的表单项(业务部门 / 项目由来说明)」改为「占满整行的表单项(如项目由来说明等多行文本字段)」,避免再误读。
## project-apply 字段 label 问号悬浮提示
- 文件:`src/views/business/project-apply.vue`
- 需求:把"项目资金使用额度"/"项目应收账款额度"两字段的提示从 placeholder 移到 label 右侧问号 tooltip。
- 实现:
-`el-form-item``class="project-apply-form__tip-label"`,用 `#label` slot 包裹文字 + `<el-tooltip content=... placement="top"><el-icon class="project-apply-form__label-tip"><QuestionFilled /></el-icon></el-tooltip>`
- placeholder 改回"请输入"。
- 提示文案按截图(去掉"额度"二字):资金使用额度→`实际业务回款周期内付款`;应收账款额度→`回款期内最大应收账款额`
- scoped 样式:`__tip-label :deep(.el-form-item__label){vertical-align:top}` 保持默认 inline 布局,让文字按全局 `white-space: normal` 换行显示;`__label-tip{margin-left:4px;color:#a8abb2;cursor:help;vertical-align:-0.125em}` 问号与文字 baseline 对齐。
- 图标 `QuestionFilled` 已在 main.js 全局注册(@element-plus/icons-vue),模板可直接用。
- 可复用模式:其它表单字段如需 label 旁问号提示,套用此 slot 结构即可。
## project-apply 详情页客户/承运商表格改造
- 文件:`src/views/business/project-apply.vue`
- 需求:
1. 客户信息、承运商信息两个表格的「客户」「承运商」列改为可点击链接,跳转打开对应客商档案。
2. 删除两个表格的「联系人」「联系方式」列。
- 实现:
- 模板:两列的 `el-table-column``#default` slot 渲染 `<el-link type="primary" :underline="false" @click="openCustomerArchive(row)">`,显示 `row.customer` / `row.carrier`
- 删除原 `prop="contact"``prop="phone"` 两列。
- methods 新增 `openCustomerArchive(row)`:取 `getCustomerRowId(row)``row.id || row.customerId || row.carrierId`),无 ID 时 `this.$message.warning`;有 ID 则 `this.$router.push({ path: '/vehicle/customer-archive/form', query: { id: String(id), name: '查看客商档案', view: '1' } })`
- 注意:客商档案查看态由 `customer-archive.vue``this.$route.query.view === '1'` 识别,与现有查看逻辑一致。
+75 -21
View File
@@ -220,7 +220,7 @@
<el-form-item label="客户名称" prop="customerNames"> <el-form-item label="客户名称" prop="customerNames">
<el-select <el-select
v-model="selectedCustomerId" v-model="selectedCustomerId"
placeholder="支持多选,选择后下方列表展示" placeholder="请选择"
multiple multiple
filterable filterable
clearable clearable
@@ -241,7 +241,7 @@
<el-form-item label="下游承运商" prop="carrierNames"> <el-form-item label="下游承运商" prop="carrierNames">
<el-select <el-select
v-model="selectedCarrierIds" v-model="selectedCarrierIds"
placeholder="支持多选选择后下方列表展示" placeholder="请选择"
multiple multiple
filterable filterable
clearable clearable
@@ -259,18 +259,30 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="项目资金使用额度万元" prop="fundLimit"> <el-form-item prop="fundLimit" class="project-apply-form__tip-label">
<template #label>
<span>项目资金使用额度(万元)</span>
<el-tooltip content="实际业务回款周期内付款" placement="top">
<el-icon class="project-apply-form__label-tip"><QuestionFilled /></el-icon>
</el-tooltip>
</template>
<el-input <el-input
v-model="form.fundLimit" v-model="form.fundLimit"
placeholder="实际业务回款周期内付款额度" placeholder="请输入"
@input="value => handleNumberInput('fundLimit', value)" @input="value => handleNumberInput('fundLimit', value)"
@blur="formatAmountField('fundLimit')" @blur="formatAmountField('fundLimit')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="项目应收账款额度万元" prop="receivableLimit"> <el-form-item prop="receivableLimit" class="project-apply-form__tip-label">
<template #label>
<span>项目应收账款额度(万元)</span>
<el-tooltip content="回款期内最大应收账款额" placement="top">
<el-icon class="project-apply-form__label-tip"><QuestionFilled /></el-icon>
</el-tooltip>
</template>
<el-input <el-input
v-model="form.receivableLimit" v-model="form.receivableLimit"
placeholder="回款期内最大应收账款额度" placeholder="请输入"
@input="value => handleNumberInput('receivableLimit', value)" @input="value => handleNumberInput('receivableLimit', value)"
@blur="formatAmountField('receivableLimit')" @blur="formatAmountField('receivableLimit')"
/> />
@@ -292,7 +304,7 @@
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item label="货物类型" prop="cargoType"> <el-form-item label="货物类型" prop="cargoType">
<el-select v-model="form.cargoType" placeholder="请选择货物类型" filterable clearable> <el-select v-model="form.cargoType" placeholder="请选择" filterable clearable>
<el-option <el-option
v-for="item in cargoTypeOptions" v-for="item in cargoTypeOptions"
:key="item.value" :key="item.value"
@@ -304,7 +316,7 @@
<el-form-item label="预估货物数量" prop="cargoQuantity"> <el-form-item label="预估货物数量" prop="cargoQuantity">
<el-input <el-input
v-model="form.cargoQuantity" v-model="form.cargoQuantity"
placeholder="请输入数字" placeholder="请输入"
@input="value => handleIntegerInput('cargoQuantity', value)" @input="value => handleIntegerInput('cargoQuantity', value)"
/> />
</el-form-item> </el-form-item>
@@ -399,7 +411,17 @@
<div class="dialog-section-title project-apply-form__table-title">客户信息</div> <div class="dialog-section-title project-apply-form__table-title">客户信息</div>
<el-table :data="customerRows" border class="project-apply-form__table"> <el-table :data="customerRows" border class="project-apply-form__table">
<el-table-column type="index" label="序号" width="80" align="center" /> <el-table-column type="index" label="序号" width="80" align="center" />
<el-table-column prop="customer" label="客户" min-width="160" align="center" /> <el-table-column prop="customer" label="客户" min-width="160" align="center">
<template #default="{ row }">
<el-link
type="primary"
:underline="false"
@click="openCustomerArchive(row)"
>
{{ row.customer }}
</el-link>
</template>
</el-table-column>
<el-table-column prop="credit" label="客户信用额度" min-width="150" align="center"> <el-table-column prop="credit" label="客户信用额度" min-width="150" align="center">
<template #default="{ row }"> <template #default="{ row }">
{{ normalizeReadonlyAmount(row.credit) }} {{ normalizeReadonlyAmount(row.credit) }}
@@ -414,14 +436,22 @@
align="center" align="center"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column prop="contact" label="联系人" min-width="120" align="center" />
<el-table-column prop="phone" label="联系方式" min-width="140" align="center" />
</el-table> </el-table>
<div class="dialog-section-title">承运商信息</div> <div class="dialog-section-title">承运商信息</div>
<el-table :data="carrierRows" border class="project-apply-form__table"> <el-table :data="carrierRows" border class="project-apply-form__table">
<el-table-column type="index" label="序号" width="80" align="center" /> <el-table-column type="index" label="序号" width="80" align="center" />
<el-table-column prop="carrier" label="承运商" min-width="180" align="center" /> <el-table-column prop="carrier" label="承运商" min-width="180" align="center">
<template #default="{ row }">
<el-link
type="primary"
:underline="false"
@click="openCustomerArchive(row)"
>
{{ row.carrier }}
</el-link>
</template>
</el-table-column>
<el-table-column prop="companyNature" label="企业性质" min-width="140" align="center" /> <el-table-column prop="companyNature" label="企业性质" min-width="140" align="center" />
<el-table-column prop="legalPerson" label="法定代表人" min-width="140" align="center" /> <el-table-column prop="legalPerson" label="法定代表人" min-width="140" align="center" />
<el-table-column <el-table-column
@@ -431,8 +461,6 @@
align="center" align="center"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column prop="contact" label="联系人" min-width="120" align="center" />
<el-table-column prop="phone" label="联系方式" min-width="140" align="center" />
</el-table> </el-table>
<div class="dialog-section-title">项目情况说明</div> <div class="dialog-section-title">项目情况说明</div>
@@ -718,8 +746,8 @@
@keyup.enter="loadUsers" @keyup.enter="loadUsers"
/> />
<el-input <el-input
v-model="userQuery.account" v-model="userQuery.phone"
placeholder="登录账" placeholder="手机"
clearable clearable
@keyup.enter="loadUsers" @keyup.enter="loadUsers"
/> />
@@ -728,8 +756,8 @@
</div> </div>
<el-table :data="userData" border v-loading="userLoading" @row-dblclick="selectUser"> <el-table :data="userData" border v-loading="userLoading" @row-dblclick="selectUser">
<el-table-column type="index" label="序号" width="70" align="center" /> <el-table-column type="index" label="序号" width="70" align="center" />
<el-table-column prop="account" label="登录账号" min-width="140" align="center" />
<el-table-column prop="realName" label="用户姓名" min-width="140" align="center" /> <el-table-column prop="realName" label="用户姓名" min-width="140" align="center" />
<el-table-column prop="phone" label="手机号" min-width="140" align="center" />
<el-table-column prop="deptName" label="所属部门" min-width="180" align="center" /> <el-table-column prop="deptName" label="所属部门" min-width="180" align="center" />
<el-table-column label="操作" width="100" align="center"> <el-table-column label="操作" width="100" align="center">
<template #default="{ row }"> <template #default="{ row }">
@@ -796,7 +824,7 @@ const emptyForm = () => ({
businessDeptName: '', businessDeptName: '',
undertakeDeptId: '', undertakeDeptId: '',
undertakeDeptName: '', undertakeDeptName: '',
projectSource: '商务洽谈', projectSource: '',
sourceRemark: '', sourceRemark: '',
changeType: '', changeType: '',
changeNo: '', changeNo: '',
@@ -1071,7 +1099,7 @@ export default {
userData: [], userData: [],
userQuery: { userQuery: {
realName: '', realName: '',
account: '', phone: '',
}, },
userPage: { userPage: {
currentPage: 1, currentPage: 1,
@@ -1729,6 +1757,17 @@ export default {
getCustomerRowId(row = {}) { getCustomerRowId(row = {}) {
return row.id || row.customerId || row.carrierId || ''; return row.id || row.customerId || row.carrierId || '';
}, },
openCustomerArchive(row = {}) {
const id = this.getCustomerRowId(row);
if (!id) {
this.$message.warning('客商档案 ID 为空无法打开');
return;
}
this.$router.push({
path: '/vehicle/customer-archive/form',
query: { id: String(id), name: '查看客商档案', view: '1' },
});
},
getCustomerRowLabel(row = {}, type) { getCustomerRowLabel(row = {}, type) {
return ( return (
row[type === 'carrier' ? 'carrier' : 'customer'] || row[type === 'carrier' ? 'carrier' : 'customer'] ||
@@ -2117,7 +2156,7 @@ export default {
}); });
}, },
resetUserQuery() { resetUserQuery() {
this.userQuery = { realName: '', account: '' }; this.userQuery = { realName: '', phone: '' };
this.userPage.currentPage = 1; this.userPage.currentPage = 1;
this.loadUsers(); this.loadUsers();
}, },
@@ -2205,6 +2244,21 @@ export default {
cursor: pointer; cursor: pointer;
} }
&__tip-label {
// 保持 .el-form-item__label 默认 inline 布局,让文字按全局 white-space: normal 换行显示
:deep(.el-form-item__label) {
vertical-align: top;
}
}
&__label-tip {
margin-left: 4px;
color: #a8abb2;
cursor: help;
font-size: 14px;
vertical-align: -0.125em;
}
&__table-title { &__table-title {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -2365,7 +2419,7 @@ export default {
} }
&--change { &--change {
justify-content: flex-start; justify-content: flex-end;
padding-left: 24px; padding-left: 24px;
} }
} }
+11 -21
View File
@@ -32,15 +32,6 @@
</el-button> </el-button>
</template> </template>
<template #menu="scope"> <template #menu="scope">
<el-link type="primary" @click.stop="handleView(scope.row, scope.index)" v-if="permissionList.viewBtn"
>查看</el-link
>
<el-link type="primary" @click.stop="handleEdit(scope.row, scope.index)" v-if="permissionList.editBtn"
>编辑</el-link
>
<el-link type="danger" @click.stop="handleDel(scope.row, scope.index)" v-if="permissionList.delBtn"
>删除</el-link
>
<el-link <el-link
type="primary" type="primary"
@click.stop="handleAdd(scope.row, scope.index)" @click.stop="handleAdd(scope.row, scope.index)"
@@ -186,9 +177,7 @@ export default {
border: true, border: true,
index: true, index: true,
selection: true, selection: true,
viewBtn: false, viewBtn: true,
editBtn: false,
delBtn: false,
menuWidth: 320, menuWidth: 320,
dialogWidth: 800, dialogWidth: 800,
dialogClickModal: false, dialogClickModal: false,
@@ -530,15 +519,6 @@ export default {
isRootDept(row) { isRootDept(row) {
return row && (row.parentId === 0 || String(row.parentId) === '0'); return row && (row.parentId === 0 || String(row.parentId) === '0');
}, },
handleView(row, index) {
this.$refs.crud.rowView(row, index);
},
handleEdit(row, index) {
this.$refs.crud.rowEdit(row, index);
},
handleDel(row, index) {
this.$refs.crud.rowDel(row, index);
},
handleAdd(row) { handleAdd(row) {
this.parentId = row.id; this.parentId = row.id;
this.loadParentDeptCode(row.id); this.loadParentDeptCode(row.id);
@@ -774,4 +754,14 @@ export default {
display: inline-flex; display: inline-flex;
} }
} }
/* 操作列删除按钮使用危险色 */
:deep(.avue-crud__menu > .el-button.is-text.avue-crud__delBtn) {
color: var(--el-color-danger);
}
:deep(.avue-crud__menu > .el-button.is-text.avue-crud__delBtn:hover),
:deep(.avue-crud__menu > .el-button.is-text.avue-crud__delBtn:focus) {
color: var(--el-color-danger-light-3);
}
</style> </style>
+1 -1
View File
@@ -2533,7 +2533,7 @@ export default {
this.loadDictOptions( this.loadDictOptions(
'nature_of_client', 'nature_of_client',
'customerNatureOptions', 'customerNatureOptions',
['有限公司', '个体工商户'], [],
options => { options => {
const customerNatureColumn = this.findColumn(this.option.column, 'customerNature'); const customerNatureColumn = this.findColumn(this.option.column, 'customerNature');
customerNatureColumn.dicData = [{ label: '全部', value: '' }, ...options]; customerNatureColumn.dicData = [{ label: '全部', value: '' }, ...options];