Merge remote-tracking branch 'websoft/master'
This commit is contained in:
@@ -0,0 +1,60 @@
|
|||||||
|
# 2026-08-28 工作日志
|
||||||
|
|
||||||
|
## contract-manage 表单底部操作栏间距/文案修复
|
||||||
|
- 文件:`src/views/business/contract-manage.vue`
|
||||||
|
- 问题:底部浮动操作栏 `.contract-manage-page__footer` 用 `gap:8px`,与全站统一 12px 标准不一致("间距不一致不统一")。
|
||||||
|
- 修复:去掉 `gap:8px`,改用 `.el-button + .el-button { margin-left:12px }`,对齐全站"去 gap、12px"规范。
|
||||||
|
- 文案:底部"关闭"→"取消"(底部操作栏统一命名规范;详情弹窗/流程图弹窗的"关闭"为只读/纯关闭场景,按规范保留)。
|
||||||
|
|
||||||
|
## contract-manage 草稿编辑页按钮缺失修复
|
||||||
|
- 问题:编辑态(含草稿编辑)底部只有单个"提交"(submitEdit),缺"暂存/提交临时合同/提交正式合同",与新增页不一致。
|
||||||
|
- 修复:新增 computed `isDraftEdit`(`formMode==='edit' && form.approvalStatus==='draft'`);footer 三按钮条件由 `formMode==='add'` 改为 `formMode==='add' || isDraftEdit`,草稿编辑复用 `submitCreate`(按 id upsert + temporary/formal 提升),非草稿编辑仍走 submitEdit 单个"提交"。
|
||||||
|
|
||||||
|
## contract-manage-change 变更页底部操作栏统一改造
|
||||||
|
- 文件:`src/views/business/contract-manage-change.vue`
|
||||||
|
- 问题:`.page-footer` 左侧对齐、`gap:16px`、不悬浮,且按钮顺序/命名(提交→关闭)与新增页规范相反。
|
||||||
|
- 修复:
|
||||||
|
- DOM:按钮重排为 `[取消][提交]`(次要居左、主操作居右),"关闭"→"取消"。
|
||||||
|
- 样式:`.page-footer` 改为 `position:fixed` 悬浮吸底(left:230px / avue--collapse 60px / avue-layout--horizontal 0)、`justify-content:flex-end` 右对齐、去 gap 改用 `.el-button+.el-button{margin-left:12px}` 统一 12px、白底+上边框+上投影。
|
||||||
|
- 容器 `.contract-change-page` 加 `padding-bottom:72px`,避免内容被悬浮栏遮挡。
|
||||||
|
|
||||||
|
## contract-manage 新增页"合同文件"标题未加粗修复
|
||||||
|
- 文件:`src/views/business/contract-manage.vue`
|
||||||
|
- 问题:`attachment-section` 子组件内渲染的 `.dialog-section-title` 不受当前页面 scoped `> .dialog-section-title` 样式命中,导致"合同文件"标题字重未加粗(截图反馈)。
|
||||||
|
- 修复:在 `.contract-manage-form__section` 样式规则中补充 `:deep(.dialog-section-title)`,使直接子元素和子组件内部标题均统一为 16px/600/#303133。
|
||||||
|
|
||||||
|
## contract-manage 搜索栏"时间段快捷筛选"组位置前置
|
||||||
|
- 文件:`src/views/business/contract-manage.vue` + `src/option/business/contract-manage.js`
|
||||||
|
- 第一轮(理解偏差):把"签约类型"select 和 check-tag 组一起塞进 `#search-menu` slot。主人纠正:「签约类型」是普通搜索字段,应与第一行 8 个搜索项同排,不是 slot 内的辅助元素。
|
||||||
|
- 第二轮(终态):
|
||||||
|
- option 把 `signType` 加 `search:true / searchOrder:10 / searchPlaceholder:'请选择'`,作为 Avue 标准搜索字段,与其它 8 项同排(放在末尾)。
|
||||||
|
- 页面 `#search-menu` slot 移除「签约类型」select,仅留 5 个 el-check-tag。
|
||||||
|
- 页面 data 移除冗余的 `contractSignType:''`,onLoad/searchReset 不再手动维护 signType(Avue search form 自动绑定到 query)。
|
||||||
|
- 样式:`.el-select { width: 180px }` 已成 dead code,移除。
|
||||||
|
- `:deep(...)` 调整:去掉 `margin-right:auto`,只留 `order:-1`。`.avue-form__menu` 本身 `flex / flex-end`,check-tag 组排首项后,整体仍紧靠右侧,与 `[查询][重置][收起]` 形成 `[快捷筛选] [查询] [重置] [收起]` 右对齐序列。
|
||||||
|
|
||||||
|
## 登录验证码:滑块(behavior) → 图形字符验证码(image)
|
||||||
|
- 文件:`src/config/website.js`(第14行 `captchaType: 'behavior'` → `'image'`)、`src/page/login/userlogin.vue`、`src/styles/login.scss`
|
||||||
|
- 背景:登录页原 `captchaType:'behavior'`(滑块/旋转行为验证)。需求改成截图中的「输入框 + 右侧独立彩色字符验证码图片」。
|
||||||
|
- 改动:
|
||||||
|
1. `website.js` 改 `captchaType: 'image'` 启用图形验证码分支(代码原本就有 image 模式的 UI 与 `getCaptcha()` 逻辑,仅未启用)。
|
||||||
|
2. `userlogin.vue` image 分支模板:验证码图片从 `el-input` 的 `#append` 内联改为 form-item 内 `.login-code-wrap` 并排独立方块(输入框 flex:1 + 右侧 130px 图片块),点击刷新。
|
||||||
|
3. `login.scss` 重写 `.login-code/.login-code-wrap/.login-code-box/.login-code-img`:flex 并排、图片块带 1px 边框 + hover 主色高亮、`object-fit:fill` 撑满。
|
||||||
|
- 验证:`vite build --outDir /tmp/tms-verify-build` 全量编译通过(exit 0,无报错)。注意原 `pnpm build` 因 WorkBuddy safe-delete 钩子拦截清空 dist/(741 文件)而中断,非代码问题。
|
||||||
|
- 注意:登录页 `activeName` 默认 `'iam'`(IAM 统一登录),图形验证码在 `userlogin.vue`,需点「账号密码登录」才可见;验证码图片依赖后端 `/blade-auth/oauth/captcha` 返回的 `data.key` + `data.image`。
|
||||||
|
|
||||||
|
## 全站「所属组织」搜索统一为树形下拉(el-tree-select)
|
||||||
|
- 背景:合同管理页「所属组织」原为 cascader(radio 风格),客户档案页(vehicle/customer-archive)已用树形下拉。主人要求全站统一为树形。
|
||||||
|
- 统一方案:新建可复用 mixin `src/mixins/organization-search.js`(封装 organizationTreeOptions 树数据、loadOrganizationOptions()、renderOrganizationSearch(scope) 渲染函数,自动识别 organizationName / deptName 两种 prop 并挂 column.renderSearch;树节点 node-key='id')。
|
||||||
|
- 适用两种架构:
|
||||||
|
1. **avue-crud 搜索**(renderSearch 模式):option 列加 `searchslot:true`,视图混入 mixin + created/初始化调 loadOrganizationOptions。已改:contract-manage(option 去 cascader 改 searchslot,视图用 renderOrganizationSearch 渲染函数)、transportCapacity 的 driver/vehicle/ship 三页(option 去 type:select 改 searchslot,视图混 mixin)。
|
||||||
|
2. **自定义搜索表单**(query.deptName 文本框模式):替换 `<el-input v-model="query.deptName">` 为 `<el-tree-select>`,node-key='id',@update:model-value 用 findOrgById(val)?.rawLabel 把 id 转回部门名写入 query.deptName(保后端按名称过滤兼容)。已改 payment 模块 4 处:invoice-application / invoice-receipt / payment-application / components/bill-payment-search。
|
||||||
|
- 关键坑:mixin 内部树数据命名为 `organizationTreeOptions`(非 organizationOptions),与 transportCapacity 等页面表单自用的扁平 `organizationOptions` 隔离,避免相互覆盖破坏表单 select。
|
||||||
|
- 待办(同自定义表单模式,未改):settlement 模块 4 个视图(transport-reconciliation/formal-settlement/pre-settlement/settlement-adjustment,搜索用动态 v-for 渲染 searchFields,需给 deptName 加 `type:'tree'` 分支)、system/user.vue(deptName)。business 模块(waybill-manage/transport-plan 等)所属组织为 `hide:true` 不展示搜索,无需改。
|
||||||
|
|
||||||
|
## project-apply 业务部门栏占满宽度修复
|
||||||
|
- 文件:`src/views/business/project-apply.vue`
|
||||||
|
- 问题:「重大项目补录」(独立表单页 /business/project-apply/form?mode=majorSupplement)下"业务部门"项横跨整行,与上下两行半宽风格不一致。
|
||||||
|
- 根因:`<el-form-item label="业务部门">` 误加 `class="project-apply-form__item--full"`(该类对应样式 `:deep(.project-apply-form__item--full) { grid-column: 1 / -1; ... }` 是横跨整行的:本意只用于"项目由来说明"等多行文本字段)。
|
||||||
|
- 修复:移除该 class,业务部门恢复为半宽(一行两列网格的常规项),仅"项目由来说明"等需要全宽铺开的字段仍保留 full。同时把样式块上方注释由「占满整行的表单项(业务部门 / 项目由来说明)」改为「占满整行的表单项(如项目由来说明等多行文本字段)」,避免再误读。
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ export default {
|
|||||||
tenantMode: true, // 是否开启租户模式
|
tenantMode: true, // 是否开启租户模式
|
||||||
tenantId: '000000', // 管理组租户编号
|
tenantId: '000000', // 管理组租户编号
|
||||||
captchaMode: true, // 是否开启验证码模式
|
captchaMode: true, // 是否开启验证码模式
|
||||||
captchaType: 'behavior', // 验证码类型(image:首屏图形验证码 behavior:登录时弹出点选/滑块/旋转随机行为验证)
|
captchaType: 'image', // 验证码类型(image:首屏图形验证码 behavior:登录时弹出点选/滑块/旋转随机行为验证)
|
||||||
switchMode: false, // 是否开启登录切换角色部门
|
switchMode: false, // 是否开启登录切换角色部门
|
||||||
lockPage: '/lock', // 锁屏页面地址
|
lockPage: '/lock', // 锁屏页面地址
|
||||||
tokenTime: 3000, // 定时刷新token间隔(单位:毫秒)
|
tokenTime: 3000, // 定时刷新token间隔(单位:毫秒)
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
|
import { ElTreeSelect } from 'element-plus';
|
||||||
|
import { h } from 'vue';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属组织 统一搜索 mixin
|
||||||
|
* ------------------------------------------------------------------
|
||||||
|
* 全站「所属组织」搜索栏统一为树形下拉(el-tree-select),风格与客户档案
|
||||||
|
* (vehicle/customer-archive.vue)保持一致。
|
||||||
|
*
|
||||||
|
* 接入步骤(在使用了 avue-crud 的页面中):
|
||||||
|
* 1. 混入本 mixin:mixins: [organizationSearch]
|
||||||
|
* 2. option 中「所属组织」列加上 searchslot: true(prop 为 organizationName 或 deptName 均可)
|
||||||
|
* 3. 在 created / 初始化时调用 this.loadOrganizationOptions()
|
||||||
|
*
|
||||||
|
* 说明:
|
||||||
|
* - 自动识别 organizationName / deptName 两种 prop,并挂载 column.renderSearch
|
||||||
|
* - 树节点标识统一用 id(node-key='id'),返回值为部门 id
|
||||||
|
* - 页面若已有 excludeExternalOrganization / normalizeOrgTree 等方法,
|
||||||
|
* 组件自身方法优先级更高,会覆盖本 mixin 的默认实现
|
||||||
|
* - 搜索值(id)需在各自的 searchChange / normalizeSearch 中按后端要求
|
||||||
|
* 转换为部门名称(参考 contract-manage 的 normalizeSearch)
|
||||||
|
*/
|
||||||
|
const ORG_PROPS = ['organizationName', 'deptName'];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 树形组织数据,仅供搜索栏 el-tree-select 使用;
|
||||||
|
// 与页面自身 organizationOptions(多为表单扁平列表)隔离,避免相互覆盖
|
||||||
|
organizationTreeOptions: [],
|
||||||
|
organizationTreeFlatOptions: [],
|
||||||
|
organizationLoading: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadOrganizationOptions() {
|
||||||
|
if (this.organizationLoading) return;
|
||||||
|
this.organizationLoading = true;
|
||||||
|
const tenantId = this.userInfo?.tenantId;
|
||||||
|
getDeptTree(tenantId)
|
||||||
|
.then(res => {
|
||||||
|
const source = res.data?.data || res.data || [];
|
||||||
|
const tree = this.excludeExternalOrganization
|
||||||
|
? this.excludeExternalOrganization(source)
|
||||||
|
: source;
|
||||||
|
this.organizationTreeOptions = this.normalizeOrgTree(tree);
|
||||||
|
this.organizationTreeFlatOptions = this.flattenOrgTree(this.organizationTreeOptions);
|
||||||
|
const option = this.tableOption || this.option;
|
||||||
|
if (!option) return;
|
||||||
|
ORG_PROPS.forEach(prop => {
|
||||||
|
const column = this.findColumn?.(option.column, prop);
|
||||||
|
if (column) {
|
||||||
|
column.renderSearch = scope => this.renderOrganizationSearch(scope, prop);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.organizationLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 默认排除「外部组织」节点;页面可覆盖
|
||||||
|
excludeExternalOrganization(tree = []) {
|
||||||
|
return (tree || []).reduce((result, item) => {
|
||||||
|
const name = item.title || item.deptName || item.name || item.label || '';
|
||||||
|
if (String(name).trim() === '外部组织') return result;
|
||||||
|
result.push({
|
||||||
|
...item,
|
||||||
|
children: this.excludeExternalOrganization(item.children || []),
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}, []);
|
||||||
|
},
|
||||||
|
normalizeOrgTree(tree = []) {
|
||||||
|
return (tree || []).map(item => {
|
||||||
|
const label = item.title || item.deptName || item.name || item.label || '';
|
||||||
|
const children = this.normalizeOrgTree(item.children || []);
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
id: String(item.id),
|
||||||
|
label,
|
||||||
|
rawLabel: label,
|
||||||
|
children: children.length ? children : undefined,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
flattenOrgTree(tree = []) {
|
||||||
|
return (tree || []).flatMap(item => [
|
||||||
|
{ id: String(item.id), label: item.label, rawLabel: item.rawLabel },
|
||||||
|
...this.flattenOrgTree(item.children || []),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
findOrgById(id) {
|
||||||
|
const value = Array.isArray(id) ? id.at(-1) : id;
|
||||||
|
return this.organizationTreeFlatOptions.find(item => String(item.id) === String(value));
|
||||||
|
},
|
||||||
|
renderOrganizationSearch(scope, prop = 'organizationName') {
|
||||||
|
return h(ElTreeSelect, {
|
||||||
|
modelValue: scope.row?.[prop] || '',
|
||||||
|
'onUpdate:modelValue': value => {
|
||||||
|
if (scope.row) scope.row[prop] = value;
|
||||||
|
},
|
||||||
|
data: this.organizationTreeOptions,
|
||||||
|
'node-key': 'id',
|
||||||
|
'check-strictly': true,
|
||||||
|
filterable: true,
|
||||||
|
clearable: true,
|
||||||
|
'render-after-expand': false,
|
||||||
|
style: 'width: 100%',
|
||||||
|
placeholder: '请选择 所属组织',
|
||||||
|
props: { label: 'label', value: 'id', children: 'children' },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -251,6 +251,7 @@ export const option = createCrudOption([
|
|||||||
searchPlaceholder: '请输入',
|
searchPlaceholder: '请输入',
|
||||||
order: 180,
|
order: 180,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
overHidden: true,
|
||||||
minWidth: 240,
|
minWidth: 240,
|
||||||
rules: textRule('合同名称', 100, true),
|
rules: textRule('合同名称', 100, true),
|
||||||
},
|
},
|
||||||
@@ -285,20 +286,11 @@ export const option = createCrudOption([
|
|||||||
prop: 'organizationName',
|
prop: 'organizationName',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 3,
|
searchOrder: 3,
|
||||||
searchType: 'cascader',
|
searchslot: true,
|
||||||
searchPlaceholder: '全部',
|
searchPlaceholder: '请选择 所属组织',
|
||||||
formslot: true,
|
formslot: true,
|
||||||
order: 120,
|
order: 120,
|
||||||
dicData: [],
|
dicData: [],
|
||||||
props: {
|
|
||||||
label: 'label',
|
|
||||||
value: 'id',
|
|
||||||
children: 'children',
|
|
||||||
},
|
|
||||||
checkStrictly: true,
|
|
||||||
emitPath: false,
|
|
||||||
showAllLevels: false,
|
|
||||||
filterable: true,
|
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
rules: selectRule('所属组织'),
|
rules: selectRule('所属组织'),
|
||||||
},
|
},
|
||||||
@@ -318,7 +310,9 @@ export const option = createCrudOption([
|
|||||||
label: '签约类型',
|
label: '签约类型',
|
||||||
prop: 'signType',
|
prop: 'signType',
|
||||||
type: 'select',
|
type: 'select',
|
||||||
search: false,
|
search: true,
|
||||||
|
searchOrder: 10,
|
||||||
|
searchPlaceholder: '请选择',
|
||||||
span: 8,
|
span: 8,
|
||||||
order: 190,
|
order: 190,
|
||||||
dicData: signTypeOptions,
|
dicData: signTypeOptions,
|
||||||
|
|||||||
@@ -81,9 +81,7 @@ export const option = {
|
|||||||
prop: 'organizationName',
|
prop: 'organizationName',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 1,
|
searchOrder: 1,
|
||||||
type: 'select',
|
searchslot: true,
|
||||||
filterable: true,
|
|
||||||
dicData: [],
|
|
||||||
slot: true,
|
slot: true,
|
||||||
minWidth: 160,
|
minWidth: 160,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -37,9 +37,7 @@ export const option = {
|
|||||||
prop: 'organizationName',
|
prop: 'organizationName',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 1,
|
searchOrder: 1,
|
||||||
type: 'select',
|
searchslot: true,
|
||||||
filterable: true,
|
|
||||||
dicData: [],
|
|
||||||
slot: true,
|
slot: true,
|
||||||
minWidth: 160,
|
minWidth: 160,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -46,9 +46,7 @@ export const option = {
|
|||||||
prop: 'organizationName',
|
prop: 'organizationName',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 1,
|
searchOrder: 1,
|
||||||
type: 'select',
|
searchslot: true,
|
||||||
filterable: true,
|
|
||||||
dicData: [],
|
|
||||||
slot: true,
|
slot: true,
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -46,21 +46,22 @@
|
|||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="code" class="login-code" v-if="captchaMode && captchaType === 'image'">
|
<el-form-item prop="code" class="login-code" v-if="captchaMode && captchaType === 'image'">
|
||||||
<el-input
|
<div class="login-code-wrap">
|
||||||
@keyup.enter="handleLogin"
|
<el-input
|
||||||
v-model="loginForm.code"
|
@keyup.enter="handleLogin"
|
||||||
auto-complete="off"
|
v-model="loginForm.code"
|
||||||
:placeholder="$t('login.code')"
|
auto-complete="off"
|
||||||
>
|
maxlength="6"
|
||||||
<template #prefix>
|
:placeholder="$t('login.code')"
|
||||||
<i class="icon-yanzhengma"></i>
|
>
|
||||||
</template>
|
<template #prefix>
|
||||||
<template #append>
|
<i class="icon-yanzhengma"></i>
|
||||||
<div class="login-code-box">
|
</template>
|
||||||
<img :src="loginForm.image" class="login-code-img" @click="refreshCode" />
|
</el-input>
|
||||||
</div>
|
<div class="login-code-box" @click="refreshCode" title="点击刷新验证码">
|
||||||
</template>
|
<img :src="loginForm.image" class="login-code-img" alt="验证码" />
|
||||||
</el-input>
|
</div>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click.prevent="handleLogin" class="login-submit"
|
<el-button type="primary" @click.prevent="handleLogin" class="login-submit"
|
||||||
|
|||||||
+26
-15
@@ -134,26 +134,37 @@
|
|||||||
}
|
}
|
||||||
.login-code {
|
.login-code {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
}
|
||||||
.el-input-group__append {
|
.login-code-wrap {
|
||||||
background-color: #fff;
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
.el-input {
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.login-code-box {
|
.login-code-box {
|
||||||
|
width: 130px;
|
||||||
|
height: 38px;
|
||||||
|
flex: none;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
background: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
&:hover {
|
||||||
|
border-color: #409eff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.login-code-img {
|
.login-code-img {
|
||||||
cursor: pointer;
|
width: 100%;
|
||||||
min-width: 100px;
|
height: 100%;
|
||||||
padding: 0 5px;
|
object-fit: fill;
|
||||||
height: 30px;
|
display: block;
|
||||||
color: #333;
|
user-select: none;
|
||||||
font-size: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
letter-spacing: 3px;
|
|
||||||
line-height: 38px;
|
|
||||||
text-indent: 5px;
|
|
||||||
text-align: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,68 +6,72 @@
|
|||||||
append-to-body
|
append-to-body
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
>
|
>
|
||||||
<el-descriptions v-if="readonly" :column="3" class="billing-plan-detail">
|
|
||||||
<el-descriptions-item label="方案名称">{{
|
<section-card>
|
||||||
displayValue(draft.planName)
|
<el-descriptions v-if="readonly" :column="3" class="billing-plan-detail">
|
||||||
}}</el-descriptions-item>
|
<el-descriptions-item label="方案名称">{{
|
||||||
<el-descriptions-item label="运输方式">{{
|
displayValue(draft.planName)
|
||||||
transportModeLabel(draft.transportMode)
|
}}</el-descriptions-item>
|
||||||
}}</el-descriptions-item>
|
<el-descriptions-item label="运输方式">{{
|
||||||
<el-descriptions-item label="默认方案">{{
|
transportModeLabel(draft.transportMode)
|
||||||
isDefaultPlan(draft) ? '是' : '否'
|
}}</el-descriptions-item>
|
||||||
}}</el-descriptions-item>
|
<el-descriptions-item label="默认方案">{{
|
||||||
<el-descriptions-item label="备注">{{ displayValue(draft.remark) }}</el-descriptions-item>
|
isDefaultPlan(draft) ? '是' : '否'
|
||||||
</el-descriptions>
|
}}</el-descriptions-item>
|
||||||
<el-form
|
<el-descriptions-item label="备注">{{ displayValue(draft.remark) }}</el-descriptions-item>
|
||||||
v-else
|
</el-descriptions>
|
||||||
ref="formRef"
|
<el-form
|
||||||
:model="draft"
|
v-else
|
||||||
:rules="formRules"
|
ref="formRef"
|
||||||
label-position="right"
|
:model="draft"
|
||||||
label-width="auto"
|
:rules="formRules"
|
||||||
>
|
label-position="right"
|
||||||
<el-row :gutter="20">
|
label-width="auto"
|
||||||
<el-col :span="8"
|
>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8"
|
||||||
><el-form-item label="方案名称" prop="planName"
|
><el-form-item label="方案名称" prop="planName"
|
||||||
><el-input
|
><el-input
|
||||||
v-model="draft.planName"
|
v-model="draft.planName"
|
||||||
maxlength="100"
|
maxlength="100"
|
||||||
:disabled="readonly" /></el-form-item
|
:disabled="readonly" /></el-form-item
|
||||||
></el-col>
|
></el-col>
|
||||||
<el-col :span="8"
|
<el-col :span="8"
|
||||||
><el-form-item label="运输方式" prop="transportMode"
|
><el-form-item label="运输方式" prop="transportMode"
|
||||||
><el-select
|
><el-select
|
||||||
v-model="draft.transportMode"
|
v-model="draft.transportMode"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
:loading="transportModeLoading"
|
:loading="transportModeLoading"
|
||||||
placeholder="请选择运输方式"
|
placeholder="请选择运输方式"
|
||||||
@visible-change="visible => visible && ensureTransportModes()"
|
@visible-change="visible => visible && ensureTransportModes()"
|
||||||
><el-option
|
><el-option
|
||||||
v-for="item in transportModeOptions"
|
v-for="item in transportModeOptions"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value" /></el-select></el-form-item
|
:value="item.value" /></el-select></el-form-item
|
||||||
></el-col>
|
></el-col>
|
||||||
<el-col :span="8"
|
<el-col :span="8"
|
||||||
><el-form-item label="默认方案"
|
><el-form-item label="默认方案"
|
||||||
><el-checkbox v-model="draft.defaultPlan" :disabled="readonly">默认方案</el-checkbox
|
><el-checkbox v-model="draft.defaultPlan" :disabled="readonly">默认方案</el-checkbox
|
||||||
><el-icon class="billing-plan-editor__default-tip" @click="showDefaultPlanTip"
|
><el-tooltip content="同一运输方式仅支持配置一个默认计费方案" placement="top">
|
||||||
><InfoFilled
|
<el-icon class="billing-plan-editor__default-tip"
|
||||||
/></el-icon>
|
><InfoFilled
|
||||||
></el-form-item
|
/></el-icon> </el-tooltip
|
||||||
|
></el-form-item
|
||||||
></el-col
|
></el-col
|
||||||
>
|
>
|
||||||
<el-col :span="24"
|
<el-col :span="24"
|
||||||
><el-form-item label="备注"
|
><el-form-item label="备注"
|
||||||
><el-input
|
><el-input
|
||||||
v-model="draft.remark"
|
v-model="draft.remark"
|
||||||
maxlength="100"
|
maxlength="100"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
:disabled="readonly" /></el-form-item
|
:disabled="readonly" /></el-form-item
|
||||||
></el-col>
|
></el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
</section-card>
|
||||||
<div class="rule-head">
|
<div class="rule-head">
|
||||||
<el-link v-if="!readonly" type="primary" @click="addRule">+添加规则</el-link>
|
<el-link v-if="!readonly" type="primary" @click="addRule">+添加规则</el-link>
|
||||||
</div>
|
</div>
|
||||||
@@ -362,6 +366,7 @@ import { getList as getFeeItemList } from '@/api/base/fee-item';
|
|||||||
import { getLazyTree as getRegionLazyTree } from '@/api/base/region';
|
import { getLazyTree as getRegionLazyTree } from '@/api/base/region';
|
||||||
import { InfoFilled } from '@element-plus/icons-vue';
|
import { InfoFilled } from '@element-plus/icons-vue';
|
||||||
import { getDictionary } from '@/api/system/dictbiz';
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
|
import SectionCard from '@/components/section-card/main.vue';
|
||||||
|
|
||||||
const clone = value => JSON.parse(JSON.stringify(value));
|
const clone = value => JSON.parse(JSON.stringify(value));
|
||||||
const defaultRule = () => ({
|
const defaultRule = () => ({
|
||||||
@@ -391,7 +396,7 @@ const defaultRule = () => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { InfoFilled },
|
components: { SectionCard, InfoFilled },
|
||||||
props: {
|
props: {
|
||||||
modelValue: Boolean,
|
modelValue: Boolean,
|
||||||
value: { type: Object, default: () => ({}) },
|
value: { type: Object, default: () => ({}) },
|
||||||
@@ -874,9 +879,6 @@ export default {
|
|||||||
this.visible = false;
|
this.visible = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
showDefaultPlanTip() {
|
|
||||||
this.$message.info('同一运输方式仅支持配置一个默认计费方案');
|
|
||||||
},
|
|
||||||
openMatch(row, index) {
|
openMatch(row, index) {
|
||||||
this.matchIndex = index;
|
this.matchIndex = index;
|
||||||
this.matchForm = { ...defaultRule().matchCondition, ...(row.matchCondition || {}) };
|
this.matchForm = { ...defaultRule().matchCondition, ...(row.matchCondition || {}) };
|
||||||
|
|||||||
@@ -83,7 +83,10 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="change-section change-reason-section"><div class="dialog-section-title">变更原因</div><el-form-item prop="changeReason"><el-input v-model="form.changeReason" type="textarea" :rows="2" maxlength="2000" show-word-limit placeholder="请输入变更原因" /></el-form-item><div class="dialog-section-title">变更材料</div><el-upload action="#" :auto-upload="false" multiple :show-file-list="false" @change="handleChangeMaterial"><el-button plain>上传变更材料</el-button></el-upload></section>
|
<section class="change-section change-reason-section"><div class="dialog-section-title">变更原因</div><el-form-item prop="changeReason"><el-input v-model="form.changeReason" type="textarea" :rows="2" maxlength="2000" show-word-limit placeholder="请输入变更原因" /></el-form-item><div class="dialog-section-title">变更材料</div><el-upload action="#" :auto-upload="false" multiple :show-file-list="false" @change="handleChangeMaterial"><el-button plain>上传变更材料</el-button></el-upload></section>
|
||||||
<div class="page-footer"><el-button type="primary" @click="submit">提交</el-button><el-button @click="$router.back()">关闭</el-button></div>
|
<div class="page-footer">
|
||||||
|
<el-button @click="$router.back()">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submit">提交</el-button>
|
||||||
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<el-dialog v-model="documentPreviewVisible" :title="previewFile.name || '附件预览'" append-to-body destroy-on-close width="90%" top="4vh">
|
<el-dialog v-model="documentPreviewVisible" :title="previewFile.name || '附件预览'" append-to-body destroy-on-close width="90%" top="4vh">
|
||||||
@@ -151,11 +154,11 @@ export default {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
.contract-change-page { min-height: 100%; background: #f5f6fa; }
|
.contract-change-page { min-height: 100%; padding-bottom: 72px; background: #f5f6fa; }
|
||||||
.contract-change-page :deep(.basic-container__card) { border: 0; background: transparent; box-shadow: none; }
|
.contract-change-page :deep(.basic-container__card) { border: 0; background: transparent; box-shadow: none; }
|
||||||
.contract-change-form { background: #f5f6fa; }
|
.contract-change-form { background: #f5f6fa; }
|
||||||
.change-section { padding: 20px 24px; background: #fff; border-bottom: 1px solid #eff1f7; }
|
.change-section { padding: 20px 24px; background: #fff; border-bottom: 1px solid #eff1f7; margin-top: 12px; }
|
||||||
.contract-basic-section { margin-bottom: 12px; padding: 14px 16px 16px; overflow: hidden; background: #fff; border-bottom: 0; border-radius: 6px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); }
|
.contract-basic-section { margin-bottom: 12px; padding: 14px 16px 16px; overflow: hidden; background: #fff; border-bottom: 0; border-radius: 6px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); }
|
||||||
.contract-basic-section > .dialog-section-title { margin-bottom: 20px; color: #303133; }
|
.contract-basic-section > .dialog-section-title { margin-bottom: 20px; color: #303133; }
|
||||||
.contract-basic-section__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 48px; }
|
.contract-basic-section__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 48px; }
|
||||||
@@ -182,8 +185,34 @@ export default {
|
|||||||
.attachment-upload .el-upload { display: inline-flex; }
|
.attachment-upload .el-upload { display: inline-flex; }
|
||||||
.settlement-switch { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
|
.settlement-switch { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
|
||||||
.settlement-form { display: grid; grid-template-columns: repeat(3, minmax(240px, 1fr)); gap: 8px 28px; }
|
.settlement-form { display: grid; grid-template-columns: repeat(3, minmax(240px, 1fr)); gap: 8px 28px; }
|
||||||
.change-reason-section { border: 1px dashed #ff8f9a; margin: 20px 16px; }
|
.change-reason-section { margin: 20px 0; }
|
||||||
.page-footer { display: flex; gap: 16px; padding: 20px 40px; border-top: 1px solid #eff1f7; }
|
.page-footer {
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 230px;
|
||||||
|
z-index: 20;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
min-height: 64px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 12px 24px;
|
||||||
|
background: #fff;
|
||||||
|
border-top: 1px solid #eff1f7;
|
||||||
|
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
|
||||||
|
|
||||||
|
// 统一 12px 间距,与全站底部操作栏(去 gap,由相邻按钮 margin 提供)一致
|
||||||
|
.el-button + .el-button {
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:global(.avue--collapse .page-footer) {
|
||||||
|
left: 60px;
|
||||||
|
}
|
||||||
|
:global(.avue-layout--horizontal .page-footer) {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
@media (max-width: 1200px) { .contract-basic-section__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; } }
|
@media (max-width: 1200px) { .contract-basic-section__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; } }
|
||||||
@media (max-width: 768px) { .contract-basic-section__grid { grid-template-columns: 1fr; } }
|
@media (max-width: 768px) { .contract-basic-section__grid { grid-template-columns: 1fr; } }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -33,16 +33,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #search-menu>
|
<template #search-menu>
|
||||||
<div v-show="searchExpanded" class="contract-manage-page__expiry-search">
|
<div class="contract-manage-page__expiry-search">
|
||||||
<span>签约类型:</span>
|
|
||||||
<el-select v-model="contractSignType" clearable placeholder="请选择">
|
|
||||||
<el-option
|
|
||||||
v-for="item in signTypeOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
<el-check-tag
|
<el-check-tag
|
||||||
v-for="item in expiryTagOptions"
|
v-for="item in expiryTagOptions"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
@@ -55,7 +46,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #contractName="{ row }">
|
<template #contractName="{ row }">
|
||||||
<el-link v-if="row.contractName" type="primary" @click.stop="openDetail(row)">
|
<el-link v-if="row.contractName" type="primary" class="contract-name-cell" @click.stop="openDetail(row)">
|
||||||
{{ row.contractName }}
|
{{ row.contractName }}
|
||||||
</el-link>
|
</el-link>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
@@ -492,8 +483,8 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="contract-manage-page__footer">
|
<div class="contract-manage-page__footer">
|
||||||
<el-button @click="closeForm">关闭</el-button>
|
<el-button @click="closeForm">取消</el-button>
|
||||||
<template v-if="formMode === 'add'">
|
<template v-if="formMode === 'add' || isDraftEdit">
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
plain
|
plain
|
||||||
@@ -803,7 +794,7 @@ import { getToken } from '@/utils/auth';
|
|||||||
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
||||||
import BillingPlanEditor from './components/billing-plan-editor.vue';
|
import BillingPlanEditor from './components/billing-plan-editor.vue';
|
||||||
import PdfPreview from '@/components/pdf-preview/main.vue';
|
import PdfPreview from '@/components/pdf-preview/main.vue';
|
||||||
import { ElImageViewer } from 'element-plus';
|
import { ElImageViewer, ElTreeSelect } from 'element-plus';
|
||||||
import { OpenFileViewer } from '@open-file-viewer/vue';
|
import { OpenFileViewer } from '@open-file-viewer/vue';
|
||||||
import { fallbackPlugin, imagePlugin, officePlugin, textPlugin } from '@open-file-viewer/core';
|
import { fallbackPlugin, imagePlugin, officePlugin, textPlugin } from '@open-file-viewer/core';
|
||||||
import '@open-file-viewer/core/style.css';
|
import '@open-file-viewer/core/style.css';
|
||||||
@@ -1111,7 +1102,6 @@ export default {
|
|||||||
page: { currentPage: 1, pageSize: 10, pageSizes: [10, 20, 50, 100], total: 0 },
|
page: { currentPage: 1, pageSize: 10, pageSizes: [10, 20, 50, 100], total: 0 },
|
||||||
selectionList: [],
|
selectionList: [],
|
||||||
searchExpanded: false,
|
searchExpanded: false,
|
||||||
contractSignType: '',
|
|
||||||
contractExpiryScope: '',
|
contractExpiryScope: '',
|
||||||
contractExpiryStats: { all: 0, within30: 0, within90: 0, over90: 0, expired: 0 },
|
contractExpiryStats: { all: 0, within30: 0, within90: 0, over90: 0, expired: 0 },
|
||||||
expiryTagOptions: [
|
expiryTagOptions: [
|
||||||
@@ -1215,6 +1205,10 @@ export default {
|
|||||||
formMode() {
|
formMode() {
|
||||||
return this.$route.query.mode === 'edit' ? 'edit' : 'add';
|
return this.$route.query.mode === 'edit' ? 'edit' : 'add';
|
||||||
},
|
},
|
||||||
|
// 草稿(approvalStatus=draft)编辑页:按钮与新增页一致(暂存/提交临时/提交正式)
|
||||||
|
isDraftEdit() {
|
||||||
|
return this.formMode === 'edit' && this.form.approvalStatus === 'draft';
|
||||||
|
},
|
||||||
formPageTitle() {
|
formPageTitle() {
|
||||||
return this.$route.query.name || `${this.formMode === 'edit' ? '编辑' : '新增'}合同管理`;
|
return this.$route.query.name || `${this.formMode === 'edit' ? '编辑' : '新增'}合同管理`;
|
||||||
},
|
},
|
||||||
@@ -1397,7 +1391,6 @@ export default {
|
|||||||
const query = this.normalizeSearch({
|
const query = this.normalizeSearch({
|
||||||
...params,
|
...params,
|
||||||
...this.query,
|
...this.query,
|
||||||
...(this.contractSignType ? { signType: this.contractSignType } : {}),
|
|
||||||
...(this.contractExpiryScope ? { expireScope: this.contractExpiryScope } : {}),
|
...(this.contractExpiryScope ? { expireScope: this.contractExpiryScope } : {}),
|
||||||
});
|
});
|
||||||
this.api
|
this.api
|
||||||
@@ -1421,7 +1414,6 @@ export default {
|
|||||||
},
|
},
|
||||||
searchReset() {
|
searchReset() {
|
||||||
this.query = {};
|
this.query = {};
|
||||||
this.contractSignType = '';
|
|
||||||
this.contractExpiryScope = '';
|
this.contractExpiryScope = '';
|
||||||
this.page.currentPage = 1;
|
this.page.currentPage = 1;
|
||||||
this.onLoad(this.page);
|
this.onLoad(this.page);
|
||||||
@@ -1692,7 +1684,10 @@ export default {
|
|||||||
this.organizationOptions = this.normalizeOrganizationTree(organizationTree);
|
this.organizationOptions = this.normalizeOrganizationTree(organizationTree);
|
||||||
this.organizationFlatOptions = this.flattenOrganizationTree(this.organizationOptions);
|
this.organizationFlatOptions = this.flattenOrganizationTree(this.organizationOptions);
|
||||||
const column = this.findColumn(this.tableOption.column, 'organizationName');
|
const column = this.findColumn(this.tableOption.column, 'organizationName');
|
||||||
if (column) column.dicData = this.organizationOptions;
|
if (column) {
|
||||||
|
column.dicData = this.organizationOptions;
|
||||||
|
column.renderSearch = scope => this.renderOrganizationSearch(scope);
|
||||||
|
}
|
||||||
this.syncCurrentOrganizationOption();
|
this.syncCurrentOrganizationOption();
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
@@ -1756,6 +1751,24 @@ export default {
|
|||||||
this.organizationOptions.unshift(item);
|
this.organizationOptions.unshift(item);
|
||||||
this.organizationFlatOptions.unshift(item);
|
this.organizationFlatOptions.unshift(item);
|
||||||
},
|
},
|
||||||
|
renderOrganizationSearch(scope) {
|
||||||
|
// 搜索区所属组织:树形下拉(与客户档案统一)
|
||||||
|
return h(ElTreeSelect, {
|
||||||
|
modelValue: scope.row?.organizationName || '',
|
||||||
|
'onUpdate:modelValue': value => {
|
||||||
|
if (scope.row) scope.row.organizationName = value;
|
||||||
|
},
|
||||||
|
data: this.organizationOptions,
|
||||||
|
'node-key': 'id',
|
||||||
|
'check-strictly': true,
|
||||||
|
filterable: true,
|
||||||
|
clearable: true,
|
||||||
|
'render-after-expand': false,
|
||||||
|
style: 'width: 100%',
|
||||||
|
placeholder: '请选择 所属组织',
|
||||||
|
props: { label: 'label', value: 'id', children: 'children' },
|
||||||
|
});
|
||||||
|
},
|
||||||
integerInput(prop, value) {
|
integerInput(prop, value) {
|
||||||
this.form[prop] = String(value || '').replace(/\D/g, '');
|
this.form[prop] = String(value || '').replace(/\D/g, '');
|
||||||
},
|
},
|
||||||
@@ -2097,17 +2110,28 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.contract-name-cell {
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
.contract-manage-page {
|
.contract-manage-page {
|
||||||
&__expiry-search {
|
&__expiry-search {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding-top: 8px;
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.el-select {
|
// 将 #search-menu slot 容器(即"时间段快捷筛选"组)排到「查询 / 重置 / 收起」之前;
|
||||||
width: 180px;
|
// .avue-form__menu 本身就是 flex + flex-end,整组内容自然靠右,无需额外推挤
|
||||||
}
|
:deep(.avue-crud__search .avue-form__menu > .contract-manage-page__expiry-search) {
|
||||||
|
order: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__footer {
|
&__footer {
|
||||||
@@ -2119,13 +2143,17 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 8px;
|
|
||||||
min-height: 64px;
|
min-height: 64px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 12px 24px;
|
padding: 12px 24px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-top: 1px solid #eff1f7;
|
border-top: 1px solid #eff1f7;
|
||||||
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
|
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
|
||||||
|
|
||||||
|
// 统一 12px 间距,与全站底部操作栏(去 gap,由相邻按钮 margin 提供)一致
|
||||||
|
.el-button + .el-button {
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__flow {
|
&__flow {
|
||||||
@@ -2144,6 +2172,17 @@ export default {
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 搜索区域白底卡片包裹
|
||||||
|
:deep(.avue-crud__search) {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.avue-crud__search:not(.el-card)) {
|
||||||
|
padding: 12px 12px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
&--form {
|
&--form {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
padding-bottom: 72px;
|
padding-bottom: 72px;
|
||||||
@@ -2180,7 +2219,8 @@ export default {
|
|||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
> .dialog-section-title {
|
> .dialog-section-title,
|
||||||
|
:deep(.dialog-section-title) {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
color: #303133;
|
color: #303133;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|||||||
@@ -165,7 +165,7 @@
|
|||||||
:disabled="isBasicInfoReadonly"
|
:disabled="isBasicInfoReadonly"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="业务部门" prop="businessDeptId" class="project-apply-form__item--full">
|
<el-form-item label="业务部门" prop="businessDeptId">
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
v-model="form.businessDeptId"
|
v-model="form.businessDeptId"
|
||||||
:data="businessDeptTreeOptions"
|
:data="businessDeptTreeOptions"
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="项目由来说明" prop="sourceRemark" class="project-apply-form__item--full">
|
<el-form-item label="项目由来说明" prop="sourceRemark" class="project-apply-form__item--full">
|
||||||
<el-input v-model="form.sourceRemark" maxlength="300" :disabled="isBasicInfoReadonly" />
|
<el-input v-model="form.sourceRemark" type="textarea" rows="2" maxlength="300" :disabled="isBasicInfoReadonly" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -2190,7 +2190,7 @@ export default {
|
|||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 占满整行的表单项(业务部门 / 项目由来说明)
|
// 占满整行的表单项(如项目由来说明等多行文本字段)
|
||||||
:deep(.project-apply-form__item--full) {
|
:deep(.project-apply-form__item--full) {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,19 @@
|
|||||||
<el-input v-model="query.paymentNo" clearable placeholder="请输入" />
|
<el-input v-model="query.paymentNo" clearable placeholder="请输入" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="使用部门">
|
<el-form-item label="使用部门">
|
||||||
<el-input v-model="query.deptName" clearable placeholder="请输入" />
|
<el-tree-select
|
||||||
|
:model-value="query.deptName"
|
||||||
|
:data="organizationTreeOptions"
|
||||||
|
node-key="id"
|
||||||
|
check-strictly
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
render-after-expand
|
||||||
|
style="width: 100%"
|
||||||
|
placeholder="请选择 所属组织"
|
||||||
|
:props="{ label: 'label', value: 'id', children: 'children' }"
|
||||||
|
@update:model-value="val => { query.deptName = findOrgById(val)?.rawLabel || val }"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="付款日期">
|
<el-form-item label="付款日期">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
@@ -47,9 +59,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue';
|
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue';
|
||||||
import { approvalStatusOptions } from '@/api/payment/billPayment';
|
import { approvalStatusOptions } from '@/api/payment/billPayment';
|
||||||
|
import organizationSearch from '@/mixins/organization-search';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'BillPaymentSearch',
|
name: 'BillPaymentSearch',
|
||||||
|
mixins: [organizationSearch],
|
||||||
props: {
|
props: {
|
||||||
query: { type: Object, required: true },
|
query: { type: Object, required: true },
|
||||||
loading: { type: Boolean, default: false },
|
loading: { type: Boolean, default: false },
|
||||||
@@ -58,6 +72,9 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return { ArrowDown, ArrowUp, expanded: false, approvalStatusOptions };
|
return { ArrowDown, ArrowUp, expanded: false, approvalStatusOptions };
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.loadOrganizationOptions();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,19 @@
|
|||||||
<el-input v-model="query.projectName" clearable placeholder="请输入" />
|
<el-input v-model="query.projectName" clearable placeholder="请输入" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="所属组织">
|
<el-form-item label="所属组织">
|
||||||
<el-input v-model="query.deptName" clearable placeholder="请输入" />
|
<el-tree-select
|
||||||
|
:model-value="query.deptName"
|
||||||
|
:data="organizationTreeOptions"
|
||||||
|
node-key="id"
|
||||||
|
check-strictly
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
render-after-expand
|
||||||
|
style="width: 100%"
|
||||||
|
placeholder="请选择 所属组织"
|
||||||
|
:props="{ label: 'label', value: 'id', children: 'children' }"
|
||||||
|
@update:model-value="val => { query.deptName = findOrgById(val)?.rawLabel || val }"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item class="invoice-kingdee-item" label="金蝶单据状态">
|
<el-form-item class="invoice-kingdee-item" label="金蝶单据状态">
|
||||||
<el-select v-model="query.kingdeeStatus" clearable placeholder="请选择">
|
<el-select v-model="query.kingdeeStatus" clearable placeholder="请选择">
|
||||||
@@ -234,6 +246,7 @@ import * as XLSX from 'xlsx';
|
|||||||
import * as api from '@/api/payment/invoiceApplication';
|
import * as api from '@/api/payment/invoiceApplication';
|
||||||
import * as formalSettlementApi from '@/api/settlement/formalSettlement';
|
import * as formalSettlementApi from '@/api/settlement/formalSettlement';
|
||||||
import { invoiceApplicationTableColumns } from '@/option/payment/invoiceApplication';
|
import { invoiceApplicationTableColumns } from '@/option/payment/invoiceApplication';
|
||||||
|
import organizationSearch from '@/mixins/organization-search';
|
||||||
|
|
||||||
const emptyQuery = () => ({
|
const emptyQuery = () => ({
|
||||||
applicationNo: '',
|
applicationNo: '',
|
||||||
@@ -245,6 +258,7 @@ const emptyQuery = () => ({
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'InvoiceApplication',
|
name: 'InvoiceApplication',
|
||||||
|
mixins: [organizationSearch],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
ArrowDown,
|
ArrowDown,
|
||||||
@@ -266,6 +280,7 @@ export default {
|
|||||||
...mapGetters(['permission']),
|
...mapGetters(['permission']),
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.loadOrganizationOptions();
|
||||||
this.loadTable();
|
this.loadTable();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -19,7 +19,19 @@
|
|||||||
<el-input v-model="query.projectName" clearable placeholder="请输入" />
|
<el-input v-model="query.projectName" clearable placeholder="请输入" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="所属组织">
|
<el-form-item label="所属组织">
|
||||||
<el-input v-model="query.deptName" clearable placeholder="请输入" />
|
<el-tree-select
|
||||||
|
:model-value="query.deptName"
|
||||||
|
:data="organizationTreeOptions"
|
||||||
|
node-key="id"
|
||||||
|
check-strictly
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
render-after-expand
|
||||||
|
style="width: 100%"
|
||||||
|
placeholder="请选择 所属组织"
|
||||||
|
:props="{ label: 'label', value: 'id', children: 'children' }"
|
||||||
|
@update:model-value="val => { query.deptName = findOrgById(val)?.rawLabel || val }"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="searchExpanded" label="审核状态">
|
<el-form-item v-if="searchExpanded" label="审核状态">
|
||||||
<el-select v-model="query.approvalStatus" clearable placeholder="请选择">
|
<el-select v-model="query.approvalStatus" clearable placeholder="请选择">
|
||||||
@@ -226,6 +238,7 @@ import { mapGetters } from 'vuex';
|
|||||||
import * as XLSX from 'xlsx';
|
import * as XLSX from 'xlsx';
|
||||||
import * as api from '@/api/payment/invoiceReceipt';
|
import * as api from '@/api/payment/invoiceReceipt';
|
||||||
import { invoiceReceiptTableColumns } from '@/option/payment/invoiceReceipt';
|
import { invoiceReceiptTableColumns } from '@/option/payment/invoiceReceipt';
|
||||||
|
import organizationSearch from '@/mixins/organization-search';
|
||||||
|
|
||||||
const emptyQuery = () => ({
|
const emptyQuery = () => ({
|
||||||
invoiceNo: '',
|
invoiceNo: '',
|
||||||
@@ -238,6 +251,7 @@ const emptyQuery = () => ({
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'InvoiceReceipt',
|
name: 'InvoiceReceipt',
|
||||||
|
mixins: [organizationSearch],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
ArrowDown,
|
ArrowDown,
|
||||||
@@ -259,6 +273,7 @@ export default {
|
|||||||
...mapGetters(['permission']),
|
...mapGetters(['permission']),
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.loadOrganizationOptions();
|
||||||
this.loadTable();
|
this.loadTable();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -23,7 +23,18 @@
|
|||||||
/></el-form-item>
|
/></el-form-item>
|
||||||
<template v-if="searchExpanded">
|
<template v-if="searchExpanded">
|
||||||
<el-form-item label="所属组织"
|
<el-form-item label="所属组织"
|
||||||
><el-input v-model="query.deptName" clearable
|
><el-tree-select
|
||||||
|
:model-value="query.deptName"
|
||||||
|
:data="organizationTreeOptions"
|
||||||
|
node-key="id"
|
||||||
|
check-strictly
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
render-after-expand
|
||||||
|
style="width: 100%"
|
||||||
|
placeholder="请选择 所属组织"
|
||||||
|
:props="{ label: 'label', value: 'id', children: 'children' }"
|
||||||
|
@update:model-value="val => { query.deptName = findOrgById(val)?.rawLabel || val }"
|
||||||
/></el-form-item>
|
/></el-form-item>
|
||||||
<el-form-item label="关联结算单"
|
<el-form-item label="关联结算单"
|
||||||
><el-input v-model="query.settlementNo" clearable
|
><el-input v-model="query.settlementNo" clearable
|
||||||
@@ -224,6 +235,7 @@ import { ArrowDown, ArrowUp, Refresh } from '@element-plus/icons-vue';
|
|||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import * as api from '@/api/payment/paymentApplication';
|
import * as api from '@/api/payment/paymentApplication';
|
||||||
import { paymentApplicationTableColumns } from '@/option/payment/paymentApplication';
|
import { paymentApplicationTableColumns } from '@/option/payment/paymentApplication';
|
||||||
|
import organizationSearch from '@/mixins/organization-search';
|
||||||
|
|
||||||
const emptyQuery = () => ({
|
const emptyQuery = () => ({
|
||||||
paymentNo: '',
|
paymentNo: '',
|
||||||
@@ -238,6 +250,7 @@ const emptyQuery = () => ({
|
|||||||
});
|
});
|
||||||
export default {
|
export default {
|
||||||
name: 'PaymentApplication',
|
name: 'PaymentApplication',
|
||||||
|
mixins: [organizationSearch],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
ArrowDown,
|
ArrowDown,
|
||||||
@@ -263,6 +276,7 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.loadOrganizationOptions();
|
||||||
this.loadTable();
|
this.loadTable();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -32,6 +32,15 @@
|
|||||||
</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)"
|
||||||
@@ -177,7 +186,9 @@ export default {
|
|||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
selection: true,
|
selection: true,
|
||||||
viewBtn: true,
|
viewBtn: false,
|
||||||
|
editBtn: false,
|
||||||
|
delBtn: false,
|
||||||
menuWidth: 320,
|
menuWidth: 320,
|
||||||
dialogWidth: 800,
|
dialogWidth: 800,
|
||||||
dialogClickModal: false,
|
dialogClickModal: false,
|
||||||
@@ -519,6 +530,15 @@ 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);
|
||||||
|
|||||||
@@ -204,7 +204,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</section-card>
|
</section-card>
|
||||||
<el-tabs class="user-permission-tabs">
|
<el-tabs type="border-card" class="user-permission-tabs">
|
||||||
<el-tab-pane label="已拥有角色">
|
<el-tab-pane label="已拥有角色">
|
||||||
<el-table :data="formRoleList" border>
|
<el-table :data="formRoleList" border>
|
||||||
<el-table-column type="index" label="序号" width="70" />
|
<el-table-column type="index" label="序号" width="70" />
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<basic-container>
|
<basic-container>
|
||||||
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
|
<el-tabs type="border-card" v-model="activeTab" @tab-change="handleTabChange">
|
||||||
<!-- 个人信息 Tab -->
|
<!-- 个人信息 Tab -->
|
||||||
<el-tab-pane label="个人信息" name="info">
|
<el-tab-pane label="个人信息" name="info">
|
||||||
<el-form ref="infoForm" :model="infoForm" label-width="auto">
|
<el-form ref="infoForm" :model="infoForm" label-width="auto">
|
||||||
|
|||||||
@@ -591,6 +591,7 @@ import {
|
|||||||
} from '@/api/transportCapacity/driver';
|
} from '@/api/transportCapacity/driver';
|
||||||
import { getList as getVehicleList } from '@/api/transportCapacity/transport-vehicle';
|
import { getList as getVehicleList } from '@/api/transportCapacity/transport-vehicle';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
|
import organizationSearch from '@/mixins/organization-search';
|
||||||
import { getDictionary } from '@/api/system/dictbiz';
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
import { getLazyTree } from '@/api/base/region';
|
import { getLazyTree } from '@/api/base/region';
|
||||||
import { exportBlob } from '@/api/common';
|
import { exportBlob } from '@/api/common';
|
||||||
@@ -661,6 +662,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
ImageUploadField,
|
ImageUploadField,
|
||||||
},
|
},
|
||||||
|
mixins: [organizationSearch],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
option,
|
option,
|
||||||
@@ -849,6 +851,7 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initDeptTree();
|
this.initDeptTree();
|
||||||
|
this.loadOrganizationOptions();
|
||||||
this.initRegionOptions();
|
this.initRegionOptions();
|
||||||
this.initQualificationTypeOptions();
|
this.initQualificationTypeOptions();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -574,6 +574,7 @@ import { ElLoading } from 'element-plus';
|
|||||||
import { InfoFilled } from '@element-plus/icons-vue';
|
import { InfoFilled } from '@element-plus/icons-vue';
|
||||||
import { option } from '@/option/transportCapacity/transport-ship';
|
import { option } from '@/option/transportCapacity/transport-ship';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
|
import organizationSearch from '@/mixins/organization-search';
|
||||||
import {
|
import {
|
||||||
getList,
|
getList,
|
||||||
getDetail,
|
getDetail,
|
||||||
@@ -639,6 +640,7 @@ const emptyForm = () => ({
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ImageUploadField, InfoFilled, ShipLedger },
|
components: { ImageUploadField, InfoFilled, ShipLedger },
|
||||||
|
mixins: [organizationSearch],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
option,
|
option,
|
||||||
@@ -731,6 +733,7 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initDeptTree();
|
this.initDeptTree();
|
||||||
|
this.loadOrganizationOptions();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
hasPermission(code) {
|
hasPermission(code) {
|
||||||
|
|||||||
@@ -544,6 +544,7 @@ import {
|
|||||||
recognizeBaiduOcr,
|
recognizeBaiduOcr,
|
||||||
} from '@/api/transportCapacity/transport-vehicle';
|
} from '@/api/transportCapacity/transport-vehicle';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
|
import organizationSearch from '@/mixins/organization-search';
|
||||||
import { exportBlob } from '@/api/common';
|
import { exportBlob } from '@/api/common';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { getUploadHeaders } from '@/utils/upload';
|
import { getUploadHeaders } from '@/utils/upload';
|
||||||
@@ -633,6 +634,7 @@ export default {
|
|||||||
ImageUploadField,
|
ImageUploadField,
|
||||||
VehicleLedger,
|
VehicleLedger,
|
||||||
},
|
},
|
||||||
|
mixins: [organizationSearch],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
option,
|
option,
|
||||||
@@ -747,6 +749,7 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initDeptTree();
|
this.initDeptTree();
|
||||||
|
this.loadOrganizationOptions();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
hasPermission(code) {
|
hasPermission(code) {
|
||||||
|
|||||||
@@ -4643,7 +4643,7 @@ export default {
|
|||||||
white-space: normal !important;
|
white-space: normal !important;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
line-height: 18px;
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 锁定表单项 label 与控件垂直居中对齐(避免长 label 折行时视觉错位)
|
// 锁定表单项 label 与控件垂直居中对齐(避免长 label 折行时视觉错位)
|
||||||
@@ -4657,8 +4657,6 @@ export default {
|
|||||||
// 通过 padding 把内容下沉到 label 中线,让 * 视觉中心落在第一行文字中心。
|
// 通过 padding 把内容下沉到 label 中线,让 * 视觉中心落在第一行文字中心。
|
||||||
:deep(.el-form-item.is-required .el-form-item__label) {
|
:deep(.el-form-item.is-required .el-form-item__label) {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
padding-top: 7px;
|
|
||||||
padding-bottom: 7px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-form-item.is-required .el-form-item__label::before) {
|
:deep(.el-form-item.is-required .el-form-item__label::before) {
|
||||||
|
|||||||
Reference in New Issue
Block a user