perf(物联网产品,设备,物模型模块): 优化物联网管理整个模块代码及其它模块bug
This commit is contained in:
parent
47f226e019
commit
803ce3dfa6
@ -1,4 +1,5 @@
|
||||
import axios from 'axios';
|
||||
import dashboard from '@/router/routes/modules/dashboard';
|
||||
|
||||
export interface DeviceRecord {
|
||||
size: number;
|
||||
@ -17,7 +18,7 @@ export interface DeviceCreateRecord {
|
||||
name?: string;
|
||||
hardwareVersion: string;
|
||||
firmwareVersion: string;
|
||||
extendParams: string;
|
||||
extendParams: string[];
|
||||
properties: string;
|
||||
productId: number;
|
||||
}
|
||||
@ -46,6 +47,14 @@ export function queryDeviceList(data: DeviceRecord) {
|
||||
export function queryDeviceDetail(id: number) {
|
||||
return axios.get(`/api/rest/device/${id}`);
|
||||
}
|
||||
// 名称模糊查询
|
||||
export function queryDeviceByName(data: any) {
|
||||
return axios({
|
||||
url: `/api/rest/product/fuzzy`,
|
||||
method: 'get',
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 新增
|
||||
export function createDevice(data: DeviceCreateRecord) {
|
||||
@ -54,7 +63,7 @@ export function createDevice(data: DeviceCreateRecord) {
|
||||
|
||||
// 修改
|
||||
export function updateDevice(data:DeviceUpdateRecord) {
|
||||
return axios.put(`/api/rest/device/${data.id}`, data);
|
||||
return axios.patch(`/api/rest/device/${data.id}`, data);
|
||||
}
|
||||
// 删除
|
||||
export function deleteDevice(id: number) {
|
||||
|
@ -26,25 +26,25 @@ export interface MessageCreateRecord {
|
||||
|
||||
// 查看详情
|
||||
export function queryMessage(userId: number, messageId: number) {
|
||||
return axios.get(`/api/rest/message/${userId}/${messageId}`);
|
||||
return axios.get(`/api/rest/notice/${userId}/${messageId}`);
|
||||
}
|
||||
// 分页查询
|
||||
export function queryMessageList(data: MessageRecord) {
|
||||
return axios({
|
||||
url: '/api/rest/message',
|
||||
url: '/api/rest/notice',
|
||||
method: 'get',
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
// 创建消息
|
||||
export function createMessage(data: MessageCreateRecord) {
|
||||
return axios.post('/api/rest/message', data);
|
||||
return axios.post('/api/rest/notice', data);
|
||||
}
|
||||
// 获取消息推送方式
|
||||
export function getMessageTypes() {
|
||||
return axios.get('/api/rest/message/setting');
|
||||
return axios.get('/api/rest/notice/setting');
|
||||
}
|
||||
// 设置消息推送方式
|
||||
export function setMessageTypes(data: string[]) {
|
||||
return axios.patch('/api/rest/message/setting', data);
|
||||
return axios.patch('/api/rest/notice/setting', data);
|
||||
}
|
@ -49,7 +49,7 @@ export interface MessagesRecord {
|
||||
}
|
||||
|
||||
export interface MessageStatus {
|
||||
ids: string[];
|
||||
ids: number[];
|
||||
}
|
||||
|
||||
export type MessageListType = MessagesList[];
|
||||
|
@ -6,7 +6,7 @@
|
||||
<span> {{ item.title }}{{ formatUnreadLength(item.key) }} </span>
|
||||
</template>
|
||||
<a-result v-if="!renderList.length" status="404">
|
||||
<template #subtitle> {{ $t('messageBox.noContent') }} </template>
|
||||
<template #subtitle> 暂无内容 </template>
|
||||
</a-result>
|
||||
<List
|
||||
:render-list="renderList"
|
||||
|
@ -150,9 +150,9 @@
|
||||
</a-tooltip>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a-button status="normal">{{ userStore.permissions }}</a-button>
|
||||
</li>
|
||||
<!-- <li>-->
|
||||
<!-- <a-button status="normal">{{ userStore.permissions }}</a-button>-->
|
||||
<!-- </li>-->
|
||||
<li>
|
||||
<a-dropdown trigger="click">
|
||||
<a-avatar
|
||||
|
@ -12,6 +12,6 @@
|
||||
"globalSettings": false,
|
||||
"device": "desktop",
|
||||
"tabBar": false,
|
||||
"menuFromServer": true,
|
||||
"menuFromServer": false,
|
||||
"serverMenu": []
|
||||
}
|
||||
|
@ -5,11 +5,11 @@ import { intersection } from 'lodash';
|
||||
function checkPermission(el: HTMLElement, binding: DirectiveBinding) {
|
||||
const { value } = binding;
|
||||
const userStore = useUserStore();
|
||||
const { authorities } = userStore;
|
||||
const { permissions } = userStore;
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
if (value.length > 0) {
|
||||
const hasPermission = intersection(value, authorities).length > 0;
|
||||
const hasPermission = intersection(value, permissions).length > 0;
|
||||
|
||||
if (!hasPermission && el.parentNode) {
|
||||
el.parentNode.removeChild(el);
|
||||
|
@ -7,6 +7,7 @@ const DASHBOARD: AppRouteRecordRaw = {
|
||||
component: DEFAULT_LAYOUT,
|
||||
meta: {
|
||||
locale: 'menu.dashboard',
|
||||
title: '首页',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-dashboard', // 设置图标
|
||||
order: 0, // 排序路由菜单项。如果设置该值,值越高,越靠前
|
||||
@ -18,6 +19,7 @@ const DASHBOARD: AppRouteRecordRaw = {
|
||||
component: () => import('@/views/dashboard/workplace/index.vue'),
|
||||
meta: {
|
||||
locale:'menu.dashboard.workplace',
|
||||
title: '工作台',
|
||||
requiresAuth: true,
|
||||
permissions: ['*'],
|
||||
},
|
||||
|
@ -18,7 +18,7 @@ const IOT: AppRouteRecordRaw = {
|
||||
name: 'Product',
|
||||
component: () => import('@/views/iot/product/index.vue'),
|
||||
meta: {
|
||||
// locale: 'menu.system.dept',
|
||||
locale: 'menu.system.product',
|
||||
title: '产品管理',
|
||||
requiresAuth: true,
|
||||
permissions: ['*'],
|
||||
@ -29,7 +29,7 @@ const IOT: AppRouteRecordRaw = {
|
||||
name: 'Device',
|
||||
component: () => import('@/views/iot/device/index.vue'),
|
||||
meta: {
|
||||
// locale: 'menu.system.role',
|
||||
locale: 'menu.system.device',
|
||||
title: '设备管理',
|
||||
requiresAuth: true,
|
||||
permissions: ['*'],
|
||||
@ -40,6 +40,7 @@ const IOT: AppRouteRecordRaw = {
|
||||
name: 'productDetail',
|
||||
component: () => import('@/views/iot/product/components/product-detail.vue'),
|
||||
meta: {
|
||||
locale:'menu.system.product',
|
||||
title: '产品详情',
|
||||
requiresAuth: true,
|
||||
showInMenu: false,
|
||||
@ -51,6 +52,7 @@ const IOT: AppRouteRecordRaw = {
|
||||
name: 'deviceDetail',
|
||||
component: () => import('@/views/iot/device/components/device-detail.vue'),
|
||||
meta: {
|
||||
locale: 'menu.system.deviceDetail',
|
||||
title: '设备详情',
|
||||
requiresAuth: true,
|
||||
showInMenu: false,
|
||||
@ -62,6 +64,7 @@ const IOT: AppRouteRecordRaw = {
|
||||
name: 'productTsl',
|
||||
component: () => import('@/views/iot/product/components/product-tsl.vue'),
|
||||
meta: {
|
||||
locale: 'menu.system.productTsl',
|
||||
title: '物模型',
|
||||
requiresAuth: true,
|
||||
showInMenu: false,
|
||||
|
@ -7,6 +7,7 @@ const NOTIFICATION: AppRouteRecordRaw = {
|
||||
component: DEFAULT_LAYOUT,
|
||||
meta: {
|
||||
locale: '通知管理',
|
||||
title: '通知管理',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-message', // 设置图标
|
||||
order: 0, // 排序路由菜单项。如果设置该值,值越高,越靠前
|
||||
@ -18,6 +19,7 @@ const NOTIFICATION: AppRouteRecordRaw = {
|
||||
component: () => import('@/views/notification/notice/index.vue'),
|
||||
meta: {
|
||||
locale: '公告通知',
|
||||
title: '公告通知',
|
||||
requiresAuth: true,
|
||||
permissions: ['*'],
|
||||
},
|
||||
@ -28,6 +30,7 @@ const NOTIFICATION: AppRouteRecordRaw = {
|
||||
component: () => import('@/views/notification/noticeSet/index.vue'),
|
||||
meta: {
|
||||
locale: '公告管理',
|
||||
title: '公告管理',
|
||||
requiresAuth: true,
|
||||
permissions: ['*'],
|
||||
},
|
||||
|
@ -27,6 +27,7 @@ const SYSTEM: AppRouteRecordRaw = {
|
||||
name: 'Role',
|
||||
component: () => import('@/views/system/role/index.vue'),
|
||||
meta: {
|
||||
title: '角色管理',
|
||||
requiresAuth: true,
|
||||
permissions: ['*'],
|
||||
},
|
||||
@ -36,6 +37,7 @@ const SYSTEM: AppRouteRecordRaw = {
|
||||
name: 'Dept',
|
||||
component: () => import('@/views/system/dept/index.vue'),
|
||||
meta: {
|
||||
title: '部门管理',
|
||||
requiresAuth: true,
|
||||
permissions: ['*'],
|
||||
},
|
||||
@ -45,14 +47,17 @@ const SYSTEM: AppRouteRecordRaw = {
|
||||
name: 'User',
|
||||
component: () => import('@/views/system/user/index.vue'),
|
||||
meta: {
|
||||
title: '用户管理',
|
||||
requiresAuth: true,
|
||||
permissions: ['*'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'authority',
|
||||
name: 'Authority',
|
||||
component: () => import('@/views/system/authority/index.vue'),
|
||||
meta: {
|
||||
title: '权限管理',
|
||||
requiresAuth: true,
|
||||
permissions: ['*'],
|
||||
},
|
||||
|
@ -6,6 +6,11 @@ import useTabBarStore from './modules/tab-bar';
|
||||
import useRoleStore from './modules/role';
|
||||
import useDeptStore from './modules/dept';
|
||||
import useAuthStore from './modules/auth';
|
||||
import useMessagesStore from './modules/messages';
|
||||
import useBulletinsStore from './modules/bulletins';
|
||||
import useMessageStore from './modules/message-mgmt';
|
||||
import useBulletinStore from './modules/bulle-mgmt';
|
||||
|
||||
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate);
|
||||
@ -17,5 +22,9 @@ export {
|
||||
useDeptStore,
|
||||
useRoleStore,
|
||||
useAuthStore,
|
||||
useMessagesStore,
|
||||
useBulletinsStore,
|
||||
useMessageStore,
|
||||
useBulletinStore
|
||||
};
|
||||
export default pinia;
|
||||
|
@ -6,7 +6,7 @@ import {
|
||||
queryDeptList,
|
||||
enabled,
|
||||
remove,
|
||||
update,
|
||||
update, getAllDeptTree
|
||||
} from '@/api/dept';
|
||||
import { deptStore } from './type';
|
||||
|
||||
@ -25,6 +25,11 @@ const useDeptStore = defineStore('dept', {
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
// 获取所有部门树
|
||||
async getAllDeptTree(id: number | string) {
|
||||
return getAllDeptTree(id);
|
||||
},
|
||||
|
||||
// 获取所有的角色列表
|
||||
async getDeptList(data: DeptRecord) {
|
||||
return queryDeptList(data);
|
||||
|
@ -49,7 +49,6 @@ const useUserStore = defineStore('user', {
|
||||
setInfo(partial: Partial<UserState>) {
|
||||
this.$patch(partial);
|
||||
},
|
||||
|
||||
// Reset user's information
|
||||
resetInfo() {
|
||||
this.$reset();
|
||||
|
@ -1,68 +1,68 @@
|
||||
// // 新建 @/utils/excel.ts
|
||||
//
|
||||
// import saveAs from 'file-saver'; // https://www.npmjs.com/package/file-saver
|
||||
// import ExcelJS from 'exceljs'; // https://github.com/exceljs/exceljs/blob/master/README_zh.md
|
||||
// import * as XLSX from 'xlsx'; // https://www.npmjs.com/package/xlsx
|
||||
// import { Message } from '@arco-design/web-vue'; // https://arco.design/vue/component/message
|
||||
// import { FileItem } from '@arco-design/web-vue/es/upload/interfaces'; // arco类型
|
||||
//
|
||||
// export interface DownloadExcelPrams {
|
||||
// columns: { title: string; key: string }[];
|
||||
// rows: object[];
|
||||
// name: string;
|
||||
// }
|
||||
//
|
||||
// // 导出下载文件
|
||||
// export function downloadExcel({
|
||||
// columns,
|
||||
// rows,
|
||||
// name = '未命名文件',
|
||||
// }: DownloadExcelPrams) {
|
||||
// const workbook = new ExcelJS.Workbook();
|
||||
// workbook.creator = 'Start-front';
|
||||
// workbook.lastModifiedBy = 'Start-front';
|
||||
// workbook.created = new Date(1985, 8, 30);
|
||||
// workbook.modified = new Date();
|
||||
// workbook.lastPrinted = new Date(2016, 9, 27);
|
||||
//
|
||||
// // 将工作簿添加一个sheet页sheet1
|
||||
// const sheet1 = workbook.addWorksheet(name);
|
||||
// // 表头数据添加
|
||||
// sheet1.columns = columns.map((item) => ({
|
||||
// header: item.title,
|
||||
// key: item.key,
|
||||
// width: 20,
|
||||
// }));
|
||||
// // 表格内容添加
|
||||
// rows.map((item) => sheet1.addRow(item));
|
||||
// workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
// saveAs(
|
||||
// new Blob([buffer], { type: 'application/octet-stream' }),
|
||||
// `${name}.xlsx`
|
||||
// );
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// // 读取文件为json格式
|
||||
// export function readExcle(fileItem: FileItem) {
|
||||
// return new Promise((resove, reject) => {
|
||||
// try {
|
||||
// let workbook: XLSX.Sheet;
|
||||
// const reader = new FileReader();
|
||||
// reader.readAsBinaryString(fileItem.file as File); // 发起异步请求
|
||||
// reader.onload = function (ev) {
|
||||
// const data = ev.target?.result;
|
||||
// workbook = XLSX.read(data, { type: 'binary' });
|
||||
// const sheetNames = workbook.SheetNames; // 工作表名称集合
|
||||
// sheetNames.forEach((name: string) => {
|
||||
// const worksheet = workbook.Sheets[name]; // 只能通过工作表名称来获取指定工作表
|
||||
// const jsonres = XLSX.utils.sheet_to_json(worksheet);
|
||||
// resove(jsonres);
|
||||
// });
|
||||
// }; // onload
|
||||
// } catch (error) {
|
||||
// Message.error('读取失败,请选择正确文件');
|
||||
// reject(error);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// 新建 @/utils/excel.ts
|
||||
|
||||
import saveAs from 'file-saver'; // https://www.npmjs.com/package/file-saver
|
||||
import ExcelJS from 'exceljs'; // https://github.com/exceljs/exceljs/blob/master/README_zh.md
|
||||
import * as XLSX from 'xlsx'; // https://www.npmjs.com/package/xlsx
|
||||
import { Message } from '@arco-design/web-vue'; // https://arco.design/vue/component/message
|
||||
import { FileItem } from '@arco-design/web-vue/es/upload/interfaces'; // arco类型
|
||||
|
||||
export interface DownloadExcelPrams {
|
||||
columns: { title: string; key: string }[];
|
||||
rows: object[];
|
||||
name: string;
|
||||
}
|
||||
|
||||
// 导出下载文件
|
||||
export function downloadExcel({
|
||||
columns,
|
||||
rows,
|
||||
name = '未命名文件',
|
||||
}: DownloadExcelPrams) {
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
workbook.creator = 'Start-front';
|
||||
workbook.lastModifiedBy = 'Start-front';
|
||||
workbook.created = new Date(1985, 8, 30);
|
||||
workbook.modified = new Date();
|
||||
workbook.lastPrinted = new Date(2016, 9, 27);
|
||||
|
||||
// 将工作簿添加一个sheet页sheet1
|
||||
const sheet1 = workbook.addWorksheet(name);
|
||||
// 表头数据添加
|
||||
sheet1.columns = columns.map((item) => ({
|
||||
header: item.title,
|
||||
key: item.key,
|
||||
width: 20,
|
||||
}));
|
||||
// 表格内容添加
|
||||
rows.map((item) => sheet1.addRow(item));
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(
|
||||
new Blob([buffer], { type: 'application/octet-stream' }),
|
||||
`${name}.xlsx`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// 读取文件为json格式
|
||||
export function readExcle(fileItem: FileItem) {
|
||||
return new Promise((resove, reject) => {
|
||||
try {
|
||||
let workbook: XLSX.Sheet;
|
||||
const reader = new FileReader();
|
||||
reader.readAsBinaryString(fileItem.file as File); // 发起异步请求
|
||||
reader.onload = function (ev) {
|
||||
const data = ev.target?.result;
|
||||
workbook = XLSX.read(data, { type: 'binary' });
|
||||
const sheetNames = workbook.SheetNames; // 工作表名称集合
|
||||
sheetNames.forEach((name: string) => {
|
||||
const worksheet = workbook.Sheets[name]; // 只能通过工作表名称来获取指定工作表
|
||||
const jsonres = XLSX.utils.sheet_to_json(worksheet);
|
||||
resove(jsonres);
|
||||
});
|
||||
}; // onload
|
||||
} catch (error) {
|
||||
Message.error('读取失败,请选择正确文件');
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
<a-modal
|
||||
width="900px"
|
||||
height="500px"
|
||||
:visible="visible"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
@ -23,23 +24,26 @@
|
||||
<a-form
|
||||
ref="CreateRef"
|
||||
:model="formData"
|
||||
:style="{ width: '650px' }"
|
||||
:style="{ width: '800px', height: '420px' }"
|
||||
>
|
||||
<!-- 产品id -->
|
||||
<a-form-item
|
||||
field="productId"
|
||||
field="productName"
|
||||
label="产品名称"
|
||||
:rules="[{ required: true, message: '产品名称不能为空' }]"
|
||||
:validate-trigger="['change']"
|
||||
>
|
||||
<a-select
|
||||
v-model="formData.productId"
|
||||
v-model="formData.productName"
|
||||
placeholder="请选择产品名称"
|
||||
:loading="loading"
|
||||
:filter-option="false"
|
||||
allow-search
|
||||
@search="handleSearch"
|
||||
>
|
||||
<a-option v-for="item of options" :key="item.id" :value="item">{{item}}</a-option>
|
||||
<a-option v-for="item of options" :key="item.id" :value="item.name">{{
|
||||
item.name
|
||||
}}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<!-- 设备名称 -->
|
||||
@ -49,10 +53,7 @@
|
||||
:rules="[{ required: true, message: '设备名称不能为空' }]"
|
||||
:validate-trigger="['change']"
|
||||
>
|
||||
<a-input
|
||||
v-model="formData.name"
|
||||
placeholder='请输入设备名称'
|
||||
/>
|
||||
<a-input v-model="formData.name" placeholder="请输入设备名称" />
|
||||
</a-form-item>
|
||||
<!-- 硬件版本 -->
|
||||
<a-form-item
|
||||
@ -63,7 +64,7 @@
|
||||
>
|
||||
<a-input
|
||||
v-model="formData.hardwareVersion"
|
||||
placeholder='请输入硬件版本'
|
||||
placeholder="请输入硬件版本"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- 固件版本 -->
|
||||
@ -75,29 +76,57 @@
|
||||
>
|
||||
<a-input
|
||||
v-model="formData.firmwareVersion"
|
||||
placeholder='请输入固件版本'
|
||||
placeholder="请输入固件版本"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="remark"
|
||||
label="备注"
|
||||
>
|
||||
<a-textarea
|
||||
v-model="formData.remark"
|
||||
placeholder="请输入描述"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- 扩展属性 -->
|
||||
<a-form-item
|
||||
field="extendParams"
|
||||
label="扩展属性"
|
||||
>
|
||||
<a-form-item field="extendParams" label="扩展属性">
|
||||
<!-- <a-input-->
|
||||
<!-- v-model="formData.extendParams"-->
|
||||
<!-- placeholder='请输入扩展属性'-->
|
||||
<!-- />-->
|
||||
<div style="width: 100%">
|
||||
<div style="width: 100%;margin-bottom: 5px; ">
|
||||
<a-space v-for="(param,index) in paramsData" :key="index" style="margin-bottom: 5px">
|
||||
<div style="width: 100%; margin-bottom: 5px">
|
||||
<a-space
|
||||
v-for="(param, index) in paramsData"
|
||||
:key="index"
|
||||
style="margin-bottom: 5px"
|
||||
>
|
||||
<a-input v-model="param.name" placeholder="名称" allow-clear />
|
||||
<a-input v-model="param.identifier" placeholder="标识" allow-clear />
|
||||
<a-select v-model="param.dataType" :options="dataTypeOptions" allow-search />
|
||||
<a-select v-model="param.type" :options="typeOptions" allow-search />
|
||||
<a-button type="text" @click="handleDeleteParams(index)"><icon-minus-circle /></a-button>
|
||||
<a-input
|
||||
v-model="param.identifier"
|
||||
placeholder="标识"
|
||||
allow-clear
|
||||
/>
|
||||
<a-select
|
||||
v-model="param.dataType"
|
||||
:options="dataTypeOptions"
|
||||
allow-search
|
||||
placeholder="数据类型"
|
||||
style="width: 140px"
|
||||
/>
|
||||
<a-select
|
||||
v-model="param.type"
|
||||
:options="typeOptions"
|
||||
allow-search
|
||||
placeholder="类型"
|
||||
style="width: 140px"
|
||||
/>
|
||||
<a-button type="text" @click="handleDeleteParams(index)"
|
||||
><icon-minus-circle
|
||||
/></a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
<a-button @click="handleAddParams" style="width: 100%" >
|
||||
<a-button type="outline" @click="handleAddParams" style="width: 100%">
|
||||
<icon-plus />
|
||||
</a-button>
|
||||
</div>
|
||||
@ -106,21 +135,30 @@
|
||||
|
||||
<template #footer>
|
||||
<a-button class="editor-button" @click="handleCancel">取消</a-button>
|
||||
<a-button class="editor-button" type="primary" @click="handleSubmit">确定</a-button>
|
||||
<a-button class="editor-button" type="primary" @click="handleSubmit"
|
||||
>确定</a-button
|
||||
>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useVisible from '@/hooks/visible';
|
||||
import { computed, defineEmits, PropType, ref, shallowRef, onBeforeUnmount, reactive } from 'vue';
|
||||
import {
|
||||
computed,
|
||||
defineEmits,
|
||||
PropType,
|
||||
ref,
|
||||
shallowRef,
|
||||
onBeforeUnmount,
|
||||
} from 'vue';
|
||||
import { CreateRecord } from '@/api/user';
|
||||
import { FormInstance } from '@arco-design/web-vue/es/form';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { useMessageStore } from '@/store';
|
||||
import '@wangeditor/editor/dist/css/style.css'
|
||||
import { createDevice, updateDevice } from '@/api/device';
|
||||
import '@wangeditor/editor/dist/css/style.css';
|
||||
import { createDevice, queryDeviceByName, queryDeviceDetail, updateDevice } from '@/api/device';
|
||||
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
||||
import { queryProductDetail } from '@/api/product';
|
||||
|
||||
const props = defineProps({
|
||||
prem: {
|
||||
@ -168,11 +206,11 @@
|
||||
]);
|
||||
const typeOptions = computed<SelectOptionData[]>(() => [
|
||||
{
|
||||
label: '物模型输入',
|
||||
label: '输入',
|
||||
value: 'INPUT',
|
||||
},
|
||||
{
|
||||
label: '物模型输出',
|
||||
label: '输出',
|
||||
value: 'OUTPUT',
|
||||
},
|
||||
{
|
||||
@ -191,22 +229,34 @@
|
||||
const formData = ref<any>({
|
||||
...props.prem,
|
||||
});
|
||||
const editorRef = shallowRef()
|
||||
const options = ref(['Option1', 'Option2', 'Option3']);
|
||||
const editorRef = shallowRef();
|
||||
const options = ref();
|
||||
const loading = ref(false);
|
||||
|
||||
// 搜索
|
||||
const handleSearch = (value: any) => {
|
||||
if (value) {
|
||||
loading.value = true;
|
||||
window.setTimeout(() => {
|
||||
options.value = [`${value}-Option1`, `${value}-Option2`, `${value}-Option3`]
|
||||
options.value = [];
|
||||
window.setTimeout(async () => {
|
||||
const res = await queryDeviceByName({
|
||||
name: value,
|
||||
page:1,
|
||||
size: 10,
|
||||
});
|
||||
options.value = res.data.records.map((item: any) => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
};
|
||||
});
|
||||
loading.value = false;
|
||||
}, 2000)
|
||||
}, 2000);
|
||||
} else {
|
||||
options.value = []
|
||||
options.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
// 点击添加参数
|
||||
const handleAddParams = () => {
|
||||
// paramsVisible.value = true;
|
||||
@ -218,7 +268,7 @@
|
||||
});
|
||||
};
|
||||
// 删除参数
|
||||
const handleDeleteParams = (record: any) => {
|
||||
const handleDeleteParams = (record: number) => {
|
||||
if (record !== -1) {
|
||||
paramsData.value.splice(record, 1);
|
||||
}
|
||||
@ -226,14 +276,27 @@
|
||||
// 组件被点击
|
||||
const handleClick = () => {
|
||||
setVisible(true);
|
||||
if(!props.isCreate) {
|
||||
const ID = formData.value.productId;
|
||||
queryProductDetail(ID).then((res) => {
|
||||
formData.value.productName = res.data.name;
|
||||
});
|
||||
queryDeviceDetail(formData.value.id).then((res) => {
|
||||
paramsData.value = res.data.extendParams;
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
// 提交
|
||||
const handleSubmit = async () => {
|
||||
const valid = await CreateRef.value?.validate();
|
||||
// formData.value.productId = formData.value.productId.id;
|
||||
if (!valid) {
|
||||
// 新增
|
||||
formData.value.extendParams = paramsData.value;
|
||||
const productId = await queryDeviceByName(formData.value.productName);
|
||||
formData.value.productId = productId.data.records[0].id;
|
||||
|
||||
if (props.isCreate) {
|
||||
// formData.value.username = formData.value.email;
|
||||
const res = await createDevice(formData.value);
|
||||
@ -263,21 +326,20 @@
|
||||
|
||||
// 组件销毁时,也及时销毁编辑器
|
||||
onBeforeUnmount(() => {
|
||||
const editor = editorRef.value
|
||||
if (editor == null) return
|
||||
editor.destroy()
|
||||
})
|
||||
const editor = editorRef.value;
|
||||
if (editor == null) return;
|
||||
editor.destroy();
|
||||
});
|
||||
|
||||
// 关闭
|
||||
const handleCancel = async () => {
|
||||
checkKeys.value = [];
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.editor-button {
|
||||
position: static
|
||||
position: static;
|
||||
}
|
||||
</style>
|
||||
|
@ -215,7 +215,6 @@
|
||||
import usePagination from '@/hooks/pagination';
|
||||
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
||||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
||||
import { useBulletinStore } from '@/store';
|
||||
import useTableOption from '@/hooks/table-option';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
@ -248,7 +247,6 @@
|
||||
deepClone,
|
||||
} = useTableOption();
|
||||
|
||||
const bulletinStore = useBulletinStore();
|
||||
|
||||
const columns = computed<TableColumnData[]>(() => [
|
||||
{
|
||||
|
@ -81,7 +81,7 @@
|
||||
field="remark"
|
||||
label="备注"
|
||||
>
|
||||
<a-input
|
||||
<a-textarea
|
||||
v-model="formData.remark"
|
||||
placeholder='请输入备注'
|
||||
/>
|
||||
@ -143,8 +143,8 @@
|
||||
<a-space v-for="(param,index) in paramsData" :key="index" style="margin-bottom: 5px">
|
||||
<a-input v-model="param.name" placeholder="名称" allow-clear />
|
||||
<a-input v-model="param.identifier" placeholder="标识" allow-clear />
|
||||
<a-select v-model="param.dataType" :options="dataTypeOptions" allow-search />
|
||||
<a-select v-model="param.type" :options="typeOptions" allow-search />
|
||||
<a-select v-model="param.dataType" :options="dataTypeOptions" allow-search placeholder="数据类型" style="width: 140px"/>
|
||||
<a-select v-model="param.type" :options="typeOptions" allow-search placeholder="类型" style="width: 140px"/>
|
||||
<a-button type="text" @click="handleDeleteParams(index)"><icon-minus-circle /></a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -348,11 +348,11 @@
|
||||
]);
|
||||
const typeOptions = computed<SelectOptionData[]>(() => [
|
||||
{
|
||||
label: '物模型输入',
|
||||
label: '输入',
|
||||
value: 'INPUT',
|
||||
},
|
||||
{
|
||||
label: '物模型输出',
|
||||
label: '输出',
|
||||
value: 'OUTPUT',
|
||||
},
|
||||
{
|
||||
@ -365,6 +365,7 @@
|
||||
const fetchData = async (Id: number | undefined) => {
|
||||
const res = await queryProductDetail(Id);
|
||||
formData.value = res.data;
|
||||
paramsData.value = res.data.params;
|
||||
};
|
||||
// 组件被点击
|
||||
const handleClick = () => {
|
||||
|
@ -80,7 +80,7 @@
|
||||
<a-form
|
||||
ref="propertyCreateRef"
|
||||
:model="propertyAddData"
|
||||
:style="{ width: '650px' }"
|
||||
:style="{ width: '800px', height: '420px' }"
|
||||
>
|
||||
<!-- 设备名称 -->
|
||||
<a-form-item
|
||||
@ -152,7 +152,7 @@
|
||||
<a-form
|
||||
ref="serveCreateRef"
|
||||
:model="serveAddData"
|
||||
:style="{ width: '650px' }"
|
||||
:style="{ width: '800px', height: '420px' }"
|
||||
>
|
||||
<!-- 服务名称 -->
|
||||
<a-form-item
|
||||
@ -188,8 +188,8 @@
|
||||
<a-space v-for="(param,index) in serveInputData" :key="index" style="margin-bottom: 5px">
|
||||
<a-input v-model="param.name" placeholder="名称" allow-clear />
|
||||
<a-input v-model="param.identifier" placeholder="标识" allow-clear />
|
||||
<a-select v-model="param.dataType" :options="dataTypeOptions" allow-search placeholder="数据类型" />
|
||||
<a-select v-model="param.type" :options="typeOptions" allow-search placeholder="类型"/>
|
||||
<a-select v-model="param.dataType" :options="dataTypeOptions" allow-search placeholder="数据类型" style="width: 140px"/>
|
||||
<a-select v-model="param.type" :options="typeOptions" allow-search placeholder="类型" style="width: 140px"/>
|
||||
<a-button type="text" @click="handleDeleteParams(index,'serveInputData')"><icon-minus-circle /></a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -208,8 +208,8 @@
|
||||
<a-space v-for="(param,index) in serveOutputData" :key="index" style="margin-bottom: 5px">
|
||||
<a-input v-model="param.name" placeholder="名称" allow-clear />
|
||||
<a-input v-model="param.identifier" placeholder="标识" allow-clear />
|
||||
<a-select v-model="param.dataType" :options="dataTypeOptions" allow-search placeholder="数据类型"/>
|
||||
<a-select v-model="param.type" :options="typeOptions" allow-search placeholder="类型"/>
|
||||
<a-select v-model="param.dataType" :options="dataTypeOptions" allow-search placeholder="数据类型" style="width: 140px"/>
|
||||
<a-select v-model="param.type" :options="typeOptions" allow-search placeholder="类型" style="width: 140px"/>
|
||||
<a-button type="text" @click="handleDeleteParams(index,'serveOutputData')"><icon-minus-circle /></a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -245,7 +245,7 @@
|
||||
<a-form
|
||||
ref="eventCreateRef"
|
||||
:model="eventAddData"
|
||||
:style="{ width: '650px' }"
|
||||
:style="{ width: '800px', height: '420px' }"
|
||||
>
|
||||
<!-- 事件名称 -->
|
||||
<a-form-item
|
||||
@ -278,10 +278,7 @@
|
||||
:rules="[{ required: true, message: '类型不能为空' }]"
|
||||
:validate-trigger="['change']"
|
||||
>
|
||||
<a-input
|
||||
v-model="eventAddData.type"
|
||||
placeholder='请输入类型'
|
||||
/>
|
||||
<a-select v-model="eventAddData.type" :options="eventTypeOptions" allow-search placeholder="请选择类型"/>
|
||||
</a-form-item>
|
||||
<!-- 输出参数 -->
|
||||
<a-form-item
|
||||
@ -293,8 +290,8 @@
|
||||
<a-space v-for="(param,index) in eventOutputData" :key="index" style="margin-bottom: 5px">
|
||||
<a-input v-model="param.name" placeholder="名称" allow-clear />
|
||||
<a-input v-model="param.identifier" placeholder="标识" allow-clear />
|
||||
<a-select v-model="param.dataType" :options="dataTypeOptions" allow-search placeholder="数据类型"/>
|
||||
<a-select v-model="param.type" :options="typeOptions" allow-search placeholder="类型"/>
|
||||
<a-select v-model="param.dataType" :options="dataTypeOptions" allow-search placeholder="数据类型" style="width: 140px"/>
|
||||
<a-select v-model="param.type" :options="typeOptions" allow-search placeholder="类型" style="width: 140px"/>
|
||||
<a-button type="text" @click="handleDeleteParams(index,'eventOutputData')"><icon-minus-circle /></a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
@ -404,11 +401,11 @@
|
||||
]);
|
||||
const typeOptions = computed<SelectOptionData[]>(() => [
|
||||
{
|
||||
label: '物模型输入',
|
||||
label: '输入',
|
||||
value: 'INPUT',
|
||||
},
|
||||
{
|
||||
label: '物模型输出',
|
||||
label: '输出',
|
||||
value: 'OUTPUT',
|
||||
},
|
||||
{
|
||||
@ -416,6 +413,16 @@
|
||||
value: 'RW',
|
||||
},
|
||||
]);
|
||||
const eventTypeOptions = computed<SelectOptionData[]>(() => [
|
||||
{
|
||||
label: '主动',
|
||||
value: 'ACTIVE',
|
||||
},
|
||||
{
|
||||
label: '被动',
|
||||
value: 'PASSIVE',
|
||||
},
|
||||
]);
|
||||
const propertyAddData = ref({
|
||||
productId:id,
|
||||
});
|
||||
|
@ -113,6 +113,7 @@
|
||||
<a-table
|
||||
row-key="id"
|
||||
:default-expand-all-rows="true"
|
||||
:default-expanded-keys="[1]"
|
||||
:loading="loading"
|
||||
:columns="(cloneColumns as TableColumnData[])"
|
||||
:data="renderData"
|
||||
@ -183,7 +184,7 @@ import { Pagination } from '@/types/global';
|
||||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
||||
import dayjs from 'dayjs';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { DeptRecord } from '@/api/dept';
|
||||
import { DeptRecord, getAllDeptTree } from '@/api/dept';
|
||||
import { useDeptStore } from '@/store';
|
||||
import DeptEdit from './components/dept-edit.vue';
|
||||
|
||||
@ -266,12 +267,12 @@ const columns = computed<TableColumnData[]>(() => [
|
||||
const fetchData = async (params?: Partial<DeptRecord>) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await deptStore.getDeptList(params);
|
||||
const res = await deptStore.getAllDeptTree(1);
|
||||
|
||||
renderData.value = res.data.records;
|
||||
pagination.page = res.data.page;
|
||||
pagination.current = res.data.current;
|
||||
pagination.total = res.data.total;
|
||||
renderData.value = res.data;
|
||||
// pagination.page = res.data.page;
|
||||
// pagination.current = res.data.current;
|
||||
// pagination.total = res.data.total;
|
||||
} catch (err) {
|
||||
// you can report use errorHandler or other
|
||||
} finally {
|
||||
|
@ -30,7 +30,7 @@
|
||||
{ message: '请输入用戶' },
|
||||
]"
|
||||
>
|
||||
<a-input
|
||||
<a-input-tag
|
||||
v-model="formData.userIds"
|
||||
placeholder='请选择用戶'
|
||||
:value=formData.userIds
|
||||
@ -142,13 +142,13 @@
|
||||
</a-tree>
|
||||
</a-card>
|
||||
<a-card style="flex: 1">
|
||||
<a-button type="primary" >全选</a-button>
|
||||
<a-button type="primary" style="margin-bottom: 10px" @click="handleCheckAllUsers">全选</a-button>
|
||||
<a-table
|
||||
:data="selectedDepartmentMembers"
|
||||
:columns="columns"
|
||||
style="height: 520px">
|
||||
<template #id="{ record }">
|
||||
<a-checkbox v-model="selectedIds" :value="record.id"> </a-checkbox>
|
||||
<a-checkbox v-model="selectedIds" :value="record.userId"> </a-checkbox>
|
||||
</template>
|
||||
<template #username="{ record }">
|
||||
{{ record.username }}
|
||||
@ -176,6 +176,7 @@
|
||||
import { IEditorConfig } from '@wangeditor/editor'
|
||||
import '@wangeditor/editor/dist/css/style.css'
|
||||
import { getAllDeptTree } from '@/api/dept';
|
||||
import configArcoStyleImportPlugin from '../../../../../config/plugin/arcoStyleImport';
|
||||
|
||||
const props = defineProps({
|
||||
prem: {
|
||||
@ -202,7 +203,7 @@
|
||||
const messageStore = useMessageStore();
|
||||
const isFullScreen = ref(false);
|
||||
const mode = 'default';
|
||||
const selectedIds= ref<string[]>([]);
|
||||
const selectedIds= ref<number[]>([]);
|
||||
const toolbarConfig = { excludeKeys: ['uploadVideo', 'insertImage','insertVideo']}
|
||||
const columns = computed<any[]>(()=>[
|
||||
{
|
||||
@ -302,7 +303,7 @@
|
||||
}
|
||||
|
||||
// 广度优先遍历树,获取选中的成员
|
||||
const getSelectedMembers = (treeData: any[], selectedKeys: string[]) => {
|
||||
const getSelectedMembers = (treeData: any[], selectedKeys: number[]) => {
|
||||
const queue:any = [...treeData];
|
||||
const selectedMembers: any[] = [];
|
||||
while (queue.length > 0) {
|
||||
@ -322,9 +323,9 @@
|
||||
|
||||
|
||||
// 部门树被点击
|
||||
const handleClickTree = (id: string[]) => {
|
||||
const handleClickTree = (id: number[]) => {
|
||||
// 假设 '1' 是总部门的键
|
||||
if (id[0] === '1' || id.length === 0) {
|
||||
if (id[0] === 1 && id.length === 1) {
|
||||
// 广度优先遍历树,获取所有成员
|
||||
const allMembers: any[] = [];
|
||||
const queue:any = [...deptTreeData.value];
|
||||
@ -346,13 +347,13 @@
|
||||
selectedDepartmentMembers.value = Members;
|
||||
}
|
||||
// 部门树被选中
|
||||
const handleCheckTree = (id: string[]) => {
|
||||
if (id[0] === '1' ) { // 假设 '1' 是总部门的键
|
||||
const allKeys: string[] = [];
|
||||
const handleCheckTree = (id: number[]) => {
|
||||
if (id[0] === 1 ) { // 假设 '1' 是总部门的键
|
||||
const allKeys: number[] = [];
|
||||
const traverseTree = (node: any) => {
|
||||
if (node.members) {
|
||||
node.members.forEach((member: any) => {
|
||||
allKeys.push(member.id);
|
||||
allKeys.push(member.userId);
|
||||
});
|
||||
}
|
||||
if (node.children) {
|
||||
@ -368,7 +369,7 @@
|
||||
|
||||
} else {
|
||||
const selectedKeys = getSelectedMembers(deptTreeData.value, id);
|
||||
selectedIds.value = selectedKeys.map(item => item.id);
|
||||
selectedIds.value = selectedKeys.map(item => item.userId);
|
||||
}
|
||||
};
|
||||
|
||||
@ -428,6 +429,17 @@
|
||||
formData.value.userIds = selectedIds.value;
|
||||
};
|
||||
|
||||
// 选择所有用户
|
||||
const handleCheckAllUsers = () => {
|
||||
if(selectedIds.value.length ===0 ) {
|
||||
handleCheckTree([1]);
|
||||
} else {
|
||||
selectedIds.value = [];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// 部门树模态框
|
||||
const deptTreeCancel = () => {
|
||||
deptVisible.value = false;
|
||||
|
Loading…
Reference in New Issue
Block a user