优化前端页面布局细节

This commit is contained in:
wjj
2026-07-13 16:46:37 +08:00
parent 7a317204f7
commit ded07a2c33
23 changed files with 495 additions and 141 deletions

View File

@@ -0,0 +1,21 @@
# 账号库管理页面布局对齐实施记录
## 修改内容
- 移除账号库管理页额外的 `.board` 卡片容器。
- 移除账号库管理页额外的灰色页面背景、圆角、边框和卡片内边距。
- 保留查询区、按钮区、表格、分页和弹窗表单的原有业务逻辑。
## 影响范围
- 前端页面:`ruoyi-ui/src/views/ccdiAccountInfo/index.vue`
- 未修改接口、查询参数、表格字段、导入逻辑、权限配置和后端代码。
## 验证情况
- 已执行 `node tests/unit/account-info-layout-polish.test.js`,账号库列顺序和外层卡片移除断言通过。
- 已使用 Node 22.22.3 + npm 10.9.8 执行 `npm run build:prod`,构建通过;因本机 Node 14.21.3 缺少 npm未使用 `.nvmrc` 指向版本。
- 已通过真实前端页面 `http://127.0.0.1:8088/ccdiAccountInfo` 验证:
- 列表表头为“所属人类型、员工姓名、关系类型、证件号、账户姓名、账户号码、账户类型、账户范围”。
- 页面不再存在 `.account-page``.board` 外层卡片容器。
- 查询区标签均为单行显示,页面无横向溢出。

View File

@@ -0,0 +1,27 @@
# 实体统一社会信用代码查询区布局实施记录
## 修改内容
- 实体库管理查询区统一使用 136px 标签宽度,并设置查询区标签不换行。
- 实体库管理查询区保持每个字段 6 栅格,使上下两行输入框左边界和宽度对齐。
- 信贷客户实体关联查询区统一使用 136px 标签宽度,并设置查询区标签不换行。
- 信贷客户实体关联查询区保持每个字段 6 栅格,使同一行输入框左边界和宽度对齐。
## 影响范围
- `ruoyi-ui/src/views/ccdiEnterpriseBaseInfo/index.vue`
- `ruoyi-ui/src/views/ccdiCustEnterpriseRelation/index.vue`
- 本次仅调整查询区展示布局,不修改查询参数、接口、表格字段、导入逻辑和后端代码。
## 验证情况
- 已使用 Node 22.22.3 + npm 10.9.8 执行 `npm run build:prod`,构建通过;本机 `.nvmrc` 指向的 Node 14.21.3 缺少 npm未使用该不完整环境。
- 已通过真实页面 `http://127.0.0.1:8088/maintain/enterpriseBaseInfo` 验证:
- “统一社会信用代码”标签单行显示,标签高度 32px。
- 查询区上下两行输入框按列对齐,当前 1280px 视口下各列输入框左边界为 396/650/904/1158px。
- 页面无横向溢出。
- 已通过真实页面 `http://127.0.0.1:8088/maintain/custEnterpriseRelation` 验证:
- “统一社会信用代码”标签单行显示,标签高度 32px。
- 查询区输入框按列对齐,当前 1280px 视口下各列输入框左边界为 396/650/904/1158px。
- 页面无横向溢出。
- 浏览器控制台错误数为 0。

View File

@@ -0,0 +1,58 @@
# 前端页面布局小优化实施记录
## 修改背景
对近期涉及的前端页面进行风格检查后,发现部分后台表格和筛选区存在列顺序不顺、下拉框宽度偏窄、窄屏挤压和长文本撑开表格的问题。本次只做页面展示层小优化,不调整接口和业务逻辑。
## 修改内容
1. 流水明细查询
- 将“交易金额”列移动到“异常标签”列前面。
- 将“交易金额”列控制为 120px“异常标签”列控制为 220px避免列宽虚高。
- 长账号、长摘要和长名称允许在单元格内断行,避免撑开表格。
- 单个超长异常标签限制在列内省略展示,避免撑开表格。
2. 风险明细-涉疑交易明细
- 将“命中模型”和“预警类型”筛选框统一调整为 240px。
- 查询按钮设置最小宽度,避免筛选栏视觉抖动。
- 将“交易金额”列移动到“异常标签”列前面,与流水明细查询保持一致。
- 将“交易金额”列控制为 120px“异常标签”列控制为 220px避免列宽虚高。
- 长账号、长摘要和长名称允许在单元格内断行。
- 单个超长异常标签限制在列内省略展示。
3. 风险模型
- 保留“模型预警统计”“命中模型涉及人员”两个区块标题。
- “模型预警统计”说明文案缩短为“点击筛选”,“命中模型涉及人员”标题下不再展示说明文案。
4. 账户库
- 列表列顺序调整为“所属人类型”在前,“员工姓名”在后,便于先判断账户归属分类。
- 查询区改为响应式列宽:手机一列、平板两列、中等屏三列、大屏四列。
- 账户库编辑/详情弹窗改为 92% 自适应宽度,并限制最大宽度 1160px。
- 员工姓名、账户姓名、账户号码增加溢出提示,避免长文本撑开表格。
## 影响范围
- 影响项目详情中的“流水明细查询”展示。
- 影响项目详情中的“风险明细-涉疑交易明细”筛选区和表格文本展示。
- 影响项目详情中的“风险模型”区块标题展示。
- 影响账户库列表查询区、表格长文本展示和编辑/详情弹窗宽度。
- 不改接口、不改后端、不改数据结构。
## 验证情况
- 已补充前端源码结构单测,覆盖流水明细查询/涉疑交易明细金额列顺序、涉疑交易筛选框宽度、账户库列表列顺序和账户库布局优化。
- 已执行前端结构单测:
- `node tests/unit/detail-query-hit-tags-list.test.js`
- `node tests/unit/risk-detail-suspicious-transaction-layout.test.js`
- `node tests/unit/account-info-layout-polish.test.js`
- 已执行 `npm run build:prod`,构建通过;存在既有资源体积告警,且当前工作区未跟踪的 `0uS5znL.docx` 会被构建扫描到,不属于本次代码改动。
- 本次构建使用 Node 22.22.3 + npm 10.9.8;本机 `.nvmrc` 指向的 Node 14.21.3 缺少 npm未继续使用该不完整环境。
- 已复查流水明细查询和涉疑交易明细列顺序与列宽:交易金额列位于异常标签列前,金额列宽为 120px异常标签列宽为 220px摘要/交易类型列收窄并允许长文本断行,单个超长异常标签在列内省略,避免长文本遮挡后续列。
- 已启动真实后端和前端开发服务检查页面:
- 账户库列表、查询区、详情弹窗可正常渲染。
- 账户库列表列头已确认调整为“所属人类型”在“员工姓名”前。
- 账户库窄屏查询区无页面级横向溢出。
- 项目详情“流水明细查询”中“交易金额”列已在“异常标签”列前。
- 项目详情“结果总览-涉疑交易明细”中“交易金额”列已在“异常标签”列前。
- 项目详情“流水明细查询”和“结果总览-涉疑交易明细”均已临时注入超长金额、超长异常标签做极限宽度验收;交易金额列保持 120px异常标签列保持 220px页面无横向溢出。
- “模型预警统计”标题保留并仅显示“点击筛选”,“命中模型涉及人员”标题保留且不再显示“查看明细”。

View File

@@ -0,0 +1,26 @@
# 项目快捷入口模板预填实施记录
## 修改内容
- 将项目首页“创建季度初核”“创建新员工排查”“创建高风险专项”三个快捷入口改为模板化打开新建项目弹窗。
- 按当前日期自动生成项目名称与项目描述:
- 季度初核:生成当年当季度纪检初核项目。
- 新员工排查:生成当年当月新员工排查项目。
- 高风险专项:生成当年高风险专项排查项目。
- 高风险专项默认选择“自定义项目规则参数配置”,季度初核与新员工排查默认选择“全局默认模型参数配置”。
- 调整快捷卡片副标题,明确提示入口会预填对应模板。
## 影响范围
- 前端页面:`ruoyi-ui/src/views/ccdiProject/index.vue`
- 快捷入口组件:`ruoyi-ui/src/views/ccdiProject/components/QuickEntry.vue`
- 未新增后端字段、接口、数据库脚本或菜单权限。
## 验证情况
- 已使用 Node 22.22.3 + npm 10.9.8 执行 `npm run build:prod`,构建通过;因本机 Node 14.21.3 缺少 npm未使用 `.nvmrc` 指向版本。
- 已通过真实前端页面 `http://127.0.0.1:8088/ccdiProject` 验证:
- 项目列表“最近更新时间”表头正常显示。
- 快捷入口副标题显示为“预填本季度项目模板”等模板化文案。
- 点击“创建季度初核”后弹窗标题为“创建季度初核项目”项目名称预填为“2026年第三季度纪检初核项目”项目描述预填为“用于开展2026年第三季度纪检初核排查工作。”。
- 验证过程中未提交新增项目。

View File

@@ -0,0 +1,21 @@
# 员工亲属实体关联查询区布局优化实施记录
## 修改内容
- 将员工亲属实体关联页查询区的“统一社会信用代码”字段调整为局部宽标签,不扩大整页所有查询项标签宽度。
- 保持查询区两行均为 8/8/8 三列对齐,只缩短“统一社会信用代码”输入框宽度,避免长标签挤压或换行。
- 为查询表单标签增加不换行约束,避免长标签撑高搜索区行高。
## 影响范围
- 前端页面:`ruoyi-ui/src/views/ccdiStaffEnterpriseRelation/index.vue`
- 未修改查询参数、接口、表格字段、导入逻辑、权限配置和后端代码。
## 验证情况
- 已执行前端结构检查,确认员工调动记录和图谱模块没有纳入本次改动。
- 已使用 Node 22.22.3 + npm 10.9.8 执行 `npm run build:prod`,构建通过;因本机 Node 14.21.3 缺少 npm未使用 `.nvmrc` 指向版本。
- 已通过真实前端页面 `http://127.0.0.1:8088/maintain/staffEnterpriseRelation` 验证:
- 两行查询项均保持三列对齐,列起点一致。
- “统一社会信用代码”标签单行显示,标签宽度 136px输入框宽度约 187px。
- 页面无横向溢出。

View File

@@ -0,0 +1,21 @@
# 员工亲属关系查询区布局优化实施记录
## 修改内容
- 将员工亲属关系维护页查询表单标签宽度调整为 128px避免“关系人身份证号”等长标签换行。
- 为查询表单标签增加不换行约束,避免单个字段撑高整行。
- 为员工身份证号、关系人身份证号列表列增加固定展示宽度并开启溢出提示。
## 影响范围
- 前端页面:`ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue`
- 未修改查询参数、接口、数据库脚本、导入逻辑和权限配置。
## 验证情况
- 已执行前端结构检查,确认员工调动记录和图谱模块没有纳入本次改动。
- 已使用 Node 22.22.3 + npm 10.9.8 执行 `npm run build:prod`,构建通过;因本机 Node 14.21.3 缺少 npm未使用 `.nvmrc` 指向版本。
- 已通过真实前端页面 `http://127.0.0.1:8088/maintain/staffFmyRelation` 验证:
- “关系人身份证号”标签单行显示,标签高度 32px。
- 第一行查询项顶部坐标一致,第二行“状态”未被前一行撑出异常空隙。
- 身份证号相关表格列未造成页面级横向溢出。

View File

@@ -0,0 +1,26 @@
# 用户管理与新增贷款查询布局调整实施记录
## 修改内容
- 新增贷款查询页将首个“柜员号”查询项的局部标签宽度调整为 72px使输入框整体向前靠拢不影响“审核人柜员号”等长标签字段。
- 系统管理-用户管理列表将“用户编号”列改为“编号”,并固定宽度为 80px。
- 用户管理新增/修改弹窗去掉页面上的“用户性别”“岗位”“备注”表单项。
- 用户管理新增/修改弹窗保留“状态”和“角色”,不调整接口、权限和提交方法。
## 影响范围
- `ruoyi-ui/src/views/ccdiProject/components/detail/IncreaseLendingSection.vue`
- `ruoyi-ui/src/views/system/user/index.vue`
- 本次仅修改前端展示层,不修改后端接口、数据库结构和权限配置。
## 验证情况
- 已使用 Node 22.22.3 + npm 10.9.8 执行 `npm run build:prod`,构建通过;本机 `.nvmrc` 指向的 Node 14.21.3 缺少 npm未使用该不完整环境。
- 已通过真实页面 `http://127.0.0.1:8088/system/user` 验证:
- 用户列表第一列显示为“编号”,宽度为 80px。
- 新增用户弹窗不再显示“用户性别”“岗位”“备注”,保留“状态”“角色”。
- 修改用户弹窗不再显示“用户性别”“岗位”“备注”,保留“状态”“角色”。
- 已通过真实页面 `http://127.0.0.1:8088/ccdiProject/detail/42?tab=special` 验证:
- 新增贷款查询“柜员号”标签宽度为 72px输入框较原 104px 标签宽度向前靠拢。
- 页面无横向溢出。
- 浏览器控制台错误数为 0。

View File

@@ -1,6 +1,5 @@
<template>
<div class="app-container account-page">
<div class="board">
<div class="app-container">
<el-form
v-show="showSearch"
ref="queryForm"
@@ -10,7 +9,7 @@
label-width="96px"
>
<el-row :gutter="16">
<el-col :span="6">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="所属人类型">
<el-select v-model="queryParams.ownerType" placeholder="请选择所属人类型" clearable style="width: 100%">
<el-option label="员工" value="EMPLOYEE" />
@@ -20,12 +19,12 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="员工姓名">
<el-input v-model="queryParams.staffName" placeholder="请输入员工姓名" clearable style="width: 100%" @keyup.enter.native="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="账户范围">
<el-select v-model="queryParams.bankScope" placeholder="请选择账户范围" clearable style="width: 100%">
<el-option label="行内" value="INTERNAL" />
@@ -33,19 +32,19 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="关系类型">
<el-select v-model="queryParams.relationType" placeholder="请选择关系类型" clearable style="width: 100%">
<el-option v-for="item in relationTypeOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="账户姓名">
<el-input v-model="queryParams.accountName" placeholder="请输入账户姓名" clearable style="width: 100%" @keyup.enter.native="handleQuery" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="账户类型">
<el-select v-model="queryParams.accountType" placeholder="请选择账户类型" clearable style="width: 100%">
<el-option label="银行账户" value="BANK" />
@@ -55,7 +54,7 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="是否实控">
<el-select v-model="queryParams.isActualControl" placeholder="请选择是否实控" clearable style="width: 100%">
<el-option label="是" :value="1" />
@@ -63,7 +62,7 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="风险等级">
<el-select v-model="queryParams.riskLevel" placeholder="请选择风险等级" clearable style="width: 100%">
<el-option label="LOW" value="LOW" />
@@ -72,7 +71,7 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="状态">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 100%">
<el-option label="正常" :value="1" />
@@ -114,9 +113,6 @@
</el-row>
<el-table v-loading="loading" :data="rows" stripe border class="account-table">
<el-table-column label="员工姓名" prop="staffName" min-width="120">
<template slot-scope="scope">{{ scope.row.staffName || '-' }}</template>
</el-table-column>
<el-table-column label="所属人类型" prop="ownerType" width="132" align="center">
<template slot-scope="scope">
<el-tag :type="ownerTypeTagType(scope.row.ownerType)" size="mini" effect="plain">
@@ -124,16 +120,19 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="员工姓名" prop="staffName" min-width="120" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.staffName || '-' }}</template>
</el-table-column>
<el-table-column label="关系类型" prop="relationType" width="90" align="center">
<template slot-scope="scope">{{ scope.row.relationType || '-' }}</template>
</el-table-column>
<el-table-column label="证件号" prop="ownerId" min-width="170" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.ownerId || scope.row.relationCertNo || '-' }}</template>
</el-table-column>
<el-table-column label="账户姓名" prop="accountName" min-width="120">
<el-table-column label="账户姓名" prop="accountName" min-width="120" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.accountName || '-' }}</template>
</el-table-column>
<el-table-column label="账户号码" prop="accountNo" min-width="180" />
<el-table-column label="账户号码" prop="accountNo" min-width="180" show-overflow-tooltip />
<el-table-column label="账户类型" prop="accountType" width="110" align="center">
<template slot-scope="scope">{{ accountTypeLabel(scope.row.accountType) }}</template>
</el-table-column>
@@ -195,10 +194,15 @@
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
</div>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="1160px" append-to-body>
<el-dialog
:title="dialogTitle"
:visible.sync="dialogVisible"
width="92%"
custom-class="account-info-dialog"
append-to-body
>
<el-form ref="dialogForm" :model="form" :rules="rules" label-width="120px">
<div class="form-section">
<div class="section-head"><span>归属信息</span></div>
@@ -887,23 +891,15 @@ export default {
margin-right: 0;
}
.account-page {
min-height: calc(100vh - 84px);
background: #f5f7fa;
}
.board {
padding: 20px;
border-radius: 8px;
background: #fff;
border: 1px solid #ebeef5;
}
.account-table ::v-deep .el-table__header th {
background: #f8f8f9;
color: #515a6e;
}
::v-deep .account-info-dialog {
max-width: 1160px;
}
.form-section {
margin-bottom: 18px;
padding: 18px 18px 4px;
@@ -930,4 +926,15 @@ export default {
font-weight: 700;
}
@media (max-width: 768px) {
::v-deep .account-info-dialog {
width: calc(100vw - 24px) !important;
margin-top: 8vh !important;
}
::v-deep .account-info-dialog .el-dialog__body {
padding: 18px 16px;
}
}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" v-show="showSearch" label-width="120px" class="query-form">
<el-form :model="queryParams" ref="queryForm" size="small" v-show="showSearch" label-width="136px" class="query-form">
<el-row :gutter="16">
<el-col :span="6">
<el-form-item label="身份证号" prop="personId">
@@ -854,6 +854,10 @@ export default {
margin-right: 0;
}
.query-form ::v-deep .el-form-item__label {
white-space: nowrap;
}
.detail-container {
padding: 0 20px;
}

View File

@@ -1,6 +1,6 @@
<template>
<div class="app-container">
<el-form ref="queryForm" :model="queryParams" size="small" v-show="showSearch" label-width="110px" class="query-form">
<el-form ref="queryForm" :model="queryParams" size="small" v-show="showSearch" label-width="136px" class="query-form">
<el-row :gutter="16">
<el-col :span="6">
<el-form-item label="企业名称" prop="enterpriseName">
@@ -1002,6 +1002,10 @@ export default {
margin-right: 0;
}
.query-form ::v-deep .el-form-item__label {
white-space: nowrap;
}
.el-upload__tip {
line-height: 1.6;
}

View File

@@ -22,7 +22,7 @@
<el-table-column
prop="updateTime"
label="更新/创建时间"
label="最近更新时间"
width="180"
align="center"
>

View File

@@ -23,7 +23,7 @@
</div>
<div class="card-content">
<div class="card-title">创建季度初核</div>
<div class="card-desc">创建季度初核</div>
<div class="card-desc">预填本季度项目模板</div>
</div>
</div>
</el-col>
@@ -34,7 +34,7 @@
</div>
<div class="card-content">
<div class="card-title">创建新员工排查</div>
<div class="card-desc">创建新员工排查</div>
<div class="card-desc">预填本月排查模板</div>
</div>
</div>
</el-col>
@@ -45,7 +45,7 @@
</div>
<div class="card-content">
<div class="card-title">创建高风险专项</div>
<div class="card-desc">创建高风险专项</div>
<div class="card-desc">预填专项排查模板</div>
</div>
</div>
</el-col>

View File

@@ -226,7 +226,7 @@
</div>
</template>
</el-table-column>
<el-table-column label="摘要 / 交易类型" min-width="240">
<el-table-column label="摘要 / 交易类型" min-width="200">
<template slot-scope="scope">
<div class="multi-line-cell">
<div class="primary-text">{{ formatField(scope.row.userMemo) }}</div>
@@ -234,6 +234,22 @@
</div>
</template>
</el-table-column>
<el-table-column
label="交易金额"
prop="displayAmount"
width="120"
align="right"
sortable="custom"
>
<template slot-scope="scope">
<span
class="amount-text"
:class="scope.row.displayAmount >= 0 ? 'amount-in' : 'amount-out'"
>
{{ formatAmount(scope.row.displayAmount) }}
</span>
</template>
</el-table-column>
<el-table-column label="异常标签" min-width="220">
<template slot-scope="scope">
<div v-if="scope.row.hitTags && scope.row.hitTags.length" class="hit-tag-list">
@@ -250,22 +266,6 @@
<span v-else class="empty-text">-</span>
</template>
</el-table-column>
<el-table-column
label="交易金额"
prop="displayAmount"
min-width="140"
align="right"
sortable="custom"
>
<template slot-scope="scope">
<span
class="amount-text"
:class="scope.row.displayAmount >= 0 ? 'amount-in' : 'amount-out'"
>
{{ formatAmount(scope.row.displayAmount) }}
</span>
</template>
</el-table-column>
<el-table-column label="详情" width="100" fixed="right" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" @click="handleViewDetail(scope.row)">
@@ -974,18 +974,31 @@ export default {
.primary-text {
color: #303133;
line-height: 20px;
min-width: 0;
overflow-wrap: anywhere;
word-break: break-word;
}
.secondary-text {
color: #909399;
font-size: 12px;
line-height: 18px;
min-width: 0;
overflow-wrap: anywhere;
word-break: break-word;
}
.hit-tag-list {
display: flex;
flex-wrap: wrap;
gap: 6px;
min-width: 0;
}
.hit-tag-list ::v-deep .el-tag {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
.empty-text {

View File

@@ -9,7 +9,7 @@
</div>
<el-form :model="queryParams" size="small" :inline="true" label-width="104px" class="query-form">
<el-form-item label="柜员号">
<el-form-item label="柜员号" label-width="72px">
<el-input
v-model="queryParams.staffId"
placeholder="请输入柜员号"

View File

@@ -93,7 +93,7 @@
</div>
</template>
</el-table-column>
<el-table-column label="摘要 / 交易类型" min-width="240">
<el-table-column label="摘要 / 交易类型" min-width="200">
<template slot-scope="scope">
<div class="multi-line-cell">
<div class="primary-text">{{ formatField(scope.row.userMemo) }}</div>
@@ -101,6 +101,16 @@
</div>
</template>
</el-table-column>
<el-table-column prop="displayAmount" label="交易金额" width="120" align="right">
<template slot-scope="scope">
<span
class="amount-text"
:class="scope.row.displayAmount >= 0 ? 'amount-in' : 'amount-out'"
>
{{ formatAmount(scope.row.displayAmount) }}
</span>
</template>
</el-table-column>
<el-table-column label="异常标签" min-width="220">
<template slot-scope="scope">
<div v-if="scope.row.hitTags && scope.row.hitTags.length" class="hit-tag-list">
@@ -117,16 +127,6 @@
<span v-else class="empty-text">-</span>
</template>
</el-table-column>
<el-table-column prop="displayAmount" label="交易金额" min-width="140" align="right">
<template slot-scope="scope">
<span
class="amount-text"
:class="scope.row.displayAmount >= 0 ? 'amount-in' : 'amount-out'"
>
{{ formatAmount(scope.row.displayAmount) }}
</span>
</template>
</el-table-column>
<el-table-column label="详情" width="100" fixed="right" align="center">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="handleViewDetail(scope.row)">
@@ -1079,12 +1079,16 @@ export default {
font-weight: 500;
}
.suspicious-filter-form :deep(.el-button) {
min-width: 88px;
}
.suspicious-filter-select {
width: 220px;
width: 240px;
}
.suspicious-type-select {
width: 160px;
width: 240px;
}
.result-table {
@@ -1100,18 +1104,31 @@ export default {
.primary-text {
color: #303133;
line-height: 20px;
min-width: 0;
overflow-wrap: anywhere;
word-break: break-word;
}
.secondary-text {
color: #909399;
font-size: 12px;
line-height: 18px;
min-width: 0;
overflow-wrap: anywhere;
word-break: break-word;
}
.hit-tag-list {
display: flex;
flex-wrap: wrap;
gap: 6px;
min-width: 0;
}
.hit-tag-list ::v-deep .el-tag {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
.empty-text {

View File

@@ -9,11 +9,11 @@
</div>
<div class="model-workbench">
<section class="model-list-panel">
<section class="model-list-panel" aria-label="模型预警统计">
<div class="panel-header">
<div>
<div class="panel-title">模型预警统计</div>
<div class="panel-subtitle">点击模型筛选下方命中人员</div>
<div class="panel-subtitle">点击筛选</div>
</div>
</div>
@@ -41,11 +41,10 @@
</div>
</section>
<section class="model-result-panel">
<section class="model-result-panel" aria-label="命中模型涉及人员">
<div class="panel-header">
<div>
<div class="panel-title">命中模型涉及人员</div>
<div class="panel-subtitle">按模型人员信息和触发方式查看明细</div>
</div>
</div>
@@ -56,7 +55,7 @@
<el-tag
v-for="item in selectedCards"
:key="`selected-${item.key}`"
size="mini"
size="small"
closable
effect="plain"
@close="toggleModelSelection(item.key)"
@@ -76,7 +75,7 @@
<span class="filter-label">{{ keywordLabel }}</span>
<el-input
v-model.trim="keyword"
size="mini"
size="small"
clearable
:placeholder="keywordPlaceholder"
@keyup.enter.native="handleQuery"
@@ -87,7 +86,7 @@
<span class="filter-label">部门</span>
<el-select
v-model="deptId"
size="mini"
size="small"
clearable
filterable
:loading="deptLoading"
@@ -106,7 +105,7 @@
<span class="filter-label">模型关系</span>
<el-radio-group
v-model="matchMode"
size="mini"
size="small"
@change="handleMatchModeChange"
>
<el-radio-button label="ANY">命中任一模型</el-radio-button>
@@ -115,8 +114,8 @@
</div>
<div class="filter-actions">
<el-button size="mini" type="primary" @click="handleQuery">查询</el-button>
<el-button size="mini" plain @click="resetQuery">重置</el-button>
<el-button size="small" type="primary" @click="handleQuery">查询</el-button>
<el-button size="small" plain @click="resetQuery">重置</el-button>
</div>
</div>
@@ -594,9 +593,9 @@ export default {
.model-list-panel,
.model-result-panel {
border: 1px solid var(--ccdi-border);
border-radius: 8px;
background: #fff;
border: 0;
border-radius: 0;
background: transparent;
overflow: hidden;
}
@@ -609,10 +608,8 @@ export default {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 54px;
padding: 12px 14px;
border-bottom: 1px solid #e7eef5;
background: #f8fbfe;
min-height: 38px;
padding: 0 2px 10px;
}
.panel-title {
@@ -623,7 +620,7 @@ export default {
}
.panel-subtitle {
margin-top: 3px;
margin-top: 2px;
font-size: 12px;
color: var(--ccdi-text-muted);
}
@@ -632,7 +629,7 @@ export default {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
padding: 12px;
padding: 0;
}
.model-card {
@@ -747,16 +744,16 @@ export default {
display: flex;
align-items: center;
gap: 10px;
margin: 12px 14px 0;
padding: 8px 10px;
border: 1px solid #e6edf5;
border-radius: 6px;
background: #fbfdff;
margin: 14px 0 0;
padding: 0 0 10px;
border-bottom: 1px solid #edf2f7;
background: transparent;
}
.selected-label {
color: var(--ccdi-text-secondary);
font-size: 12px;
font-size: 14px;
line-height: 22px;
flex-shrink: 0;
}
@@ -771,19 +768,18 @@ export default {
.selected-placeholder {
color: var(--ccdi-text-muted);
font-size: 13px;
font-size: 14px;
}
.filter-bar {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px 14px;
margin: 10px 14px 12px;
padding: 10px;
border: 1px solid #e6edf5;
border-radius: 6px;
background: #fff;
gap: 12px 18px;
margin: 12px 0 14px;
padding: 0;
border: 0;
background: transparent;
}
.filter-item {
@@ -808,7 +804,8 @@ export default {
.filter-label,
.summary-label {
font-size: 12px;
font-size: 14px;
line-height: 32px;
color: var(--ccdi-text-secondary);
flex-shrink: 0;
white-space: nowrap;
@@ -821,8 +818,8 @@ export default {
}
.model-table {
margin: 0 14px;
width: calc(100% - 28px);
margin: 0;
width: 100%;
border: 1px solid #e7eef5;
border-radius: 6px;
overflow: hidden;

View File

@@ -202,11 +202,36 @@ export default {
return {
projectId: null,
projectName: "",
projectDesc: "",
startDate: "",
endDate: "",
targetCount: 0,
targetPersons: [],
description: "",
configType: "default",
};
},
getProjectTemplate(type) {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth() + 1;
const quarter = Math.floor(now.getMonth() / 3) + 1;
const quarterNames = ["一", "二", "三", "四"];
const templates = {
quarterly: {
projectName: `${year}年第${quarterNames[quarter - 1]}季度纪检初核项目`,
description: `用于开展${year}年第${quarterNames[quarter - 1]}季度纪检初核排查工作。`,
configType: "default",
},
employee: {
projectName: `${year}${month}月新员工排查项目`,
description: `用于开展${year}${month}月新入职员工排查工作。`,
configType: "default",
},
highRisk: {
projectName: `${year}年高风险专项排查项目`,
description: `用于开展${year}年高风险人员和异常线索专项排查工作。`,
configType: "custom",
},
};
return {
...this.getEmptyForm(),
...templates[type],
};
},
/** 关闭新增弹窗 */
@@ -247,19 +272,19 @@ export default {
},
/** 创建季度初核 */
handleCreateQuarterly() {
this.projectForm = this.getEmptyForm();
this.projectForm = this.getProjectTemplate("quarterly");
this.addDialogTitle = "创建季度初核项目";
this.addDialogVisible = true;
},
/** 创建新员工排查 */
handleCreateEmployee() {
this.projectForm = this.getEmptyForm();
this.projectForm = this.getProjectTemplate("employee");
this.addDialogTitle = "创建新员工排查项目";
this.addDialogVisible = true;
},
/** 创建高风险专项 */
handleCreateHighRisk() {
this.projectForm = this.getEmptyForm();
this.projectForm = this.getProjectTemplate("highRisk");
this.addDialogTitle = "创建高风险专项项目";
this.addDialogVisible = true;
},

View File

@@ -38,7 +38,7 @@
</el-row>
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="统一社会信用代码" prop="socialCreditCode">
<el-form-item label="统一社会信用代码" prop="socialCreditCode" class="compact-query-field">
<el-input
v-model="queryParams.socialCreditCode"
placeholder="请输入统一社会信用代码"
@@ -1004,6 +1004,22 @@ export default {
margin-right: 0;
}
.query-form ::v-deep .el-form-item__label {
white-space: nowrap;
}
.query-form ::v-deep .el-form-item__content {
min-width: 0;
}
.query-form ::v-deep .compact-query-field .el-form-item__label {
width: 136px !important;
}
.query-form ::v-deep .compact-query-field .el-form-item__content {
margin-left: 136px !important;
}
.detail-container {
padding: 0 20px;
}

View File

@@ -1,6 +1,6 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" v-show="showSearch" label-width="100px" class="query-form">
<el-form :model="queryParams" ref="queryForm" size="small" v-show="showSearch" label-width="128px" class="query-form">
<el-row :gutter="16">
<el-col :span="6">
<el-form-item label="员工姓名" prop="personName">
@@ -119,14 +119,14 @@
<el-table v-loading="loading" :data="relationList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="员工姓名" align="center" prop="personName" :show-overflow-tooltip="true"/>
<el-table-column label="员工身份证号" align="center" prop="personId" width="180"/>
<el-table-column label="员工身份证号" align="center" prop="personId" width="190" :show-overflow-tooltip="true"/>
<el-table-column label="关系类型" align="center" prop="relationType" width="100">
<template slot-scope="scope">
<enum-tag type="relationType" :value="scope.row.relationType"/>
</template>
</el-table-column>
<el-table-column label="关系人姓名" align="center" prop="relationName" :show-overflow-tooltip="true"/>
<el-table-column label="关系人身份证号" align="center" prop="relationCertNo" width="180"/>
<el-table-column label="关系人身份证号" align="center" prop="relationCertNo" width="190" :show-overflow-tooltip="true"/>
<el-table-column label="家庭成员年收入" align="center" prop="annualIncome" width="160"/>
<el-table-column label="性别" align="center" prop="gender" width="80">
<template slot-scope="scope">
@@ -1612,6 +1612,14 @@ export default {
margin-right: 0;
}
.query-form ::v-deep .el-form-item__label {
white-space: nowrap;
}
.query-form ::v-deep .el-form-item__content {
min-width: 0;
}
.detail-container {
padding: 0 20px;
}

View File

@@ -58,7 +58,7 @@
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns.userId.visible" />
<el-table-column label="编号" align="center" key="userId" prop="userId" v-if="columns.userId.visible" width="80" />
<el-table-column label="用户名称" align="center" key="userName" prop="userName" v-if="columns.userName.visible" :show-overflow-tooltip="true" />
<el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns.nickName.visible" :show-overflow-tooltip="true" />
<el-table-column label="部门" align="center" key="deptName" prop="dept.deptName" v-if="columns.deptName.visible" :show-overflow-tooltip="true" />
@@ -134,13 +134,6 @@
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="用户性别">
<el-select v-model="form.sex" placeholder="请选择性别">
<el-option v-for="dict in dict.type.sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
@@ -148,15 +141,6 @@
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="岗位">
<el-select v-model="form.postIds" multiple placeholder="请选择岗位">
<el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1" ></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="角色">
<el-select v-model="selectedRoleId" placeholder="请选择角色" @change="handleRoleChange">
@@ -165,13 +149,6 @@
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
@@ -210,7 +187,7 @@ import "splitpanes/dist/splitpanes.css"
export default {
name: "User",
dicts: ['sys_normal_disable', 'sys_user_sex'],
dicts: ['sys_normal_disable'],
components: { Treeselect, Splitpanes, Pane },
data() {
return {
@@ -280,7 +257,7 @@ export default {
},
// 列信息
columns: {
userId: { label: '用户编号', visible: true },
userId: { label: '编号', visible: true },
userName: { label: '用户名称', visible: true },
nickName: { label: '用户昵称', visible: true },
deptName: { label: '部门', visible: true },

View File

@@ -0,0 +1,42 @@
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const source = fs.readFileSync(
path.resolve(__dirname, "../../src/views/ccdiAccountInfo/index.vue"),
"utf8"
);
assert(
source.includes(':xs="24" :sm="12" :md="8" :lg="6" :xl="6"'),
"账户库查询项应使用响应式列宽"
);
const ownerTypeColumnIndex = source.indexOf('label="所属人类型"');
const staffNameColumnIndex = source.indexOf('label="员工姓名" prop="staffName"');
assert.notStrictEqual(ownerTypeColumnIndex, -1, "账户库列表应保留所属人类型列");
assert.notStrictEqual(staffNameColumnIndex, -1, "账户库列表应保留员工姓名列");
assert(
ownerTypeColumnIndex < staffNameColumnIndex,
"账户库列表中所属人类型应展示在员工姓名前面"
);
["员工姓名", "账户姓名", "账户号码"].forEach((label) => {
const pattern = new RegExp(
`<el-table-column[^>]*label="${label}"[^>]*show-overflow-tooltip`,
"m"
);
assert(pattern.test(source), `${label}列应使用溢出提示避免撑开表格`);
});
assert(source.includes('width="92%"'), "账户库编辑弹窗应使用自适应宽度");
assert(
source.includes('custom-class="account-info-dialog"'),
"账户库编辑弹窗应有独立样式类"
);
assert(
/::v-deep \.account-info-dialog\s*\{[\s\S]*max-width:\s*1160px;/m.test(source),
"账户库编辑弹窗大屏应限制最大宽度"
);
console.log("account-info-layout-polish test passed");

View File

@@ -16,4 +16,21 @@ assert(
);
assert(source.includes("tag.ruleName"), "异常标签列应展示标签名称");
const amountColumnIndex = source.indexOf('label="交易金额"');
const hitTagColumnIndex = source.indexOf('label="异常标签"');
assert.notStrictEqual(amountColumnIndex, -1, "列表应保留交易金额列");
assert.notStrictEqual(hitTagColumnIndex, -1, "列表应保留异常标签列");
assert(
amountColumnIndex < hitTagColumnIndex,
"流水明细查询列表中交易金额列应展示在异常标签列前面"
);
assert(
source.includes('label="摘要 / 交易类型" min-width="200"'),
"流水明细查询摘要列不应占用过宽"
);
assert(
source.includes('width="120"') && source.includes('label="异常标签" min-width="220"'),
"流水明细查询金额列和异常标签列应保持紧凑宽度"
);
console.log("detail-query-hit-tags-list test passed");

View File

@@ -38,3 +38,30 @@ const source = fs.readFileSync(
"label=\"关系\"",
"prop=\"relationType\"",
].forEach((token) => assert(!source.includes(token), token));
assert(
/\.suspicious-filter-select\s*\{[\s\S]*width:\s*240px;/m.test(source),
"命中模型筛选框宽度应能容纳较长模型名称"
);
assert(
/\.suspicious-type-select\s*\{[\s\S]*width:\s*240px;/m.test(source),
"预警类型筛选框宽度应能容纳外部人员可疑关系"
);
assert(
/\.suspicious-filter-form :deep\(\.el-button\)\s*\{[\s\S]*min-width:\s*88px;/m.test(source),
"涉疑交易查询按钮应保持稳定宽度"
);
const riskDetailAmountIndex = source.indexOf('label="交易金额"');
const riskDetailTagIndex = source.indexOf('label="异常标签"');
assert.notStrictEqual(riskDetailAmountIndex, -1, "涉疑交易明细应保留交易金额列");
assert.notStrictEqual(riskDetailTagIndex, -1, "涉疑交易明细应保留异常标签列");
assert(
riskDetailAmountIndex < riskDetailTagIndex,
"涉疑交易明细中交易金额列应展示在异常标签列前面"
);
assert(
source.includes('label="交易金额" width="120"') &&
source.includes('label="异常标签" min-width="220"'),
"涉疑交易明细金额列和异常标签列应保持紧凑宽度"
);