Преглед изворни кода

[Feat 0000] 开发可配置首页的配置表页面

houzekong пре 7 месеци
родитељ
комит
5a981ef610

+ 1 - 8
src/views/vent/deviceManager/configurationTable/adapters.ts

@@ -6,21 +6,14 @@ export function parseFormDataToParams(formData: Record<string, number | string |
   const params = {};
   _.forEach(formData, (v: string | undefined, k) => {
     if (!v) return;
-    // 如果是以 moduleData/showStyle 打头的数据要特殊处理,因为这是配置的主要项目,表单配置见 ./configuration.data
-    if (k.startsWith('moduleData')) {
-      return _.set(params, k, JSON.parse(v));
-    }
     return _.set(params, k, v);
   });
 
   return params;
 }
 
-/** 将 api.list 返回的 moduleData 格式化,格式化之后可以支持对应的表单以用,该方法会修改源数据 */
+/** 将 api.list 返回的数据格式化,格式化之后可以支持对应的表单以用,该方法会修改源数据 */
 export function parseModuleData(listData: { moduleData: ModuleData; showStyle: ShowStyle }) {
-  _.forEach(listData.moduleData, (v, k) => {
-    listData[`moduleData.${k}`] = JSON.stringify(v);
-  });
   _.forEach(listData.showStyle, (v, k) => {
     listData[`showStyle.${k}`] = v;
   });

+ 19 - 10
src/views/vent/deviceManager/configurationTable/configuration.data.ts

@@ -1,5 +1,5 @@
 // import { ModuleVersionOptions, ModuleChartTypeOptions, ModulePositionOptions, ModuleSizeOptions } from './options';
-import { ModulePositionOptions, ModuleSizeOptions, ModuleVersionOptions } from './options';
+import { ModulePositionOptions, ModulePresetOptions, ModuleVersionOptions } from './options';
 import { BasicColumn } from '/@/components/Table';
 import { FormSchema } from '/@/components/Table';
 import _ from 'lodash-es';
@@ -18,13 +18,13 @@ export const columns: BasicColumn[] = [
     dataIndex: 'moduleName',
   },
   {
-    title: '预设类型',
-    dataIndex: 'moduleData.main',
-  },
-  {
-    title: '模块尺寸',
-    dataIndex: 'showStyle.size',
+    title: '原始预设名称',
+    dataIndex: 'desc',
   },
+  // {
+  //   title: '模块尺寸',
+  //   dataIndex: 'showStyle.size',
+  // },
   {
     title: '模块版本',
     dataIndex: 'showStyle.version',
@@ -69,6 +69,7 @@ export const formSchema: FormSchema[] = [
     label: '模块标题',
     field: 'moduleName',
     component: 'Input',
+    required: true,
   },
   {
     label: '设备类型',
@@ -91,17 +92,19 @@ export const formSchema: FormSchema[] = [
     },
   },
   {
-    label: '模块尺寸',
-    field: 'showStyle.size',
+    label: '原始预设名称',
+    field: 'desc',
     component: 'Select',
+    required: true,
     componentProps: {
-      options: ModuleSizeOptions,
+      options: ModulePresetOptions,
     },
   },
   {
     label: '模块版本',
     field: 'showStyle.version',
     component: 'Select',
+    required: true,
     componentProps: {
       options: ModuleVersionOptions,
     },
@@ -110,8 +113,14 @@ export const formSchema: FormSchema[] = [
     label: '模块定位',
     field: 'showStyle.position',
     component: 'Select',
+    required: true,
     componentProps: {
       options: ModulePositionOptions,
     },
   },
+  {
+    label: '允许预设配置覆盖',
+    field: 'allowCover',
+    component: 'Checkbox',
+  },
 ];

+ 169 - 47
src/views/vent/deviceManager/configurationTable/index.vue

@@ -1,57 +1,179 @@
 <!-- eslint-disable vue/multi-word-component-names -->
 <template>
-  <div class="device-manager-box">
-    <NormalTable
-      :columns="columns"
-      :searchFormSchema="searchFormSchema"
-      :formSchema="formSchema"
-      :list="list"
-      :deleteById="deleteById"
-      :saveOrUpdate="saveOrUpdate"
-      title="配置列表"
-      :showTab="false"
-      :deviceType="deviceType"
-    >
-      <template #filterCell="{ column, record }">
-        <template v-if="column.key === 'moduleData.main'">
-          <div v-for="(val, key) in record.moduleData.main" :key="key">
-            <span>点位:{{ key }};</span>
-            <span>名称:{{ val }};</span>
-          </div>
-        </template>
-        <template v-if="column.key === 'moduleData.chart'">
-          <div v-for="(val, key) in record.moduleData.chart" :key="key">
-            <span>点位:{{ key }};</span>
-            <span>名称:{{ val }};</span>
-          </div>
-        </template>
-        <template v-if="column.key === 'showStyle.size'">
-          {{ get(ModuleSizeMap, record.showStyle?.size) }}
-        </template>
-        <!-- <template v-if="column.key === 'showStyle.version'">
-          {{ get(ModuleVersionMap, record.showStyle?.version) }}
-        </template> -->
-        <template v-if="column.key === 'showStyle.position'">
-          {{ get(ModulePositionMap, record.showStyle?.position) }}
-        </template>
-        <!-- <template v-if="column.key === 'showStyle.charttype'">
-          {{ get(ModuleChartTypeMap, record.showStyle?.charttype) }}
-        </template> -->
-      </template>
-    </NormalTable>
-  </div>
+  <BasicTable @register="registerTable">
+    <template #tableTitle>
+      <a-button preIcon="ant-design:plus-outlined" type="primary" @click="handleAdd">新增</a-button>
+    </template>
+    <template #action="{ record }">
+      <a class="table-action-link" @click="handleConfig(record)">配置</a>
+      <a class="table-action-link" @click="handleEdit(record)">编辑</a>
+      <a-popconfirm title="确定删除?" @confirm="handleDelete(record)">
+        <a class="table-action-link">删除</a>
+      </a-popconfirm>
+    </template>
+    <!-- <template #bodyCell="{ column, record }">
+      <slot name="filterCell" v-bind="{ column, record }"></slot>
+    </template> -->
+  </BasicTable>
+  <DeviceModal @register="registerModal" @save-or-update="saveOrUpdateHandler" :showTab="false" :deviceType="deviceType" />
+  <BasicModal @register="registerConfigModal" @ok="handleUpdate" title="配置文件编辑" defaultFullscreen>
+    <CodeEditor v-model:value="configJSON" />
+  </BasicModal>
 </template>
 
-<script lang="ts" name="system-user" setup>
-  // 相关文档请参阅 vent/home/configurable/README.md
-  import { ref } from 'vue';
-  import NormalTable from '../comment/NormalTable.vue';
+<script lang="ts" setup>
+  //ts语法
+  import { ref, provide, reactive, toRaw } from 'vue';
+  import { BasicTable } from '/@/components/Table';
+  import { useModal } from '/@/components/Modal';
+  import DeviceModal from '../comment/DeviceModal.vue';
+  // import { getToken } from '/@/utils/auth';
+  // import { useGlobSetting } from '/@/hooks/setting';
+  import { useListPage } from '/@/hooks/system/useListPage';
   import { list, deleteById, saveOrUpdate } from './configuration.api';
-  import { ModulePositionMap, ModuleSizeMap } from './options';
   import { searchFormSchema, columns, formSchema } from './configuration.data';
-  import { get } from '../../home/billboard/utils';
+  import { message } from 'ant-design-vue';
+  import { BasicModal } from '/@/components/Modal';
+  import CodeEditor from '/@/components/CodeEditor/src/CodeEditor.vue';
+  import { ModulePresetMap } from './options';
+  import { merge } from 'lodash-es';
 
+  const formData = reactive({});
+  const isUpdate = ref(false);
   const deviceType = ref('');
+  const formSchemaData = ref(formSchema);
+  // const pageType = ref('');
+  const configJSON = ref('');
+
+  provide('formSchema', formSchemaData);
+  provide('isUpdate', isUpdate);
+  provide('formData', formData);
+  provide('deviceType', deviceType);
+
+  // const glob = useGlobSetting();
+  const [registerModal, { openModal, closeModal }] = useModal();
+  const [registerConfigModal, configModalCtx] = useModal();
+
+  // 列表页面公共参数、方法
+  const { tableContext } = useListPage({
+    tableProps: {
+      title: '配置列表',
+      api: list,
+      columns,
+      showTableSetting: false,
+      // size: 'small',
+      // bordered: false,
+      formConfig: {
+        showAdvancedButton: true,
+        // labelWidth: 100,
+        labelAlign: 'left',
+        labelCol: {
+          xs: 24,
+          sm: 24,
+          md: 24,
+          lg: 9,
+          xl: 7,
+          xxl: 5,
+        },
+        schemas: searchFormSchema,
+      },
+      useSearchForm: true,
+      striped: true,
+      actionColumn: {
+        width: 180,
+      },
+    },
+  });
+
+  //注册table数据
+  const [registerTable, { reload }] = tableContext;
+
+  const saveOrUpdateHandler = async (params) => {
+    // 如果是新增或者选择了覆盖配置选项的则初始化配置
+    if (!isUpdate.value || params.allowCover) {
+      merge(params, ModulePresetMap[params.desc]);
+    }
+    try {
+      await saveOrUpdate(params, isUpdate.value);
+      closeModal();
+      reload();
+    } catch (error) {
+      message.error('保存失败,请联系管理员');
+    }
+  };
+
+  /**
+   * 新增事件
+   */
+  function handleAdd() {
+    for (let key in formData) {
+      delete formData[key];
+    }
+    isUpdate.value = false;
+    openModal(true);
+  }
+
+  /**
+   * 编辑事件
+   */
+  function handleEdit(record) {
+    isUpdate.value = true;
+    Object.assign(formData, toRaw(record));
+    openModal(true, { formData }, false);
+  }
+
+  /**
+   * 删除事件
+   */
+  async function handleDelete(record) {
+    await deleteById({ id: record.id }, reload);
+  }
+
+  function handleConfig(record) {
+    Object.assign(formData, toRaw(record));
+    configJSON.value = record.moduleData || '';
+    configModalCtx.openModal();
+  }
+
+  /** 更新配置详情 */
+  async function handleUpdate() {
+    isUpdate.value = true;
+    saveOrUpdateHandler({
+      ...formData,
+      moduleData: JSON.parse(configJSON.value),
+    }).finally(() => {
+      configModalCtx.closeModal();
+    });
+  }
 </script>
 
-<style scoped></style>
+<style scoped lang="less">
+  @ventSpace: zxm;
+  @vent-table-no-hover: #00bfff10;
+
+  :deep(.@{ventSpace}-table-cell-row-hover) {
+    background: #264d8833 !important;
+  }
+  :deep(.@{ventSpace}-table-row-selected) {
+    background: #268bc522 !important;
+  }
+
+  :deep(.@{ventSpace}-table-tbody > tr > td) {
+    background-color: #0dc3ff05;
+  }
+  :deep(.jeecg-basic-table-row__striped) {
+    td {
+      background-color: @vent-table-no-hover !important;
+    }
+  }
+  :deep(.@{ventSpace}-select-dropdown) {
+    .@{ventSpace}-select-item-option-selected,
+    .@{ventSpace}-select-item-option-active {
+      background-color: #ffffff33 !important;
+    }
+
+    .@{ventSpace}-select-item:hover {
+      background-color: #ffffff33 !important;
+    }
+  }
+</style>

+ 104 - 6
src/views/vent/deviceManager/configurationTable/options.ts

@@ -12,13 +12,9 @@ export const ModuleSizeOptions = _.map(ModuleSizeMap, (_, k) => ({
   label: k,
 }));
 
-export const ModuleVersionMap = {
-  original: '原版',
-  enhanced: '新版',
-};
-export const ModuleVersionOptions = _.map(ModuleVersionMap, (v, k) => ({
+export const ModuleVersionOptions = _.map(['原版', '新版'], (k) => ({
   value: k,
-  label: v,
+  label: k,
 }));
 
 export const ModulePositionMap = {
@@ -36,6 +32,108 @@ export const ModulePositionOptions = _.map(ModulePositionMap, (_, k) => ({
   label: k,
 }));
 
+export const ModulePresetOptions = _.map(['局扇预设(1*1)', '传感器预设(1*2)'], (k) => ({
+  value: k,
+  label: k,
+}));
+export const ModulePresetMap = {
+  '局扇预设(1*1)': {
+    moduleData: {
+      header: {
+        show: true,
+        showSelector: true,
+        showSlot: true,
+        selector: {
+          prop: 'strinstallpos',
+        },
+        slot: {
+          prop: 'strinstallpos',
+        },
+      },
+      background: {
+        show: true,
+        type: 'video',
+        link: '/src/assets/vedio/fanLocal.mp4',
+      },
+      layout: ['board'],
+      board: [
+        {
+          type: 'A',
+          layout: 'val-top',
+          items: [
+            {
+              prop: 'readData.windSpeed1',
+              label: '风速1',
+            },
+            {
+              label: '风速2',
+              prop: 'readData.windSpeed2',
+            },
+          ],
+        },
+      ],
+      list: [],
+      chart: [],
+      table: [],
+      gallery: [],
+      preset: [],
+    },
+    showStyle: {
+      size: '标准尺寸(450*280)',
+      version: 'enhanced',
+      position: '左上',
+    },
+  },
+  '传感器预设(1*2)': {
+    moduleData: {
+      header: {
+        show: false,
+        showSelector: false,
+        showSlot: false,
+        selector: {
+          icon: 'SwapOutlined',
+          prop: 'strinstallpos',
+        },
+        slot: {
+          icon: 'SwapOutlined',
+          prop: 'strinstallpos',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: ['chart'],
+      board: [],
+      list: [],
+      table: [],
+      preset: [],
+      gallery: [],
+      chart: [
+        {
+          type: 'bar',
+          readFrom: 'sysdata.history',
+          xAxis: [{ prop: 'time' }],
+          yAxis: [
+            { label: '回1', align: 'left' },
+            // { label: '回2', align: 'right' },
+          ],
+          series: [
+            { label: '回1', prop: 'hui1' },
+            // { label: '回2', prop: 'hui2' },
+          ],
+        },
+      ],
+    },
+    showStyle: {
+      size: '横向拉伸(1000*280)',
+      version: 'enhanced',
+      position: '中下',
+    },
+  },
+};
+
 // export const ModuleChartTypeMap = {
 //   pie: '饼状图',
 //   bar: '柱状图',

+ 2 - 1
src/views/vent/deviceManager/configurationTable/types.ts

@@ -6,6 +6,7 @@ export interface Config {
   deviceType: string;
   moduleData: ModuleData;
   showStyle: ShowStyle;
+  desc?: string;
 }
 
 export interface ModuleDataBoard {
@@ -135,7 +136,7 @@ export interface ShowStyle {
   /** 模块的宽高 */
   size: keyof typeof ModuleSizeMap;
   /** 模块的版本,分新版及旧版,只要有一个模块指定为旧版,那么整个页面风格将变更为旧版 */
-  version: 'original' | 'enhanced';
+  version: '原版' | '新版';
   /** 模块的位置,即定位 */
   position: keyof typeof ModulePositionMap;
 }

+ 1 - 1
src/views/vent/home/configurable/configurable.data.ts

@@ -719,7 +719,7 @@ export const testConfigA: Config[] = [
       board: [],
       gallery: [
         {
-          type: 'B',
+          type: 'A',
           items: [
             {
               prop: 'total',

+ 1 - 1
src/views/vent/home/configurable/hooks/useInit.ts

@@ -26,7 +26,7 @@ export function useInitConfigs() {
   const configs = ref<Config[]>([]);
   const isOriginal = computed(() => {
     return configs.value.some((c) => {
-      return c.showStyle.version === 'original';
+      return c.showStyle.version === '原版';
     });
   });