Ben Lin
2024-06-22 8e288eefbd4e8dbf7d0180dd880ce93256daa7a5
src/views/tigerprojects/system/lowcode/high/index.vue
@@ -1,32 +1,101 @@
<!--
 *                        _oo0oo_
 *                       o8888888o
 *                       88" . "88
 *                       (| -_- |)
 *                       0\  =  /0
 *                     ___/`---'\___
 *                   .' \\|     |// '.
 *                  / \\|||  :  |||// \
 *                 / _||||| -:- |||||- \
 *                |   | \\\  - /// |   |
 *                | \_|  ''\---/''  |_/ |
 *                \  .-\__  '-'  ___/-. /
 *              ___'. .'  /--.--\  `. .'___
 *           ."" '<  `.___\_<|>_/___.' >' "".
 *          | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 *          \  \ `_.   \_ __\ /__ _/   .-` /  /
 *      =====`-.____`.___ \_____/___.-`___.-'=====
 *                        `=---='
 *
 *
 *      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *            佛祖保佑     永不宕机     永无BUG
 *
 *        佛曰:
 *                写字楼里写字间,写字间里程序员;
 *                程序人员写程序,又拿程序换酒钱。
 *                酒醒只在网上坐,酒醉还来网下眠;
 *                酒醉酒醒日复日,网上网下年复年。
 *                但愿老死电脑间,不愿鞠躬老板前;
 *                奔驰宝马贵者趣,公交自行程序员。
 *                别人笑我忒疯癫,我笑自己命太贱;
 *                不见满街漂亮妹,哪个归得程序员?
 -->
<!--
 * @Description: 低代码高级呈现页面
 * @Author: Ben Lin
 * @version: 
 * @Date: 2024-05-30 13:28:20
 * @LastEditors: your name
 * @LastEditTime: 2024-06-11 02:02:14
 * @LastEditors: Ben Lin
 * @LastEditTime: 2024-06-14 09:19:23
-->
<template>
  <div>
    <BasicTable @register="registerTable">
      <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"
        />
        <NormalModal @register="registerItemAdd" @success="(d, u) => handleItemSuccess(d, u, item)" />
      </template>
    </BasicTable>
  <PageWrapper
    class="high-form"
    :title="titleInfo['pageTitle']"
    :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>
    <a-card
      :title="item.title"
      :bordered="false"
      class="!m-5"
      v-for="(item, index) in otherCards"
      :key="item.name"
    >
      <BasicForm @register="useFormData[item.name][0]" />
    </a-card>
    <template #rightFooter>
      <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"
@@ -45,7 +114,7 @@
              @click="handleCustClick(field)"
              :preIcon="item.preIcons[name]"
            />
            <NormalModal
            <GeneralModal
              @register="useModalData[name][0]"
              @success="(d, u) => handleEntSuccess(d, u, item.name)"
            />
@@ -54,21 +123,36 @@
        <!-- 自定义内容 -->
      </template>
    </CustModal>
  </div>
  </PageWrapper>
</template>
<script lang="ts" setup>
  import { h, onMounted, ref, unref } from 'vue';
  import { BasicTable, useTable, TableAction, BasicColumn, FormSchema } from '/@/components/Table';
  import { Tag, Tooltip, Card } from 'ant-design-vue';
  import {
    BasicTable,
    useTable,
    TableAction,
    BasicColumn,
    FormSchema,
    ActionItem,
  } from '/@/components/Table';
  import { useDrawer } from '/@/components/Drawer';
  import normalDrawer from './normalDrawer.vue';
  import NormalModal from '/@/views/components/NormalModal.vue';
  import { GetEnum, getEntity, getListByPage } from '/@/api/tigerapi/system';
  import { PageWrapper } from '/@/components/Page';
  import normalDrawer from '../normalDrawer.vue';
  import GeneralModal from '/@/views/components/GeneralModal.vue';
  import {
    AddListEntity,
    DeleteEntity,
    DeleteWhere,
    GetEnum,
    SaveEntity,
    getEntity,
    getListByPage,
  } from '/@/api/tigerapi/system';
  import { useGlobSetting } from '/@/hooks/setting';
  import { useRoute } from 'vue-router';
  import { Tag, Tooltip } from 'ant-design-vue';
  import { useRoute, useRouter } from 'vue-router';
  import CustModal from '/@/views/components/CustModal.vue';
  import { BasicForm, FormActionType, useForm } from '/@/components/Form/index';
  import { isNullOrEmpty, isNullOrUnDef } from '/@/utils/is';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import {
    GetActionColumn,
    GetActionsData,
@@ -78,19 +162,41 @@
    getFormSchema,
    OpenCustModal,
    GetUseModalData,
  } from './data';
    GetBasicColumnAndInit,
    getHomeUrl,
    getTitle,
    getOthersValues,
    EditOperation,
  } 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';
  const ACard = Card;
  const { getLocale } = useLocale();
  const route = useRoute();
  const go = useGo();
  const tabStore = useMultipleTabStore();
  const router = useRouter();
  const { currentRoute } = router;
  function getCurrentTab() {
    const route = unref(currentRoute);
    return tabStore.getTabList.find((item) => item.fullPath === route.fullPath)!;
  }
  const currentTab = getCurrentTab();
  const objParams = ref(JSON.parse(decodeURI(route.params?.id as string)));
  const entityName = ref(objParams.value.ID);
  const titleInfo = getTitle(objParams.value.Name);
  const entityName = ref(objParams.value.Name);
  const isAllUpdate = ref(objParams.value.CODE != '0');
  const globSetting = useGlobSetting();
  const _columns = ref([]);
  const _searchFormSchema = ref([]);
  const _crudFormSchema = ref([]);
  const formSchemas = ref({}); //弹出框多表单结构
  const formSchemas = ref({}); //弹出框或高级页面多表单结构
  const useModalData = ref({}); //表单中插槽渲染按钮打开模态框useModal方法
  const useFormData = ref({});
  const colSlots = ref<any>(objParams.value.colSlots); //按钮插槽
@@ -98,162 +204,304 @@
  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 [registerCust, { openModal: openCustomModal, closeModal }] = useModal();
  const [registerItemAdd, { openModal: openItemModal }] = useModal();
  const [registerDrawer, { openDrawer }] = useDrawer();
  const [registerTable, { getForm, reload }] = useTable({
  const { setTitle } = useTabs();
  const [registerTable, { getForm, reload, setProps }] = useTable({
    title: '列表信息',
    api: getListByPage,
    searchInfo: { TABLE_NAME: objParams.value.ID },
    columns: _columns as unknown as BasicColumn[],
    dataSource: data,
    columns: _columns,
    formConfig: {
      labelWidth: 140,
      schemas: _searchFormSchema as unknown as FormSchema[],
      schemas: getFormSchema(`${entityName.value}_Search`),
    },
    useSearchForm: true,
    showTableSetting: true,
    bordered: true,
    canResize: true,
    showIndexColumn: false,
    actionColumn: GetActionColumn(objParams.value.ID), //自定义操作列
    actionColumn: GetActionColumn(entityName.value), //自定义操作列
  });
  /* 生成列表中操作项的按钮 */
  setTitle(objParams.value.Title); //设置标签页标题
  /**
   * @description: 生成列表中操作项的按钮
   * @param {*} record
   * @return {*}
   */
  function createActions(record) {
    return GetActionsData(
      {
        record,
        isUpdate: true,
        entityName: objParams.value.ID,
        formJson: _crudFormSchema.value,
        cType,
        dtlSlots,
        formSchemas,
        useModalData,
        useFormData,
        crudColSlots,
      },
    // 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,
    );
  }
  function handleCreate() {
    openDrawer(true, {
      isUpdate: false,
      entityName: objParams.value.ID,
      formJson: _crudFormSchema.value,
      crudColSlots,
  /**
   * @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 handleSuccess() {
  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));
  }
  onMounted(async () => {
    /* 用json获取列 */
    // _searchFormSchema.value = await fetchJson(
    //   `${globSetting.downloadUrl}/LowCode/${objParams.value.ID}/${objParams.value.ID}_Searchform.json`,
    // );
    // var objs = await fetchJson(
    //   `${globSetting.downloadUrl}/LowCode/${objParams.value.ID}/${objParams.value.ID}_Baseform.json`,
    // );
    // for (const i in objs) {
    //   if (!isNullOrEmpty(objs[i].customRender)) {
    //     const func = new Function(objs[i].customRender)();
    //     objs[i].customRender = ({ record }) => {
    //       let texts = func(record);
    //       return h(Tooltip, { title: texts.text }, () =>
    //         h(Tag, { color: texts.color }, () => texts.text),
    //       );
    //     };
    //   }
    // }
    // _columns.value = objs;
    //获取表单中插槽渲染的按钮点击弹出模态窗口的实例
    useModalData.value = GetUseModalData(objParams.value.ID);
    const data = await getEntity({
      sqlcmd: "ASSEMBLY_NAME ='" + objParams.value.ID + "'",
      entityName: 'SYS_LOW_CODE',
    isMounted.value = false;
    /* 动态import实体名.ts的自定义方法 */
    try {
      custImport.value = await import(/* @vite-ignore */ `../entityts/${entityName.value}`);
    } 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;
      }
    });
    var searchForms = JSON.parse(data.Data.Items[0].SEARCH_FORM_JSON);
    for (const i in searchForms) {
      if (
        !isNullOrEmpty(searchForms[i].componentProps) &&
        !isNullOrEmpty(searchForms[i].componentProps.api) &&
        searchForms[i].componentProps.api == 'GetEnum'
      ) {
        searchForms[i].componentProps.api = GetEnum;
        searchForms[
          i
        ].componentProps.params.name = `${objParams.value.ID}+${searchForms[i].field}s`;
        searchForms[i].componentProps.labelField = unref(getLocale) == 'zh_CN' ? 'Desc' : 'Name';
      }
      if (
        !isNullOrEmpty(searchForms[i].componentProps) &&
        !isNullOrEmpty(searchForms[i].componentProps.api) &&
        searchForms[i].componentProps.api == 'getEntity'
      ) {
        searchForms[i].componentProps.api = getEntity;
        searchForms[i].componentProps.resultField = 'Data.Items';
      }
      onChangeConfig(searchForms[i]);
    }
    _searchFormSchema.value = searchForms;
    var _cruds = JSON.parse(data.Data.Items[0].FORM_JSON);
    for (const i in _cruds) {
      if (
        !isNullOrEmpty(_cruds[i].componentProps) &&
        !isNullOrEmpty(_cruds[i].componentProps.api) &&
        _cruds[i].componentProps.api == 'GetEnum'
      ) {
        _cruds[i].componentProps.api = GetEnum;
        _cruds[i].componentProps.params.name = `${objParams.value.ID}+${_cruds[i].field}s`;
        _cruds[i].componentProps.labelField = unref(getLocale) == 'zh_CN' ? 'Desc' : 'Name';
      }
      if (
        !isNullOrEmpty(_cruds[i].componentProps) &&
        !isNullOrEmpty(_cruds[i].componentProps.api) &&
        _cruds[i].componentProps.api == 'getEntity'
      ) {
        _cruds[i].componentProps.api = getEntity;
        _cruds[i].componentProps.resultField = 'Data.Items';
      }
      onChangeConfig(_cruds[i]);
    }
    _crudFormSchema.value = _cruds;
    var objs = JSON.parse(data.Data.Items[0].BASE_FORM_JSON);
    for (const i in objs) {
      if (!isNullOrEmpty(objs[i].customRender)) {
        const func = new Function(objs[i].customRender)();
        objs[i].customRender = ({ record }) => {
          let texts = func(record);
          return h(Tooltip, { title: texts.text }, () =>
            h(Tag, { color: texts.color }, () => texts.text),
          );
        };
      }
    }
    _columns.value = objs;
    isMounted.value = true;
  });
  /* 弹出选择框选择成功后事件 */
  /**
   * @description: 异步全部提交方法
   * @return {*}
   */
  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();
                }
              });
            }
          });
        });
      });
      // 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();
      //   }
      // }
    } catch (error) {}
  }
  async function cancel() {
    try {
      tabStore.closeTab(currentTab, router);
    } catch (error) {}
  }
  /**
   * @description: 验证表单
   * @return {*}
   */
  async function validate() {
    let validates = {};
    const Keys = Object.getOwnPropertyNames(useFormData.value);
    let i;
    for (i = 0; i < Keys.length; i++) {
      validates[Keys[i]] = await useFormData.value[Keys[i]][1].validate();
    }
    return validates;
  }
  /**
   * @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`]));
    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`]);
    OpenSelectItem(
      openItemModal,
      getForm().getFieldsValue()[`${item.replace(/form-/, '').replace(/add/, '')}PSelect_0`],
    );
  }
  /* Select 自定义onChange方法 */
  /**
   * @description: Select 自定义onChange方法
   * @param {*} obj
   * @return {*}
   */
  function onChangeConfig(obj: any) {
    if (obj.component == 'Select') {
      var options = obj.componentProps.options;
@@ -261,18 +509,28 @@
      obj.componentProps = ({ schema, tableAction, formActionType, formModel }) => {
        return {
          options: options,
          onChange: (e) => custOnChange(e, onChange, objParams.value.ID),
          onChange: (e) => custOnChange(e, onChange, entityName.value),
        };
      };
    }
  }
  //弹出框确定返回
  /**
   * @description: 弹出框确定返回
   * @param {*} d
   * @return {*}
   */
  function custSuccess(d) {
    reload();
  }
  /* 各表单内弹出选择框选择成功后方法 */
  /**
   * @description: 各表单内弹出选择框选择成功后方法
   * @param {*} d
   * @param {*} u
   * @param {*} item
   * @return {*}
   */
  function handleEntSuccess(d, u, item) {
    var values = GetSelectSuccess(d, u, cType.value);
    selectVals.value = values; //保存弹出框选择的结果
@@ -281,7 +539,11 @@
    useFormData.value[item][1].setFieldsValue(_val);
  }
  /* 打开自定义模态框 */
  /**
   * @description: 打开自定义模态框
   * @param {*} item
   * @return {*}
   */
  function handleCustClick(item) {
    OpenCustModal(
      useModalData.value[item][1].openModal, //带入openModal方法
@@ -292,3 +554,8 @@
    ); //[openRvModal], selectVals.value['ID']这是自定义参数,按实际需求
  }
</script>
<style lang="less" scoped>
  .high-form {
    padding-bottom: 48px;
  }
</style>