You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
661 lines
20 KiB
661 lines
20 KiB
<template> |
|
<div class="app-container hazard-flow-config-page"> |
|
<data-list-panel modern-table> |
|
<template #filters> |
|
<el-form |
|
v-show="showSearch" |
|
ref="queryForm" |
|
:model="queryParams" |
|
size="small" |
|
:inline="true" |
|
class="data-list-filter-form" |
|
> |
|
<el-form-item label="厂区" prop="deptId"> |
|
<el-select |
|
v-model="queryParams.deptId" |
|
:disabled="!isSuperAdmin" |
|
:loading="factoryLoading" |
|
clearable |
|
filterable |
|
placeholder="全部厂区" |
|
> |
|
<el-option |
|
v-for="item in displayedFactoryOptions" |
|
:key="factoryId(item)" |
|
:label="factoryName(item)" |
|
:value="factoryId(item)" |
|
/> |
|
</el-select> |
|
</el-form-item> |
|
<el-form-item label="隐患等级" prop="hazardLevel"> |
|
<el-select |
|
v-model="queryParams.hazardLevel" |
|
clearable |
|
placeholder="全部隐患等级" |
|
> |
|
<el-option |
|
v-for="item in levelOptions" |
|
:key="item.value" |
|
:label="item.label" |
|
:value="item.value" |
|
/> |
|
</el-select> |
|
</el-form-item> |
|
<el-form-item label="状态" prop="status"> |
|
<el-select |
|
v-model="queryParams.status" |
|
clearable |
|
placeholder="全部状态" |
|
> |
|
<el-option label="正常" value="1" /> |
|
<el-option label="停用" value="0" /> |
|
</el-select> |
|
</el-form-item> |
|
<el-form-item> |
|
<el-button |
|
type="primary" |
|
icon="el-icon-search" |
|
size="mini" |
|
@click="handleQuery" |
|
>搜索</el-button> |
|
<el-button |
|
icon="el-icon-refresh" |
|
size="mini" |
|
@click="resetQuery" |
|
>重置</el-button> |
|
</el-form-item> |
|
</el-form> |
|
</template> |
|
|
|
<template #actions> |
|
<div class="data-list-actions"> |
|
<el-button |
|
type="primary" |
|
size="small" |
|
icon="el-icon-plus" |
|
@click="handleAdd" |
|
>新增</el-button> |
|
<el-button |
|
type="primary" |
|
size="small" |
|
icon="el-icon-edit" |
|
:disabled="single" |
|
:loading="detailLoading" |
|
@click="handleUpdate()" |
|
>修改</el-button> |
|
<el-button |
|
type="danger" |
|
size="small" |
|
icon="el-icon-delete" |
|
:disabled="multiple" |
|
@click="handleDelete()" |
|
>删除</el-button> |
|
<right-toolbar |
|
:show-search.sync="showSearch" |
|
@queryTable="getList" |
|
/> |
|
</div> |
|
</template> |
|
|
|
<!-- <template #header> |
|
<div class="config-heading"> |
|
<div class="config-heading__title">隐患流程模板配置</div> |
|
<div class="config-heading__description"> |
|
按厂区和隐患等级绑定对应的 Flowable 流程模板。 |
|
</div> |
|
</div> |
|
</template> --> |
|
|
|
<el-table |
|
v-loading="loading" |
|
:data="configList" |
|
border |
|
row-key="id" |
|
class="data-list-table" |
|
empty-text="暂无流程模板配置" |
|
@selection-change="handleSelectionChange" |
|
> |
|
<el-table-column type="selection" width="50" align="center" /> |
|
<el-table-column |
|
prop="id" |
|
label="配置编号" |
|
width="100" |
|
align="center" |
|
/> |
|
<el-table-column |
|
prop="deptName" |
|
label="厂区名称" |
|
min-width="130" |
|
show-overflow-tooltip |
|
> |
|
<template slot-scope="scope"> |
|
{{ scope.row.deptName || scope.row.deptId || '-' }} |
|
</template> |
|
</el-table-column> |
|
<el-table-column label="流程类型" width="120" align="center"> |
|
<template slot-scope="scope"> |
|
<el-tag v-if="bizTypeLabel(scope.row)" size="small"> |
|
{{ bizTypeLabel(scope.row) }} |
|
</el-tag> |
|
<span v-else>-</span> |
|
</template> |
|
</el-table-column> |
|
<el-table-column label="隐患等级" width="130" align="center"> |
|
<template slot-scope="scope"> |
|
<el-tag :type="levelTagType(scope.row.hazardLevel)" size="small"> |
|
{{ levelLabel(scope.row) }} |
|
</el-tag> |
|
</template> |
|
</el-table-column> |
|
<el-table-column |
|
prop="flowKey" |
|
label="流程 Key" |
|
min-width="190" |
|
show-overflow-tooltip |
|
/> |
|
<el-table-column |
|
prop="flowName" |
|
label="流程名称" |
|
min-width="220" |
|
show-overflow-tooltip |
|
> |
|
<template slot-scope="scope"> |
|
{{ scope.row.flowName || '-' }} |
|
</template> |
|
</el-table-column> |
|
<el-table-column label="状态" width="130" align="center"> |
|
<template slot-scope="scope"> |
|
<el-tag |
|
:type="statusValue(scope.row.status) === '1' ? 'success' : 'info'" |
|
size="small" |
|
> |
|
{{ statusValue(scope.row.status) === '1' ? '正常' : '停用' }} |
|
</el-tag> |
|
</template> |
|
</el-table-column> |
|
<el-table-column |
|
label="操作" |
|
width="160" |
|
align="center" |
|
fixed="right" |
|
class-name="data-list-operation-column" |
|
> |
|
<template slot-scope="scope"> |
|
<el-button |
|
size="mini" |
|
:loading="detailLoadingId === scope.row.id" |
|
@click="handleUpdate(scope.row)" |
|
>修改</el-button> |
|
<el-button |
|
type="danger" |
|
size="mini" |
|
@click="handleDelete(scope.row)" |
|
>删除</el-button> |
|
</template> |
|
</el-table-column> |
|
</el-table> |
|
|
|
<template #footer> |
|
<pagination |
|
v-show="total > 0" |
|
:total="total" |
|
:page.sync="queryParams.pageNum" |
|
:limit.sync="queryParams.pageSize" |
|
@pagination="getList" |
|
/> |
|
<div class="scope-note"> |
|
管理员可查看/配置所有厂区;厂区二级管理员仅能查看本厂区配置(数据范围「本部门」自动过滤)。隐患上报时后端根据「用户所属厂区 + 隐患等级」自动匹配对应 flowKey 启动流程。 |
|
</div> |
|
</template> |
|
</data-list-panel> |
|
|
|
<el-dialog |
|
:title="dialogTitle" |
|
:visible.sync="dialogVisible" |
|
width="620px" |
|
append-to-body |
|
:close-on-click-modal="false" |
|
> |
|
<el-form |
|
ref="configForm" |
|
:model="form" |
|
:rules="formRules" |
|
label-width="92px" |
|
size="small" |
|
class="config-form" |
|
> |
|
<el-row :gutter="16"> |
|
<el-col :xs="24" :sm="12"> |
|
<el-form-item label="厂区" prop="deptId"> |
|
<el-select |
|
v-model="form.deptId" |
|
:disabled="dialogMode === 'edit' || !isSuperAdmin" |
|
:loading="factoryLoading" |
|
filterable |
|
placeholder="请选择厂区" |
|
style="width: 100%" |
|
> |
|
<el-option |
|
v-for="item in displayedFactoryOptions" |
|
:key="factoryId(item)" |
|
:label="factoryName(item)" |
|
:value="factoryId(item)" |
|
/> |
|
</el-select> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :xs="24" :sm="12"> |
|
<el-form-item label="流程类型" prop="bizType"> |
|
<el-select |
|
v-model="form.bizType" |
|
placeholder="请选择流程类型" |
|
style="width: 100%" |
|
> |
|
<el-option |
|
v-for="item in dict.type.flow_biz_type" |
|
:key="item.value" |
|
:label="item.label" |
|
:value="item.value" |
|
/> |
|
</el-select> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :xs="24" :sm="12"> |
|
<el-form-item label="隐患等级" prop="hazardLevel"> |
|
<el-select |
|
v-model="form.hazardLevel" |
|
:disabled="dialogMode === 'edit'" |
|
placeholder="请选择隐患等级" |
|
style="width: 100%" |
|
> |
|
<el-option |
|
v-for="item in levelOptions" |
|
:key="item.value" |
|
:label="item.label" |
|
:value="item.value" |
|
/> |
|
</el-select> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :xs="24" :sm="12"> |
|
<el-form-item label="流程 Key" prop="flowKey"> |
|
<el-input |
|
v-model.trim="form.flowKey" |
|
maxlength="100" |
|
placeholder="请输入 Flowable 流程定义 Key" |
|
/> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :xs="24" :sm="12"> |
|
<el-form-item label="流程名称" prop="flowName"> |
|
<el-input |
|
v-model.trim="form.flowName" |
|
maxlength="100" |
|
placeholder="请输入流程名称" |
|
/> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :span="24"> |
|
<el-form-item label="状态" prop="status"> |
|
<el-switch |
|
v-model="form.status" |
|
active-value="1" |
|
inactive-value="0" |
|
active-text="正常" |
|
inactive-text="停用" |
|
/> |
|
</el-form-item> |
|
</el-col> |
|
</el-row> |
|
</el-form> |
|
<span slot="footer" class="dialog-footer"> |
|
<el-button @click="dialogVisible = false">取消</el-button> |
|
<el-button type="primary" :loading="saving" @click="submitForm"> |
|
确定 |
|
</el-button> |
|
</span> |
|
</el-dialog> |
|
</div> |
|
</template> |
|
|
|
<script> |
|
import { |
|
addHazardFlowConfig, |
|
deleteHazardFlowConfig, |
|
getHazardFlowConfig, |
|
listHazardFlowConfigs, |
|
updateHazardFlowConfig |
|
} from '@/api/flowable/hazardConfig' |
|
import { |
|
getMyFactoryDepartment, |
|
listFactoryDepartments |
|
} from '@/api/system/dept' |
|
|
|
const LEVEL_OPTIONS = [ |
|
{ value: 'general', label: '一般隐患' }, |
|
{ value: 'major', label: '较大隐患' }, |
|
{ value: 'critical', label: '重大隐患' } |
|
] |
|
|
|
export default { |
|
name: 'HazardFlowConfig', |
|
dicts: ['flow_biz_type'], |
|
data() { |
|
const validateDept = (rule, value, callback) => { |
|
if (this.isSuperAdmin && !value) { |
|
callback(new Error('请选择厂区')) |
|
return |
|
} |
|
callback() |
|
} |
|
return { |
|
showSearch: true, |
|
loading: false, |
|
factoryLoading: false, |
|
detailLoading: false, |
|
detailLoadingId: undefined, |
|
saving: false, |
|
total: 0, |
|
configList: [], |
|
selectedRows: [], |
|
single: true, |
|
multiple: true, |
|
factoryOptions: [], |
|
currentFactory: null, |
|
levelOptions: LEVEL_OPTIONS, |
|
dialogVisible: false, |
|
dialogMode: 'add', |
|
dialogTitle: '新增流程模板配置', |
|
queryParams: { |
|
pageNum: 1, |
|
pageSize: 10, |
|
deptId: undefined, |
|
hazardLevel: undefined, |
|
status: undefined |
|
}, |
|
form: this.createEmptyForm(), |
|
formRules: { |
|
deptId: [{ validator: validateDept, trigger: 'change' }], |
|
bizType: [ |
|
{ required: true, message: '请选择流程类型', trigger: 'change' } |
|
], |
|
hazardLevel: [ |
|
{ required: true, message: '请选择隐患等级', trigger: 'change' } |
|
], |
|
flowKey: [ |
|
{ required: true, message: '请输入流程 Key', trigger: 'blur' } |
|
] |
|
} |
|
} |
|
}, |
|
computed: { |
|
isSuperAdmin() { |
|
return (this.$store.getters.roles || []).indexOf('admin') !== -1 |
|
}, |
|
displayedFactoryOptions() { |
|
if (this.isSuperAdmin) return this.factoryOptions |
|
return this.currentFactory ? [this.currentFactory] : [] |
|
} |
|
}, |
|
created() { |
|
this.getList() |
|
this.loadFactoryScope() |
|
}, |
|
methods: { |
|
createEmptyForm() { |
|
return { |
|
id: undefined, |
|
deptId: '', |
|
deptName: '', |
|
bizType: '', |
|
hazardLevel: '', |
|
hazardLevelName: '', |
|
flowKey: '', |
|
flowName: '', |
|
status: '1' |
|
} |
|
}, |
|
unwrapData(response) { |
|
return response && response.data !== undefined ? response.data : response |
|
}, |
|
getList() { |
|
this.loading = true |
|
const params = Object.assign({}, this.queryParams) |
|
if (!this.isSuperAdmin) delete params.deptId |
|
listHazardFlowConfigs(params) |
|
.then(response => { |
|
const page = this.unwrapData(response) || {} |
|
this.configList = Array.isArray(page.list) ? page.list : [] |
|
this.total = Number(page.total) || 0 |
|
}) |
|
.catch(() => { |
|
this.configList = [] |
|
this.total = 0 |
|
this.$modal.msgError('流程模板配置加载失败') |
|
}) |
|
.finally(() => { |
|
this.loading = false |
|
}) |
|
}, |
|
loadFactoryScope() { |
|
this.factoryLoading = true |
|
const request = this.isSuperAdmin |
|
? listFactoryDepartments() |
|
: getMyFactoryDepartment() |
|
request |
|
.then(response => { |
|
const data = this.unwrapData(response) |
|
if (this.isSuperAdmin) { |
|
this.factoryOptions = Array.isArray(data) |
|
? data |
|
: (data && (data.list || data.rows)) || [] |
|
return |
|
} |
|
this.currentFactory = data || null |
|
if (this.currentFactory) { |
|
this.queryParams.deptId = this.factoryId(this.currentFactory) |
|
} |
|
}) |
|
.catch(() => { |
|
this.factoryOptions = [] |
|
this.currentFactory = null |
|
this.$modal.msgError('厂区信息加载失败') |
|
}) |
|
.finally(() => { |
|
this.factoryLoading = false |
|
}) |
|
}, |
|
handleQuery() { |
|
this.queryParams.pageNum = 1 |
|
this.getList() |
|
}, |
|
resetQuery() { |
|
this.resetForm('queryForm') |
|
if (!this.isSuperAdmin && this.currentFactory) { |
|
this.queryParams.deptId = this.factoryId(this.currentFactory) |
|
} |
|
this.handleQuery() |
|
}, |
|
handleSelectionChange(selection) { |
|
this.selectedRows = selection |
|
this.single = selection.length !== 1 |
|
this.multiple = selection.length === 0 |
|
}, |
|
handleAdd() { |
|
this.dialogMode = 'add' |
|
this.dialogTitle = '新增流程模板配置' |
|
this.form = this.createEmptyForm() |
|
if (!this.isSuperAdmin && this.currentFactory) { |
|
this.form.deptId = this.factoryId(this.currentFactory) |
|
this.form.deptName = this.factoryName(this.currentFactory) |
|
} |
|
this.dialogVisible = true |
|
this.$nextTick(() => this.$refs.configForm.clearValidate()) |
|
}, |
|
handleUpdate(row) { |
|
const target = row || this.selectedRows[0] |
|
if (!target || target.id === undefined || target.id === null) return |
|
this.detailLoading = true |
|
this.detailLoadingId = target.id |
|
getHazardFlowConfig(target.id) |
|
.then(response => { |
|
const detail = this.unwrapData(response) || target |
|
this.form = this.normalizeForm(Object.assign({}, target, detail)) |
|
this.dialogMode = 'edit' |
|
this.dialogTitle = '修改流程模板配置' |
|
this.dialogVisible = true |
|
this.$nextTick(() => this.$refs.configForm.clearValidate()) |
|
}) |
|
.catch(() => { |
|
this.$modal.msgError('流程模板配置详情加载失败') |
|
}) |
|
.finally(() => { |
|
this.detailLoading = false |
|
this.detailLoadingId = undefined |
|
}) |
|
}, |
|
normalizeForm(data) { |
|
return { |
|
id: data.id, |
|
deptId: data.deptId === undefined || data.deptId === null |
|
? '' |
|
: String(data.deptId), |
|
deptName: data.deptName || '', |
|
bizType: data.bizType || '', |
|
hazardLevel: data.hazardLevel || '', |
|
hazardLevelName: data.hazardLevelName || '', |
|
flowKey: data.flowKey || '', |
|
flowName: data.flowName || '', |
|
status: this.statusValue(data.status) |
|
} |
|
}, |
|
submitForm() { |
|
this.$refs.configForm.validate(valid => { |
|
if (!valid) return |
|
const payload = this.buildPayload(this.form) |
|
const request = this.dialogMode === 'edit' |
|
? updateHazardFlowConfig(payload) |
|
: addHazardFlowConfig(payload) |
|
this.saving = true |
|
request |
|
.then(() => { |
|
this.$modal.msgSuccess( |
|
this.dialogMode === 'edit' ? '修改成功' : '新增成功' |
|
) |
|
this.dialogVisible = false |
|
this.getList() |
|
}) |
|
.finally(() => { |
|
this.saving = false |
|
}) |
|
}) |
|
}, |
|
buildPayload(source) { |
|
const payload = { |
|
id: source.id, |
|
deptId: source.deptId, |
|
deptName: source.deptName, |
|
bizType: source.bizType, |
|
hazardLevel: source.hazardLevel, |
|
hazardLevelName: this.levelName(source.hazardLevel), |
|
flowKey: source.flowKey, |
|
flowName: source.flowName || undefined, |
|
status: this.statusValue(source.status) |
|
} |
|
const factory = this.displayedFactoryOptions.find( |
|
item => this.factoryId(item) === String(payload.deptId || '') |
|
) |
|
if (factory) payload.deptName = this.factoryName(factory) |
|
if (this.dialogMode === 'add') delete payload.id |
|
if (this.dialogMode === 'add' && !this.isSuperAdmin) { |
|
delete payload.deptId |
|
delete payload.deptName |
|
} |
|
return payload |
|
}, |
|
handleDelete(row) { |
|
const rows = row && row.id !== undefined ? [row] : this.selectedRows |
|
const ids = rows |
|
.map(item => item.id) |
|
.filter(id => id !== undefined && id !== null) |
|
if (!ids.length) return |
|
const message = ids.length === 1 |
|
? '确认删除该流程模板配置吗?' |
|
: '确认删除选中的 ' + ids.length + ' 条流程模板配置吗?' |
|
this.$modal.confirm(message) |
|
.then(() => Promise.all(ids.map(id => deleteHazardFlowConfig(id)))) |
|
.then(() => { |
|
this.$modal.msgSuccess('删除成功') |
|
this.getList() |
|
}) |
|
}, |
|
factoryId(item) { |
|
const value = item && (item.deptId !== undefined ? item.deptId : item.id) |
|
return value === undefined || value === null ? '' : String(value) |
|
}, |
|
factoryName(item) { |
|
return (item && (item.deptName || item.label || item.name)) || '' |
|
}, |
|
levelName(value) { |
|
const item = this.levelOptions.find(option => option.value === value) |
|
return item ? item.label : value || '-' |
|
}, |
|
levelLabel(row) { |
|
return row.hazardLevelName || this.levelName(row.hazardLevel) |
|
}, |
|
bizTypeLabel(row) { |
|
const value = row && row.bizType |
|
if (value === undefined || value === null || value === '') return '' |
|
const item = (this.dict.type.flow_biz_type || []).find( |
|
option => String(option.value) === String(value) |
|
) |
|
return item ? item.label : String(value) |
|
}, |
|
levelTagType(value) { |
|
return { |
|
general: '', |
|
major: 'warning', |
|
critical: 'danger' |
|
}[value] || 'info' |
|
}, |
|
statusValue(value) { |
|
return String(value) === '0' ? '0' : '1' |
|
} |
|
} |
|
} |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
.config-heading__title { |
|
color: var(--prototype-text, #1a1a2e); |
|
font-size: 14px; |
|
font-weight: 600; |
|
} |
|
|
|
.config-heading__description { |
|
margin-top: 4px; |
|
color: var(--prototype-text-secondary, #6b7280); |
|
font-size: 12px; |
|
font-weight: 400; |
|
} |
|
|
|
.scope-note { |
|
margin-top: 10px; |
|
padding: 9px 12px; |
|
// border-left: 3px solid var(--prototype-primary, #1890ff); |
|
// background: var(--prototype-panel-soft, #fafbfc); |
|
color: var(--prototype-text-secondary, #6b7280); |
|
font-size: 12px; |
|
line-height: 20px; |
|
} |
|
|
|
::v-deep .config-form .el-form-item { |
|
margin-bottom: 18px; |
|
} |
|
|
|
@media (max-width: 768px) { |
|
::v-deep .el-dialog { |
|
width: calc(100% - 24px) !important; |
|
} |
|
} |
|
</style>
|
|
|