|
|
|
@ -54,6 +54,17 @@ |
|
|
|
<dict-select v-model="form.hazardCategory" :options="dict.type.hazard_category" placeholder="请选择隐患分类" @change="syncDictName('hazardCategory', 'hazardCategoryName', 'hazard_category')" /> |
|
|
|
<dict-select v-model="form.hazardCategory" :options="dict.type.hazard_category" placeholder="请选择隐患分类" @change="syncDictName('hazardCategory', 'hazardCategoryName', 'hazard_category')" /> |
|
|
|
</el-form-item> |
|
|
|
</el-form-item> |
|
|
|
</el-col> |
|
|
|
</el-col> |
|
|
|
|
|
|
|
<el-col :span="12"> |
|
|
|
|
|
|
|
<el-form-item label="积分档位"> |
|
|
|
|
|
|
|
<el-select v-model="form.finalFlowLevelId" placeholder="请选择积分档位" style="width:100%" :loading="tierLoading" @change="handleTierChange"> |
|
|
|
|
|
|
|
<el-option v-for="item in tierOptions" :key="item.id" :label="item.label" :value="item.id" /> |
|
|
|
|
|
|
|
</el-select> |
|
|
|
|
|
|
|
<div v-if="estimatedPoints !== null" class="tier-points-tip"> |
|
|
|
|
|
|
|
预计积分:<strong>{{ estimatedPoints > 0 ? '+' : '' }}{{ estimatedPoints }}</strong> |
|
|
|
|
|
|
|
<span v-if="pointsLoading" class="tier-points-loading">计算中…</span> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
|
|
</el-col> |
|
|
|
<el-col :span="12"> |
|
|
|
<el-col :span="12"> |
|
|
|
<el-form-item label="隐患名称" prop="hazardName"> |
|
|
|
<el-form-item label="隐患名称" prop="hazardName"> |
|
|
|
<el-input v-model.trim="form.hazardName" placeholder="请输入隐患名称" maxlength="200" show-word-limit /> |
|
|
|
<el-input v-model.trim="form.hazardName" placeholder="请输入隐患名称" maxlength="200" show-word-limit /> |
|
|
|
@ -177,7 +188,7 @@ |
|
|
|
<el-dialog title="通过审核" :visible.sync="passVisible" width="460px" append-to-body> |
|
|
|
<el-dialog title="通过审核" :visible.sync="passVisible" width="460px" append-to-body> |
|
|
|
<div class="confirm-content"> |
|
|
|
<div class="confirm-content"> |
|
|
|
<i class="el-icon-warning-outline" /> |
|
|
|
<i class="el-icon-warning-outline" /> |
|
|
|
<p>确认先保存平台补录信息,再通过当前审批任务?积分、员工通知和平台同步均以后端处理结果为准。</p> |
|
|
|
<p>确认先保存平台补录信息,再通过当前审批任务?积分、员工通知和平台同步均以后端处理结果为准。<span v-if="estimatedPoints !== null">本次档位预计积分:<strong>{{ estimatedPoints > 0 ? '+' : '' }}{{ estimatedPoints }}</strong>。</span></p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<span slot="footer" class="dialog-footer"> |
|
|
|
<span slot="footer" class="dialog-footer"> |
|
|
|
<el-button @click="passVisible = false">取消</el-button> |
|
|
|
<el-button @click="passVisible = false">取消</el-button> |
|
|
|
@ -228,6 +239,7 @@ |
|
|
|
<script> |
|
|
|
<script> |
|
|
|
/* global MyConfig */ |
|
|
|
/* global MyConfig */ |
|
|
|
import SelectTree from '@/components/SelectTree' |
|
|
|
import SelectTree from '@/components/SelectTree' |
|
|
|
|
|
|
|
import { getRulesByLevel, trialCalculatePoints } from '@/api/points/rule' |
|
|
|
|
|
|
|
|
|
|
|
const DictSelect = { |
|
|
|
const DictSelect = { |
|
|
|
functional: true, |
|
|
|
functional: true, |
|
|
|
@ -263,6 +275,7 @@ export default { |
|
|
|
dicts: ['tree_dept', 'tree_person', 'hazard_major', 'hazard_category', 'hazard_management_level', 'hazard_source', 'hazard_type', 'hazard_governance_type', 'hazard_funds_source'], |
|
|
|
dicts: ['tree_dept', 'tree_person', 'hazard_major', 'hazard_category', 'hazard_management_level', 'hazard_source', 'hazard_type', 'hazard_governance_type', 'hazard_funds_source'], |
|
|
|
props: { |
|
|
|
props: { |
|
|
|
report: { type: Object, required: true }, |
|
|
|
report: { type: Object, required: true }, |
|
|
|
|
|
|
|
reportId: { type: String, default: '' }, |
|
|
|
attachments: { type: Array, default: () => [] }, |
|
|
|
attachments: { type: Array, default: () => [] }, |
|
|
|
taskId: { type: String, default: '' }, |
|
|
|
taskId: { type: String, default: '' }, |
|
|
|
submitting: Boolean |
|
|
|
submitting: Boolean |
|
|
|
@ -270,6 +283,10 @@ export default { |
|
|
|
data() { |
|
|
|
data() { |
|
|
|
return { |
|
|
|
return { |
|
|
|
form: {}, |
|
|
|
form: {}, |
|
|
|
|
|
|
|
tierOptions: [], |
|
|
|
|
|
|
|
tierLoading: false, |
|
|
|
|
|
|
|
estimatedPoints: null, |
|
|
|
|
|
|
|
pointsLoading: false, |
|
|
|
auditComment: '', |
|
|
|
auditComment: '', |
|
|
|
uploadedAttachments: [], |
|
|
|
uploadedAttachments: [], |
|
|
|
uploading: false, |
|
|
|
uploading: false, |
|
|
|
@ -320,15 +337,29 @@ export default { |
|
|
|
return this.uploadedImageAttachments.map(item => this.attachmentUrl(item)).filter(Boolean) |
|
|
|
return this.uploadedImageAttachments.map(item => this.attachmentUrl(item)).filter(Boolean) |
|
|
|
}, |
|
|
|
}, |
|
|
|
pointsSuffix() { |
|
|
|
pointsSuffix() { |
|
|
|
if (this.report.pointsAwarded === undefined || this.report.pointsAwarded === null || this.report.pointsAwarded === '') return '' |
|
|
|
// 审核阶段按当前档位实时试算,优先展示预计积分;无档位时回退到后端已发放积分。 |
|
|
|
const points = Number(this.report.pointsAwarded) |
|
|
|
const value = this.estimatedPoints !== null ? this.estimatedPoints : this.report.pointsAwarded |
|
|
|
return ` · ${points > 0 ? '+' : ''}${this.report.pointsAwarded} 积分` |
|
|
|
if (value === undefined || value === null || value === '') return '' |
|
|
|
|
|
|
|
const points = Number(value) |
|
|
|
|
|
|
|
if (!points) return '' |
|
|
|
|
|
|
|
return ` · ${points > 0 ? '+' : ''}${value} 积分` |
|
|
|
}, |
|
|
|
}, |
|
|
|
normalizedCurrentLevel() { |
|
|
|
normalizedCurrentLevel() { |
|
|
|
const value = this.report.currentFlowLevel || this.report.hazardCategory || '' |
|
|
|
const value = this.report.currentFlowLevel || this.report.hazardCategory || '' |
|
|
|
const nameMap = { 一般: 'general', 一般隐患: 'general', 较大: 'major', 较大隐患: 'major', 重大: 'critical', 重大隐患: 'critical' } |
|
|
|
const nameMap = { 一般: 'general', 一般隐患: 'general', 较大: 'major', 较大隐患: 'major', 重大: 'critical', 重大隐患: 'critical' } |
|
|
|
return nameMap[value] || value |
|
|
|
return nameMap[value] || value |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
tierFilterLevel() { |
|
|
|
|
|
|
|
return this.report.hazardCategory || this.report.currentFlowLevel || '' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
pointsQueryKey() { |
|
|
|
|
|
|
|
return [ |
|
|
|
|
|
|
|
this.report.factoryDeptId || '', |
|
|
|
|
|
|
|
this.normalizedCurrentLevel || '', |
|
|
|
|
|
|
|
this.form.finalFlowLevelId || '', |
|
|
|
|
|
|
|
this.form.finalFlowLevel || '' |
|
|
|
|
|
|
|
].join('|') |
|
|
|
|
|
|
|
}, |
|
|
|
currentLevelName() { |
|
|
|
currentLevelName() { |
|
|
|
const item = this.levelOptions.find(option => option.value === this.normalizedCurrentLevel) |
|
|
|
const item = this.levelOptions.find(option => option.value === this.normalizedCurrentLevel) |
|
|
|
return (item && item.label) || this.normalizedCurrentLevel || '—' |
|
|
|
return (item && item.label) || this.normalizedCurrentLevel || '—' |
|
|
|
@ -343,6 +374,22 @@ export default { |
|
|
|
this.auditComment = this.form.auditRemark || '' |
|
|
|
this.auditComment = this.form.auditRemark || '' |
|
|
|
this.uploadedAttachments = [] |
|
|
|
this.uploadedAttachments = [] |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
tierFilterLevel: { |
|
|
|
|
|
|
|
immediate: true, |
|
|
|
|
|
|
|
handler(level) { |
|
|
|
|
|
|
|
this.loadTierOptions(level) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
pointsQueryKey: { |
|
|
|
|
|
|
|
immediate: true, |
|
|
|
|
|
|
|
handler() { |
|
|
|
|
|
|
|
this.loadEstimatedPoints() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
estimatedPoints(value) { |
|
|
|
|
|
|
|
// 试算结果供父级同步给「流转与同步」面板。 |
|
|
|
|
|
|
|
this.$emit('estimated-points', value) |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
methods: { |
|
|
|
@ -362,6 +409,66 @@ export default { |
|
|
|
const item = (this.dict.type[dictType] || []).find(option => String(option.value) === String(this.form[valueField])) |
|
|
|
const item = (this.dict.type[dictType] || []).find(option => String(option.value) === String(this.form[valueField])) |
|
|
|
this.$set(this.form, nameField, item ? item.label : '') |
|
|
|
this.$set(this.form, nameField, item ? item.label : '') |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
loadTierOptions(level) { |
|
|
|
|
|
|
|
console.log('[积分档位] loadTierOptions 入参 level =', level, '| report.hazardCategory =', this.report.hazardCategory, '| report.currentFlowLevel =', this.report.currentFlowLevel, '| report.hazardCategoryName =', this.report.hazardCategoryName) |
|
|
|
|
|
|
|
if (!level) { |
|
|
|
|
|
|
|
console.warn('[积分档位] level 为空,跳过查询,tierOptions 清空') |
|
|
|
|
|
|
|
this.tierOptions = [] |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.tierLoading = true |
|
|
|
|
|
|
|
getRulesByLevel(level).then(res => { |
|
|
|
|
|
|
|
console.log('[积分档位] getRulesByLevel 原始返回 =', JSON.stringify(res)) |
|
|
|
|
|
|
|
const data = (res && res.data) || res || {} |
|
|
|
|
|
|
|
console.log('[积分档位] 解析后的 data =', JSON.stringify(data)) |
|
|
|
|
|
|
|
const children = Array.isArray(data.children) ? data.children : [] |
|
|
|
|
|
|
|
const nodes = children.length ? children : (data.root ? [data.root] : []) |
|
|
|
|
|
|
|
console.log('[积分档位] children =', JSON.stringify(children), '| nodes =', JSON.stringify(nodes)) |
|
|
|
|
|
|
|
this.tierOptions = nodes.map(item => ({ |
|
|
|
|
|
|
|
id: item.id, |
|
|
|
|
|
|
|
label: String(item.hazardCategory || item.ruleName || '').toUpperCase() |
|
|
|
|
|
|
|
})) |
|
|
|
|
|
|
|
console.log('[积分档位] 最终 tierOptions =', JSON.stringify(this.tierOptions)) |
|
|
|
|
|
|
|
// 档位列表到达后补一次试算,兼容只有 finalFlowLevelId、没有档位文本的历史数据。 |
|
|
|
|
|
|
|
this.loadEstimatedPoints() |
|
|
|
|
|
|
|
}).catch((err) => { |
|
|
|
|
|
|
|
console.error('[积分档位] getRulesByLevel 请求失败 =', err) |
|
|
|
|
|
|
|
this.tierOptions = [] |
|
|
|
|
|
|
|
}).finally(() => { |
|
|
|
|
|
|
|
this.tierLoading = false |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
handleTierChange(value) { |
|
|
|
|
|
|
|
const item = this.tierOptions.find(option => String(option.id) === String(value)) |
|
|
|
|
|
|
|
this.$set(this.form, 'finalFlowLevel', item ? item.label : '') |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
resolveTierCategory() { |
|
|
|
|
|
|
|
const direct = String(this.form.finalFlowLevel || '').trim() |
|
|
|
|
|
|
|
if (direct) return direct.toUpperCase() |
|
|
|
|
|
|
|
const matched = this.tierOptions.find(item => String(item.id) === String(this.form.finalFlowLevelId)) |
|
|
|
|
|
|
|
return matched ? String(matched.label || '').toUpperCase() : '' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
loadEstimatedPoints() { |
|
|
|
|
|
|
|
const hazardLevel = this.normalizedCurrentLevel |
|
|
|
|
|
|
|
const hazardCategory = this.resolveTierCategory() |
|
|
|
|
|
|
|
if (!hazardLevel || !hazardCategory) { |
|
|
|
|
|
|
|
this.estimatedPoints = null |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.pointsLoading = true |
|
|
|
|
|
|
|
const params = { hazardLevel, hazardCategory } |
|
|
|
|
|
|
|
if (this.report.factoryDeptId) params.deptId = this.report.factoryDeptId |
|
|
|
|
|
|
|
trialCalculatePoints(params).then(res => { |
|
|
|
|
|
|
|
const data = (res && res.data) || res || {} |
|
|
|
|
|
|
|
this.estimatedPoints = data.calculatedPoints === undefined || data.calculatedPoints === null |
|
|
|
|
|
|
|
? null |
|
|
|
|
|
|
|
: Number(data.calculatedPoints) |
|
|
|
|
|
|
|
}).catch(() => { |
|
|
|
|
|
|
|
this.estimatedPoints = null |
|
|
|
|
|
|
|
}).finally(() => { |
|
|
|
|
|
|
|
this.pointsLoading = false |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
}, |
|
|
|
beforeUpload(file) { |
|
|
|
beforeUpload(file) { |
|
|
|
if (this.attachmentCount >= 8) { |
|
|
|
if (this.attachmentCount >= 8) { |
|
|
|
this.$modal.msgError('附件数量不能超过 8 个') |
|
|
|
this.$modal.msgError('附件数量不能超过 8 个') |
|
|
|
@ -432,6 +539,7 @@ export default { |
|
|
|
completeData: { |
|
|
|
completeData: { |
|
|
|
taskId: this.taskId, |
|
|
|
taskId: this.taskId, |
|
|
|
instanceId: this.report.flowInstanceId, |
|
|
|
instanceId: this.report.flowInstanceId, |
|
|
|
|
|
|
|
zyxkid: String(this.reportId || this.report.id || ''), |
|
|
|
comment: this.auditComment || '同意', |
|
|
|
comment: this.auditComment || '同意', |
|
|
|
result: '1' |
|
|
|
result: '1' |
|
|
|
} |
|
|
|
} |
|
|
|
@ -447,6 +555,7 @@ export default { |
|
|
|
completeData: { |
|
|
|
completeData: { |
|
|
|
taskId: this.taskId, |
|
|
|
taskId: this.taskId, |
|
|
|
instanceId: this.report.flowInstanceId, |
|
|
|
instanceId: this.report.flowInstanceId, |
|
|
|
|
|
|
|
zyxkid: String(this.reportId || this.report.id || ''), |
|
|
|
comment, |
|
|
|
comment, |
|
|
|
result: '2' |
|
|
|
result: '2' |
|
|
|
} |
|
|
|
} |
|
|
|
@ -481,6 +590,9 @@ export default { |
|
|
|
.uploaded-remove { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); color: #c0c4cc; font-size: 13px; cursor: pointer; z-index: 1; } |
|
|
|
.uploaded-remove { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); color: #c0c4cc; font-size: 13px; cursor: pointer; z-index: 1; } |
|
|
|
.uploaded-remove:hover { color: #f56c6c; } |
|
|
|
.uploaded-remove:hover { color: #f56c6c; } |
|
|
|
.security-tip, .disabled-tip { margin-top: 6px; color: #f56c6c; font-size: 11px; line-height: 1.6; } |
|
|
|
.security-tip, .disabled-tip { margin-top: 6px; color: #f56c6c; font-size: 11px; line-height: 1.6; } |
|
|
|
|
|
|
|
.tier-points-tip { margin-top: 4px; color: #606266; font-size: 12px; line-height: 18px; } |
|
|
|
|
|
|
|
.tier-points-tip strong { color: #f56c6c; font-weight: 600; } |
|
|
|
|
|
|
|
.tier-points-loading { margin-left: 6px; color: #909399; } |
|
|
|
.action-buttons { display: grid; grid-template-columns: minmax(180px, 1fr) auto auto; gap: 8px; } |
|
|
|
.action-buttons { display: grid; grid-template-columns: minmax(180px, 1fr) auto auto; gap: 8px; } |
|
|
|
.reject-options { display: flex; flex-direction: column; gap: 12px; } |
|
|
|
.reject-options { display: flex; flex-direction: column; gap: 12px; } |
|
|
|
.confirm-content { display: flex; gap: 12px; color: #606266; line-height: 1.7; } |
|
|
|
.confirm-content { display: flex; gap: 12px; color: #606266; line-height: 1.7; } |
|
|
|
|