调整评分量化表
This commit is contained in:
@@ -85,67 +85,73 @@
|
|||||||
>
|
>
|
||||||
<div class="score-config">
|
<div class="score-config">
|
||||||
<section-card title="评分量化表">
|
<section-card title="评分量化表">
|
||||||
<el-form
|
<el-form
|
||||||
:model="configForm"
|
:model="configForm"
|
||||||
label-position="right"
|
label-position="right"
|
||||||
label-width="auto"
|
label-width="auto"
|
||||||
class="archive-form"
|
class="archive-form"
|
||||||
:disabled="readonly"
|
:disabled="readonly"
|
||||||
>
|
>
|
||||||
<el-form-item label="评定表名称" required>
|
<el-form-item label="评定表名称" required>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="configForm.name"
|
v-model="configForm.name"
|
||||||
class="score-config__name-input"
|
class="score-config__name-input"
|
||||||
maxlength="30"
|
maxlength="30"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="备注">
|
<el-form-item label="备注">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="configForm.remark"
|
v-model="configForm.remark"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
:rows="1"
|
:rows="1"
|
||||||
maxlength="500"
|
maxlength="500"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</section-card>
|
</section-card>
|
||||||
|
|
||||||
<section-card title="评分表">
|
<section-card title="评分表">
|
||||||
<el-table :data="configForm.categories" border class="config-table">
|
<el-table :data="configForm.categories" border class="config-table">
|
||||||
<el-table-column label="序号" type="index" width="90" align="center" />
|
<el-table-column label="序号" type="index" width="90" align="center" />
|
||||||
<el-table-column label="评分类目" prop="categoryName" min-width="180" />
|
<el-table-column label="评分类目" prop="categoryName" min-width="180" />
|
||||||
<el-table-column label="评分项目数" width="140" align="center">
|
<el-table-column label="评分项目数" width="140" align="center">
|
||||||
<template #default="{ row }">{{ row.items.length }}</template>
|
<template #default="{ row }">{{ row.items.length }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="160" align="center">
|
<el-table-column label="操作" width="160" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-link type="primary" @click="openCategory(row)">编辑</el-link>
|
<el-link type="primary" @click="openCategory(row)">编辑</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</section-card>
|
</section-card>
|
||||||
|
|
||||||
<section-card title="评估标准">
|
<section-card title="评估标准">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<el-button type="primary" plain icon="el-icon-plus" v-if="!readonly" @click="openStandard()">
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-plus"
|
||||||
|
v-if="!readonly"
|
||||||
|
@click="openStandard()"
|
||||||
|
>
|
||||||
添加评估标准
|
添加评估标准
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<el-table :data="configForm.standards" border class="config-table">
|
<el-table :data="configForm.standards" border class="config-table">
|
||||||
<el-table-column label="序号" type="index" width="90" align="center" />
|
<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="creditLevel" width="120" align="center" />
|
||||||
<el-table-column label="标准说明" prop="standardDescription" min-width="320" />
|
<el-table-column label="标准说明" prop="standardDescription" min-width="320" />
|
||||||
<el-table-column label="操作" width="160" align="center">
|
<el-table-column label="操作" width="160" align="center">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-link type="primary" @click="openStandard(row, $index)">编辑</el-link>
|
<el-link type="primary" @click="openStandard(row, $index)">编辑</el-link>
|
||||||
<el-link type="danger" v-if="!readonly" @click="removeStandard($index)"
|
<el-link type="danger" v-if="!readonly" @click="removeStandard($index)"
|
||||||
>删除</el-link
|
>删除</el-link
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</section-card>
|
</section-card>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -166,31 +172,37 @@
|
|||||||
<div class="category-line">评分类目:{{ currentCategory.categoryName }}</div>
|
<div class="category-line">评分类目:{{ currentCategory.categoryName }}</div>
|
||||||
<section-card title="评分项目">
|
<section-card title="评分项目">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<el-button type="primary" plain icon="el-icon-plus" v-if="!readonly" @click="openItem()">
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="el-icon-plus"
|
||||||
|
v-if="!readonly"
|
||||||
|
@click="openItem()"
|
||||||
|
>
|
||||||
添加评分项目
|
添加评分项目
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<el-table :data="currentCategory.items" border class="config-table">
|
<el-table :data="currentCategory.items" border class="config-table">
|
||||||
<el-table-column label="序号" type="index" width="90" align="center" />
|
<el-table-column label="序号" type="index" width="90" align="center" />
|
||||||
<el-table-column label="评分项目" prop="itemName" width="180" />
|
<el-table-column label="评分项目" prop="itemName" width="180" />
|
||||||
<el-table-column label="得分说明" prop="scoreDescription" min-width="260" />
|
<el-table-column label="得分说明" prop="scoreDescription" min-width="260" />
|
||||||
<el-table-column label="选项数" width="100" align="center">
|
<el-table-column label="选项数" width="100" align="center">
|
||||||
<template #default="{ row }">{{ row.options.length }}</template>
|
<template #default="{ row }">{{ row.options.length }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="160" align="center">
|
<el-table-column label="操作" width="160" align="center">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-link type="primary" @click="openItem(row, $index)">编辑</el-link>
|
<el-link type="primary" @click="openItem(row, $index)">编辑</el-link>
|
||||||
<el-link
|
<el-link
|
||||||
type="danger"
|
type="danger"
|
||||||
v-if="!readonly"
|
v-if="!readonly"
|
||||||
:disabled="currentCategory.items.length <= 1"
|
:disabled="currentCategory.items.length <= 1"
|
||||||
@click="removeItem($index)"
|
@click="removeItem($index)"
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</el-link>
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</section-card>
|
</section-card>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -206,51 +218,119 @@
|
|||||||
class="score-item-dialog"
|
class="score-item-dialog"
|
||||||
>
|
>
|
||||||
<section-card title="评分项目详情">
|
<section-card title="评分项目详情">
|
||||||
<el-form
|
<el-form
|
||||||
:model="itemForm"
|
:model="itemForm"
|
||||||
label-position="right"
|
label-position="right"
|
||||||
label-width="112px"
|
label-width="112px"
|
||||||
:disabled="readonly"
|
:disabled="readonly"
|
||||||
class="score-item-form"
|
class="score-item-form"
|
||||||
>
|
>
|
||||||
<div class="score-item-form__top">
|
<div class="score-item-form__top">
|
||||||
<el-form-item label="评分项目" required>
|
<el-form-item label="评分项目" required>
|
||||||
<el-input v-model="itemForm.itemName" maxlength="20" />
|
<el-input v-model="itemForm.itemName" maxlength="20" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="分值" required>
|
<el-form-item label="分值" required>
|
||||||
<el-input-number v-model="itemForm.score" :min="1" :precision="0" :step="1" :controls="false" />
|
<el-input-number
|
||||||
</el-form-item>
|
v-model="itemForm.score"
|
||||||
</div>
|
:min="0.01"
|
||||||
<el-form-item label="得分说明">
|
:precision="2"
|
||||||
<el-input v-model="itemForm.scoreDescription" maxlength="300" class="score-description-input" />
|
:step="0.01"
|
||||||
</el-form-item>
|
:controls="false"
|
||||||
<el-form-item label="选项描述">
|
/>
|
||||||
<el-input v-model="itemForm.optionDescription" maxlength="100" />
|
</el-form-item>
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="选项" required>
|
|
||||||
<div class="option-editor">
|
|
||||||
<div class="option-row" v-for="(option, index) in itemForm.options" :key="index">
|
|
||||||
<el-input v-model="option.optionName" maxlength="100" />
|
|
||||||
<div class="option-score">
|
|
||||||
<el-input-number v-model="option.score" :min="1" :precision="0" :step="1" :controls="false" />
|
|
||||||
<span class="score-unit">分</span>
|
|
||||||
</div>
|
|
||||||
<el-link
|
|
||||||
type="danger"
|
|
||||||
class="option-delete"
|
|
||||||
v-if="!readonly && itemForm.options.length > 1"
|
|
||||||
@click="removeOption(index)"
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</el-link>
|
|
||||||
</div>
|
|
||||||
<div class="option-add">
|
|
||||||
<el-link type="primary" v-if="!readonly" @click="addOption">
|
|
||||||
+添加选项
|
|
||||||
</el-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
<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>
|
</el-form>
|
||||||
</section-card>
|
</section-card>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -267,93 +347,99 @@
|
|||||||
:close-on-press-escape="false"
|
:close-on-press-escape="false"
|
||||||
>
|
>
|
||||||
<section-card title="评估标准设置">
|
<section-card title="评估标准设置">
|
||||||
<el-form :model="standardForm" label-position="right" label-width="auto" :disabled="readonly" class="standard-form archive-form">
|
<el-form
|
||||||
|
:model="standardForm"
|
||||||
|
label-position="right"
|
||||||
|
label-width="auto"
|
||||||
|
:disabled="readonly"
|
||||||
|
class="standard-form archive-form"
|
||||||
|
>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="信用等级" required>
|
<el-form-item label="信用等级" required>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="standardForm.creditLevel"
|
v-model="standardForm.creditLevel"
|
||||||
placeholder="请选择信用等级"
|
placeholder="请选择信用等级"
|
||||||
clearable
|
clearable
|
||||||
@change="handleStandardCreditLevelChange"
|
@change="handleStandardCreditLevelChange"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in creditLevelOptions"
|
v-for="item in creditLevelOptions"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="得分率(%)" required>
|
<el-form-item label="得分率(%)" required>
|
||||||
<div class="range-input standard-range-input score-rate-range">
|
<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="8">
|
||||||
|
<el-form-item label="得分率每增加" required>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="standardForm.scoreRateLower"
|
v-model="standardForm.scoreRateIncrease"
|
||||||
inputmode="numeric"
|
inputmode="numeric"
|
||||||
@input="value => handleStandardNumberInput('scoreRateLower', value, 0, 100)"
|
@input="value => handleStandardNumberInput('scoreRateIncrease', value)"
|
||||||
/>
|
>
|
||||||
<span>至</span>
|
<template #suffix>%</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="额度增加(万元)" required>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="standardForm.scoreRateUpper"
|
v-model="standardForm.creditLimitIncrease"
|
||||||
inputmode="numeric"
|
|
||||||
@input="value => handleStandardNumberInput('scoreRateUpper', value, 0, 100)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="8">
|
|
||||||
<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="8">
|
|
||||||
<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"
|
inputmode="decimal"
|
||||||
@input="value => handleStandardNumberInput('creditLimitLower', value, 2)"
|
@input="value => handleStandardNumberInput('creditLimitIncrease', value, 2)"
|
||||||
|
class="credit-increase-input"
|
||||||
/>
|
/>
|
||||||
<span>至</span>
|
</el-form-item>
|
||||||
<el-input
|
</el-col>
|
||||||
v-model="standardForm.creditLimitUpper"
|
</el-row>
|
||||||
inputmode="decimal"
|
<el-row :gutter="20">
|
||||||
@input="value => handleStandardNumberInput('creditLimitUpper', value, 2)"
|
<el-col :span="12">
|
||||||
/>
|
<el-form-item label="最大资金使用额度(万元)" required>
|
||||||
</div>
|
<div class="range-input standard-range-input credit-limit-range">
|
||||||
</el-form-item>
|
<el-input
|
||||||
</el-col>
|
v-model="standardForm.creditLimitLower"
|
||||||
</el-row>
|
inputmode="decimal"
|
||||||
<el-form-item label="标准说明">
|
@input="value => handleStandardNumberInput('creditLimitLower', value, 2)"
|
||||||
<el-input
|
/>
|
||||||
v-model="standardForm.standardDescription"
|
<span>至</span>
|
||||||
type="textarea"
|
<el-input
|
||||||
maxlength="500"
|
v-model="standardForm.creditLimitUpper"
|
||||||
show-word-limit
|
inputmode="decimal"
|
||||||
/>
|
@input="value => handleStandardNumberInput('creditLimitUpper', value, 2)"
|
||||||
</el-form-item>
|
/>
|
||||||
|
</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>
|
</el-form>
|
||||||
</section-card>
|
</section-card>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -413,6 +499,7 @@ export default {
|
|||||||
label: item,
|
label: item,
|
||||||
value: item,
|
value: item,
|
||||||
})),
|
})),
|
||||||
|
scoreUnitOptions: ['%', '件', '次', '项', '天'],
|
||||||
option: {
|
option: {
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
calcHeight: 32,
|
calcHeight: 32,
|
||||||
@@ -536,7 +623,19 @@ export default {
|
|||||||
score: 1,
|
score: 1,
|
||||||
scoreDescription: '',
|
scoreDescription: '',
|
||||||
optionDescription: '',
|
optionDescription: '',
|
||||||
options: [{ optionName: '', score: 1 }],
|
optionType: 'option',
|
||||||
|
baseValue: '',
|
||||||
|
options: [this.emptyOption()],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
emptyOption() {
|
||||||
|
return {
|
||||||
|
optionName: '',
|
||||||
|
score: 1,
|
||||||
|
changeType: 'increase',
|
||||||
|
changeValue: '',
|
||||||
|
changeUnit: '%',
|
||||||
|
scoreType: 'add',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
emptyStandard() {
|
emptyStandard() {
|
||||||
@@ -559,14 +658,20 @@ export default {
|
|||||||
...category,
|
...category,
|
||||||
items: (category.items || []).map(item => ({
|
items: (category.items || []).map(item => ({
|
||||||
...item,
|
...item,
|
||||||
|
optionType: this.normalizeOptionType(item.optionType),
|
||||||
options:
|
options:
|
||||||
item.options && item.options.length ? item.options : [{ optionName: '', score: 1 }],
|
item.options && item.options.length
|
||||||
|
? item.options.map(option => this.normalizeOption(option))
|
||||||
|
: [this.emptyOption()],
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
...detail,
|
...detail,
|
||||||
categories: categories.map(category => map[category.categoryCode] || category),
|
categories: categories.map(category => ({
|
||||||
|
...(map[category.categoryCode] || category),
|
||||||
|
categoryName: category.categoryName,
|
||||||
|
})),
|
||||||
standards: detail.standards || [],
|
standards: detail.standards || [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -596,10 +701,84 @@ export default {
|
|||||||
openItem(row, index = -1) {
|
openItem(row, index = -1) {
|
||||||
this.currentItemIndex = index;
|
this.currentItemIndex = index;
|
||||||
this.itemForm = row
|
this.itemForm = row
|
||||||
? { ...this.emptyItem(), ...JSON.parse(JSON.stringify(row)) }
|
? this.normalizeItem({ ...this.emptyItem(), ...JSON.parse(JSON.stringify(row)) })
|
||||||
: this.emptyItem();
|
: this.emptyItem();
|
||||||
this.itemBox = true;
|
this.itemBox = true;
|
||||||
},
|
},
|
||||||
|
normalizeOptionType(value) {
|
||||||
|
return value === 'score' || value === 2 || String(value) === 'score' ? 'score' : 'option';
|
||||||
|
},
|
||||||
|
normalizeItem(item = {}) {
|
||||||
|
return {
|
||||||
|
...this.emptyItem(),
|
||||||
|
...item,
|
||||||
|
optionType: this.normalizeOptionType(item.optionType),
|
||||||
|
options:
|
||||||
|
item.options && item.options.length
|
||||||
|
? item.options.map(option => this.normalizeOption(option))
|
||||||
|
: [this.emptyOption()],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
normalizeOption(option = {}) {
|
||||||
|
const normalized = { ...this.emptyOption(), ...option };
|
||||||
|
return {
|
||||||
|
...normalized,
|
||||||
|
changeType:
|
||||||
|
normalized.changeType === 'decrease' ||
|
||||||
|
normalized.changeType === '每减少' ||
|
||||||
|
normalized.changeType === 2
|
||||||
|
? 'decrease'
|
||||||
|
: 'increase',
|
||||||
|
scoreType:
|
||||||
|
normalized.scoreType === 'subtract' ||
|
||||||
|
normalized.scoreType === '减' ||
|
||||||
|
normalized.scoreType === 2
|
||||||
|
? 'subtract'
|
||||||
|
: 'add',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
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.options || []).forEach(option => {
|
||||||
|
option.score = this.toScoreValue(option.score);
|
||||||
|
if (this.normalizeOptionType(item.optionType) === 'score') {
|
||||||
|
option.changeValue = this.toScoreValue(option.changeValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return payload;
|
||||||
|
},
|
||||||
hasDuplicateItemName(itemName, currentIndex = -1) {
|
hasDuplicateItemName(itemName, currentIndex = -1) {
|
||||||
const name = String(itemName || '').trim();
|
const name = String(itemName || '').trim();
|
||||||
return this.currentCategory.items.some(
|
return this.currentCategory.items.some(
|
||||||
@@ -623,37 +802,55 @@ export default {
|
|||||||
this.$message.warning('请输入分值');
|
this.$message.warning('请输入分值');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.isPositiveInteger(this.itemForm.score)) {
|
|
||||||
this.$message.warning('分值只能输入正整数');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this.itemForm.options.length) {
|
if (!this.itemForm.options.length) {
|
||||||
this.$message.warning('至少添加1条档位选项');
|
this.$message.warning('至少添加1条档位选项');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const invalidOption = this.itemForm.options.some(
|
if (this.itemForm.optionType === 'score') {
|
||||||
option =>
|
if (this.itemForm.options.length !== 1) {
|
||||||
!String(option.optionName || '').trim() ||
|
this.$message.warning('分值类型只能配置1条阶梯配置');
|
||||||
option.score === undefined ||
|
return;
|
||||||
option.score === null ||
|
}
|
||||||
option.score === ''
|
if (!this.isAnyNumber(this.itemForm.baseValue)) {
|
||||||
);
|
this.$message.warning('请输入基准数值');
|
||||||
if (invalidOption) {
|
return;
|
||||||
this.$message.warning('请完整填写档位选项');
|
}
|
||||||
return;
|
const invalidScoreOption = this.itemForm.options.some(
|
||||||
}
|
option =>
|
||||||
if (this.itemForm.options.some(option => !this.isPositiveInteger(option.score))) {
|
!option.changeType ||
|
||||||
this.$message.warning('选项分数只能输入正整数');
|
!this.isPositiveDecimal(option.changeValue) ||
|
||||||
return;
|
!option.changeUnit ||
|
||||||
|
!option.scoreType ||
|
||||||
|
!this.isPositiveDecimal(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));
|
const item = JSON.parse(JSON.stringify(this.itemForm));
|
||||||
item.itemName = String(item.itemName || '').trim();
|
item.itemName = String(item.itemName || '').trim();
|
||||||
|
item.optionType = this.normalizeOptionType(item.optionType);
|
||||||
|
item.baseValue = item.optionType === 'score' ? String(item.baseValue).trim() : null;
|
||||||
item.options = item.options.map(option => ({
|
item.options = item.options.map(option => ({
|
||||||
...option,
|
...option,
|
||||||
optionName: String(option.optionName || '').trim(),
|
optionName: String(option.optionName || '').trim(),
|
||||||
score: Number(option.score),
|
score: this.toScoreValue(option.score),
|
||||||
|
...(item.optionType === 'score' ? { changeValue: this.toScoreValue(option.changeValue) } : {}),
|
||||||
}));
|
}));
|
||||||
item.score = Number(item.score);
|
item.score = this.toScoreValue(item.score);
|
||||||
if (this.currentItemIndex >= 0) {
|
if (this.currentItemIndex >= 0) {
|
||||||
this.currentCategory.items.splice(this.currentItemIndex, 1, item);
|
this.currentCategory.items.splice(this.currentItemIndex, 1, item);
|
||||||
} else {
|
} else {
|
||||||
@@ -669,7 +866,7 @@ export default {
|
|||||||
this.currentCategory.items.splice(index, 1);
|
this.currentCategory.items.splice(index, 1);
|
||||||
},
|
},
|
||||||
addOption() {
|
addOption() {
|
||||||
this.itemForm.options.push({ optionName: '', score: 1 });
|
this.itemForm.options.push(this.emptyOption());
|
||||||
},
|
},
|
||||||
removeOption(index) {
|
removeOption(index) {
|
||||||
this.itemForm.options.splice(index, 1);
|
this.itemForm.options.splice(index, 1);
|
||||||
@@ -788,8 +985,20 @@ export default {
|
|||||||
isBlankValue(value) {
|
isBlankValue(value) {
|
||||||
return value === undefined || value === null || value === '';
|
return value === undefined || value === null || value === '';
|
||||||
},
|
},
|
||||||
isPositiveInteger(value) {
|
isPositiveDecimal(value) {
|
||||||
return /^\d+$/.test(String(value)) && Number(value) > 0;
|
const number = Number(value);
|
||||||
|
console.log(
|
||||||
|
value,
|
||||||
|
Number.isFinite(number),
|
||||||
|
number,
|
||||||
|
Math.abs(number * 100 - Math.round(number * 100))
|
||||||
|
);
|
||||||
|
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) {
|
hasRangeOverlap(list, lowerProp, upperProp) {
|
||||||
const ranges = list
|
const ranges = list
|
||||||
@@ -822,17 +1031,32 @@ export default {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (const item of category.items) {
|
for (const item of category.items) {
|
||||||
if (!this.isPositiveInteger(item.score)) {
|
|
||||||
this.$message.warning(`${item.itemName || '评分项目'}的分值只能为正整数`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!item.options || item.options.length === 0) {
|
if (!item.options || item.options.length === 0) {
|
||||||
this.$message.warning(`${item.itemName}至少存在1条档位选项`);
|
this.$message.warning(`${item.itemName}至少存在1条档位选项`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (item.options.some(option => !this.isPositiveInteger(option.score))) {
|
if (this.normalizeOptionType(item.optionType) === 'score') {
|
||||||
this.$message.warning(`${item.itemName || '评分项目'}的选项分数只能为正整数`);
|
if (item.options.length !== 1) {
|
||||||
return false;
|
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.isPositiveDecimal(option.score)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
this.$message.warning(`${item.itemName || '评分项目'}的基础分值配置不完整`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -862,24 +1086,40 @@ export default {
|
|||||||
this.$message.warning('发布前请完整填写评分项目名称');
|
this.$message.warning('发布前请完整填写评分项目名称');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!this.isPositiveInteger(item.score)) {
|
|
||||||
this.$message.warning(`${item.itemName || '评分项目'}的分值只能为正整数`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!item.options || item.options.length === 0) {
|
if (!item.options || item.options.length === 0) {
|
||||||
this.$message.warning(`${item.itemName || '评分项目'}至少配置1个档位选项`);
|
this.$message.warning(`${item.itemName || '评分项目'}至少配置1个档位选项`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const invalidOption = item.options.some(
|
if (this.normalizeOptionType(item.optionType) === 'score') {
|
||||||
option => !String(option.optionName || '').trim() || this.isBlankValue(option.score)
|
if (item.options.length !== 1) {
|
||||||
);
|
this.$message.warning(`${item.itemName || '评分项目'}的分值类型只能配置1条阶梯配置`);
|
||||||
if (invalidOption) {
|
return false;
|
||||||
this.$message.warning(`${item.itemName || '评分项目'}的档位选项未填写完整`);
|
}
|
||||||
return false;
|
if (!this.isAnyNumber(item.baseValue)) {
|
||||||
}
|
this.$message.warning(`${item.itemName || '评分项目'}的基准数值不能为空且必须为数字`);
|
||||||
if (item.options.some(option => !this.isPositiveInteger(option.score))) {
|
return false;
|
||||||
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.isPositiveDecimal(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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -938,7 +1178,7 @@ export default {
|
|||||||
saveConfig() {
|
saveConfig() {
|
||||||
if (!this.validateConfig()) return;
|
if (!this.validateConfig()) return;
|
||||||
submit({
|
submit({
|
||||||
...this.configForm,
|
...this.prepareSubmitConfig(this.configForm),
|
||||||
status: 3,
|
status: 3,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.configBox = false;
|
this.configBox = false;
|
||||||
@@ -1157,6 +1397,31 @@ export default {
|
|||||||
margin-bottom: 14px;
|
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 {
|
.option-score {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@@ -1278,5 +1543,4 @@ export default {
|
|||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1210,20 +1210,32 @@
|
|||||||
<el-table-column label="评分标准" min-width="430">
|
<el-table-column label="评分标准" min-width="430">
|
||||||
<template #default="{ row: detail }">
|
<template #default="{ row: detail }">
|
||||||
<div class="score-standard-cell">
|
<div class="score-standard-cell">
|
||||||
<div class="score-standard-cell__label">请选择:</div>
|
<template v-if="isScoreTypeDetail(detail)">
|
||||||
<el-select
|
<el-input
|
||||||
v-model="detail.selectedOption"
|
:model-value="detail.scoreInput"
|
||||||
filterable
|
inputmode="decimal"
|
||||||
:disabled="readonly"
|
:disabled="readonly"
|
||||||
@change="scoreOptionChange(detail, $event)"
|
@input="value => handleScoreValueInput(detail, value)"
|
||||||
>
|
>
|
||||||
<el-option
|
<template #append>{{ getScoreRule(detail)?.changeUnit || '' }}</template>
|
||||||
v-for="item in parseScoreOptions(detail.optionsJson)"
|
</el-input>
|
||||||
:key="item.value"
|
</template>
|
||||||
:label="item.label"
|
<template v-else>
|
||||||
:value="item.value"
|
<div class="score-standard-cell__label">请选择:</div>
|
||||||
/>
|
<el-select
|
||||||
</el-select>
|
v-model="detail.selectedOption"
|
||||||
|
filterable
|
||||||
|
:disabled="readonly"
|
||||||
|
@change="scoreOptionChange(detail, $event)"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in parseScoreOptions(detail.optionsJson)"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -2154,8 +2166,8 @@ export default {
|
|||||||
const scoreDetails = this.normalizeChangeFieldValue(score.details);
|
const scoreDetails = this.normalizeChangeFieldValue(score.details);
|
||||||
const details = (Array.isArray(scoreDetails) ? scoreDetails : [])
|
const details = (Array.isArray(scoreDetails) ? scoreDetails : [])
|
||||||
.map(detail => {
|
.map(detail => {
|
||||||
const category =
|
const categoryCode = this.getScoreDetailCategoryCode(detail);
|
||||||
detail.categoryName || categoryNames[this.getScoreDetailCategoryCode(detail)] || '';
|
const category = categoryNames[categoryCode] || detail.categoryName || '';
|
||||||
const itemName = detail.itemName || '评分项目';
|
const itemName = detail.itemName || '评分项目';
|
||||||
const option = detail.selectedOption || detail.scoreDescription || '';
|
const option = detail.selectedOption || detail.scoreDescription || '';
|
||||||
const points = [
|
const points = [
|
||||||
@@ -3537,7 +3549,10 @@ export default {
|
|||||||
quantificationId: score.quantificationId ? String(score.quantificationId) : '',
|
quantificationId: score.quantificationId ? String(score.quantificationId) : '',
|
||||||
tempApplyCreditLimit: this.normalizeOptionalAmount(score.tempApplyCreditLimit),
|
tempApplyCreditLimit: this.normalizeOptionalAmount(score.tempApplyCreditLimit),
|
||||||
attachments: score.attachments || this.parseAttachments(score.proofAttachments),
|
attachments: score.attachments || this.parseAttachments(score.proofAttachments),
|
||||||
details: score.details || [],
|
details: (score.details || []).map(detail => ({
|
||||||
|
...detail,
|
||||||
|
scoreInput: this.normalizeScoreInputValue(detail.scoreInput),
|
||||||
|
})),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
normalizeOptionalAmount(value) {
|
normalizeOptionalAmount(value) {
|
||||||
@@ -3836,6 +3851,7 @@ export default {
|
|||||||
...item,
|
...item,
|
||||||
categoryCode: category.categoryCode,
|
categoryCode: category.categoryCode,
|
||||||
categoryName: category.categoryName,
|
categoryName: category.categoryName,
|
||||||
|
scoreInput: this.normalizeScoreInputValue(item.scoreInput),
|
||||||
optionsJson:
|
optionsJson:
|
||||||
item.optionsJson ||
|
item.optionsJson ||
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
@@ -3843,6 +3859,10 @@ export default {
|
|||||||
label: option.label || option.optionName || option.value,
|
label: option.label || option.optionName || option.value,
|
||||||
value: option.value || option.optionName || option.label,
|
value: option.value || option.optionName || option.label,
|
||||||
score: option.score,
|
score: option.score,
|
||||||
|
changeType: option.changeType,
|
||||||
|
changeValue: option.changeValue,
|
||||||
|
changeUnit: option.changeUnit,
|
||||||
|
scoreType: option.scoreType,
|
||||||
}))
|
}))
|
||||||
),
|
),
|
||||||
}))
|
}))
|
||||||
@@ -3862,9 +3882,16 @@ export default {
|
|||||||
...detail,
|
...detail,
|
||||||
categoryCode: detail.categoryCode || category?.categoryCode || '',
|
categoryCode: detail.categoryCode || category?.categoryCode || '',
|
||||||
categoryName: detail.categoryName || category?.categoryName || '',
|
categoryName: detail.categoryName || category?.categoryName || '',
|
||||||
|
scoreInput: this.normalizeScoreInputValue(detail.scoreInput),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
normalizeScoreInputValue(value) {
|
||||||
|
if (value === undefined || value === null || value === '' || value === -1 || value === '-1') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return String(value);
|
||||||
|
},
|
||||||
getScoreDetailCategoryCode(detail = {}) {
|
getScoreDetailCategoryCode(detail = {}) {
|
||||||
const rawCode = String(
|
const rawCode = String(
|
||||||
detail.categoryCode ||
|
detail.categoryCode ||
|
||||||
@@ -3916,12 +3943,24 @@ export default {
|
|||||||
parseScoreOptions(value) {
|
parseScoreOptions(value) {
|
||||||
if (!value) return [];
|
if (!value) return [];
|
||||||
const normalize = list =>
|
const normalize = list =>
|
||||||
list.map(item => ({
|
list.map(item => {
|
||||||
...item,
|
const isScoreOption = item.changeType || item.changeValue || item.changeUnit;
|
||||||
label: item.label || item.optionName || item.value,
|
const changeLabel = item.changeType === 'decrease' ? '每减少' : '每增加';
|
||||||
value: item.value || item.optionName || item.label,
|
const scoreLabel = item.scoreType === 'subtract' ? '减' : '加';
|
||||||
score: item.score,
|
const generatedLabel = isScoreOption
|
||||||
}));
|
? `${changeLabel}${item.changeValue || ''}${item.changeUnit || ''}${scoreLabel}${item.score || ''}分`
|
||||||
|
: '';
|
||||||
|
const label = item.label || item.optionName || item.value || generatedLabel;
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
label,
|
||||||
|
value: item.value || item.optionName || item.label || generatedLabel,
|
||||||
|
score:
|
||||||
|
item.scoreType === 'subtract' && item.score !== undefined
|
||||||
|
? -Math.abs(Number(item.score))
|
||||||
|
: item.score,
|
||||||
|
};
|
||||||
|
});
|
||||||
if (Array.isArray(value)) return normalize(value);
|
if (Array.isArray(value)) return normalize(value);
|
||||||
try {
|
try {
|
||||||
const options = JSON.parse(value);
|
const options = JSON.parse(value);
|
||||||
@@ -3930,6 +3969,50 @@ export default {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isScoreTypeDetail(detail = {}) {
|
||||||
|
return String(detail.optionType || '').toLowerCase() === 'score';
|
||||||
|
},
|
||||||
|
getScoreRule(detail = {}) {
|
||||||
|
return this.parseScoreOptions(detail.optionsJson)[0] || null;
|
||||||
|
},
|
||||||
|
handleScoreValueInput(detail, value) {
|
||||||
|
const raw = String(value ?? '')
|
||||||
|
.replace(/[^\d.-]/g, '')
|
||||||
|
.replace(/(?!^)-/g, '')
|
||||||
|
.replace(/(\..*)\./g, '$1');
|
||||||
|
const sign = raw.startsWith('-') ? '-' : '';
|
||||||
|
const unsigned = raw.replace(/^-/, '');
|
||||||
|
const hasDecimal = unsigned.includes('.');
|
||||||
|
const [integerPart, decimalPart = ''] = unsigned.split('.');
|
||||||
|
const normalized = `${sign}${integerPart}${hasDecimal ? `.${decimalPart.slice(0, 2)}` : ''}`;
|
||||||
|
detail.scoreInput = normalized;
|
||||||
|
const rule = this.getScoreRule(detail);
|
||||||
|
if (!normalized || normalized === '-' || normalized === '.') {
|
||||||
|
detail.selfScore = '';
|
||||||
|
this.calculateScore(this.currentScore);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const base = Number(detail.baseValue);
|
||||||
|
const input = Number(normalized);
|
||||||
|
if (!rule || !Number.isFinite(base) || !Number.isFinite(input)) {
|
||||||
|
detail.selfScore = '';
|
||||||
|
this.calculateScore(this.currentScore);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const increase = rule.changeType !== 'decrease';
|
||||||
|
const valid = increase ? input >= base : input <= base;
|
||||||
|
if (!valid) {
|
||||||
|
detail.selfScore = '';
|
||||||
|
this.$message.warning(`输入值${increase ? '不能小于' : '不能大于'}基准数值${base}`);
|
||||||
|
this.calculateScore(this.currentScore);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const distance = increase ? input - base : base - input;
|
||||||
|
const stepScore = Math.abs(Number(rule.score || 0));
|
||||||
|
const signedStep = rule.scoreType === 'subtract' ? -stepScore : stepScore;
|
||||||
|
detail.selfScore = Number((Number(detail.score || 0) + distance * signedStep).toFixed(2));
|
||||||
|
this.calculateScore(this.currentScore);
|
||||||
|
},
|
||||||
scoreOptionChange(detail, optionValue) {
|
scoreOptionChange(detail, optionValue) {
|
||||||
const option = this.parseScoreOptions(detail.optionsJson).find(
|
const option = this.parseScoreOptions(detail.optionsJson).find(
|
||||||
item => item.value === optionValue
|
item => item.value === optionValue
|
||||||
@@ -4076,9 +4159,13 @@ export default {
|
|||||||
return score;
|
return score;
|
||||||
},
|
},
|
||||||
hasIncompleteBasicScoreDetail(details = []) {
|
hasIncompleteBasicScoreDetail(details = []) {
|
||||||
return this.getScoreCategoryDetailsByList(details, 'basic').some(
|
return this.getScoreCategoryDetailsByList(details, 'basic').some(item => {
|
||||||
item => !item.selectedOption
|
if (this.isScoreTypeDetail(item)) {
|
||||||
);
|
const input = String(item.scoreInput ?? '').trim();
|
||||||
|
return !input || !Number.isFinite(Number(input)) || item.selfScore === '';
|
||||||
|
}
|
||||||
|
return !item.selectedOption;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
finishScore(score) {
|
finishScore(score) {
|
||||||
if (!score.details || !score.details.length) {
|
if (!score.details || !score.details.length) {
|
||||||
@@ -4086,7 +4173,7 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.hasIncompleteBasicScoreDetail(score.details)) {
|
if (this.hasIncompleteBasicScoreDetail(score.details)) {
|
||||||
this.$message.warning('请完整选择基础得分项评分明细选项');
|
this.$message.warning('请完整填写基础得分项评分明细');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.calculateScore(score);
|
this.calculateScore(score);
|
||||||
@@ -4148,6 +4235,17 @@ export default {
|
|||||||
this.$message.warning('当前评分量化表未配置评分项目');
|
this.$message.warning('当前评分量化表未配置评分项目');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const invalidScoreInput = this.currentScore.details.find(item => {
|
||||||
|
if (!this.isScoreTypeDetail(item)) return false;
|
||||||
|
const input = String(item.scoreInput ?? '').trim();
|
||||||
|
return input !== '' && item.selfScore === '';
|
||||||
|
});
|
||||||
|
if (invalidScoreInput) {
|
||||||
|
this.$message.warning(
|
||||||
|
`${invalidScoreInput.itemName || '评分项目'}的输入值不符合基准数值限制,请重新填写`
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const overMaxReviewScore = this.currentScore.details.find(item => {
|
const overMaxReviewScore = this.currentScore.details.find(item => {
|
||||||
if (
|
if (
|
||||||
item.reviewScore === undefined ||
|
item.reviewScore === undefined ||
|
||||||
@@ -4169,7 +4267,7 @@ export default {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (requireComplete && this.hasIncompleteBasicScoreDetail(this.currentScore.details)) {
|
if (requireComplete && this.hasIncompleteBasicScoreDetail(this.currentScore.details)) {
|
||||||
this.$message.warning('请完整选择基础得分项评分明细选项');
|
this.$message.warning('请完整填写基础得分项评分明细');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user