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 @@ + 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 }} + + + - - + @@ -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}`, ); }, // 删除