This commit is contained in:
zc
2026-03-20 18:07:07 +08:00
parent 0dee240c6e
commit 33db8595ec
3 changed files with 242 additions and 5 deletions

View File

@@ -0,0 +1,185 @@
<template>
<a-drawer
v-model:visible="visible"
title="导入物料流程"
:mask-closable="false"
:esc-to-close="false"
:width="width >= 600 ? 600 : '100%'"
ok-text="确认导入"
cancel-text="取消导入"
@before-ok="save"
@close="reset"
>
<a-form ref="formRef" :model="form" size="large" auto-label-width>
<a-alert v-if="!form.disabled" style="margin-bottom: 15px">
请按照模板要求填写数据填写完毕后请先上传并进行解析
<template #action>
<a-link @click="downloadTemplate">
<template #icon><icon-download /></template>
<template #default>下载模板</template>
</a-link>
</template>
</a-alert>
<fieldset>
<legend>1.解析数据</legend>
<div class="file-box">
<a-upload
draggable
:custom-request="handleUpload"
:limit="1"
:show-retry-butto="false"
:show-cancel-button="false" tip="仅支持xls、xlsx格式"
:file-list="uploadFile"
accept=".xls, .xlsx, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
/>
</div>
<div v-if="dataResult.importKey">
<div class="file-box">
<a-space size="large">
<a-statistic title="总计行数" :value="dataResult.totalRows" />
<a-statistic title="正常行数" :value="dataResult.validRows" />
</a-space>
</div>
<div class="file-box">
<a-space size="large">
<a-statistic title="已存在流程名称" :value="dataResult.duplicateNameRows" />
<a-statistic title="已存在流程编码" :value="dataResult.duplicateCodeRows" />
</a-space>
</div>
</div>
</fieldset>
<fieldset>
<legend>2.导入策略</legend>
<a-form-item label="流程名称已存在" field="duplicateName">
<a-radio-group v-model="form.duplicateName" type="button">
<a-radio :value="1">跳过该行</a-radio>
<a-radio :value="2">修改数据</a-radio>
<a-radio :value="3">停止导入</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="流程编码已存在" field="duplicateCode">
<a-radio-group v-model="form.duplicateCode" type="button">
<a-radio :value="1">跳过该行</a-radio>
<a-radio :value="2">修改数据</a-radio>
<a-radio :value="3">停止导入</a-radio>
</a-radio-group>
</a-form-item>
</fieldset>
</a-form>
</a-drawer>
</template>
<script setup lang="ts">
import { type FormInstance, Message, type RequestOption } from '@arco-design/web-vue'
import { useWindowSize } from '@vueuse/core'
import { downloadMaterialProcessImportTemplate, importMaterialProcess, parseImportMaterialProcess } from '@/apis/materialProcess/materialProcess'
import { useDownload, useResetReactive } from '@/hooks'
import { IconDownload as iconDownload } from '@arco-design/web-vue/es/icon'
const emit = defineEmits<{
(e: 'save-success'): void
}>()
const { width } = useWindowSize()
const visible = ref(false)
const formRef = ref<FormInstance>()
const uploadFile = ref([])
const [form, resetForm] = useResetReactive({
importKey: '',
duplicateName: 1,
duplicateCode: 1,
})
const dataResult = ref({
importKey: '',
totalRows: 0,
validRows: 0,
duplicateNameRows: 0,
duplicateCodeRows: 0,
})
// 重置
const reset = () => {
formRef.value?.resetFields()
dataResult.value.importKey = ''
uploadFile.value = []
resetForm()
}
// 下载模板
const downloadTemplate = () => {
useDownload(() => downloadMaterialProcessImportTemplate())
}
// 上传解析导入数据
const handleUpload = (options: RequestOption) => {
const controller = new AbortController();
(async function requestWrap() {
const { onProgress, onError, onSuccess, fileItem, name = 'file' } = options
onProgress(20)
const formData = new FormData()
formData.append(name as string, fileItem.file as Blob)
try {
const res = await parseImportMaterialProcess(formData)
dataResult.value = res.data
Message.success('上传解析成功')
onSuccess(res)
} catch (error) {
onError(error)
}
})()
return {
abort() {
controller.abort()
},
}
}
// 执行导入
const save = async () => {
try {
if (!dataResult.value.importKey) {
Message.warning('请先上传文件,解析导入数据')
return false
}
form.importKey = dataResult.value.importKey
const res = await importMaterialProcess(form)
Message.success(`导入成功! 新增${res.data.insertCount}, 修改${res.data.updateCount},总计处理${res.data.totalHandleCount}`)
emit('save-success')
return true
} catch (error) {
return false
}
}
// 打开
const onOpen = () => {
reset()
visible.value = true
}
defineExpose({ onOpen })
</script>
<style scoped lang="scss">
fieldset {
padding: 15px 15px 0 15px;
margin-bottom: 15px;
border: 1px solid var(--color-neutral-3);
border-radius: 3px;
}
fieldset legend {
color: rgb(var(--gray-10));
padding: 2px 5px 2px 5px;
border: 1px solid var(--color-neutral-3);
border-radius: 3px;
}
.file-box {
margin-bottom: 20px;
margin-left: 10px;
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<div class="gi_table_page">
<GiTable
title="海康物料流程管理"
title="物料流程管理"
row-key="id"
:data="dataList"
:columns="columns"
@@ -10,6 +10,10 @@
:pagination="pagination"
:disabled-tools="['size']"
:disabled-column-keys="['name']"
:selected-keys="selectedKeys"
:row-selection="{ type: 'checkbox', showCheckedAll: true }"
@select-all="selectAll"
@select="select"
@refresh="search"
>
<template #toolbar-left>
@@ -21,10 +25,18 @@
</a-button>
</template>
<template #toolbar-right>
<a-button v-permission="['materialProcess:materialProcess:delete']" type="outline" status="danger" @click="onDelete">
<template #icon><icon-delete /></template>
<template #default>删除</template>
</a-button>
<a-button v-permission="['materialProcess:materialProcess:add']" type="primary" @click="onAdd">
<template #icon><icon-plus /></template>
<template #default>新增</template>
</a-button>
<a-button v-permission="['materialProcess:materialProcess:import']" @click="onImport">
<template #icon><icon-upload /></template>
<template #default>导入</template>
</a-button>
<a-button v-permission="['materialProcess:materialProcess:export']" @click="onExport">
<template #icon><icon-download /></template>
<template #default>导出</template>
@@ -38,7 +50,7 @@
status="danger"
:disabled="record.disabled"
:title="record.disabled ? '不可删除' : '删除'"
@click="onDelete(record)"
@click="onDeleteOne(record)"
>
删除
</a-link>
@@ -47,16 +59,20 @@
</GiTable>
<MaterialProcessAddModal ref="MaterialProcessAddModalRef" @save-success="search" />
<MaterialProcessImportDrawer ref="MaterialProcessImportDrawerRef" @save-success="search" />
</div>
</template>
<script setup lang="ts">
import MaterialProcessAddModal from './MaterialProcessAddModal.vue'
import MaterialProcessImportDrawer from './MaterialProcessImportDrawer.vue'
import { type MaterialProcessResp, type MaterialProcessQuery, deleteMaterialProcess, exportMaterialProcess, listMaterialProcess } from '@/apis/materialProcess/materialProcess'
import type { TableInstanceColumns } from '@/components/GiTable/type'
import { useDownload, useTable } from '@/hooks'
import { isMobile } from '@/utils'
import has from '@/utils/has'
import { IconUpload as iconUpload, IconDownload as iconDownload } from '@arco-design/web-vue/es/icon'
import {Message} from "@arco-design/web-vue";
defineOptions({ name: 'MaterialProcess' })
@@ -71,6 +87,9 @@ const {
tableData: dataList,
loading,
pagination,
selectedKeys,
selectAll,
select,
search,
handleDelete
} = useTable((page) => listMaterialProcess({ ...queryForm, ...page }), { immediate: true })
@@ -100,19 +119,32 @@ const reset = () => {
}
// 删除
const onDelete = (record: MaterialProcessResp) => {
const onDeleteOne = (record: MaterialProcessResp) => {
return handleDelete(() => deleteMaterialProcess(record.id), {
content: `是否确定删除该条数据?`,
showModal: true
})
}
// 删除
const onDelete = () => {
if (!selectedKeys.value.length) {
return Message.warning('请选择数据')
}
return handleDelete(() => deleteMaterialProcess(selectedKeys.value), {
content: `是否确定删除选中的 ${selectedKeys.value.length} 条数据?`,
showModal: true
})
}
// 导出
const onExport = () => {
useDownload(() => exportMaterialProcess(queryForm))
}
const MaterialProcessAddModalRef = ref<InstanceType<typeof MaterialProcessAddModal>>()
const MaterialProcessImportDrawerRef = ref<InstanceType<typeof MaterialProcessImportDrawer>>()
// 新增
const onAdd = () => {
MaterialProcessAddModalRef.value?.onAdd()
@@ -123,7 +155,12 @@ const onUpdate = (record: MaterialProcessResp) => {
MaterialProcessAddModalRef.value?.onUpdate(record)
}
// 导入
const onImport = () => {
MaterialProcessImportDrawerRef.value?.onOpen()
}
</script>
<style scoped lang="scss"></style>
<style scoped lang="scss"></style>