diff --git a/src/api/link/certificate.ts b/src/api/link/certificate.ts
index 9ed5f5e1..3f6b0a31 100644
--- a/src/api/link/certificate.ts
+++ b/src/api/link/certificate.ts
@@ -5,3 +5,12 @@ export const NETWORK_CERTIFICATE_UPLOAD = `${BASE_API_PATH}/network/certificate/
export const save = (data: object) => server.post(`/network/certificate`, data);
+
+export const update = (data: object) => server.patch(`/network/certificate`, data);
+
+export const query = (data: object) => server.post(`/network/certificate/_query`, data);
+
+export const queryDetail = (id: string) => server.get(`/network/certificate/${id}`);
+
+export const remove = (id: string) => server.remove(`/network/certificate/${id}`);
+
diff --git a/src/api/system/menu.ts b/src/api/system/menu.ts
index 554b2502..a8e6a60e 100644
--- a/src/api/system/menu.ts
+++ b/src/api/system/menu.ts
@@ -10,4 +10,8 @@ export const queryOwnThree = (data: any) => server.post('/menu/user-own/tre
// 获取资产类型
export const getAssetsType_api = () => server.get(`/asset/types`);
// 获取菜单详情
-export const getMenuDetail_api = (id:string) => server.get(`/menu/${id}`);
+export const getMenuInfo_api = (id:string) => server.get(`/menu/${id}`);
+// 编辑菜单信息
+export const saveMenuInfo_api = (data: object) => server.patch(`/menu`, data);
+// 新增菜单信息
+export const addMenuInfo_api = (data: object) => server.post(`/menu`, data);
\ No newline at end of file
diff --git a/src/components/AIcon/index.tsx b/src/components/AIcon/index.tsx
index c580070d..1a21e6ff 100644
--- a/src/components/AIcon/index.tsx
+++ b/src/components/AIcon/index.tsx
@@ -44,6 +44,7 @@ const iconKeys = [
'QuestionCircleOutlined',
'InfoCircleOutlined',
'SearchOutlined',
+ 'EllipsisOutlined',
]
const Icon = (props: {type: string}) => {
diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx
index 7c43d1f7..1a37be86 100644
--- a/src/components/Table/index.tsx
+++ b/src/components/Table/index.tsx
@@ -37,6 +37,7 @@ export interface ActionsType {
tooltip?: TooltipProps;
popConfirm?: PopconfirmProps;
icon?: string;
+ children?: ActionsType[];
}
export interface JColumnProps extends ColumnProps{
diff --git a/src/router/menu.ts b/src/router/menu.ts
index fd304be9..234bcabf 100644
--- a/src/router/menu.ts
+++ b/src/router/menu.ts
@@ -87,7 +87,7 @@ export default [
component: () => import('@/views/link/Certificate/index.vue')
},
{
- path: '/link/certificate/detail/add',
+ path: '/link/certificate/detail/:type/:id',
component: () => import('@/views/link/Certificate/Detail/index.vue')
},
{
diff --git a/src/views/device/components/Metadata/Cat/index.vue b/src/views/device/components/Metadata/Cat/index.vue
index 5936eb0d..e0292159 100644
--- a/src/views/device/components/Metadata/Cat/index.vue
+++ b/src/views/device/components/Metadata/Cat/index.vue
@@ -16,9 +16,10 @@
-
+
+ {{ value }}
@@ -120,25 +121,29 @@ watch(
{ immediate: true }
)
-watchEffect(() => {
- if (props.visible) {
- loading.value = true
- const { id } = route.params
- if (props.type === 'device') {
- detail(id as string).then((resp) => {
- loading.value = false
- instanceStore.setCurrent(resp.result)
- value.value = resp.result.metadata
- });
- } else {
- productDetail(id as string).then((resp) => {
- loading.value = false
- // productStore.setCurrent(resp.result)
- value.value = resp.result.metadata
- });
+watch(
+ [props.visible, props.type],
+ () => {
+ if (props.visible) {
+ loading.value = true
+ const { id } = route.params
+ if (props.type === 'device') {
+ detail(id as string).then((resp) => {
+ loading.value = false
+ instanceStore.setCurrent(resp.result)
+ value.value = resp.result.metadata
+ });
+ } else {
+ productDetail(id as string).then((resp) => {
+ loading.value = false
+ // productStore.setCurrent(resp.result)
+ value.value = resp.result.metadata
+ });
+ }
}
- }
-})
+ },
+ { immediate: true }
+)
diff --git a/src/views/home/modules/config.ts b/src/views/home/modules/config.ts
deleted file mode 100644
index 377db512..00000000
--- a/src/views/home/modules/config.ts
+++ /dev/null
@@ -1,174 +0,0 @@
-// import {getImage} from '@/utils/comm'
-import { useMenuStore } from "@/store/menu";
-import { usePermissionStore } from "@/store/permission";
-import { recommendList, bootConfig } from "../index";
-
-
-// 按钮权限控制
-const hasPermission = usePermissionStore().hasPermission;
-const productPermission = (action: string) =>
- hasPermission(`device/Product:${action}`);
-const devicePermission = (action: string) =>
- hasPermission(`device/Instance:${action}`);
-const rulePermission = (action: string) =>
- hasPermission(`rule-engine/Instance:${action}`);
-// 页面权限控制
-const menuPermission = useMenuStore().hasPermission
-
-
-// 物联网引导-数据
-export const deviceBootConfig: bootConfig[] = [
- {
- english: 'STEP1',
- label: '创建产品',
- link: '/iot/device/Product',
- auth: productPermission('add'),
- params: {
- save: true,
- },
- },
- {
- english: 'STEP2',
- label: '创建设备',
- link: '/iot/device/Instance',
- auth: devicePermission('add'),
- params: {
- save: true,
- },
- },
- {
- english: 'STEP3',
- label: '规则引擎',
- link: '/iot/rule-engine/Instance',
- auth: rulePermission('add'),
- params: {
- save: true,
- },
- },
-];
-// 设备接入推荐步骤-数据
-export const deviceStepDetails: recommendList[] = [
- {
- title: '创建产品',
- details:
- '产品是设备的集合,通常指一组具有相同功能的设备。物联设备必须通过产品进行接入方式配置。',
- iconUrl: '/images/home/bottom-4.png',
- linkUrl: '/iot/device/Product',
- auth: productPermission('add'),
- params: {
- save: true,
- },
- },
- {
- title: '配置产品接入方式',
- details:
- '通过产品对同一类型的设备进行统一的接入方式配置。请参照设备铭牌说明选择匹配的接入方式。',
- iconUrl: '/images/home/bottom-1.png',
- linkUrl: '/iot/device/Product/detail',
- auth: productPermission('update'),
- dialogTag: 'accessMethod',
- },
- {
- title: '添加测试设备',
- details: '添加单个设备,用于验证产品模型是否配置正确。',
- iconUrl: '/images/home/bottom-5.png',
- linkUrl: '/iot/device/Instance',
- auth: devicePermission('add'),
- params: {
- save: true,
- },
- },
- {
- title: '功能调试',
- details:
- '对添加的测试设备进行功能调试,验证能否连接到平台,设备功能是否配置正确。',
- iconUrl: '/images/home/bottom-2.png',
- linkUrl: '/iot/device/Instance/detail',
- // auth: devicePermission('update'),
- auth: true,
- dialogTag: 'funcTest',
- },
- {
- title: '批量添加设备',
- details: '批量添加同一产品下的设备',
- iconUrl: '/images/home/bottom-3.png',
- linkUrl: '/iot/device/Instance',
- auth: devicePermission('import'),
- params: {
- import: true,
- },
- },
-];
-
-
-// 运维管理引导-数据
-export const opsBootConfig: bootConfig[] = [
- {
- english: 'STEP1',
- label: '设备接入配置',
- link: '/iot/link/accessConfig',
- auth: menuPermission('link/accessConfig'),
- },
- {
- english: 'STEP2',
- label: '日志排查',
- link: '/iot/link/Log',
- auth: menuPermission('link/Log'),
- params: {
- key: 'system',
- },
- },
- {
- english: 'STEP3',
- label: '实时监控',
- link: '/iot/link/dashboard',
- auth: menuPermission('link/dashboard'),
- params: {
- save: true,
- },
- },
-];
-// 运维管理推荐步骤-数据
-export const opsStepDetails: recommendList[] = [
- {
- title: '协议管理',
- details:
- '根据业务需求自定义开发对应的产品(设备模型)接入协议,并上传到平台。',
- iconUrl: '/images/home/bottom-1.png',
- linkUrl: '/iot/link/protocol',
- auth: menuPermission('link/Protocol'),
-
- },
- {
- title: '证书管理',
- details: '统一维护平台内的证书,用于数据通信加密。',
- iconUrl: '/images/home/bottom-6.png',
- linkUrl: '/iot/link/Certificate',
- auth: menuPermission('link/Certificate'),
-
- },
- {
- title: '网络组件',
- details: '根据不同的传输类型配置平台底层网络组件相关参数。',
- iconUrl: '/images/home/bottom-3.png',
- linkUrl: '/iot/link/type',
- auth: menuPermission('link/Type'),
- },
- {
- title: '设备接入网关',
- details: '根据不同的传输类型,关联消息协议,配置设备接入网关相关参数。',
- iconUrl: '/images/home/bottom-4.png',
- linkUrl: '/iot/link/accessConfig',
- auth: menuPermission('link/AccessConfig'),
- },
- {
- title: '日志管理',
- details: '监控系统日志,及时处理系统异常。',
- iconUrl: '/images/home/bottom-5.png',
- linkUrl: '/iot/link/Log',
- auth: menuPermission('Log'),
- params: {
- key: 'system',
- }
- },
-];
\ No newline at end of file
diff --git a/src/views/link/AccessConfig/index.vue b/src/views/link/AccessConfig/index.vue
index e1509f3b..b3a74786 100644
--- a/src/views/link/AccessConfig/index.vue
+++ b/src/views/link/AccessConfig/index.vue
@@ -1,8 +1,328 @@
- 新增
+
+
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ slotProps.channelInfo.name }}
+
+
+
+
+ {{
+ slotProps.channelInfo
+ .addresses[0].address
+ }}
+ {{
+ slotProps.channelInfo
+ .addresses[0].address
+ }}
+
+
+
+
+
+ 协议
+
+
+
+ {{
+ slotProps.protocolDetail
+ .name
+ }}
+ {{
+ slotProps.protocolDetail
+ .name
+ }}
+
+
+
+
+
+
+
+
+
+ {{
+ providersList.find(
+ (item) =>
+ item.id ===
+ slotProps.provider,
+ )?.description
+ }}
+ {{
+ providersList.find(
+ (item) =>
+ item.id ===
+ slotProps.provider,
+ )?.description
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/link/Certificate/Detail/index.vue b/src/views/link/Certificate/Detail/index.vue
index 410bd10c..e8857baf 100644
--- a/src/views/link/Certificate/Detail/index.vue
+++ b/src/views/link/Certificate/Detail/index.vue
@@ -60,6 +60,7 @@
({
type: 'common',
name: '',
configs: {
@@ -137,9 +142,10 @@ const { resetFields, validate, validateInfos } = useForm(
const onSubmit = () => {
validate()
.then(async (res) => {
- const params = toRaw(formData);
+ const params = toRaw(formData.value);
loading.value = true;
- const response = await save(params);
+ const response =
+ type === 'edit' ? await update(params) : await save(params);
if (response.status === 200) {
message.success('操作成功');
router.push('/link/certificate');
@@ -156,10 +162,28 @@ const handleChange = (info: UploadChangeParam) => {
if (info.file.status === 'done') {
message.success('上传成功!');
const result = info.file.response?.result;
- formData.configs.cert = result;
+ formData.value.configs.cert = result;
fileLoading.value = false;
}
};
+
+const detail = async (id: string) => {
+ if (type !== 'add') {
+ loading.value = true;
+ const res = await queryDetail(id);
+ if (res.success) {
+ const result = res.result as FormDataType;
+ const type = result.type.value as TypeObjType;
+ formData.value = {
+ ...result,
+ type,
+ };
+ }
+ loading.value = false;
+ }
+};
+
+detail(id);
diff --git a/src/views/link/Certificate/type.d.ts b/src/views/link/Certificate/type.d.ts
new file mode 100644
index 00000000..eb38e3e6
--- /dev/null
+++ b/src/views/link/Certificate/type.d.ts
@@ -0,0 +1,19 @@
+
+export interface TypeObjType = {
+ text: string;
+ value: string;
+};
+export type FormDataType = {
+ description: string;
+ name: string;
+ type: string | TypeObjType;
+ configs: {
+ cert: string;
+ key: string;
+ };
+ id?: string;
+ format?: string;
+ mode?: object;
+ creatorId?: string;
+ createTime?: number;
+};
diff --git a/src/views/notice/Config/index.vue b/src/views/notice/Config/index.vue
index 801f8b39..6a2af067 100644
--- a/src/views/notice/Config/index.vue
+++ b/src/views/notice/Config/index.vue
@@ -77,20 +77,35 @@
v-bind="item.tooltip"
:title="item.disabled && item.tooltip.title"
>
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+ {{ o.text }}
+
+
+
+
+
-
-
-
- {{ item.text }}
-
+
@@ -98,14 +113,8 @@
:disabled="item.disabled"
@click="item.onClick"
>
-
-
-
- {{ item.text }}
-
+
+ {{ item.text }}
@@ -351,29 +360,35 @@ const getActions = (
currentConfig.value = data;
},
},
- {
- key: 'debug',
- text: '导出',
- tooltip: {
- title: '导出',
- },
- icon: 'ArrowDownOutlined',
- onClick: () => {
- downloadObject(data, `通知配置`);
- },
- },
- {
- key: 'sync',
- text: '同步用户',
- tooltip: {
- title: '同步用户',
- },
- icon: 'TeamOutlined',
- onClick: () => {
- syncVis.value = true;
- currentConfig.value = data;
- },
- },
+ // {
+ // key: 'others',
+ // text: '其他',
+ // children: [
+ // {
+ // key: 'debug',
+ // text: '导出',
+ // tooltip: {
+ // title: '导出',
+ // },
+ // icon: 'ArrowDownOutlined',
+ // onClick: () => {
+ // downloadObject(data, `通知配置`);
+ // },
+ // },
+ // {
+ // key: 'sync',
+ // text: '同步用户',
+ // tooltip: {
+ // title: '同步用户',
+ // },
+ // icon: 'TeamOutlined',
+ // onClick: () => {
+ // syncVis.value = true;
+ // currentConfig.value = data;
+ // },
+ // },
+ // ],
+ // },
{
key: 'delete',
text: '删除',
@@ -392,9 +407,55 @@ const getActions = (
icon: 'DeleteOutlined',
},
];
- if (data.provider === 'dingTalkMessage' || data.provider === 'corpMessage')
+
+ const others: ActionsType = {
+ key: 'others',
+ text: '其他',
+ icon: 'EllipsisOutlined',
+ children: [
+ {
+ key: 'debug',
+ text: '导出',
+ tooltip: {
+ title: '导出',
+ },
+ icon: 'ArrowDownOutlined',
+ onClick: () => {
+ downloadObject(data, `通知配置`);
+ },
+ },
+ {
+ key: 'sync',
+ text: '同步用户',
+ tooltip: {
+ title: '同步用户',
+ },
+ icon: 'TeamOutlined',
+ onClick: () => {
+ syncVis.value = true;
+ currentConfig.value = data;
+ },
+ },
+ ],
+ };
+
+ if (type === 'card') {
+ if (
+ data.provider !== 'dingTalkMessage' &&
+ data.provider !== 'corpMessage'
+ )
+ others.children.splice(1, 1);
+ actions.splice(actions.length - 1, 0, others);
return actions;
- return actions.filter((i: ActionsType) => i.key !== 'sync');
+ } else {
+ if (
+ data.provider !== 'dingTalkMessage' &&
+ data.provider !== 'corpMessage'
+ )
+ others.children.splice(1, 1);
+ actions.splice(actions.length - 1, 0, ...others.children);
+ return actions;
+ }
};
diff --git a/src/views/system/Menu/components/PermissChoose.vue b/src/views/system/Menu/components/PermissChoose.vue
new file mode 100644
index 00000000..b4abf16f
--- /dev/null
+++ b/src/views/system/Menu/components/PermissChoose.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
diff --git a/src/views/system/Menu/index.vue b/src/views/system/Menu/index.vue
index 7ff407f3..648b29cc 100644
--- a/src/views/system/Menu/index.vue
+++ b/src/views/system/Menu/index.vue
@@ -208,7 +208,8 @@ const table = reactive({
};
const resp: any = await getMenuTree_api(params);
const lastItem = resp.result[resp.result.length - 1];
- table.total == lastItem ? lastItem.sortIndex + 1 : 1;
+ table.total = lastItem ? lastItem.sortIndex + 1 : 1;
+
return {
code: resp.message,
result: {
@@ -225,7 +226,7 @@ const table = reactive({
router.push(
`/system/Menu/detail/${row.id || ':id'}?pid=${
row.pid || ''
- }&basePath=${row.basePath || ''}&sortIndex=${table.total + 1}`,
+ }&basePath=${row.basePath || ''}&sortIndex=${table.total}`,
);
},
// 删除