diff --git a/src/api/iot-card/cardManagement.ts b/src/api/iot-card/cardManagement.ts index 51a77294..34aee292 100644 --- a/src/api/iot-card/cardManagement.ts +++ b/src/api/iot-card/cardManagement.ts @@ -97,4 +97,22 @@ export const _import = (configId: any, params: any) => server.get(`/network/card * @param format 类型 xlsx、csv * @param params */ -export const _export = (format: string, data: any) => server.post(`/network/card/download.${format}/_query`, data, 'blob'); \ No newline at end of file +export const _export = (format: string, data: any) => server.post(`/network/card/download.${format}/_query`, data, 'blob'); + +/** + * 验证iccid + * @param id + */ +export const validateId = (id: string) => server.get(`/network/card/id/_validate?id=${id}`); + +/** + * 新增物联卡 + * @param data + */ +export const add = (data: any) => server.patch(`/network/card`, data); + +/** + * 编辑物联卡 + * @param data + */ +export const edit = (data: any) => server.put(`/network/card/${data.id}`, data); \ No newline at end of file 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/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/iot-card/CardManagement/Save.vue b/src/views/iot-card/CardManagement/Save.vue new file mode 100644 index 00000000..9e62a69f --- /dev/null +++ b/src/views/iot-card/CardManagement/Save.vue @@ -0,0 +1,246 @@ + + + diff --git a/src/views/iot-card/CardManagement/index.vue b/src/views/iot-card/CardManagement/index.vue index 3cf85c36..3b5a1809 100644 --- a/src/views/iot-card/CardManagement/index.vue +++ b/src/views/iot-card/CardManagement/index.vue @@ -151,11 +151,18 @@ {{ slotProps.totalFlow }} - M 使用流量 + + M 使用流量
-
{{ slotProps.totalFlow - slotProps.usedFlow }} %
+
+ {{ + slotProps.totalFlow - slotProps.usedFlow + }} + % +
总共 {{ slotProps.totalFlow }} M
@@ -163,7 +170,9 @@
@@ -307,6 +316,13 @@ :cardId="cardId" @change="bindDevice" /> + +
@@ -333,6 +349,7 @@ import { getImage } from '@/utils/comm'; import BindDevice from './BindDevice.vue'; import Import from './Import.vue'; import Export from './Export.vue'; +import Save from './Save.vue'; const cardManageRef = ref>({}); const params = ref>({}); @@ -344,6 +361,7 @@ const exportVisible = ref(false); const importVisible = ref(false); const cardId = ref(); const current = ref>({}); +const saveType = ref(''); const columns = [ { @@ -504,6 +522,11 @@ const getActions = ( title: '编辑', }, icon: 'EditOutlined', + onClick: () => { + visible.value = true; + current.value = data; + saveType.value = 'edit'; + }, }, { key: 'view', @@ -651,10 +674,27 @@ const handleView = (id: string) => { /** * 新增 */ -const handleAdd = () => {}; +const handleAdd = () => { + visible.value = true; + current.value = {}; + saveType.value = 'add'; +}; + +/** + * 新增、编辑关闭弹窗 + * @param val 加载表格 + */ +const saveChange = (val: any) => { + visible.value = false; + current.value = {}; + if (val) { + cardManageRef.value?.reload(); + } +}; /** * 绑定设备关闭窗口 + * @param val */ const bindDevice = (val: boolean) => { bindDeviceVisible.value = false; diff --git a/src/views/iot-card/data.ts b/src/views/iot-card/data.ts new file mode 100644 index 00000000..cf9a9fc3 --- /dev/null +++ b/src/views/iot-card/data.ts @@ -0,0 +1,76 @@ +import { getImage } from '@/utils/comm'; + +// 平台类型 +export const PlatformTypeList = [ + { + label: '移动OneLink', + value: 'OneLinkPB', + imgUrl: getImage('/iot-card/onelink.png'), + }, + { + label: '电信Ctwing', + value: 'CtwingCmp', + imgUrl: getImage('/iot-card/ctwingcmp.png'), + }, + { + label: '联通Unicom', + value: 'UnicomCmp', + imgUrl: getImage('/iot-card/unicom.png'), + }, +]; + +//运营商 +export const OperatorList = [ + { + label: '移动', + value: '移动', + }, + { + label: '电信', + value: '电信', + }, + { + label: '联通', + value: '联通', + }, +]; + +// 类型 +export const TypeList = [ + { + label: '年卡', + value: 'year', + }, + { + label: '季卡', + value: 'season', + }, + { + label: '月卡', + value: 'month', + }, + { + label: '其他', + value: 'other', + }, +]; + +// 支付方式 +export const PaymentMethod = [ + { + label: '支付宝手机网站支付', + value: 'ALIPAY_WAP', + }, + { + label: '支付宝网页及时到账支付', + value: 'ALIPAY_WEB', + }, + { + label: '微信公众号支付', + value: 'WEIXIN_JSAPI', + }, + { + label: '微信扫码支付', + value: 'WEIXIN_NATIVE', + }, +]; diff --git a/src/views/system/Menu/Detail/BasicInfo.vue b/src/views/system/Menu/Detail/BasicInfo.vue index 18b62db3..f69d348c 100644 --- a/src/views/system/Menu/Detail/BasicInfo.vue +++ b/src/views/system/Menu/Detail/BasicInfo.vue @@ -2,7 +2,7 @@

基本信息

- +
- - 点击修改 + + 点击修改
-
+

点击选择图标

@@ -97,7 +104,11 @@

权限配置

- + @@ -194,20 +207,28 @@ import { QuestionCircleFilled, QuestionCircleOutlined, } from '@ant-design/icons-vue'; +import { FormInstance, message } from 'ant-design-vue'; +import ChooseIconDialog from '../components/ChooseIconDialog.vue'; +import PermissChoose from '../components/PermissChoose.vue'; + import { getMenuTree_api, getAssetsType_api, - getMenuDetail_api, + getMenuInfo_api, + saveMenuInfo_api, + addMenuInfo_api, } from '@/api/system/menu'; -import { exportPermission_api } from '@/api/system/permission'; const route = useRoute(); +const router = useRouter(); const routeParams = { - id: route.params.id === ':id' ? '' : (route.params.id as string), + id: route.params.id === ':id' ? undefined : (route.params.id as string), ...route.query, url: route.query.basePath, }; +const basicFormRef = ref(); +const permissFormRef = ref(); const form = reactive({ data: { name: '', @@ -215,8 +236,8 @@ const form = reactive({ sortIndex: '', icon: '', describe: '', - permissions: '', - accessSupport: '', + permissions: [], + accessSupport: 'unsupported', assetType: undefined, indirectMenus: [], ...routeParams, @@ -229,23 +250,63 @@ const form = reactive({ init: () => { // 获取菜单详情 routeParams.id && - getMenuDetail_api(routeParams.id).then((resp) => { + getMenuInfo_api(routeParams.id).then((resp) => { console.log('菜单详情', resp); }); - // 获取权限列表 - // exportPermission_api() // 获取关联菜单 getMenuTree_api({ paging: false }).then((resp) => { console.log('关联菜单', resp); }); // 获取资产类型 - getAssetsType_api().then((resp:any) => { - form.assetsType = resp.result.map((item:any)=>({label:item.name,value:item.id})) + getAssetsType_api().then((resp: any) => { + form.assetsType = resp.result.map((item: any) => ({ + label: item.name, + value: item.id, + })); }); }, }); form.init(); -const clickSave = () => {}; + +const ChooseIconRef = ref(null); +const dialog = { + openDialog: () => { + ChooseIconRef.value && ChooseIconRef.value.openDialog(); + }, + confirm: (typeStr: string) => { + form.data.icon = typeStr || form.data.icon; + }, +}; +const saveLoading = ref(false); +const clickSave = () => { + if (!basicFormRef || !permissFormRef) return; + Promise.all([ + basicFormRef.value?.validate(), + permissFormRef.value?.validate(), + ]) + .then(() => { + const api = routeParams.id ? saveMenuInfo_api : addMenuInfo_api; + saveLoading.value = true; + api(form.data) + .then((resp: any) => { + if (resp.status === 200) { + message.success('操作成功!'); + // 新增后刷新页面,编辑则不需要 + if (!routeParams.id) { + router.push( + `/system/Menu/detail/${resp.result.id}`, + ); + routeParams.id = resp.result.id; + form.init(); + } + } else { + message.error('操作失败!'); + } + }) + .finally(() => (saveLoading.value = false)); + }) + .catch((err) => {}); +}; type formType = { name: string; @@ -253,7 +314,7 @@ type formType = { url: string; sortIndex: string; icon: string; - permissions: string; + permissions: any[]; describe: string; accessSupport: string; assetType: string | undefined; @@ -321,6 +382,25 @@ type assetType = { } } .has-icon { + position: relative; + text-align: center; + + .mark { + position: absolute; + left: 0; + top: 0; + display: none; + background-color: rgba(0, 0, 0, 0.35); + color: #fff; + width: 100%; + height: 100%; + font-size: 16px; + align-items: center; + justify-content: center; + } + &:hover .mark { + display: flex; + } } .no-icon { background-color: rgba(0, 0, 0, 0.06); diff --git a/src/views/system/Menu/components/ChooseIconDialog.vue b/src/views/system/Menu/components/ChooseIconDialog.vue new file mode 100644 index 00000000..9cb64723 --- /dev/null +++ b/src/views/system/Menu/components/ChooseIconDialog.vue @@ -0,0 +1,100 @@ + + + + + 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}`, ); }, // 删除