物模型上传下载实现

This commit is contained in:
高云鹏 2024-07-04 16:44:12 +08:00
parent fc0ff8b46e
commit e4d3d79558
7 changed files with 197 additions and 148 deletions

View File

@ -9,10 +9,15 @@ import {
AddModelAttributeType,
UpdateModelAttributeType,
DelModelAttributeType,
GetModelServiceType,
AddModelServiceType,
UpdateModelServiceType,
RequestReturnRowType,
} from '/@/views/backend/DeviceModel/type'
import { useAdminInfo } from '/@/stores/adminInfo'
import { encrypt_aes } from '/@/utils/crypto'
const adminInfo = useAdminInfo()
export const getModelListReq = (data: GetModelType) => {
return createAxios<never, RequestReturnType<AddModelType[] & UpdateModelType[]>>({
url: '/api/equipment/model/list',
@ -46,7 +51,7 @@ export const delModelReq = (data: DelModelType) => {
}
export const getModelAttributeListReq = (data: GetModelAttributeType) => {
return createAxios<never,RequestReturnType<(AddModelAttributeType&UpdateModelAttributeType)[]>>({
return createAxios<never, RequestReturnRowType<(AddModelAttributeType & UpdateModelAttributeType)[]>>({
url: '/api/equipment/model/attribute/list',
method: 'post',
data: data,
@ -54,7 +59,7 @@ export const getModelAttributeListReq = (data: GetModelAttributeType) => {
}
export const addModelAttributeReq = (data: AddModelAttributeType) => {
return createAxios<never,RequestReturnType<(AddModelAttributeType&UpdateModelAttributeType)[]>>({
return createAxios<never, RequestReturnType<(AddModelAttributeType & UpdateModelAttributeType)[]>>({
url: '/api/equipment/model/attribute/add',
method: 'post',
data: data,
@ -62,7 +67,7 @@ export const addModelAttributeReq = (data: AddModelAttributeType) => {
}
export const updateModelAttributeReq = (data: UpdateModelAttributeType) => {
return createAxios<never,RequestReturnType>({
return createAxios<never, RequestReturnType>({
url: '/api/equipment/model/attribute/update',
method: 'post',
data: data,
@ -70,15 +75,15 @@ export const updateModelAttributeReq = (data: UpdateModelAttributeType) => {
}
export const delModelAttributeReq = (data: DelModelAttributeType) => {
return createAxios<never,RequestReturnType>({
return createAxios<never, RequestReturnType>({
url: '/api/equipment/model/attribute/delete',
method: 'post',
data: data,
})
}
export const getModelServiceListReq = (data: GetModelAttributeType) => {
return createAxios<never,RequestReturnType<(AddModelServiceType&UpdateModelServiceType)[]>>({
export const getModelServiceListReq = (data: GetModelServiceType) => {
return createAxios<never, RequestReturnRowType<(AddModelServiceType & UpdateModelServiceType)[]>>({
url: '/api/equipment/model/service/list',
method: 'post',
data: data,
@ -86,7 +91,7 @@ export const getModelServiceListReq = (data: GetModelAttributeType) => {
}
export const addModelServiceReq = (data: AddModelServiceType) => {
return createAxios<never,RequestReturnType<(AddModelServiceType&UpdateModelServiceType)[]>>({
return createAxios<never, RequestReturnType<(AddModelServiceType & UpdateModelServiceType)[]>>({
url: '/api/equipment/model/service/add',
method: 'post',
data: data,
@ -94,7 +99,7 @@ export const addModelServiceReq = (data: AddModelServiceType) => {
}
export const updateModelServiceReq = (data: UpdateModelServiceType) => {
return createAxios<never,RequestReturnType>({
return createAxios<never, RequestReturnType>({
url: '/api/equipment/model/service/update',
method: 'post',
data: data,
@ -102,27 +107,35 @@ export const updateModelServiceReq = (data: UpdateModelServiceType) => {
}
export const delModelServiceReq = (data: DelModelAttributeType) => {
return createAxios<never,RequestReturnType>({
return createAxios<never, RequestReturnType>({
url: '/api/equipment/model/service/delete',
method: 'post',
data: data,
})
}
// export const uploadModel = ()=>{
// return createAxios<never,RequestReturnType>({
// url: ,
// method: 'post',
// data: data,
// })
// }
export const downloadModelReq = (data:{id:string})=>{
return createAxios<never,RequestReturnType>({
url:'/api/equipment/model/export' ,
method: 'post',
data: data,
responseType:'blob'
})
export const uploadModelReq = (data: FormData, v: string) => {
const token = encrypt_aes(adminInfo.token, v)
return createAxios<never, RequestReturnType>(
{
url: '/api/equipment/model/import',
method: 'post',
data: data,
headers: {
'Content-Type': 'multipart/form-data',
v,
token,
},
},
{ customEncrypt: true }
)
}
export const downloadModelReq = (data: { id: string }) => {
return createAxios<never, RequestReturnType>({
url: '/api/equipment/model/export',
method: 'post',
data: data,
responseType: 'blob',
})
}

View File

@ -70,6 +70,7 @@ function createAxios<Data = any, T = ApiPromise<Data>>(axiosConfig: AxiosRequest
showCodeMessage: true, // 是否开启code不为1时的信息提示, 默认为true
showSuccessMessage: false, // 是否开启code为1时的信息提示, 默认为false
anotherToken: '', // 当前请求使用另外的用户token
customEncrypt: false, // 是否开启自定义加密
},
options
)
@ -87,24 +88,24 @@ function createAxios<Data = any, T = ApiPromise<Data>>(axiosConfig: AxiosRequest
loadingInstance.target = ElLoading.service(loading)
}
}
if (!options.customEncrypt) {
if (config.method === 'post' && config.data) {
// 对data进行加密
console.log(config.data)
config.data = encrypt_aes(config.data, v)
} else if (config.method === 'get' && config.params) {
// 对params进行加密
console.log(config.params)
config.params = encrypt_aes(config.params, v)
}
if (config.method === 'post' && config.data) {
// 对data进行加密
console.log(config.data)
config.data = encrypt_aes(config.data, v)
} else if (config.method === 'get' && config.params) {
// 对params进行加密
console.log(config.params)
config.params = encrypt_aes(config.params, v)
// 自动携带token
if (config.headers) {
config.headers.v = v
const token = adminInfo.getToken()
if (token) (config.headers as anyObj).token = encrypt_aes(token, v)
}
}
// 自动携带token
if (config.headers) {
config.headers.v = v
const token = adminInfo.getToken()
if (token) (config.headers as anyObj).token = encrypt_aes(token, v)
}
return config
},
(error) => {
@ -347,6 +348,8 @@ interface Options {
showSuccessMessage?: boolean
// 当前请求使用另外的用户token
anotherToken?: string
// 是否开启自定义加密
customEncrypt?: boolean
}
/*

View File

@ -12,10 +12,8 @@
<el-input :disabled="modelDialogState === ModelDialogTitleStateType['detail']" v-model="modelForm.objectType"></el-input>
</el-form-item>
</el-form>
<template #footer>
<el-button :disabled="modelDialogState === ModelDialogTitleStateType['detail']" type="primary" @click="submitModelForm"
>提交</el-button
>
<template #footer v-if="modelDialogState !== ModelDialogTitleStateType['detail']">
<el-button type="primary" @click="submitModelForm">提交</el-button>
<el-button @click="cancelModelForm">取消</el-button>
</template>
</el-dialog>
@ -31,7 +29,8 @@
></el-input>
</el-header>
<el-main class="asideMain">
<el-tree
<el-tree-v2
ref="modelTreeRef"
:data="treeData"
:props="DeviceModelPropReplace"
class="modelTree"
@ -39,22 +38,26 @@
@node-click="modelNodeClick"
highlight-current
>
</el-tree>
</el-tree-v2>
</el-main>
</el-aside>
<el-container class="mainContainer">
<el-header class="mainHeader">
<div class="mainHeaderCenter">
<el-input class="modelAttributeSearchInput"></el-input>
<el-input clearable class="modelAttributeSearchInput" v-model="modelAttributeAndServiceInputValue"></el-input>
<el-radio-group v-model="modelAttributeSearchRadio">
<el-radio value="attributeName">名称</el-radio>
<el-radio value="attributeCode">编码</el-radio>
<el-radio value="Name">名称</el-radio>
<el-radio value="Code">编码</el-radio>
</el-radio-group>
<el-button :icon="Search" @input="searchModelAttribute">查询</el-button>
<el-button :icon="Search" type="primary" @click="searchModelAttribute">查询</el-button>
</div>
<div class="mainHeaderRight">
<el-button :icon="Plus" @click="addModelAttributeAndService">新增</el-button>
<el-button :icon="Upload" @click="upLoadModel">导入</el-button>
<el-button :icon="Plus" type="primary" @click="addModelAttributeAndService">新增</el-button>
<el-upload :show-file-list="false" :limit="1" :http-request="upLoadModel">
<template #trigger>
<el-button :icon="Upload">导入</el-button>
</template>
</el-upload>
<el-button :icon="Download" @click="downLoadModel">导出</el-button>
</div>
</el-header>
@ -128,12 +131,13 @@
background
:pager-count="7"
layout="prev, pager, next, jumper,sizes,total"
@change="getcurrentPage"
></el-pagination>
</div>
</el-main>
</el-container>
</el-container>
<ContextMenu :pos="contextMenuPos" :visible="modelOperateVisible" @update:visible="closeModelOperate">
<ContextMenu :pos="contextMenuPos" v-model:visible="modelOperateVisible">
<template #default>
<div class="modelOperate">
<el-button @click="openModel('detail', curContextMenuTreeData)" :icon="Reading">查看</el-button>
@ -204,7 +208,7 @@ import {
ElAside,
ElHeader,
ElMain,
ElTree,
ElTreeV2,
ElInput,
ElMessage,
ElRadioGroup,
@ -213,7 +217,11 @@ import {
ElTabs,
ElTabPane,
ElTable,
ElUpload,
FormInstance,
UploadRequestOptions,
TreeNode,
TreeInstance
} from 'element-plus'
import { Reading, DocumentAdd, DocumentChecked, DocumentDelete, Search, Plus, Download, Upload } from '@element-plus/icons-vue'
import {
@ -236,6 +244,8 @@ import {
ModelServiceFieldsEnums,
AttributeDialogTitleStateType,
serviceDialogTitleStateType,
GetModelServiceType,
GetModelAttributeType,
} from './type'
import {
getModelListReq,
@ -251,13 +261,16 @@ import {
updateModelServiceReq,
delModelServiceReq,
downloadModelReq,
uploadModelReq,
} from '/@/api/backend/deviceModel/request'
import ContextMenu from './contextMenu.vue'
import { encrypt_aes, generateRandomNumber } from '/@/utils/crypto'
import { debounce } from 'lodash'
const DeviceModelPropReplace = {
label: 'iotModelName',
}
const modelTreeRef = ref<TreeInstance>()
const treeData = ref<(AddModelType & UpdateModelType)[]>([])
const originTreeData = ref<(AddModelType & UpdateModelType)[]>([])
@ -364,16 +377,13 @@ const contextMenuPos = ref({
y: 0,
})
const curContextMenuTreeData = ref<AddModelType & UpdateModelType>()
const modelContextMenu = (event: MouseEvent, data: AddModelType & UpdateModelType) => {
const modelContextMenu = (event: any, data: TreeNode) => {
contextMenuPos.value.x = event.pageX
contextMenuPos.value.y = event.pageY
curContextMenuTreeData.value = JSON.parse(JSON.stringify(data))
modelOperateVisible.value = true
}
const closeModelOperate = () => {
modelOperateVisible.value = false
}
const modelNodeClick = (target: AddModelType & UpdateModelType) => {
const modelNodeClick = (target: TreeNode) => {
curContextMenuTreeData.value = JSON.parse(JSON.stringify(target))
if (ModelTabs.value === 'attribute') {
getAttributeList()
@ -395,6 +405,7 @@ const delModel = () => {
if (res.success) {
ElMessage.success('删除物模型成功')
getModelList()
modelOperateVisible.value = false
} else {
ElMessage.error(res.msg)
}
@ -402,12 +413,27 @@ const delModel = () => {
.catch((err) => {
ElMessage.error(err?.response?.data?.msg ?? '删除失败')
})
closeModelOperate()
}
const modelAttributeAndServiceInputValue = ref('')
const searchModelAttribute = () => {
if (modelAttributeSearchRadio.value === 'Name') {
if (ModelTabs.value === 'attribute') {
console.log('test')
getAttributeList(modelAttributeSearchRadio.value, modelAttributeAndServiceInputValue.value)
} else if (ModelTabs.value === 'service') {
getServiceList(modelAttributeSearchRadio.value, modelAttributeAndServiceInputValue.value)
}
} else if (modelAttributeSearchRadio.value === 'Code') {
if (ModelTabs.value === 'attribute') {
getAttributeList(modelAttributeSearchRadio.value, modelAttributeAndServiceInputValue.value)
} else if (ModelTabs.value === 'service') {
getServiceList(modelAttributeSearchRadio.value, modelAttributeAndServiceInputValue.value)
}
}
}
const searchModelAttribute = () => {}
const modelAttributeSearchRadio = ref<radioGroupType>('attributeName')
const modelAttributeSearchRadio = ref<radioGroupType>('Name')
const ModelTabs = ref<modelTabsTypeKeyType>('attribute')
const changeTabs = (name: any) => {
@ -418,7 +444,7 @@ const changeTabs = (name: any) => {
}
}
const attributeTableData = ref<(AddModelAttributeType & UpdateModelAttributeType)[]>([])
const attributeTableData = ref<ModelAttributeTableType[]>([])
const editAttributeForm = (data: AddModelAttributeType & UpdateModelAttributeType) => {
attributeFormTitle.value = AttributeDialogTitleStateType['edit']
attributeForm.value = JSON.parse(JSON.stringify(data))
@ -439,11 +465,22 @@ const delAttributeForm = (data: AddModelAttributeType & UpdateModelAttributeType
})
}
const getAttributeList = () => {
getModelAttributeListReq({ iotModelId: curContextMenuTreeData.value!.id! })
const getAttributeList = (type?: radioGroupType, value?: string) => {
const requestData: GetModelAttributeType = {
iotModelId: curContextMenuTreeData.value!.id!,
pageNum: currentPage.value,
pageSize: currentPageSize.value,
}
if (type === 'Name') {
requestData.attributeName = value
} else if (type === 'Code') {
requestData.attributeCode = value
}
getModelAttributeListReq(requestData)
.then((res) => {
if (res.success) {
attributeTableData.value = res.data!.map((item) => {
if (res.rows && res.rows.length > 0) {
attributeTableData.value = res.rows!.map((item) => {
return {
...item,
attributeTypeName:
@ -453,10 +490,10 @@ const getAttributeList = () => {
? '累积量'
: item.attributeType === 140
? '离散量'
: item.attributeType,
: item.attributeType!,
}
})
pageTotal.value = res.total
} else {
ElMessage.error(res.msg)
}
@ -466,17 +503,27 @@ const getAttributeList = () => {
})
}
const getServiceList = () => {
getModelServiceListReq({ iotModelId: curContextMenuTreeData.value!.id! })
const getServiceList = (type?: radioGroupType, value?: string) => {
const requestData: GetModelServiceType = {
iotModelId: curContextMenuTreeData.value!.id!,
pageNum: currentPage.value,
pageSize: currentPageSize.value,
}
if (type === 'Name') {
requestData.serviceName = value
} else if (type === 'Code') {
requestData.serviceCode = value
}
getModelServiceListReq(requestData)
.then((res) => {
if (res.success) {
serviceTableData.value = res.data!.map((item) => {
if (res.rows && res.rows.length > 0) {
serviceTableData.value = res.rows!.map((item) => {
return {
...item,
serviceTypeName: item.serviceType === 146 ? '遥调' : item.serviceType === 147 ? '遥控' : item.serviceType,
serviceTypeName: item.serviceType === 146 ? '遥调' : item.serviceType === 147 ? '遥控' : item.serviceType!,
}
})
pageTotal.value = res.total
} else {
ElMessage.error(res.msg)
}
@ -486,7 +533,7 @@ const getServiceList = () => {
})
}
const serviceTableData = ref<(AddModelServiceType & UpdateModelServiceType)[]>([])
const serviceTableData = ref<ModelServiceTableType[]>([])
const editServiceForm = (data: AddModelServiceType & UpdateModelServiceType) => {
serviceFormTitle.value = serviceDialogTitleStateType['edit']
@ -635,7 +682,25 @@ const addModelAttributeAndService = () => {
}
}
const upLoadModel = () => {}
const upLoadModel = (file: UploadRequestOptions) => {
const formData = new FormData()
formData.append('file', file.file)
const v = generateRandomNumber(16)
const id = encrypt_aes(curContextMenuTreeData.value!.id!, v)
formData.append('id', id)
return uploadModelReq(formData, v)
.then((res) => {
if (res.success) {
ElMessage.success('上传物模型成功')
getModelList()
} else {
ElMessage.error(res.msg)
}
})
.catch((err) => {
ElMessage.error(err?.response?.data?.msg ?? '上传失败')
})
}
const downLoadModel = () => {
downloadModelReq({ id: curContextMenuTreeData.value!.id! }).then((res: any) => {
@ -654,9 +719,17 @@ const currentPage = ref(1)
const currentPageSize = ref(10)
const pageTotal = ref(0)
const pagePagination = ref([10, 20, 30])
const getcurrentPage = () => {
if (ModelTabs.value === 'attribute') {
getAttributeList()
} else if (ModelTabs.value === 'service') {
getServiceList()
}
}
getModelList().then((res) => {
curContextMenuTreeData.value = JSON.parse(JSON.stringify(res))
modelTreeRef.value?.setCurrentKey(curContextMenuTreeData.value!.id!)
if (ModelTabs.value === 'attribute') {
getAttributeList()
} else {
@ -716,12 +789,17 @@ $paginationHeight: 32px;
display: flex;
justify-content: space-between;
align-items: center;
width: 445px;
width: 480px;
}
.mainHeaderRight {
display: flex;
justify-content: space-between;
align-items: center;
width: 280px;
}
.el-button {
width: 88px;
height: 40px;
}
}
.mainMain {

View File

@ -1,60 +0,0 @@
<template>
<el-table :data="tableData" class="tablePart">
<el-table-column
v-for="item in tableColumn"
:key="item.key"
:prop="item.prop"
:label="item.label"
:fixed="item.fixed"
:align="item.align ?? 'center'"
></el-table-column>
<el-table-column fixed="right" label="操作" min-width="80" align="center">
<template #default="scope">
<div class="tableOperate">
<a @click="editForm(scope.row)">编辑</a>
<a>|</a>
<el-popconfirm title="确定删除么?" @confirm="delForm(scope.row)">
<template #reference>
<a>删除</a>
</template>
</el-popconfirm>
</div>
</template>
</el-table-column>
</el-table>
</template>
<script setup lang="ts">
import { ElTable, ElTableColumn } from 'element-plus'
import { defineProps, defineEmits } from 'vue'
const props = defineProps<{
tableData: any[]
tableColumn: any[]
}>()
const emits = defineEmits(['editForm', 'delForm'])
const editForm = (row: any) => {
emits('editForm', row)
}
const delForm = (row: any) => {
emits('delForm', row)
}
</script>
<style lang="scss" scoped>
.tableOperate {
display: flex;
justify-content: center;
align-items: center;
a {
margin: 5px;
color: #0064aa;
font-weight: 600;
&:hover {
cursor: pointer;
}
}
}
</style>

View File

@ -4,6 +4,12 @@ export type RequestReturnType<T = never> = Promise<{
success: boolean
data?: T
}>
export type RequestReturnRowType<T = never> = Promise<{
code: number
msg: string
rows: T
total: number
}>
export enum ModelFieldsEnums {
'id' = 'id',
@ -80,6 +86,10 @@ export enum ModelServiceFieldsEnums {
export type GetModelAttributeType = {
iotModelId: string
attributeCode?: string
attributeName?: string
pageSize: number
pageNum: number
}
export type AddModelAttributeType = {
@ -103,6 +113,14 @@ export type DelModelAttributeType = {
id: string
}
export type GetModelServiceType = {
iotModelId: string
serviceCode?: string
serviceName?: string
pageSize: number
pageNum: number
}
export type AddModelServiceType = {
iotModelId: string
serviceCode: string
@ -128,7 +146,7 @@ export enum ModelDialogTitleStateType {
export type ModelDialogTitleStateKeyType = keyof typeof ModelDialogTitleStateType
export type ModelDialogTitleStateValueType = `${ModelDialogTitleStateType}`
export type radioGroupType = keyof Pick<AddModelAttributeType, 'attributeCode' | 'attributeName'>
export type radioGroupType = 'Code' | 'Name'
export enum modelTabsType {
'attribute' = '属性',
@ -138,11 +156,11 @@ export type modelTabsTypeKeyType = keyof typeof modelTabsType
export type ModelAttributeTableType = AddModelAttributeType &
UpdateModelAttributeType & {
attributeTypeName: string
attributeTypeName: '模拟量' | '累积量' | '离散量' | ModelAttributeType
}
export type ModelServiceTableType = AddModelServiceType &
UpdateModelServiceType & {
serviceTypeName: string
serviceTypeName: '遥调' | '遥控' | ModelServiceType
}
export enum AttributeDialogTitleStateType {
@ -153,4 +171,3 @@ export enum serviceDialogTitleStateType {
'add' = '新增物模型方法',
'edit' = '编辑物模型方法',
}

View File

@ -208,7 +208,7 @@
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { Search, CirclePlusFilled } from '@element-plus/icons-vue'
import { userQuery, userUpdate, userDelete, userAdd, userList, allRoleQuery } from '/@/api/backend'
import { userQuery, userUpdate, userDelete, userAdd, userList, allRoleQuery } from '/@/api/backend/index'
import { ElTable, ElMessage, FormRules } from 'element-plus'
import type Node from 'element-plus/es/components/tree/src/model/node'
import Avatar from '/@/views/backend/auth/userInfo/avatar.vue'

View File

@ -20,7 +20,7 @@
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { ref } from 'vue'
import { ElScrollbar, ElIcon, ElPopover, ElRow, ElCol } from 'element-plus'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const emits = defineEmits(['selectAvatar'])
@ -29,9 +29,7 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
iconArr.push(component)
}
const computedHeight = Math.ceil(iconArr.length / 4) * 40
const computedIconArr = () => {
return iconArr.slice()
}
const popoverVisible = ref(false)
const selectAvatar = (name: string) => {
emits('selectAvatar', name)