Explorar o código

更新系统管理功能。

CodeLife Leno hai 2 meses
pai
achega
6bdfa784a1

BIN=BIN
Procedure/backend/project/lib/sd-prod-baseFrame-3.240429.1.jar


BIN=BIN
Procedure/backend/project/lib/sd-prod-baseFrame-3.240708.1.jar


+ 142 - 142
Procedure/frontend/projectb/src/components/SDImpDialog.tsx

@@ -1,142 +1,142 @@
-import { Upload } from 'antd';
-import { useRef, useState } from 'react';
-import { baseFun, SDButton, SDForm, SDFormText, SDLayout, SDModal, SDOperate } from '@sundata/ui-frame';
-import { getDetail, ImpmTypeConfigModel, uploadAction } from '../services/pubMng/excelMng';
-import type { ActionType, ProFormInstance } from '@ant-design/pro-components';
-import { UploadOutlined } from '@ant-design/icons';
-
-export type SDImpDialogProps = {
-  /**组件标识,组件内唯一 */
-  key: string;
-  /** 导入类型,格式:模板代码&导入序号&导入期次;导入序号和导入期次可为空 */
-  type: string;
-  /**上传按钮调用的方法 */
-  onclick?: () => any;
-  /** */
-  //disTemplate?: boolean;
-  /**窗口大小 */
-  impDialogSize?: 'l' | 'm' | 's' | 'large' | 'medium' | 'small';
-  /** */
-  visible: boolean;
-  //onVisibleChange: React.Dispatch<React.SetStateAction<boolean>>; /** 弹出窗口显示状态发生改变后的处理方法 */
-  /** 关联表格的引用对象,应与对应ProTable的actionRef一致,用于刷新表格 */
-  tableRef?: React.MutableRefObject<ActionType | undefined>;
-  /**回调函数,上传后返回数据 */
-  callback?: (data: any) => any;
-  /**用于关闭弹窗 例:onCancel={()=>setVisible(false)} */
-  onCancel?: () => any;
-  /**展示期次,true-展示 false/undefined-不展示 */
-  showTerm?: boolean;
-  /** moment规则的日期格式,可使用中文 */
-  dateFmt?: string;
-};
-
-const SDImpDialog: React.FC<SDImpDialogProps> = (props) => {
-  const formRef = useRef<ProFormInstance>();
-  console.log(props.type);
-  const [disModal, setDisModal] = useState<boolean>(props.visible);
-  const mType: string[] = props.type.split('@');
-  /**上传文件 */
-  const [fileState, setFileState] = useState<File>();
-  /**上传属性 */
-  const fileProps = {
-    onRemove: () => {
-      setFileState(undefined);
-    },
-    beforeUpload(info: any) {
-      setFileState(info);
-    },
-    customRequest: (options: { onSuccess: () => void; }) => {
-      options?.onSuccess?.();
-    },
-  };
-  /**上传提交 */
-  const uploadSubmit = async () => {
-    let type = props.type;
-    if(props.showTerm){
-      let term = formRef.current?.getFieldValue("term");
-      if(!term){
-        baseFun.warning('未选择期次');
-        return;
-      }
-      if(typeof term === 'string'){//传参转换
-        const date = new Date(term);
-        const year = date.getFullYear();
-        const month = (date.getMonth() < 10 ? '0' + (date.getMonth() + 1) : date.getMonth());
-        term =`${year}${month}`;
-      }else{//日期控件切换转换
-        term = term.format("YYYYMM");
-      }
-      if(mType.length>1){
-        type = `${mType[0]}@${mType[1]}@${term}`
-      }
-    }
-    
-    if (!fileState) {
-      baseFun.warning('未上传文件');
-      return;
-    }
-    const res = await uploadAction(fileState, type);
-    // if (res.success) {
-    //   baseFun.info('导入成功');
-    // } else {
-    //   baseFun.error(res.message || '导入失败');
-    // }
-    baseFun.info(res._msg)
-    if (props.callback) props.callback(res);
-  };
-
-  const download = () => {
-    baseFun.download('/api/admin/excelmanage/importAndAuditp/importExcelModel.do', {
-      mType: mType[0],
-    });
-  };
-
-  const getDetailReq = async () => {
-    const data: ImpmTypeConfigModel = await getDetail({ mtype: mType[0] });
-    if(mType.length==3 && mType[2]){
-      return {mtypename: data.mtypename,term: mType[2]}
-    }else{
-      return {mtypename: data.mtypename,term: null}
-    }
-  };
-
-  return (
-    <SDModal
-      title=""
-      visible={disModal}
-      footer={[ <SDButton successMessage='' autoLoading primary onClick={uploadSubmit}>保存</SDButton>,
-       <SDButton onClick={download}>下载模板文件</SDButton>,
-      ]}
-      size={props.impDialogSize ? props.impDialogSize : 's'}
-      onCancel={() => {
-        setDisModal(false);
-        //props.onVisibleChange(false);
-        props.tableRef?.current?.reload();
-        props.tableRef?.current?.clearSelected?.();
-        if(props.onCancel)props.onCancel();
-      }}
-    >
-      <SDLayout >
-        <SDForm
-          editType={'create'}
-          request={getDetailReq}
-          formRef={formRef}
-        >
-          {props.showTerm && 
-            <SDFormText name="term" required type='prodmonth'label="期次" dateFmt={props.dateFmt?props.dateFmt:'YYYYMM'}/>
-          }
-          <SDFormText name="mtypename" readonlyCond="both" label="模板名称" />
-          
-          <Upload maxCount={1} {...fileProps} name="file">
-          <div style={{paddingLeft:'3.4vw'}}>
-                上传文件: &nbsp;&nbsp;<SDOperate icon={<UploadOutlined />}>上传</SDOperate>
-            </div>
-          </Upload>
-          
-        </SDForm>
-      </SDLayout>
-    </SDModal>
-  );
-};
-export default SDImpDialog;
+import { Upload } from 'antd';
+import { useRef, useState } from 'react';
+import { baseFun, SDButton, SDForm, SDFormText, SDLayout, SDModal, SDOperate } from '@sundata/ui-frame';
+import { getDetail, ImpmTypeConfigModel, uploadAction } from '../services/pubMng/excelMng';
+import type { ActionType, ProFormInstance } from '@ant-design/pro-components';
+import { UploadOutlined } from '@ant-design/icons';
+
+export type SDImpDialogProps = {
+  /**组件标识,组件内唯一 */
+  key: string;
+  /** 导入类型,格式:模板代码&导入序号&导入期次;导入序号和导入期次可为空 */
+  type: string;
+  /**上传按钮调用的方法 */
+  onclick?: () => any;
+  /** */
+  //disTemplate?: boolean;
+  /**窗口大小 */
+  impDialogSize?: 'l' | 'm' | 's' | 'large' | 'medium' | 'small';
+  /** */
+  visible: boolean;
+  //onVisibleChange: React.Dispatch<React.SetStateAction<boolean>>; /** 弹出窗口显示状态发生改变后的处理方法 */
+  /** 关联表格的引用对象,应与对应ProTable的actionRef一致,用于刷新表格 */
+  tableRef?: React.MutableRefObject<ActionType | undefined>;
+  /**回调函数,上传后返回数据 */
+  callback?: (data: any) => any;
+  /**用于关闭弹窗 例:onCancel={()=>setVisible(false)} */
+  onCancel?: () => any;
+  /**展示期次,true-展示 false/undefined-不展示 */
+  showTerm?: boolean;
+  /** moment规则的日期格式,可使用中文 */
+  dateFmt?: string;
+};
+
+const SDImpDialog: React.FC<SDImpDialogProps> = (props) => {
+  const formRef = useRef<ProFormInstance>();
+  console.log(props.type);
+  const [disModal, setDisModal] = useState<boolean>(props.visible);
+  const mType: string[] = props.type.split('@');
+  /**上传文件 */
+  const [fileState, setFileState] = useState<File>();
+  /**上传属性 */
+  const fileProps = {
+    onRemove: () => {
+      setFileState(undefined);
+    },
+    beforeUpload(info: any) {
+      setFileState(info);
+    },
+    customRequest: (options: any) => {
+      options?.onSuccess?.();
+    },
+  };
+  /**上传提交 */
+  const uploadSubmit = async () => {
+    let type = props.type;
+    if(props.showTerm){
+      let term = formRef.current?.getFieldValue("term");
+      if(!term){
+        baseFun.warning('未选择期次');
+        return;
+      }
+      if(typeof term === 'string'){//传参转换
+        const date = new Date(term);
+        const year = date.getFullYear();
+        const month = (date.getMonth() < 10 ? '0' + (date.getMonth() + 1) : date.getMonth());
+        term =`${year}${month}`;
+      }else{//日期控件切换转换
+        term = term.format("YYYYMM");
+      }
+      if(mType.length>1){
+        type = `${mType[0]}@${mType[1]}@${term}`
+      }
+    }
+    
+    if (!fileState) {
+      baseFun.warning('未上传文件');
+      return;
+    }
+    const res = await uploadAction(fileState, type);
+    // if (res.success) {
+    //   baseFun.info('导入成功');
+    // } else {
+    //   baseFun.error(res.message || '导入失败');
+    // }
+    baseFun.info(res._msg)
+    if (props.callback) props.callback(res);
+  };
+
+  const download = () => {
+    baseFun.download('/api/admin/excelmanage/importAndAuditp/importExcelModel.do', {
+      mType: mType[0],
+    });
+  };
+
+  const getDetailReq = async () => {
+    const data: ImpmTypeConfigModel = await getDetail({ mtype: mType[0] });
+    if(mType.length==3 && mType[2]){
+      return {mtypename: data.mtypename,term: mType[2]}
+    }else{
+      return {mtypename: data.mtypename,term: null}
+    }
+  };
+
+  return (
+    <SDModal
+      title=""
+      visible={disModal}
+      footer={[ <SDButton successMessage='' autoLoading primary onClick={uploadSubmit}>保存</SDButton>,
+       <SDButton onClick={download}>下载模板文件</SDButton>,
+      ]}
+      size={props.impDialogSize ? props.impDialogSize : 's'}
+      onCancel={() => {
+        setDisModal(false);
+        //props.onVisibleChange(false);
+        props.tableRef?.current?.reload();
+        props.tableRef?.current?.clearSelected?.();
+        if(props.onCancel)props.onCancel();
+      }}
+    >
+      <SDLayout >
+        <SDForm
+          editType={'create'}
+          request={getDetailReq}
+          formRef={formRef}
+        >
+          {props.showTerm && 
+            <SDFormText name="term" required type='prodmonth'label="期次" dateFmt={props.dateFmt?props.dateFmt:'YYYYMM'}/>
+          }
+          <SDFormText name="mtypename" readonlyCond="both" label="模板名称" />
+          
+          <Upload maxCount={1} {...fileProps} name="file">
+          <div style={{paddingLeft:'3.4vw'}}>
+                上传文件: &nbsp;&nbsp;<SDOperate icon={<UploadOutlined />}>上传</SDOperate>
+            </div>
+          </Upload>
+          
+        </SDForm>
+      </SDLayout>
+    </SDModal>
+  );
+};
+export default SDImpDialog;

+ 3 - 3
Procedure/frontend/projectb/src/pages/Welcome.tsx

@@ -216,8 +216,8 @@ const Welcome: React.FC = () => {
   useEffect(() => {
     init();
     //十分钟请求一次后台获取数据
-    setInterval(init, 1000 * 60 * 3);
-    getChartData();
+    // setInterval(init, 1000 * 60 * 3);
+    // getChartData();
   }, []);
 
 
@@ -243,7 +243,7 @@ const Welcome: React.FC = () => {
           setTop10OrgAssetAccountName([]);
           setTop10OrgAssetAccountValue([]);
          }
-         
+
          // 风险暴露(一级)风险加权资产占比
          setRiskExposeAssetRatio(resData.RiskExposeAssetRatio?.pieData);
          // 风险暴露(一级)缓释前风险暴露占比

+ 315 - 315
Procedure/frontend/projectb/src/pages/authMng/RoleMng/components/RoleUserMng.tsx

@@ -1,315 +1,315 @@
-import React, { useEffect, useRef, useState } from 'react';
-import type { ProColumns } from '@ant-design/pro-table';
-import type { SysRoleModel } from '@/services/authMng/roleMng';
-import { getRoleUsersfy, saveRoleUser, getRoleUsers } from '@/services/authMng/roleMng';
-import { Space, Switch, Table, Transfer } from 'antd';
-import ProTable from '@ant-design/pro-table';
-import { SDButton, SDModal, baseFun, SDLayout, SDTable } from '@sundata/ui-frame';
-import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
-import type { SysUserModel } from '@/services/authMng/userMng';
-import { ActionType, ProFormInstance } from '@ant-design/pro-components';
-import { ColumnsType, TableRowSelection } from 'antd/es/table/interface';
-import { TransferItem, TransferProps } from 'antd/es/transfer';
-import { difference } from 'lodash';
-
-type RoleUserMngProps = {
-  roleid: string;
-  rolename: string;
-  visible: boolean;
-  onCancel: () => void;
-};
-const RoleUserMng: React.FC<RoleUserMngProps> = (props) => {
-  // /** 用于触发用户列表刷新 */
-  // const [roleUserParam, setRoleUserParam] = useState<SysRoleModel>({});
-  // /** 拥有当前角色的用户列表 */
-  // const [roleUsers, setRoleUsers] = useState<SysUserModel[]>([]);
-  // const formRef = useRef<ProFormInstance>();
-  //   /** 表格引用对象,刷新表格使用 */
-  //   const actionRef = useRef<ActionType>();
-  //     /** 表格引用对象,刷新表格使用 */
-  //     const actionRef2 = useRef<ActionType>();
-  const columns: ColumnsType<SysUserModel> = [
-    {
-      dataIndex: 'cnname',
-      title: '用户名',
-    },
-    {
-      dataIndex: 'loginname',
-      title: '登录名',
-    },
-    {
-      dataIndex: 'orgname',
-      title: '所属机构',
-    },
-  ];
-  const userColumns: ProColumns<SysUserModel>[] = [
-
-    {
-      title: '用户名',
-      dataIndex: 'cnname',
-      // hideInSearch: true,
-    },
-    {
-      title: '登录名',
-      dataIndex: 'loginname',
-      // hideInSearch: true,
-    },
-    {
-      title: '所属机构',
-      dataIndex: 'orgname',
-      // hideInSearch: true,
-    },
-  ];
-  interface TableTransferProps extends TransferProps<SysUserModel> {
-    dataSource: SysUserModel[];
-    Columns: ProColumns<SysUserModel>[];
-  }
-  useEffect(() => {
-    setMockData
-    getRoleUsersfy({ roleid: props.roleid, canselect: 'can' },).then((data) => {
-      setMockData(data.data)
-      // data.data.forEach((item)=>{
-      //   item.key=item.account;
-      // })
-    })
-    getRoleUsers({ roleid: props.roleid, canselect: 'no' }).then((data) => {
-      // let key: string[] =[];
-      // data.data.forEach((item)=>{key.push(item.account||'')})
-      setTargetKeys(data);
-    })
-  }, []);
-  // Customize Table Transfer
-  const TableTransfer = ({ Columns, ...restProps }: TableTransferProps) => (
-    <Transfer {...restProps}>
-      {({
-        filteredItems,
-        onItemSelect,
-        selectedKeys: listSelectedKeys,
-      }) => {
-        const rowSelection: TableRowSelection<SysUserModel> = {
-          onSelect({ key }, selected) {
-            onItemSelect(key as string, selected);
-          },
-          selectedRowKeys: listSelectedKeys,
-        };
-        return (
-          <Table
-            key='account'
-            rowSelection={rowSelection}
-            columns={columns}
-            dataSource={filteredItems}
-            size="small"
-          />
-        );
-      }}
-    </Transfer>
-  );
-  const onChange = (nextTargetKeys: string[]) => {
-    setTargetKeys(nextTargetKeys);
-  };
-
-  const [targetKeys, setTargetKeys] = useState<string[]>([]);
-  const [mockData, setMockData] = useState<SysUserModel[]>([]);
-  return (
-    // sdtable获取不到选中行,按钮先放到toolBarRender
-    <SDModal
-
-      title={`配置角色【${props.rolename}】对应用户`}
-      visible={props.visible}
-      footer={[<SDButton
-        primary
-        key="setRole"
-        onClick={async () => {
-          await saveRoleUser({ roleid: props.roleid }, targetKeys);
-        }}
-
-      >保存
-      </SDButton>,]}
-      onCancel={props.onCancel}
-    >
-      <SDLayout>
-        <TableTransfer
-          titles={['待配置', '已配置']}
-          showSearch
-          dataSource={mockData}
-          targetKeys={targetKeys}
-          onChange={onChange}
-          filterOption={(inputValue, item) =>
-            item.cnname!.indexOf(inputValue) !== -1 || item.loginname!.indexOf(inputValue) !== -1 || item.orgname!.indexOf(inputValue) !== -1
-          }
-          Columns={userColumns}
-        />
-      </SDLayout>
-      {/* <SDLayout subLayout='horizontal'>
-        <SDLayout
-          title='可选用户'
-          colSpan='50%'
-          
-        >
-         <SDTable    
-               rowKey="loginname"
-               search={false}
-               //params={roleUserParam}
-               formRef={formRef}
-               actionRef={actionRef2}
-               request={(data) =>getRoleUsersfy({ ...data, roleid: props.roleid, canselect: 'can' }, ) }
-               columns={userColumns}
-               singleSelect={false}
-               toolBarRender={(_: any, { selectedRows }: any) => [
-                <SDButton
-                  primary
-                  key="setRole"
-                  icon={ <PlusOutlined />}
-                  successMessage=""
-                  autoLoading={true}
-                  onClick={async () => {
-                    if (selectedRows === undefined || selectedRows.length < 1) {
-                      baseFun.warning('请先选择要配置角色的用户');
-                      return;
-                    }
-                    const users = selectedRows.concat(roleUsers);
-                    await saveRoleUser({ roleid: props.roleid }, users);
-                    setRoleUserParam({ remark: Date.now().toString() });
-                    actionRef.current?.reload();
-                    actionRef2.current?.reload();
-                    baseFun.info("处理完成");
-                  } }
-                >
-                  配置角色
-                </SDButton>]}
-    
-   />
-        </SDLayout>
-        <SDLayout
-          title='已选用户'
-          colSpan='50%'
-          
-       //   bodyStyle='layout'
-        >
-           <SDTable    
-              rowKey="loginname"
-               search={false}
-               actionRef={actionRef}
-               //params={roleUserParam}
-
-               request={async () => {
-                            const data = await getRoleUsers({ roleid: props.roleid, canselect: 'no' });
-                             setRoleUsers(data.data);
-                             return data;
-                           } }
-               columns={userColumns}
-               singleSelect={false}
-               toolBarRender={(_, { selectedRows }) => [
-                 <SDButton
-                   primary
-                   key="delRole"
-                   successMessage=""
-                   autoLoading={true}
-                   icon={<DeleteOutlined />}
-                   onClick={async () => {
-                     if (selectedRows === undefined || selectedRows.length < 1) {
-                       baseFun.warning('请先选择要取消角色的用户');
-                       return;
-                     }
-                     const users = roleUsers.filter((item) => !selectedRows.includes(item));
-                     await saveRoleUser({ roleid: props.roleid }, users);
-                     setRoleUserParam({ remark: Date.now().toString() });
-                     actionRef.current?.reload();
-                     actionRef2.current?.reload();
-                     baseFun.info("处理完成");
-                   } }
-               >
-                   取消角色
-                 </SDButton>,
-               ]}
-    
-   />
-        </SDLayout> */}
-      {/* </SDLayout> */}
-    </SDModal>
-
-
-
-
-    // <SDModal
-    //   title={`配置角色【${props.rolename}】对应用户`}
-    //   visible={props.visible}
-    //   footer={null}
-    //   onCancel={props.onCancel}
-    // >
-    //     <SDLayoutLR
-    //       left={{
-    //         title: '可选用户',
-    //         children: (<ProTable<SysUserModel, SysRoleModel>
-    //           search={false}
-    //           rowKey="loginname"
-    //           params={roleUserParam}
-    //           request={(data) => getRoleUsersfy({ ...data, roleid: props.roleid, canselect: 'can' })}
-    //           columns={userColumns}
-    //           rowSelection={{
-    //             selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
-    //           }}
-    //           tableAlertRender={false}
-    //           tableAlertOptionRender={false}
-    //           toolBarRender={(_, { selectedRows }) => [
-    //             <SDButton
-    //               primary
-    //               key="setRole"
-    //               onClick={async () => {
-    //                 if (selectedRows === undefined || selectedRows.length < 1) {
-    //                   baseFun.warning('请先选择要配置角色的用户');
-    //                   return;
-    //                 }
-    //                 const users = selectedRows.concat(roleUsers);
-    //                 await saveRoleUser({ roleid: props.roleid }, users);
-    //                 setRoleUserParam({ remark: Date.now().toString() });
-    //               } }
-    //             >
-    //               <PlusOutlined /> 配置角色
-    //             </SDButton>,
-    //           ]} />),
-    //         colSpan: "50%",
-    //       }}
-    //       rights={[{
-    //         title: "已选用户",
-    //         children: (<ProTable<SysUserModel, SysRoleModel>
-    //           search={false}
-    //           rowKey="loginname"
-    //           params={roleUserParam}
-    //           request={async () => {
-    //             const data = await getRoleUsers({ roleid: props.roleid, canselect: 'no' });
-    //             setRoleUsers(data.data);
-    //             return data;
-    //           } }
-    //           pagination={false}
-    //           columns={userColumns}
-    //           rowSelection={{
-    //             selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
-    //           }}
-    //           tableAlertRender={false}
-    //           tableAlertOptionRender={false}
-    //           toolBarRender={(_, { selectedRows }) => [
-    //             <SDButton
-    //               primary
-    //               key="delRole"
-    //               icon={<DeleteOutlined />}
-    //               onClick={async () => {
-    //                 if (selectedRows === undefined || selectedRows.length < 1) {
-    //                   baseFun.warning('请先选择要取消角色的用户');
-    //                   return;
-    //                 }
-    //                 const users = roleUsers.filter((item) => !selectedRows.includes(item));
-    //                 await saveRoleUser({ roleid: props.roleid }, users);
-    //                 setRoleUserParam({ remark: Date.now().toString() });
-    //               } }
-    //             >
-    //               取消角色
-    //             </SDButton>,
-    //           ]} />),
-    //         colSpan: "50%",
-    //       }]} />
-    //   </SDModal>
-  );
-};
-
-export default RoleUserMng;
+import React, { useEffect, useRef, useState } from 'react';
+import type { ProColumns } from '@ant-design/pro-table';
+import type { SysRoleModel } from '@/services/authMng/roleMng';
+import { getRoleUsersfy, saveRoleUser, getRoleUsers } from '@/services/authMng/roleMng';
+import { Space, Switch, Table, Transfer } from 'antd';
+import ProTable from '@ant-design/pro-table';
+import { SDButton, SDModal, baseFun, SDLayout, SDTable } from '@sundata/ui-frame';
+import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
+import type { SysUserModel } from '@/services/authMng/userMng';
+import { ActionType, ProFormInstance } from '@ant-design/pro-components';
+import { ColumnsType, TableRowSelection } from 'antd/es/table/interface';
+import { TransferItem, TransferProps } from 'antd/es/transfer';
+import { difference } from 'lodash';
+
+type RoleUserMngProps = {
+  roleid: string;
+  rolename: string;
+  visible: boolean;
+  onCancel: () => void;
+};
+const RoleUserMng: React.FC<RoleUserMngProps> = (props) => {
+  // /** 用于触发用户列表刷新 */
+  // const [roleUserParam, setRoleUserParam] = useState<SysRoleModel>({});
+  // /** 拥有当前角色的用户列表 */
+  // const [roleUsers, setRoleUsers] = useState<SysUserModel[]>([]);
+  // const formRef = useRef<ProFormInstance>();
+  //   /** 表格引用对象,刷新表格使用 */
+  //   const actionRef = useRef<ActionType>();
+  //     /** 表格引用对象,刷新表格使用 */
+  //     const actionRef2 = useRef<ActionType>();
+  const columns: ColumnsType<SysUserModel> = [
+    {
+      dataIndex: 'cnname',
+      title: '用户名',
+    },
+    {
+      dataIndex: 'loginname',
+      title: '登录名',
+    },
+    {
+      dataIndex: 'orgname',
+      title: '所属机构',
+    },
+  ];
+  const userColumns: ProColumns<SysUserModel>[] = [
+
+    {
+      title: '用户名',
+      dataIndex: 'cnname',
+      // hideInSearch: true,
+    },
+    {
+      title: '登录名',
+      dataIndex: 'loginname',
+      // hideInSearch: true,
+    },
+    {
+      title: '所属机构',
+      dataIndex: 'orgname',
+      // hideInSearch: true,
+    },
+  ];
+  interface TableTransferProps extends TransferProps<SysUserModel> {
+    dataSource: SysUserModel[];
+    Columns: ProColumns<SysUserModel>[];
+  }
+  useEffect(() => {
+    setMockData
+    getRoleUsersfy({ roleid: props.roleid, canselect: 'can' },).then((data) => {
+      setMockData(data.data)
+      // data.data.forEach((item)=>{
+      //   item.key=item.account;
+      // })
+    })
+    getRoleUsers({ roleid: props.roleid, canselect: 'no' }).then((data) => {
+      // let key: string[] =[];
+      // data.data.forEach((item)=>{key.push(item.account||'')})
+      setTargetKeys(data);
+    })
+  }, []);
+  // Customize Table Transfer
+  const TableTransfer = ({ Columns, ...restProps }: TableTransferProps) => (
+    <Transfer {...restProps}>
+      {({
+        filteredItems,
+        onItemSelect,
+        selectedKeys: listSelectedKeys,
+      }) => {
+        const rowSelection: TableRowSelection<SysUserModel> = {
+          onSelect({ key }, selected) {
+            onItemSelect(key as string, selected);
+          },
+          selectedRowKeys: listSelectedKeys,
+        };
+        return (
+          <Table
+            key='account'
+            rowSelection={rowSelection}
+            columns={columns}
+            dataSource={filteredItems}
+            size="small"
+          />
+        );
+      }}
+    </Transfer>
+  );
+  const onChange = (nextTargetKeys: any[]) => {
+    setTargetKeys(nextTargetKeys);
+  };
+
+  const [targetKeys, setTargetKeys] = useState<string[]>([]);
+  const [mockData, setMockData] = useState<SysUserModel[]>([]);
+  return (
+    // sdtable获取不到选中行,按钮先放到toolBarRender
+    <SDModal
+
+      title={`配置角色【${props.rolename}】对应用户`}
+      visible={props.visible}
+      footer={[<SDButton
+        primary
+        key="setRole"
+        onClick={async () => {
+          await saveRoleUser({ roleid: props.roleid }, targetKeys);
+        }}
+
+      >保存
+      </SDButton>,]}
+      onCancel={props.onCancel}
+    >
+      <SDLayout>
+        <TableTransfer
+          titles={['待配置', '已配置']}
+          showSearch
+          dataSource={mockData}
+          targetKeys={targetKeys}
+          onChange={onChange}
+          filterOption={(inputValue, item) =>
+            item.cnname!.indexOf(inputValue) !== -1 || item.loginname!.indexOf(inputValue) !== -1 || item.orgname!.indexOf(inputValue) !== -1
+          }
+          Columns={userColumns}
+        />
+      </SDLayout>
+      {/* <SDLayout subLayout='horizontal'>
+        <SDLayout
+          title='可选用户'
+          colSpan='50%'
+          
+        >
+         <SDTable    
+               rowKey="loginname"
+               search={false}
+               //params={roleUserParam}
+               formRef={formRef}
+               actionRef={actionRef2}
+               request={(data) =>getRoleUsersfy({ ...data, roleid: props.roleid, canselect: 'can' }, ) }
+               columns={userColumns}
+               singleSelect={false}
+               toolBarRender={(_: any, { selectedRows }: any) => [
+                <SDButton
+                  primary
+                  key="setRole"
+                  icon={ <PlusOutlined />}
+                  successMessage=""
+                  autoLoading={true}
+                  onClick={async () => {
+                    if (selectedRows === undefined || selectedRows.length < 1) {
+                      baseFun.warning('请先选择要配置角色的用户');
+                      return;
+                    }
+                    const users = selectedRows.concat(roleUsers);
+                    await saveRoleUser({ roleid: props.roleid }, users);
+                    setRoleUserParam({ remark: Date.now().toString() });
+                    actionRef.current?.reload();
+                    actionRef2.current?.reload();
+                    baseFun.info("处理完成");
+                  } }
+                >
+                  配置角色
+                </SDButton>]}
+    
+   />
+        </SDLayout>
+        <SDLayout
+          title='已选用户'
+          colSpan='50%'
+          
+       //   bodyStyle='layout'
+        >
+           <SDTable    
+              rowKey="loginname"
+               search={false}
+               actionRef={actionRef}
+               //params={roleUserParam}
+
+               request={async () => {
+                            const data = await getRoleUsers({ roleid: props.roleid, canselect: 'no' });
+                             setRoleUsers(data.data);
+                             return data;
+                           } }
+               columns={userColumns}
+               singleSelect={false}
+               toolBarRender={(_, { selectedRows }) => [
+                 <SDButton
+                   primary
+                   key="delRole"
+                   successMessage=""
+                   autoLoading={true}
+                   icon={<DeleteOutlined />}
+                   onClick={async () => {
+                     if (selectedRows === undefined || selectedRows.length < 1) {
+                       baseFun.warning('请先选择要取消角色的用户');
+                       return;
+                     }
+                     const users = roleUsers.filter((item) => !selectedRows.includes(item));
+                     await saveRoleUser({ roleid: props.roleid }, users);
+                     setRoleUserParam({ remark: Date.now().toString() });
+                     actionRef.current?.reload();
+                     actionRef2.current?.reload();
+                     baseFun.info("处理完成");
+                   } }
+               >
+                   取消角色
+                 </SDButton>,
+               ]}
+    
+   />
+        </SDLayout> */}
+      {/* </SDLayout> */}
+    </SDModal>
+
+
+
+
+    // <SDModal
+    //   title={`配置角色【${props.rolename}】对应用户`}
+    //   visible={props.visible}
+    //   footer={null}
+    //   onCancel={props.onCancel}
+    // >
+    //     <SDLayoutLR
+    //       left={{
+    //         title: '可选用户',
+    //         children: (<ProTable<SysUserModel, SysRoleModel>
+    //           search={false}
+    //           rowKey="loginname"
+    //           params={roleUserParam}
+    //           request={(data) => getRoleUsersfy({ ...data, roleid: props.roleid, canselect: 'can' })}
+    //           columns={userColumns}
+    //           rowSelection={{
+    //             selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
+    //           }}
+    //           tableAlertRender={false}
+    //           tableAlertOptionRender={false}
+    //           toolBarRender={(_, { selectedRows }) => [
+    //             <SDButton
+    //               primary
+    //               key="setRole"
+    //               onClick={async () => {
+    //                 if (selectedRows === undefined || selectedRows.length < 1) {
+    //                   baseFun.warning('请先选择要配置角色的用户');
+    //                   return;
+    //                 }
+    //                 const users = selectedRows.concat(roleUsers);
+    //                 await saveRoleUser({ roleid: props.roleid }, users);
+    //                 setRoleUserParam({ remark: Date.now().toString() });
+    //               } }
+    //             >
+    //               <PlusOutlined /> 配置角色
+    //             </SDButton>,
+    //           ]} />),
+    //         colSpan: "50%",
+    //       }}
+    //       rights={[{
+    //         title: "已选用户",
+    //         children: (<ProTable<SysUserModel, SysRoleModel>
+    //           search={false}
+    //           rowKey="loginname"
+    //           params={roleUserParam}
+    //           request={async () => {
+    //             const data = await getRoleUsers({ roleid: props.roleid, canselect: 'no' });
+    //             setRoleUsers(data.data);
+    //             return data;
+    //           } }
+    //           pagination={false}
+    //           columns={userColumns}
+    //           rowSelection={{
+    //             selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
+    //           }}
+    //           tableAlertRender={false}
+    //           tableAlertOptionRender={false}
+    //           toolBarRender={(_, { selectedRows }) => [
+    //             <SDButton
+    //               primary
+    //               key="delRole"
+    //               icon={<DeleteOutlined />}
+    //               onClick={async () => {
+    //                 if (selectedRows === undefined || selectedRows.length < 1) {
+    //                   baseFun.warning('请先选择要取消角色的用户');
+    //                   return;
+    //                 }
+    //                 const users = roleUsers.filter((item) => !selectedRows.includes(item));
+    //                 await saveRoleUser({ roleid: props.roleid }, users);
+    //                 setRoleUserParam({ remark: Date.now().toString() });
+    //               } }
+    //             >
+    //               取消角色
+    //             </SDButton>,
+    //           ]} />),
+    //         colSpan: "50%",
+    //       }]} />
+    //   </SDModal>
+  );
+};
+
+export default RoleUserMng;

+ 534 - 534
Procedure/frontend/projectb/src/pages/batchMng/BatchDispatch/batchDispatch.tsx

@@ -1,535 +1,535 @@
-import React, { useState, useRef, useEffect, useContext } from 'react';
-import { Button, FormInstance, Table } from 'antd';
-import {
-  CaretRightOutlined,
-  ClockCircleOutlined,
-  LoadingOutlined,
-  PauseOutlined,
-  PoweroffOutlined,
-  ReloadOutlined,
-  RotateRightOutlined,
-  SearchOutlined,
-  SyncOutlined,
-} from '@ant-design/icons';
-import dayjs from 'dayjs';
-import type { ProColumns, ActionType, ProFormInstance } from '@ant-design/pro-components';
-import { ProTable } from '@ant-design/pro-components';
-import {
-  ProFormDatePicker,
-  ProFormDateRangePicker,
-  ProFormSelect,
-  ProFormText,
-} from '@ant-design/pro-components';
-
-import {
-  BatchDispatchModel,
-  BatchDispatchPropsModel,
-  queryDefaultCondition,
-} from '@/services/batchMng/batchDispatch';
-import {
-  getDataList,
-  saveBatchStartInfo,
-  batchStatusRefresh,
-  batchStop,
-  batchFuns,
-} from '@/services/batchMng/batchDispatch';
-import { selHeadOrgCode, getBatchname } from '@/services/batchMng/batchLog';
-import { SDFormText, SDModalForm, baseFun, SDModal, SDButton, SDLayout, SDPage, SDSubmitButton } from '@sundata/ui-frame';
-import BatchLog from '../BatchLog/batchLog';
-import SDContext, { calFormItemProps, SDFormItem } from '@sundata/ui-frame/lib/components/SDContext';
-
-const BatchDispatch: React.FC = () => {
-  /** 表格引用对象,刷新表格使用 */
-  const actionRef = useRef<ActionType>();
-  const caledProps = calFormItemProps(useContext(SDContext), {});
-  /** 批次整体运行状态 */
-  const [batchStatus, setBatchStatus] = useState<string>('normalRunning');
-  const [batchStatusName, setBatchStatusName] = useState<string>('未开始');
-  /** 列表轮询设置 */
-  const [polling, setPolling] = useState<number | undefined>();
-  /** 批次日期 */
-  const [batchDate, setBatchDate] = useState<string | undefined>();
-  /** 法人行 */
-  const [headOrgCode, setHeadOrgCode] = useState<string | undefined>();
-  /** 批次编码 */
-  const [batchId, setBatchId] = useState<string | undefined>();
-    /** 批次编码 */
-    const [batchName, setBatchName] = useState<string | undefined>();
-  /** 批次名称 */
-  const [stepName, setStepName] = useState<string | undefined>();
-  /** 控制列表刷新,每次+1可导致列表自动刷新 */
-  const [resh, setResh] = useState<number>(1);
-
-  /**批次运行配置页面展示控制 */
-  const [batchStartVisible, setBatchStartVisible] = useState<boolean>(false);
-  /**轮询时间配置页面展示控制 */
-  const [refTimeVisible, setRefTimeVisible] = useState<boolean>(false);
-  /**批次日志查询陀展示控制 */
-  const [batchLogVisible, setBatchLogVisible] = useState<boolean>(false);
-  /**当前选择的行 */
-  const [selectedRows, setSelectedRows] = useState<BatchDispatchModel[]>([]);
-  const formRef = useRef<FormInstance>();//展示批次步骤列表
-  const startBatchRef = useRef<ProFormInstance>();//发起批次
-  const cycformRef = useRef<ProFormInstance>();//轮询
-
-
-  useEffect(() => {
-    queryDefaultCondition().then((data)=>{
-        setBatchStatus(data.batchStatus || 'normalRunning');
-        setBatchStatusName(data.batchStatusName || '未开始');
-        formRef.current?.setFieldValue('batchId', data.batchId);
-        formRef.current?.setFieldValue('headOrgCode', data.headOrgCode);
-        formRef.current?.setFieldValue('batchDate', data.batchDate);
-        formRef.current?.setFieldValue('wholestate', data.batchStatusName || '未开始');
-        setHeadOrgCode(data.headOrgCode);
-        setBatchId(data.batchId);
-        setBatchDate(data.batchDate);
-       // actionRef.current?.reload();
-    })
-    
-  }, []);
-
-  const columns: ProColumns<BatchDispatchModel, 'treeSelect'>[] = [
-    {
-      title: '步骤',
-      dataIndex: 'stepName',
-      search: false,
-      width: '30%',
-      render: (_, record: BatchDispatchModel) => {
-        return record.runType ? <a>{_}</a> : _;
-      },
-    },
-    {
-      title: '执行状态',
-      dataIndex: 'stepStatusName',
-      search: false,
-      width: '7%',
-    },
-    {
-      title: '开始时间',
-      dataIndex: 'beginTime',
-      search: false,
-      width: '16%',
-    },
-    {
-      title: '结束时间',
-      dataIndex: 'endTime',
-      search: false,
-      width: '16%',
-    },
-    {
-      title: '用时(毫秒)',
-      dataIndex: 'duration',
-      search: false,
-      width: '9%',
-    },
-    {
-      title: '执行结果',
-      dataIndex: 'msg',
-      search: false,
-      ellipsis: true,
-      copyable: true,
-      width: '20%',
-    },
-    {
-      title: '步骤编码',
-      dataIndex: 'stepId',
-      search: false,
-      hideInTable: true,
-    },
-    {
-      title: '执行状态编码',
-      dataIndex: 'stepStatus',
-      search: false,
-      hideInTable: true,
-    },
-    {
-      title: '批次日期',
-      dataIndex: 'batchDate',
-      hideInTable: true,
-      renderFormItem: () => {
-        return (
-          <ProFormDatePicker
-            fieldProps={{
-              onChange: (_, val) => {
-                setBatchDate(val);
-              },
-            }}
-          />
-        );
-      },
-    },
-    {
-      title: '法人行',
-      dataIndex: 'headOrgCode',
-      hideInTable: true,
-      renderFormItem: () => {
-        return (
-          <ProFormSelect
-            request={async () => await selHeadOrgCode({})}
-            fieldProps={{
-              onChange: (value) => {
-                setHeadOrgCode(value);
-              },
-            }}
-          />
-        );
-      },
-    },
-    {
-      title: '批次名称',
-      dataIndex: 'batchId',
-      hideInTable: true,
-      renderFormItem: () => {
-        return (
-          <ProFormSelect
-            request={async () => await getBatchname()}
-            fieldProps={{
-              onChange: (value) => {
-                setBatchId(value);
-              },
-            }}
-          />
-        );
-      },
-    },
-    {
-      title: '执行状态',
-      dataIndex: 'wholestate',
-      readonly: true,
-      hideInTable: true,
-    }
-  ];
-
-  /**
-   * 批次步骤状态总控制
-   * @param type
-   */
-  const batchOperate = async (type: 'reStart' | 'reTry' | 'skip' | 'stop') => {
-    if (selectedRows.length == 0) {
-      baseFun.warning('至少选择一条记录!');
-    } else {
-      const stepIds: string[] = [];
-      selectedRows.forEach((item) => {
-        if (item.stepStatus == 'running') {
-          baseFun.warning('不能选择状态为执行中的步骤!');
-          throw new Error('Function not implemented.');
-        } else if (item.stepId) {
-          stepIds.push(item.stepId);
-        }
-      });
-      const body = {
-        batchDate: batchDate,
-        batchId: batchId,
-        headOrgCode: headOrgCode,
-        stepIds: stepIds,
-      };
-      await batchFuns(body, type).then((data: any) => {
-        if(type == 'stop'){
-          baseFun.info(data);
-        }else{
-          baseFun.info('处理成功');
-        }
-        
-        setResh(resh + 1);
-      });
-    }
-  };
-  // defaultExpandAllRows只对可编辑表格首次数据加载时生效
-  const [expandedRowKeys, setExpandedRowKeys] = useState<number[]>([]);
-
-  return (
-    <SDPage>
-      <ProTable<BatchDispatchModel>
-        //headerTitle={'整体执行状态:' + batchStatusName}
-        // rowKey="stepId"
-        rowSelection={{
-          selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
-          onChange: (_, selecteds) => {
-            setSelectedRows(selecteds);
-          },
-        }}
-        request={async (body: BatchDispatchPropsModel) => {
-          if (!body.batchDate || !body.batchId || !body.headOrgCode) {
-            return [];
-          }
-          const statusModel = await batchStatusRefresh(body);
-          setBatchStatus(statusModel.batchStatus || 'normalRunning');
-          setBatchStatusName(statusModel.batchStatusName || '未开始');
-          formRef.current?.setFieldValue('wholestate', statusModel.batchStatusName || '未开始')
-          const datas = await getDataList(body);
-          const count = datas.data[0].key || 1;
-          const keys = [count];
-          for (let i=0; i< count; i++) keys.push(i);
-          setExpandedRowKeys(keys);
-          return datas;
-        }}
-        pagination={false}
-        formRef={formRef}
-        params={{ headOrgCode: headOrgCode, batchDate: batchDate, batchId: batchId, resh: resh }}
-        columns={columns}
-        actionRef={actionRef}
-        polling={polling || undefined}
-        toolBarRender={() => {
-          const btns: React.ReactNode[] = [];
-          const btnInfos = [
-            {
-              label: '发起批次',
-              icon: <CaretRightOutlined style={{color:'#00cc66'}}/>,
-              click: async () => {
-                
-                if (batchDate && batchId && headOrgCode) {
-                  const batchNames = await getBatchname();
-                  batchNames.forEach((data)=>{
-                    if(data.value===batchId){
-                      setBatchName(data.label);
-                    }
-                  })
-                  setBatchStartVisible(true);
-                } else {
-                  baseFun.warning('请录入所有条件!');
-                }
-
-              },
-            },
-            {
-              label: '停止批次',
-              icon: <PoweroffOutlined style={{color:'red'}}/>,
-              click: () => {
-                baseFun.confirm('即将停止批次执行,是否确定', async () => {
-                  if (batchStatus != 'normalRunning' && batchStatus != 'errorRunning') {
-                    baseFun.warning('批次状态不在执行中不可用');
-                  } else {
-                    if (batchDate && batchId && headOrgCode) {
-                      await batchStop({
-                        batchDate: batchDate,
-                        batchId: batchId,
-                        headOrgCode: headOrgCode,
-                      }).then(
-                        (data) =>{ 
-                          baseFun.info('停止批次成功');
-                          setResh(resh + 1)
-                        });
-                    } else {
-                      baseFun.warning('批次状态不在执行中不可用');
-                    }
-                  }
-                });
-              },
-            },
-            { label: '步骤重跑', icon: <ReloadOutlined style={{color:'#EEB422'}}/>, click: () => batchOperate('reStart') },
-            { label: '步骤停止', icon: <PauseOutlined style={{color:'red'}}/>, click: () => batchOperate('stop') },
-            { label: '递归重跑', icon: <SyncOutlined style={{color:'#EEB422'}}/>, click: () => batchOperate('reTry') },
-            { label: '步骤跳过', icon: <RotateRightOutlined style={{color:'#EEB422'}}/>, click: () => batchOperate('skip') },
-            {
-              label: '明细查看',
-              icon: <SearchOutlined style={{color:'#EEB422'}}/>,
-              click: () => {
-                if (selectedRows.length == 1) {
-                  setStepName(selectedRows[0].stepName);
-                  setBatchLogVisible(true);
-                } else {
-                  baseFun.warning('只能选择一条!');
-                }
-              },
-            },
-          ];
-          let btnIndex = 0;
-          btnInfos.forEach((btnInfo) => {
-            const btn = (
-              <SDButton
-                successMessage=''
-                autoLoading={true}
-                key={'btn' + btnIndex++}
-                icon={btnInfo.icon}
-                //type="text"
-                onClick={btnInfo.click}
-              >
-                {btnInfo.label}
-              </SDButton>
-            );
-            btns.push(btn);
-          });
-          return [
-            <Button.Group key="btnGroup" style={{ float: 'left' }}>
-              {btns}
-            </Button.Group>,
-            <SDButton
-              key="setRefTimeBtn"
-              successMessage=''
-              icon={<ClockCircleOutlined />}
-              primary
-              onClick={() => setRefTimeVisible(true)}
-            >
-              设置刷新时间
-            </SDButton>,
-            <SDButton
-              key="pollBtn"
-              successMessage=''
-              primary
-              icon={polling ? <LoadingOutlined /> : <ReloadOutlined />}
-              onClick={() => {
-                if (polling) {
-                  setPolling(undefined);
-                  return;
-                }
-                setPolling(2000);
-              }}
-            >
-
-              {polling ? '停止轮询' : '开始轮询'}
-            </SDButton>,
-          ];
-        }}
-
-        search={
-          { optionRender: () => [], defaultCollapsed: false }
-        }
-        rowKey="key"
-        expandable={{
-          expandedRowKeys,
-          onExpand: (expanded, record) => {
-            if (expanded) setExpandedRowKeys([...expandedRowKeys, record.key!]);
-            else setExpandedRowKeys(expandedRowKeys.filter(item => item !== record.key));
-          }
-        }}
-      />
-      {batchStartVisible && (
-        <SDModalForm
-          editType="create"
-          initialValues={{
-            batchId: batchId,
-            headOrgCode: headOrgCode,
-            batchName:batchName,
-          }}
-          title={'批次发起信息配置'}
-          visible={batchStartVisible}
-          onVisibleChange={setBatchStartVisible}
-          tableRef={actionRef}
-          formRef={startBatchRef}
-          footer={<SDButton primary 
-            successMessage='发起批次成功'
-            autoLoading={true}
-            onClick={async () => {
-            const obj = startBatchRef?.current?.getFieldFormatValue?.();
-            const par = {
-              batchId: obj.batchId,
-              headOrgCode: obj.headOrgCode,
-              startdate: dayjs(obj.runDate?.startOrEnd[0]).format('YYYY-MM-DD'),
-              enddate: dayjs(obj.runDate?.startOrEnd[1]).format('YYYY-MM-DD'),
-            }
-            //console.log(par);
-            await saveBatchStartInfo(par).then(() => {
-
-              setResh(resh + 1);
-              setBatchStartVisible(false);
-            });
-          }}>确定</SDButton>}
-        >
-
-          <ProFormText name="batchId" hidden />
-          <SDFormItem {...caledProps} label="批次名称">
-          <ProFormText name="batchName"  readonly width="xl"
-            colProps={{ xs: 24 }}/>
-            </SDFormItem>
-             <SDFormItem {...caledProps} label="法人行">
-          <ProFormSelect
-            name="headOrgCode"
-            readonly={true}
-            request={async () => {
-              return await selHeadOrgCode({});
-            }}
-            width="xl"
-            colProps={{ xs: 24 }}
-          />
-          </SDFormItem>
-          {/* <SDFormText type='date' name="startdate" label="批次执行日期" required />
-              <SDFormText type='date' name="enddate" />  */}
-  <SDFormItem {...caledProps} label="批次执行日期">        
-          <ProFormDateRangePicker
-            name={['runDate', 'startOrEnd']}
-            required
-            dataFormat='YYYY-MM-DD'
-            fieldProps={{ 
-              format: (value: any) => {
-                return value.format('YYYY-MM-DD');
-              } }}
-          />
-</SDFormItem>
-
-        </SDModalForm>
-      )}
-      {refTimeVisible && (
-        <SDModalForm
-          editType="create"
-          formRef={cycformRef}
-          title={'轮询时间设置'}
-          // doSubmit={async (body: { refTime?: number }) => {
-          //   if (body.refTime) {
-          //     setPolling(body.refTime);
-          //   }
-          // }}
-          // footer={<SDButton onClick={() => {
-          //     const refVar: number = cycformRef.current?.getFieldValue('refTime');
-          //     if (refVar) {
-          //       setPolling(refVar);
-          //     }
-          // }}>
-          // </SDButton>}
-          footer={<SDSubmitButton 
-            primary
-            formRef={cycformRef} 
-            editType={"create"}
-            doSubmit={async (body: { refTime?: number }) => {
-              if (body.refTime) {
-                setPolling(body.refTime);
-              }
-              setRefTimeVisible(false);
-            }}
-          >确定</SDSubmitButton>}
-          visible={refTimeVisible}
-          onVisibleChange={setRefTimeVisible}
-          tableRef={actionRef}
-        >
-          {/* <SDLayout bodyStyle={true}> </SDLayout>*/}
-          <SDFormText name="refTime" label="轮询时间(毫秒)" type="number" />
-
-        </SDModalForm>
-      )}
-      {batchLogVisible && (
-        <SDModal
-          title="批次日志查询"
-          size="m"
-          visible={batchLogVisible}
-          footer={null}
-          onCancel={() => setBatchLogVisible(false)}
-        >
-          <SDLayout
-            footer={[
-              <SDButton primary key='save'
-                onClick={() => {
-                  setBatchLogVisible(false);
-                }}> 确定
-              </SDButton>,
-              <SDButton
-                key='click'
-                onClick={() => {
-                  setBatchLogVisible(false);
-                }}>
-                关闭
-              </SDButton>]}
-          >
-            <BatchLog
-              params={{
-                batchDate: batchDate,
-                batchId: batchId,
-                stepName: stepName,
-              }}
-            />
-          </SDLayout>
-        </SDModal>
-      )}
-    </SDPage>
-  );
-};
+import React, { useState, useRef, useEffect, useContext } from 'react';
+import { Button, FormInstance, Table } from 'antd';
+import {
+  CaretRightOutlined,
+  ClockCircleOutlined,
+  LoadingOutlined,
+  PauseOutlined,
+  PoweroffOutlined,
+  ReloadOutlined,
+  RotateRightOutlined,
+  SearchOutlined,
+  SyncOutlined,
+} from '@ant-design/icons';
+import dayjs from 'dayjs';
+import type { ProColumns, ActionType, ProFormInstance } from '@ant-design/pro-components';
+import { ProTable } from '@ant-design/pro-components';
+import {
+  ProFormDatePicker,
+  ProFormDateRangePicker,
+  ProFormSelect,
+  ProFormText,
+} from '@ant-design/pro-components';
+
+import {
+  BatchDispatchModel,
+  BatchDispatchPropsModel,
+  queryDefaultCondition,
+} from '@/services/batchMng/batchDispatch';
+import {
+  getDataList,
+  saveBatchStartInfo,
+  batchStatusRefresh,
+  batchStop,
+  batchFuns,
+} from '@/services/batchMng/batchDispatch';
+import { selHeadOrgCode, getBatchname } from '@/services/batchMng/batchLog';
+import { SDFormText, SDModalForm, baseFun, SDModal, SDButton, SDLayout, SDPage, SDSubmitButton } from '@sundata/ui-frame';
+import BatchLog from '../BatchLog/batchLog';
+import SDContext, { calFormItemProps, SDFormItem } from '@sundata/ui-frame/lib/components/SDContext';
+
+const BatchDispatch: React.FC = () => {
+  /** 表格引用对象,刷新表格使用 */
+  const actionRef = useRef<ActionType>();
+  const caledProps = calFormItemProps(useContext(SDContext), {});
+  /** 批次整体运行状态 */
+  const [batchStatus, setBatchStatus] = useState<string>('normalRunning');
+  const [batchStatusName, setBatchStatusName] = useState<string>('未开始');
+  /** 列表轮询设置 */
+  const [polling, setPolling] = useState<number | undefined>();
+  /** 批次日期 */
+  const [batchDate, setBatchDate] = useState<any>();
+  /** 法人行 */
+  const [headOrgCode, setHeadOrgCode] = useState<string | undefined>();
+  /** 批次编码 */
+  const [batchId, setBatchId] = useState<string | undefined>();
+    /** 批次编码 */
+    const [batchName, setBatchName] = useState<string | undefined>();
+  /** 批次名称 */
+  const [stepName, setStepName] = useState<string | undefined>();
+  /** 控制列表刷新,每次+1可导致列表自动刷新 */
+  const [resh, setResh] = useState<number>(1);
+
+  /**批次运行配置页面展示控制 */
+  const [batchStartVisible, setBatchStartVisible] = useState<boolean>(false);
+  /**轮询时间配置页面展示控制 */
+  const [refTimeVisible, setRefTimeVisible] = useState<boolean>(false);
+  /**批次日志查询陀展示控制 */
+  const [batchLogVisible, setBatchLogVisible] = useState<boolean>(false);
+  /**当前选择的行 */
+  const [selectedRows, setSelectedRows] = useState<BatchDispatchModel[]>([]);
+  const formRef = useRef<FormInstance>();//展示批次步骤列表
+  const startBatchRef = useRef<ProFormInstance>();//发起批次
+  const cycformRef = useRef<ProFormInstance>();//轮询
+
+
+  useEffect(() => {
+    queryDefaultCondition().then((data)=>{
+        setBatchStatus(data.batchStatus || 'normalRunning');
+        setBatchStatusName(data.batchStatusName || '未开始');
+        formRef.current?.setFieldValue('batchId', data.batchId);
+        formRef.current?.setFieldValue('headOrgCode', data.headOrgCode);
+        formRef.current?.setFieldValue('batchDate', data.batchDate);
+        formRef.current?.setFieldValue('wholestate', data.batchStatusName || '未开始');
+        setHeadOrgCode(data.headOrgCode);
+        setBatchId(data.batchId);
+        setBatchDate(data.batchDate);
+       // actionRef.current?.reload();
+    })
+    
+  }, []);
+
+  const columns: ProColumns<BatchDispatchModel, 'treeSelect'>[] = [
+    {
+      title: '步骤',
+      dataIndex: 'stepName',
+      search: false,
+      width: '30%',
+      render: (_, record: BatchDispatchModel) => {
+        return record.runType ? <a>{_}</a> : _;
+      },
+    },
+    {
+      title: '执行状态',
+      dataIndex: 'stepStatusName',
+      search: false,
+      width: '7%',
+    },
+    {
+      title: '开始时间',
+      dataIndex: 'beginTime',
+      search: false,
+      width: '16%',
+    },
+    {
+      title: '结束时间',
+      dataIndex: 'endTime',
+      search: false,
+      width: '16%',
+    },
+    {
+      title: '用时(毫秒)',
+      dataIndex: 'duration',
+      search: false,
+      width: '9%',
+    },
+    {
+      title: '执行结果',
+      dataIndex: 'msg',
+      search: false,
+      ellipsis: true,
+      copyable: true,
+      width: '20%',
+    },
+    {
+      title: '步骤编码',
+      dataIndex: 'stepId',
+      search: false,
+      hideInTable: true,
+    },
+    {
+      title: '执行状态编码',
+      dataIndex: 'stepStatus',
+      search: false,
+      hideInTable: true,
+    },
+    {
+      title: '批次日期',
+      dataIndex: 'batchDate',
+      hideInTable: true,
+      renderFormItem: () => {
+        return (
+          <ProFormDatePicker
+            fieldProps={{
+              onChange: (_, val) => {
+                setBatchDate(val);
+              },
+            }}
+          />
+        );
+      },
+    },
+    {
+      title: '法人行',
+      dataIndex: 'headOrgCode',
+      hideInTable: true,
+      renderFormItem: () => {
+        return (
+          <ProFormSelect
+            request={async () => await selHeadOrgCode({})}
+            fieldProps={{
+              onChange: (value) => {
+                setHeadOrgCode(value);
+              },
+            }}
+          />
+        );
+      },
+    },
+    {
+      title: '批次名称',
+      dataIndex: 'batchId',
+      hideInTable: true,
+      renderFormItem: () => {
+        return (
+          <ProFormSelect
+            request={async () => await getBatchname()}
+            fieldProps={{
+              onChange: (value) => {
+                setBatchId(value);
+              },
+            }}
+          />
+        );
+      },
+    },
+    {
+      title: '执行状态',
+      dataIndex: 'wholestate',
+      readonly: true,
+      hideInTable: true,
+    }
+  ];
+
+  /**
+   * 批次步骤状态总控制
+   * @param type
+   */
+  const batchOperate = async (type: 'reStart' | 'reTry' | 'skip' | 'stop') => {
+    if (selectedRows.length == 0) {
+      baseFun.warning('至少选择一条记录!');
+    } else {
+      const stepIds: string[] = [];
+      selectedRows.forEach((item) => {
+        if (item.stepStatus == 'running') {
+          baseFun.warning('不能选择状态为执行中的步骤!');
+          throw new Error('Function not implemented.');
+        } else if (item.stepId) {
+          stepIds.push(item.stepId);
+        }
+      });
+      const body = {
+        batchDate: batchDate,
+        batchId: batchId,
+        headOrgCode: headOrgCode,
+        stepIds: stepIds,
+      };
+      await batchFuns(body, type).then((data: any) => {
+        if(type == 'stop'){
+          baseFun.info(data);
+        }else{
+          baseFun.info('处理成功');
+        }
+        
+        setResh(resh + 1);
+      });
+    }
+  };
+  // defaultExpandAllRows只对可编辑表格首次数据加载时生效
+  const [expandedRowKeys, setExpandedRowKeys] = useState<number[]>([]);
+
+  return (
+    <SDPage>
+      <ProTable<BatchDispatchModel>
+        //headerTitle={'整体执行状态:' + batchStatusName}
+        // rowKey="stepId"
+        rowSelection={{
+          selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
+          onChange: (_, selecteds) => {
+            setSelectedRows(selecteds);
+          },
+        }}
+        request={async (body: BatchDispatchPropsModel) => {
+          if (!body.batchDate || !body.batchId || !body.headOrgCode) {
+            return [];
+          }
+          const statusModel = await batchStatusRefresh(body);
+          setBatchStatus(statusModel.batchStatus || 'normalRunning');
+          setBatchStatusName(statusModel.batchStatusName || '未开始');
+          formRef.current?.setFieldValue('wholestate', statusModel.batchStatusName || '未开始')
+          const datas = await getDataList(body);
+          const count = datas.data[0].key || 1;
+          const keys = [count];
+          for (let i=0; i< count; i++) keys.push(i);
+          setExpandedRowKeys(keys);
+          return datas;
+        }}
+        pagination={false}
+        formRef={formRef}
+        params={{ headOrgCode: headOrgCode, batchDate: batchDate, batchId: batchId, resh: resh }}
+        columns={columns}
+        actionRef={actionRef}
+        polling={polling || undefined}
+        toolBarRender={() => {
+          const btns: React.ReactNode[] = [];
+          const btnInfos = [
+            {
+              label: '发起批次',
+              icon: <CaretRightOutlined style={{color:'#00cc66'}}/>,
+              click: async () => {
+                
+                if (batchDate && batchId && headOrgCode) {
+                  const batchNames = await getBatchname();
+                  batchNames.forEach((data)=>{
+                    if(data.value===batchId){
+                      setBatchName(data.label);
+                    }
+                  })
+                  setBatchStartVisible(true);
+                } else {
+                  baseFun.warning('请录入所有条件!');
+                }
+
+              },
+            },
+            {
+              label: '停止批次',
+              icon: <PoweroffOutlined style={{color:'red'}}/>,
+              click: () => {
+                baseFun.confirm('即将停止批次执行,是否确定', async () => {
+                  if (batchStatus != 'normalRunning' && batchStatus != 'errorRunning') {
+                    baseFun.warning('批次状态不在执行中不可用');
+                  } else {
+                    if (batchDate && batchId && headOrgCode) {
+                      await batchStop({
+                        batchDate: batchDate,
+                        batchId: batchId,
+                        headOrgCode: headOrgCode,
+                      }).then(
+                        (data) =>{ 
+                          baseFun.info('停止批次成功');
+                          setResh(resh + 1)
+                        });
+                    } else {
+                      baseFun.warning('批次状态不在执行中不可用');
+                    }
+                  }
+                });
+              },
+            },
+            { label: '步骤重跑', icon: <ReloadOutlined style={{color:'#EEB422'}}/>, click: () => batchOperate('reStart') },
+            { label: '步骤停止', icon: <PauseOutlined style={{color:'red'}}/>, click: () => batchOperate('stop') },
+            { label: '递归重跑', icon: <SyncOutlined style={{color:'#EEB422'}}/>, click: () => batchOperate('reTry') },
+            { label: '步骤跳过', icon: <RotateRightOutlined style={{color:'#EEB422'}}/>, click: () => batchOperate('skip') },
+            {
+              label: '明细查看',
+              icon: <SearchOutlined style={{color:'#EEB422'}}/>,
+              click: () => {
+                if (selectedRows.length == 1) {
+                  setStepName(selectedRows[0].stepName);
+                  setBatchLogVisible(true);
+                } else {
+                  baseFun.warning('只能选择一条!');
+                }
+              },
+            },
+          ];
+          let btnIndex = 0;
+          btnInfos.forEach((btnInfo) => {
+            const btn = (
+              <SDButton
+                successMessage=''
+                autoLoading={true}
+                key={'btn' + btnIndex++}
+                icon={btnInfo.icon}
+                //type="text"
+                onClick={btnInfo.click}
+              >
+                {btnInfo.label}
+              </SDButton>
+            );
+            btns.push(btn);
+          });
+          return [
+            <Button.Group key="btnGroup" style={{ float: 'left' }}>
+              {btns}
+            </Button.Group>,
+            <SDButton
+              key="setRefTimeBtn"
+              successMessage=''
+              icon={<ClockCircleOutlined />}
+              primary
+              onClick={() => setRefTimeVisible(true)}
+            >
+              设置刷新时间
+            </SDButton>,
+            <SDButton
+              key="pollBtn"
+              successMessage=''
+              primary
+              icon={polling ? <LoadingOutlined /> : <ReloadOutlined />}
+              onClick={() => {
+                if (polling) {
+                  setPolling(undefined);
+                  return;
+                }
+                setPolling(2000);
+              }}
+            >
+
+              {polling ? '停止轮询' : '开始轮询'}
+            </SDButton>,
+          ];
+        }}
+
+        search={
+          { optionRender: () => [], defaultCollapsed: false }
+        }
+        rowKey="key"
+        expandable={{
+          expandedRowKeys,
+          onExpand: (expanded, record) => {
+            if (expanded) setExpandedRowKeys([...expandedRowKeys, record.key!]);
+            else setExpandedRowKeys(expandedRowKeys.filter(item => item !== record.key));
+          }
+        }}
+      />
+      {batchStartVisible && (
+        <SDModalForm
+          editType="create"
+          initialValues={{
+            batchId: batchId,
+            headOrgCode: headOrgCode,
+            batchName:batchName,
+          }}
+          title={'批次发起信息配置'}
+          visible={batchStartVisible}
+          onVisibleChange={setBatchStartVisible}
+          tableRef={actionRef}
+          formRef={startBatchRef}
+          footer={<SDButton primary 
+            successMessage='发起批次成功'
+            autoLoading={true}
+            onClick={async () => {
+            const obj = startBatchRef?.current?.getFieldFormatValue?.();
+            const par = {
+              batchId: obj.batchId,
+              headOrgCode: obj.headOrgCode,
+              startdate: dayjs(obj.runDate?.startOrEnd[0]).format('YYYY-MM-DD'),
+              enddate: dayjs(obj.runDate?.startOrEnd[1]).format('YYYY-MM-DD'),
+            }
+            //console.log(par);
+            await saveBatchStartInfo(par).then(() => {
+
+              setResh(resh + 1);
+              setBatchStartVisible(false);
+            });
+          }}>确定</SDButton>}
+        >
+
+          <ProFormText name="batchId" hidden />
+          <SDFormItem {...caledProps} label="批次名称">
+          <ProFormText name="batchName"  readonly width="xl"
+            colProps={{ xs: 24 }}/>
+            </SDFormItem>
+             <SDFormItem {...caledProps} label="法人行">
+          <ProFormSelect
+            name="headOrgCode"
+            readonly={true}
+            request={async () => {
+              return await selHeadOrgCode({});
+            }}
+            width="xl"
+            colProps={{ xs: 24 }}
+          />
+          </SDFormItem>
+          {/* <SDFormText type='date' name="startdate" label="批次执行日期" required />
+              <SDFormText type='date' name="enddate" />  */}
+  <SDFormItem {...caledProps} label="批次执行日期">        
+          <ProFormDateRangePicker
+            name={['runDate', 'startOrEnd']}
+            required
+            dataFormat='YYYY-MM-DD'
+            fieldProps={{ 
+              format: (value: any) => {
+                return value.format('YYYY-MM-DD');
+              } }}
+          />
+</SDFormItem>
+
+        </SDModalForm>
+      )}
+      {refTimeVisible && (
+        <SDModalForm
+          editType="create"
+          formRef={cycformRef}
+          title={'轮询时间设置'}
+          // doSubmit={async (body: { refTime?: number }) => {
+          //   if (body.refTime) {
+          //     setPolling(body.refTime);
+          //   }
+          // }}
+          // footer={<SDButton onClick={() => {
+          //     const refVar: number = cycformRef.current?.getFieldValue('refTime');
+          //     if (refVar) {
+          //       setPolling(refVar);
+          //     }
+          // }}>
+          // </SDButton>}
+          footer={<SDSubmitButton 
+            primary
+            formRef={cycformRef} 
+            editType={"create"}
+            doSubmit={async (body: { refTime?: number }) => {
+              if (body.refTime) {
+                setPolling(body.refTime);
+              }
+              setRefTimeVisible(false);
+            }}
+          >确定</SDSubmitButton>}
+          visible={refTimeVisible}
+          onVisibleChange={setRefTimeVisible}
+          tableRef={actionRef}
+        >
+          {/* <SDLayout bodyStyle={true}> </SDLayout>*/}
+          <SDFormText name="refTime" label="轮询时间(毫秒)" type="number" />
+
+        </SDModalForm>
+      )}
+      {batchLogVisible && (
+        <SDModal
+          title="批次日志查询"
+          size="m"
+          visible={batchLogVisible}
+          footer={null}
+          onCancel={() => setBatchLogVisible(false)}
+        >
+          <SDLayout
+            footer={[
+              <SDButton primary key='save'
+                onClick={() => {
+                  setBatchLogVisible(false);
+                }}> 确定
+              </SDButton>,
+              <SDButton
+                key='click'
+                onClick={() => {
+                  setBatchLogVisible(false);
+                }}>
+                关闭
+              </SDButton>]}
+          >
+            <BatchLog
+              params={{
+                batchDate: batchDate,
+                batchId: batchId,
+                stepName: stepName,
+              }}
+            />
+          </SDLayout>
+        </SDModal>
+      )}
+    </SDPage>
+  );
+};
 export default BatchDispatch;

+ 115 - 114
Procedure/frontend/projectb/src/pages/batchMng/BatchGroup/batchGroup.tsx

@@ -1,114 +1,115 @@
-import React, { useState, useRef } from 'react';
-import type { ProColumns, ActionType } from '@ant-design/pro-components';
-import type { ProFormInstance } from '@ant-design/pro-components';
-
-import type { BatchGroupModel } from '@/services/batchMng/batchGroup';
-import {
-  getDataList,
-  getDetail,
-  deleteRows,
-  save,
-  isNotExist,
-} from '@/services/batchMng/batchGroup';
-import {
-  SDTable,
-  SDModalForm,
-  SDFormText,
-  SDFormDict,
-  validateFun,
-  SDPage,
-  SDSubmitButton,
-} from '@sundata/ui-frame';
-import type { EditType } from '@sundata/ui-frame';
-
-// const { TextArea } = Input;
-
-const BatchGroup: React.FC = () => {
-  /** 表格引用对象,刷新表格使用 */
-  const actionRef = useRef<ActionType>();
-  const formRef = useRef<ProFormInstance>();
-  /** 是否显示详细信息窗口 */
-  const [detailVisible, setDetailVisible] = useState<boolean>(false);
-  /** 当前行对象,查看详情、修改时,作为详细信息表单的查询条件 */
-  const [currentRow, setCurrentRow] = useState<BatchGroupModel>();
-  /** 编辑方式,查看、修改、新增按钮时设置,详细信息表单中使用 */
-  const [editType, setEditType] = useState<EditType>('display');
-
-  const columns: ProColumns<BatchGroupModel, 'treeSelect'>[] = [
-    {
-      title: '任务组代码',
-      dataIndex: 'batchgroupid',
-      sorter: true,
-    },
-    {
-      title: '任务组名称',
-      dataIndex: 'batchgroupname',
-    },
-  ];
-
-  return (
-    <SDPage>
-      <SDTable<BatchGroupModel>
-        title="批次任务组列表"
-        rowKey="batchgroupid"
-        request={getDataList}
-        columns={columns}
-        operations="all"
-        displayColumn="batchgroupid"
-        actionRef={actionRef}
-        handleRemove={deleteRows}
-        setDetailVisible={setDetailVisible}
-        setCurrentRow={setCurrentRow}
-        setEditType={setEditType}
-      />
-      {detailVisible && (
-        <SDModalForm
-          title={'详细信息'}
-          editType={editType}
-          //doSubmit={save}
-          footer={<SDSubmitButton 
-            primary
-            formRef={formRef} 
-            editType={editType}
-            doSubmit={ async (data: BatchGroupModel)=>{
-              await save(data);
-              setDetailVisible(false);
-              actionRef.current?.reload();
-            }}
-          >确定</SDSubmitButton>}
-          visible={detailVisible}
-          onVisibleChange={setDetailVisible}
-          formRef={formRef}
-          tableRef={actionRef}
-          params={currentRow}
-          request={async (body: BatchGroupModel) => await getDetail(body)}
-        >
-         
-            <SDFormText
-              name="batchgroupid"
-              label="任务组代码"
-              readonlyCond="update"
-              bgValidater={(batchgroupid: string) => isNotExist({ batchgroupid: batchgroupid })}
-              required={true}
-              max={60}
-              rules={[{ validator: validateFun.noChinese }]}
-              width='md'
-            />
-            <SDFormText name="batchgroupname" label="任务组名称" required={true} max={100} width='md'/>
-            <SDFormDict
-              name="stepidArr"
-              label="批次步骤"
-              required={true}
-              dictKey="@getSteName"
-              level={1}
-              multiple={true}
-              onlyLeafCheck={true}
-            />
-            <SDFormText name="batchgroupdesc" label="说明" type="textarea" max={500} />
-         
-        </SDModalForm>
-      )}
-    </SDPage>
-  );
-};
-export default BatchGroup;
+import React, { useState, useRef } from 'react';
+import type { ProColumns, ActionType } from '@ant-design/pro-components';
+import type { ProFormInstance } from '@ant-design/pro-components';
+
+import type { BatchGroupModel } from '@/services/batchMng/batchGroup';
+import {
+  getDataList,
+  getDetail,
+  deleteRows,
+  save,
+  isNotExist,
+} from '@/services/batchMng/batchGroup';
+import {
+  SDTable,
+  SDModalForm,
+  SDFormText,
+  SDFormDict,
+  validateFun,
+  SDPage,
+  SDSubmitButton,
+} from '@sundata/ui-frame';
+import type { EditType } from '@sundata/ui-frame';
+
+// const { TextArea } = Input;
+
+const BatchGroup: React.FC = () => {
+  /** 表格引用对象,刷新表格使用 */
+  const actionRef = useRef<ActionType>();
+  const formRef = useRef<ProFormInstance>();
+  /** 是否显示详细信息窗口 */
+  const [detailVisible, setDetailVisible] = useState<boolean>(false);
+  /** 当前行对象,查看详情、修改时,作为详细信息表单的查询条件 */
+  const [currentRow, setCurrentRow] = useState<BatchGroupModel>();
+  /** 编辑方式,查看、修改、新增按钮时设置,详细信息表单中使用 */
+  const [editType, setEditType] = useState<EditType>('display');
+
+  const columns: ProColumns<BatchGroupModel, 'treeSelect'>[] = [
+    {
+      title: '任务组代码',
+      dataIndex: 'batchgroupid',
+      sorter: true,
+    },
+    {
+      title: '任务组名称',
+      dataIndex: 'batchgroupname',
+    },
+  ];
+
+  return (
+    <SDPage>
+      <SDTable<BatchGroupModel>
+        title="批次任务组列表"
+        rowKey="batchgroupid"
+        request={getDataList}
+        columns={columns}
+        operations="all"
+        displayColumn="batchgroupid"
+        actionRef={actionRef}
+        handleRemove={deleteRows}
+        setDetailVisible={setDetailVisible}
+        setCurrentRow={setCurrentRow}
+        setEditType={setEditType}
+      />
+      {detailVisible && (
+        <SDModalForm
+          title={'详细信息'}
+          editType={editType}
+          //doSubmit={save}
+          footer={<SDSubmitButton 
+            primary
+            formRef={formRef} 
+            editType={editType}
+            doSubmit={ async (data: BatchGroupModel)=>{
+              await save(data);
+              setDetailVisible(false);
+              actionRef.current?.reload();
+            }}
+          >确定</SDSubmitButton>}
+          visible={detailVisible}
+          onVisibleChange={setDetailVisible}
+          formRef={formRef}
+          tableRef={actionRef}
+          params={currentRow}
+          request={async (body: BatchGroupModel) => await getDetail(body)}
+        >
+         
+            <SDFormText
+              name="batchgroupid"
+              label="任务组代码"
+              readonlyCond="update"
+              bgValidater={(batchgroupid: string) => isNotExist({ batchgroupid: batchgroupid })}
+              required={true}
+              max={60}
+              rules={[{ validator: validateFun.noChinese }]}
+              width='md'
+            />
+            <SDFormText name="batchgroupname" label="任务组名称" required={true} max={100} width='md'/>
+            <SDFormDict
+              name="stepidArr"
+              label="批次步骤"
+              required={true}
+              dictKey="@getSteName"
+              level={1}
+              multiple={true}
+              cascadeCheck = {true}
+              //onlyLeafCheck={true}
+            />
+            <SDFormText name="batchgroupdesc" label="说明" type="textarea" max={500} />
+         
+        </SDModalForm>
+      )}
+    </SDPage>
+  );
+};
+export default BatchGroup;

+ 391 - 362
Procedure/frontend/projectb/src/pages/idataMng/ExcelMng/excelMng.tsx

@@ -1,362 +1,391 @@
-import React, { useState, useRef, useEffect } from 'react';
-import { EditableFormInstance } from '@ant-design/pro-components';
-import type { ProColumns, ActionType } from '@ant-design/pro-components';
-import type { FormInstance } from '@ant-design/pro-components';
-import { EditType, SDAreaTtile, SDEditableTable, SDForm, SDLayout, SDModal, SDOperate, SDPage, SDSubmitButton } from '@sundata/ui-frame';
-import { SDButton } from '@sundata/ui-frame';
-import { SDFormText, SDTable, SDFormDict } from '@sundata/ui-frame';
-import { baseFun, validateFun } from '@sundata/ui-frame';
-import { CloudUploadOutlined, ExportOutlined, SearchOutlined } from '@ant-design/icons';
-import type { ImpmTypeConfigModel, ImportColunnConfigModel } from '@/services/idataMng/excelMng';
-import { Release } from '@/services/idataMng/excelMng';
-import {
-  getDataList,
-  saveDetail,
-  deleteRows,
-  getDetail,
-  isNotExist,
-  exportExcelModel,
-  getImportColunnConfigList,
-} from '@/services/idataMng/excelMng';
-import { useModel } from '@umijs/max';
-import { Select } from 'antd';
-import { DictTree } from '@sundata/ui-frame/lib/types';
-
-const ExcelMng: React.FC = () => {
-  const { fetchDict } = useModel('dict');
-  const [colunconfigList, setColunconfigList] = useState<readonly ImportColunnConfigModel[]>();
-  /** 是否显示详细信息窗口 */
-  const [detailVisible, setDetailVisible] = useState<boolean>(false);
-  /** 当前行对象,查看详情、修改时,作为详细信息表单的查询条件 */
-  const [currentRow, setCurrentRow] = useState<ImpmTypeConfigModel>();
-  /** 编辑方式,查看、修改、新增按钮时设置,详细信息表单中使用 */
-  const [editType, setEditType] = useState<EditType>('display');
-  const [selectdata, setSelectdata] = useState<DictTree[]>([]);
-  /** 表格引用对象,刷新表格使用 */
-  const actionRef = useRef<ActionType>();
-  //删除
-  const deleteSingleRow = (data: ImpmTypeConfigModel[]) => deleteRows(data[0]);
-  // 可编辑表格的引用
-  const tableRef = useRef<EditableFormInstance>();
-  //查询类型配置列
-  const getImportColunnList = async (data: ImpmTypeConfigModel) => {
-    let flag1 = '';
-    if (editType === 'update' || editType === 'display') {
-      flag1 = '1';
-    }
-    const mtypecolparam: ImportColunnConfigModel = {
-      id: Date.now(),
-      mtype: data.mtype,
-      sundataEditType: editType,
-      flag: flag1,
-    };
-
-    const rst = await getImportColunnConfigList(mtypecolparam);
-    let i = 0;
-    rst.data = rst.data.map((item: ImportColunnConfigModel) => {
-      i += 1;
-      return { ...item, id: i };
-    });
-    return rst;//getImportColunnConfigList(mtypecolparam);
-  };
-
-
-  const columns: ProColumns<ImpmTypeConfigModel, 'text'>[] = [
-    {
-      title: '模板代码', //查询条件
-      dataIndex: 'mtype',
-      tip: '全系统唯一',
-    },
-    {
-      title: '模板名称',
-      dataIndex: 'mtypename',
-    },
-    {
-      title: '状态',
-      dataIndex: 'statusname',
-      search: false,
-    },
-    {
-      title: '操作',
-      dataIndex: 'operate',
-      valueType: 'option',
-      render: (_, record) => [
-        <SDOperate key="prodcfg"
-          successMessage=''
-          icon={<CloudUploadOutlined />}
-          onClick={() => {
-            console.log(record.mtype, record.statusname);
-            if (!record.mtype && '已发布' == record.statusname) {
-              baseFun.warning('未取到模板代码或状态,无法处理');
-              return;
-            } else {
-              baseFun.confirm('确认发布?', async () => {
-                await Release(record);
-                baseFun.info('处理完成');
-                actionRef.current?.reloadAndRest?.();
-              });
-            }
-          }}>  发布</SDOperate>
-        ,
-        <SDOperate
-          successMessage=''
-          key="prodcfg1"
-          icon={<SearchOutlined />}
-          onClick={() => {
-            setEditType('display');
-            setDetailVisible(true);
-            setCurrentRow(record);
-          }} >  查看 </SDOperate>
-
-      ],
-    },
-  ];
-  const impColumns: ProColumns<ImportColunnConfigModel>[] = [
-    {
-      title: 'id',
-      dataIndex: 'id',
-      hideInTable: true,
-    },
-    {
-      title: '类型',
-      dataIndex: 'mtype',
-      hideInTable: true,
-    },
-    {
-      title: '字段位置',
-      dataIndex: 'cellname',
-      width: 130,
-      formItemProps: () => {
-        return {
-          rules: [{ required: true }],
-        };
-      },
-    },
-    {
-      title: '中间表字段英文名',
-      dataIndex: 'fieldname',
-      search: false,
-      width: 130,
-      formItemProps: () => {
-        return {
-          rules: [
-            { required: true },
-            { max: 20, message: '最大长度为20' },
-            { validator: validateFun.noChinese },
-          ],
-        };
-      },
-    },
-    {
-      title: '中间表字段中文名',
-      dataIndex: 'fieldcnname',
-      search: false,
-      width: 130,
-      formItemProps: () => {
-        return {
-          rules: [{ required: true }],
-        };
-      },
-    },
-    {
-      title: '中间表字段类型及长度',
-      align: 'center',
-      dataIndex: 'fieldtype',
-      search: false,
-      width: 160,
-      formItemProps: () => {
-        return {
-          rules: [{ required: true }],
-        };
-      },
-    },
-    {
-      title: '字典代码',
-      dataIndex: 'fileddict',
-      search: false,
-      valueType: 'select',
-      width: 130,
-      request: () => fetchDict({ dictKey: '@getBranchDict' }),
-    },
-    {
-      title: '业务主键',
-      dataIndex: 'bussipk',
-      search: false,
-      valueType: 'select',
-      width: 130,
-      request: () => fetchDict({ dictKey: 'YESORNO' }),
-    },
-    {
-      title: '种类代码',
-      dataIndex: 'classcode',
-      search: false,
-      width: 130,
-    },
-    {
-      title: '校验类型',
-      dataIndex: 'checkTypes',
-      search: false,
-      width: 200,
-      renderFormItem: (_, record) => {
-
-        return (
-          <Select
-            mode="multiple"
-            allowClear
-            size={'middle'}
-            // defaultValue={['a10', 'c12']}
-            style={{ width: '100%' }}
-            options={selectdata}
-          />
-        )
-      },
-      valueType: 'select',
-      request: () => fetchDict({ dictKey: 'excelCheckType' }),
-    },
-    {
-      title: '中间表字段种类',
-      dataIndex: 'fieldclass',
-      width: 130,
-      valueType: 'select',
-      search: false,
-      request: () => fetchDict({ dictKey: 'FIELDCLASS' }),
-    }
-  ];
-
-  const handleSave = async (data: ImpmTypeConfigModel) => {
-    const editingRows = tableRef.current?.getRowsData?.();
-    if (editingRows && editingRows.length > 0) {
-      baseFun.warning('参数列表中有正在编辑的参数,请确认或取消修改后再保存');
-      return;
-    }
-    const typeconfigmode = { ...data };
-    delete typeconfigmode.colunconfigList;
-    console.log(typeconfigmode, colunconfigList);
-    let config = colunconfigList
-    config?.forEach((item) => {
-      let checkType = '';
-      if (item.checkTypes) {
-        for (let i = 0; i < item.checkTypes.length; i++){
-          checkType = checkType + item.checkTypes[i] + ',';
-        }
-        checkType = checkType.substring(0, checkType.length - 1);
-      }
-      item.checkType = checkType
-    })
-    await saveDetail({
-      typeconfigmode: typeconfigmode,
-      colunconfigmodel: colunconfigList,
-    });
-    baseFun.info('处理完成');
-
-
-
-  };
-  const formRef = useRef<FormInstance>();
-  const gettree = async () => {
-    const tree = await fetchDict({ dictKey: 'excelCheckType' })
-    setSelectdata(tree);
-  }
-  useEffect(() => {
-    gettree();
-    if (currentRow) {
-      getImportColunnList(currentRow).then((data) => {
-        data.data.forEach((item) => {
-          if (item.checkType) {
-            // const str = item.checkType.substring(0, item.checkType.length - 1);
-            item.checkTypes = item.checkType?.split(',')
-          }else{
-            item.checkTypes=[]
-          }
-        })
-        setColunconfigList(data?.data);
-      });
-    }
-  }, [currentRow]);
-  return (
-    <SDPage>
-      <SDTable<ImpmTypeConfigModel>
-        title="查询表格"
-        rowKey="mtype"
-        request={getDataList}
-        columns={columns}
-        singleSelect={true}
-        operations="all"
-        displayColumn="mtype"
-        actionRef={actionRef}
-        handleRemove={deleteSingleRow}
-        setDetailVisible={setDetailVisible}
-        setCurrentRow={setCurrentRow}
-        setEditType={setEditType}
-        toolBarRender={(_, { selectedRows }) => [
-          <SDButton
-            key="export"
-            successMessage=''
-            icon={<ExportOutlined />}
-            onClick={() => {
-              if (selectedRows === undefined || selectedRows.length < 1) {
-                baseFun.warning('请先选择要倒出的模板');
-                return;
-              }
-              exportExcelModel(selectedRows[0].mtype || '');
-              //baseFun.info('处理完成');
-            }}
-          >
-            导出模板
-          </SDButton>,
-        ]}
-      />
-      {detailVisible && (
-        <SDModal
-          title={'详细信息'}
-          visible={detailVisible}
-          onCancel={() => {
-            setDetailVisible(false);
-            actionRef.current?.reload();
-          }}
-          footer={[<SDSubmitButton successMessage='' autoLoading={true} editType={editType} formRef={formRef} doSubmit={handleSave} >保存</SDSubmitButton>]}
-        >
-          <SDForm
-            params={currentRow}
-            request={getDetail}
-            formRef={formRef}
-            editType={editType}>
-            <SDAreaTtile title="基本信息" />
-            <SDFormText
-              name="mtype"
-              label="模板代码"
-              max={30}
-              required
-              readonlyCond="update"
-              rules={[{ validator: validateFun.noChinese }]}
-              bgValidater={(mtype: string) => isNotExist({ mtype: mtype })} />
-            <SDFormText name="mtypename" label="模板名称" required width='md' />
-            <SDFormText name="tmptable" label="临时表名" required width='md' />
-            <SDFormText name="formaltable" label="中间表名" required width='md' />
-            <SDFormDict
-              name="orgcodeList"
-              label="适用机构"
-              dictKey="org"
-              multiple={true}
-              onlyLeafCheck={true} />
-            <SDFormDict name="ischeckData" label="是否直接提交" dictKey="YESORNO" required />
-            <SDFormText name="flowUrl" label="流程url" max={1000} />
-            <SDFormText name="remark" label="说明" type="textarea" max={1000} />
-          </SDForm>
-          <SDLayout title='模板列定义'>
-            <SDEditableTable
-              rowKey="id"
-              columns={impColumns}
-              value={colunconfigList || []}
-              formRef={tableRef}
-              onChange={(value: readonly ImportColunnConfigModel[]) => {
-                setColunconfigList(value);
-              }}
-              editable={editType != 'display'} />
-          </SDLayout>
-        </SDModal>
-      )}
-    </SDPage>
-  );
-};
-export default ExcelMng;
+import React, { useState, useRef, useEffect } from 'react';
+import { EditableFormInstance } from '@ant-design/pro-components';
+import type { ProColumns, ActionType } from '@ant-design/pro-components';
+import type { FormInstance } from '@ant-design/pro-components';
+import { EditType, SDAreaTtile, SDEditableTable, SDForm, SDLayout, SDModal, SDOperate, SDPage, SDSubmitButton } from '@sundata/ui-frame';
+import { SDButton } from '@sundata/ui-frame';
+import { SDFormText, SDTable, SDFormDict } from '@sundata/ui-frame';
+import { baseFun, validateFun } from '@sundata/ui-frame';
+import { CloudUploadOutlined, ExportOutlined, SearchOutlined } from '@ant-design/icons';
+import type { ImpmTypeConfigModel, ImportColunnConfigModel } from '../../../services/idataMng/excelMng';
+import { Release } from '../../../services/idataMng/excelMng';
+import {
+  getDataList,
+  saveDetail,
+  deleteRows,
+  getDetail,
+  isNotExist,
+  exportExcelModel,
+  getImportColunnConfigList,
+} from '@/services/idataMng/excelMng';
+import { useModel } from '@umijs/max';
+import { Select } from 'antd';
+import { DictTree } from '@sundata/ui-frame/lib/types';
+import ImportSqlConfig from './importSqlConfig';
+
+const ExcelMng: React.FC = () => {
+  const { fetchDict } = useModel('dict');
+  const [colunconfigList, setColunconfigList] = useState<readonly ImportColunnConfigModel[]>();
+  /** 是否显示详细信息窗口 */
+  const [detailVisible, setDetailVisible] = useState<boolean>(false);
+  /** 当前行对象,查看详情、修改时,作为详细信息表单的查询条件 */
+  const [currentRow, setCurrentRow] = useState<ImpmTypeConfigModel>();
+  /** 编辑方式,查看、修改、新增按钮时设置,详细信息表单中使用 */
+  const [editType, setEditType] = useState<EditType>('display');
+  const [selectdata, setSelectdata] = useState<any>([]);
+  /** 表格引用对象,刷新表格使用 */
+  const actionRef = useRef<ActionType>();
+  //删除
+  const deleteSingleRow = (data: ImpmTypeConfigModel[]) => deleteRows(data[0]);
+  // 可编辑表格的引用
+  const tableRef = useRef<EditableFormInstance>();
+  const mtypeRef = useRef<string>();
+  const [sqlDetailVisible,setSqlDetailVisible] = useState<boolean>(false);
+  //查询类型配置列
+  const getImportColunnList = async (data: ImpmTypeConfigModel) => {
+    let flag1 = '';
+    if (editType === 'update' || editType === 'display') {
+      flag1 = '1';
+    }
+    const mtypecolparam: ImportColunnConfigModel = {
+      id: Date.now(),
+      mtype: data.mtype,
+      sundataEditType: editType,
+      flag: flag1,
+    };
+
+    const rst = await getImportColunnConfigList(mtypecolparam);
+    let i = 0;
+    rst.data = rst.data.map((item: ImportColunnConfigModel) => {
+      i += 1;
+      return { ...item, id: i };
+    });
+    return rst;//getImportColunnConfigList(mtypecolparam);
+  };
+
+
+  const columns: ProColumns<ImpmTypeConfigModel, 'text'>[] = [
+    {
+      title: '模板代码', //查询条件
+      dataIndex: 'mtype',
+      tip: '全系统唯一',
+    },
+    {
+      title: '模板名称',
+      dataIndex: 'mtypename',
+    },
+    {
+      title: '状态',
+      dataIndex: 'statusname',
+      search: false,
+    },
+    {
+      title: '操作',
+      dataIndex: 'operate',
+      valueType: 'option',
+      render: (_, record) => [
+        <SDOperate key="prodcfg"
+          successMessage=''
+          icon={<CloudUploadOutlined />}
+          onClick={() => {
+            console.log(record.mtype, record.statusname);
+            if (!record.mtype && '已发布' == record.statusname) {
+              baseFun.warning('未取到模板代码或状态,无法处理');
+              return;
+            } else {
+              baseFun.confirm('确认发布?', async () => {
+                await Release(record);
+                baseFun.info('处理完成');
+                actionRef.current?.reloadAndRest?.();
+              });
+            }
+          }}>  发布</SDOperate>
+        ,
+        <SDOperate
+          successMessage=''
+          key="prodcfg1"
+          icon={<SearchOutlined />}
+          onClick={() => {
+            setEditType('display');
+            setDetailVisible(true);
+            setCurrentRow(record);
+          }} >  查看 </SDOperate>
+
+      ],
+    },
+  ];
+  const impColumns: ProColumns<ImportColunnConfigModel>[] = [
+    {
+      title: 'id',
+      dataIndex: 'id',
+      hideInTable: true,
+    },
+    {
+      title: '类型',
+      dataIndex: 'mtype',
+      hideInTable: true,
+    },
+    {
+      title: '字段位置',
+      dataIndex: 'cellname',
+      width: 130,
+      formItemProps: () => {
+        return {
+          rules: [{ required: true }],
+        };
+      },
+    },
+    {
+      title: '中间表字段英文名',
+      dataIndex: 'fieldname',
+      search: false,
+      width: 130,
+      formItemProps: () => {
+        return {
+          rules: [
+            { required: true },
+            { max: 20, message: '最大长度为20' },
+            { validator: validateFun.noChinese },
+          ],
+        };
+      },
+    },
+    {
+      title: '中间表字段中文名',
+      dataIndex: 'fieldcnname',
+      search: false,
+      width: 130,
+      formItemProps: () => {
+        return {
+          rules: [{ required: true }],
+        };
+      },
+    },
+    {
+      title: '中间表字段类型及长度',
+      align: 'center',
+      dataIndex: 'fieldtype',
+      search: false,
+      width: 160,
+      formItemProps: () => {
+        return {
+          rules: [{ required: true }],
+        };
+      },
+    },
+    {
+      title: '字典代码',
+      dataIndex: 'fileddict',
+      search: false,
+      valueType: 'select',
+      width: 130,
+      request: () => fetchDict({ dictKey: '@getBranchDict' }),
+    },
+    {
+      title: '业务主键',
+      dataIndex: 'bussipk',
+      search: false,
+      valueType: 'select',
+      width: 130,
+      request: () => fetchDict({ dictKey: 'YESORNO' }),
+    },
+    {
+      title: '种类代码',
+      dataIndex: 'classcode',
+      search: false,
+      width: 130,
+    },
+    {
+      title: '校验类型',
+      dataIndex: 'checkTypes',
+      search: false,
+      width: 200,
+      renderFormItem: (_, record) => {
+
+        return (
+          <Select
+            mode="multiple"
+            allowClear
+            size={'middle'}
+            // defaultValue={['a10', 'c12']}
+            style={{ width: '100%' }}
+            options={selectdata}
+          />
+        )
+      },
+      valueType: 'select',
+      request: () => fetchDict({ dictKey: 'excelCheckType' }),
+    },
+    {
+      title: '中间表字段种类',
+      dataIndex: 'fieldclass',
+      width: 130,
+      valueType: 'select',
+      search: false,
+      request: () => fetchDict({ dictKey: 'FIELDCLASS' }),
+    }
+  ];
+
+  const handleSave = async (data: ImpmTypeConfigModel) => {
+    const editingRows = tableRef.current?.getRowsData?.();
+    if (editingRows && editingRows.length > 0) {
+      baseFun.warning('参数列表中有正在编辑的参数,请确认或取消修改后再保存');
+      return;
+    }
+    const typeconfigmode = { ...data };
+    delete typeconfigmode.colunconfigList;
+    console.log(typeconfigmode, colunconfigList);
+    let config = colunconfigList
+    config?.forEach((item) => {
+      let checkType = '';
+      if (item.checkTypes) {
+        for (let i = 0; i < item.checkTypes.length; i++){
+          checkType = checkType + item.checkTypes[i] + ',';
+        }
+        checkType = checkType.substring(0, checkType.length - 1);
+      }
+      item.checkType = checkType
+    })
+    await saveDetail({
+      typeconfigmode: typeconfigmode,
+      colunconfigmodel: colunconfigList,
+    });
+    setEditType("update");
+    mtypeRef.current = data.mtype;
+    baseFun.info('处理完成');
+
+
+
+  };
+  const formRef = useRef<FormInstance>();
+  const gettree = async () => {
+    const tree = await fetchDict({ dictKey: 'excelCheckType' })
+    setSelectdata(tree);
+  }
+  useEffect(() => {
+    gettree();
+    if (currentRow) {
+      getImportColunnList(currentRow).then((data) => {
+        data.data.forEach((item) => {
+          if (item.checkType) {
+            // const str = item.checkType.substring(0, item.checkType.length - 1);
+            item.checkTypes = item.checkType?.split(',')
+          }else{
+            item.checkTypes=[]
+          }
+        })
+        setColunconfigList(data?.data);
+      });
+    }
+  }, [currentRow]);
+
+
+  const getDetailFooterButton = () => {
+    const buttonArray: React.ReactNode[] = [
+      <SDSubmitButton successMessage='' autoLoading={true} editType={editType} formRef={formRef} doSubmit={handleSave} >保存</SDSubmitButton>
+    ];
+    if(editType != 'create'){
+      buttonArray.push(<SDButton successMessage='' primary tooltip='向正式表转换的逻辑,通过此功能配置' onClick={()=>{setSqlDetailVisible(true);}}>转换逻辑</SDButton>);
+    }
+    return buttonArray;
+  }
+
+  
+  return (
+    <SDPage>
+      <SDTable<ImpmTypeConfigModel>
+        title="查询表格"
+        rowKey="mtype"
+        request={getDataList}
+        columns={columns}
+        singleSelect={true}
+        operations="all"
+        displayColumn="mtype"
+        actionRef={actionRef}
+        handleRemove={deleteSingleRow}
+        setDetailVisible={setDetailVisible}
+        setCurrentRow={setCurrentRow}
+        setEditType={setEditType}
+        toolBarRender={(_, { selectedRows }) => [
+          <SDButton
+            key="export"
+            successMessage=''
+            icon={<ExportOutlined />}
+            onClick={() => {
+              if (selectedRows === undefined || selectedRows.length < 1) {
+                baseFun.warning('请先选择要倒出的模板');
+                return;
+              }
+              exportExcelModel(selectedRows[0].mtype || '');
+              //baseFun.info('处理完成');
+            }}
+          >
+            导出模板
+          </SDButton>,
+        ]}
+      />
+      {detailVisible && (
+        <SDModal
+          title={'详细信息'}
+          visible={detailVisible}
+          onCancel={() => {
+            setDetailVisible(false);
+            actionRef.current?.reload();
+          }}
+          footer={getDetailFooterButton()}
+        >
+          <SDForm
+            params={currentRow}
+            request={getDetail}
+            formRef={formRef}
+            editType={editType}>
+            <SDAreaTtile title="基本信息" />
+            <SDFormText
+              name="mtype"
+              label="模板代码"
+              max={30}
+              required
+              readonlyCond="update"
+              rules={[{ validator: validateFun.noChinese }]}
+              bgValidater={(mtype: string) => isNotExist({ mtype: mtype })} />
+            <SDFormText name="mtypename" label="模板名称" required width='md' />
+            <SDFormText name="tmptable" label="临时表名" required width='md' />
+            <SDFormText name="formaltable" label="中间表名" required width='md' />
+            <SDFormDict
+              name="orgcodeList"
+              label="适用机构"
+              dictKey="org"
+              multiple={true}
+              onlyLeafCheck={true} />
+            <SDFormDict name="ischeckData" label="是否直接提交" dictKey="YESORNO" required />
+            <SDFormText name="flowUrl" label="流程url" max={1000} />
+            <SDFormText name="remark" label="说明" type="textarea" max={1000} />
+          </SDForm>
+          <SDLayout title='模板列定义'>
+            <SDEditableTable
+              rowKey="id"
+              columns={impColumns}
+              value={colunconfigList || []}
+              formRef={tableRef}
+              onChange={(value: readonly ImportColunnConfigModel[]) => {
+                setColunconfigList(value);
+              }}
+              editable={editType != 'display'} />
+          </SDLayout>
+        </SDModal>
+      )}
+
+      {detailVisible && (
+          <ImportSqlConfig
+            onCancelfun={() => {
+              setSqlDetailVisible(false);
+            }}
+            visible={sqlDetailVisible}
+            mType={mtypeRef.current || currentRow?.mtype}
+            editType={editType}
+          />
+      )}
+    </SDPage>
+  );
+};
+export default ExcelMng;

+ 113 - 0
Procedure/frontend/projectb/src/pages/idataMng/ExcelMng/importSqlConfig.tsx

@@ -0,0 +1,113 @@
+import type { EditableFormInstance, ProColumns } from '@ant-design/pro-components';
+import { baseFun, EditType, SDButton, SDEditableTable, SDLayout, SDModal } from '@sundata/ui-frame';
+import { useEffect, useRef, useState } from 'react';
+import { getImpSqlConfigList, ImpSqlConfigModel, saveImpSqlConfigList } from '../../../services/idataMng/excelMng';
+  
+  export type ImportSqlConfigProp = {
+    editType?: EditType;
+    mType?: string;//模板代码
+    visible: boolean;
+    onCancelfun?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
+  };
+  
+  const ImportSqlConfig: React.FC<ImportSqlConfigProp> = (props) => {
+    const sqlTableRef = useRef<EditableFormInstance>();
+    const [sqlConfigList, setSqlConfigList] = useState<readonly ImpSqlConfigModel[]>();
+    const [max,setMax] = useState<number>(2000);
+
+    useEffect(() => {
+        getImpSqlConfigList({mtype: props.mType}).then((data) => {
+        setSqlConfigList(data?.data);
+        });
+    }, []);
+
+    const saveSqlConfig = async () => {
+        const editingRows = sqlTableRef.current?.getRowsData?.();
+        if (editingRows && editingRows.length > 0) {
+            baseFun.warning('列表中有正在编辑的参数,请确认或取消修改后再保存');
+            return;
+        }
+        // if(sqlConfigList?.length==0){
+        //     baseFun.warning('列表中没有数据,请新增后再保存');
+        //     return;
+        // }
+        sqlConfigList?.forEach((data: ImpSqlConfigModel)=>{
+            data.mtype = props.mType;
+        })
+        await saveImpSqlConfigList(sqlConfigList || []);
+        baseFun.info('处理完成');
+      };
+    
+      const sqlColumns: ProColumns<ImpSqlConfigModel>[] = [
+        {
+          title: '处理类型',
+          dataIndex: 'methodtype',
+          width: '15%',
+          valueType:'select',
+          valueEnum: {
+            "SQL": {
+              text: 'SQL'
+            },
+            "JAVA": {
+              text: 'JAVA'
+            },
+          },
+          formItemProps: () => {
+            return {
+              rules: [{ required: true }],
+            };
+          },
+          fieldProps: () => {
+            return {
+                onChange: (methodtype: string) => {
+                    if(methodtype=="JAVA"){
+                        setMax(30);
+                    }else{
+                        setMax(2000);
+                    }
+                }
+            }
+          }
+        },
+        {
+          title: '逻辑体',
+          dataIndex: 'lbody',
+          valueType: 'textarea',
+          tooltip:'处理类型为SQL时,配置sql语句;处理类型为JAVA时,配置java接口方法所在类配置bean的name',
+          width: '65%',
+          ellipsis:true,
+          formItemProps: () => {
+            return {
+              rules: [
+                { required: true, message: '此项为必填项' },
+                { max: max, message: `最多输入 [${max}] 个字符` },
+              ],
+            };
+          },
+        },
+      ]
+  
+    return (
+        <SDModal
+            title={'转换逻辑'}
+            visible={props.visible}
+            onCancel={props.onCancelfun}
+            footer={props.editType != 'display'? <SDButton successMessage='' autoLoading={true} onClick={saveSqlConfig} >保存</SDButton> : undefined}
+        >
+            <SDLayout>
+            <SDEditableTable
+                columns={sqlColumns}
+                value={sqlConfigList || []}
+                formRef={sqlTableRef}
+                onChange={(value: readonly ImpSqlConfigModel[]) => {
+                    setSqlConfigList(value);
+                }}
+                dragable
+                editable={props.editType != 'display'} />
+            </SDLayout>
+        </SDModal>
+    );
+  };
+  
+  export default ImportSqlConfig;
+  

+ 119 - 119
Procedure/frontend/projectb/src/pages/pubMng/Holiday/holiday.tsx

@@ -1,120 +1,120 @@
-import { calendar, dateinit, insert, isExist, upFlag } from '@/services/pubMng/holiday';
-import { SDButton, SDLayout, SDPage, baseFun } from '@sundata/ui-frame';
-import { Alert, Calendar, message } from 'antd';
-import dayjs from 'dayjs';
-import { SetStateAction, useEffect, useState } from 'react';
-const Holiday: React.FC = () => {
-
-    const [detailVisible, setDetailVisible] = useState<boolean>(true);
-    const [begindate, setBegindate] = useState<dayjs.Dayjs>(dayjs('1970-01-01'));
-    const [enddate, setEnddate] = useState<dayjs.Dayjs>(dayjs('2099-01-01'));
-    const [value, setValue] = useState<dayjs.Dayjs>(dayjs());
-    const [holidys, setHolidys] = useState<string[]>();
-    const [workdate, setWorkdate] = useState<dayjs.Dayjs>();
-    const [num, setNum] = useState<Date>();
-    useEffect(() => {
-        dateinit().then((data) => {
-            setBegindate(dayjs(eval(`data.minyear`)));
-            setEnddate(dayjs(eval(`data.maxyear`)+'-12-31'));
-            setHolidys(eval(`data.holiday`));
-            if (!value) {
-                setValue(dayjs(eval(`data.workdate`)));
-            }
-            setWorkdate(dayjs(eval(`data.workdate`)));
-        }
-        )
-    }, [num]);
-    const addNew = async () => {
-        const beginyear = value.format('YYYY');
-        const flag = isExist(beginyear);
-        baseFun.confirm(await flag === true ? beginyear + "年的数据已存在,确认初始化吗?" : "确认初始化" + beginyear + "年的数据吗?", async () => {
-            await insert(beginyear).then(() => { setNum(new Date); });
-
-        })
-    }
-    const upVocation = async (flag: string) => {
-        if (value) {
-            const seldays = "'" + value.format('YYYY-MM-DD') + "'";
-            baseFun.confirm('确认进行修改吗?', async () => {
-                await upFlag(flag, seldays).then((data) => {
-                    if (data.count == 0) {
-                        message.destroy();
-                        baseFun.warning("请先点击【初始化】按钮初始化数据!");
-                    } else {
-                        setNum(new Date);
-                    }
-                });
-            });
-        }
-    }
-    const fullCellRender = (date: dayjs.Dayjs, info: any) => {
-        const ob = calendar(date.toDate());
-        if (info.type === 'date') {
-            setDetailVisible(true);
-            let style;
-
-            if (holidys && holidys?.indexOf(date.format('YYYY-MM-DD')) > -1) {
-                style = { color: 'red', fontSize: '18px' }
-            }
-            else {
-                style = { fontSize: '18px' }
-            }
-            if (date.format('YYYY-MM-DD') === workdate?.format('YYYY-MM-DD')) {
-                style = { ...style, backgroundColor: 'orange' }
-            }
-            return (
-                <div className="ant-picker-cell-inner ant-picker-calendar-date" style={{ height: '8vh' }}>
-                    <div className="ant-picker-calendar-date-value" style={style}>
-                        {date.format('DD')}
-                    </div>
-                    <div className="ant-picker-calendar-date-content" style={{ ...style, fontSize: '13px', backgroundColor: '', textAlign: 'center', paddingTop: '0.5vh' }}>
-                        {ob.solarTerm?ob.solarTerm: ob.lunarDayCn === '初一' ? ob.lunarMonthCn : ob.lunarDayCn}
-                    </div>
-                </div>
-            )
-        } else {
-            setDetailVisible(false);
-            return (
-                <div className="ant-picker-cell-inner ant-picker-calendar-date" style={{ height: '12vh' }}>
-                    <div className="ant-picker-calendar-date-value" style={{ textAlign: 'center', fontSize: '20px', paddingTop: '3vh' }}>
-                        {date.format('M')}月
-                    </div>
-                    <div className="ant-picker-calendar-date-content" >
-                    </div>
-                </div>
-            )
-        }
-    }
-
-    return (
-        <SDPage>
-            <SDLayout>
-                <div style={{ margin: 'auto', width: '60%' }}>
-                    {detailVisible && (<>
-                    <SDButton autoLoading={true} key="propertyinfo" onClick={() => { return upVocation('0') }}>设为假日</SDButton>
-                    <SDButton autoLoading={true} key="propertyinfo2" onClick={() => { return upVocation('1') }}>设为工作日</SDButton>
-                    <SDButton autoLoading={true} key="propertyinfo3" onClick={addNew}>初始化</SDButton>
-                    <Alert message={`选择的日期为${value?.format('YYYY-MM-DD')}`} style={{textAlign: 'center',marginTop:'1vh'}}/>
-                    </>
-                    )}
-                   
-                    <Calendar
-                        validRange={[begindate, enddate]}
-                        onPanelChange={(newValue: SetStateAction<dayjs.Dayjs>) => {
-                            setValue(newValue);
-                        }}
-                        className="attendanceCal"
-                        onSelect={(date: SetStateAction<dayjs.Dayjs>) => {
-                            // setSelect(date);
-                            setValue(date);
-                        }}
-                        fullCellRender={fullCellRender}
-                        value={value}
-                        defaultValue={value}
-                    />
-                </div>
-            </SDLayout>
-        </SDPage>
-    );
-}
+import { calendarFun, dateinit, insert, isExist, upFlag } from '@/services/pubMng/holiday';
+import { SDButton, SDLayout, SDPage, baseFun } from '@sundata/ui-frame';
+import { Alert, Calendar, message } from 'antd';
+import dayjs from 'dayjs';
+import { SetStateAction, useEffect, useState } from 'react';
+const Holiday: React.FC = () => {
+
+    const [detailVisible, setDetailVisible] = useState<boolean>(true);
+    const [begindate, setBegindate] = useState<any>(dayjs('1970-01-01'));
+    const [enddate, setEnddate] = useState<any>(dayjs('2099-01-01'));
+    const [value, setValue] = useState<any>(dayjs());
+    const [holidys, setHolidys] = useState<string[]>();
+    const [workdate, setWorkdate] = useState<any>();
+    const [num, setNum] = useState<Date>();
+    useEffect(() => {
+        dateinit().then((data) => {
+            setBegindate(dayjs(eval(`data.minyear`)));
+            setEnddate(dayjs(eval(`data.maxyear`)+'-12-31'));
+            setHolidys(eval(`data.holiday`));
+            if (!value) {
+                setValue(dayjs(eval(`data.workdate`)));
+            }
+            setWorkdate(dayjs(eval(`data.workdate`)));
+        }
+        )
+    }, [num]);
+    const addNew = async () => {
+        const beginyear = value.format('YYYY');
+        const flag = isExist(beginyear);
+        baseFun.confirm(await flag === true ? beginyear + "年的数据已存在,确认初始化吗?" : "确认初始化" + beginyear + "年的数据吗?", async () => {
+            await insert(beginyear).then(() => { setNum(new Date); });
+
+        })
+    }
+    const upVocation = async (flag: string) => {
+        if (value) {
+            const seldays = "'" + value.format('YYYY-MM-DD') + "'";
+            baseFun.confirm('确认进行修改吗?', async () => {
+                await upFlag(flag, seldays).then((data) => {
+                    if (data.count == 0) {
+                        message.destroy();
+                        baseFun.warning("请先点击【初始化】按钮初始化数据!");
+                    } else {
+                        setNum(new Date);
+                    }
+                });
+            });
+        }
+    }
+    const fullCellRender = (date: dayjs.Dayjs, info: any) => {
+        const ob = calendarFun(date.toDate());
+        if (info.type === 'date') {
+            setDetailVisible(true);
+            let style;
+
+            if (holidys && holidys?.indexOf(date.format('YYYY-MM-DD')) > -1) {
+                style = { color: 'red', fontSize: '18px' }
+            }
+            else {
+                style = { fontSize: '18px' }
+            }
+            if (date.format('YYYY-MM-DD') === workdate?.format('YYYY-MM-DD')) {
+                style = { ...style, backgroundColor: 'orange' }
+            }
+            return (
+                <div className="ant-picker-cell-inner ant-picker-calendar-date" style={{ height: '8vh' }}>
+                    <div className="ant-picker-calendar-date-value" style={style}>
+                        {date.format('DD')}
+                    </div>
+                    <div className="ant-picker-calendar-date-content" style={{ ...style, fontSize: '13px', backgroundColor: '', textAlign: 'center', paddingTop: '0.5vh' }}>
+                        {ob.solarTerm?ob.solarTerm: ob.lunarDayCn === '初一' ? ob.lunarMonthCn : ob.lunarDayCn}
+                    </div>
+                </div>
+            )
+        } else {
+            setDetailVisible(false);
+            return (
+                <div className="ant-picker-cell-inner ant-picker-calendar-date" style={{ height: '12vh' }}>
+                    <div className="ant-picker-calendar-date-value" style={{ textAlign: 'center', fontSize: '20px', paddingTop: '3vh' }}>
+                        {date.format('M')}月
+                    </div>
+                    <div className="ant-picker-calendar-date-content" >
+                    </div>
+                </div>
+            )
+        }
+    }
+
+    return (
+        <SDPage>
+            <SDLayout>
+                <div style={{ margin: 'auto', width: '60%' }}>
+                    {detailVisible && (<>
+                    <SDButton autoLoading={true} key="propertyinfo" onClick={() => { return upVocation('0') }}>设为假日</SDButton>
+                    <SDButton autoLoading={true} key="propertyinfo2" onClick={() => { return upVocation('1') }}>设为工作日</SDButton>
+                    <SDButton autoLoading={true} key="propertyinfo3" onClick={addNew}>初始化</SDButton>
+                    <Alert message={`选择的日期为${value?.format('YYYY-MM-DD')}`} style={{textAlign: 'center',marginTop:'1vh'}}/>
+                    </>
+                    )}
+                   
+                    <Calendar
+                        validRange={[begindate, enddate]}
+                        onPanelChange={(newValue: SetStateAction<dayjs.Dayjs>) => {
+                            setValue(newValue);
+                        }}
+                        className="attendanceCal"
+                        onSelect={(date: SetStateAction<dayjs.Dayjs>) => {
+                            // setSelect(date);
+                            setValue(date);
+                        }}
+                        fullCellRender={fullCellRender}
+                        value={value}
+                        defaultValue={value}
+                    />
+                </div>
+            </SDLayout>
+        </SDPage>
+    );
+}
 export default Holiday;

+ 180 - 180
Procedure/frontend/projectb/src/pages/pubMng/SqlEditMng/defOperate.tsx

@@ -1,180 +1,180 @@
-import React, { useEffect, useRef, useState, } from 'react';
-import type { EditableFormInstance, ProColumns, } from '@ant-design/pro-components';
-import {
-  baseFun,
-  SDAreaTtile,
-  SDButton,
-  SDEditableTable,
-  SDLayout,
-  SDPage,
-} from '@sundata/ui-frame';
-import type { SysSqlEditDefOperateModel } from './../../../services/pubMng/defOperate';
-import { vailOperName } from './../../../services/pubMng/defOperate';
-import { saveOperateDefineList } from './../../../services/pubMng/defOperate';
-import { getDataList } from './../../../services/pubMng/defOperate';
-import { useModel } from '@umijs/max';
-
-
-const DefOperate: React.FC = () => {
-
-  /** 字段数据 */
-  const [fieldDataSource, setFieldDataSource] = useState<readonly SysSqlEditDefOperateModel[]>();
-  // 可编辑表格的引用
-  const tableRef = useRef<EditableFormInstance>();
-  const { fetchDict } = useModel('dict');
-  
-  /**关系维护 */
-  const getListFun = async () => {
-    const resu = await getDataList();
-    setFieldDataSource(resu);
-  }
-  useEffect(() => {
-    getListFun();
-  }, []);
-
-  const saveinfo = async () => {
-
-     // 检查表格编辑状态
-     const editingRows = tableRef.current?.getRowsData?.();
-     if (editingRows && editingRows.length > 0) {
-       baseFun.warning('参数列表中有正在编辑的参数,请确认或取消修改后再保存');
-       return;
-     }
-    if (!fieldDataSource) {
-      return;
-    }
-    for (let i = 0; i < fieldDataSource.length; i++) {
-      if (fieldDataSource[i].operusemode == 'attribute' && fieldDataSource[i].datatype == "") {
-        baseFun.warning("操作符" + fieldDataSource[i].opercode + "使用方式为属性时数据类型不能为空!");
-        return;
-      }
-      for (let j = 0; j < fieldDataSource.length; j++) {
-        if (fieldDataSource[i].opercode == fieldDataSource[j].opercode && i != j) {
-          baseFun.warning("操作符" + fieldDataSource[i].opercode + "不唯一");
-          return;
-        }
-        if (fieldDataSource[i].opername == fieldDataSource[j].opername && i != j) {
-          baseFun.warning("操作符名称 " + fieldDataSource[i].opername + " 不唯一");
-          return;
-        }
-      }
-    }
-    //保存
-    await saveOperateDefineList([...(fieldDataSource || [])]);
-    baseFun.info('处理完成');
-  }
-
-
-  const filedColumns: ProColumns<SysSqlEditDefOperateModel>[] = [
-    {
-      title: '使用方式',
-      dataIndex: 'operusemode',
-      valueType: 'select',
-      search: false,
-      request: () => fetchDict({ dictKey: 'operusemode' }),
-      formItemProps: () => {
-        return {
-          rules: [{ required: true }],
-        };
-      },
-    },
-    {
-      title: '操作符',
-      dataIndex: 'opercode',
-      search: false,
-      valueType: 'text',
-      //render:
-      formItemProps: () => {
-        return {
-          rules: [
-            { required: true },
-          ],
-        };
-      },
-    },
-    {
-      title: '操作参数',
-      dataIndex: 'operpara',
-      search: false,
-      formItemProps: () => {
-        return {
-          rules: [{ max: 20, message: '最多20个字符' }],
-        };
-      },
-    },
-    {
-      title: '操作名称',
-      dataIndex: 'opername',
-      search: false,
-      formItemProps: () => {
-        return {
-          rules: [
-            { max: 60, message: '最多60个字符' },
-            { required: true },
-            {
-              validator: async (rule, value,) => {
-
-                if (value) {
-                  if (value.indexOf(" ") != -1) {
-                    return Promise.reject(new Error("操作名称[" + value + "]不能含有空格!"));
-                  }
-                  if (value.indexOf(".") != -1) {
-                    return Promise.reject(new Error("操作名称[" + value + "]不能含有点号!"));
-                  }
-                }
-                const rs = await vailOperName(value);
-                if (!rs) {
-                  return Promise.reject(new Error("操作名称与编辑器变量名重复"));
-                }
-                return Promise.resolve();
-              }
-            },
-          ],
-        };
-      },
-    },
-    {
-      title: '数据类型',
-      dataIndex: 'datatype',
-      search: false,
-      valueType: 'select',
-      request: () => fetchDict({ dictKey: 'datatype' }),
-    },
-    {
-      title: '操作说明',
-      dataIndex: 'opercomment',
-      search: false,
-      ellipsis: true,
-      valueType: 'textarea',
-      formItemProps: () => {
-        return {
-          rules: [{ max: 200, message: '最多200个字符' }],
-        };
-      },
-    },
-
-  ];
-
-
-
-  return (
-    <SDPage 
-    footer={[<SDButton autoLoading={true}  successMessage='' primary key='save' onClick={saveinfo} >保存</SDButton>]}
-    >
-      <SDAreaTtile title="数据操作定义"/>
-      <SDLayout>
-      <SDEditableTable
-        columns={filedColumns}
-        value={fieldDataSource || []}
-        //insertDelete={false}
-        editable={true}
-        dragable={true}
-        onChange={setFieldDataSource}
-        formRef={tableRef}
-        //bodyMaxHeight='calc(100vh - 350px)'
-      />
-      </SDLayout>
-    </SDPage>
-  );
-};
-export default DefOperate;
+import React, { useEffect, useRef, useState, } from 'react';
+import type { EditableFormInstance, ProColumns, } from '@ant-design/pro-components';
+import {
+  baseFun,
+  SDAreaTtile,
+  SDButton,
+  SDEditableTable,
+  SDLayout,
+  SDPage,
+} from '@sundata/ui-frame';
+import type { SysSqlEditDefOperateModel } from './../../../services/pubMng/defOperate';
+import { vailOperName } from './../../../services/pubMng/defOperate';
+import { saveOperateDefineList } from './../../../services/pubMng/defOperate';
+import { getDataList } from './../../../services/pubMng/defOperate';
+import { useModel } from '@umijs/max';
+
+
+const DefOperate: React.FC = () => {
+
+  /** 字段数据 */
+  const [fieldDataSource, setFieldDataSource] = useState<readonly SysSqlEditDefOperateModel[]>();
+  // 可编辑表格的引用
+  const tableRef = useRef<EditableFormInstance>();
+  const { fetchDict } = useModel('dict');
+  
+  /**关系维护 */
+  const getListFun = async () => {
+    const resu = await getDataList();
+    setFieldDataSource(resu);
+  }
+  useEffect(() => {
+    getListFun();
+  }, []);
+
+  const saveinfo = async () => {
+
+     // 检查表格编辑状态
+     const editingRows = tableRef.current?.getRowsData?.();
+     if (editingRows && editingRows.length > 0) {
+       baseFun.warning('参数列表中有正在编辑的参数,请确认或取消修改后再保存');
+       return;
+     }
+    if (!fieldDataSource) {
+      return;
+    }
+    for (let i = 0; i < fieldDataSource.length; i++) {
+      if (fieldDataSource[i].operusemode == 'attribute' && fieldDataSource[i].datatype == "") {
+        baseFun.warning("操作符" + fieldDataSource[i].opercode + "使用方式为属性时数据类型不能为空!");
+        return;
+      }
+      for (let j = 0; j < fieldDataSource.length; j++) {
+        if (fieldDataSource[i].opercode == fieldDataSource[j].opercode && i != j) {
+          baseFun.warning("操作符" + fieldDataSource[i].opercode + "不唯一");
+          return;
+        }
+        if (fieldDataSource[i].opername == fieldDataSource[j].opername && i != j) {
+          baseFun.warning("操作符名称 " + fieldDataSource[i].opername + " 不唯一");
+          return;
+        }
+      }
+    }
+    //保存
+    await saveOperateDefineList([...(fieldDataSource || [])]);
+    baseFun.info('处理完成');
+  }
+
+
+  const filedColumns: ProColumns<SysSqlEditDefOperateModel>[] = [
+    {
+      title: '使用方式',
+      dataIndex: 'operusemode',
+      valueType: 'select',
+      search: false,
+      request: () => fetchDict({ dictKey: 'operusemode' }),
+      formItemProps: () => {
+        return {
+          rules: [{ required: true }],
+        };
+      },
+    },
+    {
+      title: '操作符',
+      dataIndex: 'opercode',
+      search: false,
+      valueType: 'text',
+      //render:
+      formItemProps: () => {
+        return {
+          rules: [
+            { required: true },
+          ],
+        };
+      },
+    },
+    {
+      title: '操作参数',
+      dataIndex: 'operpara',
+      search: false,
+      formItemProps: () => {
+        return {
+          rules: [{ max: 20, message: '最多20个字符' }],
+        };
+      },
+    },
+    {
+      title: '操作名称',
+      dataIndex: 'opername',
+      search: false,
+      formItemProps: () => {
+        return {
+          rules: [
+            { max: 60, message: '最多60个字符' },
+            { required: true },
+            {
+              validator: async (rule, value,) => {
+
+                if (value) {
+                  if (value.indexOf(" ") != -1) {
+                    return Promise.reject(new Error("操作名称[" + value + "]不能含有空格!"));
+                  }
+                  if (value.indexOf(".") != -1) {
+                    return Promise.reject(new Error("操作名称[" + value + "]不能含有点号!"));
+                  }
+                }
+                const rs = await vailOperName(value);
+                if (!rs) {
+                  return Promise.reject(new Error("操作名称与编辑器变量名重复"));
+                }
+                return Promise.resolve();
+              }
+            },
+          ],
+        };
+      },
+    },
+    {
+      title: '数据类型',
+      dataIndex: 'datatype',
+      search: false,
+      valueType: 'select',
+      request: () => fetchDict({ dictKey: 'datatype' }),
+    },
+    {
+      title: '操作说明',
+      dataIndex: 'opercomment',
+      search: false,
+      ellipsis: true,
+      valueType: 'textarea',
+      formItemProps: () => {
+        return {
+          rules: [{ max: 200, message: '最多200个字符' }],
+        };
+      },
+    },
+
+  ];
+
+
+
+  return (
+    <SDPage 
+    footer={[<SDButton autoLoading={true}  successMessage='' primary key='save' onClick={saveinfo} >保存</SDButton>]}
+    >
+      <SDAreaTtile title="数据操作定义"/>
+      <SDLayout>
+      <SDEditableTable
+        columns={filedColumns}
+        value={fieldDataSource || []}
+        //insertDelete={false}
+        editable={true}
+        dragable={true}
+        onChange={(value: any)=>{setFieldDataSource(value)}}
+        formRef={tableRef}
+        //bodyMaxHeight='calc(100vh - 350px)'
+      />
+      </SDLayout>
+    </SDPage>
+  );
+};
+export default DefOperate;

+ 159 - 139
Procedure/frontend/projectb/src/services/idataMng/excelMng.ts

@@ -1,139 +1,159 @@
-import type { BasePageModel, TableData } from '@sundata/ui-frame';
-import { baseFun } from '@sundata/ui-frame';
-
-export type SysSqlEditDefDataClassModel = {
-  mtype?: string;
-  mtypename?: string;
-  status?: string;
-  orgcode?: string;
-  tmptable?: string;
-  formaltable?: string;
-  remark?: string;
-  operate?: string;
-  flowUrl?: string;
-  ischeckData?: string;
-  statusname?: string;
-  orgcodeList?: string[];
-  colunconfigList?: ImportColunnConfigModel[];
-} & BasePageModel;
-
-export type ImportColunnConfigModel = {
-  id: number;
-  mtype?: string;
-  cellname?: string;
-  fieldname?: string;
-  fieldcnname?: string;
-  fieldtype?: string;
-  bussipk?: string;
-  fieldclass?: string;
-  classcode?: string;
-  checkType?: string;
-  checkTypes?: string[];
-  ldlength?: string;
-  fileddict?: string;
-  fieldtypename?: string;
-  fileddictname?: string;
-  bussipkname?: string;
-  checkTypename?: string;
-  fieldclassname?: string;
-  flag?: string;
-} & BasePageModel;
-
-export type ImpmTypeConfigModel = {
-  mtype?: string; //导入类型编号
-  mtypename?: string; //类型名称
-  status?: string; //装态
-  orgcodeList?: string[]; //机构
-  orgcode?: string;
-  tmptable?: string;
-  formaltable?: string;
-  remark?: string; //说明
-  operate?: string; //操作
-  flowUrl?: string; //流程发起链接  Varchar(1000)
-  ischeckData?: string; //是否直接提交
-  statusname?: string;
-  colunconfigList?: ImportColunnConfigModel[];
-};
-
-export type ImportTypeDataiAndList = {
-  typeconfigmode?: ImpmTypeConfigModel;
-  colunconfigmodel?: readonly ImportColunnConfigModel[];
-};
-
-/** 获取页面初始参数 POST /excelmanage/init */
-// export async function init() {
-//     return baseFun.request<Record<string, any>>('/api/admin/excelmanage/init', {});
-// }
-
-/** 获取数据补录模板列表 POST /excelmanage/getDataList */
-export async function getDataList(body: ImpmTypeConfigModel) {
-  return baseFun.request<TableData<ImpmTypeConfigModel>>('/api/admin/excelmanage/impmtype/getDataList.do', {
-    data: body,
-  });
-}
-
-/** 获取数据补录模板详情 POST /excelmanage/getDetail */
-export async function getDetail(body: ImpmTypeConfigModel) {
-  return baseFun.request<ImpmTypeConfigModel>('/api/admin/excelmanage/impmtype/getDetail.do', {
-    data: body,
-  });
-}
-
-/** 获取数据补录模板详情 POST /excelmanage/getImportColunnList */
-export async function getImportColunnConfigList(body: ImportColunnConfigModel) {
-  return baseFun.request<TableData<ImportColunnConfigModel>>(
-    '/api/admin/excelmanage/impmtype/getImportColunnConfigList.do',
-    {
-      data: body,
-    },
-  );
-}
-
-/** 用户代码是否存在 POST /excelmanage/isNotExist */
-export async function isNotExist(body: ImpmTypeConfigModel) {
-  return baseFun.request<string>('/api/admin/excelmanage/impmtype/isNotExist.do', {
-    data: body,
-  });
-}
-
-/** 保存 POST /excelmanage/save */
-export async function saveDetail(body: ImportTypeDataiAndList) {
-  return baseFun.request<void>('/api/admin/excelmanage/impmtype/save.do', {
-    data: body,
-  });
-}
-
-/** 删除 POST /excelmanage/delete */
-export async function deleteRows(body: ImpmTypeConfigModel) {
-  return baseFun.request<any>('/api/admin/excelmanage/impmtype/delete.do', {
-    data: body,
-  });
-}
-
-/** 倒出模板 */
-export async function exportExcelModel(mtype: string) {
-  return baseFun.download('/api/admin/excelmanage/importAndAuditp/importExcelModel.do', { mType:mtype });
-}
-
-//上传
-export async function uploadAction(file: File, mtype: string) {
-  const data = new FormData();
-  data.append('file', file);
-  data.append('mtype', mtype);
-  const res = await fetch('/api/admin/excelmanage/imp/imptable.do', {
-    method: 'POST',
-    body: data,
-  });
-  const sd = await res.json().catch(() => {
-    baseFun.error('导入失败');
-  });
-  console.log(sd);
-  return sd;
-}
-
-/** 发布 POST /excelmanage/Release */
-export async function Release(body: ImpmTypeConfigModel) {
-  return baseFun.request<void>('/api/admin/excelmanage/impmtype/Release.do', {
-    data: body,
-  });
-}
+import type { BasePageModel, TableData } from '@sundata/ui-frame';
+import { baseFun } from '@sundata/ui-frame';
+
+export type SysSqlEditDefDataClassModel = {
+  mtype?: string;
+  mtypename?: string;
+  status?: string;
+  orgcode?: string;
+  tmptable?: string;
+  formaltable?: string;
+  remark?: string;
+  operate?: string;
+  flowUrl?: string;
+  ischeckData?: string;
+  statusname?: string;
+  orgcodeList?: string[];
+  colunconfigList?: ImportColunnConfigModel[];
+} & BasePageModel;
+
+export type ImportColunnConfigModel = {
+  id: number;
+  mtype?: string;
+  cellname?: string;
+  fieldname?: string;
+  fieldcnname?: string;
+  fieldtype?: string;
+  bussipk?: string;
+  fieldclass?: string;
+  classcode?: string;
+  checkType?: string;
+  checkTypes?: string[];
+  ldlength?: string;
+  fileddict?: string;
+  fieldtypename?: string;
+  fileddictname?: string;
+  bussipkname?: string;
+  checkTypename?: string;
+  fieldclassname?: string;
+  flag?: string;
+} & BasePageModel;
+
+export type ImpmTypeConfigModel = {
+  mtype?: string; //导入类型编号
+  mtypename?: string; //类型名称
+  status?: string; //装态
+  orgcodeList?: string[]; //机构
+  orgcode?: string;
+  tmptable?: string;
+  formaltable?: string;
+  remark?: string; //说明
+  operate?: string; //操作
+  flowUrl?: string; //流程发起链接  Varchar(1000)
+  ischeckData?: string; //是否直接提交
+  statusname?: string;
+  colunconfigList?: ImportColunnConfigModel[];
+};
+
+export type ImportTypeDataiAndList = {
+  typeconfigmode?: ImpmTypeConfigModel;
+  colunconfigmodel?: readonly ImportColunnConfigModel[];
+};
+
+export type ImpSqlConfigModel = {
+  mtype?: string; //模板代码
+  methodtype?: string; //处理类型,SQL/JAVA
+  lbody?: string; //逻辑体,处理类型为SQL,配置转换的sql语句,处理类型为JAVA时,配置java方法所在类配置bean的name值
+}
+
+/** 获取页面初始参数 POST /excelmanage/init */
+// export async function init() {
+//     return baseFun.request<Record<string, any>>('/api/admin/excelmanage/init', {});
+// }
+
+/** 获取数据补录模板列表 POST /excelmanage/getDataList */
+export async function getDataList(body: ImpmTypeConfigModel) {
+  return baseFun.request<TableData<ImpmTypeConfigModel>>('/api/admin/excelmanage/impmtype/getDataList.do', {
+    data: body,
+  });
+}
+
+/** 获取数据补录模板详情 POST /excelmanage/getDetail */
+export async function getDetail(body: ImpmTypeConfigModel) {
+  return baseFun.request<ImpmTypeConfigModel>('/api/admin/excelmanage/impmtype/getDetail.do', {
+    data: body,
+  });
+}
+
+/** 获取数据补录模板详情 POST /excelmanage/getImportColunnList */
+export async function getImportColunnConfigList(body: ImportColunnConfigModel) {
+  return baseFun.request<TableData<ImportColunnConfigModel>>(
+    '/api/admin/excelmanage/impmtype/getImportColunnConfigList.do',
+    {
+      data: body,
+    },
+  );
+}
+
+/** 用户代码是否存在 POST /excelmanage/isNotExist */
+export async function isNotExist(body: ImpmTypeConfigModel) {
+  return baseFun.request<string>('/api/admin/excelmanage/impmtype/isNotExist.do', {
+    data: body,
+  });
+}
+
+/** 保存 POST /excelmanage/save */
+export async function saveDetail(body: ImportTypeDataiAndList) {
+  return baseFun.request<void>('/api/admin/excelmanage/impmtype/save.do', {
+    data: body,
+  });
+}
+
+/** 删除 POST /excelmanage/delete */
+export async function deleteRows(body: ImpmTypeConfigModel) {
+  return baseFun.request<any>('/api/admin/excelmanage/impmtype/delete.do', {
+    data: body,
+  });
+}
+
+/** 倒出模板 */
+export async function exportExcelModel(mtype: string) {
+  return baseFun.download('/api/admin/excelmanage/importAndAuditp/importExcelModel.do', { mType:mtype });
+}
+
+//上传
+export async function uploadAction(file: File, mtype: string) {
+  const data = new FormData();
+  data.append('file', file);
+  data.append('mtype', mtype);
+  const res = await fetch('/api/admin/excelmanage/imp/imptable.do', {
+    method: 'POST',
+    body: data,
+  });
+  const sd = await res.json().catch(() => {
+    baseFun.error('导入失败');
+  });
+  console.log(sd);
+  return sd;
+}
+
+/** 发布 POST /excelmanage/Release */
+export async function Release(body: ImpmTypeConfigModel) {
+  return baseFun.request<void>('/api/admin/excelmanage/impmtype/Release.do', {
+    data: body,
+  });
+}
+
+/** 获取转换逻辑配置列表 */
+export async function getImpSqlConfigList(body: ImpSqlConfigModel) {
+  return baseFun.request<TableData<ImpSqlConfigModel>>('/api/admin/excelmanage/impmtype/getImpSqlConfigList.do', {
+    data: body,
+  });
+}
+
+/** 保存转换逻辑配置列表 */
+export async function saveImpSqlConfigList(body: readonly ImpSqlConfigModel[]) {
+  return baseFun.request<void>('/api/admin/excelmanage/impmtype/saveImpSqlConfigList.do', {
+    data: body,
+  });
+}

+ 289 - 286
Procedure/frontend/projectb/src/services/pubMng/holiday.ts

@@ -1,286 +1,289 @@
-import { baseFun } from "@sundata/ui-frame";
-
-export async function dateinit() {
-    return baseFun.request<Map<string,object>>('/api/admin/holidaymanage/init.do', {
-      method: 'POST',
-    });
-  }
-
-  export async function isExist(begindate: string) {
-    return baseFun.request<boolean>('/api/admin/holidaymanage/isExist.do?year='+begindate, {
-      method: 'POST',
-    });
-  }
-  export async function insert(begindate: string) {
-    return baseFun.request<any>('/api/admin/holidaymanage/insert.do?year='+begindate, {
-      method: 'POST',
-    });
-  }
-  export async function upFlag(flag: string,seldays:string) {
-    return baseFun.request<any>('/api/admin/holidaymanage/upFlag.do?flag='+flag+'&seldays='+seldays, {
-      method: 'POST',
-    });
-  }
-  export function calendar(now :Date) {
-  interface Calendar {
-    gregorianYear?: Number;          //公历年
-    gregorianMonth?: String;         //公历月
-    gregorianDay?: String;           //公历日
-    weekday?: String;                //星期
-    hours?: String;
-    minutes?: String;
-    seconds?: String;
-
-    lunarYear?: Number;              //农历年
-    lunarMonth?: Number;             //农历月
-    lunarDay?: Number;               //农历日
-
-    lunarYearCn?: String;              //农历天干地支纪年
-    lunarMonthCn?: String;             //农历中文月
-    lunarDayCn?: String;               //农历中文日
-    zodiacYear?: String;               //农历生肖年
-
-    solarTerm?: String;                //节气
-    gregorianFestival?: String;        //公历节日
-    lunarFestival?: String;             //农历节日
-}
-
-let lunarInfo = [
-    0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
-    0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
-    0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
-    0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
-    0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
-    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0,
-    0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
-    0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
-    0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
-    0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
-    0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
-    0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
-    0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
-    0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
-    0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0]
-
-let zodiacs = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪']
-let Gan = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']
-let Zhi = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
-let weekday = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
-// let now = new Date()
-//用于计算农历年月日的数据
-let GY = now.getFullYear()
-let GM = now.getMonth()
-let GD = now.getDate()
-
-let year    = now.getFullYear()
-let _month   = now.getMonth() + 1
-let _date    = now.getDate()
-let _hours   = now.getHours()
-let _minutes = now.getMinutes()
-let _seconds = now.getSeconds()
-let month   = _month.toString().padStart(2, '0')
-let date    = _date.toString().padStart(2, '0')
-let hours   = _hours.toString().padStart(2, '0')
-let minutes = _minutes.toString().padStart(2, '0')
-let seconds = _seconds.toString().padStart(2, '0')
-
-//==== 传入 offset 传回干支, 0=甲子
-function cyclical(num : number) {
-    return(Gan[num % 10] + Zhi[num % 12])
-}
-
-//==== 传回农历 year年的总天数
-function lYearDays(year : number) {
-    let i, sum = 348
-    for(i = 0x8000; i > 0x8; i >>= 1) {
-        sum += (lunarInfo[year - 1900] & i) ? 1: 0
-    }
-    return(sum + leapDays(year))
-}
-
-//==== 传回农历 year年闰月的天数
-function leapDays(year : number) {
-    if(leapMonth(year)) {
-        return((lunarInfo[year-1900] & 0x10000)? 30: 29)
-    }
-    else {
-        return 0
-    }
-}
-
-//==== 传回农历 year年闰哪个月 1-12 , 没闰传回 0
-function leapMonth(year : number) {
-    return(lunarInfo[year - 1900] & 0xf)
-}
-
-//==== 传回农历 year年month月的总天数
-function monthDays(year : number, month : number) {
-    return( (lunarInfo[year - 1900] & (0x10000 >> month))? 30: 29 )
-}
-
-//==== 算出农历, 传入日期对象, 传回农历日期对象
-//     该对象属性有 农历年year 农历月month 农历日day 是否闰年isLeap yearCyl dayCyl monCyl
-function Lunar(objDate : Date) {
-    let i, temp = 0
-    let baseDate = new Date(1900,0,31)
-    let offset   = Math.floor((objDate.getTime() - baseDate.getTime())/86400000)
-
-    let dayCyl = offset + 40
-    let monCyl = 14
-
-    for(i = 1900; i < 2050 && offset > 0; i++) {
-        temp = lYearDays(i)
-        offset -= temp
-        monCyl += 12
-    }
-    if(offset < 0) {
-        offset += temp;
-        i--;
-        monCyl -= 12
-    }
-    //农历年
-    let year = i
-    let yearCyl = i-1864
-
-    let leap = leapMonth(i) //闰哪个月
-    let isLeap = false  //是否闰年
-
-    for(i=1; i<13 && offset>0; i++) {
-        //闰月
-        if(leap>0 && i === (leap+1) && isLeap === false) {
-            --i; isLeap = true; temp = leapDays(year);
-        }
-        else {
-            temp = monthDays(year, i);
-        }
-
-        //解除闰月
-        if(isLeap === true && i === (leap + 1)) {
-            isLeap = false
-        }
-
-        offset -= temp
-        if(isLeap === false) {
-            monCyl ++
-        }
-    }
-
-    if(offset === 0 && leap>0 && i===leap+1)
-        if(isLeap) {
-            isLeap = false
-        }
-        else {
-            isLeap = true
-            --i
-            --monCyl
-        }
-
-    if(offset<0){
-        offset += temp
-        --i
-        --monCyl
-    }
-    //农历月
-    let month = i
-    //农历日
-    let day = offset + 1
-
-    return {
-        year: year,
-        month: month,
-        day: day,
-        isLeap: isLeap,
-        leap: leap,
-        yearCyl: yearCyl,
-        dayCyl: dayCyl,
-        monCyl: monCyl
-    }
-}
-
-//==== 中文日期 m为传入月份,d为传入日期
-function cDay(m : number, d : number){
-    let nStr1 = ['日', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
-    let nStr2 = ['初', '十', '廿', '卅', '']
-    //农历中文月
-    let lunarMonthCn
-    //农历中文日
-    let lunarDayCn
-    if (m > 10){
-        lunarMonthCn = '十' + nStr1[m - 10]
-    } else {
-        lunarMonthCn = nStr1[m]
-    }
-    lunarMonthCn += '月'
-
-    switch (d) {
-        case 10: lunarDayCn = '初十'; break;
-        case 20: lunarDayCn = '二十'; break;
-        case 30: lunarDayCn = '三十'; break;
-        default: lunarDayCn = nStr2[Math.floor(d/10)] + nStr1[d % 10]
-    }
-    return {
-        lunarMonthCn: lunarMonthCn,
-        lunarDayCn: lunarDayCn
-    }
-}
-
-//节气
-function getSolarTerm() {
-    let sTermInfo = [
-        0, 21208, 42467, 63836, 85337, 107014,
-        128867, 150921, 173149, 195551, 218072, 240693,
-        263343, 285989, 308563, 331033, 353350, 375494,
-        397447, 419210, 440795, 462224, 483532, 504758
-    ]
-    let solarTerm = [
-        '小寒', '大寒', '立春', '雨水', '惊蛰', '春分',
-        '清明', '谷雨', '立夏', '小满', '芒种', '夏至',
-        '小暑', '大暑', '立秋', '处暑', '白露', '秋分',
-        '寒露', '霜降', '立冬', '小雪', '大雪', '冬至'
-    ]
-
-    let solarTerms = ''
-    let tmp1 = new Date(
-        (31556925974.7 * (GY - 1900) + sTermInfo[GM * 2 + 1] * 60000) + Date.UTC(1900,0,6,2,5)
-    )
-    let tmp2 = tmp1.getUTCDate()
-    if (tmp2 === GD) solarTerms = solarTerm[GM * 2 + 1]
-    tmp1 = new Date(
-        (31556925974.7 * (GY - 1900) + sTermInfo[GM * 2] * 60000) + Date.UTC(1900,0,6,2,5)
-    )
-    tmp2= tmp1.getUTCDate()
-    if (tmp2 === GD) solarTerms = solarTerm[GM * 2]
-
-    return solarTerms
-}
-
-let  calendar: Calendar = {}
-//公历年月日、星期、时分秒
-calendar.gregorianYear = year
-calendar.gregorianMonth = month
-calendar.gregorianDay = date
-calendar.weekday = weekday[now.getDay()]
-calendar.hours = hours
-calendar.minutes = minutes
-calendar.seconds = seconds
-
-//去掉时分秒的日期
-let sDObj = new Date(GY, GM, GD);
-let lDObj = Lunar(sDObj);
-
-//农历年月日、生肖年
-calendar.lunarYear = lDObj.year
-calendar.lunarMonth = lDObj.month
-calendar.lunarDay = lDObj.day
-calendar.zodiacYear = zodiacs[(GY - 4) % 12]
-
-//农历中文年月日
-calendar.lunarYearCn = cyclical( GY - 1900 + 36)
-calendar.lunarMonthCn = cDay(lDObj.month,lDObj.day).lunarMonthCn
-calendar.lunarDayCn = cDay(lDObj.month,lDObj.day).lunarDayCn
-
-//节气
-calendar.solarTerm = getSolarTerm()
-return calendar;
-  }
-// export default calendar
+import { baseFun } from "@sundata/ui-frame";
+
+export async function dateinit() {
+    return baseFun.request<Map<string,object>>('/api/admin/holidaymanage/init.do', {
+      method: 'POST',
+    });
+  }
+
+  export async function isExist(begindate: string) {
+    return baseFun.request<boolean>('/api/admin/holidaymanage/isExist.do?year='+begindate, {
+      method: 'POST',
+    });
+  }
+  export async function insert(begindate: string) {
+    return baseFun.request<any>('/api/admin/holidaymanage/insert.do?year='+begindate, {
+      method: 'POST',
+    });
+  }
+  export async function upFlag(flag: string,seldays:string) {
+    return baseFun.request<any>('/api/admin/holidaymanage/upFlag.do?flag='+flag+'&seldays='+seldays, {
+      method: 'POST',
+    });
+  }
+
+  interface CalendarITF {
+    gregorianYear?: Number;          //公历年
+    gregorianMonth?: String;         //公历月
+    gregorianDay?: String;           //公历日
+    weekday?: String;                //星期
+    hours?: String;
+    minutes?: String;
+    seconds?: String;
+
+    lunarYear?: Number;              //农历年
+    lunarMonth?: Number;             //农历月
+    lunarDay?: Number;               //农历日
+
+    lunarYearCn?: String;              //农历天干地支纪年
+    lunarMonthCn?: String;             //农历中文月
+    lunarDayCn?: String;               //农历中文日
+    zodiacYear?: String;               //农历生肖年
+
+    solarTerm?: String;                //节气
+    gregorianFestival?: String;        //公历节日
+    lunarFestival?: String;             //农历节日
+}
+
+
+  export function calendarFun(now :Date) {
+  
+let lunarInfo = [
+    0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
+    0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
+    0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
+    0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
+    0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
+    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0,
+    0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
+    0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
+    0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
+    0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
+    0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
+    0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
+    0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
+    0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
+    0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0]
+
+let zodiacs = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪']
+let Gan = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']
+let Zhi = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
+let weekday = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
+// let now = new Date()
+//用于计算农历年月日的数据
+let GY = now.getFullYear()
+let GM = now.getMonth()
+let GD = now.getDate()
+
+let year    = now.getFullYear()
+let _month   = now.getMonth() + 1
+let _date    = now.getDate()
+let _hours   = now.getHours()
+let _minutes = now.getMinutes()
+let _seconds = now.getSeconds()
+let month   = _month.toString().padStart(2, '0')
+let date    = _date.toString().padStart(2, '0')
+let hours   = _hours.toString().padStart(2, '0')
+let minutes = _minutes.toString().padStart(2, '0')
+let seconds = _seconds.toString().padStart(2, '0')
+
+//==== 传入 offset 传回干支, 0=甲子
+function cyclical(num : number) {
+    return(Gan[num % 10] + Zhi[num % 12])
+}
+
+//==== 传回农历 year年的总天数
+function lYearDays(year : number) {
+    let i, sum = 348
+    for(i = 0x8000; i > 0x8; i >>= 1) {
+        sum += (lunarInfo[year - 1900] & i) ? 1: 0
+    }
+    return(sum + leapDays(year))
+}
+
+//==== 传回农历 year年闰月的天数
+function leapDays(year : number) {
+    if(leapMonth(year)) {
+        return((lunarInfo[year-1900] & 0x10000)? 30: 29)
+    }
+    else {
+        return 0
+    }
+}
+
+//==== 传回农历 year年闰哪个月 1-12 , 没闰传回 0
+function leapMonth(year : number) {
+    return(lunarInfo[year - 1900] & 0xf)
+}
+
+//==== 传回农历 year年month月的总天数
+function monthDays(year : number, month : number) {
+    return( (lunarInfo[year - 1900] & (0x10000 >> month))? 30: 29 )
+}
+
+//==== 算出农历, 传入日期对象, 传回农历日期对象
+//     该对象属性有 农历年year 农历月month 农历日day 是否闰年isLeap yearCyl dayCyl monCyl
+function Lunar(objDate : Date) {
+    let i, temp = 0
+    let baseDate = new Date(1900,0,31)
+    let offset   = Math.floor((objDate.getTime() - baseDate.getTime())/86400000)
+
+    let dayCyl = offset + 40
+    let monCyl = 14
+
+    for(i = 1900; i < 2050 && offset > 0; i++) {
+        temp = lYearDays(i)
+        offset -= temp
+        monCyl += 12
+    }
+    if(offset < 0) {
+        offset += temp;
+        i--;
+        monCyl -= 12
+    }
+    //农历年
+    let year = i
+    let yearCyl = i-1864
+
+    let leap = leapMonth(i) //闰哪个月
+    let isLeap = false  //是否闰年
+
+    for(i=1; i<13 && offset>0; i++) {
+        //闰月
+        if(leap>0 && i === (leap+1) && isLeap === false) {
+            --i; isLeap = true; temp = leapDays(year);
+        }
+        else {
+            temp = monthDays(year, i);
+        }
+
+        //解除闰月
+        if(isLeap === true && i === (leap + 1)) {
+            isLeap = false
+        }
+
+        offset -= temp
+        if(isLeap === false) {
+            monCyl ++
+        }
+    }
+
+    if(offset === 0 && leap>0 && i===leap+1)
+        if(isLeap) {
+            isLeap = false
+        }
+        else {
+            isLeap = true
+            --i
+            --monCyl
+        }
+
+    if(offset<0){
+        offset += temp
+        --i
+        --monCyl
+    }
+    //农历月
+    let month = i
+    //农历日
+    let day = offset + 1
+
+    return {
+        year: year,
+        month: month,
+        day: day,
+        isLeap: isLeap,
+        leap: leap,
+        yearCyl: yearCyl,
+        dayCyl: dayCyl,
+        monCyl: monCyl
+    }
+}
+
+//==== 中文日期 m为传入月份,d为传入日期
+function cDay(m : number, d : number){
+    let nStr1 = ['日', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
+    let nStr2 = ['初', '十', '廿', '卅', '']
+    //农历中文月
+    let lunarMonthCn
+    //农历中文日
+    let lunarDayCn
+    if (m > 10){
+        lunarMonthCn = '十' + nStr1[m - 10]
+    } else {
+        lunarMonthCn = nStr1[m]
+    }
+    lunarMonthCn += '月'
+
+    switch (d) {
+        case 10: lunarDayCn = '初十'; break;
+        case 20: lunarDayCn = '二十'; break;
+        case 30: lunarDayCn = '三十'; break;
+        default: lunarDayCn = nStr2[Math.floor(d/10)] + nStr1[d % 10]
+    }
+    return {
+        lunarMonthCn: lunarMonthCn,
+        lunarDayCn: lunarDayCn
+    }
+}
+
+//节气
+function getSolarTerm() {
+    let sTermInfo = [
+        0, 21208, 42467, 63836, 85337, 107014,
+        128867, 150921, 173149, 195551, 218072, 240693,
+        263343, 285989, 308563, 331033, 353350, 375494,
+        397447, 419210, 440795, 462224, 483532, 504758
+    ]
+    let solarTerm = [
+        '小寒', '大寒', '立春', '雨水', '惊蛰', '春分',
+        '清明', '谷雨', '立夏', '小满', '芒种', '夏至',
+        '小暑', '大暑', '立秋', '处暑', '白露', '秋分',
+        '寒露', '霜降', '立冬', '小雪', '大雪', '冬至'
+    ]
+
+    let solarTerms = ''
+    let tmp1 = new Date(
+        (31556925974.7 * (GY - 1900) + sTermInfo[GM * 2 + 1] * 60000) + Date.UTC(1900,0,6,2,5)
+    )
+    let tmp2 = tmp1.getUTCDate()
+    if (tmp2 === GD) solarTerms = solarTerm[GM * 2 + 1]
+    tmp1 = new Date(
+        (31556925974.7 * (GY - 1900) + sTermInfo[GM * 2] * 60000) + Date.UTC(1900,0,6,2,5)
+    )
+    tmp2= tmp1.getUTCDate()
+    if (tmp2 === GD) solarTerms = solarTerm[GM * 2]
+
+    return solarTerms
+}
+
+let  calendar: CalendarITF = {}
+//公历年月日、星期、时分秒
+calendar.gregorianYear = year
+calendar.gregorianMonth = month
+calendar.gregorianDay = date
+calendar.weekday = weekday[now.getDay()]
+calendar.hours = hours
+calendar.minutes = minutes
+calendar.seconds = seconds
+
+//去掉时分秒的日期
+let sDObj = new Date(GY, GM, GD);
+let lDObj = Lunar(sDObj);
+
+//农历年月日、生肖年
+calendar.lunarYear = lDObj.year
+calendar.lunarMonth = lDObj.month
+calendar.lunarDay = lDObj.day
+calendar.zodiacYear = zodiacs[(GY - 4) % 12]
+
+//农历中文年月日
+calendar.lunarYearCn = cyclical( GY - 1900 + 36)
+calendar.lunarMonthCn = cDay(lDObj.month,lDObj.day).lunarMonthCn
+calendar.lunarDayCn = cDay(lDObj.month,lDObj.day).lunarDayCn
+
+//节气
+calendar.solarTerm = getSolarTerm()
+return calendar;
+  }
+// export default calendar