202 lines
5.6 KiB
Vue
202 lines
5.6 KiB
Vue
<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-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>
|
||
<a-form-item label="默认状态" field="defaultStatus">
|
||
<a-switch
|
||
v-model="form.defaultStatus"
|
||
:checked-value="1"
|
||
:unchecked-value="2"
|
||
checked-text="启用"
|
||
unchecked-text="禁用"
|
||
type="round"
|
||
/>
|
||
</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 MaterialImportResp,
|
||
downloadMaterialInfoImportTemplate,
|
||
importMaterial,
|
||
parseImportMaterial,
|
||
} from '@/apis/material/materialInfo'
|
||
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: '',
|
||
errorPolicy: 1,
|
||
duplicateName: 1,
|
||
duplicateCode: 1,
|
||
defaultStatus: 1,
|
||
})
|
||
|
||
const dataResult = ref<MaterialImportResp>({
|
||
importKey: '',
|
||
totalRows: 0,
|
||
validRows: 0,
|
||
duplicateNameRows: 0,
|
||
duplicateCodeRows: 0,
|
||
})
|
||
|
||
// 重置
|
||
const reset = () => {
|
||
formRef.value?.resetFields()
|
||
dataResult.value.importKey = ''
|
||
uploadFile.value = []
|
||
resetForm()
|
||
}
|
||
|
||
// 下载模板
|
||
const downloadTemplate = () => {
|
||
useDownload(() => downloadMaterialInfoImportTemplate())
|
||
}
|
||
|
||
// 上传解析导入数据
|
||
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 parseImportMaterial(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 importMaterial(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>
|