Showing
19 changed files
with
1085 additions
and
1047 deletions
src/views/report/config/ReportConfigDrawer.vue
deleted
100644 → 0
| 1 | -<template> | ||
| 2 | - <BasicDrawer | ||
| 3 | - :maskClosable="true" | ||
| 4 | - @close="handleClose" | ||
| 5 | - destroyOnClose | ||
| 6 | - v-bind="$attrs" | ||
| 7 | - @register="registerDrawer" | ||
| 8 | - showFooter | ||
| 9 | - :title="getTitle" | ||
| 10 | - width="30%" | ||
| 11 | - @ok="handleSubmit" | ||
| 12 | - > | ||
| 13 | - <BasicForm @register="registerForm"> | ||
| 14 | - <template #devices="{ model, field }"> | ||
| 15 | - <p style="display: none">{{ field }}</p> | ||
| 16 | - <p>{{ queryModeFunc(model['queryMode']) }}</p> | ||
| 17 | - <p>{{ orgFunc(model['organizationId']) }}</p> | ||
| 18 | - <p>{{ dataTypeFunc(model['dataType']) }}</p> | ||
| 19 | - <Select | ||
| 20 | - placeholder="请选择设备" | ||
| 21 | - v-model:value="selectDevice" | ||
| 22 | - style="width: 100%" | ||
| 23 | - :options="selectOptions" | ||
| 24 | - @change="handleDeviceChange" | ||
| 25 | - @deselect="handleDeselect" | ||
| 26 | - mode="multiple" | ||
| 27 | - labelInValue | ||
| 28 | - notFoundContent="请选择设备" | ||
| 29 | - /> | ||
| 30 | - <div style="margin-top: 1.5vh"></div> | ||
| 31 | - <template v-for="(item, index) in deviceList" :key="item.value"> | ||
| 32 | - <p style="display: none">{{ index }}</p> | ||
| 33 | - <DeviceAttrCpns | ||
| 34 | - :ref="bindDeviceRefObj.deviceAttrRef" | ||
| 35 | - :value="item" | ||
| 36 | - :orgId="organizationId || orgId" | ||
| 37 | - /> | ||
| 38 | - </template> | ||
| 39 | - </template> | ||
| 40 | - </BasicForm> | ||
| 41 | - </BasicDrawer> | ||
| 42 | -</template> | ||
| 43 | -<script lang="ts" setup> | ||
| 44 | - import { ref, computed, unref, reactive, watch, Ref, nextTick } from 'vue'; | ||
| 45 | - import { BasicForm, useForm } from '/@/components/Form'; | ||
| 46 | - import { DataTypeEnum, formSchema, organizationId } from './config.data'; | ||
| 47 | - import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
| 48 | - import { | ||
| 49 | - createOrEditReportManage, | ||
| 50 | - putReportConfigManage, | ||
| 51 | - reportEditDetailPage, | ||
| 52 | - } from '/@/api/report/reportManager'; | ||
| 53 | - import { useMessage } from '/@/hooks/web/useMessage'; | ||
| 54 | - import moment from 'moment'; | ||
| 55 | - import { screenLinkPageByDeptIdGetDevice } from '/@/api/ruleengine/ruleengineApi'; | ||
| 56 | - import { Select } from 'ant-design-vue'; | ||
| 57 | - import DeviceAttrCpns from './cpns/DeviceAttrCpns.vue'; | ||
| 58 | - import { SchemaFiled } from './config.data'; | ||
| 59 | - import { QueryWay } from '../../device/localtion/cpns/TimePeriodForm/config'; | ||
| 60 | - import { AggregateDataEnum } from '../../device/localtion/cpns/TimePeriodForm/config'; | ||
| 61 | - | ||
| 62 | - type TDeviceList = { | ||
| 63 | - key?: string; | ||
| 64 | - value?: string; | ||
| 65 | - label?: string; | ||
| 66 | - attribute?: string; | ||
| 67 | - device?: string; | ||
| 68 | - name?: string; | ||
| 69 | - attributes?: string | undefined; | ||
| 70 | - deviceProfileId?: string; | ||
| 71 | - id?: string; | ||
| 72 | - }; | ||
| 73 | - type TSelectOption = { | ||
| 74 | - value?: string; | ||
| 75 | - label?: string; | ||
| 76 | - deviceProfileId?: string; | ||
| 77 | - id?: string; | ||
| 78 | - }; | ||
| 79 | - const emit = defineEmits(['success', 'register']); | ||
| 80 | - const bindDeviceRefObj = { | ||
| 81 | - deviceAttrRef: ref([]), | ||
| 82 | - }; | ||
| 83 | - const isUpdate = ref(true); | ||
| 84 | - const editId = ref(''); | ||
| 85 | - const orgId = ref(''); | ||
| 86 | - const selectOptions: Ref<TSelectOption[]> = ref([]); | ||
| 87 | - const selectDevice = ref([]); | ||
| 88 | - const deviceList: Ref<TDeviceList[]> = ref([]); | ||
| 89 | - const editDeviceList: Ref<TDeviceList[]> = ref([]); | ||
| 90 | - let editResData: any = reactive({}); | ||
| 91 | - const editDeviceAttr: any = ref([]); | ||
| 92 | - const orgFuncId = ref(''); | ||
| 93 | - const queryModeStr = ref(''); | ||
| 94 | - const dataTypeStr = ref(0); | ||
| 95 | - const orgFunc = (e) => { | ||
| 96 | - orgFuncId.value = e; | ||
| 97 | - }; | ||
| 98 | - const queryModeFunc = (e) => { | ||
| 99 | - queryModeStr.value = e; | ||
| 100 | - }; | ||
| 101 | - const dataTypeFunc = (e) => { | ||
| 102 | - dataTypeStr.value = e; | ||
| 103 | - }; | ||
| 104 | - watch( | ||
| 105 | - () => dataTypeStr.value, | ||
| 106 | - (newValue) => { | ||
| 107 | - if (newValue == 0) { | ||
| 108 | - setFieldsValue({ limit: 100 }); | ||
| 109 | - } else { | ||
| 110 | - } | ||
| 111 | - } | ||
| 112 | - ); | ||
| 113 | - watch( | ||
| 114 | - () => queryModeStr.value, | ||
| 115 | - (newValue: string) => { | ||
| 116 | - if (newValue == 'latest') { | ||
| 117 | - setFieldsValue({ startTs: 1000 }); | ||
| 118 | - setFieldsValue({ interval: 1000 }); | ||
| 119 | - } else { | ||
| 120 | - } | ||
| 121 | - } | ||
| 122 | - ); | ||
| 123 | - watch( | ||
| 124 | - () => orgFuncId.value, | ||
| 125 | - async (newValue: string) => { | ||
| 126 | - if (newValue) { | ||
| 127 | - //获取设备 | ||
| 128 | - const { items } = await screenLinkPageByDeptIdGetDevice({ | ||
| 129 | - organizationId: newValue, | ||
| 130 | - }); | ||
| 131 | - selectOptions.value = items.map((item) => { | ||
| 132 | - if (item.deviceType !== 'GATEWAY') | ||
| 133 | - return { | ||
| 134 | - label: item.alias ? item.alias : item.name, | ||
| 135 | - value: item.tbDeviceId, | ||
| 136 | - id: item.id, | ||
| 137 | - deviceProfileId: item.deviceProfileId, | ||
| 138 | - }; | ||
| 139 | - }); | ||
| 140 | - } | ||
| 141 | - } | ||
| 142 | - ); | ||
| 143 | - //设备Select选中 | ||
| 144 | - const handleDeviceChange = (_, o) => { | ||
| 145 | - if (unref(isUpdate)) { | ||
| 146 | - //编辑 | ||
| 147 | - let temp: any = []; | ||
| 148 | - editDeviceAttr.value.forEach((f) => { | ||
| 149 | - temp = [f, ...o]; | ||
| 150 | - }); | ||
| 151 | - let deWeightThree = () => { | ||
| 152 | - let map = new Map(); | ||
| 153 | - for (let item of deviceList.value) { | ||
| 154 | - if (!map.has(item.value)) { | ||
| 155 | - map.set(item.value, item); | ||
| 156 | - } | ||
| 157 | - } | ||
| 158 | - return [...map.values()]; | ||
| 159 | - }; | ||
| 160 | - temp = deWeightThree(); | ||
| 161 | - deviceList.value = temp; | ||
| 162 | - if (o.length !== 0) { | ||
| 163 | - deviceList.value = o; | ||
| 164 | - } | ||
| 165 | - } else { | ||
| 166 | - deviceList.value = o; | ||
| 167 | - } | ||
| 168 | - }; | ||
| 169 | - //设备取消删除 | ||
| 170 | - const handleDeselect = (e) => { | ||
| 171 | - if (unref(isUpdate)) { | ||
| 172 | - //编辑 | ||
| 173 | - let deWeightThree = () => { | ||
| 174 | - let map = new Map(); | ||
| 175 | - for (let item of deviceList.value) { | ||
| 176 | - if (!map.has(item.value)) { | ||
| 177 | - map.set(item.value, item); | ||
| 178 | - } | ||
| 179 | - } | ||
| 180 | - return [...map.values()]; | ||
| 181 | - }; | ||
| 182 | - deviceList.value = deWeightThree(); | ||
| 183 | - const findEditValue = deviceList.value.findIndex((f) => f.value == e.value); | ||
| 184 | - if (findEditValue !== -1) deviceList.value.splice(findEditValue, 1); | ||
| 185 | - } else { | ||
| 186 | - const eDevice = e.key || e.value; | ||
| 187 | - const findValue = deviceList.value.findIndex((f) => f.value == eDevice); | ||
| 188 | - if (findValue !== -1) deviceList.value.splice(findValue, 1); | ||
| 189 | - } | ||
| 190 | - }; | ||
| 191 | - const [registerForm, { validate, setFieldsValue, resetFields, updateSchema, getFieldsValue }] = | ||
| 192 | - useForm({ | ||
| 193 | - labelWidth: 120, | ||
| 194 | - schemas: formSchema, | ||
| 195 | - showActionButtonGroup: false, | ||
| 196 | - fieldMapToTime: [[SchemaFiled.DATE_RANGE, [SchemaFiled.START_TS, SchemaFiled.END_TS]]], | ||
| 197 | - }); | ||
| 198 | - const isViewDetail = ref(false); | ||
| 199 | - | ||
| 200 | - const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => { | ||
| 201 | - await nextTick(); | ||
| 202 | - await resetFields(); | ||
| 203 | - setDrawerProps({ confirmLoading: false }); | ||
| 204 | - isUpdate.value = !!data?.isUpdate; | ||
| 205 | - isViewDetail.value = !!data?.isView; | ||
| 206 | - if (unref(isViewDetail)) { | ||
| 207 | - setDrawerProps({ showFooter: true }); | ||
| 208 | - if (unref(isUpdate)) { | ||
| 209 | - setDrawerProps({ title: '编辑报表配置' }); | ||
| 210 | - } else { | ||
| 211 | - setDrawerProps({ title: '新增报表配置' }); | ||
| 212 | - } | ||
| 213 | - } else { | ||
| 214 | - setDrawerProps({ showFooter: false }); | ||
| 215 | - setDrawerProps({ title: '查看报表配置' }); | ||
| 216 | - } | ||
| 217 | - if (unref(isUpdate)) { | ||
| 218 | - //编辑回显数据 | ||
| 219 | - editResData = await reportEditDetailPage(data.record.id); | ||
| 220 | - //回显基础数据 | ||
| 221 | - editId.value = editResData.data.id; | ||
| 222 | - const spanDisance = editResData.data.executeContent?.split(' '); | ||
| 223 | - await setFieldsValue(editResData.data); | ||
| 224 | - //回显嵌套数据 | ||
| 225 | - await setFieldsValue({ | ||
| 226 | - dateGroupGap: | ||
| 227 | - editResData.data.queryCondition?.queryMode === 1 | ||
| 228 | - ? editResData.data.queryCondition?.interval | ||
| 229 | - : null, | ||
| 230 | - agg: editResData.data.queryCondition?.agg, | ||
| 231 | - interval: editResData.data.queryCondition?.interval, | ||
| 232 | - limit: editResData.data.queryCondition?.limit, | ||
| 233 | - orderBy: editResData.data.queryCondition?.orderBy, | ||
| 234 | - useStrictDataTypes: editResData.data.queryCondition?.useStrictDataTypes, | ||
| 235 | - startTs: editResData.data.queryCondition?.startTs, | ||
| 236 | - endTs: editResData.data.queryCondition?.endTs, | ||
| 237 | - way: editResData.data?.way, | ||
| 238 | - queryMode: editResData.data.queryCondition?.queryMode === 0 ? 'latest' : 'timePeriod', | ||
| 239 | - cronTime: | ||
| 240 | - editResData.data?.cycle?.cycleType === 2 | ||
| 241 | - ? spanDisance[2] < 10 | ||
| 242 | - ? editResData.data.executeContent.slice(0, 7) + '* * ?' | ||
| 243 | - : editResData.data.executeContent.slice(0, 7) + ' ' + '* * ?' | ||
| 244 | - : editResData.data?.cycle?.cycleType === 1 | ||
| 245 | - ? spanDisance[2] < 10 | ||
| 246 | - ? editResData.data.executeContent.slice(0, 5) + ' ' + ' * * ?' | ||
| 247 | - : editResData.data.executeContent.slice(0, 6) + ' ' + ' * * ?' | ||
| 248 | - : editResData.data.executeContent, | ||
| 249 | - currentCycle: editResData.data?.cycle?.currentCycle, | ||
| 250 | - cycleTime: editResData.data?.cycle?.cycleTime, | ||
| 251 | - cycleType: editResData.data?.cycle?.cycleType, | ||
| 252 | - }); | ||
| 253 | - const endTsTime = editResData.data.queryCondition?.endTs; | ||
| 254 | - const startTsTime = editResData.data.queryCondition?.startTs; | ||
| 255 | - const mathFloor = (endTsTime - startTsTime) / 10; | ||
| 256 | - const multTen = Math.floor(mathFloor) * 10; | ||
| 257 | - await setFieldsValue({ | ||
| 258 | - startTs: multTen, | ||
| 259 | - }); | ||
| 260 | - if (editResData.data.queryCondition?.queryMode == 1) { | ||
| 261 | - await setFieldsValue({ | ||
| 262 | - dataRange: [ | ||
| 263 | - editResData.data.queryCondition?.startTs, | ||
| 264 | - editResData.data.queryCondition?.endTs, | ||
| 265 | - ], | ||
| 266 | - }); | ||
| 267 | - } | ||
| 268 | - //回显聚合条件 | ||
| 269 | - const dataCompareOpions = [ | ||
| 270 | - { label: '最小值', value: AggregateDataEnum.MIN }, | ||
| 271 | - { label: '最大值', value: AggregateDataEnum.MAX }, | ||
| 272 | - { label: '平均值', value: AggregateDataEnum.AVG }, | ||
| 273 | - { label: '求和', value: AggregateDataEnum.SUM }, | ||
| 274 | - { label: '计数', value: AggregateDataEnum.COUNT }, | ||
| 275 | - { label: '空', value: AggregateDataEnum.NONE }, | ||
| 276 | - ]; | ||
| 277 | - const updateSchemaAgg = (options: {}) => { | ||
| 278 | - updateSchema({ | ||
| 279 | - field: SchemaFiled.AGG, | ||
| 280 | - componentProps: { | ||
| 281 | - options, | ||
| 282 | - }, | ||
| 283 | - }); | ||
| 284 | - }; | ||
| 285 | - if (editResData.data.dataType == 1) updateSchemaAgg(dataCompareOpions.slice(0, 5)); | ||
| 286 | - else updateSchemaAgg(dataCompareOpions.slice(5, 6)); | ||
| 287 | - //回显执行方式和查询周期 | ||
| 288 | - const dataQueryOpions = [ | ||
| 289 | - { label: '固定周期', value: QueryWay.LATEST }, | ||
| 290 | - { label: '自定义周期', value: QueryWay.TIME_PERIOD }, | ||
| 291 | - ]; | ||
| 292 | - const updateSchemaQuery = (options: {}) => { | ||
| 293 | - updateSchema({ | ||
| 294 | - field: SchemaFiled.WAY, | ||
| 295 | - componentProps: { | ||
| 296 | - options, | ||
| 297 | - }, | ||
| 298 | - }); | ||
| 299 | - }; | ||
| 300 | - if (editResData.data.executeWay == 0) updateSchemaQuery(dataQueryOpions); | ||
| 301 | - else updateSchemaQuery(dataQueryOpions.slice(0, 1)); | ||
| 302 | - //回显设备 | ||
| 303 | - orgId.value = editResData.data.organizationId; | ||
| 304 | - const { items } = await screenLinkPageByDeptIdGetDevice({ | ||
| 305 | - organizationId: editResData.data.organizationId, | ||
| 306 | - }); | ||
| 307 | - selectOptions.value = items.map((item) => { | ||
| 308 | - if (item.deviceType !== 'GATEWAY') | ||
| 309 | - return { | ||
| 310 | - label: item.alias ? item.alias : item.name, | ||
| 311 | - value: item.tbDeviceId, | ||
| 312 | - id: item.id, | ||
| 313 | - deviceProfileId: item.deviceProfileId, | ||
| 314 | - }; | ||
| 315 | - }); | ||
| 316 | - const deviceIds = editResData.data.executeAttributes.map((m) => { | ||
| 317 | - return { | ||
| 318 | - label: m.name, | ||
| 319 | - key: m.device, | ||
| 320 | - }; | ||
| 321 | - }); | ||
| 322 | - selectDevice.value = deviceIds; | ||
| 323 | - //回显设备属性 | ||
| 324 | - editDeviceAttr.value = editResData.data.executeAttributes?.map((item) => { | ||
| 325 | - const T = selectOptions.value.find((o) => { | ||
| 326 | - if (item.device === o.value) { | ||
| 327 | - return { | ||
| 328 | - id: o.id, | ||
| 329 | - deviceProfileId: o.deviceProfileId, | ||
| 330 | - }; | ||
| 331 | - } | ||
| 332 | - }); | ||
| 333 | - return { | ||
| 334 | - ...T, | ||
| 335 | - label: item.alias ? item.alias : item.name, | ||
| 336 | - value: item.device, | ||
| 337 | - attributes: item.attributes, | ||
| 338 | - }; | ||
| 339 | - }); | ||
| 340 | - deviceList.value = editDeviceAttr.value; | ||
| 341 | - editDeviceList.value = editResData.data.executeAttributes; | ||
| 342 | - } else { | ||
| 343 | - setFieldsValue({ | ||
| 344 | - startTs: 1000, | ||
| 345 | - interval: 1000, | ||
| 346 | - }); | ||
| 347 | - editId.value = ''; | ||
| 348 | - orgId.value = ''; | ||
| 349 | - selectDevice.value = []; | ||
| 350 | - selectOptions.value = []; | ||
| 351 | - deviceList.value = []; | ||
| 352 | - getAttrDevice.value = []; | ||
| 353 | - editDeviceList.value = []; | ||
| 354 | - editDeviceAttr.value = []; | ||
| 355 | - updateSchema({ | ||
| 356 | - field: SchemaFiled.AGG, | ||
| 357 | - componentProps: { | ||
| 358 | - options: [], | ||
| 359 | - }, | ||
| 360 | - }); | ||
| 361 | - //新增显示执行方式和查询周期 | ||
| 362 | - const dataQueryOpions = [ | ||
| 363 | - { label: '固定周期', value: QueryWay.LATEST }, | ||
| 364 | - { label: '自定义周期', value: QueryWay.TIME_PERIOD }, | ||
| 365 | - ]; | ||
| 366 | - const updateSchemaQuery = (options: {}) => { | ||
| 367 | - updateSchema({ | ||
| 368 | - field: SchemaFiled.WAY, | ||
| 369 | - componentProps: { | ||
| 370 | - options, | ||
| 371 | - }, | ||
| 372 | - }); | ||
| 373 | - }; | ||
| 374 | - if (getFieldsValue().executeWay == 0) updateSchemaQuery(dataQueryOpions); | ||
| 375 | - } | ||
| 376 | - }); | ||
| 377 | - const handleClose = () => { | ||
| 378 | - deviceList.value = []; | ||
| 379 | - editId.value = ''; | ||
| 380 | - orgId.value = ''; | ||
| 381 | - selectDevice.value = []; | ||
| 382 | - selectOptions.value = []; | ||
| 383 | - getAttrDevice.value = []; | ||
| 384 | - editDeviceList.value = []; | ||
| 385 | - editDeviceAttr.value = []; | ||
| 386 | - }; | ||
| 387 | - const getAttrDevice: Ref<TDeviceList[]> = ref([]); | ||
| 388 | - const getTitle = computed(() => (!unref(isUpdate) ? '新增报表配置' : '编辑报表配置')); | ||
| 389 | - let postObj: any = reactive({}); | ||
| 390 | - let queryCondition: any = reactive({}); | ||
| 391 | - let executeContent: any = reactive({}); | ||
| 392 | - const startTs = ref(0); | ||
| 393 | - const endTs = ref(0); | ||
| 394 | - | ||
| 395 | - const getFormValueFunc = () => { | ||
| 396 | - const item: any = unref(bindDeviceRefObj.deviceAttrRef)?.map((item: any) => item.emitChange()); | ||
| 397 | - getAttrDevice.value = item; | ||
| 398 | - }; | ||
| 399 | - | ||
| 400 | - async function handleSubmit() { | ||
| 401 | - setDrawerProps({ confirmLoading: true }); | ||
| 402 | - try { | ||
| 403 | - const { createMessage } = useMessage(); | ||
| 404 | - const values = await validate(); | ||
| 405 | - if (!values) return; | ||
| 406 | - getFormValueFunc(); | ||
| 407 | - let hasAttr = false; | ||
| 408 | - if (!unref(isUpdate)) { | ||
| 409 | - if (getAttrDevice.value.length === 0) { | ||
| 410 | - return createMessage.error('请选择设备及其属性'); | ||
| 411 | - } else { | ||
| 412 | - getAttrDevice.value.forEach((f: any) => { | ||
| 413 | - if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true; | ||
| 414 | - }); | ||
| 415 | - } | ||
| 416 | - } else { | ||
| 417 | - if (getAttrDevice.value.length === 0) { | ||
| 418 | - return createMessage.error('请选择设备及其属性'); | ||
| 419 | - } else { | ||
| 420 | - getAttrDevice.value.forEach((f: any) => { | ||
| 421 | - if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true; | ||
| 422 | - }); | ||
| 423 | - } | ||
| 424 | - } | ||
| 425 | - if (hasAttr) return createMessage.error('请选择设备属性'); | ||
| 426 | - if (values.executeWay == 0) { | ||
| 427 | - executeContent = null; | ||
| 428 | - } else { | ||
| 429 | - //拼接corn | ||
| 430 | - let joinCorn = ''; | ||
| 431 | - if (values.cycleType === 1) { | ||
| 432 | - joinCorn = values.cronTime.slice(0, 6) + values.currentCycle.slice(5); | ||
| 433 | - executeContent = joinCorn; | ||
| 434 | - } else if (values.cycleType === 0) { | ||
| 435 | - executeContent = values.cronTime; | ||
| 436 | - } else if (values.cycleType === 2) { | ||
| 437 | - joinCorn = values.cronTime.slice(0, 6) + values.cycleTime.slice(5); | ||
| 438 | - executeContent = joinCorn; | ||
| 439 | - } | ||
| 440 | - } | ||
| 441 | - if (values.queryMode === QueryWay.LATEST) { | ||
| 442 | - startTs.value = moment().subtract(values.startTs, 'ms').valueOf(); | ||
| 443 | - endTs.value = Date.now(); | ||
| 444 | - } else { | ||
| 445 | - const fT = JSON.parse(JSON.stringify(values.dataRange)); | ||
| 446 | - startTs.value = moment(fT[0]).valueOf(); | ||
| 447 | - endTs.value = moment(fT[1]).valueOf(); | ||
| 448 | - } | ||
| 449 | - queryCondition = { | ||
| 450 | - agg: values.agg, | ||
| 451 | - ...(values?.queryMode === QueryWay.LATEST && values?.dataType != DataTypeEnum.ORIGINAL | ||
| 452 | - ? { interval: values?.queryMode === 'latest' ? values.interval : values.dateGroupGap } | ||
| 453 | - : {}), | ||
| 454 | - limit: values.limit, | ||
| 455 | - ...{ | ||
| 456 | - startTs: startTs.value, | ||
| 457 | - }, | ||
| 458 | - ...{ | ||
| 459 | - endTs: endTs.value, | ||
| 460 | - }, | ||
| 461 | - queryMode: values?.queryMode === 'latest' ? 0 : 1, | ||
| 462 | - }; | ||
| 463 | - const cycle: any = {}; | ||
| 464 | - if (values.cycleType === 0) { | ||
| 465 | - cycle.cycleType = values.cycleType; | ||
| 466 | - cycle.cronTime = values.cronTime; | ||
| 467 | - } | ||
| 468 | - if (values.cycleType === 1) { | ||
| 469 | - cycle.cycleType = values.cycleType; | ||
| 470 | - cycle.currentCycle = values.currentCycle; | ||
| 471 | - cycle.cronTime = values.cronTime; | ||
| 472 | - } | ||
| 473 | - if (values.cycleType === 2) { | ||
| 474 | - cycle.cycleType = values.cycleType; | ||
| 475 | - cycle.cycleTime = values.cycleTime; | ||
| 476 | - cycle.cronTime = values.cronTime; | ||
| 477 | - } | ||
| 478 | - // const cycle = { | ||
| 479 | - // currentCycle: values.currentCycle, | ||
| 480 | - // cycleTime: values.cycleTime, | ||
| 481 | - // cronTime: values.cronTime, | ||
| 482 | - // cycleType: values.cycleType, | ||
| 483 | - // }; | ||
| 484 | - delete values.devices; | ||
| 485 | - delete values.agg; | ||
| 486 | - delete values.interval; | ||
| 487 | - delete values.timeZone; | ||
| 488 | - delete values.cronTime; | ||
| 489 | - delete values.currentCycle; | ||
| 490 | - delete values.cycleTime; | ||
| 491 | - delete values.limit1; | ||
| 492 | - delete values.startTs; | ||
| 493 | - delete values.queryMode; | ||
| 494 | - delete values.cycleType; | ||
| 495 | - postObj = { | ||
| 496 | - ...values, | ||
| 497 | - ...{ | ||
| 498 | - executeAttributes: | ||
| 499 | - getAttrDevice.value.length == 0 ? editDeviceList.value : getAttrDevice.value, | ||
| 500 | - }, | ||
| 501 | - ...{ queryCondition }, | ||
| 502 | - ...{ cycle }, | ||
| 503 | - ...{ executeContent }, | ||
| 504 | - ...{ id: editId.value !== '' ? editId.value : '' }, | ||
| 505 | - }; | ||
| 506 | - let saveMessage = '添加成功'; | ||
| 507 | - let updateMessage = '修改成功'; | ||
| 508 | - editId.value !== '' | ||
| 509 | - ? await putReportConfigManage(postObj) | ||
| 510 | - : await createOrEditReportManage(postObj); | ||
| 511 | - | ||
| 512 | - closeDrawer(); | ||
| 513 | - emit('success'); | ||
| 514 | - createMessage.success(unref(isUpdate) ? updateMessage : saveMessage); | ||
| 515 | - handleClose(); | ||
| 516 | - } finally { | ||
| 517 | - setTimeout(() => { | ||
| 518 | - setDrawerProps({ confirmLoading: false }); | ||
| 519 | - }, 300); | ||
| 520 | - } | ||
| 521 | - } | ||
| 522 | -</script> |
src/views/report/config/components/DevicePreviewModal.vue
renamed from
src/views/report/config/DevicePreviewModal.vue
| @@ -6,7 +6,6 @@ | @@ -6,7 +6,6 @@ | ||
| 6 | width="55rem" | 6 | width="55rem" |
| 7 | @register="register" | 7 | @register="register" |
| 8 | title="执行设备及属性" | 8 | title="执行设备及属性" |
| 9 | - @cancel="handleCancel" | ||
| 10 | :showOkBtn="false" | 9 | :showOkBtn="false" |
| 11 | > | 10 | > |
| 12 | <div> | 11 | <div> |
| @@ -19,10 +18,11 @@ | @@ -19,10 +18,11 @@ | ||
| 19 | import { ref, nextTick } from 'vue'; | 18 | import { ref, nextTick } from 'vue'; |
| 20 | import { BasicModal, useModalInner } from '/@/components/Modal'; | 19 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
| 21 | import { BasicTable, useTable } from '/@/components/Table'; | 20 | import { BasicTable, useTable } from '/@/components/Table'; |
| 22 | - import { viewDeviceColumn } from './config.data'; | 21 | + import { viewDeviceColumn } from '../config'; |
| 23 | import { reportEditDetailPage } from '/@/api/report/reportManager'; | 22 | import { reportEditDetailPage } from '/@/api/report/reportManager'; |
| 24 | 23 | ||
| 25 | - const tableData: any = ref([]); | 24 | + const tableData = ref([]); |
| 25 | + | ||
| 26 | const [registerTable] = useTable({ | 26 | const [registerTable] = useTable({ |
| 27 | columns: viewDeviceColumn, | 27 | columns: viewDeviceColumn, |
| 28 | showIndexColumn: false, | 28 | showIndexColumn: false, |
| @@ -30,22 +30,20 @@ | @@ -30,22 +30,20 @@ | ||
| 30 | showTableSetting: false, | 30 | showTableSetting: false, |
| 31 | bordered: true, | 31 | bordered: true, |
| 32 | }); | 32 | }); |
| 33 | + | ||
| 33 | const [register] = useModalInner((data) => { | 34 | const [register] = useModalInner((data) => { |
| 34 | const getTableData = async () => { | 35 | const getTableData = async () => { |
| 35 | - const res: any = await reportEditDetailPage(data.record.id); | ||
| 36 | - const resMap = res.data.executeAttributes.map((d) => { | ||
| 37 | - return { | ||
| 38 | - device: d.name, | ||
| 39 | - attribute: d.attributes.join(','), | ||
| 40 | - }; | ||
| 41 | - }); | 36 | + const res = (await reportEditDetailPage(data.record?.id)) as any; |
| 37 | + const resMap = res?.data?.executeAttributes?.map((item) => ({ | ||
| 38 | + device: item.name, | ||
| 39 | + attribute: item.attributes.join(','), | ||
| 40 | + })); | ||
| 42 | tableData.value = resMap; | 41 | tableData.value = resMap; |
| 43 | }; | 42 | }; |
| 44 | nextTick(() => { | 43 | nextTick(() => { |
| 45 | getTableData(); | 44 | getTableData(); |
| 46 | }); | 45 | }); |
| 47 | }); | 46 | }); |
| 48 | - const handleCancel = () => {}; | ||
| 49 | </script> | 47 | </script> |
| 50 | <style lang="less" scoped> | 48 | <style lang="less" scoped> |
| 51 | :deep(.ant-table-body) { | 49 | :deep(.ant-table-body) { |
| 1 | +<template> | ||
| 2 | + <BasicDrawer | ||
| 3 | + destroyOnClose | ||
| 4 | + v-bind="$attrs" | ||
| 5 | + showFooter | ||
| 6 | + width="35%" | ||
| 7 | + :maskClosable="true" | ||
| 8 | + :title="businessText" | ||
| 9 | + @register="registerDrawer" | ||
| 10 | + @ok="handleSubmit" | ||
| 11 | + @close="handleClose" | ||
| 12 | + > | ||
| 13 | + <BasicForm @register="registerForm"> | ||
| 14 | + <!-- 设备选择 --> | ||
| 15 | + <template #devices="{ model }"> | ||
| 16 | + <span class="hidden">{{ handleChangeOrg(model['organizationId']) }}</span> | ||
| 17 | + <SelectDevice ref="selectDeviceRef" :selectOptions="selectOptions" /> | ||
| 18 | + </template> | ||
| 19 | + </BasicForm> | ||
| 20 | + </BasicDrawer> | ||
| 21 | +</template> | ||
| 22 | +<script lang="ts" setup> | ||
| 23 | + import { ref, reactive, Ref, nextTick, watch } from 'vue'; | ||
| 24 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
| 25 | + import { formSchema } from '../config'; | ||
| 26 | + import { SchemaFiled, BusinessReportConfigTextEnum, BusinessExecutewayEnum } from '../enum'; | ||
| 27 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
| 28 | + import { | ||
| 29 | + createOrEditReportManage, | ||
| 30 | + putReportConfigManage, | ||
| 31 | + reportEditDetailPage, | ||
| 32 | + } from '/@/api/report/reportManager'; | ||
| 33 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
| 34 | + import { TSelectOption } from '../type'; | ||
| 35 | + import { SelectDevice } from './index'; | ||
| 36 | + import { useHooks } from '../hooks/index.hooks'; | ||
| 37 | + import { useThrottleFn } from '@vueuse/shared'; | ||
| 38 | + | ||
| 39 | + const emits = defineEmits(['success', 'register']); | ||
| 40 | + | ||
| 41 | + const selectDeviceRef = ref<InstanceType<typeof SelectDevice>>(); | ||
| 42 | + | ||
| 43 | + const { createMessage } = useMessage(); | ||
| 44 | + | ||
| 45 | + const { | ||
| 46 | + getDeviceList, | ||
| 47 | + getQueryCondition, | ||
| 48 | + removeFields, | ||
| 49 | + setDefaultTime, | ||
| 50 | + setQueryCondition, | ||
| 51 | + setAggByDateType, | ||
| 52 | + disableCustomWeekly, | ||
| 53 | + setPropsForModal, | ||
| 54 | + validateSelectDevice, | ||
| 55 | + } = useHooks(); | ||
| 56 | + | ||
| 57 | + const selectOptions: Ref<TSelectOption[]> = ref([]); | ||
| 58 | + | ||
| 59 | + const orgId = ref(''); | ||
| 60 | + | ||
| 61 | + const handleChangeOrg = (e) => { | ||
| 62 | + orgId.value = e; | ||
| 63 | + //放在这里的话,会造成发出很多请求,原因不是很清楚 | ||
| 64 | + // getDeviceListByOrg(orgId.value); | ||
| 65 | + }; | ||
| 66 | + | ||
| 67 | + const getDeviceListByOrg = async (organizationId) => { | ||
| 68 | + selectOptions.value = await getDeviceList(organizationId); | ||
| 69 | + }; | ||
| 70 | + | ||
| 71 | + watch( | ||
| 72 | + () => orgId.value, | ||
| 73 | + (newValue: string) => { | ||
| 74 | + if (newValue) { | ||
| 75 | + //获取设备 | ||
| 76 | + selectDeviceRef.value?.resetValue(); | ||
| 77 | + getDeviceListByOrg(newValue); | ||
| 78 | + } | ||
| 79 | + }, | ||
| 80 | + { | ||
| 81 | + immediate: true, | ||
| 82 | + } | ||
| 83 | + ); | ||
| 84 | + | ||
| 85 | + const [registerForm, { validate, resetFields, setFieldsValue, updateSchema }] = useForm({ | ||
| 86 | + labelWidth: 120, | ||
| 87 | + schemas: formSchema, | ||
| 88 | + showActionButtonGroup: false, | ||
| 89 | + fieldMapToTime: [[SchemaFiled.DATE_RANGE, [SchemaFiled.START_TS, SchemaFiled.END_TS]]], | ||
| 90 | + }); | ||
| 91 | + | ||
| 92 | + const businessText = ref(''); | ||
| 93 | + | ||
| 94 | + const restData = reactive({ | ||
| 95 | + data: {}, | ||
| 96 | + }); | ||
| 97 | + | ||
| 98 | + const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => { | ||
| 99 | + try { | ||
| 100 | + await nextTick(); | ||
| 101 | + handleClose(); | ||
| 102 | + businessText.value = data.text; | ||
| 103 | + setFieldsValue(setDefaultTime()); | ||
| 104 | + updateSchema(disableCustomWeekly(BusinessExecutewayEnum.BUSINESS_EXECUTEWAY_IMMEDIATE)); | ||
| 105 | + setDrawerProps(setPropsForModal(businessText.value)); | ||
| 106 | + if (businessText.value === BusinessReportConfigTextEnum.BUSINESS_ADD_TEXT) return; | ||
| 107 | + const rest = await reportEditDetailPage(data.record?.id); | ||
| 108 | + restData.data = rest['data'] ?? {}; | ||
| 109 | + const { | ||
| 110 | + organizationId, | ||
| 111 | + executeAttributes, | ||
| 112 | + queryCondition, | ||
| 113 | + dataType, | ||
| 114 | + executeWay, | ||
| 115 | + cycle, | ||
| 116 | + executeContent, | ||
| 117 | + } = restData.data as any; | ||
| 118 | + await setFieldsValue({ | ||
| 119 | + ...restData.data, | ||
| 120 | + ...setQueryCondition(queryCondition, cycle, executeContent), | ||
| 121 | + }); | ||
| 122 | + if (organizationId) { | ||
| 123 | + await getDeviceListByOrg(organizationId); | ||
| 124 | + selectDeviceRef.value?.setValue(executeAttributes); | ||
| 125 | + } | ||
| 126 | + await updateSchema(setAggByDateType(dataType)); | ||
| 127 | + await updateSchema(disableCustomWeekly(executeWay)); | ||
| 128 | + } finally { | ||
| 129 | + setDrawerProps({ loading: false }); | ||
| 130 | + } | ||
| 131 | + }); | ||
| 132 | + | ||
| 133 | + const handleClose = () => resetValue(); | ||
| 134 | + | ||
| 135 | + const useThrottle = useThrottleFn(() => { | ||
| 136 | + getValue(); | ||
| 137 | + }, 2000); | ||
| 138 | + | ||
| 139 | + const handleSubmit = () => { | ||
| 140 | + useThrottle(); | ||
| 141 | + }; | ||
| 142 | + | ||
| 143 | + const getValue = async () => { | ||
| 144 | + try { | ||
| 145 | + setDrawerProps({ confirmLoading: true }); | ||
| 146 | + const values = await validate(); | ||
| 147 | + if (!values) return; | ||
| 148 | + const [queryCondition, cycle, executeContent] = getQueryCondition(values); | ||
| 149 | + const executeAttributes = selectDeviceRef.value?.getSelectAttributes(); | ||
| 150 | + validateSelectDevice(executeAttributes); | ||
| 151 | + const data = { | ||
| 152 | + ...values, | ||
| 153 | + executeAttributes, | ||
| 154 | + queryCondition, | ||
| 155 | + cycle, | ||
| 156 | + executeContent, | ||
| 157 | + }; | ||
| 158 | + removeFields.forEach((item) => { | ||
| 159 | + Reflect.deleteProperty(data, item); | ||
| 160 | + }); | ||
| 161 | + businessText.value === BusinessReportConfigTextEnum.BUSINESS_ADD_TEXT | ||
| 162 | + ? await createOrEditReportManage(data) | ||
| 163 | + : putReportConfigManage({ ...restData.data, ...data }); | ||
| 164 | + emits('success'); | ||
| 165 | + createMessage.success(`${businessText.value}成功`); | ||
| 166 | + closeDrawer(); | ||
| 167 | + handleClose(); | ||
| 168 | + } finally { | ||
| 169 | + setDrawerProps({ confirmLoading: false }); | ||
| 170 | + } | ||
| 171 | + }; | ||
| 172 | + | ||
| 173 | + //重置表单 | ||
| 174 | + const resetValue = () => { | ||
| 175 | + resetFields(); | ||
| 176 | + selectOptions.value = []; | ||
| 177 | + selectDeviceRef.value?.resetValue(); | ||
| 178 | + }; | ||
| 179 | +</script> |
src/views/report/config/components/SelectAttributes.vue
renamed from
src/views/report/config/cpns/DeviceAttrCpns.vue
| 1 | <template> | 1 | <template> |
| 2 | <div | 2 | <div |
| 3 | + class="flex" | ||
| 3 | v-for="param in dynamicInput.params" | 4 | v-for="param in dynamicInput.params" |
| 4 | :key="param.key" | 5 | :key="param.key" |
| 5 | - style="display: flex; margin-top: 0.25vh" | 6 | + style="margin-top: 1.25vh" |
| 6 | > | 7 | > |
| 7 | - <a-input | ||
| 8 | - :disabled="true" | ||
| 9 | - v-model:value="param.name" | ||
| 10 | - style="width: 38%; margin-bottom: 5px; margin-left: 1vh" | ||
| 11 | - @change="emitChange" | ||
| 12 | - /> | 8 | + <a-input :disabled="true" v-model:value="param.name" style="width: 38%; margin-bottom: 5px" /> |
| 13 | <Select | 9 | <Select |
| 14 | placeholder="请选择设备属性" | 10 | placeholder="请选择设备属性" |
| 15 | v-model:value="param.attributes" | 11 | v-model:value="param.attributes" |
| 16 | - style="width: 160px; margin-left: 1.8vw" | 12 | + style="width: 38%; margin-left: 1.8vw" |
| 17 | :options="selectOptions" | 13 | :options="selectOptions" |
| 18 | @change="emitChange" | 14 | @change="emitChange" |
| 19 | mode="multiple" | 15 | mode="multiple" |
| @@ -26,72 +22,66 @@ | @@ -26,72 +22,66 @@ | ||
| 26 | inheritAttrs: false, | 22 | inheritAttrs: false, |
| 27 | }; | 23 | }; |
| 28 | </script> | 24 | </script> |
| 29 | -<script lang="ts" setup> | 25 | +<script lang="ts" setup name="SelectAttributes"> |
| 30 | import { reactive, UnwrapRef, watchEffect, ref } from 'vue'; | 26 | import { reactive, UnwrapRef, watchEffect, ref } from 'vue'; |
| 31 | import { propTypes } from '/@/utils/propTypes'; | 27 | import { propTypes } from '/@/utils/propTypes'; |
| 32 | import { Select } from 'ant-design-vue'; | 28 | import { Select } from 'ant-design-vue'; |
| 33 | - import { getAttribute } from '/@/api/ruleengine/ruleengineApi'; | 29 | + import { Params } from '../type/'; |
| 30 | + import { useHooks } from '../hooks/index.hooks'; | ||
| 34 | 31 | ||
| 35 | - interface Params { | ||
| 36 | - [x: string]: string; | ||
| 37 | - attributes: any; | ||
| 38 | - device: string; | ||
| 39 | - } | ||
| 40 | const props = defineProps({ | 32 | const props = defineProps({ |
| 41 | value: propTypes.object.def({}), | 33 | value: propTypes.object.def({}), |
| 42 | - orgId: propTypes.string.def(''), | ||
| 43 | }); | 34 | }); |
| 35 | + | ||
| 44 | const selectOptions: any = ref([]); | 36 | const selectOptions: any = ref([]); |
| 45 | - //获取对应设备属性 | ||
| 46 | - const getAttr = async (orgId, _) => { | ||
| 47 | - if (orgId) { | ||
| 48 | - const res = await getAttribute(orgId); | ||
| 49 | - if (Array.isArray(res)) { | ||
| 50 | - selectOptions.value = res.map((o) => { | ||
| 51 | - let obj: any = {}; | ||
| 52 | - if (o?.identifier !== null) { | ||
| 53 | - obj = { | ||
| 54 | - label: o?.identifier, | ||
| 55 | - value: o?.identifier, | ||
| 56 | - }; | ||
| 57 | - return obj; | ||
| 58 | - } | ||
| 59 | - }); | ||
| 60 | - //如果服务端返回的数组里含有null 过滤null值 | ||
| 61 | - const excludeNull = selectOptions.value.filter(Boolean); | ||
| 62 | - selectOptions.value = excludeNull; | ||
| 63 | - } | ||
| 64 | - } | ||
| 65 | - }; | 37 | + |
| 38 | + const { getDeviceAttr } = useHooks(); | ||
| 39 | + | ||
| 66 | //动态数据 | 40 | //动态数据 |
| 67 | const dynamicInput: UnwrapRef<{ params: Params[] }> = reactive({ params: [] }); | 41 | const dynamicInput: UnwrapRef<{ params: Params[] }> = reactive({ params: [] }); |
| 68 | - const rEffect = watchEffect(() => { | ||
| 69 | - initVal(); | ||
| 70 | - }); | ||
| 71 | - rEffect(); | ||
| 72 | - /** | ||
| 73 | - * 初始化数值 | ||
| 74 | - */ | ||
| 75 | - async function initVal() { | 42 | + |
| 43 | + const initVal = async () => { | ||
| 76 | if (props.value) { | 44 | if (props.value) { |
| 77 | - await getAttr(props.value?.deviceProfileId, props.value?.id); | 45 | + selectOptions.value = await getDeviceAttr(props.value?.deviceProfileId); |
| 78 | dynamicInput.params.push({ | 46 | dynamicInput.params.push({ |
| 79 | name: props.value.label, | 47 | name: props.value.label, |
| 80 | device: props.value.value, | 48 | device: props.value.value, |
| 81 | - attributes: props.value?.attributes == [] ? [] : props.value.attributes, | 49 | + attributes: props.value.attributes, |
| 82 | }); | 50 | }); |
| 83 | } | 51 | } |
| 84 | - } | ||
| 85 | - /** | ||
| 86 | - * 数值改变 | ||
| 87 | - */ | ||
| 88 | - function emitChange() { | 52 | + }; |
| 53 | + | ||
| 54 | + //数值改变 | ||
| 55 | + const valEffect = watchEffect(() => { | ||
| 56 | + initVal(); | ||
| 57 | + }); | ||
| 58 | + | ||
| 59 | + valEffect(); | ||
| 60 | + | ||
| 61 | + //chang改变 | ||
| 62 | + const emitChange = () => { | ||
| 89 | return dynamicInput.params[0]; | 63 | return dynamicInput.params[0]; |
| 90 | - } | 64 | + }; |
| 91 | defineExpose({ | 65 | defineExpose({ |
| 92 | emitChange, | 66 | emitChange, |
| 93 | }); | 67 | }); |
| 94 | </script> | 68 | </script> |
| 95 | <style scoped lang="css"> | 69 | <style scoped lang="css"> |
| 96 | - @import './deviceAttrCpns.css'; | 70 | + .dynamic-delete-button { |
| 71 | + cursor: pointer; | ||
| 72 | + position: relative; | ||
| 73 | + top: 4px; | ||
| 74 | + font-size: 24px; | ||
| 75 | + color: #999; | ||
| 76 | + transition: all 0.3s; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + .dynamic-delete-button:hover { | ||
| 80 | + color: #777; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + .dynamic-delete-button[disabled] { | ||
| 84 | + cursor: not-allowed; | ||
| 85 | + opacity: 0.5; | ||
| 86 | + } | ||
| 97 | </style> | 87 | </style> |
| 1 | +<template> | ||
| 2 | + <Select | ||
| 3 | + placeholder="请选择设备" | ||
| 4 | + v-model:value="selectValue" | ||
| 5 | + style="width: 100%" | ||
| 6 | + :options="selectOptions" | ||
| 7 | + @change="handleDeviceChange" | ||
| 8 | + mode="multiple" | ||
| 9 | + labelInValue | ||
| 10 | + /> | ||
| 11 | + <template v-for="(item, index) in deviceList" :key="item.value"> | ||
| 12 | + <SelectAttributes :ref="bindDeviceRef.deviceAttrRef" :value="item" :index="index" /> | ||
| 13 | + </template> | ||
| 14 | +</template> | ||
| 15 | +<script lang="ts" setup name="SelectDevice"> | ||
| 16 | + import { ref, Ref, PropType, unref } from 'vue'; | ||
| 17 | + import { Select } from 'ant-design-vue'; | ||
| 18 | + import SelectAttributes from './SelectAttributes.vue'; | ||
| 19 | + import { TDeviceList, TSelectOption } from '../type'; | ||
| 20 | + | ||
| 21 | + const props = defineProps({ | ||
| 22 | + selectOptions: { | ||
| 23 | + type: Array as PropType<TSelectOption[]>, | ||
| 24 | + required: true, | ||
| 25 | + }, | ||
| 26 | + }); | ||
| 27 | + | ||
| 28 | + const selectValue = ref([]); | ||
| 29 | + | ||
| 30 | + const bindDeviceRef = { | ||
| 31 | + deviceAttrRef: ref([]), | ||
| 32 | + }; | ||
| 33 | + | ||
| 34 | + const deviceList: Ref<TDeviceList[]> = ref([]); | ||
| 35 | + | ||
| 36 | + const getSelectAttributes = () => { | ||
| 37 | + return unref(bindDeviceRef.deviceAttrRef)?.map((item: any) => item.emitChange()); | ||
| 38 | + }; | ||
| 39 | + | ||
| 40 | + const handleDeviceChange = (_, options) => { | ||
| 41 | + deviceList.value = options; | ||
| 42 | + }; | ||
| 43 | + | ||
| 44 | + const setValue = (value) => { | ||
| 45 | + selectValue.value = value.map((item) => ({ | ||
| 46 | + label: item.name, | ||
| 47 | + key: item.device, | ||
| 48 | + })); | ||
| 49 | + deviceList.value = value?.map((item) => { | ||
| 50 | + const T = props.selectOptions.find((o) => { | ||
| 51 | + if (item.device === o.value) { | ||
| 52 | + return { | ||
| 53 | + id: o.id, | ||
| 54 | + deviceProfileId: o.deviceProfileId, | ||
| 55 | + }; | ||
| 56 | + } | ||
| 57 | + }); | ||
| 58 | + return { | ||
| 59 | + ...T, | ||
| 60 | + label: item.alias ? item.alias : item.name, | ||
| 61 | + value: item.device, | ||
| 62 | + attributes: item.attributes, | ||
| 63 | + }; | ||
| 64 | + }); | ||
| 65 | + }; | ||
| 66 | + | ||
| 67 | + const resetValue = () => { | ||
| 68 | + selectValue.value = []; | ||
| 69 | + deviceList.value = []; | ||
| 70 | + }; | ||
| 71 | + defineExpose({ | ||
| 72 | + getSelectAttributes, | ||
| 73 | + setValue, | ||
| 74 | + resetValue, | ||
| 75 | + }); | ||
| 76 | +</script> | ||
| 77 | +<style scoped lang="css"></style> |
src/views/report/config/components/index.ts
0 → 100644
| 1 | +import SelectDevice from './SelectDevice.vue'; | ||
| 2 | +import SelectAttributes from './SelectAttributes.vue'; | ||
| 3 | +import DevicePreviewModal from './DevicePreviewModal.vue'; | ||
| 4 | +import ReportConfigDrawer from './ReportConfigDrawer.vue'; | ||
| 5 | + | ||
| 6 | +export { SelectDevice, SelectAttributes, DevicePreviewModal, ReportConfigDrawer }; |
src/views/report/config/config.ts
renamed from
src/views/report/config/config.data.ts
| 1 | -import { ref } from 'vue'; | ||
| 2 | -import { BasicColumn, FormSchema } from '/@/components/Table'; | ||
| 3 | -import { FormSchema as QFormSchema, useComponentRegister } from '/@/components/Form/index'; | 1 | +import { BasicColumn, BasicTableProps, FormSchema } from '/@/components/Table'; |
| 2 | +import { FormSchema as BFormSchema, useComponentRegister } from '/@/components/Form/index'; | ||
| 4 | import { findDictItemByCode } from '/@/api/system/dict'; | 3 | import { findDictItemByCode } from '/@/api/system/dict'; |
| 5 | -import { isTiming, isWeek, isMonth, isFixedTime } from './timeConfig'; | ||
| 6 | -import { AggregateDataEnum } from '../../device/localtion/cpns/TimePeriodForm/config'; | 4 | +import { AggregateDataEnum } from '/@/views/device/localtion/cpns/TimePeriodForm/config'; |
| 7 | import { | 5 | import { |
| 8 | getPacketIntervalByRange, | 6 | getPacketIntervalByRange, |
| 9 | getPacketIntervalByValue, | 7 | getPacketIntervalByValue, |
| 10 | intervalOption, | 8 | intervalOption, |
| 11 | -} from '../../device/localtion/cpns/TimePeriodForm/helper'; | 9 | +} from '/@/views/device/localtion/cpns/TimePeriodForm/helper'; |
| 12 | import moment, { Moment } from 'moment'; | 10 | import moment, { Moment } from 'moment'; |
| 13 | import { OrgTreeSelect } from '../../common/OrgTreeSelect'; | 11 | import { OrgTreeSelect } from '../../common/OrgTreeSelect'; |
| 12 | +import { | ||
| 13 | + BusinessExecutewayEnum, | ||
| 14 | + BusinessReportConfigTextEnum, | ||
| 15 | + CycleTypeEnum, | ||
| 16 | + DataTypeEnum, | ||
| 17 | + DataTypeNameEnum, | ||
| 18 | + ExecuteWayNameEnum, | ||
| 19 | + QueryWay, | ||
| 20 | + SchemaFiled, | ||
| 21 | + businesAggOptions, | ||
| 22 | + businesCycleTypeOptions, | ||
| 23 | + businesDataTypeOptions, | ||
| 24 | + businesLimitValue, | ||
| 25 | + businesQueryCycleOptions, | ||
| 26 | + businesWayOptions, | ||
| 27 | + businessExecuteWayOptions, | ||
| 28 | + cycleTypeIsMonthly, | ||
| 29 | + cycleTypeIsWeekly, | ||
| 30 | + cycleTypeSetDefault, | ||
| 31 | + exectueIsImmed, | ||
| 32 | + exectueIsSchedule, | ||
| 33 | +} from './enum'; | ||
| 14 | useComponentRegister('OrgTreeSelect', OrgTreeSelect); | 34 | useComponentRegister('OrgTreeSelect', OrgTreeSelect); |
| 15 | -export enum QueryWay { | ||
| 16 | - LATEST = 'latest', | ||
| 17 | - TIME_PERIOD = 'timePeriod', | ||
| 18 | -} | ||
| 19 | -export enum SchemaFiled { | ||
| 20 | - WAY = 'queryMode', | ||
| 21 | - TIME_PERIOD = 'timePeriod', | ||
| 22 | - KEYS = 'keys', | ||
| 23 | - DATE_RANGE = 'dataRange', | ||
| 24 | - START_TS = 'startTs', | ||
| 25 | - END_TS = 'endTs', | ||
| 26 | - INTERVAL = 'interval', | ||
| 27 | - LIMIT = 'limit', | ||
| 28 | - AGG = 'agg', | ||
| 29 | - ORDER_BY = 'orderBy', | ||
| 30 | - DATA_TYPE = 'dataType', | ||
| 31 | -} | ||
| 32 | - | ||
| 33 | -export enum DataTypeEnum { | ||
| 34 | - ORIGINAL = 0, | ||
| 35 | - AGG = 1, | ||
| 36 | -} | ||
| 37 | - | ||
| 38 | -export enum DataTypeNameEnum { | ||
| 39 | - ORIGINAL = '原始数据', | ||
| 40 | - AGG = '聚合数据', | ||
| 41 | -} | ||
| 42 | - | ||
| 43 | -export const organizationId = ref(''); | ||
| 44 | 35 | ||
| 45 | -// 表格配置 | 36 | +// 表格列配置 |
| 46 | export const columns: BasicColumn[] = [ | 37 | export const columns: BasicColumn[] = [ |
| 47 | { | 38 | { |
| 48 | title: '配置名称', | 39 | title: '配置名称', |
| @@ -75,7 +66,9 @@ export const columns: BasicColumn[] = [ | @@ -75,7 +66,9 @@ export const columns: BasicColumn[] = [ | ||
| 75 | dataIndex: 'executeWay', | 66 | dataIndex: 'executeWay', |
| 76 | width: 160, | 67 | width: 160, |
| 77 | format: (_text: string, record: Recordable) => { | 68 | format: (_text: string, record: Recordable) => { |
| 78 | - return record.executeWay === 0 ? '立即执行' : '定时执行'; | 69 | + return record.executeWay === BusinessExecutewayEnum.BUSINESS_EXECUTEWAY_IMMEDIATE |
| 70 | + ? ExecuteWayNameEnum.EXECUTEWAY_IMMEDIATE | ||
| 71 | + : ExecuteWayNameEnum.EXECUTEWAY_SCHEDULED; | ||
| 79 | }, | 72 | }, |
| 80 | }, | 73 | }, |
| 81 | { | 74 | { |
| @@ -95,20 +88,8 @@ export const columns: BasicColumn[] = [ | @@ -95,20 +88,8 @@ export const columns: BasicColumn[] = [ | ||
| 95 | width: 180, | 88 | width: 180, |
| 96 | }, | 89 | }, |
| 97 | ]; | 90 | ]; |
| 98 | -export const viewDeviceColumn: BasicColumn[] = [ | ||
| 99 | - { | ||
| 100 | - title: '设备', | ||
| 101 | - dataIndex: 'device', | ||
| 102 | - width: 80, | ||
| 103 | - }, | ||
| 104 | - { | ||
| 105 | - title: '属性', | ||
| 106 | - dataIndex: 'attribute', | ||
| 107 | - width: 120, | ||
| 108 | - }, | ||
| 109 | -]; | ||
| 110 | 91 | ||
| 111 | -// 查询配置 | 92 | +// 表格查询配置 |
| 112 | export const searchFormSchema: FormSchema[] = [ | 93 | export const searchFormSchema: FormSchema[] = [ |
| 113 | { | 94 | { |
| 114 | field: 'name', | 95 | field: 'name', |
| @@ -152,8 +133,45 @@ export const searchFormSchema: FormSchema[] = [ | @@ -152,8 +133,45 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 152 | }, | 133 | }, |
| 153 | ]; | 134 | ]; |
| 154 | 135 | ||
| 155 | -// 新增编辑配置 | ||
| 156 | -export const formSchema: QFormSchema[] = [ | 136 | +//表格通用属性配置 |
| 137 | +export const defaultTableAttribtes: BasicTableProps = { | ||
| 138 | + title: '报表列表', | ||
| 139 | + columns, | ||
| 140 | + showIndexColumn: false, | ||
| 141 | + clickToRowSelect: false, | ||
| 142 | + formConfig: { | ||
| 143 | + labelWidth: 120, | ||
| 144 | + schemas: searchFormSchema, | ||
| 145 | + fieldMapToTime: [['sendTime', ['startTime', 'endTime'], 'x']], | ||
| 146 | + }, | ||
| 147 | + useSearchForm: true, | ||
| 148 | + showTableSetting: true, | ||
| 149 | + bordered: true, | ||
| 150 | + rowKey: 'id', | ||
| 151 | + actionColumn: { | ||
| 152 | + width: 200, | ||
| 153 | + title: '操作', | ||
| 154 | + dataIndex: 'action', | ||
| 155 | + slots: { customRender: 'action' }, | ||
| 156 | + fixed: 'right', | ||
| 157 | + }, | ||
| 158 | +}; | ||
| 159 | + | ||
| 160 | +export const viewDeviceColumn: BasicColumn[] = [ | ||
| 161 | + { | ||
| 162 | + title: '设备', | ||
| 163 | + dataIndex: 'device', | ||
| 164 | + width: 80, | ||
| 165 | + }, | ||
| 166 | + { | ||
| 167 | + title: '属性', | ||
| 168 | + dataIndex: 'attribute', | ||
| 169 | + width: 120, | ||
| 170 | + }, | ||
| 171 | +]; | ||
| 172 | + | ||
| 173 | +// 表单配置 | ||
| 174 | +export const formSchema: BFormSchema[] = [ | ||
| 157 | { | 175 | { |
| 158 | field: 'name', | 176 | field: 'name', |
| 159 | label: '报表名称', | 177 | label: '报表名称', |
| @@ -171,13 +189,6 @@ export const formSchema: QFormSchema[] = [ | @@ -171,13 +189,6 @@ export const formSchema: QFormSchema[] = [ | ||
| 171 | colProps: { span: 24 }, | 189 | colProps: { span: 24 }, |
| 172 | component: 'OrgTreeSelect', | 190 | component: 'OrgTreeSelect', |
| 173 | required: true, | 191 | required: true, |
| 174 | - componentProps: () => { | ||
| 175 | - return { | ||
| 176 | - async onChange(e) { | ||
| 177 | - organizationId.value = e; | ||
| 178 | - }, | ||
| 179 | - }; | ||
| 180 | - }, | ||
| 181 | }, | 192 | }, |
| 182 | { | 193 | { |
| 183 | field: 'remark', | 194 | field: 'remark', |
| @@ -192,64 +203,48 @@ export const formSchema: QFormSchema[] = [ | @@ -192,64 +203,48 @@ export const formSchema: QFormSchema[] = [ | ||
| 192 | { | 203 | { |
| 193 | field: 'executeWay', | 204 | field: 'executeWay', |
| 194 | component: 'RadioGroup', | 205 | component: 'RadioGroup', |
| 195 | - helpMessage: [ | ||
| 196 | - `立即执行,在创建完报表配置后,启用配置即执行。 | ||
| 197 | - 定时执行,用户定义执行时间,启用后, | ||
| 198 | - 在满足执行时间条件后,自动执行。`, | ||
| 199 | - ], | 206 | + helpMessage: [BusinessReportConfigTextEnum.BUSINESS_EXECUTEWAY_HELPMESSAGE_TEXT], |
| 200 | label: '执行方式', | 207 | label: '执行方式', |
| 201 | colProps: { | 208 | colProps: { |
| 202 | span: 24, | 209 | span: 24, |
| 203 | }, | 210 | }, |
| 204 | - defaultValue: 0, | 211 | + defaultValue: BusinessExecutewayEnum.BUSINESS_EXECUTEWAY_IMMEDIATE, |
| 205 | componentProps: ({ formActionType }) => { | 212 | componentProps: ({ formActionType }) => { |
| 206 | const { updateSchema, setFieldsValue } = formActionType; | 213 | const { updateSchema, setFieldsValue } = formActionType; |
| 207 | - const options = [ | ||
| 208 | - { | ||
| 209 | - label: '立即执行', | ||
| 210 | - value: 0, | ||
| 211 | - }, | ||
| 212 | - { | ||
| 213 | - label: '定时执行', | ||
| 214 | - value: 1, | ||
| 215 | - }, | ||
| 216 | - ]; | ||
| 217 | return { | 214 | return { |
| 218 | - options, | 215 | + options: businessExecuteWayOptions, |
| 219 | placeholder: '请选择执行方式', | 216 | placeholder: '请选择执行方式', |
| 220 | onChange(e) { | 217 | onChange(e) { |
| 221 | - let dataCompareOpions: any = []; | ||
| 222 | - setFieldsValue({ | ||
| 223 | - startTs: 1000, | ||
| 224 | - interval: 1000, | ||
| 225 | - }); | ||
| 226 | - if (e.target.value == 0) { | ||
| 227 | - setFieldsValue({ queryMode: QueryWay.LATEST }); | ||
| 228 | - dataCompareOpions = [ | ||
| 229 | - { label: '固定周期', value: QueryWay.LATEST }, | ||
| 230 | - { label: '自定义周期', value: QueryWay.TIME_PERIOD }, | ||
| 231 | - ]; | 218 | + //动态切换 最近时间 间隔时间变化 |
| 219 | + const setDefaultTime = (startTs, interval, queryMode) => { | ||
| 220 | + setFieldsValue({ | ||
| 221 | + startTs, | ||
| 222 | + interval, | ||
| 223 | + queryMode, | ||
| 224 | + }); | ||
| 225 | + }; | ||
| 226 | + //动态切换 查询周期变化 | ||
| 227 | + const setQueryMode = (defaultValue, field = SchemaFiled.WAY, comObJ) => { | ||
| 232 | updateSchema({ | 228 | updateSchema({ |
| 233 | - field: SchemaFiled.WAY, | ||
| 234 | - componentProps: { | ||
| 235 | - options: dataCompareOpions, | ||
| 236 | - }, | 229 | + defaultValue, |
| 230 | + field, | ||
| 231 | + componentProps: comObJ, | ||
| 232 | + }); | ||
| 233 | + }; | ||
| 234 | + if (e.target.value == BusinessExecutewayEnum.BUSINESS_EXECUTEWAY_IMMEDIATE) { | ||
| 235 | + //业务 选择立即执行 | ||
| 236 | + setDefaultTime(1000, 1000, QueryWay.LATEST); | ||
| 237 | + setQueryMode(null, SchemaFiled.WAY, { | ||
| 238 | + options: businesQueryCycleOptions, | ||
| 237 | }); | 239 | }); |
| 238 | } else { | 240 | } else { |
| 239 | - setFieldsValue({ queryMode: QueryWay.LATEST }); | ||
| 240 | - setFieldsValue({ startTs: 5000 }); | ||
| 241 | - setFieldsValue({ interval: 1000 }); | ||
| 242 | - dataCompareOpions = [{ label: '固定周期', value: QueryWay.LATEST }]; | ||
| 243 | - updateSchema({ | ||
| 244 | - defaultValue: QueryWay.LATEST, | ||
| 245 | - field: SchemaFiled.WAY, | ||
| 246 | - componentProps: { | ||
| 247 | - options: dataCompareOpions, | ||
| 248 | - }, | 241 | + //业务 选择定时执行 |
| 242 | + setDefaultTime(5000, 1000, QueryWay.LATEST); | ||
| 243 | + setQueryMode(QueryWay.LATEST, SchemaFiled.WAY, { | ||
| 244 | + options: businesQueryCycleOptions.filter((item) => item.value === QueryWay.LATEST), | ||
| 249 | }); | 245 | }); |
| 250 | } | 246 | } |
| 251 | }, | 247 | }, |
| 252 | - maxLength: 250, | ||
| 253 | }; | 248 | }; |
| 254 | }, | 249 | }, |
| 255 | }, | 250 | }, |
| @@ -259,16 +254,12 @@ export const formSchema: QFormSchema[] = [ | @@ -259,16 +254,12 @@ export const formSchema: QFormSchema[] = [ | ||
| 259 | label: '周期', | 254 | label: '周期', |
| 260 | required: true, | 255 | required: true, |
| 261 | colProps: { span: 24 }, | 256 | colProps: { span: 24 }, |
| 262 | - defaultValue: 0, | 257 | + defaultValue: CycleTypeEnum.DAILY, |
| 263 | componentProps: { | 258 | componentProps: { |
| 264 | placeholder: '请选择周期', | 259 | placeholder: '请选择周期', |
| 265 | - options: [ | ||
| 266 | - { label: '每日', value: 0 }, | ||
| 267 | - { label: '每周', value: 1 }, | ||
| 268 | - { label: '每月', value: 2 }, | ||
| 269 | - ], | 260 | + options: businesCycleTypeOptions, |
| 270 | }, | 261 | }, |
| 271 | - ifShow: ({ values }) => isTiming(values.executeWay), | 262 | + ifShow: ({ values }) => exectueIsSchedule(values.executeWay), |
| 272 | }, | 263 | }, |
| 273 | { | 264 | { |
| 274 | field: 'currentCycle', | 265 | field: 'currentCycle', |
| @@ -276,7 +267,7 @@ export const formSchema: QFormSchema[] = [ | @@ -276,7 +267,7 @@ export const formSchema: QFormSchema[] = [ | ||
| 276 | label: '每周', | 267 | label: '每周', |
| 277 | required: true, | 268 | required: true, |
| 278 | colProps: { span: 24 }, | 269 | colProps: { span: 24 }, |
| 279 | - defaultValue: '0 0 0 ? * MON', | 270 | + defaultValue: cycleTypeSetDefault.WEEKLY, |
| 280 | componentProps: { | 271 | componentProps: { |
| 281 | placeholder: '请选择周期', | 272 | placeholder: '请选择周期', |
| 282 | api: findDictItemByCode, | 273 | api: findDictItemByCode, |
| @@ -286,7 +277,8 @@ export const formSchema: QFormSchema[] = [ | @@ -286,7 +277,8 @@ export const formSchema: QFormSchema[] = [ | ||
| 286 | labelField: 'itemText', | 277 | labelField: 'itemText', |
| 287 | valueField: 'itemValue', | 278 | valueField: 'itemValue', |
| 288 | }, | 279 | }, |
| 289 | - ifShow: ({ values }) => isWeek(values.cycleType), | 280 | + ifShow: ({ values }) => |
| 281 | + exectueIsSchedule(values.executeWay) && cycleTypeIsWeekly(values.cycleType), | ||
| 290 | }, | 282 | }, |
| 291 | { | 283 | { |
| 292 | field: 'cycleTime', | 284 | field: 'cycleTime', |
| @@ -294,7 +286,7 @@ export const formSchema: QFormSchema[] = [ | @@ -294,7 +286,7 @@ export const formSchema: QFormSchema[] = [ | ||
| 294 | label: '每月', | 286 | label: '每月', |
| 295 | required: true, | 287 | required: true, |
| 296 | colProps: { span: 24 }, | 288 | colProps: { span: 24 }, |
| 297 | - defaultValue: '0 0 0 1 * ? *', | 289 | + defaultValue: cycleTypeSetDefault.MONTHLY, |
| 298 | componentProps: { | 290 | componentProps: { |
| 299 | placeholder: '请选择月份', | 291 | placeholder: '请选择月份', |
| 300 | api: findDictItemByCode, | 292 | api: findDictItemByCode, |
| @@ -304,7 +296,8 @@ export const formSchema: QFormSchema[] = [ | @@ -304,7 +296,8 @@ export const formSchema: QFormSchema[] = [ | ||
| 304 | labelField: 'itemText', | 296 | labelField: 'itemText', |
| 305 | valueField: 'itemValue', | 297 | valueField: 'itemValue', |
| 306 | }, | 298 | }, |
| 307 | - ifShow: ({ values }) => isMonth(values.cycleType), | 299 | + ifShow: ({ values }) => |
| 300 | + exectueIsSchedule(values.executeWay) && cycleTypeIsMonthly(values.cycleType), | ||
| 308 | }, | 301 | }, |
| 309 | { | 302 | { |
| 310 | field: 'cronTime', | 303 | field: 'cronTime', |
| @@ -312,7 +305,7 @@ export const formSchema: QFormSchema[] = [ | @@ -312,7 +305,7 @@ export const formSchema: QFormSchema[] = [ | ||
| 312 | label: '时间', | 305 | label: '时间', |
| 313 | required: true, | 306 | required: true, |
| 314 | colProps: { span: 24 }, | 307 | colProps: { span: 24 }, |
| 315 | - defaultValue: '0 0 0 * * ?', | 308 | + defaultValue: cycleTypeSetDefault.DAILY, |
| 316 | componentProps: { | 309 | componentProps: { |
| 317 | placeholder: '请选择时间', | 310 | placeholder: '请选择时间', |
| 318 | api: findDictItemByCode, | 311 | api: findDictItemByCode, |
| @@ -322,12 +315,13 @@ export const formSchema: QFormSchema[] = [ | @@ -322,12 +315,13 @@ export const formSchema: QFormSchema[] = [ | ||
| 322 | labelField: 'itemText', | 315 | labelField: 'itemText', |
| 323 | valueField: 'itemValue', | 316 | valueField: 'itemValue', |
| 324 | }, | 317 | }, |
| 325 | - ifShow: ({ values }) => isTiming(values.executeWay), | 318 | + ifShow: ({ values }) => |
| 319 | + exectueIsSchedule(values.executeWay) && exectueIsSchedule(values.executeWay), | ||
| 326 | }, | 320 | }, |
| 327 | { | 321 | { |
| 328 | field: 'devices', | 322 | field: 'devices', |
| 329 | label: '设备', | 323 | label: '设备', |
| 330 | - component: 'Select', | 324 | + component: 'Input', |
| 331 | slot: 'devices', | 325 | slot: 'devices', |
| 332 | colProps: { span: 24 }, | 326 | colProps: { span: 24 }, |
| 333 | }, | 327 | }, |
| @@ -338,42 +332,37 @@ export const formSchema: QFormSchema[] = [ | @@ -338,42 +332,37 @@ export const formSchema: QFormSchema[] = [ | ||
| 338 | component: 'Select', | 332 | component: 'Select', |
| 339 | componentProps: ({ formActionType }) => { | 333 | componentProps: ({ formActionType }) => { |
| 340 | const { updateSchema, setFieldsValue } = formActionType; | 334 | const { updateSchema, setFieldsValue } = formActionType; |
| 341 | - const options = [ | ||
| 342 | - { label: DataTypeNameEnum.ORIGINAL, value: DataTypeEnum.ORIGINAL }, | ||
| 343 | - { label: DataTypeNameEnum.AGG, value: DataTypeEnum.AGG }, | ||
| 344 | - ]; | ||
| 345 | return { | 335 | return { |
| 346 | - options, | 336 | + options: businesDataTypeOptions, |
| 347 | onSelect(e) { | 337 | onSelect(e) { |
| 348 | - let dataCompareOpions: any = []; | ||
| 349 | - if (e == 0) { | ||
| 350 | - setFieldsValue({ agg: 'NONE' }); | ||
| 351 | - dataCompareOpions = [{ label: '空', value: AggregateDataEnum.NONE }]; | 338 | + setFieldsValue({ |
| 339 | + [SchemaFiled.DATE_RANGE]: [], | ||
| 340 | + [SchemaFiled.START_TS]: null, | ||
| 341 | + [SchemaFiled.END_TS]: null, | ||
| 342 | + [SchemaFiled.INTERVAL]: null, | ||
| 343 | + dateGroupGap: null, | ||
| 344 | + }); | ||
| 345 | + const setAgg = (agg, field = SchemaFiled.AGG, comObj) => { | ||
| 346 | + setFieldsValue({ agg }); | ||
| 352 | updateSchema({ | 347 | updateSchema({ |
| 353 | - field: SchemaFiled.AGG, | ||
| 354 | - componentProps: { | ||
| 355 | - options: dataCompareOpions, | ||
| 356 | - }, | 348 | + field, |
| 349 | + componentProps: comObj, | ||
| 350 | + }); | ||
| 351 | + }; | ||
| 352 | + if (e == DataTypeEnum.ORIGINAL) { | ||
| 353 | + //业务 选择原始数据 | ||
| 354 | + setAgg('NONE', SchemaFiled.AGG, { | ||
| 355 | + options: businesAggOptions.filter((item) => item.value === AggregateDataEnum.NONE), | ||
| 357 | }); | 356 | }); |
| 357 | + setFieldsValue({ limit: businesLimitValue.default }); | ||
| 358 | } else { | 358 | } else { |
| 359 | - setFieldsValue({ agg: '' }); | ||
| 360 | - dataCompareOpions = [ | ||
| 361 | - { label: '最小值', value: AggregateDataEnum.MIN }, | ||
| 362 | - { label: '最大值', value: AggregateDataEnum.MAX }, | ||
| 363 | - { label: '平均值', value: AggregateDataEnum.AVG }, | ||
| 364 | - { label: '求和', value: AggregateDataEnum.SUM }, | ||
| 365 | - { label: '计数', value: AggregateDataEnum.COUNT }, | ||
| 366 | - ]; | ||
| 367 | - updateSchema({ | ||
| 368 | - field: SchemaFiled.AGG, | ||
| 369 | - componentProps: { | ||
| 370 | - options: dataCompareOpions, | ||
| 371 | - }, | 359 | + //业务 选择聚合数据 |
| 360 | + setAgg('', SchemaFiled.AGG, { | ||
| 361 | + options: businesAggOptions.filter((item) => item.value !== AggregateDataEnum.NONE), | ||
| 372 | }); | 362 | }); |
| 373 | } | 363 | } |
| 374 | }, | 364 | }, |
| 375 | - maxLength: 250, | ||
| 376 | - placeholder: '请选择属性性质', | 365 | + placeholder: '请选择数据类型', |
| 377 | }; | 366 | }; |
| 378 | }, | 367 | }, |
| 379 | colProps: { span: 24 }, | 368 | colProps: { span: 24 }, |
| @@ -393,15 +382,15 @@ export const formSchema: QFormSchema[] = [ | @@ -393,15 +382,15 @@ export const formSchema: QFormSchema[] = [ | ||
| 393 | required: true, | 382 | required: true, |
| 394 | label: '最大条数', | 383 | label: '最大条数', |
| 395 | component: 'InputNumber', | 384 | component: 'InputNumber', |
| 396 | - defaultValue: 100, | 385 | + defaultValue: businesLimitValue.default, |
| 397 | ifShow({ values }) { | 386 | ifShow({ values }) { |
| 398 | return values[SchemaFiled.AGG] === AggregateDataEnum.NONE; | 387 | return values[SchemaFiled.AGG] === AggregateDataEnum.NONE; |
| 399 | }, | 388 | }, |
| 400 | - colProps: { span: 12 }, | ||
| 401 | componentProps: { | 389 | componentProps: { |
| 390 | + style: { width: '10vw' }, | ||
| 402 | placeholder: '请输入最大条数', | 391 | placeholder: '请输入最大条数', |
| 403 | - min: 7, | ||
| 404 | - max: 50000, | 392 | + min: businesLimitValue.min, |
| 393 | + max: businesLimitValue.max, | ||
| 405 | }, | 394 | }, |
| 406 | }, | 395 | }, |
| 407 | { | 396 | { |
| @@ -414,18 +403,20 @@ export const formSchema: QFormSchema[] = [ | @@ -414,18 +403,20 @@ export const formSchema: QFormSchema[] = [ | ||
| 414 | const { setFieldsValue } = formActionType; | 403 | const { setFieldsValue } = formActionType; |
| 415 | return { | 404 | return { |
| 416 | placeholder: '请选择查询周期', | 405 | placeholder: '请选择查询周期', |
| 417 | - options: [ | ||
| 418 | - { label: '固定周期', value: QueryWay.LATEST }, | ||
| 419 | - { label: '自定义周期', value: QueryWay.TIME_PERIOD }, | ||
| 420 | - ], | 406 | + options: businesWayOptions, |
| 421 | onChange(value) { | 407 | onChange(value) { |
| 422 | value === QueryWay.LATEST | 408 | value === QueryWay.LATEST |
| 423 | ? setFieldsValue({ | 409 | ? setFieldsValue({ |
| 424 | [SchemaFiled.DATE_RANGE]: [], | 410 | [SchemaFiled.DATE_RANGE]: [], |
| 425 | [SchemaFiled.START_TS]: null, | 411 | [SchemaFiled.START_TS]: null, |
| 426 | [SchemaFiled.END_TS]: null, | 412 | [SchemaFiled.END_TS]: null, |
| 413 | + [SchemaFiled.INTERVAL]: null, | ||
| 414 | + dateGroupGap: null, | ||
| 427 | }) | 415 | }) |
| 428 | - : setFieldsValue({ [SchemaFiled.START_TS]: null }); | 416 | + : setFieldsValue({ |
| 417 | + [SchemaFiled.START_TS]: null, | ||
| 418 | + [SchemaFiled.INTERVAL]: null, | ||
| 419 | + }); | ||
| 429 | }, | 420 | }, |
| 430 | }; | 421 | }; |
| 431 | }, | 422 | }, |
| @@ -436,7 +427,7 @@ export const formSchema: QFormSchema[] = [ | @@ -436,7 +427,7 @@ export const formSchema: QFormSchema[] = [ | ||
| 436 | component: 'RangePicker', | 427 | component: 'RangePicker', |
| 437 | required: true, | 428 | required: true, |
| 438 | ifShow({ values }) { | 429 | ifShow({ values }) { |
| 439 | - return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay); | 430 | + return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && exectueIsImmed(values.executeWay); |
| 440 | }, | 431 | }, |
| 441 | componentProps({ formActionType }) { | 432 | componentProps({ formActionType }) { |
| 442 | const { setFieldsValue } = formActionType; | 433 | const { setFieldsValue } = formActionType; |
| @@ -462,14 +453,12 @@ export const formSchema: QFormSchema[] = [ | @@ -462,14 +453,12 @@ export const formSchema: QFormSchema[] = [ | ||
| 462 | getPopupContainer: () => document.body, | 453 | getPopupContainer: () => document.body, |
| 463 | }; | 454 | }; |
| 464 | }, | 455 | }, |
| 465 | - colProps: { | ||
| 466 | - span: 10, | ||
| 467 | - }, | ||
| 468 | }, | 456 | }, |
| 469 | { | 457 | { |
| 470 | field: 'dateGroupGap', | 458 | field: 'dateGroupGap', |
| 471 | label: '分组间隔', | 459 | label: '分组间隔', |
| 472 | component: 'Select', | 460 | component: 'Select', |
| 461 | + colProps: { span: 24 }, | ||
| 473 | dynamicRules: ({ model }) => { | 462 | dynamicRules: ({ model }) => { |
| 474 | return [ | 463 | return [ |
| 475 | { | 464 | { |
| @@ -480,7 +469,7 @@ export const formSchema: QFormSchema[] = [ | @@ -480,7 +469,7 @@ export const formSchema: QFormSchema[] = [ | ||
| 480 | ]; | 469 | ]; |
| 481 | }, | 470 | }, |
| 482 | ifShow({ values }) { | 471 | ifShow({ values }) { |
| 483 | - return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && !isFixedTime(values.executeWay); | 472 | + return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD && exectueIsImmed(values.executeWay); |
| 484 | }, | 473 | }, |
| 485 | componentProps({ formModel, formActionType }) { | 474 | componentProps({ formModel, formActionType }) { |
| 486 | const options = | 475 | const options = |
| @@ -542,3 +531,5 @@ export const formSchema: QFormSchema[] = [ | @@ -542,3 +531,5 @@ export const formSchema: QFormSchema[] = [ | ||
| 542 | }, | 531 | }, |
| 543 | }, | 532 | }, |
| 544 | ]; | 533 | ]; |
| 534 | + | ||
| 535 | +export { SchemaFiled }; |
src/views/report/config/cpns/deviceAttrCpns.css
deleted
100644 → 0
| 1 | -.dynamic-delete-button { | ||
| 2 | - cursor: pointer; | ||
| 3 | - position: relative; | ||
| 4 | - top: 4px; | ||
| 5 | - font-size: 24px; | ||
| 6 | - color: #999; | ||
| 7 | - transition: all 0.3s; | ||
| 8 | -} | ||
| 9 | - | ||
| 10 | -.dynamic-delete-button:hover { | ||
| 11 | - color: #777; | ||
| 12 | -} | ||
| 13 | - | ||
| 14 | -.dynamic-delete-button[disabled] { | ||
| 15 | - cursor: not-allowed; | ||
| 16 | - opacity: 0.5; | ||
| 17 | -} |
src/views/report/config/enum/index.ts
0 → 100644
| 1 | +/** | ||
| 2 | + * 报表配置相关枚举值定义 | ||
| 3 | + */ | ||
| 4 | +import { AggregateDataEnum } from '/@/views/device/localtion/cpns/TimePeriodForm/config'; | ||
| 5 | + | ||
| 6 | +//业务权限配置枚举 | ||
| 7 | +export enum PermissionReportConfigEnum { | ||
| 8 | + PERMISSION_POST = 'api:yt:report_form:config:post', | ||
| 9 | + PERMISSION_GET = 'api:yt:report:get', | ||
| 10 | + PERMISSION_DELETE = 'api:yt:report_form:config:delete', | ||
| 11 | + PERMISSION_UPDATE = 'api:yt:report_form:config:update', | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +//业务文字描述配置枚举 | ||
| 15 | +export enum BusinessReportConfigTextEnum { | ||
| 16 | + BUSINESS_ADD_TEXT = '新增报表', | ||
| 17 | + BUSINESS_EXPORT_TEXT = '下载报表', | ||
| 18 | + BUSINESS_DELETE_TEXT = '批量删除', | ||
| 19 | + BUSINESS_VIEW_DEVICE_TEXT = '查看设备', | ||
| 20 | + BUSINESS_UPDATE_TEXT = '编辑报表', | ||
| 21 | + BUSINESS_ENABLE_TEXT = '启用', | ||
| 22 | + BUSINESS_DISABLE_TEXT = '禁用', | ||
| 23 | + BUSINESS_VIEW_TEXT = '查看报表', | ||
| 24 | + BUSINESS_EXECUTEWAY_HELPMESSAGE_TEXT = `立即执行,在创建完报表配置后,启用配置即执行; | ||
| 25 | + 定时执行,用户定义执行时间,启用后, | ||
| 26 | + 在满足执行时间条件后,自动执行。 | ||
| 27 | + `, | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +//业务表格状态配置枚举 | ||
| 31 | +export enum BusinessReportConfigStatusEnum { | ||
| 32 | + BUSINESS_ENABLE = 0, | ||
| 33 | + BUSINESS_DISABLE = 1, | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +//业务表单执行方式配置枚举 | ||
| 37 | +export enum BusinessExecutewayEnum { | ||
| 38 | + BUSINESS_EXECUTEWAY_IMMEDIATE = 0, | ||
| 39 | + BUSINESS_EXECUTEWAY_SCHEDULED = 1, | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +//业务表单查询周期配置枚举 | ||
| 43 | +export enum QueryWay { | ||
| 44 | + LATEST = 'latest', | ||
| 45 | + TIME_PERIOD = 'timePeriod', | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +//业务表单周期配置枚举 | ||
| 49 | +export enum CycleTypeEnum { | ||
| 50 | + DAILY = 0, | ||
| 51 | + WEEKLY = 1, | ||
| 52 | + MONTHLY = 2, | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +export enum SchemaFiled { | ||
| 56 | + WAY = 'queryMode', | ||
| 57 | + TIME_PERIOD = 'timePeriod', | ||
| 58 | + KEYS = 'keys', | ||
| 59 | + DATE_RANGE = 'dataRange', | ||
| 60 | + START_TS = 'startTs', | ||
| 61 | + END_TS = 'endTs', | ||
| 62 | + INTERVAL = 'interval', | ||
| 63 | + LIMIT = 'limit', | ||
| 64 | + AGG = 'agg', | ||
| 65 | + ORDER_BY = 'orderBy', | ||
| 66 | + DATA_TYPE = 'dataType', | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +export enum DataTypeEnum { | ||
| 70 | + ORIGINAL = 0, | ||
| 71 | + AGG = 1, | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +export enum DataTypeNameEnum { | ||
| 75 | + ORIGINAL = '原始数据', | ||
| 76 | + AGG = '聚合数据', | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +//映射执行方式文本值 | ||
| 80 | +export enum ExecuteWayNameEnum { | ||
| 81 | + EXECUTEWAY_IMMEDIATE = '立即执行', | ||
| 82 | + EXECUTEWAY_SCHEDULED = '定时执行', | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +//业务表单执行方式配置项 | ||
| 86 | +export const businessExecuteWayOptions = [ | ||
| 87 | + { | ||
| 88 | + label: '立即执行', | ||
| 89 | + value: BusinessExecutewayEnum.BUSINESS_EXECUTEWAY_IMMEDIATE, | ||
| 90 | + }, | ||
| 91 | + { | ||
| 92 | + label: '定时执行', | ||
| 93 | + value: BusinessExecutewayEnum.BUSINESS_EXECUTEWAY_SCHEDULED, | ||
| 94 | + }, | ||
| 95 | +]; | ||
| 96 | + | ||
| 97 | +//业务表单查询周期配置项 | ||
| 98 | +export const businesQueryCycleOptions = [ | ||
| 99 | + { | ||
| 100 | + label: '固定周期', | ||
| 101 | + value: QueryWay.LATEST, | ||
| 102 | + }, | ||
| 103 | + { | ||
| 104 | + label: '自定义周期', | ||
| 105 | + value: QueryWay.TIME_PERIOD, | ||
| 106 | + }, | ||
| 107 | +]; | ||
| 108 | + | ||
| 109 | +//业务表单周期配置项 | ||
| 110 | +export const businesCycleTypeOptions = [ | ||
| 111 | + { label: '每日', value: CycleTypeEnum.DAILY }, | ||
| 112 | + { label: '每周', value: CycleTypeEnum.WEEKLY }, | ||
| 113 | + { label: '每月', value: CycleTypeEnum.MONTHLY }, | ||
| 114 | +]; | ||
| 115 | + | ||
| 116 | +//业务表单动态判断是否为定时执行配置项 | ||
| 117 | +export const exectueIsSchedule = (type: number) => { | ||
| 118 | + return type === BusinessExecutewayEnum.BUSINESS_EXECUTEWAY_SCHEDULED; | ||
| 119 | +}; | ||
| 120 | + | ||
| 121 | +//业务表单动态判断是否为立即执行配置项 | ||
| 122 | +export const exectueIsImmed = (type: number) => { | ||
| 123 | + return type === BusinessExecutewayEnum.BUSINESS_EXECUTEWAY_IMMEDIATE; | ||
| 124 | +}; | ||
| 125 | + | ||
| 126 | +//业务表单动态判断是否为每周配置项 | ||
| 127 | +export const cycleTypeIsWeekly = (type: number) => { | ||
| 128 | + return type === CycleTypeEnum.WEEKLY; | ||
| 129 | +}; | ||
| 130 | + | ||
| 131 | +//业务表单动态判断是否为每月配置项 | ||
| 132 | +export const cycleTypeIsMonthly = (type: number) => { | ||
| 133 | + return type === CycleTypeEnum.MONTHLY; | ||
| 134 | +}; | ||
| 135 | + | ||
| 136 | +//业务表单每周每日每月默认值配置 | ||
| 137 | +export const cycleTypeSetDefault = { | ||
| 138 | + DAILY: '0 0 0 * * ?', | ||
| 139 | + WEEKLY: '0 0 0 ? * MON', | ||
| 140 | + MONTHLY: '0 0 0 1 * ? *', | ||
| 141 | +}; | ||
| 142 | + | ||
| 143 | +//业务表单数据类型配置项 | ||
| 144 | +export const businesDataTypeOptions = [ | ||
| 145 | + { label: DataTypeNameEnum.ORIGINAL, value: DataTypeEnum.ORIGINAL }, | ||
| 146 | + { label: DataTypeNameEnum.AGG, value: DataTypeEnum.AGG }, | ||
| 147 | +]; | ||
| 148 | + | ||
| 149 | +//业务表单聚合条件配置项 | ||
| 150 | +export const businesAggOptions = [ | ||
| 151 | + { label: '最小值', value: AggregateDataEnum.MIN }, | ||
| 152 | + { label: '最大值', value: AggregateDataEnum.MAX }, | ||
| 153 | + { label: '平均值', value: AggregateDataEnum.AVG }, | ||
| 154 | + { label: '求和', value: AggregateDataEnum.SUM }, | ||
| 155 | + { label: '计数', value: AggregateDataEnum.COUNT }, | ||
| 156 | + { label: '空', value: AggregateDataEnum.NONE }, | ||
| 157 | +]; | ||
| 158 | + | ||
| 159 | +//业务表单最大条数配置项 | ||
| 160 | +export const businesLimitValue = { | ||
| 161 | + default: 100, | ||
| 162 | + min: 7, | ||
| 163 | + max: 50000, | ||
| 164 | +}; | ||
| 165 | + | ||
| 166 | +//业务查询周期配置项 | ||
| 167 | +export const businesWayOptions = [ | ||
| 168 | + { label: '固定周期', value: QueryWay.LATEST }, | ||
| 169 | + { label: '自定义周期', value: QueryWay.TIME_PERIOD }, | ||
| 170 | +]; |
src/views/report/config/hooks/index.hooks.ts
0 → 100644
| 1 | +/** | ||
| 2 | + * 报表配置所需hooks | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +import { ref } from 'vue'; | ||
| 6 | +import { | ||
| 7 | + DataTypeEnum, | ||
| 8 | + QueryWay, | ||
| 9 | + SchemaFiled, | ||
| 10 | + businesAggOptions, | ||
| 11 | + BusinessExecutewayEnum, | ||
| 12 | + businesWayOptions, | ||
| 13 | + CycleTypeEnum, | ||
| 14 | + BusinessReportConfigTextEnum, | ||
| 15 | +} from '../enum'; | ||
| 16 | +import moment from 'moment'; | ||
| 17 | +import { DeviceTypeEnum } from '/@/api/device/model/deviceModel'; | ||
| 18 | +import { getAttribute, screenLinkPageByDeptIdGetDevice } from '/@/api/ruleengine/ruleengineApi'; | ||
| 19 | +import { TSelectOption } from '../type'; | ||
| 20 | +import { AggregateDataEnum } from '/@/views/device/localtion/config.data'; | ||
| 21 | +import { useMessage } from '/@/hooks/web/useMessage'; | ||
| 22 | + | ||
| 23 | +export const useHooks = () => { | ||
| 24 | + const { createMessage } = useMessage(); | ||
| 25 | + | ||
| 26 | + //获取设备 | ||
| 27 | + const getDeviceList = async (organizationId) => { | ||
| 28 | + const { items } = await screenLinkPageByDeptIdGetDevice({ | ||
| 29 | + organizationId, | ||
| 30 | + }); | ||
| 31 | + return items?.map((item) => { | ||
| 32 | + if (item.deviceType !== DeviceTypeEnum.GATEWAY) | ||
| 33 | + return { | ||
| 34 | + label: item.alias ? item.alias : item.name, | ||
| 35 | + value: item.tbDeviceId, | ||
| 36 | + id: item.id, | ||
| 37 | + deviceProfileId: item.deviceProfileId, | ||
| 38 | + }; | ||
| 39 | + }); | ||
| 40 | + }; | ||
| 41 | + | ||
| 42 | + //获取对应设备属性 | ||
| 43 | + const getDeviceAttr = async (deviceProfileId) => { | ||
| 44 | + //业务 根据产品id | ||
| 45 | + if (!deviceProfileId) return; | ||
| 46 | + const res = await getAttribute(deviceProfileId); | ||
| 47 | + if (!Array.isArray(res)) return; | ||
| 48 | + return res.map((items) => { | ||
| 49 | + const item = ref<TSelectOption>(); | ||
| 50 | + if (items?.identifier !== null) { | ||
| 51 | + item.value = { | ||
| 52 | + label: items?.identifier, | ||
| 53 | + value: items?.identifier, | ||
| 54 | + }; | ||
| 55 | + return item.value; | ||
| 56 | + } | ||
| 57 | + }); | ||
| 58 | + }; | ||
| 59 | + | ||
| 60 | + //映射查询周期值 | ||
| 61 | + const mapQueryMode = (queryMode) => { | ||
| 62 | + return queryMode === QueryWay.LATEST ? 0 : 1; | ||
| 63 | + }; | ||
| 64 | + | ||
| 65 | + //映射查询周期文本 | ||
| 66 | + const mapQueryModeText = (queryMode) => { | ||
| 67 | + return queryMode === 0 ? QueryWay.LATEST : QueryWay.TIME_PERIOD; | ||
| 68 | + }; | ||
| 69 | + | ||
| 70 | + //要删除的字段,不需要传给服务端 | ||
| 71 | + const removeFields = [ | ||
| 72 | + 'agg', | ||
| 73 | + 'interval', | ||
| 74 | + 'queryMode', | ||
| 75 | + 'startTs', | ||
| 76 | + 'devices', | ||
| 77 | + 'dataRange', | ||
| 78 | + 'cycleType', | ||
| 79 | + 'currentCycle', | ||
| 80 | + 'cycleTime', | ||
| 81 | + 'cronTime', | ||
| 82 | + 'limit', | ||
| 83 | + 'dateGroupGap', | ||
| 84 | + ]; | ||
| 85 | + | ||
| 86 | + //获取表单部分字段组合成queryCondition和cycle对象和根据cron表达式生成executeContent | ||
| 87 | + const getQueryCondition = (values) => { | ||
| 88 | + const { | ||
| 89 | + agg, | ||
| 90 | + queryMode, | ||
| 91 | + startTs, | ||
| 92 | + interval, | ||
| 93 | + dateGroupGap, | ||
| 94 | + cycleType, | ||
| 95 | + currentCycle, | ||
| 96 | + cycleTime, | ||
| 97 | + cronTime, | ||
| 98 | + limit, | ||
| 99 | + } = values; | ||
| 100 | + const startTsValue = ref(); | ||
| 101 | + const endTsValue = ref(); | ||
| 102 | + const intervalValue = ref(); | ||
| 103 | + if (queryMode === QueryWay.LATEST) { | ||
| 104 | + //业务 查询周期为固定周期 | ||
| 105 | + startTsValue.value = moment().subtract(startTs, 'ms').valueOf(); | ||
| 106 | + endTsValue.value = Date.now(); | ||
| 107 | + intervalValue.value = interval; | ||
| 108 | + } else { | ||
| 109 | + //业务 查询周期为自定义周期 | ||
| 110 | + const defineDate = JSON.parse(JSON.stringify(values.dataRange)); | ||
| 111 | + startTsValue.value = moment(defineDate[0]).valueOf(); | ||
| 112 | + endTsValue.value = moment(defineDate[1]).valueOf(); | ||
| 113 | + intervalValue.value = dateGroupGap; | ||
| 114 | + } | ||
| 115 | + const executeContent = ref(''); | ||
| 116 | + if (cycleType === CycleTypeEnum.WEEKLY) { | ||
| 117 | + executeContent.value = cronTime.slice(0, 6) + currentCycle.slice(5); | ||
| 118 | + } else if (cycleType === CycleTypeEnum.DAILY) { | ||
| 119 | + executeContent.value = cronTime; | ||
| 120 | + } else if (cycleType === CycleTypeEnum.MONTHLY) { | ||
| 121 | + executeContent.value = cronTime.slice(0, 6) + cycleTime.slice(5); | ||
| 122 | + } | ||
| 123 | + return [ | ||
| 124 | + { | ||
| 125 | + limit, | ||
| 126 | + agg, | ||
| 127 | + interval: intervalValue.value, | ||
| 128 | + queryMode: mapQueryMode(queryMode), | ||
| 129 | + startTs: startTsValue.value, | ||
| 130 | + endTs: endTsValue.value, | ||
| 131 | + }, | ||
| 132 | + { | ||
| 133 | + cycleType, | ||
| 134 | + currentCycle, | ||
| 135 | + cycleTime, | ||
| 136 | + cronTime, | ||
| 137 | + }, | ||
| 138 | + executeContent.value, | ||
| 139 | + ]; | ||
| 140 | + }; | ||
| 141 | + | ||
| 142 | + //新增默认设置部分字段(执行方式,查询周期,最近时间,间隔时间) | ||
| 143 | + const setDefaultTime = () => { | ||
| 144 | + return { | ||
| 145 | + executeWay: BusinessExecutewayEnum.BUSINESS_EXECUTEWAY_IMMEDIATE, | ||
| 146 | + [SchemaFiled.WAY]: QueryWay.LATEST, | ||
| 147 | + [SchemaFiled.START_TS]: 1000, | ||
| 148 | + [SchemaFiled.INTERVAL]: 1000, | ||
| 149 | + }; | ||
| 150 | + }; | ||
| 151 | + | ||
| 152 | + //编辑回显queryCondition和cycle对象 | ||
| 153 | + const setQueryCondition = (value, cycle, executeContent) => { | ||
| 154 | + const conditionObj = ref({}); | ||
| 155 | + //业务 查询周期是固定周期 | ||
| 156 | + if (value?.queryMode === 0) { | ||
| 157 | + const formatNumber = (value?.endTs - value?.startTs) / 10; | ||
| 158 | + const transNumber = Math.floor(formatNumber) * 10; | ||
| 159 | + conditionObj.value = { | ||
| 160 | + interval: value?.interval, | ||
| 161 | + startTs: transNumber, | ||
| 162 | + endTs: value?.endTs, | ||
| 163 | + }; | ||
| 164 | + } else { | ||
| 165 | + conditionObj.value = { | ||
| 166 | + dataRange: [value?.startTs, value?.endTs], | ||
| 167 | + dateGroupGap: value?.interval, | ||
| 168 | + }; | ||
| 169 | + } | ||
| 170 | + const spanDisance = executeContent?.split(' '); | ||
| 171 | + const cronTime = | ||
| 172 | + cycle?.cycleType === 2 | ||
| 173 | + ? spanDisance[2] < 10 | ||
| 174 | + ? executeContent.slice(0, 7) + '* * ?' | ||
| 175 | + : executeContent.slice(0, 7) + ' ' + '* * ?' | ||
| 176 | + : cycle?.cycleType === 1 | ||
| 177 | + ? spanDisance[2] < 10 | ||
| 178 | + ? executeContent.slice(0, 5) + ' ' + ' * * ?' | ||
| 179 | + : executeContent.slice(0, 6) + ' ' + ' * * ?' | ||
| 180 | + : executeContent; | ||
| 181 | + return { | ||
| 182 | + ...value, | ||
| 183 | + ...conditionObj.value, | ||
| 184 | + ...cycle, | ||
| 185 | + cronTime, | ||
| 186 | + queryMode: mapQueryModeText(value?.queryMode), | ||
| 187 | + }; | ||
| 188 | + }; | ||
| 189 | + | ||
| 190 | + //业务 回显聚合条件如果数据类型是原始数据则只有空 | ||
| 191 | + const setAggByDateType = (dataType) => { | ||
| 192 | + const options = ref([]); | ||
| 193 | + if (dataType === DataTypeEnum.ORIGINAL) { | ||
| 194 | + options.value = businesAggOptions.filter( | ||
| 195 | + (item) => item.value === AggregateDataEnum.NONE | ||
| 196 | + ) as any; | ||
| 197 | + } else | ||
| 198 | + options.value = businesAggOptions.filter( | ||
| 199 | + (item) => item.value !== AggregateDataEnum.NONE | ||
| 200 | + ) as any; | ||
| 201 | + return { | ||
| 202 | + field: SchemaFiled.AGG, | ||
| 203 | + componentProps: { | ||
| 204 | + options: options.value, | ||
| 205 | + }, | ||
| 206 | + }; | ||
| 207 | + }; | ||
| 208 | + | ||
| 209 | + //业务 执行方式为定时执行 查询周期只有固定周期 | ||
| 210 | + const disableCustomWeekly = (type) => { | ||
| 211 | + const options = ref([]); | ||
| 212 | + if (type === BusinessExecutewayEnum.BUSINESS_EXECUTEWAY_SCHEDULED) { | ||
| 213 | + options.value = businesWayOptions.filter((item) => item.value === QueryWay.LATEST) as any; | ||
| 214 | + } else { | ||
| 215 | + options.value = businesWayOptions as any; | ||
| 216 | + } | ||
| 217 | + return { | ||
| 218 | + field: SchemaFiled.WAY, | ||
| 219 | + componentProps: { | ||
| 220 | + options: options.value, | ||
| 221 | + }, | ||
| 222 | + }; | ||
| 223 | + }; | ||
| 224 | + | ||
| 225 | + //Modal弹窗属性 | ||
| 226 | + const setPropsForModal = (text) => { | ||
| 227 | + return { | ||
| 228 | + loading: true, | ||
| 229 | + title: text, | ||
| 230 | + showOkBtn: text !== BusinessReportConfigTextEnum.BUSINESS_VIEW_TEXT, | ||
| 231 | + showCancelBtn: text !== BusinessReportConfigTextEnum.BUSINESS_VIEW_TEXT, | ||
| 232 | + }; | ||
| 233 | + }; | ||
| 234 | + | ||
| 235 | + //验证设备以及所选属性 | ||
| 236 | + const validateSelectDevice = (values) => { | ||
| 237 | + const throwErrorMsg = () => { | ||
| 238 | + createMessage.error('请选择设备及其属性'); | ||
| 239 | + throw new Error('请选择设备及其属性'); | ||
| 240 | + }; | ||
| 241 | + if (Array.isArray(values) && values.length === 0) throwErrorMsg(); | ||
| 242 | + else { | ||
| 243 | + values.forEach((f) => { | ||
| 244 | + if (!f.attributes || f.attributes.length == 0) throwErrorMsg(); | ||
| 245 | + }); | ||
| 246 | + } | ||
| 247 | + }; | ||
| 248 | + | ||
| 249 | + return { | ||
| 250 | + getDeviceList, | ||
| 251 | + getQueryCondition, | ||
| 252 | + removeFields, | ||
| 253 | + setDefaultTime, | ||
| 254 | + getDeviceAttr, | ||
| 255 | + setQueryCondition, | ||
| 256 | + setAggByDateType, | ||
| 257 | + disableCustomWeekly, | ||
| 258 | + setPropsForModal, | ||
| 259 | + validateSelectDevice, | ||
| 260 | + }; | ||
| 261 | +}; |
| 1 | <template> | 1 | <template> |
| 2 | <div> | 2 | <div> |
| 3 | - <BasicTable :clickToRowSelect="false" @register="registerTable" :searchInfo="searchInfo"> | 3 | + <BasicTable :clickToRowSelect="false" @register="registerTable"> |
| 4 | <template #toolbar> | 4 | <template #toolbar> |
| 5 | - <Authority value="api:yt:report_form:config:post"> | ||
| 6 | - <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增报表 </a-button> | 5 | + <Authority :value="PermissionReportConfigEnum.PERMISSION_POST"> |
| 6 | + <a-button | ||
| 7 | + type="primary" | ||
| 8 | + @click="handleBussinessDrawer(BusinessReportConfigTextEnum.BUSINESS_ADD_TEXT, null)" | ||
| 9 | + > | ||
| 10 | + {{ BusinessReportConfigTextEnum.BUSINESS_ADD_TEXT }} | ||
| 11 | + </a-button> | ||
| 7 | </Authority> | 12 | </Authority> |
| 8 | - <Authority value="api:yt:report:get"> | ||
| 9 | - <a-button type="primary" @click="go('/report/export')"> 下载报表 </a-button> | 13 | + <Authority :value="PermissionReportConfigEnum.PERMISSION_GET"> |
| 14 | + <a-button type="primary" @click="go('/report/export')"> | ||
| 15 | + {{ BusinessReportConfigTextEnum.BUSINESS_EXPORT_TEXT }} | ||
| 16 | + </a-button> | ||
| 10 | </Authority> | 17 | </Authority> |
| 11 | - <Authority value="api:yt:report_form:config:delete"> | 18 | + <Authority :value="PermissionReportConfigEnum.PERMISSION_DELETE"> |
| 12 | <Popconfirm | 19 | <Popconfirm |
| 13 | title="您确定要批量删除数据" | 20 | title="您确定要批量删除数据" |
| 14 | ok-text="确定" | 21 | ok-text="确定" |
| 15 | cancel-text="取消" | 22 | cancel-text="取消" |
| 16 | @confirm="handleDeleteOrBatchDelete(null)" | 23 | @confirm="handleDeleteOrBatchDelete(null)" |
| 17 | > | 24 | > |
| 18 | - <a-button type="primary" color="error" :disabled="hasBatchDelete"> 批量删除 </a-button> | 25 | + <a-button type="primary" color="error" :disabled="hasBatchDelete"> |
| 26 | + {{ BusinessReportConfigTextEnum.BUSINESS_DELETE_TEXT }} | ||
| 27 | + </a-button> | ||
| 19 | </Popconfirm> | 28 | </Popconfirm> |
| 20 | </Authority> | 29 | </Authority> |
| 21 | </template> | 30 | </template> |
| 22 | <template #doDeviceSlot="{ record }"> | 31 | <template #doDeviceSlot="{ record }"> |
| 23 | <a-button type="text" @click="handleDeviceView(record)"> | 32 | <a-button type="text" @click="handleDeviceView(record)"> |
| 24 | - <span style="color: #377dff">查看设备</span> | 33 | + <span style="color: #377dff">{{ |
| 34 | + BusinessReportConfigTextEnum.BUSINESS_VIEW_DEVICE_TEXT | ||
| 35 | + }}</span> | ||
| 25 | </a-button> | 36 | </a-button> |
| 26 | </template> | 37 | </template> |
| 27 | <template #action="{ record }"> | 38 | <template #action="{ record }"> |
| 28 | <TableAction | 39 | <TableAction |
| 29 | :actions="[ | 40 | :actions="[ |
| 30 | { | 41 | { |
| 31 | - label: '查看', | 42 | + label: BusinessReportConfigTextEnum.BUSINESS_VIEW_TEXT.slice(0, 2), |
| 32 | icon: 'ant-design:eye-outlined', | 43 | icon: 'ant-design:eye-outlined', |
| 33 | - onClick: handleViewDetail.bind(null, record), | 44 | + onClick: handleBussinessDrawer.bind( |
| 45 | + null, | ||
| 46 | + BusinessReportConfigTextEnum.BUSINESS_VIEW_TEXT, | ||
| 47 | + record | ||
| 48 | + ), | ||
| 34 | ifShow: record.status === 1, | 49 | ifShow: record.status === 1, |
| 35 | }, | 50 | }, |
| 36 | { | 51 | { |
| 37 | - label: '编辑', | 52 | + label: BusinessReportConfigTextEnum.BUSINESS_UPDATE_TEXT.slice(0, 2), |
| 38 | icon: 'clarity:note-edit-line', | 53 | icon: 'clarity:note-edit-line', |
| 39 | - auth: 'api:yt:report_form:config:update', | ||
| 40 | - onClick: handleCreateOrEdit.bind(null, record), | 54 | + auth: PermissionReportConfigEnum.PERMISSION_UPDATE, |
| 55 | + onClick: handleBussinessDrawer.bind( | ||
| 56 | + null, | ||
| 57 | + BusinessReportConfigTextEnum.BUSINESS_UPDATE_TEXT, | ||
| 58 | + record | ||
| 59 | + ), | ||
| 41 | ifShow: record.status === 0, | 60 | ifShow: record.status === 0, |
| 42 | }, | 61 | }, |
| 43 | { | 62 | { |
| 44 | - label: '删除', | 63 | + label: BusinessReportConfigTextEnum.BUSINESS_DELETE_TEXT.slice(2), |
| 45 | icon: 'ant-design:delete-outlined', | 64 | icon: 'ant-design:delete-outlined', |
| 46 | - auth: 'api:yt:report_form:config:delete', | 65 | + auth: PermissionReportConfigEnum.PERMISSION_DELETE, |
| 47 | color: 'error', | 66 | color: 'error', |
| 48 | ifShow: record.status === 0, | 67 | ifShow: record.status === 0, |
| 49 | popConfirm: { | 68 | popConfirm: { |
| @@ -59,8 +78,8 @@ | @@ -59,8 +78,8 @@ | ||
| 59 | :disabled="disabledSwitch" | 78 | :disabled="disabledSwitch" |
| 60 | :checked="record.status === 1" | 79 | :checked="record.status === 1" |
| 61 | :loading="record.pendingStatus" | 80 | :loading="record.pendingStatus" |
| 62 | - checkedChildren="启用" | ||
| 63 | - unCheckedChildren="禁用" | 81 | + :checkedChildren="BusinessReportConfigTextEnum.BUSINESS_ENABLE_TEXT" |
| 82 | + :unCheckedChildren="BusinessReportConfigTextEnum.BUSINESS_DISABLE_TEXT" | ||
| 64 | @change="(checked: boolean) => statusChange(checked, record)" | 83 | @change="(checked: boolean) => statusChange(checked, record)" |
| 65 | /> | 84 | /> |
| 66 | </template> | 85 | </template> |
| @@ -71,130 +90,96 @@ | @@ -71,130 +90,96 @@ | ||
| 71 | </template> | 90 | </template> |
| 72 | 91 | ||
| 73 | <script lang="ts" setup> | 92 | <script lang="ts" setup> |
| 74 | - import { reactive, nextTick, ref } from 'vue'; | 93 | + import { nextTick, ref } from 'vue'; |
| 75 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 94 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
| 76 | import { useDrawer } from '/@/components/Drawer'; | 95 | import { useDrawer } from '/@/components/Drawer'; |
| 77 | - import ReportConfigDrawer from './ReportConfigDrawer.vue'; | ||
| 78 | - import DevicePreviewModal from './DevicePreviewModal.vue'; | ||
| 79 | import { | 96 | import { |
| 80 | reportPage, | 97 | reportPage, |
| 81 | deleteReportManage, | 98 | deleteReportManage, |
| 82 | putReportByidAndStatusManage, | 99 | putReportByidAndStatusManage, |
| 83 | } from '/@/api/report/reportManager'; | 100 | } from '/@/api/report/reportManager'; |
| 84 | - import { searchFormSchema, columns } from './config.data'; | 101 | + import { defaultTableAttribtes } from './config'; |
| 85 | import { Authority } from '/@/components/Authority'; | 102 | import { Authority } from '/@/components/Authority'; |
| 86 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | 103 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; |
| 87 | import { Popconfirm, Switch } from 'ant-design-vue'; | 104 | import { Popconfirm, Switch } from 'ant-design-vue'; |
| 88 | import { useModal } from '/@/components/Modal'; | 105 | import { useModal } from '/@/components/Modal'; |
| 89 | import { useGo } from '/@/hooks/web/usePage'; | 106 | import { useGo } from '/@/hooks/web/usePage'; |
| 90 | import { useMessage } from '/@/hooks/web/useMessage'; | 107 | import { useMessage } from '/@/hooks/web/useMessage'; |
| 108 | + import { ReportConfigDrawer, DevicePreviewModal } from './components'; | ||
| 109 | + import { | ||
| 110 | + PermissionReportConfigEnum, | ||
| 111 | + BusinessReportConfigTextEnum, | ||
| 112 | + BusinessReportConfigStatusEnum, | ||
| 113 | + } from './enum'; | ||
| 91 | 114 | ||
| 92 | - const searchInfo = reactive<Recordable>({}); | ||
| 93 | const disabledSwitch = ref(false); | 115 | const disabledSwitch = ref(false); |
| 94 | 116 | ||
| 95 | const [registerTable, { reload, setProps, setSelectedRowKeys }] = useTable({ | 117 | const [registerTable, { reload, setProps, setSelectedRowKeys }] = useTable({ |
| 96 | - title: '报表列表', | ||
| 97 | api: reportPage, | 118 | api: reportPage, |
| 98 | - columns, | ||
| 99 | - showIndexColumn: false, | ||
| 100 | - clickToRowSelect: false, | ||
| 101 | - formConfig: { | ||
| 102 | - labelWidth: 120, | ||
| 103 | - schemas: searchFormSchema, | ||
| 104 | - fieldMapToTime: [['sendTime', ['startTime', 'endTime'], 'x']], | ||
| 105 | - }, | ||
| 106 | - useSearchForm: true, | ||
| 107 | - showTableSetting: true, | ||
| 108 | - bordered: true, | ||
| 109 | - rowKey: 'id', | ||
| 110 | - actionColumn: { | ||
| 111 | - width: 200, | ||
| 112 | - title: '操作', | ||
| 113 | - dataIndex: 'action', | ||
| 114 | - slots: { customRender: 'action' }, | ||
| 115 | - fixed: 'right', | ||
| 116 | - }, | 119 | + ...defaultTableAttribtes, |
| 117 | }); | 120 | }); |
| 118 | 121 | ||
| 119 | - // 弹框 | 122 | + // 业务弹窗 |
| 120 | const [registerDrawer, { openDrawer }] = useDrawer(); | 123 | const [registerDrawer, { openDrawer }] = useDrawer(); |
| 124 | + | ||
| 121 | const { createMessage } = useMessage(); | 125 | const { createMessage } = useMessage(); |
| 122 | 126 | ||
| 123 | - // 刷新 | ||
| 124 | const handleSuccess = () => { | 127 | const handleSuccess = () => { |
| 125 | reload(); | 128 | reload(); |
| 126 | }; | 129 | }; |
| 127 | 130 | ||
| 128 | const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } = | 131 | const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } = |
| 129 | - useBatchDelete(deleteReportManage, handleSuccess, setProps); | 132 | + useBatchDelete(deleteReportManage, handleSuccess, setProps) as any; |
| 130 | selectionOptions.rowSelection.getCheckboxProps = (record: Recordable) => { | 133 | selectionOptions.rowSelection.getCheckboxProps = (record: Recordable) => { |
| 131 | - // Demo:status为1的选择框禁用 | ||
| 132 | - if (record.status === 1) { | 134 | + //业务 status为1 选择框则禁用 |
| 135 | + if (record.status === BusinessReportConfigStatusEnum.BUSINESS_DISABLE) | ||
| 133 | return { disabled: true }; | 136 | return { disabled: true }; |
| 134 | - } else { | ||
| 135 | - return { disabled: false }; | ||
| 136 | - } | 137 | + else return { disabled: false }; |
| 137 | }; | 138 | }; |
| 138 | 139 | ||
| 139 | nextTick(() => { | 140 | nextTick(() => { |
| 140 | setProps(selectionOptions); | 141 | setProps(selectionOptions); |
| 141 | }); | 142 | }); |
| 142 | 143 | ||
| 143 | - // 新增或编辑 | ||
| 144 | - const handleCreateOrEdit = (record: Recordable | null) => { | ||
| 145 | - if (record) { | ||
| 146 | - openDrawer(true, { | ||
| 147 | - isUpdate: true, | ||
| 148 | - record, | ||
| 149 | - isView: true, | ||
| 150 | - }); | ||
| 151 | - } else { | ||
| 152 | - openDrawer(true, { | ||
| 153 | - isUpdate: false, | ||
| 154 | - isView: true, | ||
| 155 | - }); | ||
| 156 | - } | ||
| 157 | - }; | ||
| 158 | - const handleViewDetail = (record: Recordable) => { | ||
| 159 | - if (record) { | ||
| 160 | - openDrawer(true, { | ||
| 161 | - isUpdate: true, | ||
| 162 | - record, | ||
| 163 | - isView: false, | ||
| 164 | - }); | ||
| 165 | - } | 144 | + // 业务弹窗 |
| 145 | + const handleBussinessDrawer = (text, record) => { | ||
| 146 | + const modalParams = { | ||
| 147 | + text, | ||
| 148 | + record, | ||
| 149 | + }; | ||
| 150 | + openDrawer(true, modalParams); | ||
| 166 | }; | 151 | }; |
| 167 | 152 | ||
| 168 | //查看设备 | 153 | //查看设备 |
| 169 | const [registerModal, { openModal }] = useModal(); | 154 | const [registerModal, { openModal }] = useModal(); |
| 155 | + | ||
| 170 | const handleDeviceView = (record) => { | 156 | const handleDeviceView = (record) => { |
| 171 | openModal(true, { | 157 | openModal(true, { |
| 172 | isUpdate: true, | 158 | isUpdate: true, |
| 173 | record, | 159 | record, |
| 174 | }); | 160 | }); |
| 175 | }; | 161 | }; |
| 162 | + | ||
| 163 | + const setPropsLoading = (loading) => { | ||
| 164 | + setProps({ | ||
| 165 | + loading, | ||
| 166 | + }); | ||
| 167 | + setSelectedRowKeys([]); | ||
| 168 | + resetSelectedRowKeys(); | ||
| 169 | + }; | ||
| 170 | + | ||
| 176 | const statusChange = async (checked, record) => { | 171 | const statusChange = async (checked, record) => { |
| 177 | try { | 172 | try { |
| 178 | - setProps({ | ||
| 179 | - loading: true, | ||
| 180 | - }); | ||
| 181 | - setSelectedRowKeys([]); | ||
| 182 | - resetSelectedRowKeys(); | 173 | + setPropsLoading(true); |
| 183 | disabledSwitch.value = true; | 174 | disabledSwitch.value = true; |
| 184 | const newStatus = checked ? 1 : 0; | 175 | const newStatus = checked ? 1 : 0; |
| 185 | const res = await putReportByidAndStatusManage(record.id, newStatus); | 176 | const res = await putReportByidAndStatusManage(record.id, newStatus); |
| 186 | - if (res && newStatus) { | ||
| 187 | - createMessage.success(`启用成功`); | ||
| 188 | - } else { | ||
| 189 | - createMessage.success('禁用成功'); | ||
| 190 | - } | 177 | + if (res && newStatus) |
| 178 | + createMessage.success(`${BusinessReportConfigTextEnum.BUSINESS_ENABLE_TEXT}成功`); | ||
| 179 | + else createMessage.success(`${BusinessReportConfigTextEnum.BUSINESS_DISABLE_TEXT}成功`); | ||
| 191 | } finally { | 180 | } finally { |
| 192 | - setTimeout(() => { | ||
| 193 | - setProps({ | ||
| 194 | - loading: false, | ||
| 195 | - }); | ||
| 196 | - disabledSwitch.value = false; | ||
| 197 | - }, 500); | 181 | + setPropsLoading(false); |
| 182 | + disabledSwitch.value = false; | ||
| 198 | reload(); | 183 | reload(); |
| 199 | } | 184 | } |
| 200 | }; | 185 | }; |
src/views/report/config/timeConfig.ts
deleted
100644 → 0
| 1 | -interface IOptionConfig { | ||
| 2 | - label: string; | ||
| 3 | - value: number; | ||
| 4 | -} | ||
| 5 | - | ||
| 6 | -export const optionsConfig: IOptionConfig[] = [ | ||
| 7 | - { | ||
| 8 | - label: '1秒', | ||
| 9 | - value: 1000, | ||
| 10 | - }, | ||
| 11 | - { | ||
| 12 | - label: '5秒', | ||
| 13 | - value: 5000, | ||
| 14 | - }, | ||
| 15 | - { | ||
| 16 | - label: '10秒', | ||
| 17 | - value: 10000, | ||
| 18 | - }, | ||
| 19 | - { | ||
| 20 | - label: '15秒', | ||
| 21 | - value: 15000, | ||
| 22 | - }, | ||
| 23 | - { | ||
| 24 | - label: '30秒', | ||
| 25 | - value: 30000, | ||
| 26 | - }, | ||
| 27 | - { | ||
| 28 | - label: '1分钟', | ||
| 29 | - value: 60000, | ||
| 30 | - }, | ||
| 31 | - { | ||
| 32 | - label: '2分钟', | ||
| 33 | - value: 120000, | ||
| 34 | - }, | ||
| 35 | - { | ||
| 36 | - label: '5分钟', | ||
| 37 | - value: 300000, | ||
| 38 | - }, | ||
| 39 | - { | ||
| 40 | - label: '10分钟', | ||
| 41 | - value: 600000, | ||
| 42 | - }, | ||
| 43 | - { | ||
| 44 | - label: '15分钟', | ||
| 45 | - value: 900000, | ||
| 46 | - }, | ||
| 47 | - { | ||
| 48 | - label: '30分钟', | ||
| 49 | - value: 1800000, | ||
| 50 | - }, | ||
| 51 | - { | ||
| 52 | - label: '1小时', | ||
| 53 | - value: 3600000, | ||
| 54 | - }, | ||
| 55 | - { | ||
| 56 | - label: '2小时', | ||
| 57 | - value: 7200000, | ||
| 58 | - }, | ||
| 59 | - { | ||
| 60 | - label: '5小时', | ||
| 61 | - value: 18000000, | ||
| 62 | - }, | ||
| 63 | - { | ||
| 64 | - label: '10小时', | ||
| 65 | - value: 36000000, | ||
| 66 | - }, | ||
| 67 | - { | ||
| 68 | - label: '12小时', | ||
| 69 | - value: 43200000, | ||
| 70 | - }, | ||
| 71 | - { | ||
| 72 | - label: '1天', | ||
| 73 | - value: 86400000, | ||
| 74 | - }, | ||
| 75 | -]; | ||
| 76 | - | ||
| 77 | -export enum TypeEnum { | ||
| 78 | - IS_TIMING = 1, | ||
| 79 | - IS_WEEK = 1, | ||
| 80 | - IS_MONTH = 2, | ||
| 81 | - IS_EMPTY = 'NONE', | ||
| 82 | - IS_DEFAULT_WEEK = 'defaultIsWeek', | ||
| 83 | - IS_FIXED_WEEK = '2', | ||
| 84 | - IS_MIN = 'MIN', | ||
| 85 | - IS_MAX = 'MAX', | ||
| 86 | - IS_AVG = 'AVG', | ||
| 87 | - IS_SUM = 'SUM', | ||
| 88 | - COUNT = 'COUNT', | ||
| 89 | - IS_FIXED_TIME = 1, | ||
| 90 | -} | ||
| 91 | - | ||
| 92 | -export enum AggregateDataEnum { | ||
| 93 | - MIN = 'MIN', | ||
| 94 | - MAX = 'MAX', | ||
| 95 | - AVG = 'AVG', | ||
| 96 | - SUM = 'SUM', | ||
| 97 | - COUNT = 'COUNT', | ||
| 98 | - NONE = 'NONE', | ||
| 99 | -} | ||
| 100 | -export const isFixedTime = (type: string) => { | ||
| 101 | - return type === TypeEnum.IS_FIXED_TIME; | ||
| 102 | -}; | ||
| 103 | - | ||
| 104 | -export const isTiming = (type: string) => { | ||
| 105 | - return type === TypeEnum.IS_TIMING; | ||
| 106 | -}; | ||
| 107 | - | ||
| 108 | -export const isWeek = (type: string) => { | ||
| 109 | - return type === TypeEnum.IS_WEEK; | ||
| 110 | -}; | ||
| 111 | - | ||
| 112 | -export const isMonth = (type: string) => { | ||
| 113 | - return type === TypeEnum.IS_MONTH; | ||
| 114 | -}; | ||
| 115 | - | ||
| 116 | -export const isEmpty = (type: string) => { | ||
| 117 | - return type === TypeEnum.IS_EMPTY; | ||
| 118 | -}; | ||
| 119 | - | ||
| 120 | -export const isDefultWeek = (type: string) => { | ||
| 121 | - return type === TypeEnum.IS_DEFAULT_WEEK; | ||
| 122 | -}; | ||
| 123 | -export const isFixedWeek = (type: string) => { | ||
| 124 | - return type === TypeEnum.IS_FIXED_WEEK; | ||
| 125 | -}; | ||
| 126 | - | ||
| 127 | -export const isMin = (type: string) => { | ||
| 128 | - return type === TypeEnum.IS_MIN; | ||
| 129 | -}; | ||
| 130 | - | ||
| 131 | -export const isMax = (type: string) => { | ||
| 132 | - return type === TypeEnum.IS_MAX; | ||
| 133 | -}; | ||
| 134 | - | ||
| 135 | -export const isAvg = (type: string) => { | ||
| 136 | - return type === TypeEnum.IS_AVG; | ||
| 137 | -}; | ||
| 138 | -export const isSum = (type: string) => { | ||
| 139 | - return type === TypeEnum.IS_SUM; | ||
| 140 | -}; | ||
| 141 | - | ||
| 142 | -export const isCountAll = (type: string) => { | ||
| 143 | - return type === TypeEnum.COUNT; | ||
| 144 | -}; |
src/views/report/config/type/index.ts
0 → 100644
| 1 | +/** | ||
| 2 | + * 报表配置相关类型定义 | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +//设备列表类型定义 | ||
| 6 | +export type TDeviceList = { | ||
| 7 | + key?: string; | ||
| 8 | + value?: string; | ||
| 9 | + label?: string; | ||
| 10 | + attribute?: string; | ||
| 11 | + device?: string; | ||
| 12 | + name?: string; | ||
| 13 | + attributes?: string | undefined; | ||
| 14 | + deviceProfileId?: string; | ||
| 15 | + id?: string; | ||
| 16 | +}; | ||
| 17 | + | ||
| 18 | +//设备下拉框类型定义 | ||
| 19 | +export type TSelectOption = { | ||
| 20 | + label: string; | ||
| 21 | + value: string; | ||
| 22 | + deviceProfileId?: string; | ||
| 23 | + id?: string; | ||
| 24 | +}; | ||
| 25 | + | ||
| 26 | +//设备属性 | ||
| 27 | +export interface Params { | ||
| 28 | + [x: string]: string; | ||
| 29 | + attributes: any; | ||
| 30 | + device: string; | ||
| 31 | +} |
src/views/report/export/ReportPreviewModal.less
deleted
100644 → 0
src/views/report/export/components/ReportPreviewModal.vue
renamed from
src/views/report/export/ReportPreviewModal.vue
| @@ -306,7 +306,20 @@ | @@ -306,7 +306,20 @@ | ||
| 306 | }); | 306 | }); |
| 307 | </script> | 307 | </script> |
| 308 | <style lang="less" scoped> | 308 | <style lang="less" scoped> |
| 309 | - @import url('./ReportPreviewModal.less'); | 309 | + .wrapper { |
| 310 | + margin: 10px 60px 60px 60px; | ||
| 311 | + } | ||
| 312 | + | ||
| 313 | + .inner { | ||
| 314 | + width: 400px; | ||
| 315 | + height: 400px; | ||
| 316 | + } | ||
| 317 | + | ||
| 318 | + .item { | ||
| 319 | + text-align: center; | ||
| 320 | + font-size: 200%; | ||
| 321 | + color: #fff; | ||
| 322 | + } | ||
| 310 | 323 | ||
| 311 | .chart-style { | 324 | .chart-style { |
| 312 | display: flex; | 325 | display: flex; |
src/views/report/export/components/index.ts
0 → 100644
src/views/report/export/config.ts
renamed from
src/views/report/export/config.data.ts
| 1 | -import { BasicColumn, FormSchema } from '/@/components/Table'; | 1 | +import { BasicColumn, BasicTableProps, FormSchema } from '/@/components/Table'; |
| 2 | import moment from 'moment'; | 2 | import moment from 'moment'; |
| 3 | import { h } from 'vue'; | 3 | import { h } from 'vue'; |
| 4 | import { Tag } from 'ant-design-vue'; | 4 | import { Tag } from 'ant-design-vue'; |
| 5 | +import { DataTypeNameEnum, ExecuteWayNameEnum } from '../config/enum'; | ||
| 5 | 6 | ||
| 6 | // 表格配置 | 7 | // 表格配置 |
| 7 | export const columns: BasicColumn[] = [ | 8 | export const columns: BasicColumn[] = [ |
| @@ -20,7 +21,7 @@ export const columns: BasicColumn[] = [ | @@ -20,7 +21,7 @@ export const columns: BasicColumn[] = [ | ||
| 20 | dataIndex: 'dataType', | 21 | dataIndex: 'dataType', |
| 21 | width: 120, | 22 | width: 120, |
| 22 | format: (_text: string, record: Recordable) => { | 23 | format: (_text: string, record: Recordable) => { |
| 23 | - return record.dataCompare === 0 ? '原始数据' : '聚合数据'; | 24 | + return record.dataCompare === 0 ? DataTypeNameEnum.ORIGINAL : DataTypeNameEnum.AGG; |
| 24 | }, | 25 | }, |
| 25 | }, | 26 | }, |
| 26 | { | 27 | { |
| @@ -28,7 +29,9 @@ export const columns: BasicColumn[] = [ | @@ -28,7 +29,9 @@ export const columns: BasicColumn[] = [ | ||
| 28 | dataIndex: 'executeWay', | 29 | dataIndex: 'executeWay', |
| 29 | width: 120, | 30 | width: 120, |
| 30 | format: (_text: string, record: Recordable) => { | 31 | format: (_text: string, record: Recordable) => { |
| 31 | - return record.executeWay === 0 ? '立即执行' : '定时执行'; | 32 | + return record.executeWay === 0 |
| 33 | + ? ExecuteWayNameEnum.EXECUTEWAY_IMMEDIATE | ||
| 34 | + : ExecuteWayNameEnum.EXECUTEWAY_SCHEDULED; | ||
| 32 | }, | 35 | }, |
| 33 | }, | 36 | }, |
| 34 | { | 37 | { |
| @@ -49,7 +52,7 @@ export const columns: BasicColumn[] = [ | @@ -49,7 +52,7 @@ export const columns: BasicColumn[] = [ | ||
| 49 | }, | 52 | }, |
| 50 | ]; | 53 | ]; |
| 51 | 54 | ||
| 52 | -// 查询配置 | 55 | +// 表格查询配置 |
| 53 | export const searchFormSchema: FormSchema[] = [ | 56 | export const searchFormSchema: FormSchema[] = [ |
| 54 | { | 57 | { |
| 55 | field: 'reportConfigName', | 58 | field: 'reportConfigName', |
| @@ -96,3 +99,27 @@ export const searchFormSchema: FormSchema[] = [ | @@ -96,3 +99,27 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 96 | colProps: { span: 6 }, | 99 | colProps: { span: 6 }, |
| 97 | }, | 100 | }, |
| 98 | ]; | 101 | ]; |
| 102 | + | ||
| 103 | +//表格通用属性配置 | ||
| 104 | +export const defaultTableAttribtes: BasicTableProps = { | ||
| 105 | + title: '报表导出列表', | ||
| 106 | + columns, | ||
| 107 | + showIndexColumn: false, | ||
| 108 | + clickToRowSelect: false, | ||
| 109 | + formConfig: { | ||
| 110 | + labelWidth: 120, | ||
| 111 | + schemas: searchFormSchema, | ||
| 112 | + fieldMapToTime: [['sendTime', ['startTime', 'endTime'], 'x']], | ||
| 113 | + }, | ||
| 114 | + useSearchForm: true, | ||
| 115 | + showTableSetting: true, | ||
| 116 | + bordered: true, | ||
| 117 | + rowKey: 'id', | ||
| 118 | + actionColumn: { | ||
| 119 | + width: 200, | ||
| 120 | + title: '操作', | ||
| 121 | + dataIndex: 'action', | ||
| 122 | + slots: { customRender: 'action' }, | ||
| 123 | + fixed: 'right', | ||
| 124 | + }, | ||
| 125 | +}; |
src/views/report/export/enum/index.ts
0 → 100644
| 1 | +/** | ||
| 2 | + * 报表导出相关枚举值定义 | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +//业务权限配置枚举 | ||
| 6 | +export enum PermissionReportExportEnum { | ||
| 7 | + PERMISSION_GET = 'api:yt:reportExport:get', | ||
| 8 | + PERMISSION_EXPORT = 'api:yt:reportExport:export', | ||
| 9 | + PERMISSION_DELETE = 'api:yt:report:generate:record:delete', | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +//业务文字描述配置枚举 | ||
| 13 | +export enum BusinessReportExportTextEnum { | ||
| 14 | + BUSINESS_EXPORT_TEXT = '报表导出', | ||
| 15 | + BUSINESS_DELETE_TEXT = '批量删除', | ||
| 16 | + BUSINESS_VIEW_TEXT = '报表查看', | ||
| 17 | +} |
| 1 | <template> | 1 | <template> |
| 2 | <div> | 2 | <div> |
| 3 | - <BasicTable :clickToRowSelect="false" @register="registerTable" :searchInfo="searchInfo"> | 3 | + <BasicTable :clickToRowSelect="false" @register="registerTable"> |
| 4 | <template #toolbar> | 4 | <template #toolbar> |
| 5 | - <Authority value="api:yt:report:generate:record:delete"> | 5 | + <Authority :value="PermissionReportExportEnum.PERMISSION_DELETE"> |
| 6 | <Popconfirm | 6 | <Popconfirm |
| 7 | title="您确定要批量删除数据" | 7 | title="您确定要批量删除数据" |
| 8 | ok-text="确定" | 8 | ok-text="确定" |
| 9 | cancel-text="取消" | 9 | cancel-text="取消" |
| 10 | @confirm="handleDeleteOrBatchDelete(null)" | 10 | @confirm="handleDeleteOrBatchDelete(null)" |
| 11 | > | 11 | > |
| 12 | - <a-button type="primary" color="error" :disabled="hasBatchDelete"> 批量删除 </a-button> | 12 | + <a-button type="primary" color="error" :disabled="hasBatchDelete"> |
| 13 | + {{ BusinessReportExportTextEnum.BUSINESS_DELETE_TEXT }} | ||
| 14 | + </a-button> | ||
| 13 | </Popconfirm> | 15 | </Popconfirm> |
| 14 | </Authority> | 16 | </Authority> |
| 15 | </template> | 17 | </template> |
| @@ -17,9 +19,9 @@ | @@ -17,9 +19,9 @@ | ||
| 17 | <TableAction | 19 | <TableAction |
| 18 | :actions="[ | 20 | :actions="[ |
| 19 | { | 21 | { |
| 20 | - label: '报表导出', | 22 | + label: BusinessReportExportTextEnum.BUSINESS_EXPORT_TEXT, |
| 21 | icon: 'ant-design:dot-chart-outlined', | 23 | icon: 'ant-design:dot-chart-outlined', |
| 22 | - auth: 'api:yt:reportExport:export', | 24 | + auth: PermissionReportExportEnum.PERMISSION_EXPORT, |
| 23 | ifShow: record.executeStatus === 1, | 25 | ifShow: record.executeStatus === 1, |
| 24 | popConfirm: { | 26 | popConfirm: { |
| 25 | title: '是否需要导出', | 27 | title: '是否需要导出', |
| @@ -27,15 +29,15 @@ | @@ -27,15 +29,15 @@ | ||
| 27 | }, | 29 | }, |
| 28 | }, | 30 | }, |
| 29 | { | 31 | { |
| 30 | - label: '报表查看', | 32 | + label: BusinessReportExportTextEnum.BUSINESS_VIEW_TEXT, |
| 31 | icon: 'clarity:note-edit-line', | 33 | icon: 'clarity:note-edit-line', |
| 32 | - auth: 'api:yt:reportExport:get', | 34 | + auth: PermissionReportExportEnum.PERMISSION_GET, |
| 33 | onClick: handleView.bind(null, record), | 35 | onClick: handleView.bind(null, record), |
| 34 | }, | 36 | }, |
| 35 | { | 37 | { |
| 36 | - label: '删除', | 38 | + label: BusinessReportExportTextEnum.BUSINESS_DELETE_TEXT.slice(2), |
| 37 | icon: 'ant-design:delete-outlined', | 39 | icon: 'ant-design:delete-outlined', |
| 38 | - auth: 'api:yt:report:generate:record:delete', | 40 | + auth: PermissionReportExportEnum.PERMISSION_DELETE, |
| 39 | color: 'error', | 41 | color: 'error', |
| 40 | popConfirm: { | 42 | popConfirm: { |
| 41 | title: '是否确认删除', | 43 | title: '是否确认删除', |
| @@ -51,40 +53,21 @@ | @@ -51,40 +53,21 @@ | ||
| 51 | </template> | 53 | </template> |
| 52 | 54 | ||
| 53 | <script lang="ts" setup> | 55 | <script lang="ts" setup> |
| 54 | - import { reactive, nextTick } from 'vue'; | 56 | + import { nextTick } from 'vue'; |
| 55 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 57 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
| 56 | - import { searchFormSchema, columns } from './config.data'; | 58 | + import { defaultTableAttribtes } from './config'; |
| 57 | import { Authority } from '/@/components/Authority'; | 59 | import { Authority } from '/@/components/Authority'; |
| 58 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; | 60 | import { useBatchDelete } from '/@/hooks/web/useBatchDelete'; |
| 59 | import { Popconfirm } from 'ant-design-vue'; | 61 | import { Popconfirm } from 'ant-design-vue'; |
| 60 | import { useModal } from '/@/components/Modal'; | 62 | import { useModal } from '/@/components/Modal'; |
| 61 | - import ReportPreviewModal from './ReportPreviewModal.vue'; | 63 | + import { ReportPreviewModal } from './components'; |
| 62 | import { exportPage, deleteExportManage } from '/@/api/export/exportManager'; | 64 | import { exportPage, deleteExportManage } from '/@/api/export/exportManager'; |
| 63 | import { downloadByUrl } from '/@/utils/file/download'; | 65 | import { downloadByUrl } from '/@/utils/file/download'; |
| 66 | + import { PermissionReportExportEnum, BusinessReportExportTextEnum } from './enum'; | ||
| 64 | 67 | ||
| 65 | - const searchInfo = reactive<Recordable>({}); | ||
| 66 | const [registerTable, { reload, setProps }] = useTable({ | 68 | const [registerTable, { reload, setProps }] = useTable({ |
| 67 | - title: '报表导出列表', | ||
| 68 | api: exportPage, | 69 | api: exportPage, |
| 69 | - columns, | ||
| 70 | - showIndexColumn: false, | ||
| 71 | - clickToRowSelect: false, | ||
| 72 | - formConfig: { | ||
| 73 | - labelWidth: 120, | ||
| 74 | - schemas: searchFormSchema, | ||
| 75 | - fieldMapToTime: [['sendTime', ['startTime', 'endTime'], 'x']], | ||
| 76 | - }, | ||
| 77 | - useSearchForm: true, | ||
| 78 | - showTableSetting: true, | ||
| 79 | - bordered: true, | ||
| 80 | - rowKey: 'id', | ||
| 81 | - actionColumn: { | ||
| 82 | - width: 200, | ||
| 83 | - title: '操作', | ||
| 84 | - dataIndex: 'action', | ||
| 85 | - slots: { customRender: 'action' }, | ||
| 86 | - fixed: 'right', | ||
| 87 | - }, | 70 | + ...defaultTableAttribtes, |
| 88 | }); | 71 | }); |
| 89 | 72 | ||
| 90 | const handleSuccess = () => { | 73 | const handleSuccess = () => { |
| @@ -101,19 +84,23 @@ | @@ -101,19 +84,23 @@ | ||
| 101 | setProps(selectionOptions); | 84 | setProps(selectionOptions); |
| 102 | }); | 85 | }); |
| 103 | 86 | ||
| 87 | + //业务弹窗 | ||
| 104 | const [registerModal, { openModal }] = useModal(); | 88 | const [registerModal, { openModal }] = useModal(); |
| 89 | + | ||
| 105 | const handleView = (record) => { | 90 | const handleView = (record) => { |
| 106 | openModal(true, { | 91 | openModal(true, { |
| 107 | isUpdate: true, | 92 | isUpdate: true, |
| 108 | record, | 93 | record, |
| 109 | }); | 94 | }); |
| 110 | }; | 95 | }; |
| 96 | + | ||
| 111 | const exportUrlsFunc = (fUrl) => { | 97 | const exportUrlsFunc = (fUrl) => { |
| 112 | const options: any = { | 98 | const options: any = { |
| 113 | url: fUrl, | 99 | url: fUrl, |
| 114 | }; | 100 | }; |
| 115 | downloadByUrl(options); | 101 | downloadByUrl(options); |
| 116 | }; | 102 | }; |
| 103 | + | ||
| 117 | const handleExport = (record) => { | 104 | const handleExport = (record) => { |
| 118 | if (record.reportPath) { | 105 | if (record.reportPath) { |
| 119 | const urls = record.reportPath.split(','); | 106 | const urls = record.reportPath.split(','); |