123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- <script setup lang="ts">
- import { ref, reactive, nextTick } from 'vue'
- import * as XLSX from 'xlsx';
- import { Delete } from '@element-plus/icons-vue'
- import Drawer from '@/components/Drawer/index.vue'
- import type { FormInstance, FormRules } from 'element-plus'
- import { Storehouse_Device_Check } from '@/api/storehouse/index'
- import { ElMessage } from 'element-plus'
- type Fn = () => void
- interface FormSnType {
- Id?: number
- sn: string
- type?: number
- }
- const snTable = ref()
- const SNDataMap = new Map<number, FormSnType[]>()
- const tableSnData = ref<FormSnType[]>([])
- const ruleSnFormRef = ref<FormInstance>()
- const drawerSnRef = ref<InstanceType<typeof Drawer> | null>(null)
- const snColumns = [
- { type: 'index', label: '序号', width: 80, align: 'center ' },
- { label: 'SN', prop: 'sn', align: 'center ' },
- { prop: 'operation', label: '操作', width: 80, fixed: 'right' }
- ]
- const formSn = reactive<FormSnType>({
- Id: undefined,
- sn: '',
- type: undefined
- })
- const rulesSn = reactive<FormRules>({
- sn: [{ required: true, message: '请输入SN号', trigger: 'blur' }]
- })
- const addSn = (formEl: FormInstance | undefined) => {
- if (!formEl) return
- formEl.validate(async valid => {
- if (valid) {
- if (formSn.sn.length === 16 || formSn.sn.length === 24) {
- if(formSn.sn.length==24){
- formSn.sn = formSn.sn.substring(2, formSn.sn.length - 6)
- }
- const res: any = await Storehouse_Device_Check({ T_sn: formSn.sn, T_type: formSn.type })
- if (res.Code === 200) {
- tableSnData.value.unshift({ sn: formSn.sn })
- tableSnData.value = tableSnData.value.filter((value, index, self) => { //去重
- return self.findIndex(t => (t.sn === value.sn)) === index;
- });
- nextTick(() => {
- resetSnForm(ruleSnFormRef.value)
- })
- }
- } else {
- ElMessage.error('扫描设备异常')
- nextTick(() => {
- resetSnForm(ruleSnFormRef.value)
- })
- return
- }
- }
- })
- }
- const deleteSn = (row: any) => {
- const index = tableSnData.value.findIndex((item: any) => row.sn === item.sn)
- tableSnData.value.splice(index, 1)
- }
- const callbackSnDrawer = (done: Fn) => {
- SNDataMap.set(formSn.Id as number, tableSnData.value)
- let arrs = tableSnData.value.map((item:any) => item.sn);
- emit('onCount', SNDataMap.get(formSn.Id as number)?.length, formSn.Id as number,arrs)
- done()
- nextTick(() => {
- resetSnForm(ruleSnFormRef.value)
- tableSnData.value = []
- })
- }
- const emit = defineEmits<{ (event: 'onCount', value: any, id: number,mapArr:any): void }>()
- const resetSnForm = (formEl: FormInstance | undefined) => {
- if (!formEl) return
- formEl.resetFields()
- }
- const addDeviceSn = (id: number, type: number) => {
- console.log('1212',id,type)
- formSn.Id = id
- formSn.type = type
- if (SNDataMap.has(id)) {
- tableSnData.value = SNDataMap.get(id) as FormSnType[]
- } else {
- SNDataMap.set(id, [])
- }
- drawerSnRef.value?.openDrawer()
- }
- const drawer = ref(false)
- /**
- * 导入xlsx
- */
- // 组件状态变化的回调
- const uploadExcelFile = (event:any) => {
- const files = event.target.files;
- if (files.length === 0) return;
- const file = files[0];
- const reader = new FileReader();
- reader.onload = (e:any) => {
- const data = new Uint8Array(e.target.result);
- const workbook = XLSX.read(data, { type: 'array' });
- // 假设我们知道第一个工作表包含我们需要的数据
- const firstSheetName = workbook.SheetNames[0];
- const worksheet:any = workbook.Sheets[firstSheetName];
- // 假设我们知道 t_sn 是第一列
- const tSnColumn = 'A'; // 或者使用 XLSX.utils.decode_col(columnNumber) 来从列号获取列名
- const columnNumber = XLSX.utils.decode_col(tSnColumn); // 但实际上我们可能直接知道列号,如 0
- // 使用 sheet_to_json 但只选择我们需要的列
- const json = XLSX.utils.sheet_to_json(worksheet, { header: 1, range: XLSX.utils.decode_range(worksheet['!ref']) });
- // 如果表头不是第一行,或者你不想要表头,可以调整 header 选项
- // 提取 t_sn 列的数据(假设表头在第一行,且 t_sn 是第一列)
- let tSnData:any = json.map((row:any) => row[0]); // 假设 t_sn 是第一列,所以使用 row[0]
- let snArray = tSnData.map((sn:any) => ({ sn: sn }));
- snArray = snArray.slice(1)
- let arrs = [...tableSnData.value,...snArray]
- // 去重
- let seen = new Set();
- tableSnData.value = arrs.filter((item:any) => {
- return seen.has(item.sn) ? false : seen.add(item.sn) || true;
- });
- console.log('打印',tableSnData.value)
- // 注意:如果 t_sn 列不是第一列,你需要调整索引号
- // 例如,如果 t_sn 是第三列,则使用 row[2]
- };
-
- reader.readAsArrayBuffer(file);
- };
- const getDeviceSn = () => SNDataMap
- const clearDeviceSn = () => SNDataMap.clear()
- const deleteDeviceSn = (id: number) => SNDataMap.delete(id)
- defineExpose({
- getDeviceSn,
- addDeviceSn,
- clearDeviceSn,
- deleteDeviceSn,tableSnData,drawerSnRef
- })
- </script>
- <template>
- <Drawer ref="drawerSnRef" :handleClose="callbackSnDrawer" size="50%">
- <el-card class="box-card" shadow="never">
- <template #header>
- <div class="sn-header">
- <el-form ref="ruleSnFormRef" :model="formSn" :rules="rulesSn">
- <el-form-item label="SN:" label-width="120px" prop="sn">
- <el-input v-model="formSn.sn" type="text" placeholder="请输入SN" @keyup.enter="addSn(ruleSnFormRef)" class="w-50" />
- </el-form-item>
- </el-form>
- <el-button type="primary" @click="addSn(ruleSnFormRef)">添加</el-button>
- <el-button type="success" @click="drawer = true">导入xlsx</el-button>
- </div>
- </template>
- <div>数量:{{ tableSnData.length }}</div>
- <el-table
- ref="snTable"
- :data="tableSnData"
- style="width: 100%; height: 99%"
- :header-cell-style="{
- background: '#dedfe0',
- height: '50px'
- }"
- >
- <template v-for="item in snColumns" :key="item">
- <el-table-column v-if="item.type === 'index'" v-bind="item" />
- <el-table-column show-overflow-tooltip v-if="item.prop" align="center" v-bind="item">
- <template #default="{ row }">
- <el-button
- v-if="item.prop === 'operation'"
- link
- type="danger"
- size="small"
- :icon="Delete"
- @click="deleteSn(row)"
- >删除</el-button
- >
- </template>
- </el-table-column>
- </template>
- </el-table>
- </el-card>
- <el-drawer v-model="drawer" title="导入xlsx" size="50%" :destroy-on-close="true">
- <input type="file" @change="uploadExcelFile" accept=".xlsx, .xls" />
- </el-drawer>
- </Drawer>
- </template>
- <style scoped lang="scss">
- .box-card {
- height: 100%;
- :deep(.el-card__body) {
- height: calc(100% - 70px);
- }
- .sn-header {
- display: flex;
- justify-content: end;
- }
- }
- </style>
|