设备点位导入

main
liutao 1 week ago
parent 8e24e37673
commit 6d74957b6e

@ -57,8 +57,8 @@ export const ProductUnitApi = {
return await request.get({ url: `/erp/product-unit/flag-list`})
},
// 下载用户导入模板
importUserTemplate: async () => {
// 下载产品主单位导入模板
importProductUnitTemplate: async () => {
return await request.download({ url: '/erp/product-unit/get-import-template' })
}
}

@ -195,6 +195,10 @@ export const DeviceApi = {
getDeviceAttributeList: async (deviceId: number | string) => {
return await request.get({ url: `/iot/device/device-attribute/list?deviceId=` + deviceId })
},
// 下载设备属性导入模板
importDeviceAttributeTemplate: async () => {
return await request.download({ url: '/iot/device/device-attribute/get-import-template' })
},
getDeviceContactModelPage: async () => {
return await request.get({ url: `/iot/device-contact-model/page` })
@ -219,7 +223,7 @@ export const DeviceApi = {
return await request.download({ url: `/iot/device-contact-model/export-excel`, params })
},
// 获得设备属性
// 获得设备点位
getDeviceAttribute: async (id: number) => {
return await request.get({ url: `/iot/device-contact-model/get?id=` + id })
}

@ -4935,6 +4935,7 @@ export default {
create: 'Create',
batchDelete: 'Batch Delete',
export: 'Export',
import: 'Import',
placeholderCode: 'Please enter type code',
placeholderName: 'Please enter type name',
@ -5059,7 +5060,7 @@ export default {
create: 'Create',
batchDelete: 'Batch Delete',
export: 'Export',
import: 'Import',
placeholderDeviceCode: 'Please enter device code',
placeholderDeviceName: 'Please enter device name',
placeholderModel: 'Please select device model',
@ -5089,7 +5090,7 @@ export default {
dataUnit: 'Unit',
ratio: 'Ratio',
remark: 'Remark',
deviceAttributeTabLabel: 'Device Attributes',
deviceAttributeTabLabel: 'Device Point',
deviceRuleTabLabel: 'Point Rules',
currentDeviceLabel: 'Current Device: ',
@ -5136,7 +5137,17 @@ export default {
messageDeviceInfoMissingForRules: 'Device information is missing, unable to load point rules',
gridView: 'gridView',
sudoku: 'sudoku'
sudoku: 'sudoku',
importDragText: 'Drag file here, or',
importClickText: 'click to upload',
importUpdateSupport: 'Update existing user data if present',
importFormatLimit: 'Only xls, xlsx format files are allowed.',
importDownloadTemplate: 'Download template',
importFileRequired: 'Please upload file',
importSuccessTip:
'Upload success: {createCount}; Update success: {updateCount}; Update failed: {failureCount};',
importFailed: 'Upload failed, please upload again!',
importFileLimit: 'Only one file can be uploaded!'
},
RunReport: {
moduleName: 'Device Operation Report',

@ -4912,7 +4912,7 @@ export default {
create: '新增',
batchDelete: '批量删除',
export: '导出',
import: '导入',
placeholderDeviceCode: '请输入设备编号',
placeholderDeviceName: '请输入设备名称',
placeholderModel: '请选择设备模型',
@ -4942,7 +4942,7 @@ export default {
dataUnit: '单位',
ratio: '倍率',
remark: '备注',
deviceAttributeTabLabel: '设备属性',
deviceAttributeTabLabel: '设备点位',
deviceRuleTabLabel: '点位规则',
currentDeviceLabel: '当前设备:',
@ -4989,7 +4989,17 @@ export default {
messageDeviceInfoMissingForRules: '设备信息缺失,无法加载点位规则',
gridView: '表格视图',
sudoku: '九宫格'
sudoku: '九宫格',
importDragText: '将文件拖到此处,或',
importClickText: '点击上传',
importUpdateSupport: '是否更新已经存在的用户数据',
importFormatLimit: '仅允许导入 xls、xlsx 格式文件。',
importDownloadTemplate: '下载模板',
importFileRequired: '请上传文件',
importSuccessTip:
'上传成功数量:{createCount};更新成功数量:{updateCount};更新失败数量:{failureCount}',
importFailed: '上传失败,请您重新上传!',
importFileLimit: '最多只能上传一个文件!'
},
RunReport: {
moduleName: '设备运行报表',

@ -138,7 +138,7 @@ const handleExceed = (): void => {
/** 下载模板操作 */
const importTemplate = async () => {
const res = await ProductUnitApi.importUserTemplate()
const res = await ProductUnitApi.importProductUnitTemplate()
download.excel(res, '单位导入模版.xls')
}
</script>

@ -0,0 +1,151 @@
<template>
<Dialog v-model="dialogVisible" :title="t('DataCollection.Device.import')" width="400">
<el-upload
ref="uploadRef"
v-model:file-list="fileList"
:action="importUrl + '?updateSupport=' + updateSupport + '&deviceId=' + deviceId"
:auto-upload="false"
:disabled="formLoading"
:headers="uploadHeaders"
:limit="1"
:on-error="submitFormError"
:on-exceed="handleExceed"
:on-success="submitFormSuccess"
accept=".xlsx, .xls"
drag
>
<Icon icon="ep:upload" />
<div class="el-upload__text">
{{ t('DataCollection.Device.importDragText') }}<em>{{ t('DataCollection.Device.importClickText') }}</em>
</div>
<template #tip>
<div class="el-upload__tip text-center">
<!-- <div class="el-upload__tip">
<el-checkbox v-model="updateSupport" />
{{ t('FactoryModeling.ProductUnit.importUpdateSupport') }}
</div>-->
<span>{{ t('DataCollection.Device.importFormatLimit') }}</span>
<el-link
:underline="false"
style="font-size: 12px; vertical-align: baseline"
type="primary"
@click="importTemplate"
>
{{ t('DataCollection.Device.importDownloadTemplate') }}
</el-link>
</div>
</template>
</el-upload>
<template #footer>
<el-button :disabled="formLoading" type="primary" @click="submitForm">{{ t('common.ok') }}</el-button>
<el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
</template>
<script lang="ts" setup>
import * as UserApi from '@/api/system/user'
import { getAccessToken, getTenantId } from '@/utils/auth'
import download from '@/utils/download'
import { DeviceApi } from '@/api/iot/device'
defineOptions({ name: 'DeviceAttributeImportForm' })
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const formLoading = ref(false) //
const uploadRef = ref()
const importUrl =
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/iot/device/device-attribute/import'
const deviceId = ref<number | string>()
const uploadHeaders = ref() // Header
const fileList = ref([]) //
const updateSupport = ref(0) //
/** 打开弹窗 */
const open = (id: number | string) => {
deviceId.value = id
dialogVisible.value = true
updateSupport.value = 0
fileList.value = []
resetForm()
}
defineExpose({ open }) // open
/** 提交表单 */
const submitForm = async () => {
if (!deviceId.value) {
message.error(t('DataCollection.Device.messageSelectDeviceRequired'))
return
}
if (fileList.value.length == 0) {
message.error(t('DataCollection.Device.importFileRequired'))
return
}
//
uploadHeaders.value = {
Authorization: 'Bearer ' + getAccessToken(),
'tenantId': getTenantId()
}
formLoading.value = true
uploadRef.value!.submit()
}
/** 文件上传成功 */
const emits = defineEmits(['success'])
const submitFormSuccess = (response: any) => {
if (response.code !== 0) {
message.error(response.msg)
formLoading.value = false
return
}
/* // 拼接提示语
const data = response.data
let text = t('FactoryModeling.ProductUnit.importSuccessTip', {
createCount: data.createUsernames.length,
updateCount: data.updateUsernames.length,
failureCount: Object.keys(data.failureUsernames).length
})
for (let username of data.createUsernames) {
text += '< ' + username + ' >'
}
for (const username of data.updateUsernames) {
text += '< ' + username + ' >'
}
for (const username in data.failureUsernames) {
text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
}*/
message.alert(response.data)
formLoading.value = false
dialogVisible.value = false
//
emits('success')
}
/** 上传错误提示 */
const submitFormError = (): void => {
message.error(t('DataCollection.Device.importFailed'))
formLoading.value = false
}
/** 重置表单 */
const resetForm = async (): Promise<void> => {
//
formLoading.value = false
await nextTick()
uploadRef.value?.clearFiles()
}
/** 文件数超出提示 */
const handleExceed = (): void => {
message.error(t('DataCollection.Device.importFileLimit'))
}
/** 下载模板操作 */
const importTemplate = async () => {
const res = await DeviceApi.importDeviceAttributeTemplate()
download.excel(res, '设备点位导入模版.xls')
}
</script>

@ -51,6 +51,14 @@
>
<Icon icon="ep:plus" class="mr-5px" /> {{ t('DataCollection.Device.create') }}
</el-button>
<el-button
type="warning"
plain
@click="handleImport"
v-hasPermi="['iot:device:export']"
>
<Icon icon="ep:upload" /> {{ t('DataCollection.Device.import') }}
</el-button>
<el-button
type="success"
plain
@ -182,6 +190,9 @@ ref="tableRef" v-loading="loading" :data="list" :stripe="true" :show-overflow-to
</ContentWrap>
<DeviceAttributeForm ref="formRef" @success="getList" />
<!-- 单位导入对话框 -->
<DeviceAttributeImportForm ref="importFormRef" @success="getList" />
</template>
<script setup lang="ts">
import { DICT_TYPE } from '@/utils/dict'
@ -326,6 +337,16 @@ const handleBatchDelete = async () => {
await handleDelete(selectedIds.value)
}
/** 导入 */
const importFormRef = ref()
const handleImport = () => {
if (!props.deviceId) {
message.error(t('DataCollection.Device.messageSelectDeviceRequired'))
return
}
importFormRef.value.open(props.deviceId)
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

Loading…
Cancel
Save