wujingjing
2024-09-09 71ffe1b098e8a7b2b2c8f938e7765be9776e8966
src/views/project/yw/lowCode/sqlAmis/edit/SqlAmisEdit.vue
@@ -4,7 +4,7 @@
         <template v-slot:left>
            <el-button
               icon="ele-ArrowLeft"
               text
               link
               style="margin-right: 10px; margin-left: 10px; width: 40px"
               size="small"
               @click="backLastPage"
@@ -16,16 +16,19 @@
      <div class="grid grid-cols-2 gap-2 h-full flex-auto">
         <div class="h-full overflow-auto">
            <el-table
               ref="rsTableRef"
               :data="configList"
               row-class-name="cursor-pointer"
               class="h-full"
               highlight-current-row
               @current-change="dockRowChange"
            >
               <el-table-column prop="asyncId" label="查询 id" />
               <el-table-column prop="path" label="配置路径" />
               <el-table-column prop="recordId" label="SQL记录id" />
               <el-table-column prop="queryId" label="查询id" />
               <el-table-column prop="url" label="请求地址" />
               <el-table-column prop="recordId" label="SQL id" />
               <!-- <el-table-column prop="url" label="请求地址" /> -->
            </el-table>
            <!-- <codemirror
               v-model="dockCode"
@@ -39,16 +42,16 @@
               @blur="log('blur', $event)"
            /> -->
         </div>
         <div class="h-full overflow-auto">
         <div class="h-full overflow-auto" v-if="currentSql">
            <codemirror
               class="h-full overflow-auto"
               v-model="sqlCode"
               v-model="currentSql.sql"
               :style="{ height: '100%' }"
               :autofocus="true"
               :indent-with-tab="true"
               :tab-size="2"
               :extensions="sqlEditorExtensions"
               @change="log('change', $event)"
               @change="sqlCodeChange"
               @focus="log('focus', $event)"
               @blur="log('blur', $event)"
            />
@@ -62,20 +65,22 @@
import { sql } from '@codemirror/lang-sql';
import { xml } from '@codemirror/lang-xml';
import { vscodeDark } from '@uiw/codemirror-theme-vscode';
import _ from 'lodash';
import _, { debounce } from 'lodash';
import { onMounted, ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import * as codeExample from './testData';
import titleBox from '/@/components/titleBox.vue';
import { v4 as uuid } from 'uuid';
import { getAmisXml } from '/@/api/supervisorAdmin';
import { useCompRef } from '/@/utils/types';
import { XMLParser, XMLBuilder, XMLValidator } from 'fast-xml-parser';
import type { TableInstance } from 'element-plus';
import { ElMessage } from 'element-plus';
import { v4 as uuid } from 'uuid';
import * as supervisorApi from '/@/api/supervisorAdmin';
import { updateSqlApi } from '/@/api/supervisorAdmin';
import { useCompRef } from '/@/utils/types';
import { SupervisorPublished } from '../types';
const props = defineProps(['supervisor']);
const emit = defineEmits(['backLastPage']);
const emit = defineEmits(['backLastPage', 'updatePublished']);
const log = console.log;
const jsonCode = ref(codeExample.jsonCode);
const dockCode = ref(codeExample.dockCode);
@@ -95,7 +100,15 @@
   // }, 300);
   emit('backLastPage');
};
const dockRowChange = (row) => {};
const currentRs = ref<AmisDockConfig>(null);
const dockRowChange = (row) => {
   currentRs.value = row;
   currentSql.value = sqlList.value.find((item) => item.id === currentRs.value.recordId) ?? {
      id: row.recordId,
      sql: '',
   };
};
const currentSql = ref(null);
/** @description 路径分隔符 */
const PATH_SEPARATOR = '/';
/** @description 1 退出所有循环 -1退出当次循环 0或其他值继续 */
@@ -140,56 +153,149 @@
type AmisDockApi = string;
type AmisDockValue = AmisDockApi;
type AmisDockConfig = {
   type: AmisDockType;
   type?: AmisDockType;
   path: string;
   value: AmisDockValue;
};
type AmisDockSQLConfig = AmisDockConfig & {
   queryId: string;
   asyncId: string;
   recordId: string;
};
const configList = ref<AmisDockConfig[]>([]);
const parseJSONData = (json: string) => {
   if (!json) return;
   const obj = JSON.parse(json);
const parseJSONData = (obj: any, apiDataList) => {
   // 先清空
   const jsonConfigList = [];
   travelObj(obj, (key, value, path) => {
      if (key === 'api') {
         const url = value.url;
         // const url = value.url;
         const urlPath = path + PATH_SEPARATOR + 'url';
         const queryId = 'query_' + uuid().slice(0, 12);
         const randomStr = 'query_' + uuid().slice(0, 12);
         const foundItem = apiDataList.find((item) => item.path === urlPath);
         const asyncId = foundItem?.asyncId ?? randomStr;
         const recordId = foundItem?.recordId ?? randomStr;
         // const recordId = uniqueId()
         configList.value.push({
            queryId: queryId,
            recordId: queryId,
         jsonConfigList.push({
            asyncId: asyncId,
            recordId: recordId,
            type: AmisDockType.Api,
            path: urlPath,
            value: url,
            url: url,
         } as any);
         });
      }
   });
   return jsonConfigList;
};
const updateSqlAndRs = (id?, sqlValue?: string) => {
   const apiConfig = configList.value.filter((item) => item.type === AmisDockType.Api);
   if (apiConfig.length === 0) return;
   const asyncRsList = apiConfig.map((item) => ({
      amis_path: item.path,
      async_id: item.asyncId,
      rec_id: item.recordId,
   }));
   if (id) {
      const found = sqlList.value?.find((item) => item.id === id);
      if (found) {
         found.sql = sqlValue;
      } else {
         if (!sqlList.value || sqlList.value.length === 0) {
            sqlList.value = [
               {
                  id: id,
                  sql: sqlValue,
               },
            ];
         } else {
            sqlList.value.push({
               id: id,
               sql: sqlValue,
            });
         }
      }
   }
   updateSqlApi(
      {
         id: props.supervisor.id,
         sql_json: sqlList.value.length === 0 ? null : JSON.stringify(sqlList.value),
         async_rs_json: asyncRsList.length === 0 ? null : JSON.stringify(asyncRsList),
      },
      {
         loading: false,
      }
   ).then(() => {
      emit('updatePublished', props.supervisor.id, SupervisorPublished.N);
   });
};
const sqlCodeChange = debounce((val) => {
   if (!currentRs.value.recordId) return;
   updateSqlAndRs(currentRs.value.recordId, val);
}, 1000);
const sqlList = ref([]);
const rsTableRef = ref<TableInstance>(null);
let xmlJson = null;
const xmlParserInstance = new XMLParser();
const xmlBuilderInstance = new XMLBuilder();
let xmlConfig = null;
onMounted(async () => {
   xmlConfig = await getAmisXml({
      agent_id: props.supervisor.id,
// 检查是否需要更新 rs
const checkRsUpdate = (originData: AmisDockConfig[], currentData: AmisDockConfig[]) => {
   // 都为空,不需要更新
   if ((!originData || originData.length === 0) && (!currentData || currentData.length === 0)) {
      return false;
   }
   // 存在一方为空,需要更新
   if (!originData || !currentData) {
      return true;
   }
   // 长度不一致,需要更新
   if (originData.length !== currentData.length) {
      return true;
   }
   return originData.some((originItem) => {
      const id = originItem.asyncId;
      const currentItem = currentData.find((item) => item.asyncId === id);
      // 没找到对应项,需要更新
      if (!currentItem) {
         return true;
      }
      // 对象项值不相等,需要更新
      return Object.keys(currentItem).some((item) => originItem[item] !== currentItem[item]);
   });
   if (!xmlConfig?.amis_xml) {
      // ElMessage.warning('暂无数据');
};
onMounted(async () => {
   xmlJson = await supervisorApi.getLowCodeJson({
      id: props.supervisor.id,
   });
   if (!xmlJson?.amis_json) {
      ElMessage.warning('暂无SQL配置');
      return;
   }
   const jObj = xmlParserInstance.parse(xmlConfig.amis_xml);
   if (!jObj?.AMIS_JSON) {
      return;
   const originConfig =
      xmlJson.async_rs?.map(
         (item) =>
            ({
               type: AmisDockType.Api,
               asyncId: item.async_id,
               recordId: item.rec_id,
               path: item.amis_path,
            } as AmisDockConfig)
      ) ?? [];
   sqlList.value = xmlJson.sql ?? null;
   configList.value = parseJSONData(xmlJson.amis_json, originConfig);
   if (configList.value.length > 0) {
      rsTableRef.value.setCurrentRow(configList.value[0]);
      // dockRowChange(configList.value[0]);
   }
   const amisJSON = jObj.AMIS_JSON;
   parseJSONData(amisJSON);
   if (checkRsUpdate(originConfig, configList.value)) {
      // 自动更新Rs
      updateSqlAndRs();
   }
});
</script>