899a8c1c2b
- 票据账册搜索改用 el-check-tag 实现快捷筛选,提升用户交互体验 - 查询按钮增加图标,重置按钮同样添加图标及文字说明 - 调整票据搜索表单标签宽度由160px统一为88px,优化界面一致性 - 全站多处搜索栏表单标签宽度由160px改为88px,涵盖多页面及组件 - 修复业务组件内el-autocomplete输入框宽度适配,避免placeholder被裁剪 - 业务页面货物名称表格列宽由150调整为240,改善显示效果 - 修正系统部门操作列宽度避免按钮竖排溢出问题 - 修改多个表单页和搜索板块样式,确保标签宽度和对齐一致 - 调整表单按钮等样式,提升整体页面美观性和操作友好度
1590 lines
51 KiB
Vue
1590 lines
51 KiB
Vue
<template>
|
||
<basic-container>
|
||
<avue-crud
|
||
:option="option"
|
||
:table-loading="loading"
|
||
:data="data"
|
||
v-model:page="page"
|
||
v-model="form"
|
||
ref="crud"
|
||
:permission="permissionList"
|
||
@search-change="searchChange"
|
||
@search-reset="searchReset"
|
||
@selection-change="selectionChange"
|
||
@current-change="currentChange"
|
||
@size-change="sizeChange"
|
||
@refresh-change="refreshChange"
|
||
@on-load="onLoad"
|
||
>
|
||
<template #menu-left>
|
||
<el-button
|
||
type="primary"
|
||
icon="el-icon-plus"
|
||
v-if="hasPermission('credit_score_quantification_add')"
|
||
@click="openConfig()"
|
||
>新增
|
||
</el-button>
|
||
<el-button
|
||
type="danger"
|
||
icon="el-icon-delete"
|
||
plain
|
||
v-if="hasPermission('credit_score_quantification_delete')"
|
||
@click="handleDelete"
|
||
>批量删除
|
||
</el-button>
|
||
</template>
|
||
<template #name="{ row }">
|
||
<el-button type="primary" link @click="openConfig(row, true)">
|
||
{{ row.name }}
|
||
</el-button>
|
||
</template>
|
||
<template #status="{ row }">
|
||
<el-tag :type="statusMap[row.status].type" class="status-text">
|
||
{{ statusMap[row.status].label }}
|
||
</el-tag>
|
||
</template>
|
||
<template #menu="{ row }">
|
||
<el-link
|
||
type="primary"
|
||
v-if="hasPermission('credit_score_quantification_status') && row.status === 1"
|
||
@click="handleStatus(row)"
|
||
>
|
||
停用
|
||
</el-link>
|
||
<el-link
|
||
type="primary"
|
||
v-if="hasPermission('credit_score_quantification_publish') && row.status !== 1"
|
||
@click="handlePublish(row)"
|
||
>
|
||
发布
|
||
</el-link>
|
||
<el-link
|
||
type="primary"
|
||
v-if="hasPermission('credit_score_quantification_edit') && row.status !== 1"
|
||
@click="openConfig(row)"
|
||
>
|
||
编辑
|
||
</el-link>
|
||
<el-link
|
||
type="danger"
|
||
v-if="hasPermission('credit_score_quantification_delete')"
|
||
@click="rowDel(row)"
|
||
>
|
||
删除
|
||
</el-link>
|
||
</template>
|
||
</avue-crud>
|
||
|
||
<el-dialog
|
||
:title="readonly ? '查看评分量化表' : configForm.id ? '编辑评分量化表' : '新增评分量化表'"
|
||
append-to-body
|
||
v-model="configBox"
|
||
width="65%"
|
||
class="score-dialog"
|
||
@closed="resetConfig"
|
||
>
|
||
<div class="score-config">
|
||
<section-card title="评分量化表">
|
||
<el-form
|
||
:model="configForm"
|
||
label-position="right"
|
||
label-width="auto"
|
||
class="archive-form"
|
||
:disabled="readonly"
|
||
>
|
||
<el-form-item label="评定表名称" required>
|
||
<el-input
|
||
v-model="configForm.name"
|
||
class="score-config__name-input"
|
||
maxlength="30"
|
||
show-word-limit
|
||
style="width: 500px"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="备注">
|
||
<el-input
|
||
v-model="configForm.remark"
|
||
type="textarea"
|
||
:rows="2"
|
||
maxlength="500"
|
||
show-word-limit
|
||
/>
|
||
</el-form-item>
|
||
</el-form>
|
||
</section-card>
|
||
|
||
<section-card title="评分表">
|
||
<el-table :data="configForm.categories" border class="config-table">
|
||
<el-table-column label="序号" type="index" width="90" align="center" />
|
||
<el-table-column label="评分类目" prop="categoryName" min-width="180" />
|
||
<el-table-column label="评分项目数" width="140" align="center">
|
||
<template #default="{ row }">{{ row.items.length }}</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="160" align="center">
|
||
<template #default="{ row }">
|
||
<el-link type="primary" @click="openCategory(row)">
|
||
{{ readonly ? '查看' : '编辑' }}
|
||
</el-link>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</section-card>
|
||
|
||
<section-card title="评估标准">
|
||
<template #extra>
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
icon="el-icon-plus"
|
||
v-if="!readonly"
|
||
@click="openStandard()"
|
||
>
|
||
添加评估标准
|
||
</el-button>
|
||
</template>
|
||
<el-table :data="configForm.standards" border class="config-table">
|
||
<el-table-column label="序号" type="index" width="90" align="center" />
|
||
<el-table-column label="信用等级" prop="creditLevel" width="120" align="center" />
|
||
<el-table-column label="标准说明" prop="standardDescription" min-width="320" />
|
||
<el-table-column v-if="!readonly" label="操作" width="160" align="center">
|
||
<template #default="{ row, $index }">
|
||
<el-link type="primary" @click="openStandard(row, $index)">编辑</el-link>
|
||
<el-link type="danger" v-if="!readonly" @click="removeStandard($index)"
|
||
>删除</el-link
|
||
>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</section-card>
|
||
</div>
|
||
<template #footer>
|
||
<el-button @click="configBox = false">{{ readonly ? '关闭' : '取消' }}</el-button>
|
||
<el-button type="primary" v-if="!readonly" @click="saveConfig">保存</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<el-dialog
|
||
title="评分类目详情"
|
||
append-to-body
|
||
v-model="categoryBox"
|
||
width="61%"
|
||
class="score-dialog category-dialog"
|
||
:close-on-press-escape="false"
|
||
>
|
||
<div class="category-detail">
|
||
<div class="category-line">评分类目:{{ currentCategory.categoryName }}</div>
|
||
<section-card title="评分项目">
|
||
<template #extra>
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
icon="el-icon-plus"
|
||
v-if="!readonly"
|
||
@click="openItem()"
|
||
>
|
||
添加评分项目
|
||
</el-button>
|
||
</template>
|
||
<el-table :data="currentCategory.items" border class="config-table">
|
||
<el-table-column label="序号" type="index" width="90" align="center" />
|
||
<el-table-column label="评分项目" prop="itemName" width="180" />
|
||
<el-table-column label="得分说明" prop="scoreDescription" min-width="260" />
|
||
<el-table-column label="选项数" width="100" align="center">
|
||
<template #default="{ row }">{{ row.options.length }}</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="160" align="center">
|
||
<template #default="{ row, $index }">
|
||
<el-link type="primary" @click="openItem(row, $index)">
|
||
{{ readonly ? '查看' : '编辑' }}
|
||
</el-link>
|
||
<el-link
|
||
type="danger"
|
||
v-if="!readonly"
|
||
:disabled="currentCategory.items.length <= 1"
|
||
@click="removeItem($index)"
|
||
>
|
||
删除
|
||
</el-link>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</section-card>
|
||
</div>
|
||
<template #footer>
|
||
<el-button :type="readonly ? 'default' : 'primary'" @click="categoryBox = false">
|
||
{{ readonly ? '关闭' : '保存' }}
|
||
</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<el-dialog
|
||
title="评分项目详情"
|
||
append-to-body
|
||
v-model="itemBox"
|
||
width="58%"
|
||
class="score-item-dialog"
|
||
>
|
||
<section-card title="评分项目详情">
|
||
<el-form
|
||
:model="itemForm"
|
||
label-position="right"
|
||
label-width="112px"
|
||
:disabled="readonly"
|
||
class="score-item-form"
|
||
>
|
||
<div class="score-item-form__top">
|
||
<el-form-item label="评分项目" required>
|
||
<el-input v-model="itemForm.itemName" maxlength="20" />
|
||
</el-form-item>
|
||
<el-form-item label="分值" required>
|
||
<el-input-number
|
||
v-model="itemForm.score"
|
||
:min="0"
|
||
:precision="2"
|
||
:step="0.01"
|
||
:controls="false"
|
||
/>
|
||
</el-form-item>
|
||
</div>
|
||
<el-form-item label="得分说明">
|
||
<el-input
|
||
v-model="itemForm.scoreDescription"
|
||
maxlength="300"
|
||
class="score-description-input"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="选项描述">
|
||
<el-input v-model="itemForm.optionDescription" maxlength="100" />
|
||
</el-form-item>
|
||
<el-form-item label="选项类型" required>
|
||
<el-radio-group v-model="itemForm.optionType" @change="handleOptionTypeChange">
|
||
<el-radio value="option">选项</el-radio>
|
||
<el-radio value="score">分值</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item v-if="itemForm.optionType === 'score'" label="基准数值" required>
|
||
<el-input
|
||
:model-value="itemForm.baseValue"
|
||
inputmode="decimal"
|
||
@input="handleBaseValueInput"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item :label="itemForm.optionType === 'score' ? '阶梯配置' : '选项'" required>
|
||
<div class="option-editor">
|
||
<div
|
||
class="option-row"
|
||
:class="{ 'option-row--score': itemForm.optionType === 'score' }"
|
||
v-for="(option, index) in itemForm.options"
|
||
:key="index"
|
||
>
|
||
<template v-if="itemForm.optionType === 'score'">
|
||
<el-select v-model="option.changeType" class="option-change-type">
|
||
<el-option label="每增加" value="increase" />
|
||
<el-option label="每减少" value="decrease" />
|
||
</el-select>
|
||
<el-input
|
||
:model-value="option.changeValue"
|
||
inputmode="decimal"
|
||
@input="value => handleOptionDecimalInput(option, 'changeValue', value)"
|
||
>
|
||
<template #append>
|
||
<el-select v-model="option.changeUnit" class="option-unit-select">
|
||
<el-option
|
||
v-for="unit in scoreUnitOptions"
|
||
:key="unit"
|
||
:label="unit"
|
||
:value="unit"
|
||
/>
|
||
</el-select>
|
||
</template>
|
||
</el-input>
|
||
<el-select v-model="option.scoreType" class="option-score-type">
|
||
<el-option label="加" value="add" />
|
||
<el-option label="减" value="subtract" />
|
||
</el-select>
|
||
<div class="option-score">
|
||
<el-input
|
||
:model-value="option.score"
|
||
inputmode="decimal"
|
||
@input="value => handleOptionDecimalInput(option, 'score', value)"
|
||
>
|
||
<template #append>分</template>
|
||
</el-input>
|
||
</div>
|
||
</template>
|
||
<template v-else>
|
||
<el-input v-model="option.optionName" maxlength="100" />
|
||
<div class="option-score">
|
||
<el-input
|
||
:model-value="option.score"
|
||
inputmode="decimal"
|
||
@input="value => handleOptionDecimalInput(option, 'score', value)"
|
||
>
|
||
<template #append>分</template>
|
||
</el-input>
|
||
</div>
|
||
</template>
|
||
<el-link
|
||
type="danger"
|
||
class="option-delete"
|
||
v-if="!readonly && itemForm.options.length > 1"
|
||
@click="removeOption(index)"
|
||
>
|
||
删除
|
||
</el-link>
|
||
</div>
|
||
<div class="option-add" v-if="itemForm.optionType !== 'score'">
|
||
<el-link type="primary" v-if="!readonly" @click="addOption"> +添加选项 </el-link>
|
||
</div>
|
||
</div>
|
||
</el-form-item>
|
||
</el-form>
|
||
</section-card>
|
||
<template #footer>
|
||
<el-button @click="itemBox = false">{{ readonly ? '关闭' : '取消' }}</el-button>
|
||
<el-button type="primary" v-if="!readonly" @click="saveItem">保存</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<el-dialog
|
||
title="评估标准设置"
|
||
append-to-body
|
||
v-model="standardBox"
|
||
width="50%"
|
||
:close-on-press-escape="false"
|
||
>
|
||
<section-card title="评估标准设置">
|
||
<el-form
|
||
:model="standardForm"
|
||
label-position="right"
|
||
label-width="auto"
|
||
:disabled="readonly"
|
||
class="standard-form archive-form"
|
||
>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="信用等级" required>
|
||
<el-select
|
||
v-model="standardForm.creditLevel"
|
||
placeholder="请选择信用等级"
|
||
clearable
|
||
@change="handleStandardCreditLevelChange"
|
||
>
|
||
<el-option
|
||
v-for="item in creditLevelOptions"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="得分率(%)" required>
|
||
<div class="range-input standard-range-input score-rate-range">
|
||
<el-input
|
||
v-model="standardForm.scoreRateLower"
|
||
inputmode="numeric"
|
||
@input="value => handleStandardNumberInput('scoreRateLower', value, 0, 100)"
|
||
/>
|
||
<span>至</span>
|
||
<el-input
|
||
v-model="standardForm.scoreRateUpper"
|
||
inputmode="numeric"
|
||
@input="value => handleStandardNumberInput('scoreRateUpper', value, 0, 100)"
|
||
/>
|
||
</div>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="得分率每增加" required>
|
||
<el-input
|
||
v-model="standardForm.scoreRateIncrease"
|
||
inputmode="numeric"
|
||
@input="value => handleStandardNumberInput('scoreRateIncrease', value)"
|
||
>
|
||
<template #suffix>%</template>
|
||
</el-input>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="额度增加(万元)" required>
|
||
<el-input
|
||
v-model="standardForm.creditLimitIncrease"
|
||
inputmode="decimal"
|
||
@input="value => handleStandardNumberInput('creditLimitIncrease', value, 2)"
|
||
class="credit-increase-input"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="最大资金使用额度(万元)" required>
|
||
<div class="range-input standard-range-input credit-limit-range">
|
||
<el-input
|
||
v-model="standardForm.creditLimitLower"
|
||
inputmode="decimal"
|
||
@input="value => handleStandardNumberInput('creditLimitLower', value, 2)"
|
||
/>
|
||
<span>至</span>
|
||
<el-input
|
||
v-model="standardForm.creditLimitUpper"
|
||
inputmode="decimal"
|
||
@input="value => handleStandardNumberInput('creditLimitUpper', value, 2)"
|
||
/>
|
||
</div>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-form-item label="标准说明">
|
||
<el-input
|
||
v-model="standardForm.standardDescription"
|
||
type="textarea"
|
||
maxlength="500"
|
||
show-word-limit
|
||
/>
|
||
</el-form-item>
|
||
</el-form>
|
||
</section-card>
|
||
<template #footer>
|
||
<el-button @click="standardBox = false">取消</el-button>
|
||
<el-button type="primary" v-if="!readonly" @click="saveStandard">保存</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
</basic-container>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
getList,
|
||
getDetail,
|
||
submit,
|
||
remove,
|
||
publish,
|
||
changeStatus,
|
||
} from '@/api/vehicle/credit-score-quantification';
|
||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||
import { mapGetters } from 'vuex';
|
||
|
||
const createTimeRangeMap = {
|
||
createTimeRange: ['createTimeStart', 'createTimeEnd'],
|
||
};
|
||
|
||
const standardNumberFields = [
|
||
'scoreRateLower',
|
||
'scoreRateUpper',
|
||
'scoreRateIncrease',
|
||
'creditLimitLower',
|
||
'creditLimitUpper',
|
||
'creditLimitIncrease',
|
||
];
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
form: {},
|
||
query: {},
|
||
loading: true,
|
||
data: [],
|
||
page: {
|
||
pageSize: 10,
|
||
currentPage: 1,
|
||
total: 0,
|
||
},
|
||
selectionList: [],
|
||
configBox: false,
|
||
categoryBox: false,
|
||
itemBox: false,
|
||
standardBox: false,
|
||
readonly: false,
|
||
configForm: this.emptyConfig(),
|
||
currentCategory: { items: [] },
|
||
currentItemIndex: -1,
|
||
currentStandardIndex: -1,
|
||
itemForm: this.emptyItem(),
|
||
standardForm: this.emptyStandard(),
|
||
statusMap: {
|
||
1: { label: '正常', type: 'success' },
|
||
2: { label: '停用', type: 'info' },
|
||
3: { label: '草稿', type: 'warning' },
|
||
},
|
||
creditLevelOptions: ['A', 'B', 'C', 'D', 'E', 'F'].map(item => ({
|
||
label: item,
|
||
value: item,
|
||
})),
|
||
scoreUnitOptions: ['%', '件', '次', '项', '天'],
|
||
option: {
|
||
height: 'auto',
|
||
calcHeight: 32,
|
||
dialogWidth: 760,
|
||
labelPosition: 'right',
|
||
tip: false,
|
||
searchShow: true,
|
||
searchMenuSpan: 24,
|
||
searchIcon: true,
|
||
searchIndex: 4,
|
||
searchMenuPosition: 'right',
|
||
border: true,
|
||
index: true,
|
||
indexLabel: '序号',
|
||
indexWidth: 90,
|
||
addBtn: false,
|
||
viewBtn: false,
|
||
delBtn: false,
|
||
editBtn: false,
|
||
selection: true,
|
||
dialogClickModal: false,
|
||
menuWidth: 180,
|
||
column: [
|
||
{
|
||
label: '评分表名称',
|
||
prop: 'name',
|
||
slot: true,
|
||
minWidth: 180,
|
||
search: true,
|
||
maxlength: 30,
|
||
rules: [{ required: true, message: '请输入评定表名称', trigger: 'blur' }],
|
||
},
|
||
{
|
||
label: '创建人',
|
||
prop: 'createUserName',
|
||
minWidth: 120,
|
||
display: false,
|
||
},
|
||
{
|
||
label: '创建时间',
|
||
prop: 'createTime',
|
||
sortable: true,
|
||
type: 'datetime',
|
||
format: 'YYYY-MM-DD HH:mm:ss',
|
||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||
minWidth: 160,
|
||
display: false,
|
||
},
|
||
{
|
||
label: '状态',
|
||
prop: 'status',
|
||
type: 'select',
|
||
search: true,
|
||
slot: true,
|
||
dataType: 'number',
|
||
searchValue: '',
|
||
dicData: [
|
||
{ label: '全部', value: '' },
|
||
{ label: '正常', value: 1 },
|
||
{ label: '停用', value: 2 },
|
||
],
|
||
clearable: true,
|
||
},
|
||
{
|
||
label: '创建时间',
|
||
prop: 'createTimeRange',
|
||
type: 'date',
|
||
format: 'YYYY-MM-DD',
|
||
valueFormat: 'YYYY-MM-DD',
|
||
searchRange: true,
|
||
hide: true,
|
||
display: false,
|
||
},
|
||
],
|
||
},
|
||
};
|
||
},
|
||
computed: {
|
||
...mapGetters(['permission', 'userInfo']),
|
||
isAdmin() {
|
||
const authority = this.userInfo.authority || '';
|
||
return authority.includes('admin');
|
||
},
|
||
permissionList() {
|
||
return {
|
||
addBtn: false,
|
||
};
|
||
},
|
||
ids() {
|
||
let ids = [];
|
||
this.selectionList.forEach(ele => {
|
||
ids.push(ele.id);
|
||
});
|
||
return ids.join(',');
|
||
},
|
||
},
|
||
methods: {
|
||
hasPermission(code) {
|
||
return this.isAdmin || this.validData(this.permission[code], false);
|
||
},
|
||
emptyConfig() {
|
||
return {
|
||
name: '',
|
||
remark: '',
|
||
standardDescription: '',
|
||
status: 3,
|
||
categories: this.defaultCategories(),
|
||
standards: [],
|
||
};
|
||
},
|
||
defaultCategories() {
|
||
return [
|
||
{ categoryCode: 'basic', categoryName: '基础得分项', sort: 1, items: [] },
|
||
{ categoryCode: 'plus', categoryName: '加分项目', sort: 2, items: [] },
|
||
{ categoryCode: 'minus', categoryName: '减分项目', sort: 3, items: [] },
|
||
];
|
||
},
|
||
emptyItem() {
|
||
return {
|
||
itemName: '',
|
||
score: 1,
|
||
scoreDescription: '',
|
||
optionDescription: '',
|
||
optionType: 'option',
|
||
baseValue: '',
|
||
options: [this.emptyOption()],
|
||
};
|
||
},
|
||
emptyOption() {
|
||
return {
|
||
optionName: '',
|
||
score: 1,
|
||
changeType: 'increase',
|
||
changeValue: '',
|
||
changeUnit: '%',
|
||
scoreType: 'add',
|
||
};
|
||
},
|
||
emptyStandard() {
|
||
return {
|
||
creditLevel: '',
|
||
scoreRateLower: undefined,
|
||
scoreRateUpper: undefined,
|
||
scoreRateIncrease: undefined,
|
||
creditLimitLower: undefined,
|
||
creditLimitUpper: undefined,
|
||
creditLimitIncrease: undefined,
|
||
standardDescription: '',
|
||
};
|
||
},
|
||
normalizeDetail(detail) {
|
||
const categories = this.defaultCategories();
|
||
const map = {};
|
||
(detail.categories || []).forEach(category => {
|
||
map[category.categoryCode] = {
|
||
...category,
|
||
items: (category.items || []).map(item => this.normalizeItem(item)),
|
||
};
|
||
});
|
||
return {
|
||
...detail,
|
||
categories: categories.map(category => ({
|
||
...(map[category.categoryCode] || category),
|
||
categoryName: category.categoryName,
|
||
})),
|
||
standards: (detail.standards || []).map(standard => this.normalizeStandard(standard)),
|
||
};
|
||
},
|
||
openConfig(row, readonly = false) {
|
||
this.readonly = readonly;
|
||
if (row && row.id) {
|
||
getDetail(row.id).then(res => {
|
||
this.configForm = this.normalizeDetail(res.data.data);
|
||
this.configBox = true;
|
||
});
|
||
return;
|
||
}
|
||
this.configForm = this.emptyConfig();
|
||
if (row && row.name) {
|
||
this.configForm.name = row.name;
|
||
}
|
||
this.configBox = true;
|
||
},
|
||
resetConfig() {
|
||
this.readonly = false;
|
||
this.configForm = this.emptyConfig();
|
||
},
|
||
openCategory(category) {
|
||
this.currentCategory = category;
|
||
this.categoryBox = true;
|
||
},
|
||
openItem(row, index = -1) {
|
||
this.currentItemIndex = index;
|
||
this.itemForm = row
|
||
? this.normalizeItem({ ...this.emptyItem(), ...JSON.parse(JSON.stringify(row)) })
|
||
: this.emptyItem();
|
||
this.itemBox = true;
|
||
},
|
||
normalizeOptionType(value) {
|
||
return value === 'score' || value === 2 || String(value) === 'score' ? 'score' : 'option';
|
||
},
|
||
normalizeItem(item = {}) {
|
||
const normalized = { ...this.emptyItem(), ...item };
|
||
const score = Number(this.normalizePlainDecimal(normalized.score));
|
||
return {
|
||
...normalized,
|
||
score: Number.isFinite(score) ? score : normalized.score,
|
||
baseValue: this.normalizePlainDecimal(normalized.baseValue),
|
||
optionType: this.normalizeOptionType(normalized.optionType),
|
||
options:
|
||
normalized.options && normalized.options.length
|
||
? normalized.options.map(option => this.normalizeOption(option))
|
||
: [this.emptyOption()],
|
||
};
|
||
},
|
||
normalizeOption(option = {}) {
|
||
const normalized = { ...this.emptyOption(), ...option };
|
||
return {
|
||
...normalized,
|
||
score: this.normalizePlainDecimal(normalized.score),
|
||
changeValue: this.normalizePlainDecimal(normalized.changeValue),
|
||
changeType:
|
||
normalized.changeType === 'decrease' ||
|
||
normalized.changeType === '每减少' ||
|
||
normalized.changeType === 2
|
||
? 'decrease'
|
||
: 'increase',
|
||
scoreType:
|
||
normalized.scoreType === 'subtract' ||
|
||
normalized.scoreType === '减' ||
|
||
normalized.scoreType === 2
|
||
? 'subtract'
|
||
: 'add',
|
||
};
|
||
},
|
||
normalizePlainDecimal(value) {
|
||
if (value === undefined || value === null || value === '') return '';
|
||
const text = String(value).trim();
|
||
const matched = text.match(/^([+-]?)(\d+)(?:\.(\d*))?[eE]([+-]?\d+)$/);
|
||
if (!matched) return text;
|
||
const [, sign, integer, decimal = '', exponentText] = matched;
|
||
const exponent = Number(exponentText);
|
||
const digits = `${integer}${decimal}`;
|
||
const decimalIndex = integer.length + exponent;
|
||
const resultLength =
|
||
decimalIndex <= 0 ? 2 - decimalIndex + digits.length : Math.max(decimalIndex, digits.length);
|
||
if (!Number.isSafeInteger(exponent) || resultLength > 1000) return text;
|
||
let result;
|
||
if (decimalIndex <= 0) {
|
||
result = `0.${'0'.repeat(-decimalIndex)}${digits}`;
|
||
} else if (decimalIndex >= digits.length) {
|
||
result = `${digits}${'0'.repeat(decimalIndex - digits.length)}`;
|
||
} else {
|
||
result = `${digits.slice(0, decimalIndex)}.${digits.slice(decimalIndex)}`;
|
||
}
|
||
return `${sign === '-' ? '-' : ''}${result}`;
|
||
},
|
||
normalizeStandard(standard = {}) {
|
||
const normalized = { ...this.emptyStandard(), ...standard };
|
||
standardNumberFields.forEach(field => {
|
||
normalized[field] = this.normalizePlainDecimal(normalized[field]);
|
||
});
|
||
return normalized;
|
||
},
|
||
handleOptionTypeChange(value) {
|
||
this.itemForm.optionType = this.normalizeOptionType(value);
|
||
this.itemForm.options = (this.itemForm.options || []).map(option =>
|
||
this.normalizeOption(option)
|
||
);
|
||
},
|
||
handleBaseValueInput(value) {
|
||
const source = String(value ?? '').replace(/[^\d.-]/g, '');
|
||
const negative = source.startsWith('-');
|
||
const unsigned = source.replace(/-/g, '');
|
||
const [integer = '', ...decimalParts] = unsigned.split('.');
|
||
const decimal = decimalParts.join('').slice(0, 10);
|
||
this.itemForm.baseValue = `${negative ? '-' : ''}${integer}${decimalParts.length ? `.${decimal}` : ''}`;
|
||
},
|
||
handleOptionDecimalInput(option, field, value) {
|
||
option[field] = this.normalizeDecimalInput(value);
|
||
},
|
||
normalizeDecimalInput(value) {
|
||
const source = String(value ?? '').replace(/[^\d.]/g, '');
|
||
const [integer = '', ...decimalParts] = source.split('.');
|
||
const decimal = decimalParts.join('').slice(0, 2);
|
||
return decimalParts.length ? `${integer}.${decimal}` : integer;
|
||
},
|
||
toScoreValue(value) {
|
||
const number = Number(value);
|
||
return Number.isFinite(number) ? number.toFixed(2) : value;
|
||
},
|
||
prepareSubmitConfig(config) {
|
||
const payload = JSON.parse(JSON.stringify(config || {}));
|
||
(payload.categories || []).forEach(category => {
|
||
(category.items || []).forEach(item => {
|
||
item.score = this.toScoreValue(item.score);
|
||
item.baseValue =
|
||
this.normalizeOptionType(item.optionType) === 'score'
|
||
? this.normalizePlainDecimal(item.baseValue)
|
||
: null;
|
||
(item.options || []).forEach(option => {
|
||
option.score = this.toScoreValue(option.score);
|
||
if (this.normalizeOptionType(item.optionType) === 'score') {
|
||
option.changeValue = this.toScoreValue(option.changeValue);
|
||
}
|
||
});
|
||
});
|
||
});
|
||
(payload.standards || []).forEach(standard => {
|
||
standardNumberFields.forEach(field => {
|
||
standard[field] = this.normalizePlainDecimal(standard[field]);
|
||
});
|
||
});
|
||
return payload;
|
||
},
|
||
hasDuplicateItemName(itemName, currentIndex = -1) {
|
||
const name = String(itemName || '').trim();
|
||
return this.currentCategory.items.some(
|
||
(item, index) => index !== currentIndex && String(item.itemName || '').trim() === name
|
||
);
|
||
},
|
||
saveItem() {
|
||
if (!this.itemForm.itemName || !this.itemForm.itemName.trim()) {
|
||
this.$message.warning('请输入评分项目');
|
||
return;
|
||
}
|
||
if (this.hasDuplicateItemName(this.itemForm.itemName, this.currentItemIndex)) {
|
||
this.$message.warning('评分项目名称不能重复');
|
||
return;
|
||
}
|
||
if (
|
||
this.itemForm.score === undefined ||
|
||
this.itemForm.score === null ||
|
||
this.itemForm.score === ''
|
||
) {
|
||
this.$message.warning('请输入分值');
|
||
return;
|
||
}
|
||
if (!this.itemForm.options.length) {
|
||
this.$message.warning('至少添加1条档位选项');
|
||
return;
|
||
}
|
||
if (this.itemForm.optionType === 'score') {
|
||
if (this.itemForm.options.length !== 1) {
|
||
this.$message.warning('分值类型只能配置1条阶梯配置');
|
||
return;
|
||
}
|
||
if (!this.isAnyNumber(this.itemForm.baseValue)) {
|
||
this.$message.warning('请输入基准数值');
|
||
return;
|
||
}
|
||
const invalidScoreOption = this.itemForm.options.some(
|
||
option =>
|
||
!option.changeType ||
|
||
!this.isPositiveDecimal(option.changeValue) ||
|
||
!option.changeUnit ||
|
||
!option.scoreType ||
|
||
!this.isNonNegativeDecimal(option.score)
|
||
);
|
||
if (invalidScoreOption) {
|
||
this.$message.warning('请完整填写基础分值,并确保数值不能为负数且最多两位小数');
|
||
return;
|
||
}
|
||
} else {
|
||
const invalidOption = this.itemForm.options.some(
|
||
option =>
|
||
!String(option.optionName || '').trim() ||
|
||
option.score === undefined ||
|
||
option.score === null ||
|
||
option.score === ''
|
||
);
|
||
if (invalidOption) {
|
||
this.$message.warning('请完整填写档位选项');
|
||
return;
|
||
}
|
||
}
|
||
const item = JSON.parse(JSON.stringify(this.itemForm));
|
||
item.itemName = String(item.itemName || '').trim();
|
||
item.optionType = this.normalizeOptionType(item.optionType);
|
||
item.baseValue =
|
||
item.optionType === 'score' ? this.normalizePlainDecimal(item.baseValue) : null;
|
||
item.options = item.options.map(option => ({
|
||
...option,
|
||
optionName: String(option.optionName || '').trim(),
|
||
score: this.toScoreValue(option.score),
|
||
...(item.optionType === 'score' ? { changeValue: this.toScoreValue(option.changeValue) } : {}),
|
||
}));
|
||
item.score = this.toScoreValue(item.score);
|
||
if (this.currentItemIndex >= 0) {
|
||
this.currentCategory.items.splice(this.currentItemIndex, 1, item);
|
||
} else {
|
||
this.currentCategory.items.push(item);
|
||
}
|
||
this.itemBox = false;
|
||
},
|
||
removeItem(index) {
|
||
if (this.currentCategory.items.length <= 1) {
|
||
this.$message.warning('评分类目详情至少保留1条评分项目');
|
||
return;
|
||
}
|
||
this.currentCategory.items.splice(index, 1);
|
||
},
|
||
addOption() {
|
||
this.itemForm.options.push(this.emptyOption());
|
||
},
|
||
removeOption(index) {
|
||
this.itemForm.options.splice(index, 1);
|
||
},
|
||
openStandard(row, index = -1) {
|
||
this.currentStandardIndex = index;
|
||
this.standardForm = row
|
||
? this.normalizeStandard(JSON.parse(JSON.stringify(row)))
|
||
: this.emptyStandard();
|
||
this.standardBox = true;
|
||
},
|
||
hasDuplicateCreditLevel(creditLevel, currentIndex = -1) {
|
||
const level = String(creditLevel || '').trim();
|
||
return this.configForm.standards.some(
|
||
(item, index) => index !== currentIndex && String(item.creditLevel || '').trim() === level
|
||
);
|
||
},
|
||
handleStandardCreditLevelChange(value) {
|
||
if (!value) return;
|
||
if (this.hasDuplicateCreditLevel(value, this.currentStandardIndex)) {
|
||
this.$message.warning('信用等级不能重复');
|
||
this.standardForm.creditLevel = '';
|
||
}
|
||
},
|
||
handleStandardNumberInput(field, value, precision = 0, max) {
|
||
let normalized = String(value || '').replace(precision > 0 ? /[^\d.]/g : /\D/g, '');
|
||
if (precision > 0) {
|
||
const [integer = '', ...decimalParts] = normalized.split('.');
|
||
const decimal = decimalParts.join('').slice(0, precision);
|
||
normalized = decimalParts.length ? `${integer}.${decimal}` : integer;
|
||
}
|
||
if (max !== undefined && normalized !== '' && Number(normalized) > max) {
|
||
normalized = String(max);
|
||
}
|
||
this.standardForm[field] = normalized;
|
||
},
|
||
isValidCreditLevel(creditLevel) {
|
||
return this.creditLevelOptions.some(item => item.value === String(creditLevel || '').trim());
|
||
},
|
||
saveStandard() {
|
||
if (!this.standardForm.creditLevel) {
|
||
this.$message.warning('请选择信用等级');
|
||
return;
|
||
}
|
||
if (!this.isValidCreditLevel(this.standardForm.creditLevel)) {
|
||
this.$message.warning('信用等级只能选择A/B/C/D/E/F');
|
||
return;
|
||
}
|
||
if (this.hasDuplicateCreditLevel(this.standardForm.creditLevel, this.currentStandardIndex)) {
|
||
this.$message.warning('信用等级不能重复');
|
||
return;
|
||
}
|
||
if (
|
||
[
|
||
this.standardForm.scoreRateLower,
|
||
this.standardForm.scoreRateUpper,
|
||
this.standardForm.scoreRateIncrease,
|
||
this.standardForm.creditLimitLower,
|
||
this.standardForm.creditLimitUpper,
|
||
this.standardForm.creditLimitIncrease,
|
||
].some(value => value === undefined || value === null || value === '')
|
||
) {
|
||
this.$message.warning('请完整填写评估标准必填项');
|
||
return;
|
||
}
|
||
if (Number(this.standardForm.scoreRateLower) >= Number(this.standardForm.scoreRateUpper)) {
|
||
this.$message.warning('得分率下限必须小于上限');
|
||
return;
|
||
}
|
||
if (
|
||
Number(this.standardForm.creditLimitLower) >= Number(this.standardForm.creditLimitUpper)
|
||
) {
|
||
this.$message.warning('授信额度下限必须小于上限');
|
||
return;
|
||
}
|
||
const standard = JSON.parse(JSON.stringify(this.standardForm));
|
||
standard.creditLevel = String(standard.creditLevel || '').trim();
|
||
standardNumberFields.forEach(field => {
|
||
standard[field] = Number(standard[field]);
|
||
});
|
||
const nextStandards = JSON.parse(JSON.stringify(this.configForm.standards));
|
||
if (this.currentStandardIndex >= 0) {
|
||
nextStandards.splice(this.currentStandardIndex, 1, standard);
|
||
} else {
|
||
nextStandards.push(standard);
|
||
}
|
||
if (this.hasRangeOverlap(nextStandards, 'scoreRateLower', 'scoreRateUpper')) {
|
||
this.$message.warning('评估标准中的得分率区间不能重叠');
|
||
return;
|
||
}
|
||
if (this.hasRangeOverlap(nextStandards, 'creditLimitLower', 'creditLimitUpper')) {
|
||
this.$message.warning('评估标准中的授信额度区间不能重叠');
|
||
return;
|
||
}
|
||
if (this.currentStandardIndex >= 0) {
|
||
this.configForm.standards.splice(this.currentStandardIndex, 1, standard);
|
||
} else {
|
||
this.configForm.standards.push(standard);
|
||
}
|
||
this.standardBox = false;
|
||
},
|
||
removeStandard(index) {
|
||
this.$confirm('确定删除该评估标准?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
}).then(() => {
|
||
this.configForm.standards.splice(index, 1);
|
||
});
|
||
},
|
||
isBlankValue(value) {
|
||
return value === undefined || value === null || value === '';
|
||
},
|
||
isPositiveDecimal(value) {
|
||
const number = Number(value);
|
||
if (!Number.isFinite(number) || number <= 0) return false;
|
||
return Math.abs(number * 100 - Math.round(number * 100)) < 1e-8;
|
||
},
|
||
isNonNegativeDecimal(value) {
|
||
if (value === undefined || value === null || String(value).trim() === '') return false;
|
||
const number = Number(value);
|
||
if (!Number.isFinite(number) || number < 0) return false;
|
||
return Math.abs(number * 100 - Math.round(number * 100)) < 1e-8;
|
||
},
|
||
isAnyNumber(value) {
|
||
const text = String(value ?? '').trim();
|
||
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(text) && Number.isFinite(Number(text));
|
||
},
|
||
hasRangeOverlap(list, lowerProp, upperProp) {
|
||
const ranges = list
|
||
.map(item => ({
|
||
lower: Number(item[lowerProp]),
|
||
upper: Number(item[upperProp]),
|
||
}))
|
||
.sort((a, b) => a.lower - b.lower);
|
||
return ranges.some((range, index) => {
|
||
const next = ranges[index + 1];
|
||
return next && range.upper > next.lower;
|
||
});
|
||
},
|
||
validateConfig() {
|
||
if (!this.configForm.name || !this.configForm.name.trim()) {
|
||
this.$message.warning('请输入评定表名称');
|
||
return false;
|
||
}
|
||
const basic = this.configForm.categories.find(item => item.categoryCode === 'basic');
|
||
if (!basic || basic.items.length === 0) {
|
||
this.$message.warning('至少配置1个基础得分项目');
|
||
return false;
|
||
}
|
||
for (const category of this.configForm.categories) {
|
||
const itemNames = (category.items || [])
|
||
.map(item => String(item.itemName || '').trim())
|
||
.filter(Boolean);
|
||
if (new Set(itemNames).size !== itemNames.length) {
|
||
this.$message.warning(`${category.categoryName}的评分项目名称不能重复`);
|
||
return false;
|
||
}
|
||
for (const item of category.items) {
|
||
if (!item.options || item.options.length === 0) {
|
||
this.$message.warning(`${item.itemName}至少存在1条档位选项`);
|
||
return false;
|
||
}
|
||
if (this.normalizeOptionType(item.optionType) === 'score') {
|
||
if (item.options.length !== 1) {
|
||
this.$message.warning(`${item.itemName || '评分项目'}的分值类型只能配置1条阶梯配置`);
|
||
return false;
|
||
}
|
||
if (!this.isAnyNumber(item.baseValue)) {
|
||
this.$message.warning(`${item.itemName || '评分项目'}的基准数值不能为空且必须为数字`);
|
||
return false;
|
||
}
|
||
if (
|
||
item.options.some(
|
||
option =>
|
||
!option.changeType ||
|
||
!this.isPositiveDecimal(option.changeValue) ||
|
||
!this.scoreUnitOptions.includes(option.changeUnit) ||
|
||
!option.scoreType ||
|
||
!this.isNonNegativeDecimal(option.score)
|
||
)
|
||
) {
|
||
this.$message.warning(`${item.itemName || '评分项目'}的基础分值配置不完整`);
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
const creditLevels = this.configForm.standards
|
||
.map(item => String(item.creditLevel || '').trim())
|
||
.filter(Boolean);
|
||
if (creditLevels.some(level => !this.isValidCreditLevel(level))) {
|
||
this.$message.warning('评估标准中的信用等级只能选择A/B/C/D/E/F');
|
||
return false;
|
||
}
|
||
if (new Set(creditLevels).size !== creditLevels.length) {
|
||
this.$message.warning('评估标准中的信用等级不能重复');
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
validatePublishConfig(config) {
|
||
const detail = this.normalizeDetail(config || {});
|
||
const basic = detail.categories.find(item => item.categoryCode === 'basic');
|
||
if (!basic || !basic.items || basic.items.length === 0) {
|
||
this.$message.warning('发布前至少配置1条基础得分项目');
|
||
return false;
|
||
}
|
||
for (const category of detail.categories) {
|
||
for (const item of category.items || []) {
|
||
if (!String(item.itemName || '').trim()) {
|
||
this.$message.warning('发布前请完整填写评分项目名称');
|
||
return false;
|
||
}
|
||
if (!item.options || item.options.length === 0) {
|
||
this.$message.warning(`${item.itemName || '评分项目'}至少配置1个档位选项`);
|
||
return false;
|
||
}
|
||
if (this.normalizeOptionType(item.optionType) === 'score') {
|
||
if (item.options.length !== 1) {
|
||
this.$message.warning(`${item.itemName || '评分项目'}的分值类型只能配置1条阶梯配置`);
|
||
return false;
|
||
}
|
||
if (!this.isAnyNumber(item.baseValue)) {
|
||
this.$message.warning(`${item.itemName || '评分项目'}的基准数值不能为空且必须为数字`);
|
||
return false;
|
||
}
|
||
if (
|
||
item.options.some(
|
||
option =>
|
||
!option.changeType ||
|
||
!this.isPositiveDecimal(option.changeValue) ||
|
||
!this.scoreUnitOptions.includes(option.changeUnit) ||
|
||
!option.scoreType ||
|
||
!this.isNonNegativeDecimal(option.score)
|
||
)
|
||
) {
|
||
this.$message.warning(`${item.itemName || '评分项目'}的基础分值配置不完整`);
|
||
return false;
|
||
}
|
||
} else {
|
||
const invalidOption = item.options.some(
|
||
option => !String(option.optionName || '').trim() || this.isBlankValue(option.score)
|
||
);
|
||
if (invalidOption) {
|
||
this.$message.warning(`${item.itemName || '评分项目'}的档位选项未填写完整`);
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
const standards = detail.standards || [];
|
||
if (standards.length === 0) {
|
||
this.$message.warning('发布前至少配置1条信用等级评估标准');
|
||
return false;
|
||
}
|
||
for (const standard of standards) {
|
||
if (!standard.creditLevel) {
|
||
this.$message.warning('评估标准中的信用等级不能为空');
|
||
return false;
|
||
}
|
||
if (!this.isValidCreditLevel(standard.creditLevel)) {
|
||
this.$message.warning('评估标准中的信用等级只能选择A/B/C/D/E/F');
|
||
return false;
|
||
}
|
||
if (standardNumberFields.some(field => this.isBlankValue(standard[field]))) {
|
||
this.$message.warning(`${standard.creditLevel}信用等级评估标准必填项未填写完整`);
|
||
return false;
|
||
}
|
||
if (Number(standard.scoreRateLower) >= Number(standard.scoreRateUpper)) {
|
||
this.$message.warning(`${standard.creditLevel}信用等级得分率下限必须小于上限`);
|
||
return false;
|
||
}
|
||
if (Number(standard.creditLimitLower) >= Number(standard.creditLimitUpper)) {
|
||
this.$message.warning(`${standard.creditLevel}信用等级授信额度下限必须小于上限`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
const creditLevels = standards.map(item => String(item.creditLevel || '').trim());
|
||
if (new Set(creditLevels).size !== creditLevels.length) {
|
||
this.$message.warning('评估标准中的信用等级不能重复');
|
||
return false;
|
||
}
|
||
if (this.hasRangeOverlap(standards, 'scoreRateLower', 'scoreRateUpper')) {
|
||
this.$message.warning('评估标准中的得分率区间不能重叠');
|
||
return false;
|
||
}
|
||
if (this.hasRangeOverlap(standards, 'creditLimitLower', 'creditLimitUpper')) {
|
||
this.$message.warning('评估标准中的授信额度区间不能重叠');
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
saveConfig() {
|
||
if (!this.validateConfig()) return;
|
||
submit({
|
||
...this.prepareSubmitConfig(this.configForm),
|
||
status: 3,
|
||
}).then(() => {
|
||
this.configBox = false;
|
||
this.onLoad(this.page);
|
||
this.$message({ type: 'success', message: '操作成功!' });
|
||
});
|
||
},
|
||
rowDel(row) {
|
||
this.$confirm('确定将选择数据删除?', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => remove(row.id))
|
||
.then(() => {
|
||
this.onLoad(this.page);
|
||
this.$message({ type: 'success', message: '操作成功!' });
|
||
});
|
||
},
|
||
handleDelete() {
|
||
if (this.selectionList.length === 0) {
|
||
this.$message.warning('请选择至少一条数据');
|
||
return;
|
||
}
|
||
this.$confirm('确定删除所选评分量化表?', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => remove(this.ids))
|
||
.then(() => {
|
||
this.onLoad(this.page);
|
||
this.$message({ type: 'success', message: '操作成功!' });
|
||
this.$refs.crud.toggleSelection();
|
||
});
|
||
},
|
||
handlePublish(row) {
|
||
this.$confirm('发布前将校验所有评分项目、档位选项和评估标准,是否继续?', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => getDetail(row.id))
|
||
.then(res => {
|
||
const detail = this.normalizeDetail(res.data.data || {});
|
||
if (!this.validatePublishConfig(detail)) {
|
||
return false;
|
||
}
|
||
return publish(row.id).then(() => true);
|
||
})
|
||
.then(published => {
|
||
if (!published) return;
|
||
this.onLoad(this.page);
|
||
this.$message({ type: 'success', message: '发布成功!' });
|
||
});
|
||
},
|
||
handleStatus(row) {
|
||
const nextStatus = row.status === 1 ? 2 : 1;
|
||
const actionName = nextStatus === 1 ? '启用' : '停用';
|
||
this.$confirm(`是否确认${actionName}该评分量化表?`, {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => changeStatus(row.id, nextStatus))
|
||
.then(() => {
|
||
this.onLoad(this.page);
|
||
this.$message({ type: 'success', message: '操作成功!' });
|
||
});
|
||
},
|
||
searchReset() {
|
||
this.query = {};
|
||
this.onLoad(this.page);
|
||
},
|
||
searchChange(params, done) {
|
||
this.query = this.buildQuery(params);
|
||
this.page.currentPage = 1;
|
||
this.onLoad(this.page);
|
||
done();
|
||
},
|
||
selectionChange(list) {
|
||
this.selectionList = list;
|
||
},
|
||
currentChange(currentPage) {
|
||
this.page.currentPage = currentPage;
|
||
},
|
||
sizeChange(pageSize) {
|
||
this.page.pageSize = pageSize;
|
||
},
|
||
refreshChange() {
|
||
this.onLoad(this.page, this.query);
|
||
},
|
||
onLoad(page, params = {}) {
|
||
this.loading = true;
|
||
getList(page.currentPage, page.pageSize, this.buildQuery(params)).then(res => {
|
||
const data = res.data.data;
|
||
this.page.total = data.total;
|
||
this.data = data.records;
|
||
this.loading = false;
|
||
});
|
||
},
|
||
buildQuery(params = {}) {
|
||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.score-config {
|
||
&__name-input {
|
||
width: min(420px, 100%);
|
||
}
|
||
}
|
||
|
||
.archive-form {
|
||
:deep(.el-form-item__label) {
|
||
flex: 0 0 calc(6em + 24px) !important;
|
||
width: calc(6em + 24px) !important;
|
||
height: auto;
|
||
white-space: normal !important;
|
||
word-break: break-all;
|
||
overflow-wrap: anywhere;
|
||
line-height: 18px;
|
||
}
|
||
|
||
:deep(.el-form-item) {
|
||
align-items: center;
|
||
}
|
||
|
||
:deep(.el-form-item__content > .el-input),
|
||
:deep(.el-form-item__content > .el-select),
|
||
:deep(.el-form-item__content > .el-cascader),
|
||
:deep(.el-form-item__content > .el-input-number),
|
||
:deep(.el-form-item__content > .el-date-editor) {
|
||
width: 250px;
|
||
max-width: 100%;
|
||
}
|
||
}
|
||
|
||
.config-table {
|
||
width: 100%;
|
||
}
|
||
|
||
.category-line {
|
||
margin: 0 0 24px;
|
||
font-size: 16px;
|
||
font-weight: 400;
|
||
color: #606266;
|
||
}
|
||
|
||
:deep(.category-dialog .el-dialog__title) {
|
||
font-weight: 700;
|
||
}
|
||
|
||
.score-item-form {
|
||
width: 100%;
|
||
max-width: 1400px;
|
||
margin: 0 auto;
|
||
padding: 4px 0 6px;
|
||
|
||
:deep(.el-form-item) {
|
||
margin-bottom: 14px;
|
||
}
|
||
|
||
:deep(.el-form-item__label) {
|
||
padding-right: 10px;
|
||
color: #606266;
|
||
font-size: 14px;
|
||
}
|
||
|
||
:deep(.el-input),
|
||
:deep(.el-input-number) {
|
||
width: 100%;
|
||
}
|
||
|
||
:deep(.el-input__wrapper),
|
||
:deep(.el-input-number .el-input__wrapper) {
|
||
min-height: 32px;
|
||
border-radius: 0;
|
||
box-shadow: 0 0 0 1px #dcdfe6 inset;
|
||
}
|
||
|
||
:deep(.el-input__inner) {
|
||
height: 32px;
|
||
color: #303133;
|
||
font-size: 14px;
|
||
font-weight: 400;
|
||
}
|
||
|
||
:deep(.score-description-input .el-input__inner) {
|
||
text-align: left;
|
||
}
|
||
|
||
&__top {
|
||
display: grid;
|
||
grid-template-columns: 360px 360px;
|
||
column-gap: 112px;
|
||
|
||
:deep(.el-form-item) {
|
||
margin-bottom: 14px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.option-editor {
|
||
width: 100%;
|
||
}
|
||
|
||
.option-row {
|
||
display: grid;
|
||
grid-template-columns: minmax(560px, 2fr) 200px 74px;
|
||
gap: 24px;
|
||
align-items: center;
|
||
margin-bottom: 14px;
|
||
}
|
||
|
||
.option-row--score {
|
||
grid-template-columns: 150px minmax(220px, 1fr) 110px 180px 74px;
|
||
gap: 16px;
|
||
|
||
.option-score {
|
||
min-width: 0;
|
||
}
|
||
}
|
||
|
||
.option-change-type,
|
||
.option-score-type {
|
||
width: 100%;
|
||
}
|
||
|
||
.option-unit-select {
|
||
width: 78px;
|
||
|
||
:deep(.el-input__wrapper) {
|
||
border: 0;
|
||
border-left: 1px solid #dcdfe6;
|
||
border-radius: 0;
|
||
box-shadow: none;
|
||
}
|
||
}
|
||
|
||
.option-score {
|
||
position: relative;
|
||
|
||
.score-unit {
|
||
position: absolute;
|
||
top: 50%;
|
||
right: 12px;
|
||
z-index: 1;
|
||
margin: 0;
|
||
color: #303133;
|
||
font-size: 14px;
|
||
line-height: 1;
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
:deep(.el-input__inner) {
|
||
padding-right: 42px;
|
||
}
|
||
}
|
||
|
||
.option-delete {
|
||
justify-self: start;
|
||
min-height: 32px;
|
||
padding: 0;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.option-add {
|
||
display: flex;
|
||
justify-content: center;
|
||
margin-top: 6px;
|
||
|
||
:deep(.el-button) {
|
||
min-height: 32px;
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.range-input {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.standard-range-input {
|
||
width: 100%;
|
||
min-width: 0;
|
||
|
||
:deep(.el-input) {
|
||
flex: 1;
|
||
width: 0;
|
||
min-width: 0;
|
||
}
|
||
}
|
||
|
||
.credit-limit-range {
|
||
width: 520px;
|
||
max-width: 100%;
|
||
|
||
:deep(.el-input) {
|
||
width: 250px;
|
||
flex: none;
|
||
}
|
||
}
|
||
|
||
.score-rate-range {
|
||
width: 250px;
|
||
max-width: 100%;
|
||
}
|
||
|
||
.credit-increase-input {
|
||
}
|
||
|
||
.score-unit {
|
||
margin-left: 8px;
|
||
color: #606266;
|
||
}
|
||
|
||
:deep(.score-dialog .el-dialog__body) {
|
||
max-height: 70vh;
|
||
overflow: auto;
|
||
}
|
||
|
||
:deep(.score-config__name-input) {
|
||
width: 500px;
|
||
}
|
||
|
||
:deep(.score-item-dialog) {
|
||
.el-dialog__header {
|
||
padding: 20px 24px 10px;
|
||
}
|
||
|
||
.el-dialog__title {
|
||
color: #303133;
|
||
font-size: 20px;
|
||
font-weight: 700;
|
||
line-height: 1;
|
||
}
|
||
|
||
.el-dialog__body {
|
||
padding: 12px 24px 14px;
|
||
}
|
||
|
||
.el-dialog__footer {
|
||
padding: 12px 24px 20px;
|
||
}
|
||
|
||
.dialog-footer,
|
||
.el-dialog__footer {
|
||
text-align: right;
|
||
}
|
||
|
||
.el-dialog__footer .el-button {
|
||
min-width: 88px;
|
||
min-height: 32px;
|
||
border-radius: 4px;
|
||
font-size: 14px;
|
||
font-weight: 400;
|
||
}
|
||
|
||
.el-dialog__footer .el-button + .el-button {
|
||
margin-left: 12px;
|
||
}
|
||
}
|
||
</style>
|