diff --git a/apps/web-antd/src/components/upload/file-upload.vue b/apps/web-antd/src/components/upload/file-upload.vue index 3838642ea..85afc3b9d 100644 --- a/apps/web-antd/src/components/upload/file-upload.vue +++ b/apps/web-antd/src/components/upload/file-upload.vue @@ -32,6 +32,7 @@ const props = withDefaults(defineProps(), { multiple: false, api: undefined, resultField: '', + returnText: false, showDescription: false, }); const emit = defineEmits([ @@ -147,9 +148,6 @@ function handleUploadError(error: any) { * @returns 是否允许上传 */ async function beforeUpload(file: File) { - const fileContent = await file.text(); - emit('returnText', fileContent); - // 检查文件数量限制 if (fileList.value!.length >= props.maxNumber) { message.error($t('ui.upload.maxNumber', [props.maxNumber])); @@ -176,6 +174,10 @@ async function beforeUpload(file: File) { // 只有在验证通过后才增加计数器 uploadNumber.value++; + if (props.returnText) { + const fileContent = await file.text(); + emit('returnText', fileContent); + } return true; } diff --git a/apps/web-antd/src/components/upload/input-upload.vue b/apps/web-antd/src/components/upload/input-upload.vue index 90b2f4f7c..88f00f1cf 100644 --- a/apps/web-antd/src/components/upload/input-upload.vue +++ b/apps/web-antd/src/components/upload/input-upload.vue @@ -58,6 +58,7 @@ const textareaProps = computed(() => { const fileUploadProps = computed(() => { return { ...props.fileUploadProps, + returnText: true, }; }); diff --git a/apps/web-antd/src/components/upload/typing.ts b/apps/web-antd/src/components/upload/typing.ts index f3c16bc4d..990aa7d8a 100644 --- a/apps/web-antd/src/components/upload/typing.ts +++ b/apps/web-antd/src/components/upload/typing.ts @@ -27,6 +27,7 @@ export interface FileUploadProps { maxSize?: number; // 文件最大多少MB multiple?: boolean; // 是否支持多选 resultField?: string; // support xxx.xxx.xx + returnText?: boolean; // 是否返回文件文本内容 showDescription?: boolean; // 是否显示下面的描述 value?: string | string[]; } diff --git a/apps/web-antd/src/views/iot/alert/record/index.vue b/apps/web-antd/src/views/iot/alert/record/index.vue index d3d8f9d17..b5c59a7a8 100644 --- a/apps/web-antd/src/views/iot/alert/record/index.vue +++ b/apps/web-antd/src/views/iot/alert/record/index.vue @@ -45,10 +45,6 @@ function handleProcess(row: AlertRecordApi.AlertRecord) { }), ]), async onOk() { - if (!processRemark.value) { - message.warning('请输入处理原因'); - throw new Error('请输入处理原因'); - } const hideLoading = message.loading({ content: '正在处理...', duration: 0, diff --git a/apps/web-antd/src/views/iot/device/device/detail/modules/modbus-config.vue b/apps/web-antd/src/views/iot/device/device/detail/modules/modbus-config.vue index 672915a01..ce4d907d8 100644 --- a/apps/web-antd/src/views/iot/device/device/detail/modules/modbus-config.vue +++ b/apps/web-antd/src/views/iot/device/device/detail/modules/modbus-config.vue @@ -14,7 +14,7 @@ import { computed, h, onMounted, ref } from 'vue'; import { confirm, useVbenModal } from '@vben/common-ui'; import { DICT_TYPE, ModbusFunctionCodeOptions } from '@vben/constants'; -import { Button, message } from 'ant-design-vue'; +import { message } from 'ant-design-vue'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { getModbusConfig } from '#/api/iot/device/modbus/config'; @@ -307,7 +307,16 @@ onMounted(async () => { @@ -320,6 +329,7 @@ onMounted(async () => { label: '新增点位', type: 'primary', icon: ACTION_ICON.ADD, + auth: ['iot:device:create'], onClick: handleAddPoint, }, ]" @@ -331,12 +341,14 @@ onMounted(async () => { { label: '编辑', type: 'link', + auth: ['iot:device:update'], onClick: () => handleEditPoint(row), }, { label: '删除', type: 'link', danger: true, + auth: ['iot:device:delete'], popConfirm: { title: `确定要删除点位【${row.name}】吗?`, confirm: () => handleDeletePoint(row), diff --git a/apps/web-antd/src/views/iot/device/device/detail/modules/simulator.vue b/apps/web-antd/src/views/iot/device/device/detail/modules/simulator.vue index ebfa9087c..8a58ce5f7 100644 --- a/apps/web-antd/src/views/iot/device/device/detail/modules/simulator.vue +++ b/apps/web-antd/src/views/iot/device/device/detail/modules/simulator.vue @@ -312,13 +312,15 @@ async function handleEventPost(row: ThingModelApi.ThingModel) { const valueStr = formData.value[row.identifier!]; let eventValue: any; - if (valueStr) { - try { - eventValue = JSON.parse(valueStr); - } catch { - message.error('事件参数格式错误,请输入有效的JSON格式'); - return; - } + if (valueStr === undefined || valueStr === null || valueStr === '') { + message.warning('请输入事件参数'); + return; + } + try { + eventValue = JSON.parse(valueStr); + } catch { + message.error('事件参数格式错误,请输入有效的JSON格式'); + return; } // 与后端 IotDeviceEventPostReqDTO 对齐 :{ identifier, value, time } @@ -399,21 +401,23 @@ async function handleServiceInvoke(row: ThingModelApi.ThingModel) { const valueStr = formData.value[row.identifier!]; let inputParams: any = {}; - if (valueStr) { - try { - inputParams = JSON.parse(valueStr); - } catch { - message.error('服务参数格式错误,请输入有效的JSON格式'); - return; - } - if ( - typeof inputParams !== 'object' || - inputParams === null || - Array.isArray(inputParams) - ) { - message.error('服务参数必须是 JSON 对象'); - return; - } + if (valueStr === undefined || valueStr === null || valueStr === '') { + message.warning('请输入服务参数'); + return; + } + try { + inputParams = JSON.parse(valueStr); + } catch { + message.error('服务参数格式错误,请输入有效的JSON格式'); + return; + } + if ( + typeof inputParams !== 'object' || + inputParams === null || + Array.isArray(inputParams) + ) { + message.error('服务参数必须是 JSON 对象'); + return; } // 与后端 IotDeviceServiceInvokeReqDTO 对齐 :{ identifier, inputParams } diff --git a/apps/web-antd/src/views/iot/device/device/detail/modules/sub-device.vue b/apps/web-antd/src/views/iot/device/device/detail/modules/sub-device.vue index 36d1fc372..8515630fa 100644 --- a/apps/web-antd/src/views/iot/device/device/detail/modules/sub-device.vue +++ b/apps/web-antd/src/views/iot/device/device/detail/modules/sub-device.vue @@ -317,6 +317,7 @@ watch( label: '添加子设备', type: 'primary', icon: ACTION_ICON.ADD, + auth: ['iot:device:update'], onClick: openAddModal, }, { @@ -324,6 +325,7 @@ watch( type: 'primary', danger: true, icon: ACTION_ICON.DELETE, + auth: ['iot:device:update'], disabled: isEmpty(checkedIds), onClick: handleUnbindBatch, }, @@ -342,6 +344,7 @@ watch( label: '解绑', type: 'link', danger: true, + auth: ['iot:device:update'], onClick: () => handleUnbind(row), }, ]" diff --git a/apps/web-antd/src/views/iot/device/device/detail/modules/thing-model-property.vue b/apps/web-antd/src/views/iot/device/device/detail/modules/thing-model-property.vue index c73ebe2d8..e0ce9dc6c 100644 --- a/apps/web-antd/src/views/iot/device/device/detail/modules/thing-model-property.vue +++ b/apps/web-antd/src/views/iot/device/device/detail/modules/thing-model-property.vue @@ -207,6 +207,13 @@ function handleQuery() { } } +/** 搜索关键词变化 */ +function handleKeywordChange(event: Event) { + if (!(event.target as HTMLInputElement).value) { + handleQuery(); + } +} + /** 视图切换 */ async function handleViewModeChange(mode: 'card' | 'list') { if (viewMode.value === mode) { @@ -281,6 +288,7 @@ onBeforeUnmount(() => { allow-clear placeholder="请输入属性名称、标识符" style="width: 240px" + @change="handleKeywordChange" @press-enter="handleQuery" />