diff --git a/public/images/iot-card/iot-card-bg.png b/public/images/iot-card/iot-card-bg.png new file mode 100644 index 00000000..7b47b0e0 Binary files /dev/null and b/public/images/iot-card/iot-card-bg.png differ diff --git a/src/api/iot-card/cardManagement.ts b/src/api/iot-card/cardManagement.ts index 390685e0..51a77294 100644 --- a/src/api/iot-card/cardManagement.ts +++ b/src/api/iot-card/cardManagement.ts @@ -64,4 +64,37 @@ export const sync = () => server.get(`/network/card/state/_sync`); * 批量删除物联卡 * @param data */ -export const removeCards = (data: any) => server.post(`/network/card/batch/_delete`, data); \ No newline at end of file +export const removeCards = (data: any) => server.post(`/network/card/batch/_delete`, data); + +/** + * 解绑设备 + * @param cardId + */ +export const unbind = (cardId: string) => server.get(`/network/card/${cardId}/_unbind`); + +/** + * 分页查询未绑定设备列表 + * @param data +*/ +export const queryUnbounded = (data: any) => server.post(`/network/card/unbounded/device/_query`, data); + +/** + * 绑定设备 + * @param cardId + * @param deviceId 选择的设备id + */ +export const bind = (cardId: string | any, deviceId: string) => server.get(`/network/card/${cardId}/${deviceId}/_bind`); + +/** + * 导入物联卡实例 + * @param configId 对接平台id + * @param params + */ +export const _import = (configId: any, params: any) => server.get(`/network/card/${configId}/_import`, params); + +/** + * 根据id批量导出 + * @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 diff --git a/src/components/CardBox/index.vue b/src/components/CardBox/index.vue index b3449223..cb958ce7 100644 --- a/src/components/CardBox/index.vue +++ b/src/components/CardBox/index.vue @@ -232,6 +232,17 @@ const handleClick = () => { :deep(.card-item-content-title) { cursor: pointer; } + + :deep(.card-item-heard-name) { + font-weight: 700; + font-size: 16px; + margin-bottom: 12px; + } + + :deep(.card-item-content-text) { + color: rgba(0, 0, 0, 0.75); + font-size: 12px; + } } .card-mask { diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 239ee90f..d9d3e290 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -54,6 +54,17 @@ export const downloadObject = (record: Record, fileName: string, fo formElement.submit(); document.body.removeChild(formElement); }; + +export const downloadFileByUrl = (url: string, name: string, type: string) => { + const downNode = document.createElement('a'); + downNode.style.display = 'none'; + downNode.download = `${name}.${type}`; + downNode.href = url; + document.body.appendChild(downNode); + downNode.click(); + document.body.removeChild(downNode); +}; + // 是否不是community版本 export const isNoCommunity = !(localStorage.getItem(SystemConst.VERSION_CODE) === 'community'); diff --git a/src/views/iot-card/CardManagement/BindDevice.vue b/src/views/iot-card/CardManagement/BindDevice.vue new file mode 100644 index 00000000..cdf48031 --- /dev/null +++ b/src/views/iot-card/CardManagement/BindDevice.vue @@ -0,0 +1,155 @@ + + + + + + diff --git a/src/views/iot-card/CardManagement/Export.vue b/src/views/iot-card/CardManagement/Export.vue new file mode 100644 index 00000000..5f20c55f --- /dev/null +++ b/src/views/iot-card/CardManagement/Export.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/src/views/iot-card/CardManagement/Import.vue b/src/views/iot-card/CardManagement/Import.vue new file mode 100644 index 00000000..0ca75bca --- /dev/null +++ b/src/views/iot-card/CardManagement/Import.vue @@ -0,0 +1,157 @@ + + + + + diff --git a/src/views/iot-card/CardManagement/index.vue b/src/views/iot-card/CardManagement/index.vue index 6ab563d4..3cf85c36 100644 --- a/src/views/iot-card/CardManagement/index.vue +++ b/src/views/iot-card/CardManagement/index.vue @@ -103,6 +103,113 @@ + + @@ -204,16 +325,25 @@ import { resumptionBatch, sync, removeCards, + unbind, } from '@/api/iot-card/cardManagement'; import { message } from 'ant-design-vue'; +import type { CardManagement } from './typing'; +import { getImage } from '@/utils/comm'; +import BindDevice from './BindDevice.vue'; +import Import from './Import.vue'; +import Export from './Export.vue'; const cardManageRef = ref>({}); const params = ref>({}); const _selectedRowKeys = ref([]); const _selectedRow = ref([]); +const bindDeviceVisible = ref(false); const visible = ref(false); const exportVisible = ref(false); const importVisible = ref(false); +const cardId = ref(); +const current = ref>({}); const columns = [ { @@ -239,9 +369,10 @@ const columns = [ }, { title: '绑定设备', - dataIndex: 'deviceName', - key: 'deviceName', + dataIndex: 'deviceId', + key: 'deviceId', ellipsis: true, + scopedSlots: true, width: 200, }, { @@ -360,7 +491,10 @@ const columns = [ }, ]; -const getActions = (data: Partial>): ActionsType[] => { +const getActions = ( + data: Partial>, + type: 'card' | 'table', +): ActionsType[] => { if (!data) return []; return [ { @@ -386,6 +520,25 @@ const getActions = (data: Partial>): ActionsType[] => { title: data.deviceId ? '解绑设备' : '绑定设备', }, icon: data.deviceId ? 'DisconnectOutlined' : 'LinkOutlined', + popConfirm: data.deviceId + ? { + title: '确认解绑设备?', + onConfirm: async () => { + unbind(data.id).then((resp: any) => { + if (resp.status === 200) { + message.success('操作成功'); + cardManageRef.value?.reload(); + } + }); + }, + } + : undefined, + onClick: () => { + if (!data.deviceId) { + bindDeviceVisible.value = true; + cardId.value = data.id; + } + }, }, { key: 'activation', @@ -479,11 +632,38 @@ const cancelSelect = () => { _selectedRowKeys.value = []; }; +const handleClick = (dt: any) => { + if (_selectedRowKeys.value.includes(dt.id)) { + const _index = _selectedRowKeys.value.findIndex((i) => i === dt.id); + _selectedRowKeys.value.splice(_index, 1); + } else { + _selectedRowKeys.value = [..._selectedRowKeys.value, dt.id]; + } +}; + +/** + * 查看 + */ +const handleView = (id: string) => { + message.warn(id + '暂未开发'); +}; + /** * 新增 */ const handleAdd = () => {}; +/** + * 绑定设备关闭窗口 + */ +const bindDevice = (val: boolean) => { + bindDeviceVisible.value = false; + cardId.value = ''; + if (val) { + cardManageRef.value?.reload(); + } +}; + /** * 批量激活 */ @@ -565,7 +745,25 @@ const handelRemove = async () => { diff --git a/src/views/iot-card/CardManagement/typing.d.ts b/src/views/iot-card/CardManagement/typing.d.ts new file mode 100644 index 00000000..b661a226 --- /dev/null +++ b/src/views/iot-card/CardManagement/typing.d.ts @@ -0,0 +1,20 @@ +export type CardManagement = { + id: string; + name: string; + iccId: string; + deviceId: string; + deviceName: string; + platformConfigId: string; + operatorName: string; + cardType: any; + totalFlow: number; + usedFlow: number; + residualFlow: number; + activationDate: string; + updateTime: string; + cardStateType: any; + cardState: any; + describe: string; + platformConfigName: string; + operatorPlatformType: any; +};