Ben Lin
2024-07-16 5a4d79d9765dfca8812638b57d5f5fe21f7a06ee
src/views/tigerprojects/system/lowcode/high/index.vue
@@ -1,4 +1,12 @@
<!--
 * @Description: 低代码高级呈现页面
 * @Author: Ben Lin
 * @version:
 * @Date: 2024-06-18 15:09:48
 * @LastEditors: Ben Lin
 * @LastEditTime: 2024-07-15 22:23:12
-->
<!--
 *                        _oo0oo_
 *                       o8888888o
 *                       88" . "88
@@ -33,14 +41,6 @@
 *                别人笑我忒疯癫,我笑自己命太贱;  
 *                不见满街漂亮妹,哪个归得程序员?
 -->
<!--
 * @Description: 低代码高级呈现页面
 * @Author: Ben Lin
 * @version:
 * @Date: 2024-05-30 13:28:20
 * @LastEditors: Ben Lin
 * @LastEditTime: 2024-06-14 09:19:23
-->
<template>
  <PageWrapper
    class="high-form"
@@ -48,40 +48,14 @@
    :content="titleInfo['pageContent']"
    @back="goBack"
  >
    <a-card
      :title="item.title"
      :bordered="false"
      v-for="(item, index) in baseCards"
      :key="item.name"
    >
      <BasicForm @register="useFormData[item.name][0]" />
    </a-card>
    <a-card :title="titleInfo['baseTableTitle']" :bordered="false" class="!mt-5">
      <div>
        <BasicTable @register="registerTable" v-if="isMounted">
          <template #toolbar>
            <a-button type="primary" @click="handleCreate" preIcon="add_02|svg"> 新增 </a-button>
          </template>
          <template #action="{ record }">
            <TableAction :actions="createActions(record)" />
          </template>
          <template #[item]="{ field }" v-for="item in colSlots" :key="item">
            <!-- <template #form-BAS_REASON3aadd="{ field }"> -->
            <a-button
              v-if="field"
              class="mt-1 ml-1"
              size="small"
              @click="handleSelectItem(item)"
              preIcon="search|svg"
            />
            <GeneralModal
              @register="registerItemAdd"
              @success="(d, u) => handleItemSuccess(d, u, item)"
            />
          </template>
        </BasicTable>
      </div>
    </a-card>
    <Suspense>
      <baseForm :entityName="entityName" />
    </Suspense>
    <!-- <a-card :title="titleInfo['baseTableTitle']" :bordered="false" class="!mt-5"> -->
    <Suspense>
      <dtl :entityName="entityName" @search="dtlFormSearch" />
    </Suspense>
    <!-- </a-card> -->
    <a-card
      :title="item.title"
      :bordered="false"
@@ -96,93 +70,66 @@
      <a-button class="mr-4" type="info" @click="cancel"> 取消 </a-button>
      <a-button type="primary" @click="submitAll"> 提交 </a-button>
    </template>
    <normalDrawer @register="registerDrawer" @success="handleSuccess" />
    <CustModal
      @register="registerCust"
      @success="custSuccess"
      :type="cType"
      :detailSlots="dtlSlots"
    >
      <!-- 用插槽自定义多表单 -->
      <template #[item.name] v-for="item in dtlSlots" :key="item.name">
        <BasicForm @register="useFormData[item.name][0]" v-if="useFormData[item.name]">
          <!-- 用插槽自定义弹出选择框 -->
          <template #[name]="{ field }" v-for="name in item.slots" :key="name">
            <a-button
              class="mt-1 ml-1"
              size="small"
              @click="handleCustClick(field)"
              :preIcon="item.preIcons[name]"
            />
            <GeneralModal
              @register="useModalData[name][0]"
              @success="(d, u) => handleEntSuccess(d, u, item.name)"
            />
          </template>
        </BasicForm>
        <!-- 自定义内容 -->
      </template>
    </CustModal>
    <Suspense>
      <CustModal
        @register="registerCust"
        @success="custSuccess"
        :type="cType"
        :detailSlots="dtlSlots"
        :entityName="entityName"
      >
        <!-- 用插槽自定义多表单 -->
        <template #[item.name] v-for="item in dtlSlots" :key="item.name">
          <BasicForm @register="useFormData[item.name][0]" v-if="useFormData[item.name]">
            <!-- 用插槽自定义弹出选择框 -->
            <template #[name]="{ field }" v-for="name in item.slots" :key="name">
              <a-button
                class="mt-1 ml-1"
                size="small"
                @click="handleCustClick(field)"
                :preIcon="item.preIcons[name]"
              />
              <GeneralModal
                @register="useModalData[name][0]"
                @success="(d, u) => handleEntSuccess(d, u, item.name)"
              />
            </template>
          </BasicForm>
          <!-- 自定义内容 -->
        </template>
      </CustModal>
    </Suspense>
  </PageWrapper>
</template>
<script lang="ts" setup>
  import { h, onMounted, ref, unref } from 'vue';
  import { Tag, Tooltip, Card } from 'ant-design-vue';
  import {
    BasicTable,
    useTable,
    TableAction,
    BasicColumn,
    FormSchema,
    ActionItem,
  } from '/@/components/Table';
  import { useDrawer } from '/@/components/Drawer';
  import { Ref, h, nextTick, onMounted, provide, reactive, ref, unref } from 'vue';
  import { Card } from 'ant-design-vue';
  import { PageWrapper } from '/@/components/Page';
  import normalDrawer from '../normalDrawer.vue';
  import dtl from './dtl.vue';
  import baseForm from './baseForm.vue';
  import GeneralModal from '/@/views/components/GeneralModal.vue';
  import {
    AddListEntity,
    DeleteEntity,
    DeleteWhere,
    GetEnum,
    SaveEntity,
    getEntity,
    getListByPage,
  } from '/@/api/tigerapi/system';
  import { AddAfterDelete, SaveEntity } from '/@/api/tigerapi/system';
  import { useGlobSetting } from '/@/hooks/setting';
  import { useRoute, useRouter } from 'vue-router';
  import CustModal from '/@/views/components/CustModal.vue';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import {
    GetActionColumn,
    GetActionsData,
    OpenSelectItem,
    GetSelectSuccess,
    custOnChange,
    getFormSchema,
    OpenCustModal,
    GetUseModalData,
    GetBasicColumnAndInit,
    getHomeUrl,
    getTitle,
    getOthersValues,
    EditOperation,
  } from '../data';
  import { custOnChange, OpenCustModal } from '../data';
  import { useModal } from '/@/components/Modal';
  import { useLocale } from '/@/locales/useLocale';
  import { useGo } from '/@/hooks/web/usePage';
  import { useMultipleTabStore } from '/@/store/modules/multipleTab';
  import { useTabs } from '/@/hooks/web/useTabs';
  import { isEmpty, isNullOrEmpty } from '/@/utils/is';
  import { BAS_DEFECT } from '/@/api/tigerapi/model/mesModel';
  import { buildUUID } from '/@/utils/uuid';
  import { useUserStore } from '/@/store/modules/user';
  import { formatToDateTime } from '/@/utils/dateUtil';
  import { isNullOrEmpty, isNullOrUnDef } from '/@/utils/is';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { isFunction } from 'xe-utils';
  const { t } = useI18n();
  const ACard = Card;
  const { getLocale } = useLocale();
  const route = useRoute();
  const go = useGo();
  const route = useRoute();
  const tabStore = useMultipleTabStore();
  const router = useRouter();
  const { currentRoute } = router;
@@ -191,218 +138,59 @@
    return tabStore.getTabList.find((item) => item.fullPath === route.fullPath)!;
  }
  const currentTab = getCurrentTab();
  const objParams = ref(JSON.parse(decodeURI(route.params?.id as string)));
  const titleInfo = getTitle(objParams.value.Name);
  const entityName = ref(objParams.value.Name);
  const routeParams = ref(JSON.parse(decodeURI(route.params?.id as string)));
  const entityName = ref(routeParams.value.Name);
  // 从sessionStorage中读取参数并转换回对象
  const savedParams = sessionStorage.getItem(`${routeParams.value.sName}_params`);
  const objParams = savedParams ? ref(JSON.parse(decodeURI(savedParams))) : ref({});
  const titleInfo = ref({}); //getTitle(objParams.value.Name);
  const isAllUpdate = ref(objParams.value.CODE != '0');
  const globSetting = useGlobSetting();
  const formSchemas = ref({}); //弹出框或高级页面多表单结构
  const useModalData = ref({}); //表单中插槽渲染按钮打开模态框useModal方法
  const useFormData = ref({});
  const colSlots = ref<any>(objParams.value.colSlots); //按钮插槽
  const crudColSlots = ref<any>(objParams.value.crudColSlots);
  const useTableData = ref({});
  const cType = ref('');
  const dtlSlots = ref([] as any[]);
  const selectVals = ref({});
  const baseCards = ref([] as any[]);
  const otherCards = ref([] as any[]);
  const isMounted = ref(false);
  const custImport = ref(null);
  const others = ref(getOthersValues(entityName.value, objParams.value.CODE, objParams.value.ID));
  //获取表格列信息并初始化一些数据,如:formSchemas(弹出框或高级页面多表单结构), useFormData(表单中插槽渲染按钮打开模态框useModal方法)...等
  const _columns = GetBasicColumnAndInit(
    entityName.value,
    formSchemas,
    useFormData,
    baseCards,
    otherCards,
    useForm,
  );
  const data = ref([]);
  const custImport = ref<any[]>([]);
  const keyFieldValues = ref<any>(null);
  const data = ref<any>({});
  const useTables = ref<any>({});
  for (const i in objParams.value['drawers']) {
    data.value[objParams.value['drawers'][i]['name']] = ref<Recordable[]>([]);
  }
  provide<Ref<any>>('objParams', objParams);
  provide<Ref<any>>('data', data);
  provide<Ref<any>>('keyFieldValues', keyFieldValues);
  provide<Ref<{}>>('useFormData', useFormData);
  provide<Ref<any>>('baseCards', baseCards);
  provide<Ref<any>>('useTables', useTables);
  const [registerCust, { openModal: openCustomModal, closeModal }] = useModal();
  const [registerItemAdd, { openModal: openItemModal }] = useModal();
  const [registerDrawer, { openDrawer }] = useDrawer();
  const { setTitle } = useTabs();
  const [registerTable, { getForm, reload, setProps }] = useTable({
    title: '列表信息',
    dataSource: data,
    columns: _columns,
    formConfig: {
      labelWidth: 140,
      schemas: getFormSchema(`${entityName.value}_Search`),
    },
    useSearchForm: true,
    showTableSetting: true,
    bordered: true,
    canResize: true,
    showIndexColumn: false,
    actionColumn: GetActionColumn(entityName.value), //自定义操作列
  });
  setTitle(objParams.value.Title); //设置标签页标题
  /**
   * @description: 生成列表中操作项的按钮
   * @param {*} record
   * @return {*}
   */
  function createActions(record) {
    // return GetActionsData(
    //   {
    //     record,
    //     isUpdate: true,
    //     ifSave: true,
    //     entityName: entityName.value,
    //     formJson: getFormSchema(`${entityName.value}_Crud`),
    //     cType,
    //     dtlSlots,
    //     useModalData,
    //     useFormData,
    //     crudColSlots,
    //     data,
    //   },
    //   openDrawer,
    //   reload,
    //   openCustomModal,
    //   useForm,
    //   useModal,
    //   go,
    //   setProps,
    // );
    const params = {
      record,
      isUpdate: true,
      ifSave: true,
      entityName: entityName.value,
      formJson: getFormSchema(`${entityName.value}_Crud`),
      cType,
      dtlSlots,
      useModalData,
      useFormData,
      crudColSlots,
      data,
    };
    const [ActionItem] = custImport.value.default();
    return ActionItem(
      params,
      [
        {
          icon: 'clarity:note-edit-line',
          onClick: editRecord.bind(null, openDrawer, params),
        },
        {
          icon: 'ant-design:delete-outlined',
          color: 'error',
          popConfirm: {
            title: '是否确认删除?',
            placement: 'left',
            confirm: deleteRecord.bind(null, reload, params),
          },
        },
      ],
      openDrawer,
      reload,
      openCustomModal,
      useForm,
      useModal,
      go,
      setProps,
    );
  }
  /**
   * @description: 公用编辑方法
   * @param {Fn} fn
   * @param {*} params
   * @return {*}
   */
  function editRecord(fn: Fn, params: {}) {
    fn(true, params);
  }
  /**
   * @description: 公用删除方法
   * @param {Fn} fn
   * @param {*} params
   * @return {*}
   */
  function deleteRecord(fn: Fn, params: {}) {
    console.log(params['record']);
    //删除
    DeleteEntity(params['record'], params['entityName']).then((action) => {
      if (action.IsSuccessed) {
        fn();
      }
    });
  }
  function handleCreate() {
    validate().then((res) => {
      const Keys = Object.getOwnPropertyNames(useFormData.value);
      let i;
      for (i = 0; i < Keys.length; i++) {
        others.value[objParams.value.pCode] = objParams.value.IsID
          ? res[Keys[i]]['ID']
          : res[Keys[i]][objParams.value.pCode];
      }
      openDrawer(true, {
        isUpdate: false,
        ifSave: true,
        entityName: entityName.value,
        formJson: getFormSchema(`${entityName.value}_Crud`),
        crudColSlots,
        others: others.value,
      });
    });
  }
  /**
   * @description: 新增编辑返回成功方法
   * @param {*} d
   * @param {*} u
   * @return {*}
   */
  function handleSuccess(d, u) {
    /* 自定义编辑方法,根据实体名去调用 */
    EditOperation(entityName.value, data, d, u);
    setProps({
      dataSource: [],
    });
    setProps({
      dataSource: data,
    });
    reload();
  }
  function goBack() {
    // 本例的效果时点击返回始终跳转到账号列表页,实际应用时可返回上一页
    go(getHomeUrl(entityName.value));
    if (!isNullOrUnDef(custImport.value)) {
      const [{ GetHomeUrl }] = custImport.value['default']();
      // 本例的效果时点击返回始终跳转到账号列表页,实际应用时可返回上一页
      go(GetHomeUrl(entityName.value));
    }
  }
  onMounted(async () => {
    isMounted.value = false;
    await nextTick();
    /* 动态import实体名.ts的自定义方法 */
    try {
      custImport.value = await import(/* @vite-ignore */ `../entityts/${entityName.value}`);
      custImport.value = await import(`../entityts/${entityName.value}.ts`);
      const [{ GetTitle }] = custImport.value['default']();
      titleInfo.value = GetTitle();
    } catch (e) {}
    useFormData.value[baseCards.value[0]['name']][1].resetFields();
    Promise.all([
      getEntity({
        sqlcmd: ` ID = '${objParams.value.ID}'`,
        entityName: baseCards.value[0]['entityName'],
      }),
      getEntity({
        sqlcmd: ` ${objParams.value.pCode} = '${others.value[objParams.value.pCode]}'`,
        entityName: entityName.value,
      }),
    ]).then((res) => {
      if (!isNullOrEmpty(res[0].Data.Items)) {
        useFormData.value[baseCards.value[0]['name']][1].setFieldsValue(res[0].Data.Items[0]);
      }
      if (!isNullOrEmpty(res[1].Data.Items)) {
        data.value = res[1].Data.Items;
      }
    });
    isMounted.value = true;
  });
@@ -410,42 +198,51 @@
   * @description: 异步全部提交方法
   * @return {*}
   */
  function submitAll() {
  async function submitAll() {
    try {
      validate().then((res) => {
        const Keys = Object.getOwnPropertyNames(useFormData.value);
        let i;
        let p = [] as Promise<any>[];
        for (i = 0; i < Keys.length; i++) {
          p.push(SaveEntity(res[Keys[i]], unref(isAllUpdate), baseCards.value[i]['entityName']));
        }
        Promise.all(p).then((action) => {
          DeleteWhere(
            ` ${objParams.value.pCode} = '${others.value[objParams.value.pCode]}'`,
            entityName.value,
          ).then((res) => {
            if (res.IsSuccessed) {
              data.value.forEach((item) => {
                item.ID = buildUUID();
              });
              AddListEntity(data.value, entityName.value).then((action) => {
                if (action.IsSuccessed) {
                  cancel();
                }
              });
      const validates = await validate();
      const Keys = Object.getOwnPropertyNames(useFormData.value);
      let i;
      let p = [] as Promise<any>[];
      for (i = 0; i < Keys.length; i++) {
        p.push(
          SaveEntity(
            validates[Keys[i]],
            unref(isAllUpdate),
            baseCards.value[i]['entityName'],
            `${objParams.value['IsExist']}='${validates[Keys[i]][objParams.value['IsExist']]}'`,
            true,
          ),
        );
      }
      await Promise.all(p);
      if (
        !custImport.value['default']()[0].SubmitAll &&
        !isFunction(custImport.value['default']()[0].SubmitAll)
      ) {
        /* 默认提交 */
        objParams.value['drawers'].forEach((d) => {
          let where = `${d['code']} = '${keyFieldValues.value[d['code']]}'`;
          /* type: all-表示需要code的所有的值 */
          if (d['type'] == 'all' && data.value[d['keyName']].length > 0) {
            where = `${d['code']} in (${data.value[d['keyName']].map((value) => `'${value[d['code']]}'`).join(',')})`;
          }
          /* 如果高级表单中关联的是ID(IsID == true),则不用初始化ID */
          if (!objParams.value['IsID']) {
            data.value[d['name']].map((item) => {
              item.ID = buildUUID();
            });
          }
          AddAfterDelete(d['name'], data.value[d['name']], where).then((action) => {
            if (action.IsSuccessed) {
              cancel();
            }
          });
        });
      });
      // values.ID = params.RULE_ID;
      // const action = await SaveRule({ ...values, ...testValues });
      // if (action.IsSuccessed) {
      //   await DeleteRuleDtl(params.RULE_ID);
      //   const dtlAction = await SaveRuleDtl(data.value);
      //   if (dtlAction.IsSuccessed) {
      //     cancel();
      //   }
      // }
      } else {
        /* 如果自定义提交方法存在就用自定义提交 */
        custImport.value['default']()[0].SubmitAll(data, keyFieldValues, cancel);
      }
    } catch (error) {}
  }
  async function cancel() {
@@ -469,32 +266,22 @@
  }
  /**
   * @description: 弹出选择框选择成功后事件
   * @description: 表格查询回调,根据对应子组件中表格的查询按钮提交事件转入动态调用的实体名方法去执行对应的查询逻辑,返回后刷新数据
   * @param {*} d
   * @param {*} u
   * @param {*} item
   * @return {*}
   */
  function handleItemSuccess(d, u, item) {
    getForm().setFieldsValue(
      GetSelectSuccess(
        d,
        u,
        getForm().getFieldsValue()[`${item.replace(/form-/, '').replace(/add/, '')}PSelect_0`],
      ),
    );
  }
  /**
   * @description: 弹出选择框
   * @param {*} item
   * @return {*}
   */
  function handleSelectItem(item) {
    OpenSelectItem(
      openItemModal,
      getForm().getFieldsValue()[`${item.replace(/form-/, '').replace(/add/, '')}PSelect_0`],
    );
  function dtlFormSearch(d) {
    try {
      var values = useTables.value[d.type][1].getForm().getFieldsValue();
      let data = custImport.value['default']()[0].FormSearch({ ...d, ...{ values: values } });
      useTables.value[d.type][1].setProps({
        dataSource: [],
      });
      useTables.value[d.type][1].setProps({
        dataSource: data,
      });
      useTables.value[d.type][1].reload();
    } catch (e) {}
  }
  /**
@@ -521,7 +308,7 @@
   * @return {*}
   */
  function custSuccess(d) {
    reload();
    useTableData.value['table'][1].reload();
  }
  /**
@@ -532,11 +319,17 @@
   * @return {*}
   */
  function handleEntSuccess(d, u, item) {
    var values = GetSelectSuccess(d, u, cType.value);
    selectVals.value = values; //保存弹出框选择的结果
    let _val = {};
    _val[d.returnFieldName] = values[d.returnFieldName];
    useFormData.value[item][1].setFieldsValue(_val);
    /* 动态import实体名.ts的自定义方法 */
    try {
      import(`../entityts/${cType.value}.ts`).then((m) => {
        const [{ GetSelectSuccess }] = m.default();
        var values = GetSelectSuccess(d, u);
        selectVals.value = values; //保存弹出框选择的结果
        let _val = {};
        _val[d.returnFieldName] = values[d.returnFieldName];
        useFormData.value[item][1].setFieldsValue(_val);
      });
    } catch (e) {}
  }
  /**