Showing
20 changed files
with
471 additions
and
61 deletions
| @@ -90,7 +90,7 @@ | @@ -90,7 +90,7 @@ | ||
| 90 | ContactDrawer, | 90 | ContactDrawer, |
| 91 | }, | 91 | }, |
| 92 | setup() { | 92 | setup() { |
| 93 | - const selectArray: any = ref([]); | 93 | + let selectArray: any = []; |
| 94 | const hasBatchDelete = ref(true); | 94 | const hasBatchDelete = ref(true); |
| 95 | const searchInfo = reactive<Recordable>({}); | 95 | const searchInfo = reactive<Recordable>({}); |
| 96 | const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); | 96 | const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); |
| @@ -140,17 +140,19 @@ | @@ -140,17 +140,19 @@ | ||
| 140 | } | 140 | } |
| 141 | }; | 141 | }; |
| 142 | const useSelectionChange = () => { | 142 | const useSelectionChange = () => { |
| 143 | - selectArray.value = getSelectRows() | ||
| 144 | - .filter((f) => f.status !== 1) | ||
| 145 | - .map((m) => m.id); | ||
| 146 | - if (selectArray.value.length > 0) { | ||
| 147 | - hasBatchDelete.value = false; | ||
| 148 | - } else { | 143 | + let getRows = getSelectRows(); |
| 144 | + const isJudge = getRows.map((m) => m.status); | ||
| 145 | + if (isJudge.length === 0) { | ||
| 146 | + hasBatchDelete.value = true; | ||
| 147 | + } | ||
| 148 | + if (isJudge.includes(1) && isJudge.includes(0)) { | ||
| 149 | hasBatchDelete.value = true; | 149 | hasBatchDelete.value = true; |
| 150 | + } else if (isJudge.includes(1) && !isJudge.includes(0)) { | ||
| 151 | + hasBatchDelete.value = true; | ||
| 152 | + } else if (!isJudge.includes(1) && isJudge.includes(0)) { | ||
| 153 | + hasBatchDelete.value = false; | ||
| 150 | } | 154 | } |
| 151 | - // const isJude = getSelectRows().some((s) => { | ||
| 152 | - // if (s.status == 1) return createMessage.error('不能删除已经启用的,请选择未启用的'); | ||
| 153 | - // }); | 155 | + selectArray = getRows.filter((f) => f.status !== 1).map((m) => m.id); |
| 154 | }; | 156 | }; |
| 155 | // 删除或批量删除 | 157 | // 删除或批量删除 |
| 156 | const handleDeleteOrBatchDelete = async (record: Recordable | null) => { | 158 | const handleDeleteOrBatchDelete = async (record: Recordable | null) => { |
| @@ -159,18 +161,17 @@ | @@ -159,18 +161,17 @@ | ||
| 159 | await deleteAlarmConfig([record.id]); | 161 | await deleteAlarmConfig([record.id]); |
| 160 | createMessage.success('删除成功'); | 162 | createMessage.success('删除成功'); |
| 161 | handleSuccess(); | 163 | handleSuccess(); |
| 162 | - } catch (e: any) { | ||
| 163 | - createMessage.error(e.msg); | ||
| 164 | - } | 164 | + } catch (e: any) {} |
| 165 | } else { | 165 | } else { |
| 166 | try { | 166 | try { |
| 167 | - await deleteAlarmConfig(selectArray.value); | 167 | + await deleteAlarmConfig(selectArray); |
| 168 | createMessage.success('批量删除成功'); | 168 | createMessage.success('批量删除成功'); |
| 169 | handleSuccess(); | 169 | handleSuccess(); |
| 170 | - selectArray.value.length = 0; | 170 | + selectArray.length = 0; |
| 171 | } catch (e: any) { | 171 | } catch (e: any) { |
| 172 | - createMessage.error(e.msg); | ||
| 173 | - selectArray.value.length = 0; | 172 | + selectArray.length = 0; |
| 173 | + } finally { | ||
| 174 | + selectArray.length = 0; | ||
| 174 | } | 175 | } |
| 175 | } | 176 | } |
| 176 | }; | 177 | }; |
| @@ -77,6 +77,7 @@ export const formSchema: FormSchema[] = [ | @@ -77,6 +77,7 @@ export const formSchema: FormSchema[] = [ | ||
| 77 | { | 77 | { |
| 78 | field: 'organizationId', | 78 | field: 'organizationId', |
| 79 | label: '所属组织', | 79 | label: '所属组织', |
| 80 | + required: true, | ||
| 80 | component: 'ApiTreeSelect', | 81 | component: 'ApiTreeSelect', |
| 81 | componentProps: { | 82 | componentProps: { |
| 82 | api: async () => { | 83 | api: async () => { |
| @@ -6,6 +6,12 @@ import { DeviceTypeEnum, DeviceState } from '/@/api/device/model/deviceModel'; | @@ -6,6 +6,12 @@ import { DeviceTypeEnum, DeviceState } from '/@/api/device/model/deviceModel'; | ||
| 6 | // 表格列数据 | 6 | // 表格列数据 |
| 7 | export const columns: BasicColumn[] = [ | 7 | export const columns: BasicColumn[] = [ |
| 8 | { | 8 | { |
| 9 | + title: '设备图片', | ||
| 10 | + dataIndex: 'deviceInfo.avatar', | ||
| 11 | + width: 120, | ||
| 12 | + slots: { customRender: 'img' }, | ||
| 13 | + }, | ||
| 14 | + { | ||
| 9 | title: '设备名称', | 15 | title: '设备名称', |
| 10 | dataIndex: 'name', | 16 | dataIndex: 'name', |
| 11 | width: 120, | 17 | width: 120, |
| @@ -171,6 +171,7 @@ | @@ -171,6 +171,7 @@ | ||
| 171 | ]); | 171 | ]); |
| 172 | }; | 172 | }; |
| 173 | const handleOk = async () => { | 173 | const handleOk = async () => { |
| 174 | + const { createMessage } = useMessage(); | ||
| 174 | // 验证 | 175 | // 验证 |
| 175 | const valid = await validate(); | 176 | const valid = await validate(); |
| 176 | if (!valid) return; | 177 | if (!valid) return; |
| @@ -197,14 +198,17 @@ | @@ -197,14 +198,17 @@ | ||
| 197 | ? field.publicKey | 198 | ? field.publicKey |
| 198 | : null, | 199 | : null, |
| 199 | }; | 200 | }; |
| 200 | - | ||
| 201 | - await saveDeviceToken(editData); | ||
| 202 | - const { createMessage } = useMessage(); | ||
| 203 | - createMessage.success('修改设备凭证成功'); | ||
| 204 | - | ||
| 205 | - // 请求 | ||
| 206 | - closeModal(); | ||
| 207 | - handleCancel(); | 201 | + saveDeviceToken(editData) |
| 202 | + .then((res) => { | ||
| 203 | + if (!res) return; | ||
| 204 | + createMessage.success('修改设备凭证成功'); | ||
| 205 | + // 请求 | ||
| 206 | + closeModal(); | ||
| 207 | + handleCancel(); | ||
| 208 | + }) | ||
| 209 | + .catch((e) => { | ||
| 210 | + createMessage.error(e); | ||
| 211 | + }); | ||
| 208 | }; | 212 | }; |
| 209 | return { | 213 | return { |
| 210 | registerModal, | 214 | registerModal, |
| @@ -18,6 +18,20 @@ | @@ -18,6 +18,20 @@ | ||
| 18 | 批量删除 | 18 | 批量删除 |
| 19 | </a-button> | 19 | </a-button> |
| 20 | </template> | 20 | </template> |
| 21 | + <template #img="{ record }"> | ||
| 22 | + <TableImg | ||
| 23 | + :size="30" | ||
| 24 | + :showBadge="false" | ||
| 25 | + :simpleShow="true" | ||
| 26 | + :imgList=" | ||
| 27 | + typeof record.deviceInfo.avatar !== 'undefined' && | ||
| 28 | + record.deviceInfo.avatar !== '' && | ||
| 29 | + record.deviceInfo.avatar != null | ||
| 30 | + ? [record.deviceInfo.avatar] | ||
| 31 | + : null | ||
| 32 | + " | ||
| 33 | + /> | ||
| 34 | + </template> | ||
| 21 | <template #deviceProfile="{ record }"> | 35 | <template #deviceProfile="{ record }"> |
| 22 | <a-button type="link" class="ml-2" @click="goDeviceProfile(record.deviceProfile.name)"> | 36 | <a-button type="link" class="ml-2" @click="goDeviceProfile(record.deviceProfile.name)"> |
| 23 | {{ record.deviceProfile.name }} | 37 | {{ record.deviceProfile.name }} |
| @@ -83,13 +97,13 @@ | @@ -83,13 +97,13 @@ | ||
| 83 | { | 97 | { |
| 84 | label: '编辑', | 98 | label: '编辑', |
| 85 | icon: 'clarity:note-edit-line', | 99 | icon: 'clarity:note-edit-line', |
| 86 | - ifShow: authBtn(role), | 100 | + ifShow: authBtn(role) && record.customerId === undefined, |
| 87 | onClick: handleEdit.bind(null, record), | 101 | onClick: handleEdit.bind(null, record), |
| 88 | }, | 102 | }, |
| 89 | { | 103 | { |
| 90 | label: '删除', | 104 | label: '删除', |
| 91 | icon: 'ant-design:delete-outlined', | 105 | icon: 'ant-design:delete-outlined', |
| 92 | - ifShow: authBtn(role), | 106 | + ifShow: authBtn(role) && record.customerId === undefined, |
| 93 | color: 'error', | 107 | color: 'error', |
| 94 | popConfirm: { | 108 | popConfirm: { |
| 95 | title: '是否确认删除', | 109 | title: '是否确认删除', |
| @@ -109,7 +123,7 @@ | @@ -109,7 +123,7 @@ | ||
| 109 | <script lang="ts"> | 123 | <script lang="ts"> |
| 110 | import { defineComponent, reactive } from 'vue'; | 124 | import { defineComponent, reactive } from 'vue'; |
| 111 | import { DeviceState, DeviceTypeEnum } from '/@/api/device/model/deviceModel'; | 125 | import { DeviceState, DeviceTypeEnum } from '/@/api/device/model/deviceModel'; |
| 112 | - import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 126 | + import { BasicTable, useTable, TableAction, TableImg } from '/@/components/Table'; |
| 113 | import { columns, searchFormSchema } from './config/device.data'; | 127 | import { columns, searchFormSchema } from './config/device.data'; |
| 114 | import { Tag } from 'ant-design-vue'; | 128 | import { Tag } from 'ant-design-vue'; |
| 115 | import { | 129 | import { |
| @@ -145,6 +159,7 @@ | @@ -145,6 +159,7 @@ | ||
| 145 | DeviceModal, | 159 | DeviceModal, |
| 146 | DeviceDetailDrawer, | 160 | DeviceDetailDrawer, |
| 147 | CustomerModal, | 161 | CustomerModal, |
| 162 | + TableImg, | ||
| 148 | }, | 163 | }, |
| 149 | setup(_) { | 164 | setup(_) { |
| 150 | const go = useGo(); | 165 | const go = useGo(); |
| @@ -167,11 +167,17 @@ | @@ -167,11 +167,17 @@ | ||
| 167 | if (isUpdate.value == 1) { | 167 | if (isUpdate.value == 1) { |
| 168 | delete postDeviceConfogData.id; | 168 | delete postDeviceConfogData.id; |
| 169 | } | 169 | } |
| 170 | - await deviceConfigAddOrEdit(postDeviceConfogData); | ||
| 171 | - createMessage.success(isUpdate.value == 1 ? '新增' + '成功' : '编辑' + '成功'); | ||
| 172 | - closeModal(); | ||
| 173 | - emit('success'); | ||
| 174 | - isNextStatus.value = false; | 170 | + deviceConfigAddOrEdit(postDeviceConfogData) |
| 171 | + .then((res) => { | ||
| 172 | + if (!res) return; | ||
| 173 | + createMessage.success(isUpdate.value == 1 ? '新增' + '成功' : '编辑' + '成功'); | ||
| 174 | + closeModal(); | ||
| 175 | + emit('success'); | ||
| 176 | + isNextStatus.value = false; | ||
| 177 | + }) | ||
| 178 | + .catch((e) => { | ||
| 179 | + createMessage.error(e); | ||
| 180 | + }); | ||
| 175 | }; | 181 | }; |
| 176 | const handleCancel = () => { | 182 | const handleCancel = () => { |
| 177 | nextTick(() => { | 183 | nextTick(() => { |
| @@ -6,6 +6,12 @@ import { numberRule } from '/@/utils/rules'; | @@ -6,6 +6,12 @@ import { numberRule } from '/@/utils/rules'; | ||
| 6 | 6 | ||
| 7 | export const columns: BasicColumn[] = [ | 7 | export const columns: BasicColumn[] = [ |
| 8 | { | 8 | { |
| 9 | + title: '配置图片', //图标 | ||
| 10 | + dataIndex: 'image', | ||
| 11 | + width: 80, | ||
| 12 | + slots: { customRender: 'img' }, | ||
| 13 | + }, | ||
| 14 | + { | ||
| 9 | title: '名称', | 15 | title: '名称', |
| 10 | dataIndex: 'name', | 16 | dataIndex: 'name', |
| 11 | width: 120, | 17 | width: 120, |
| @@ -15,6 +15,18 @@ | @@ -15,6 +15,18 @@ | ||
| 15 | 批量删除 | 15 | 批量删除 |
| 16 | </a-button> | 16 | </a-button> |
| 17 | </template> | 17 | </template> |
| 18 | + <template #img="{ record }"> | ||
| 19 | + <TableImg | ||
| 20 | + :size="30" | ||
| 21 | + :showBadge="false" | ||
| 22 | + :simpleShow="true" | ||
| 23 | + :imgList=" | ||
| 24 | + typeof record.image !== 'undefined' && record.image !== '' && record.image != null | ||
| 25 | + ? [record.image] | ||
| 26 | + : null | ||
| 27 | + " | ||
| 28 | + /> | ||
| 29 | + </template> | ||
| 18 | <template #action="{ record }"> | 30 | <template #action="{ record }"> |
| 19 | <TableAction | 31 | <TableAction |
| 20 | :actions="[ | 32 | :actions="[ |
| @@ -62,8 +74,8 @@ | @@ -62,8 +74,8 @@ | ||
| 62 | </div> | 74 | </div> |
| 63 | </template> | 75 | </template> |
| 64 | <script lang="ts"> | 76 | <script lang="ts"> |
| 65 | - import { defineComponent, ref, reactive, nextTick, onUnmounted } from 'vue'; | ||
| 66 | - import { BasicTable, useTable, TableAction, BasicColumn } from '/@/components/Table'; | 77 | + import { defineComponent, ref, nextTick, onUnmounted } from 'vue'; |
| 78 | + import { BasicTable, TableImg, useTable, TableAction, BasicColumn } from '/@/components/Table'; | ||
| 67 | import { columns, searchFormSchema } from './device.profile.data'; | 79 | import { columns, searchFormSchema } from './device.profile.data'; |
| 68 | import { useMessage } from '/@/hooks/web/useMessage'; | 80 | import { useMessage } from '/@/hooks/web/useMessage'; |
| 69 | import { | 81 | import { |
| @@ -78,22 +90,24 @@ | @@ -78,22 +90,24 @@ | ||
| 78 | 90 | ||
| 79 | export default defineComponent({ | 91 | export default defineComponent({ |
| 80 | name: 'DeviceProfileManagement', | 92 | name: 'DeviceProfileManagement', |
| 81 | - components: { BasicTable, DeviceProfileModal, TableAction, ImpExcel }, | 93 | + components: { BasicTable, DeviceProfileModal, TableAction, ImpExcel, TableImg }, |
| 82 | setup() { | 94 | setup() { |
| 83 | const deviceDetailRef = ref(null); | 95 | const deviceDetailRef = ref(null); |
| 84 | - let selectedRowKeys: string[] = reactive([]); | 96 | + let selectedRowKeys: any = []; |
| 85 | const getPathUrl = ref(''); | 97 | const getPathUrl = ref(''); |
| 86 | const getPathUrlName = ref(''); | 98 | const getPathUrlName = ref(''); |
| 87 | const disabled = ref(true); | 99 | const disabled = ref(true); |
| 88 | const onCloseVal = ref(0); | 100 | const onCloseVal = ref(0); |
| 101 | + const immediateStatus = ref(false); | ||
| 89 | 102 | ||
| 90 | const { createMessage } = useMessage(); | 103 | const { createMessage } = useMessage(); |
| 91 | const [registerModal, { openModal }] = useModal(); | 104 | const [registerModal, { openModal }] = useModal(); |
| 92 | const [registerModalDetail] = useModal(); | 105 | const [registerModalDetail] = useModal(); |
| 93 | - const [registerTable, { reload, getSelectRowKeys, setTableData, getForm }] = useTable({ | 106 | + const [registerTable, { reload, getSelectRows, setTableData, getForm }] = useTable({ |
| 94 | title: '设备配置列表', | 107 | title: '设备配置列表', |
| 95 | clickToRowSelect: false, | 108 | clickToRowSelect: false, |
| 96 | api: deviceConfigGetQuery, | 109 | api: deviceConfigGetQuery, |
| 110 | + immediate: immediateStatus.value, | ||
| 97 | columns, | 111 | columns, |
| 98 | formConfig: { | 112 | formConfig: { |
| 99 | labelWidth: 120, | 113 | labelWidth: 120, |
| @@ -150,12 +164,13 @@ | @@ -150,12 +164,13 @@ | ||
| 150 | resetFields(); | 164 | resetFields(); |
| 151 | } | 165 | } |
| 152 | }); | 166 | }); |
| 167 | + } else { | ||
| 168 | + setTimeout(() => { | ||
| 169 | + reload(); | ||
| 170 | + }, 80); | ||
| 153 | } | 171 | } |
| 154 | }; | 172 | }; |
| 155 | - setTimeout(() => { | ||
| 156 | - setRowClassName(); | ||
| 157 | - }, 500); | ||
| 158 | - | 173 | + setRowClassName(); |
| 159 | onUnmounted(() => { | 174 | onUnmounted(() => { |
| 160 | getPathUrlName.value = ''; | 175 | getPathUrlName.value = ''; |
| 161 | onCloseVal.value = 1; | 176 | onCloseVal.value = 1; |
| @@ -212,7 +227,7 @@ | @@ -212,7 +227,7 @@ | ||
| 212 | }, 10); | 227 | }, 10); |
| 213 | } | 228 | } |
| 214 | const useSelectionChange = () => { | 229 | const useSelectionChange = () => { |
| 215 | - selectedRowKeys = getSelectRowKeys(); | 230 | + selectedRowKeys = getSelectRows(); |
| 216 | if (selectedRowKeys.length > 0) { | 231 | if (selectedRowKeys.length > 0) { |
| 217 | disabled.value = false; | 232 | disabled.value = false; |
| 218 | } else { | 233 | } else { |
| @@ -220,6 +235,9 @@ | @@ -220,6 +235,9 @@ | ||
| 220 | } | 235 | } |
| 221 | }; | 236 | }; |
| 222 | async function handleTableDel() { | 237 | async function handleTableDel() { |
| 238 | + selectedRowKeys = selectedRowKeys | ||
| 239 | + .filter((f: any) => f.default !== true) | ||
| 240 | + .map((m: any) => m.id); | ||
| 223 | await deviceConfigDelete(selectedRowKeys); | 241 | await deviceConfigDelete(selectedRowKeys); |
| 224 | createMessage.success('删除成功'); | 242 | createMessage.success('删除成功'); |
| 225 | handleSuccess(); | 243 | handleSuccess(); |
| @@ -91,7 +91,7 @@ | @@ -91,7 +91,7 @@ | ||
| 91 | } | 91 | } |
| 92 | const isLt2M = (file.size as number) / 1024 / 1024 < 2; | 92 | const isLt2M = (file.size as number) / 1024 / 1024 < 2; |
| 93 | if (!isLt2M) { | 93 | if (!isLt2M) { |
| 94 | - createMessage.error('图片大小不能超过5MB!'); | 94 | + createMessage.error('图片大小不能超过2MB!'); |
| 95 | } | 95 | } |
| 96 | return isJpgOrPng && isLt2M; | 96 | return isJpgOrPng && isLt2M; |
| 97 | }; | 97 | }; |
| @@ -11,6 +11,9 @@ | @@ -11,6 +11,9 @@ | ||
| 11 | <div v-else-if="isMqttType == 'LWM2M'"> | 11 | <div v-else-if="isMqttType == 'LWM2M'"> |
| 12 | <Lwm2mCpns ref="lwm2mRef" /> | 12 | <Lwm2mCpns ref="lwm2mRef" /> |
| 13 | </div> | 13 | </div> |
| 14 | + <div v-else-if="isMqttType == 'SNMP1'"> | ||
| 15 | + <SnmpCpns ref="snmpRef" /> | ||
| 16 | + </div> | ||
| 14 | <div | 17 | <div |
| 15 | style=" | 18 | style=" |
| 16 | display: flex; | 19 | display: flex; |
| @@ -40,6 +43,7 @@ | @@ -40,6 +43,7 @@ | ||
| 40 | import MqttCpns from '../step/cpns/mqtt/Mqtt.vue'; | 43 | import MqttCpns from '../step/cpns/mqtt/Mqtt.vue'; |
| 41 | import CoapCpns from '../step/cpns/coap/Coap.vue'; | 44 | import CoapCpns from '../step/cpns/coap/Coap.vue'; |
| 42 | import Lwm2mCpns from '../step/cpns/lwm2m/index.vue'; | 45 | import Lwm2mCpns from '../step/cpns/lwm2m/index.vue'; |
| 46 | + import SnmpCpns from '../step/cpns/snmp/index.vue'; | ||
| 43 | 47 | ||
| 44 | export default defineComponent({ | 48 | export default defineComponent({ |
| 45 | components: { | 49 | components: { |
| @@ -52,6 +56,7 @@ | @@ -52,6 +56,7 @@ | ||
| 52 | MqttCpns, | 56 | MqttCpns, |
| 53 | CoapCpns, | 57 | CoapCpns, |
| 54 | Lwm2mCpns, | 58 | Lwm2mCpns, |
| 59 | + SnmpCpns, | ||
| 55 | }, | 60 | }, |
| 56 | emits: ['next', 'prev', 'register'], | 61 | emits: ['next', 'prev', 'register'], |
| 57 | setup(_, { emit }) { | 62 | setup(_, { emit }) { |
| @@ -59,6 +64,7 @@ | @@ -59,6 +64,7 @@ | ||
| 59 | const mqttRef = ref(null); | 64 | const mqttRef = ref(null); |
| 60 | const coapRef = ref(null); | 65 | const coapRef = ref(null); |
| 61 | const lwm2mRef = ref(null); | 66 | const lwm2mRef = ref(null); |
| 67 | + const snmpRef = ref(null); | ||
| 62 | const isMqttType = ref(''); | 68 | const isMqttType = ref(''); |
| 63 | let step2Data = reactive({ | 69 | let step2Data = reactive({ |
| 64 | transportConfiguration: {}, | 70 | transportConfiguration: {}, |
| @@ -104,6 +110,7 @@ | @@ -104,6 +110,7 @@ | ||
| 104 | { label: 'MQTT', value: 'MQTT' }, | 110 | { label: 'MQTT', value: 'MQTT' }, |
| 105 | { label: 'CoAP', value: 'COAP' }, | 111 | { label: 'CoAP', value: 'COAP' }, |
| 106 | { label: 'LWM2M', value: 'LWM2M' }, | 112 | { label: 'LWM2M', value: 'LWM2M' }, |
| 113 | + // { label: 'SNMP', value: 'SNMP' }, | ||
| 107 | ], | 114 | ], |
| 108 | onChange(e) { | 115 | onChange(e) { |
| 109 | isMqttType.value = e; | 116 | isMqttType.value = e; |
| @@ -139,6 +146,7 @@ | @@ -139,6 +146,7 @@ | ||
| 139 | mqttRef, | 146 | mqttRef, |
| 140 | coapRef, | 147 | coapRef, |
| 141 | lwm2mRef, | 148 | lwm2mRef, |
| 149 | + snmpRef, | ||
| 142 | }; | 150 | }; |
| 143 | }, | 151 | }, |
| 144 | }); | 152 | }); |
| @@ -498,6 +498,7 @@ export const deviceSchemas: FormSchema[] = [ | @@ -498,6 +498,7 @@ export const deviceSchemas: FormSchema[] = [ | ||
| 498 | colProps: { span: 22 }, | 498 | colProps: { span: 22 }, |
| 499 | component: 'InputTextArea', | 499 | component: 'InputTextArea', |
| 500 | componentProps: { | 500 | componentProps: { |
| 501 | + disabled: true, | ||
| 501 | autoSize: { | 502 | autoSize: { |
| 502 | maxRows: 50, | 503 | maxRows: 50, |
| 503 | }, | 504 | }, |
| @@ -78,6 +78,7 @@ | @@ -78,6 +78,7 @@ | ||
| 78 | observe: [], | 78 | observe: [], |
| 79 | telemetry: [], | 79 | telemetry: [], |
| 80 | }); | 80 | }); |
| 81 | + | ||
| 81 | const [ | 82 | const [ |
| 82 | registerModel, | 83 | registerModel, |
| 83 | { resetFields: resetObjectListValue, getFieldsValue: getObjectListValue }, | 84 | { resetFields: resetObjectListValue, getFieldsValue: getObjectListValue }, |
| 1 | +<template> | ||
| 2 | + <div style="display: flex; flex-direction: row; width: 30vw"> | ||
| 3 | + <div style="width: 9vw"> | ||
| 4 | + <BasicForm | ||
| 5 | + :showResetButton="false" | ||
| 6 | + :showSubmitButton="false" | ||
| 7 | + @register="registerRightSelect" | ||
| 8 | + /> | ||
| 9 | + </div> | ||
| 10 | + <div style="width: 20vw"> | ||
| 11 | + <BasicForm :showResetButton="false" :showSubmitButton="false" @register="registerRightInput" | ||
| 12 | + /></div> | ||
| 13 | + <div style="width: 1vw; margin-left: -0.8vw"> | ||
| 14 | + <span @click="handleDelScopeAndKeyAndVal" style="color: red; cursor: pointer">X</span> | ||
| 15 | + </div> | ||
| 16 | + </div> | ||
| 17 | +</template> | ||
| 18 | +<script lang="ts"> | ||
| 19 | + import { defineComponent } from 'vue'; | ||
| 20 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
| 21 | + import { snmpRightSelectSchemas, snmpRightInputSchemas } from '../index'; | ||
| 22 | + | ||
| 23 | + export default defineComponent({ | ||
| 24 | + components: { | ||
| 25 | + BasicForm, | ||
| 26 | + }, | ||
| 27 | + | ||
| 28 | + emits: ['next', 'prev', 'register', 'clear'], | ||
| 29 | + setup(_, { emit }) { | ||
| 30 | + const [registerRightSelect] = useForm({ | ||
| 31 | + labelWidth: 80, | ||
| 32 | + schemas: snmpRightSelectSchemas, | ||
| 33 | + actionColOptions: { | ||
| 34 | + span: 14, | ||
| 35 | + }, | ||
| 36 | + }); | ||
| 37 | + const [registerRightInput] = useForm({ | ||
| 38 | + labelWidth: 80, | ||
| 39 | + schemas: snmpRightInputSchemas, | ||
| 40 | + actionColOptions: { | ||
| 41 | + span: 14, | ||
| 42 | + }, | ||
| 43 | + }); | ||
| 44 | + const handleDelScopeAndKeyAndVal = () => { | ||
| 45 | + emit('clear'); | ||
| 46 | + }; | ||
| 47 | + return { | ||
| 48 | + registerRightSelect, | ||
| 49 | + registerRightInput, | ||
| 50 | + handleDelScopeAndKeyAndVal, | ||
| 51 | + }; | ||
| 52 | + }, | ||
| 53 | + }); | ||
| 54 | +</script> | ||
| 55 | +<style lang="less" scoped></style> |
| 1 | +import { FormSchema } from '/@/components/Form'; | ||
| 2 | + | ||
| 3 | +export const snmpSchemas: FormSchema[] = [ | ||
| 4 | + { | ||
| 5 | + field: 'timeoutMs', | ||
| 6 | + component: 'InputNumber', | ||
| 7 | + label: 'Timeout,ns', | ||
| 8 | + required: true, | ||
| 9 | + defaultValue: 500, | ||
| 10 | + colProps: { span: 11 }, | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + field: 'retries', | ||
| 14 | + component: 'InputNumber', | ||
| 15 | + label: 'Retries', | ||
| 16 | + required: true, | ||
| 17 | + defaultValue: 0, | ||
| 18 | + colProps: { span: 11 }, | ||
| 19 | + }, | ||
| 20 | + { | ||
| 21 | + field: 'noknown', | ||
| 22 | + component: 'Input', | ||
| 23 | + label: '', | ||
| 24 | + slot: 'add', | ||
| 25 | + colProps: { span: 11 }, | ||
| 26 | + }, | ||
| 27 | +]; | ||
| 28 | + | ||
| 29 | +export const snmpLeftSchemas: FormSchema[] = [ | ||
| 30 | + { | ||
| 31 | + field: 'spec', | ||
| 32 | + component: 'Select', | ||
| 33 | + label: 'Scope', | ||
| 34 | + defaultValue: 'CLIENT_ATTRIBUTES_QUERYING', | ||
| 35 | + componentProps: { | ||
| 36 | + options: [ | ||
| 37 | + { | ||
| 38 | + label: 'Telemetry', | ||
| 39 | + value: 'TELEMETRY_QUERYING', | ||
| 40 | + }, | ||
| 41 | + { | ||
| 42 | + label: 'Client attributes', | ||
| 43 | + value: 'CLIENT_ATTRIBUTES_QUERYING', | ||
| 44 | + }, | ||
| 45 | + { | ||
| 46 | + label: 'Shared attributes', | ||
| 47 | + value: 'SHARED_ATTRIBUTES_SETTING', | ||
| 48 | + }, | ||
| 49 | + { | ||
| 50 | + label: 'RPC request', | ||
| 51 | + value: 'TO_DEVICE_RPC_REQUEST', | ||
| 52 | + }, | ||
| 53 | + ], | ||
| 54 | + }, | ||
| 55 | + colProps: { span: 11 }, | ||
| 56 | + }, | ||
| 57 | +]; | ||
| 58 | + | ||
| 59 | +export const snmpRightSchemas: FormSchema[] = [ | ||
| 60 | + { | ||
| 61 | + field: 'queryingFrequencyMs', | ||
| 62 | + component: 'InputNumber', | ||
| 63 | + label: '查询频率,毫秒', | ||
| 64 | + required: true, | ||
| 65 | + defaultValue: 5000, | ||
| 66 | + colProps: { span: 22 }, | ||
| 67 | + }, | ||
| 68 | +]; | ||
| 69 | + | ||
| 70 | +export const snmpRightSelectSchemas: FormSchema[] = [ | ||
| 71 | + { | ||
| 72 | + field: 'dataType', | ||
| 73 | + component: 'Select', | ||
| 74 | + label: 'Type', | ||
| 75 | + defaultValue: '字符串', | ||
| 76 | + componentProps: { | ||
| 77 | + options: [ | ||
| 78 | + { | ||
| 79 | + label: '字符串', | ||
| 80 | + value: '字符串', | ||
| 81 | + }, | ||
| 82 | + { | ||
| 83 | + label: '数字', | ||
| 84 | + value: '数字', | ||
| 85 | + }, | ||
| 86 | + { | ||
| 87 | + label: '布尔值', | ||
| 88 | + value: '布尔值', | ||
| 89 | + }, | ||
| 90 | + { | ||
| 91 | + label: '双精度小数', | ||
| 92 | + value: '双精度小数', | ||
| 93 | + }, | ||
| 94 | + { | ||
| 95 | + label: 'JSON', | ||
| 96 | + value: 'JSON', | ||
| 97 | + }, | ||
| 98 | + ], | ||
| 99 | + }, | ||
| 100 | + colProps: { span: 11 }, | ||
| 101 | + }, | ||
| 102 | +]; | ||
| 103 | + | ||
| 104 | +export const snmpRightInputSchemas: FormSchema[] = [ | ||
| 105 | + { | ||
| 106 | + field: 'key', | ||
| 107 | + component: 'Input', | ||
| 108 | + label: 'Data key', | ||
| 109 | + required: true, | ||
| 110 | + colProps: { span: 11 }, | ||
| 111 | + }, | ||
| 112 | + { | ||
| 113 | + field: 'oid', | ||
| 114 | + component: 'Input', | ||
| 115 | + label: 'OID', | ||
| 116 | + required: true, | ||
| 117 | + colProps: { span: 11 }, | ||
| 118 | + }, | ||
| 119 | +]; |
| 1 | +<template> | ||
| 2 | + <div | ||
| 3 | + style=" | ||
| 4 | + margin-top: -5vh; | ||
| 5 | + border: 0.5px solid gray; | ||
| 6 | + margin-left: 0.1vw; | ||
| 7 | + border-radius: 5px; | ||
| 8 | + padding-left: 1.5vw; | ||
| 9 | + " | ||
| 10 | + > | ||
| 11 | + <div style="margin-top: 1.2vh"> | ||
| 12 | + <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register"> | ||
| 13 | + <template #add> | ||
| 14 | + <div> | ||
| 15 | + <template v-for="(item, index) in scopeData" :key="item.id1"> | ||
| 16 | + <span style="display: none">{{ item }}</span> | ||
| 17 | + <div | ||
| 18 | + style=" | ||
| 19 | + display: flex; | ||
| 20 | + width: 45vw; | ||
| 21 | + flex-direction: row; | ||
| 22 | + border: 0.5px solid gray; | ||
| 23 | + border-radius: 5px; | ||
| 24 | + margin-left: -1.5vw; | ||
| 25 | + " | ||
| 26 | + > | ||
| 27 | + <div | ||
| 28 | + style=" | ||
| 29 | + width: 14vw; | ||
| 30 | + border: 0.5px solid gray; | ||
| 31 | + border-radius: 5px; | ||
| 32 | + margin-left: -2vw; | ||
| 33 | + " | ||
| 34 | + > | ||
| 35 | + <BasicForm | ||
| 36 | + :showResetButton="false" | ||
| 37 | + :showSubmitButton="false" | ||
| 38 | + @register="registerLeft" | ||
| 39 | + /> | ||
| 40 | + </div> | ||
| 41 | + <div style="width: 29.3vw; border: 0.5px solid gray; border-radius: 5px"> | ||
| 42 | + <BasicForm | ||
| 43 | + :showResetButton="false" | ||
| 44 | + :showSubmitButton="false" | ||
| 45 | + @register="registerRight" | ||
| 46 | + /> | ||
| 47 | + <div> | ||
| 48 | + <template v-for="(item1, index1) in item.mappings" :key="item1.id2"> | ||
| 49 | + <span style="display: none">{{ index1 }}</span> | ||
| 50 | + <span style="display: none">{{ item1 }}</span> | ||
| 51 | + <KeyAndValVue @clear="clearFun(index, index1)" /> | ||
| 52 | + </template> | ||
| 53 | + <div | ||
| 54 | + style=" | ||
| 55 | + margin-top: -3.8vh; | ||
| 56 | + margin-left: 2.3vw; | ||
| 57 | + position: relative; | ||
| 58 | + top: -1.5vh; | ||
| 59 | + " | ||
| 60 | + > | ||
| 61 | + <a-button size="small" type="default" @click="handleAddMapping(index)"> | ||
| 62 | + Add mapping | ||
| 63 | + </a-button> | ||
| 64 | + </div> | ||
| 65 | + </div> | ||
| 66 | + </div> | ||
| 67 | + <div style="width: 1vw; margin-top: 8.5vh; margin-left: 0.5vw"> | ||
| 68 | + <span @click="handleDelScope(index)" style="color: red; cursor: pointer">X</span> | ||
| 69 | + </div> | ||
| 70 | + </div> | ||
| 71 | + <div style="height: 2vh"></div> | ||
| 72 | + </template> | ||
| 73 | + <div style="margin-left: -1vw"> | ||
| 74 | + <a-button size="small" type="default" @click="handleAddScope"> | ||
| 75 | + Add communication config | ||
| 76 | + </a-button> | ||
| 77 | + </div> | ||
| 78 | + </div> | ||
| 79 | + </template> | ||
| 80 | + </BasicForm> | ||
| 81 | + </div> | ||
| 82 | + </div> | ||
| 83 | +</template> | ||
| 84 | +<script lang="ts"> | ||
| 85 | + import { defineComponent, ref } from 'vue'; | ||
| 86 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
| 87 | + import { snmpSchemas, snmpLeftSchemas, snmpRightSchemas } from './index'; | ||
| 88 | + import { Alert, Divider, Descriptions } from 'ant-design-vue'; | ||
| 89 | + import KeyAndValVue from './cpns/KeyAndVal.vue'; | ||
| 90 | + | ||
| 91 | + export default defineComponent({ | ||
| 92 | + components: { | ||
| 93 | + BasicForm, | ||
| 94 | + [Alert.name]: Alert, | ||
| 95 | + [Divider.name]: Divider, | ||
| 96 | + [Descriptions.name]: Descriptions, | ||
| 97 | + [Descriptions.Item.name]: Descriptions.Item, | ||
| 98 | + KeyAndValVue, | ||
| 99 | + }, | ||
| 100 | + | ||
| 101 | + emits: ['next', 'prev', 'register'], | ||
| 102 | + setup() { | ||
| 103 | + const scopeData: any = ref([ | ||
| 104 | + { | ||
| 105 | + id1: 1, | ||
| 106 | + mappings: [ | ||
| 107 | + { | ||
| 108 | + id2: 2, | ||
| 109 | + }, | ||
| 110 | + ], | ||
| 111 | + }, | ||
| 112 | + ]); | ||
| 113 | + | ||
| 114 | + const [register] = useForm({ | ||
| 115 | + labelWidth: 150, | ||
| 116 | + schemas: snmpSchemas, | ||
| 117 | + actionColOptions: { | ||
| 118 | + span: 14, | ||
| 119 | + }, | ||
| 120 | + }); | ||
| 121 | + const [registerLeft] = useForm({ | ||
| 122 | + labelWidth: 100, | ||
| 123 | + schemas: snmpLeftSchemas, | ||
| 124 | + actionColOptions: { | ||
| 125 | + span: 14, | ||
| 126 | + }, | ||
| 127 | + }); | ||
| 128 | + const [registerRight] = useForm({ | ||
| 129 | + labelWidth: 150, | ||
| 130 | + schemas: snmpRightSchemas, | ||
| 131 | + actionColOptions: { | ||
| 132 | + span: 14, | ||
| 133 | + }, | ||
| 134 | + }); | ||
| 135 | + | ||
| 136 | + const handleAddMapping = (i) => { | ||
| 137 | + scopeData.value[i].mappings.push({ | ||
| 138 | + id2: Date.now() + 3, | ||
| 139 | + }); | ||
| 140 | + }; | ||
| 141 | + const clearFun = (i1, i2) => { | ||
| 142 | + scopeData.value[i1].mappings.splice(i2, 1); | ||
| 143 | + }; | ||
| 144 | + | ||
| 145 | + const handleDelScope = (i) => { | ||
| 146 | + scopeData.value.splice(i, 1); | ||
| 147 | + }; | ||
| 148 | + | ||
| 149 | + const handleAddScope = () => { | ||
| 150 | + if (scopeData.value.length < 4) { | ||
| 151 | + scopeData.value.push({ | ||
| 152 | + id1: Date.now() + 1, | ||
| 153 | + mappings: [ | ||
| 154 | + { | ||
| 155 | + id2: Date.now() + 2, | ||
| 156 | + }, | ||
| 157 | + ], | ||
| 158 | + }); | ||
| 159 | + } | ||
| 160 | + }; | ||
| 161 | + | ||
| 162 | + return { | ||
| 163 | + register, | ||
| 164 | + registerLeft, | ||
| 165 | + registerRight, | ||
| 166 | + handleAddMapping, | ||
| 167 | + scopeData, | ||
| 168 | + handleDelScope, | ||
| 169 | + handleAddScope, | ||
| 170 | + clearFun, | ||
| 171 | + }; | ||
| 172 | + }, | ||
| 173 | + }); | ||
| 174 | +</script> | ||
| 175 | +<style lang="less" scoped></style> |
| @@ -78,6 +78,7 @@ export const step2Schemas: FormSchema[] = [ | @@ -78,6 +78,7 @@ export const step2Schemas: FormSchema[] = [ | ||
| 78 | { label: 'MQTT', value: 'MQTT' }, | 78 | { label: 'MQTT', value: 'MQTT' }, |
| 79 | { label: 'CoAP', value: 'COAP' }, | 79 | { label: 'CoAP', value: 'COAP' }, |
| 80 | { label: 'LWM2M', value: 'LWM2M' }, | 80 | { label: 'LWM2M', value: 'LWM2M' }, |
| 81 | + // { label: 'SNMP', value: 'SNMP' }, | ||
| 81 | ], | 82 | ], |
| 82 | onChange(e) {}, | 83 | onChange(e) {}, |
| 83 | }; | 84 | }; |
| @@ -15,7 +15,8 @@ | @@ -15,7 +15,8 @@ | ||
| 15 | icon: 'ant-design:eye-outlined', | 15 | icon: 'ant-design:eye-outlined', |
| 16 | onClick: handleView.bind(null, record), | 16 | onClick: handleView.bind(null, record), |
| 17 | ifShow: (_action) => { | 17 | ifShow: (_action) => { |
| 18 | - return record.status === 1 && rolePermission == 'CUSTOMER_USER'; | 18 | + const isCurrent = record.status === 1 && record.creator === userId; |
| 19 | + return isCurrent; | ||
| 19 | }, | 20 | }, |
| 20 | }, | 21 | }, |
| 21 | { | 22 | { |
| @@ -23,14 +24,15 @@ | @@ -23,14 +24,15 @@ | ||
| 23 | icon: 'clarity:note-edit-line', | 24 | icon: 'clarity:note-edit-line', |
| 24 | onClick: handleEdit.bind(null, record), | 25 | onClick: handleEdit.bind(null, record), |
| 25 | ifShow: (_action) => { | 26 | ifShow: (_action) => { |
| 26 | - return record.status === 0 && record.creator == userId; | 27 | + const isCurrent = record.status === 0 && record.creator === userId; |
| 28 | + return isCurrent; | ||
| 27 | }, | 29 | }, |
| 28 | }, | 30 | }, |
| 29 | { | 31 | { |
| 30 | label: '删除', | 32 | label: '删除', |
| 31 | icon: 'ant-design:delete-outlined', | 33 | icon: 'ant-design:delete-outlined', |
| 32 | color: 'error', | 34 | color: 'error', |
| 33 | - ifShow: record.creator == userId, | 35 | + ifShow: record.creator === userId, |
| 34 | popConfirm: { | 36 | popConfirm: { |
| 35 | title: '是否确认删除', | 37 | title: '是否确认删除', |
| 36 | confirm: handleDeleteOrBatchDelete.bind(null, record), | 38 | confirm: handleDeleteOrBatchDelete.bind(null, record), |
| @@ -49,7 +51,7 @@ | @@ -49,7 +51,7 @@ | ||
| 49 | </div> | 51 | </div> |
| 50 | </template> | 52 | </template> |
| 51 | <script lang="ts"> | 53 | <script lang="ts"> |
| 52 | - import { defineComponent, ref, computed } from 'vue'; | 54 | + import { defineComponent, ref } from 'vue'; |
| 53 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 55 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
| 54 | import { useDrawer } from '/@/components/Drawer'; | 56 | import { useDrawer } from '/@/components/Drawer'; |
| 55 | import NotifyManagerDrawer from './useDrawer.vue'; | 57 | import NotifyManagerDrawer from './useDrawer.vue'; |
| @@ -59,22 +61,14 @@ | @@ -59,22 +61,14 @@ | ||
| 59 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | 61 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; |
| 60 | import { USER_INFO_KEY } from '/@/enums/cacheEnum'; | 62 | import { USER_INFO_KEY } from '/@/enums/cacheEnum'; |
| 61 | import { getAuthCache } from '/@/utils/auth'; | 63 | import { getAuthCache } from '/@/utils/auth'; |
| 62 | - import { RoleEnum } from '/@/enums/roleEnum'; | ||
| 63 | - import { usePermission } from '/@/hooks/web/usePermission'; | ||
| 64 | - import { useUserStore } from '/@/store/modules/user'; | ||
| 65 | 64 | ||
| 66 | export default defineComponent({ | 65 | export default defineComponent({ |
| 67 | name: 'Notificationmannager', | 66 | name: 'Notificationmannager', |
| 68 | components: { BasicTable, NotifyManagerDrawer, TableAction, tableViewChild }, | 67 | components: { BasicTable, NotifyManagerDrawer, TableAction, tableViewChild }, |
| 69 | setup() { | 68 | setup() { |
| 70 | - const { hasPermission } = usePermission(); | ||
| 71 | - const userStore = useUserStore(); | ||
| 72 | - const isTenant = computed(() => userStore.getRoleList.includes(RoleEnum.TENANT_ADMIN)); | ||
| 73 | - const isCustomer = computed(() => userStore.getRoleList.includes(RoleEnum.CUSTOMER_USER)); | ||
| 74 | const userInfo: any = getAuthCache(USER_INFO_KEY); | 69 | const userInfo: any = getAuthCache(USER_INFO_KEY); |
| 75 | const userId = userInfo.userId; | 70 | const userId = userInfo.userId; |
| 76 | const tenantId = userInfo.tenantId; | 71 | const tenantId = userInfo.tenantId; |
| 77 | - const rolePermission: string = userInfo.roles[0]; | ||
| 78 | const [registerDrawer, { openDrawer }] = useDrawer(); | 72 | const [registerDrawer, { openDrawer }] = useDrawer(); |
| 79 | const [registerAdd, { openDrawer: openDrawerAdd }] = useDrawer(); | 73 | const [registerAdd, { openDrawer: openDrawerAdd }] = useDrawer(); |
| 80 | // 批量删除 | 74 | // 批量删除 |
| @@ -137,12 +131,8 @@ | @@ -137,12 +131,8 @@ | ||
| 137 | handleSuccess, | 131 | handleSuccess, |
| 138 | handleDeleteOrBatchDelete, | 132 | handleDeleteOrBatchDelete, |
| 139 | NotifyManagerDrawerRef, | 133 | NotifyManagerDrawerRef, |
| 140 | - rolePermission, | ||
| 141 | userId, | 134 | userId, |
| 142 | tenantId, | 135 | tenantId, |
| 143 | - hasPermission, | ||
| 144 | - isTenant, | ||
| 145 | - isCustomer, | ||
| 146 | }; | 136 | }; |
| 147 | }, | 137 | }, |
| 148 | }); | 138 | }); |
| @@ -46,7 +46,7 @@ | @@ -46,7 +46,7 @@ | ||
| 46 | //编辑 | 46 | //编辑 |
| 47 | if (data.isUpdate) { | 47 | if (data.isUpdate) { |
| 48 | noticeId.value = data.record.id; | 48 | noticeId.value = data.record.id; |
| 49 | - Reflect.set(data.record, 'receiverType', data.record.receiverType === '全部' ? 0 : 1); | 49 | + Reflect.set(data.record, 'receiverType', data.record.receiverType === 0 ? 0 : 1); |
| 50 | if (data.record.receiverType === 1) { | 50 | if (data.record.receiverType === 1) { |
| 51 | if (!data.record.pointId.length) return; | 51 | if (!data.record.pointId.length) return; |
| 52 | const organizationId = data.record.pointId.split(','); | 52 | const organizationId = data.record.pointId.split(','); |
| @@ -380,6 +380,7 @@ export const modeMqttForm: FormSchema[] = [ | @@ -380,6 +380,7 @@ export const modeMqttForm: FormSchema[] = [ | ||
| 380 | component: 'Select', | 380 | component: 'Select', |
| 381 | label: 'type', | 381 | label: 'type', |
| 382 | colProps: { span: 12 }, | 382 | colProps: { span: 12 }, |
| 383 | + defaultValue: 'anonymous', | ||
| 383 | componentProps: { | 384 | componentProps: { |
| 384 | placeholder: '请选择Credentials', | 385 | placeholder: '请选择Credentials', |
| 385 | options: [ | 386 | options: [ |
| @@ -898,6 +899,7 @@ export const modeApiForm: FormSchema[] = [ | @@ -898,6 +899,7 @@ export const modeApiForm: FormSchema[] = [ | ||
| 898 | component: 'Select', | 899 | component: 'Select', |
| 899 | label: 'type', | 900 | label: 'type', |
| 900 | colProps: { span: 12 }, | 901 | colProps: { span: 12 }, |
| 902 | + defaultValue: 'anonymous', | ||
| 901 | componentProps: { | 903 | componentProps: { |
| 902 | placeholder: '请选择Number of acknowledgments', | 904 | placeholder: '请选择Number of acknowledgments', |
| 903 | options: [ | 905 | options: [ |
| @@ -122,6 +122,7 @@ export const schemas: FormSchema[] = [ | @@ -122,6 +122,7 @@ export const schemas: FormSchema[] = [ | ||
| 122 | { | 122 | { |
| 123 | field: 'prov', | 123 | field: 'prov', |
| 124 | label: '所在城市', | 124 | label: '所在城市', |
| 125 | + required: true, | ||
| 125 | component: 'Input', | 126 | component: 'Input', |
| 126 | colProps: { | 127 | colProps: { |
| 127 | span: 24, | 128 | span: 24, |