This commit is contained in:
zc
2026-04-12 18:26:48 +08:00
parent d1aca2113d
commit 69c1430836
3 changed files with 220 additions and 0 deletions

View File

@@ -21,6 +21,19 @@ export interface MaterialTypeQuery {
}
export interface MaterialTypePageQuery extends MaterialTypeQuery, PageQuery {}
export interface MaterialTypeImportResp {
importKey: string
totalRows: number
validRows: number
duplicateNameRows: number
}
export interface MaterialTypeImportResult {
insertRows: number
updateRows: number
totalRows: number
}
/** @desc 查询物料品类列表 */
export function listMaterialType(query: MaterialTypePageQuery) {
return http.get<PageRes<MaterialTypeResp[]>>(`${BASE_URL}`, query)
@@ -50,3 +63,18 @@ export function deleteMaterialType(id: string) {
export function exportMaterialType(query: MaterialTypeQuery) {
return http.download(`${BASE_URL}/export`, query)
}
/** @desc 下载物料品类导入模板 */
export function downloadMaterialTypeImportTemplate() {
return http.download(`${BASE_URL}/importTemplate`)
}
/** @desc 解析物料品类导入数据 */
export function parseImportMaterialType(data: FormData) {
return http.post<MaterialTypeImportResp>(`${BASE_URL}/parseImport`, data)
}
/** @desc 导入物料品类 */
export function importMaterialType(data: any) {
return http.post<MaterialTypeImportResult>(`${BASE_URL}/import`, data)
}

View File

@@ -0,0 +1,179 @@
<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><GiSvgIcon name="file-excel" :size="16" /></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-space>
</div>
</div>
</fieldset>
<fieldset>
<legend>2.导入策略</legend>
<a-form-item label="品类名已存在" field="duplicateTypeName">
<a-radio-group v-model="form.duplicateTypeName" 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 {
type MaterialTypeImportResp,
downloadMaterialTypeImportTemplate,
importMaterialType,
parseImportMaterialType,
} from '@/apis/materialType/materialType'
import { useDownload, useResetReactive } from '@/hooks'
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: '',
duplicateTypeName: 1,
})
const dataResult = ref<MaterialTypeImportResp>({
importKey: '',
totalRows: 0,
validRows: 0,
duplicateNameRows: 0,
})
// 重置
const reset = () => {
formRef.value?.resetFields()
dataResult.value.importKey = ''
uploadFile.value = []
resetForm()
}
// 下载模板
const downloadTemplate = () => {
useDownload(() => downloadMaterialTypeImportTemplate())
}
// 上传解析导入数据
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 parseImportMaterialType(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 importMaterialType(form)
Message.success(`导入成功! 新增${res.data.insertRows}, 修改${res.data.updateRows},总计处理${res.data.totalRows}`)
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

@@ -28,6 +28,10 @@
<template #icon><icon-plus /></template>
<template #default>新增</template>
</a-button>
<a-button v-permission="['materialType:materialType:import']" @click="onImport">
<template #icon><icon-upload /></template>
<template #default>导入</template>
</a-button>
<a-button v-permission="['materialType:materialType:export']" @click="onExport">
<template #icon><icon-download /></template>
<template #default>导出</template>
@@ -53,12 +57,14 @@
</GiTable>
<MaterialTypeAddModal ref="MaterialTypeAddModalRef" @save-success="search" />
<MaterialTypeImportDrawer ref="MaterialTypeImportDrawerRef" @save-success="search" />
</div>
</template>
<script setup lang="ts">
import { h } from 'vue'
import MaterialTypeAddModal from './MaterialTypeAddModal.vue'
import MaterialTypeImportDrawer from './MaterialTypeImportDrawer.vue'
import { type MaterialTypeResp, type MaterialTypeQuery, deleteMaterialType, exportMaterialType, listMaterialType } from '@/apis/materialType/materialType'
import type { TableInstanceColumns } from '@/components/GiTable/type'
import { useDownload, useTable } from '@/hooks'
@@ -138,6 +144,8 @@ const onExport = () => {
}
const MaterialTypeAddModalRef = ref<InstanceType<typeof MaterialTypeAddModal>>()
const MaterialTypeImportDrawerRef = ref<InstanceType<typeof MaterialTypeImportDrawer>>()
// 新增
const onAdd = () => {
MaterialTypeAddModalRef.value?.onAdd()
@@ -148,6 +156,11 @@ const onUpdate = (record: MaterialTypeResp) => {
MaterialTypeAddModalRef.value?.onUpdate(record)
}
// 导入
const onImport = () => {
MaterialTypeImportDrawerRef.value?.onOpen()
}
</script>
<style scoped lang="scss"></style>