<template>
|
<ElDialog
|
:model-value="visible"
|
width="80%"
|
top="6vh"
|
destroy-on-close
|
:title="t('pages.task.flowStepDialog.title')"
|
@update:model-value="emit('update:visible', $event)"
|
>
|
<div class="flex flex-col gap-4">
|
<div
|
class="rounded-xl border border-[var(--el-border-color-lighter)] bg-[var(--el-fill-color-blank)] px-4 py-3"
|
>
|
<div class="text-sm text-[var(--art-gray-500)]">{{
|
t('pages.task.flowStepDialog.currentTask')
|
}}</div>
|
<div
|
class="mt-1 flex flex-wrap items-center gap-x-6 gap-y-2 text-sm text-[var(--art-gray-900)]"
|
>
|
<span>{{ t('pages.task.detail.taskCode') }}:{{ taskRow?.taskCode || '--' }}</span>
|
<span
|
>{{ t('pages.task.detail.taskStatus') }}:{{ taskRow?.taskStatusLabel || '--' }}</span
|
>
|
<span>{{ t('pages.task.detail.taskType') }}:{{ taskRow?.taskTypeLabel || '--' }}</span>
|
</div>
|
</div>
|
|
<div class="flex items-center justify-end">
|
<ElButton v-auth="'add'" type="primary" plain @click="handleOpenCreate">
|
{{ t('pages.task.flowStepDialog.create') }}
|
</ElButton>
|
</div>
|
|
<ArtTable
|
:loading="loading"
|
:data="rows"
|
:columns="columns"
|
:pagination="pagination"
|
@pagination:size-change="handleSizeChange"
|
@pagination:current-change="handleCurrentChange"
|
/>
|
</div>
|
|
<ElDialog
|
:model-value="editorVisible"
|
:title="editorTitle"
|
width="560px"
|
append-to-body
|
destroy-on-close
|
@update:model-value="handleEditorVisibleChange"
|
>
|
<ElForm
|
ref="formRef"
|
:model="formData"
|
:rules="formRules"
|
label-width="96px"
|
label-position="right"
|
>
|
<ElFormItem :label="t('pages.task.flowStepDialog.form.taskNo')" prop="taskNo">
|
<ElInput v-model="formData.taskNo" disabled />
|
</ElFormItem>
|
<ElFormItem :label="t('pages.task.flowStepDialog.form.stepOrder')" prop="stepOrder">
|
<ElInputNumber
|
v-model="formData.stepOrder"
|
class="w-full"
|
:min="0"
|
controls-position="right"
|
/>
|
</ElFormItem>
|
<ElFormItem :label="t('pages.task.flowStepDialog.form.stepCode')" prop="stepCode">
|
<ElInput v-model.trim="formData.stepCode" />
|
</ElFormItem>
|
<ElFormItem :label="t('pages.task.flowStepDialog.form.stepName')" prop="stepName">
|
<ElInput v-model.trim="formData.stepName" />
|
</ElFormItem>
|
<ElFormItem :label="t('pages.task.flowStepDialog.form.stepType')" prop="stepType">
|
<ElInput v-model.trim="formData.stepType" />
|
</ElFormItem>
|
<ElFormItem :label="t('pages.task.flowStepDialog.form.status')" prop="status">
|
<ElSelect v-model="formData.status" class="w-full">
|
<ElOption
|
v-for="item in statusOptions"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</ElSelect>
|
</ElFormItem>
|
<ElFormItem :label="t('pages.task.flowStepDialog.form.executeResult')" prop="executeResult">
|
<ElInput
|
v-model.trim="formData.executeResult"
|
type="textarea"
|
:rows="3"
|
:placeholder="t('pages.task.flowStepDialog.form.executeResultPlaceholder')"
|
/>
|
</ElFormItem>
|
</ElForm>
|
|
<template #footer>
|
<div class="flex justify-end gap-3">
|
<ElButton @click="handleEditorVisibleChange(false)">{{ t('common.cancel') }}</ElButton>
|
<ElButton type="primary" :loading="submitLoading" @click="handleSubmit">
|
{{ t('common.actions.save') }}
|
</ElButton>
|
</div>
|
</template>
|
</ElDialog>
|
</ElDialog>
|
</template>
|
|
<script setup>
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { computed, h, reactive, ref, watch } from 'vue'
|
import { useI18n } from 'vue-i18n'
|
import { guardRequestWithMessage } from '@/utils/sys/requestGuard'
|
import ArtButtonMore from '@/components/core/forms/art-button-more/index.vue'
|
import {
|
fetchFlowStepInstancePage,
|
fetchJumpCurrentFlowStepInstance,
|
fetchRemoveFlowStepInstance,
|
fetchSaveFlowStepInstance,
|
fetchUpdateFlowStepInstance
|
} from '@/api/flow-step-instance'
|
import { normalizeFlowStepInstanceRow } from '@/views/system/flow-step-instance/flowStepInstancePage.helpers'
|
|
const props = defineProps({
|
visible: {
|
type: Boolean,
|
default: false
|
},
|
taskRow: {
|
type: Object,
|
default: () => ({})
|
}
|
})
|
|
const emit = defineEmits(['update:visible'])
|
const { t } = useI18n()
|
|
const formRef = ref()
|
const loading = ref(false)
|
const rows = ref([])
|
const editorVisible = ref(false)
|
const submitLoading = ref(false)
|
const editingId = ref(null)
|
const pagination = reactive({
|
current: 1,
|
size: 20,
|
total: 0
|
})
|
const formData = reactive(createFormState())
|
|
const statusOptions = computed(() => [
|
{ value: 0, label: t('pages.task.flowStepDialog.statusOptions.0') },
|
{ value: 1, label: t('pages.task.flowStepDialog.statusOptions.1') },
|
{ value: 2, label: t('pages.task.flowStepDialog.statusOptions.2') },
|
{ value: 3, label: t('pages.task.flowStepDialog.statusOptions.3') },
|
{ value: 4, label: t('pages.task.flowStepDialog.statusOptions.4') },
|
{ value: 5, label: t('pages.task.flowStepDialog.statusOptions.5') },
|
{ value: 6, label: t('pages.task.flowStepDialog.statusOptions.6') }
|
])
|
|
const formRules = computed(() => ({
|
stepOrder: [
|
{
|
required: true,
|
message: t('pages.task.flowStepDialog.validation.stepOrder'),
|
trigger: 'blur'
|
}
|
],
|
stepCode: [
|
{
|
required: true,
|
message: t('pages.task.flowStepDialog.validation.stepCode'),
|
trigger: 'blur'
|
}
|
],
|
stepName: [
|
{
|
required: true,
|
message: t('pages.task.flowStepDialog.validation.stepName'),
|
trigger: 'blur'
|
}
|
],
|
stepType: [
|
{
|
required: true,
|
message: t('pages.task.flowStepDialog.validation.stepType'),
|
trigger: 'blur'
|
}
|
],
|
status: [
|
{
|
required: true,
|
message: t('pages.task.flowStepDialog.validation.status'),
|
trigger: 'change'
|
}
|
]
|
}))
|
|
const editorTitle = computed(() =>
|
editingId.value
|
? t('pages.task.flowStepDialog.editTitle')
|
: t('pages.task.flowStepDialog.createTitle')
|
)
|
|
const columns = computed(() => [
|
{
|
type: 'globalIndex',
|
label: t('table.index'),
|
width: 72,
|
align: 'center'
|
},
|
{
|
prop: 'flowInstanceNo',
|
label: t('pages.task.flowStepDialog.flowInstanceNo'),
|
minWidth: 160,
|
showOverflowTooltip: true
|
},
|
{
|
prop: 'stepCode',
|
label: t('pages.task.flowStepDialog.stepCode'),
|
minWidth: 140,
|
showOverflowTooltip: true
|
},
|
{
|
prop: 'stepName',
|
label: t('pages.task.flowStepDialog.stepName'),
|
minWidth: 180,
|
showOverflowTooltip: true
|
},
|
{
|
prop: 'stepType',
|
label: t('pages.task.flowStepDialog.stepType'),
|
minWidth: 140,
|
showOverflowTooltip: true
|
},
|
{
|
prop: 'executeResult',
|
label: t('pages.task.flowStepDialog.executeResult'),
|
minWidth: 140,
|
showOverflowTooltip: true
|
},
|
{
|
prop: 'statusText',
|
label: t('table.status'),
|
width: 120,
|
showOverflowTooltip: true
|
},
|
{
|
prop: 'startTimeText',
|
label: t('pages.task.flowStepDialog.startTime'),
|
minWidth: 180,
|
showOverflowTooltip: true
|
},
|
{
|
prop: 'endTimeText',
|
label: t('pages.task.flowStepDialog.endTime'),
|
minWidth: 180,
|
showOverflowTooltip: true
|
},
|
{
|
prop: 'operation',
|
label: t('table.operation'),
|
width: 120,
|
align: 'center',
|
fixed: 'right',
|
formatter: (row) =>
|
h(ArtButtonMore, {
|
list: getActionList(row),
|
onClick: (item) => handleActionClick(item, row)
|
})
|
}
|
])
|
|
function createFormState() {
|
return {
|
id: '',
|
taskNo: '',
|
stepOrder: 0,
|
stepCode: '',
|
stepName: '',
|
stepType: '',
|
status: 0,
|
executeResult: ''
|
}
|
}
|
|
function resetFormState(seed = {}) {
|
Object.assign(formData, createFormState(), seed)
|
}
|
|
function getActionList() {
|
return [
|
{
|
key: 'edit',
|
label: t('common.actions.edit'),
|
icon: 'ri:pencil-line',
|
auth: 'update'
|
},
|
{
|
key: 'jumpCurrent',
|
label: t('pages.task.flowStepDialog.jumpCurrent'),
|
icon: 'ri:send-plane-line',
|
auth: 'update'
|
},
|
{
|
key: 'delete',
|
label: t('common.actions.delete'),
|
icon: 'ri:delete-bin-5-line',
|
color: '#f56c6c',
|
auth: 'delete'
|
}
|
]
|
}
|
|
function updatePaginationState(response) {
|
pagination.total = Number(response?.total || 0)
|
pagination.current = Number(response?.current || pagination.current || 1)
|
pagination.size = Number(response?.size || pagination.size || 20)
|
}
|
|
async function loadRows() {
|
if (!props.visible || !props.taskRow?.taskCode) {
|
return
|
}
|
|
loading.value = true
|
try {
|
const response = await guardRequestWithMessage(
|
fetchFlowStepInstancePage({
|
taskNo: props.taskRow.taskCode,
|
current: pagination.current,
|
pageSize: pagination.size
|
}),
|
{
|
records: [],
|
total: 0,
|
current: pagination.current,
|
size: pagination.size
|
},
|
{ timeoutMessage: t('pages.task.flowStepDialog.timeout') }
|
)
|
rows.value = Array.isArray(response?.records)
|
? response.records.map((record) => normalizeFlowStepInstanceRow(record))
|
: []
|
updatePaginationState(response)
|
} finally {
|
loading.value = false
|
}
|
}
|
|
function handleSizeChange(size) {
|
pagination.size = size
|
pagination.current = 1
|
void loadRows()
|
}
|
|
function handleCurrentChange(current) {
|
pagination.current = current
|
void loadRows()
|
}
|
|
function handleOpenCreate() {
|
editingId.value = null
|
resetFormState({
|
taskNo: props.taskRow?.taskCode || '',
|
status: 0
|
})
|
editorVisible.value = true
|
}
|
|
function handleOpenEdit(row) {
|
editingId.value = row.id
|
resetFormState({
|
...row,
|
id: row.id,
|
taskNo: row.taskNo || props.taskRow?.taskCode || '',
|
stepOrder: Number(row.stepOrder ?? 0),
|
status: Number(row.status ?? 0)
|
})
|
editorVisible.value = true
|
}
|
|
function handleEditorVisibleChange(visible) {
|
editorVisible.value = visible
|
if (!visible) {
|
editingId.value = null
|
resetFormState({
|
taskNo: props.taskRow?.taskCode || '',
|
status: 0
|
})
|
formRef.value?.clearValidate()
|
}
|
}
|
|
async function handleSubmit() {
|
if (!formRef.value) {
|
return
|
}
|
|
const valid = await formRef.value.validate().catch(() => false)
|
if (!valid) {
|
return
|
}
|
|
submitLoading.value = true
|
try {
|
const payload = {
|
...(editingId.value ? { id: editingId.value } : {}),
|
taskNo: formData.taskNo,
|
stepOrder: Number(formData.stepOrder ?? 0),
|
stepCode: formData.stepCode,
|
stepName: formData.stepName,
|
stepType: formData.stepType,
|
status: Number(formData.status ?? 0),
|
executeResult: formData.executeResult
|
}
|
|
if (editingId.value) {
|
await fetchUpdateFlowStepInstance(payload)
|
ElMessage.success(t('pages.task.flowStepDialog.messages.updateSuccess'))
|
} else {
|
await fetchSaveFlowStepInstance(payload)
|
ElMessage.success(t('pages.task.flowStepDialog.messages.createSuccess'))
|
}
|
|
handleEditorVisibleChange(false)
|
await loadRows()
|
} catch (error) {
|
ElMessage.error(error?.message || t('pages.task.flowStepDialog.messages.submitFailed'))
|
} finally {
|
submitLoading.value = false
|
}
|
}
|
|
async function handleDelete(row) {
|
try {
|
await ElMessageBox.confirm(
|
t('pages.task.flowStepDialog.messages.deleteConfirm', {
|
code: row.stepCode || row.id || ''
|
}),
|
t('crud.confirm.deleteTitle'),
|
{
|
type: 'warning',
|
confirmButtonText: t('common.confirm'),
|
cancelButtonText: t('common.cancel')
|
}
|
)
|
await fetchRemoveFlowStepInstance(row.id)
|
ElMessage.success(t('pages.task.flowStepDialog.messages.deleteSuccess'))
|
await loadRows()
|
} catch (error) {
|
if (error === 'cancel' || error === 'close') {
|
return
|
}
|
ElMessage.error(error?.message || t('pages.task.flowStepDialog.messages.deleteFailed'))
|
}
|
}
|
|
async function handleJumpCurrent(row) {
|
try {
|
await fetchJumpCurrentFlowStepInstance(row.id)
|
ElMessage.success(t('pages.task.flowStepDialog.messages.jumpSuccess'))
|
await loadRows()
|
} catch (error) {
|
ElMessage.error(error?.message || t('pages.task.flowStepDialog.messages.jumpFailed'))
|
}
|
}
|
|
function handleActionClick(action, row) {
|
if (action.key === 'edit') {
|
handleOpenEdit(row)
|
return
|
}
|
if (action.key === 'jumpCurrent') {
|
void handleJumpCurrent(row)
|
return
|
}
|
if (action.key === 'delete') {
|
void handleDelete(row)
|
}
|
}
|
|
watch(
|
() => [props.visible, props.taskRow?.taskCode],
|
([visible]) => {
|
if (!visible) {
|
rows.value = []
|
pagination.current = 1
|
handleEditorVisibleChange(false)
|
return
|
}
|
pagination.current = 1
|
resetFormState({
|
taskNo: props.taskRow?.taskCode || '',
|
status: 0
|
})
|
void loadRows()
|
}
|
)
|
</script>
|