Showing
8 changed files
with
157 additions
and
17 deletions
| @@ -45,6 +45,7 @@ enum DeviceManagerApi { | @@ -45,6 +45,7 @@ enum DeviceManagerApi { | ||
| 45 | DEVICE_PUBLIC = '/customer/public/device', | 45 | DEVICE_PUBLIC = '/customer/public/device', |
| 46 | 46 | ||
| 47 | DEVICE_PRIVATE = '/customer/device', | 47 | DEVICE_PRIVATE = '/customer/device', |
| 48 | + DEVICE_COLLECT = '/device/collect ', //收藏 | ||
| 48 | 49 | ||
| 49 | /** | 50 | /** |
| 50 | * @description 通过设备列表获取设备信息 | 51 | * @description 通过设备列表获取设备信息 |
| @@ -61,6 +62,13 @@ export const devicePage = (params: DeviceQueryParam) => { | @@ -61,6 +62,13 @@ export const devicePage = (params: DeviceQueryParam) => { | ||
| 61 | }); | 62 | }); |
| 62 | }; | 63 | }; |
| 63 | 64 | ||
| 65 | +export const deviceCollect = (params: Array<any>) => { | ||
| 66 | + return defHttp.post({ | ||
| 67 | + url: `${DeviceManagerApi.DEVICE_COLLECT}`, | ||
| 68 | + params, | ||
| 69 | + }); | ||
| 70 | +}; | ||
| 71 | + | ||
| 64 | /** | 72 | /** |
| 65 | * 分页查询设备配置页面 | 73 | * 分页查询设备配置页面 |
| 66 | * @param params pageSize page name | 74 | * @param params pageSize page name |
| @@ -12,7 +12,7 @@ export const columns: BasicColumn[] = [ | @@ -12,7 +12,7 @@ export const columns: BasicColumn[] = [ | ||
| 12 | { | 12 | { |
| 13 | title: '状态', | 13 | title: '状态', |
| 14 | dataIndex: 'deviceState', | 14 | dataIndex: 'deviceState', |
| 15 | - width: 80, | 15 | + width: 110, |
| 16 | slots: { customRender: 'deviceState' }, | 16 | slots: { customRender: 'deviceState' }, |
| 17 | }, | 17 | }, |
| 18 | { | 18 | { |
| @@ -167,4 +167,17 @@ export const searchFormSchema: FormSchema[] = [ | @@ -167,4 +167,17 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 167 | }; | 167 | }; |
| 168 | }, | 168 | }, |
| 169 | }, | 169 | }, |
| 170 | + { | ||
| 171 | + field: 'isCollect', | ||
| 172 | + label: '是否收藏', | ||
| 173 | + component: 'Select', | ||
| 174 | + colProps: { span: 6 }, | ||
| 175 | + componentProps: { | ||
| 176 | + options: [ | ||
| 177 | + { label: '是', value: 1 }, | ||
| 178 | + { label: '否', value: 0 }, | ||
| 179 | + ], | ||
| 180 | + placeholder: '请选择', | ||
| 181 | + }, | ||
| 182 | + }, | ||
| 170 | ]; | 183 | ]; |
| @@ -34,6 +34,11 @@ | @@ -34,6 +34,11 @@ | ||
| 34 | 批量分配 | 34 | 批量分配 |
| 35 | </a-button> | 35 | </a-button> |
| 36 | </Authority> | 36 | </Authority> |
| 37 | + <!-- <Authority> | ||
| 38 | + <a-button type="primary" @click="handelCollect()" :disabled="!isExistOption"> | ||
| 39 | + 批量收藏 | ||
| 40 | + </a-button> | ||
| 41 | + </Authority> --> | ||
| 37 | </template> | 42 | </template> |
| 38 | <template #img="{ record }"> | 43 | <template #img="{ record }"> |
| 39 | <TableImg | 44 | <TableImg |
| @@ -85,7 +90,13 @@ | @@ -85,7 +90,13 @@ | ||
| 85 | </Tag> | 90 | </Tag> |
| 86 | </template> | 91 | </template> |
| 87 | <template #deviceState="{ record }"> | 92 | <template #deviceState="{ record }"> |
| 93 | + <!-- <HeartOutlined v-if="!record.isCollect" class="mr-1" style="color: red" /> --> | ||
| 94 | + <Tooltip> | ||
| 95 | + <template #title> 我的收藏</template> | ||
| 96 | + <HeartTwoTone v-if="record.isCollect" class="mr-1" twoToneColor="#3B82F6" /> | ||
| 97 | + </Tooltip> | ||
| 88 | <Tag | 98 | <Tag |
| 99 | + :style="{ marginLeft: !record.isCollect ? '17px' : '' }" | ||
| 89 | :color=" | 100 | :color=" |
| 90 | record.deviceState == DeviceState.INACTIVE | 101 | record.deviceState == DeviceState.INACTIVE |
| 91 | ? 'warning' | 102 | ? 'warning' |
| @@ -154,6 +165,18 @@ | @@ -154,6 +165,18 @@ | ||
| 154 | icon: 'ant-design:rise-outlined', | 165 | icon: 'ant-design:rise-outlined', |
| 155 | onClick: handleUpAndDownRecord.bind(null, record), | 166 | onClick: handleUpAndDownRecord.bind(null, record), |
| 156 | }, | 167 | }, |
| 168 | + !record.isCollect | ||
| 169 | + ? { | ||
| 170 | + label: '收藏', | ||
| 171 | + icon: 'ant-design:heart-outlined', | ||
| 172 | + onClick: handelCollect.bind(null, record), | ||
| 173 | + } | ||
| 174 | + : { | ||
| 175 | + label: '取消收藏', | ||
| 176 | + auth: 'api:yt:device:online:record', | ||
| 177 | + icon: 'ant-design:heart-outlined', | ||
| 178 | + onClick: handelCollect.bind(null, record), | ||
| 179 | + }, | ||
| 157 | { | 180 | { |
| 158 | label: '删除', | 181 | label: '删除', |
| 159 | auth: 'api:yt:device:delete', | 182 | auth: 'api:yt:device:delete', |
| @@ -195,10 +218,12 @@ | @@ -195,10 +218,12 @@ | ||
| 195 | } from '/@/api/device/model/deviceModel'; | 218 | } from '/@/api/device/model/deviceModel'; |
| 196 | import { BasicTable, useTable, TableAction, TableImg } from '/@/components/Table'; | 219 | import { BasicTable, useTable, TableAction, TableImg } from '/@/components/Table'; |
| 197 | import { columns, searchFormSchema } from './config/device.data'; | 220 | import { columns, searchFormSchema } from './config/device.data'; |
| 198 | - import { Tag, Popover, Popconfirm, Button } from 'ant-design-vue'; | 221 | + import { Tag, Popover, Popconfirm, Button, Tooltip } from 'ant-design-vue'; |
| 222 | + import { HeartTwoTone } from '@ant-design/icons-vue'; | ||
| 199 | import { | 223 | import { |
| 200 | deleteDevice, | 224 | deleteDevice, |
| 201 | devicePage, | 225 | devicePage, |
| 226 | + deviceCollect, | ||
| 202 | cancelDispatchCustomer, | 227 | cancelDispatchCustomer, |
| 203 | getGATEWAY, | 228 | getGATEWAY, |
| 204 | privateDevice, | 229 | privateDevice, |
| @@ -244,6 +269,9 @@ | @@ -244,6 +269,9 @@ | ||
| 244 | Popconfirm, | 269 | Popconfirm, |
| 245 | BatchImportModal, | 270 | BatchImportModal, |
| 246 | Button, | 271 | Button, |
| 272 | + // HeartOutlined, | ||
| 273 | + HeartTwoTone, | ||
| 274 | + Tooltip, | ||
| 247 | }, | 275 | }, |
| 248 | setup(_) { | 276 | setup(_) { |
| 249 | const { isCustomer } = useAuthDeviceDetail(); | 277 | const { isCustomer } = useAuthDeviceDetail(); |
| @@ -462,6 +490,26 @@ | @@ -462,6 +490,26 @@ | ||
| 462 | } catch (error) {} | 490 | } catch (error) {} |
| 463 | }; | 491 | }; |
| 464 | 492 | ||
| 493 | + // 收藏 && 批量收藏 | ||
| 494 | + const handelCollect = async (record?: Recordable) => { | ||
| 495 | + let ids: string[] = []; | ||
| 496 | + if (record) { | ||
| 497 | + ids.push(record.id); | ||
| 498 | + } else { | ||
| 499 | + ids = await getSelectRowKeys(); | ||
| 500 | + } | ||
| 501 | + try { | ||
| 502 | + setLoading(true); | ||
| 503 | + await deviceCollect(ids); | ||
| 504 | + createMessage.success('操作成功'); | ||
| 505 | + handleReload(); | ||
| 506 | + } catch (error) { | ||
| 507 | + throw error; | ||
| 508 | + } finally { | ||
| 509 | + setLoading(false); | ||
| 510 | + } | ||
| 511 | + }; | ||
| 512 | + | ||
| 465 | onMounted(() => { | 513 | onMounted(() => { |
| 466 | const queryParams = ROUTE.query as Record<'deviceProfileId', undefined | string>; | 514 | const queryParams = ROUTE.query as Record<'deviceProfileId', undefined | string>; |
| 467 | const { setFieldsValue } = getForm(); | 515 | const { setFieldsValue } = getForm(); |
| @@ -489,6 +537,7 @@ | @@ -489,6 +537,7 @@ | ||
| 489 | copySN, | 537 | copySN, |
| 490 | isExistOption, | 538 | isExistOption, |
| 491 | handleDelete, | 539 | handleDelete, |
| 540 | + handelCollect, | ||
| 492 | // hasBatchDelete, | 541 | // hasBatchDelete, |
| 493 | // handleDeleteOrBatchDelete, | 542 | // handleDeleteOrBatchDelete, |
| 494 | handleReload, | 543 | handleReload, |
| @@ -55,10 +55,18 @@ | @@ -55,10 +55,18 @@ | ||
| 55 | const { createMessage } = useMessage(); | 55 | const { createMessage } = useMessage(); |
| 56 | let config = {}; | 56 | let config = {}; |
| 57 | if (values.messageType === 'PHONE_MESSAGE') { | 57 | if (values.messageType === 'PHONE_MESSAGE') { |
| 58 | - config = { | ||
| 59 | - accessKeyId: values.accessKeyId, | ||
| 60 | - accessKeySecret: values.accessKeySecret, | ||
| 61 | - }; | 58 | + if (values.platformType === 'ALI_CLOUD') { |
| 59 | + config = { | ||
| 60 | + accessKeyId: values.accessKeyId, | ||
| 61 | + accessKeySecret: values.accessKeySecret, | ||
| 62 | + }; | ||
| 63 | + } else { | ||
| 64 | + config = { | ||
| 65 | + appId: values.appId, | ||
| 66 | + secretId: values.secretId, | ||
| 67 | + secretKey: values.secretKey, | ||
| 68 | + }; | ||
| 69 | + } | ||
| 62 | } else if (values.messageType === 'EMAIL_MESSAGE') { | 70 | } else if (values.messageType === 'EMAIL_MESSAGE') { |
| 63 | config = { | 71 | config = { |
| 64 | host: values.host, | 72 | host: values.host, |
| @@ -79,6 +79,9 @@ export const isMessage = (type: string) => { | @@ -79,6 +79,9 @@ export const isMessage = (type: string) => { | ||
| 79 | export const isEmail = (type: string) => { | 79 | export const isEmail = (type: string) => { |
| 80 | return type === MessageEnum.IS_EMAIL; | 80 | return type === MessageEnum.IS_EMAIL; |
| 81 | }; | 81 | }; |
| 82 | +export const messageTypeIsTencentCloud = (type: string) => { | ||
| 83 | + return type === 'TENCENT_CLOUD'; | ||
| 84 | +}; | ||
| 82 | 85 | ||
| 83 | export const formSchema: FormSchema[] = [ | 86 | export const formSchema: FormSchema[] = [ |
| 84 | { | 87 | { |
| @@ -121,15 +124,53 @@ export const formSchema: FormSchema[] = [ | @@ -121,15 +124,53 @@ export const formSchema: FormSchema[] = [ | ||
| 121 | ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), | 124 | ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), |
| 122 | }, | 125 | }, |
| 123 | { | 126 | { |
| 127 | + field: 'appId', | ||
| 128 | + label: 'appId', | ||
| 129 | + required: true, | ||
| 130 | + component: 'Input', | ||
| 131 | + componentProps: { | ||
| 132 | + maxLength: 36, | ||
| 133 | + placeholder: '请输入appId', | ||
| 134 | + }, | ||
| 135 | + ifShow: ({ values }) => messageTypeIsTencentCloud(Reflect.get(values, 'platformType')), | ||
| 136 | + }, | ||
| 137 | + { | ||
| 138 | + field: 'secretId', | ||
| 139 | + label: 'secretId', | ||
| 140 | + required: true, | ||
| 141 | + component: 'Input', | ||
| 142 | + helpMessage: ['腾讯云:API密钥参考地址: https://console.cloud.tencent.com/cam/capi'], | ||
| 143 | + componentProps: { | ||
| 144 | + maxLength: 36, | ||
| 145 | + placeholder: '请输入secretId', | ||
| 146 | + }, | ||
| 147 | + ifShow: ({ values }) => messageTypeIsTencentCloud(Reflect.get(values, 'platformType')), | ||
| 148 | + }, | ||
| 149 | + { | ||
| 150 | + field: 'secretKey', | ||
| 151 | + label: 'secretKey', | ||
| 152 | + required: true, | ||
| 153 | + componentProps: { | ||
| 154 | + maxLength: 36, | ||
| 155 | + placeholder: '请输入secretKey', | ||
| 156 | + }, | ||
| 157 | + | ||
| 158 | + component: 'Input', | ||
| 159 | + ifShow: ({ values }) => messageTypeIsTencentCloud(Reflect.get(values, 'platformType')), | ||
| 160 | + }, | ||
| 161 | + { | ||
| 124 | field: 'accessKeyId', | 162 | field: 'accessKeyId', |
| 125 | label: 'accessKeyId', | 163 | label: 'accessKeyId', |
| 126 | required: true, | 164 | required: true, |
| 127 | component: 'Input', | 165 | component: 'Input', |
| 166 | + helpMessage: ['阿里云:API密钥参考地址:https://ram.console.aliyun.com/manage/ak'], | ||
| 128 | componentProps: { | 167 | componentProps: { |
| 129 | maxLength: 36, | 168 | maxLength: 36, |
| 130 | placeholder: '请输入accessKeyId', | 169 | placeholder: '请输入accessKeyId', |
| 131 | }, | 170 | }, |
| 132 | - ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), | 171 | + ifShow: ({ values }) => |
| 172 | + isMessage(Reflect.get(values, 'messageType')) && | ||
| 173 | + !messageTypeIsTencentCloud(Reflect.get(values, 'platformType')), | ||
| 133 | }, | 174 | }, |
| 134 | { | 175 | { |
| 135 | field: 'accessKeySecret', | 176 | field: 'accessKeySecret', |
| @@ -141,7 +182,9 @@ export const formSchema: FormSchema[] = [ | @@ -141,7 +182,9 @@ export const formSchema: FormSchema[] = [ | ||
| 141 | }, | 182 | }, |
| 142 | 183 | ||
| 143 | component: 'Input', | 184 | component: 'Input', |
| 144 | - ifShow: ({ values }) => isMessage(Reflect.get(values, 'messageType')), | 185 | + ifShow: ({ values }) => |
| 186 | + isMessage(Reflect.get(values, 'messageType')) && | ||
| 187 | + !messageTypeIsTencentCloud(Reflect.get(values, 'platformType')), | ||
| 145 | }, | 188 | }, |
| 146 | { | 189 | { |
| 147 | field: 'host', | 190 | field: 'host', |
| @@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
| 6 | </BasicModal> | 6 | </BasicModal> |
| 7 | </template> | 7 | </template> |
| 8 | <script lang="ts"> | 8 | <script lang="ts"> |
| 9 | - import { defineComponent } from 'vue'; | 9 | + import { defineComponent, ref } from 'vue'; |
| 10 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 10 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
| 11 | import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; | 11 | import { BasicForm, FormSchema, useForm } from '/@/components/Form/index'; |
| 12 | import { sendSms } from '/@/api/message/template'; | 12 | import { sendSms } from '/@/api/message/template'; |
| @@ -76,7 +76,7 @@ | @@ -76,7 +76,7 @@ | ||
| 76 | label: '短信参数', | 76 | label: '短信参数', |
| 77 | required: true, | 77 | required: true, |
| 78 | componentProps: { | 78 | componentProps: { |
| 79 | - placeholder: '示例:{"code":"3654"}', | 79 | + placeholder: '示例:{"code":"1234"}', |
| 80 | }, | 80 | }, |
| 81 | dynamicRules: () => { | 81 | dynamicRules: () => { |
| 82 | return [ | 82 | return [ |
| @@ -90,10 +90,10 @@ | @@ -90,10 +90,10 @@ | ||
| 90 | if (typeof JSON.parse(value) == 'object') { | 90 | if (typeof JSON.parse(value) == 'object') { |
| 91 | return Promise.resolve(); | 91 | return Promise.resolve(); |
| 92 | } | 92 | } |
| 93 | - return Promise.reject('请输入JSON格式例如{"code":"123"}'); | 93 | + return Promise.reject('请输入JSON格式例如{"code":"1234"}'); |
| 94 | } | 94 | } |
| 95 | } catch { | 95 | } catch { |
| 96 | - return Promise.reject('请输入JSON格式例如{"code":"123"}'); | 96 | + return Promise.reject('请输入JSON格式例如{"code":"1234"}'); |
| 97 | } | 97 | } |
| 98 | }, | 98 | }, |
| 99 | }, | 99 | }, |
| @@ -126,8 +126,9 @@ | @@ -126,8 +126,9 @@ | ||
| 126 | export default defineComponent({ | 126 | export default defineComponent({ |
| 127 | components: { BasicModal, BasicForm }, | 127 | components: { BasicModal, BasicForm }, |
| 128 | setup() { | 128 | setup() { |
| 129 | + const platformType = ref(''); | ||
| 129 | const { createMessage } = useMessage(); | 130 | const { createMessage } = useMessage(); |
| 130 | - const [registerForm, { validate, resetFields, setFieldsValue }] = useForm({ | 131 | + const [registerForm, { validate, resetFields, setFieldsValue, updateSchema }] = useForm({ |
| 131 | labelWidth: 70, | 132 | labelWidth: 70, |
| 132 | schemas, | 133 | schemas, |
| 133 | showActionButtonGroup: false, | 134 | showActionButtonGroup: false, |
| @@ -136,6 +137,14 @@ | @@ -136,6 +137,14 @@ | ||
| 136 | }, | 137 | }, |
| 137 | }); | 138 | }); |
| 138 | const [register, { closeModal }] = useModalInner(async (data) => { | 139 | const [register, { closeModal }] = useModalInner(async (data) => { |
| 140 | + platformType.value = data.record?.messageConfig?.platformType; | ||
| 141 | + updateSchema({ | ||
| 142 | + field: 'params', | ||
| 143 | + componentProps: { | ||
| 144 | + placeholder: | ||
| 145 | + platformType.value !== 'TENCENT_CLOUD' ? '示例:{"code":"1234"}' : '示例:["123456"]', | ||
| 146 | + }, | ||
| 147 | + }); | ||
| 139 | await resetFields(); | 148 | await resetFields(); |
| 140 | await setFieldsValue({ | 149 | await setFieldsValue({ |
| 141 | ...data.record, | 150 | ...data.record, |
| @@ -143,9 +152,17 @@ | @@ -143,9 +152,17 @@ | ||
| 143 | }); | 152 | }); |
| 144 | 153 | ||
| 145 | async function handleOK() { | 154 | async function handleOK() { |
| 155 | + let smsParams: any = null; | ||
| 146 | const values = await validate(); | 156 | const values = await validate(); |
| 147 | - //将字符串转为json | ||
| 148 | - const smsParams = JSON.parse(Reflect.get(values, 'params')); | 157 | + if (platformType.value === 'TENCENT_CLOUD') { |
| 158 | + //腾讯云发送格式 将字符串转为数组 | ||
| 159 | + smsParams = { | ||
| 160 | + tencent_param: JSON.parse(Reflect.get(values, 'params')), | ||
| 161 | + }; | ||
| 162 | + } else { | ||
| 163 | + //阿里云发送格式 将字符串转为json | ||
| 164 | + smsParams = JSON.parse(Reflect.get(values, 'params')); | ||
| 165 | + } | ||
| 149 | Reflect.set(values, 'params', smsParams); | 166 | Reflect.set(values, 'params', smsParams); |
| 150 | await sendSms(values); | 167 | await sendSms(values); |
| 151 | closeModal(); | 168 | closeModal(); |
| @@ -247,10 +247,11 @@ export const formSchema: FormSchema[] = [ | @@ -247,10 +247,11 @@ export const formSchema: FormSchema[] = [ | ||
| 247 | helpMessage: `告警通知模板平台提供如下参数: | 247 | helpMessage: `告警通知模板平台提供如下参数: |
| 248 | { | 248 | { |
| 249 | "type":"告警类型", | 249 | "type":"告警类型", |
| 250 | - "device_name":"设备名称", | 250 | + "deviceName":"设备名称", |
| 251 | "severity":"告警等级", | 251 | "severity":"告警等级", |
| 252 | "organization":"设备所属组织", | 252 | "organization":"设备所属组织", |
| 253 | - "createTime":告警时间 | 253 | + "createTime":"告警时间", |
| 254 | + "triggerValue":"触发值", | ||
| 254 | }`, | 255 | }`, |
| 255 | }); | 256 | }); |
| 256 | } else if (value === 'FOR_SET_PASSWORD') { | 257 | } else if (value === 'FOR_SET_PASSWORD') { |
| @@ -50,6 +50,7 @@ | @@ -50,6 +50,7 @@ | ||
| 50 | label: BusinessConvertScriptTextEnum.BUSINESS_EDIT_TEXT.slice(0, 2), | 50 | label: BusinessConvertScriptTextEnum.BUSINESS_EDIT_TEXT.slice(0, 2), |
| 51 | icon: 'clarity:note-edit-line', | 51 | icon: 'clarity:note-edit-line', |
| 52 | auth: PermissionConvertScriptEnum.PERMISSION_UPDATE, | 52 | auth: PermissionConvertScriptEnum.PERMISSION_UPDATE, |
| 53 | + ifShow: record.status == 0, | ||
| 53 | onClick: handleBusinessModal.bind( | 54 | onClick: handleBusinessModal.bind( |
| 54 | null, | 55 | null, |
| 55 | BusinessConvertScriptTextEnum.BUSINESS_EDIT_TEXT, | 56 | BusinessConvertScriptTextEnum.BUSINESS_EDIT_TEXT, |