style(process-config): 优化流程配置页样式及结构一致性

- process-config.vue 基本信息区改用 section-card 和 el-form 组件,统一右侧固定宽 label 栅格布局
- 现行过程节点和节点设置区使用 section-card 包裹,替换原有灰色标题,增加白卡样式和卡片间距
- 删除不再使用的自定义样式 __section/__field/__field-label/__field-label--required,保留与节点表格相关样式
- 保证三个 section-card 正确闭合,编译通过,无业务逻辑变更
- master-order-detail.vue 主界面改用 section-card 代替 div 容器,提升风格统一性
- 注释部分 Element UI 弹窗表单项 margin-bottom 样式,减少样式冗余
- loading-manage.vue loading-detail 取消 flex gap,防止潜在样式冲突
- shipping-template.js 表单项 grid 栅格 span 值调整优化表单布局,使各项宽度分配更合理
This commit is contained in:
2026-08-13 16:44:45 +08:00
parent 490efe2ce5
commit b64465a4c3
6 changed files with 107 additions and 127 deletions
+9
View File
@@ -60,3 +60,12 @@
- 用户反馈新增弹窗中"所属区县"label 太挤(实测约 85×32px),要求加宽。 - 用户反馈新增弹窗中"所属区县"label 太挤(实测约 85×32px),要求加宽。
- 已把 `option.labelWidth: '108px' → '140px'`,同步全局覆盖 `.el-form-item__label{width:108px!important} → 140px!important` - 已把 `option.labelWidth: '108px' → '140px'`,同步全局覆盖 `.el-form-item__label{width:108px!important} → 140px!important`
- 140px 够"所属区县"4字+必填星号+留白,也覆盖表单其他 label("行政区划编号"6字 + * 也够)。若仍觉不够可再调到 160px。 - 140px 够"所属区县"4字+必填星号+留白,也覆盖表单其他 label("行政区划编号"6字 + * 也够)。若仍觉不够可再调到 160px。
## process-config.vue 套用 customer-archive 样式(用户要求"和 business-crud-page 一样的问题"
- 根因同商务页:本页原用灰色 `div.dialog-section-title` 标题 + 自定义 `__field` flex 布局(label `flex:0 0 150px`),既无白卡样式也无 8px 卡片间距,与 customer-archive 的 `<section-card>` 白卡风格不一致。Avue form 本身 `labelPosition:'right'``labelWidth:'auto'`,故原页才需自定义固定宽 label。
- 改动(src/views/business/process-config.vue):
1. `#basicInfo-form` 槽:去掉 `process-config-page__section` + `dialog-section-title`,改为 `<section-card title="基本信息">` + 嵌套 `<el-form label-position="right" label-width="calc(6em + 24px)">` + `<el-row :gutter="18">` + `el-col`(配置名称6/项目6/运输完成时限12/备注24) + `el-form-item`,与 customer-archive 右侧固定宽 label 栅格完全对齐。必填项加 `required`
2. `#nodeConfigJson-form` 槽:两个 `dialog-section-title`(现行过程节点 / 节点设置)分别改为 `<section-card title=...>` 包裹(timeline 与 el-table 内容不变)。
3. 删除不再使用的 `__section/__field/__field-label/__field-label--required` 样式;保留 `__finish-days` 与节点表格相关样式。
- 卡片间距:全局 `.section-card{margin-bottom:8px}` 在本页生效(无 `!important` 覆盖),三张白卡自动保持 8px 间隔。
- 校验:@vue/compiler-sfc 编译通过,3 个 section-card 均正确闭合;未动任何业务逻辑(validateRow/syncNodeFields 等不变)。
+7 -7
View File
@@ -56,7 +56,7 @@ export const option = {
prop: 'templateCode', prop: 'templateCode',
search: true, search: true,
searchOrder: 4, searchOrder: 4,
span: 8, span: 6,
order: 390, order: 390,
minWidth: 170, minWidth: 170,
disabled: true, disabled: true,
@@ -67,7 +67,7 @@ export const option = {
prop: 'templateName', prop: 'templateName',
search: true, search: true,
searchOrder: 3, searchOrder: 3,
span: 8, span: 6,
order: 380, order: 380,
minWidth: 150, minWidth: 150,
rules: textRule('模板名称', 50, true), rules: textRule('模板名称', 50, true),
@@ -78,7 +78,7 @@ export const option = {
type: 'select', type: 'select',
search: true, search: true,
searchOrder: 2, searchOrder: 2,
span: 8, span: 6,
order: 370, order: 370,
dicData: templateTypeOptions, dicData: templateTypeOptions,
minWidth: 120, minWidth: 120,
@@ -89,7 +89,7 @@ export const option = {
prop: 'remark', prop: 'remark',
type: 'textarea', type: 'textarea',
minRows: 3, minRows: 3,
span: 24, span: 18,
order: 360, order: 360,
minWidth: 180, minWidth: 180,
maxlength: 200, maxlength: 200,
@@ -111,7 +111,7 @@ export const option = {
formslot: true, formslot: true,
search: true, search: true,
searchOrder: 1, searchOrder: 1,
span: 8, span: 6,
order: 340, order: 340,
minWidth: 150, minWidth: 150,
rules: textRule('项目', 100, true), rules: textRule('项目', 100, true),
@@ -120,7 +120,7 @@ export const option = {
label: '客户合同', label: '客户合同',
prop: 'contractName', prop: 'contractName',
formslot: true, formslot: true,
span: 8, span: 6,
order: 330, order: 330,
minWidth: 160, minWidth: 160,
rules: textRule('客户合同', 100, true), rules: textRule('客户合同', 100, true),
@@ -129,7 +129,7 @@ export const option = {
label: '运输方式', label: '运输方式',
prop: 'transportType', prop: 'transportType',
type: 'select', type: 'select',
span: 8, span: 6,
order: 320, order: 320,
dicData: transportTypeOptions, dicData: transportTypeOptions,
minWidth: 130, minWidth: 130,
+2 -2
View File
@@ -173,7 +173,7 @@
.el-dialog .el-form-item--small.el-form-item, .el-dialog .el-form-item--small.el-form-item,
.el-dialog .el-form-item--large.el-form-item, .el-dialog .el-form-item--large.el-form-item,
.el-dialog .el-form-item--medium.el-form-item { .el-dialog .el-form-item--medium.el-form-item {
margin-bottom: 20px; //margin-bottom: 20px;
} }
/* 全站弹窗:底部操作栏浮动效果(参照 business/project-apply /* 全站弹窗:底部操作栏浮动效果(参照 business/project-apply
@@ -329,7 +329,7 @@
// 4) 弹窗内表单项默认上下间距 16px(覆盖默认 18px / 22px,与 customer-archive 对齐) // 4) 弹窗内表单项默认上下间距 16px(覆盖默认 18px / 22px,与 customer-archive 对齐)
.el-dialog .el-form-item { .el-dialog .el-form-item {
margin-bottom: 16px; //margin-bottom: 16px;
} }
// 5) 通用分组白卡组件(<section-card>):标题融入卡头 // 5) 通用分组白卡组件(<section-card>):标题融入卡头
@@ -1,5 +1,5 @@
<template> <template>
<div v-loading="loading" class="master-detail"> <section-card v-loading="loading" class="master-detail">
<section v-if="master" class="detail-overview"> <section v-if="master" class="detail-overview">
<div class="detail-heading"><div><h2>多联总单详情 <span>|</span> {{ master.masterNo }}</h2><el-tag :type="statusType(master.businessStatus)">{{ statusName(master.businessStatus) }}</el-tag></div><el-button @click="$emit('back')">返回</el-button></div> <div class="detail-heading"><div><h2>多联总单详情 <span>|</span> {{ master.masterNo }}</h2><el-tag :type="statusType(master.businessStatus)">{{ statusName(master.businessStatus) }}</el-tag></div><el-button @click="$emit('back')">返回</el-button></div>
<dl class="detail-meta"><div><dt>客户</dt><dd>{{ master.customerName || '-' }}</dd></div><div><dt>合同编号</dt><dd>{{ master.contractNo || '-' }}</dd></div><div><dt>项目</dt><dd>{{ master.projectName || '-' }}</dd></div><div><dt>货物名称</dt><dd>{{ goodsNames }}</dd></div><div><dt>货物类型</dt><dd>{{ goodsTypes }}</dd></div><div><dt>运输周期</dt><dd>{{ dateRange }}</dd></div></dl> <dl class="detail-meta"><div><dt>客户</dt><dd>{{ master.customerName || '-' }}</dd></div><div><dt>合同编号</dt><dd>{{ master.contractNo || '-' }}</dd></div><div><dt>项目</dt><dd>{{ master.projectName || '-' }}</dd></div><div><dt>货物名称</dt><dd>{{ goodsNames }}</dd></div><div><dt>货物类型</dt><dd>{{ goodsTypes }}</dd></div><div><dt>运输周期</dt><dd>{{ dateRange }}</dd></div></dl>
@@ -23,14 +23,16 @@
<el-table :data="master.goods || []" border><el-table-column type="index" label="序号" width="64" /><el-table-column prop="cargoName" label="货物名称" min-width="150" /><el-table-column prop="cargoType" label="货物类型" min-width="130" /><el-table-column label="数量" width="130"><template #default="{ row }">{{ quantity(row.quantity) }} {{ row.quantityUnit || '' }}</template></el-table-column><el-table-column prop="packageType" label="包装" min-width="120" /><el-table-column prop="brand" label="品牌" min-width="120" /><el-table-column prop="specification" label="规格" min-width="120" /><el-table-column prop="model" label="型号" min-width="120" /></el-table> <el-table :data="master.goods || []" border><el-table-column type="index" label="序号" width="64" /><el-table-column prop="cargoName" label="货物名称" min-width="150" /><el-table-column prop="cargoType" label="货物类型" min-width="130" /><el-table-column label="数量" width="130"><template #default="{ row }">{{ quantity(row.quantity) }} {{ row.quantityUnit || '' }}</template></el-table-column><el-table-column prop="packageType" label="包装" min-width="120" /><el-table-column prop="brand" label="品牌" min-width="120" /><el-table-column prop="specification" label="规格" min-width="120" /><el-table-column prop="model" label="型号" min-width="120" /></el-table>
<el-empty v-if="!(master.goods || []).length" description="暂无货物信息" :image-size="56" /> <el-empty v-if="!(master.goods || []).length" description="暂无货物信息" :image-size="56" />
</section> </section>
</div> </section-card>
</template> </template>
<script> <script>
import * as api from '@/api/business/master-order'; import * as api from '@/api/business/master-order';
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue'; import { ArrowDown, ArrowUp } from '@element-plus/icons-vue';
import SectionCard from '@/components/section-card/main.vue';
export default { export default {
components: { SectionCard },
props: { id: [String, Number] }, props: { id: [String, Number] },
emits: ['back'], emits: ['back'],
data() { return { loading: false, master: null, expandedSegments: {}, ArrowDown, ArrowUp }; }, data() { return { loading: false, master: null, expandedSegments: {}, ArrowDown, ArrowUp }; },
+1 -1
View File
@@ -2207,7 +2207,7 @@ export default {
.loading-detail { .loading-detail {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; //gap: 8px;
color: #303133; color: #303133;
.loading-detail__summary { display: flex; align-items: center; flex-wrap: wrap; gap: 24px; padding: 4px 0 16px; } .loading-detail__summary { display: flex; align-items: center; flex-wrap: wrap; gap: 24px; padding: 4px 0 16px; }
.loading-detail__heading { font-size: 20px; font-weight: 600; margin-right: 8px; } .loading-detail__heading { font-size: 20px; font-weight: 600; margin-right: 8px; }
+84 -115
View File
@@ -80,106 +80,100 @@
</template> </template>
<template #basicInfo-form> <template #basicInfo-form>
<div class="process-config-page__section"> <section-card title="基本信息">
<div class="dialog-section-title">基本信息</div> <el-form
<el-row :gutter="16"> :model="form"
<el-col :span="8"> label-position="right"
<div class="process-config-page__field"> label-width="calc(6em + 24px)"
<span >
class="process-config-page__field-label process-config-page__field-label--required" <el-row :gutter="18">
> <el-col :span="6">
配置名称 <el-form-item label="配置名称" required>
</span>
<el-input
v-model="form.configName"
:disabled="dialogReadonly"
maxlength="100"
placeholder="请输入"
/>
</div>
</el-col>
<el-col :span="8">
<div class="process-config-page__field">
<span
class="process-config-page__field-label process-config-page__field-label--required"
>
项目
</span>
<el-select
v-model="selectedProjectId"
clearable
filterable
remote
:remote-method="loadProjectOptions"
:loading="projectLoading"
:disabled="dialogReadonly"
placeholder="请选择"
style="width: 100%"
@change="handleProjectChange"
>
<el-option
v-for="item in projectOptions"
:key="item.id"
:label="formatProjectLabel(item)"
:value="String(item.id)"
/>
</el-select>
</div>
</el-col>
<el-col :span="8">
<div class="process-config-page__field">
<span class="process-config-page__field-label">运输完成时限</span>
<div class="process-config-page__finish-days">
<span>默认</span>
<el-input <el-input
v-model="form.defaultFinishDays" v-model="form.configName"
:disabled="dialogReadonly" :disabled="dialogReadonly"
maxlength="3" maxlength="100"
placeholder="请输入" placeholder="请输入"
@input="handleFinishDaysInput"
/> />
<span>天后完成运输</span> </el-form-item>
</div> </el-col>
</div> <el-col :span="6">
</el-col> <el-form-item label="项目" required>
<el-col :span="24"> <el-select
<div class="process-config-page__field"> v-model="selectedProjectId"
<span class="process-config-page__field-label">备注</span> clearable
<el-input filterable
v-model="form.remark" remote
type="textarea" :remote-method="loadProjectOptions"
:rows="4" :loading="projectLoading"
:disabled="dialogReadonly" :disabled="dialogReadonly"
maxlength="500" placeholder="请选择"
show-word-limit style="width: 100%"
placeholder="请输入" @change="handleProjectChange"
/> >
</div> <el-option
</el-col> v-for="item in projectOptions"
</el-row> :key="item.id"
</div> :label="formatProjectLabel(item)"
:value="String(item.id)"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="运输完成时限">
<div class="process-config-page__finish-days">
<span>默认</span>
<el-input
v-model="form.defaultFinishDays"
:disabled="dialogReadonly"
maxlength="3"
placeholder="请输入"
@input="handleFinishDaysInput"
/>
<span>天后完成运输</span>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注">
<el-input
v-model="form.remark"
type="textarea"
:rows="4"
:disabled="dialogReadonly"
maxlength="500"
show-word-limit
placeholder="请输入"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</section-card>
</template> </template>
<template #nodeConfigJson-form> <template #nodeConfigJson-form>
<div class="process-config-page__custom-form"> <div class="process-config-page__custom-form">
<div class="dialog-section-title">现行过程节点</div> <section-card title="现行过程节点">
<div class="process-config-page__timeline" v-if="enabledNodes.length"> <div class="process-config-page__timeline" v-if="enabledNodes.length">
<div class="process-config-page__timeline-line"></div> <div class="process-config-page__timeline-line"></div>
<div <div
v-for="node in enabledNodes" v-for="node in enabledNodes"
:key="node.key" :key="node.key"
class="process-config-page__timeline-item" class="process-config-page__timeline-item"
> >
<span class="process-config-page__timeline-dot"></span> <span class="process-config-page__timeline-dot"></span>
<div class="process-config-page__timeline-name">{{ node.name }}</div> <div class="process-config-page__timeline-name">{{ node.name }}</div>
<div class="process-config-page__timeline-desc"> <div class="process-config-page__timeline-desc">
<div v-for="text in timelineDescriptions(node)" :key="text">{{ text }}</div> <div v-for="text in timelineDescriptions(node)" :key="text">{{ text }}</div>
</div>
</div> </div>
</div> </div>
</div> <el-empty v-else description="请在节点设置中勾选过程节点" :image-size="72" />
<el-empty v-else description="请在节点设置中勾选过程节点" :image-size="72" /> </section-card>
<div class="dialog-section-title">节点设置</div> <section-card title="节点设置">
<el-table <el-table
class="process-config-page__node-table" class="process-config-page__node-table"
border border
@@ -363,6 +357,7 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</section-card>
</div> </div>
</template> </template>
@@ -1106,32 +1101,6 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.process-config-page { .process-config-page {
&__section {
width: 100%;
}
&__field {
display: flex;
align-items: flex-start;
gap: 10px;
margin-bottom: 16px;
}
&__field-label {
flex: 0 0 150px;
line-height: 32px;
color: #303133;
font-weight: 500;
text-align: right;
white-space: nowrap;
&--required::before {
margin-right: 4px;
color: #f56c6c;
content: '*';
}
}
&__node-value { &__node-value {
white-space: normal; white-space: normal;
word-break: break-all; word-break: break-all;