shenwu há 7 meses atrás
pai
commit
104c0dafd6

+ 5 - 0
config/routes.tsx

@@ -86,6 +86,11 @@ const newMenu = [
             name: '小程序组件配置',
             component: './distribution/miniprogram/mimiModule',
           },
+          {
+            path: '/distribution/miniprogram/pagesManage',
+            name: '页面模板管理',
+            component: './distribution/miniprogram/pagesManage',
+          },
         ],
       },
       {

+ 1 - 1
src/Hook/useAjax.tsx

@@ -61,7 +61,7 @@ export function useAjax(
         if (options?.type === 'noPage') {
           return {
             current: 1,
-            data: res.data,
+            data: res.data?.[0]?.id ? res.data : res.data.map((a: any,b: any)=>({...a,id:b})),
             pageSize: 20,
             total: res.data.length,
             success: true,

+ 0 - 1
src/components/MenuChange.tsx

@@ -13,7 +13,6 @@ const MenuChange: React.FC<Props> = (props) => {
       ...initialState,
       menuType,
       token: initialState?.token || '',
-      selectApp: data,
     });
     sessionStorage.setItem('menuType', menuType);
     sessionStorage.setItem('selectApp', JSON.stringify(data));

+ 3 - 6
src/components/uploadImg/index.tsx

@@ -1,17 +1,15 @@
 import CropperImg from '@/components/CropperImg';
-import { useAjax } from '@/Hook/useAjax';
 import { useOss } from '@/Hook/useOss';
-import { MediaTypeProps, upLoadMediaApi } from '@/services/global';
-import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
 import { message, Upload } from 'antd';
 import { RcFile } from 'antd/es/upload';
 import dayjs from 'dayjs';
 import React, { useEffect, useState } from 'react';
 import styles from './index.less';
+import { PlusOutlined } from '@ant-design/icons';
 type CompareType = '<' | '<=' | '>' | '>=' | '=' | '!=';
 
 interface Props {
-  type?: MediaTypeProps;
+  type?: any;
   value?: string;
   onChange?: (data: { value: string; file: RcFile; name: string }) => void;
   size?: { width: number; height: number; evalW: CompareType; evalH: CompareType; msg: string };
@@ -24,7 +22,6 @@ const UploadImg: React.FC<Props> = ({ value, onChange, size, type, isCropper, is
   /********************************/
   const [visible, setVisible] = useState<boolean>(false);
   const [file, setFile] = useState<RcFile>();
-  const upLoadMedia = useAjax((params) => upLoadMediaApi(params));
   const ossUpload = useOss(true);
   const [imageUrl, setImageUrl] = useState<string>('');
   /********************************/
@@ -37,7 +34,7 @@ const UploadImg: React.FC<Props> = ({ value, onChange, size, type, isCropper, is
     <div>
       <div style={{ height: 45, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
         {' '}
-        {upLoadMedia.loading ? <LoadingOutlined /> : <PlusOutlined />}
+        <PlusOutlined/>
       </div>
       <div style={{ display: 'flex', flexFlow: 'column' }}>
         <span>上传图片</span>

+ 26 - 85
src/pages/distribution/miniprogram/mimiModule/index.tsx

@@ -1,25 +1,13 @@
 import { useAjax } from '@/Hook/useAjax';
-import { apiDistributorInfoList } from '@/services/distribution/info';
-import {
-  apiWxAppInfo,
-  apiWxAppInfoPageList,
-  apiWxAppInfoRemove,
-  apiWxAppInfoUpdate,
-  apiWxAppInfoUpdateEnabled,
-  apiWxAppInfoWxAppConfigAddOrEdit,
-  wechatMchAll,
-} from '@/services/distribution/weChatInfo';
-import { PlusCircleOutlined } from '@ant-design/icons';
 import {
   ActionType,
   BetaSchemaForm,
-  PageContainer,
   ProFormInstance,
   ProTable,
 } from '@ant-design/pro-components';
 import { useModel } from '@umijs/max';
 import { Button, message } from 'antd';
-import { useCallback, useEffect, useRef, useState } from 'react';
+import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
 import formConfig from './formConfig';
 import { columns } from './tableConfig';
 import { apiMiniappComponentInfoDel, apiMiniappComponentInfoPageList, apiMiniappComponentInfoSave, apiMiniappComponentInfoUpdate, apiMiniappComponentInfoUpdateEnabled } from '@/services/distribution/miniprogram';
@@ -28,13 +16,12 @@ type DataItem = {
   name: string;
   state: string;
 };
-const Page: React.FC = () => {
+const Page = forwardRef((props: any, ref?: any) =>{
+  let { data,reload } = props
   const formRef = useRef<ProFormInstance>();
-  const assignRormRef = useRef<ProFormInstance>();
   const actionRef = useRef<ActionType>();
   let { state } = useModel('global');
-  let [open, setOpen] = useState<any>(null); //新增
-  let [assignOpen, setAssignOpen] = useState(false);
+  let [open, setOpen] = useState<any>(null); //新增 存在ID代表是当前模板页面
   let [editValues, setEditValues] = useState<any>({});
   // ======API===============
   let MiniappComponentInfoPageList = useAjax((params) => apiMiniappComponentInfoPageList(params), { type: 'table' }); //列表
@@ -49,7 +36,7 @@ const Page: React.FC = () => {
   const del = (id: any) => {
     MiniappComponentInfoDel.run(id).then((res) => {
       if (res.code === 200) {
-        actionRef?.current?.reload();
+        reload()
         message.success('删除成功');
       }
     });
@@ -58,7 +45,7 @@ const Page: React.FC = () => {
   const stateUpdata = (id: any, ck: boolean) => {
     MiniappComponentInfoUpdateEnabled.run({ id, enabled: ck }).then((res) => {
       if (res.data) {
-        actionRef?.current?.reload();
+        reload()
         message.success(ck ? '启动成功' : '停用成功');
       }
     });
@@ -68,10 +55,14 @@ const Page: React.FC = () => {
     let api = editValues?.id ? MiniappComponentInfoUpdate : MiniappComponentInfoSave;
     if (editValues?.id) {
       values.id = editValues?.id;
+      values.enabledAppPageId = editValues?.enabledAppPageId
+    }else{
+      values.enabledAppPageId = open
     }
+
     api.run(values).then((res) => {
       if (res.code === 200) {
-        actionRef?.current?.reload();
+        reload()
         message.success('操作成功!');
         closeForm(false);
       }
@@ -92,34 +83,24 @@ const Page: React.FC = () => {
       setOpen(b);
     }
   };
+  useImperativeHandle(ref, () => ({
+    openMoadl:(id:any)=>{
+      setOpen(id)
+    }
+  }));
+  console.log("open",open)
   return (
-    <PageContainer>
+    <div >
       <ProTable<any, any>
-        headerTitle={'小程序组件列表'}
+        headerTitle={false}
         actionRef={actionRef}
         rowKey={(r) => r.id}
-        search={{
-          labelWidth: 120,
-        }}
+        search={false}
         scroll={{ x: 'auto' }}
-        request={async (params) => {
-          return await MiniappComponentInfoPageList.run(params);
-        }}
-        toolBarRender={() => {
-          return [
-            <Button
-              type="primary"
-              onClick={() => {
-                setOpen(true);
-              }}
-            >
-              <PlusCircleOutlined />
-              新增组件
-            </Button>,
-          ];
-        }}
-        columns={columns(closeForm, del, stateUpdata,state?.enumList)}
-        // bordered
+        dataSource={data}
+        toolBarRender={false}
+        columns={columns(closeForm, del, stateUpdata, state?.enumList)}
+      // bordered
       />
       {/* 新增修改 */}
       <BetaSchemaForm<DataItem>
@@ -140,47 +121,7 @@ const Page: React.FC = () => {
         columns={formConfig(state?.enumList)}
         loading={MiniappComponentInfoSave?.loading || MiniappComponentInfoUpdate?.loading}
       />
-      {/*指派  */}
-      {/* <BetaSchemaForm<DataItem>
-        title={editValues?.appName + '小程序指派'}
-        formRef={assignRormRef}
-        width={400}
-        open={assignOpen}
-        onOpenChange={(b) => {
-          if (!b) {
-            setEditValues({});
-            setAssignOpen(false);
-          }
-        }}
-        layoutType={'ModalForm'}
-        labelCol={{ span: 6 }}
-        wrapperCol={{ span: 14 }}
-        grid={true}
-        rowProps={{ gutter: [20, 20] }}
-        layout="horizontal"
-        onFinish={assign}
-        columns={[
-          {
-            title: '分销商',
-            dataIndex: 'distributorId',
-            formItemProps: {
-              style: { marginTop: 20 },
-              rules: [
-                {
-                  required: true,
-                  message: '此项为必填项',
-                },
-              ],
-            },
-            valueEnum: () => {
-              let arr = DistributorInfoList?.data?.data;
-              return new Map(arr?.map(({ id, companyName }: any) => [id, companyName]));
-            },
-          },
-        ]}
-        loading={WxAppInfoWxAppConfigAddOrEdit?.loading}
-      /> */}
-    </PageContainer>
+    </div>
   );
-};
+});
 export default Page;

+ 91 - 0
src/pages/distribution/miniprogram/pagesManage/formComp.tsx

@@ -0,0 +1,91 @@
+import UploadImg from '@/components/uploadImg';
+import {
+    ProCard,
+    ProForm,
+    ProFormGroup,
+    ProFormInstance,
+    ProFormItem,
+    ProFormList,
+    ProFormRadio,
+    ProFormText,
+    ProFormTextArea,
+} from '@ant-design/pro-components';
+import { forwardRef, useImperativeHandle, useRef } from 'react';
+let rules = [{
+    required: true,
+    message: '此项为必填项',
+}]
+let options = [
+    {
+        value: true,
+        label: "是"
+    },
+    {
+        value: false,
+        label: "否"
+    },
+]
+const FormComp = forwardRef((props: any, ref?: any) => {
+    const formRef = useRef<ProFormInstance>(); // 内部 formRef 供 ProForm 使用
+    // 使用 useImperativeHandle 暴露方法给父组件
+    useImperativeHandle(ref, () => ({
+        ...formRef.current
+    }));
+    return (
+        <ProForm onFinish={async (e) => console.log(e)} formRef={formRef} submitter={false}>
+            <ProFormText name="templateName" label="模板名称" rules={rules} />
+            <ProFormList
+                name="appPageConfigDTOList"
+                creatorButtonProps={
+                    {creatorButtonText:"新增页面"}
+                }
+                // label="页面配置"
+                itemRender={({ listDom, action }, { record }) => {
+                    return (
+                        <ProCard
+                            bordered
+                            extra={action}
+                            title={record?.name}
+                            style={{
+                                marginBlockEnd: 8,
+                            }}
+                        >
+                            {listDom}
+                        </ProCard>
+                    );
+                }}
+            >
+                <ProForm.Group>
+                    <ProFormGroup direction='vertical'>
+                        <ProFormText name="pageName" label="页面名称" rules={rules} />
+                        <ProFormText name="pagePath" label="页面路径" rules={rules} />
+                    </ProFormGroup>
+                    <ProFormGroup direction='vertical' >
+                        <ProFormRadio.Group name="readingContent" label="是否阅读内容" options={options} initialValue={false} />
+                        <ProFormRadio.Group name="enabledComponent" label="是否支持组件配置" options={options} initialValue={false} />
+                    </ProFormGroup>
+                    <ProFormGroup direction='vertical'>
+                        <ProFormText name="shareTitles" label="分享标题" />
+                        <ProFormTextArea name="pageDesc" label="页面描述" />
+                    </ProFormGroup>
+                    <ProForm.Item name="sharePicUrl" label="分享图片" >
+                        <UploadImg
+                            size={{
+                                width: 300,
+                                height: 400,
+                                evalW: '!=',
+                                evalH: '!=',
+                                msg: '需要图片大小300*400',
+                            }}
+                            isEdit={true}
+                            type="image"
+                            isCropper
+                        />
+                    </ProForm.Item>
+                </ProForm.Group>
+            </ProFormList>
+        </ProForm>
+    );
+});
+
+export default FormComp;

+ 127 - 0
src/pages/distribution/miniprogram/pagesManage/index.tsx

@@ -0,0 +1,127 @@
+import { useAjax } from '@/Hook/useAjax';
+import { PlusCircleOutlined } from '@ant-design/icons';
+import {
+  ActionType,
+  PageContainer,
+  ProFormInstance,
+  ProTable,
+} from '@ant-design/pro-components';
+import { Button, message, Modal, Table } from 'antd';
+import { useRef, useState } from 'react';
+import { childrenColumns, columns } from './tableConfig';
+import { appPageList, configAppPages } from '@/services/distribution/pagesManage';
+import FormComp from './formComp';
+import MimiModule from '../mimiModule'
+
+const Page: React.FC = () => {
+  const formRef = useRef<ProFormInstance>();
+  const actionRef = useRef<ActionType>();
+  const tableRef = useRef<any>();
+  let [open, setOpen] = useState<any>(null); //新增作者
+  let [editValues, setEditValues] = useState<any>({});
+  let appPageListApi = useAjax((params) => appPageList(params), { type: 'noPage' });
+  let configAppPagesApi = useAjax((params) => configAppPages(params));
+
+  // 编辑
+  const edit = (item: any) => {
+    setEditValues(item);
+    setTimeout(() => {
+      formRef?.current?.setFieldsValue({ ...item, appPageConfigDTOList: item.appPageVOList });
+    }, 100);
+    setOpen(true);
+  };
+  // 新增 or 编辑
+  const submit = async () => {
+    let values = await formRef.current?.validateFields()
+    configAppPagesApi.run(values).then((res) => {
+      if (res.code === 200) {
+        actionRef?.current?.reload();
+        message.success('操作成功!');
+        closeForm(false);
+      }
+    });
+  };
+  // 关闭表单弹窗和重置表单内容
+  const closeForm = (b: boolean, values?: any) => {
+    if (!b) {
+      setEditValues({});
+      formRef?.current?.resetFields?.();
+      setOpen(b);
+    } else {
+    }
+  };
+  // 刷新页面
+  const reloadList = () => {
+    actionRef?.current?.reload();
+  }
+  // 添加页面
+  const openAdd = (id: any) => {
+    tableRef?.current?.openMoadl(id)
+  }
+  return (
+    <PageContainer>
+      <ProTable<any, any>
+        headerTitle={'页面模板列表'}
+        actionRef={actionRef}
+        rowKey={(r) => r.id}
+        search={{
+          labelWidth: 120,
+        }}
+        request={async (params) => {
+          return await appPageListApi.run(params);
+        }}
+        scroll={{ x: 'auto' }}
+        toolBarRender={() => {
+          return [
+            <Button
+              type="primary"
+              onClick={() => {
+                setOpen(true);
+              }}
+            >
+              <PlusCircleOutlined />
+              新增页面模板
+            </Button>,
+          ];
+        }}
+        columns={columns(edit)}
+        // 页面列表
+        expandable={{
+          defaultExpandedRowKeys: [0],
+          rowExpandable: (record) => record?.appPageVOList?.length > 0,
+          expandRowByClick: true,
+          expandedRowRender: (record) => {
+            return <Table
+              columns={childrenColumns(openAdd)}
+              dataSource={record.appPageVOList}
+              rowKey={(r) => r.id}
+              pagination={false}
+              size='small'
+              bordered
+              // 页面组件列表
+              expandable={{
+                rowExpandable: (record) => record?.componentList?.length > 0,
+                expandRowByClick: true,
+                expandedRowRender: (record) => {
+                  return <MimiModule data={record?.componentList} ref={tableRef} reload={reloadList} />
+                }
+              }}
+            />
+          },
+        }}
+      // bordered
+      />
+      <Modal
+        title={!editValues?.templateName ? '新增页面模板' : '编辑页面模板'}
+        width={"55%"}
+        open={open}
+        onCancel={() => { closeForm(false) }}
+        loading={appPageListApi?.loading}
+        onOk={submit}
+      >
+        <FormComp ref={formRef} />
+      </Modal>
+    </PageContainer>
+  );
+};
+export default Page;

+ 113 - 0
src/pages/distribution/miniprogram/pagesManage/tableConfig.tsx

@@ -0,0 +1,113 @@
+import { ProColumns } from '@ant-design/pro-components';
+import { Badge, Button, Popconfirm, Space, TableColumnsType } from 'antd';
+
+export const columns = (edit: (params: any) => void): ProColumns<any>[] => {
+  return [
+    {
+      title: '模板名称',
+      dataIndex: 'templateName',
+      key: 'templateName',
+      align: 'center',
+      ellipsis: true,
+      hideInSearch: true,
+    },
+    {
+      title: '操作',
+      dataIndex: 'cz',
+      key: 'cz',
+      width: 160,
+      align: 'center',
+      className: 'table_fixed',
+      hideInSearch: true,
+      render: (a: any, b: any) => {
+        return (
+          <Space>
+            <Button
+              onClick={() => {
+                edit(b);
+              }}
+              type="link"
+            >
+              编辑
+            </Button>
+          </Space>
+        );
+      },
+    },
+  ];
+};
+
+export const childrenColumns = (openAdd:(id:any)=>void): TableColumnsType<any> => {
+  return [
+    {
+      title: "ID",
+      dataIndex: 'id',
+      align: "center",
+    },
+    {
+      title: "页面名称",
+      dataIndex: 'pageName',
+      align: "center",
+    },
+    {
+      title: "页面描述",
+      dataIndex: 'pageDesc',
+      align: "center",
+    },
+    {
+      title: "页面路径",
+      dataIndex: 'pagePath',
+      align: "center",
+    },
+    {
+      title: "分享图片",
+      dataIndex: 'sharePicUrl',
+      align: "center",
+    },
+    {
+      title: "分享标题",
+      dataIndex: 'shareTitles',
+      align: "center",
+    },
+    {
+      title: "是否阅读内容",
+      dataIndex: 'readingContent',
+      align: "center",
+      render: (a) => {
+        return <Badge status={a ? "success" : "error"} text={a ? "是" : "否"} />
+      }
+    },
+    {
+      title: "是否支持组件配置",
+      dataIndex: 'enabledComponent',
+      align: "center",
+      render: (a) => {
+        return <Badge status={a ? "success" : "error"} text={a ? "是" : "否"} />
+      }
+    },
+    {
+      title: '操作',
+      dataIndex: 'cz',
+      key: 'cz',
+      width: 160,
+      align: 'center',
+      className: 'table_fixed',
+      render: (a: any, b: any) => {
+        return (
+          <Space>
+            <Button
+              onClick={(e) => {
+                e.stopPropagation()
+                openAdd(b.id);
+              }}
+              type="link"
+              disabled={!b?.enabledComponent}
+            >
+              新增组件
+            </Button>
+          </Space>
+        );
+      },
+    },
+  ]
+}

+ 36 - 2
src/pages/distribution/miniprogram/weChatInfo/formConfig.tsx

@@ -2,6 +2,7 @@ import { ProFormColumnsType } from '@ant-design/pro-components';
 function formConfig(
   enumList?: { [key: string]: any },
   getWechatMchAll?: any[],
+  pageList?: any[]
 ): ProFormColumnsType<{
   name: string;
   state: string;
@@ -37,6 +38,7 @@ function formConfig(
       title: '商户',
       dataIndex: 'mchId',
       valueType: 'select',
+      fieldProps: { showSearch: true, placeholder: '请选择商户' },
       formItemProps: {
         style: { marginBottom: 10 },
         rules: [
@@ -86,8 +88,10 @@ function formConfig(
       },
     },
     {
-      title: '小程序首页链接',
-      dataIndex: 'homePage',
+      title: '小程序页面模板',
+      dataIndex: 'templateName',
+      fieldProps: { showSearch: true, placeholder: '请选择小程序页面模板' },
+      valueType: 'select',
       formItemProps: {
         style: { marginBottom: 10 },
         rules: [
@@ -97,6 +101,36 @@ function formConfig(
           },
         ],
       },
+      valueEnum: () => {
+        let arr = pageList || [];
+        return arr ? new Map([...arr]?.map(({ templateName }: any) => [templateName, templateName])) : {};
+      }
+    },
+    {
+      valueType: 'dependency',
+      name: ['templateName'],
+      columns: ({ templateName }) => {
+        return [
+          {
+            title: '小程序首页链接',
+            dataIndex: 'homePage',
+            hideInForm: !templateName,
+            formItemProps: {
+              style: { marginBottom: 10 },
+              rules: [
+                {
+                  required: true,
+                  message: '此项为必填项',
+                },
+              ],
+            },
+            valueEnum: () => {
+              let arr = pageList?.find(item => item.templateName === templateName)?.appPageVOList || [];
+              return arr ? new Map([...arr]?.map(({ pagePath, pageName }: any) => [pagePath, pageName])) : {};
+            }
+          },
+        ]
+      },
     },
     {
       title: '小程序版本号',

+ 4 - 1
src/pages/distribution/miniprogram/weChatInfo/index.tsx

@@ -22,6 +22,7 @@ import { Button, message } from 'antd';
 import { useCallback, useEffect, useRef, useState } from 'react';
 import formConfig from './formConfig';
 import { columns } from './tableConfig';
+import { appPageList } from '@/services/distribution/pagesManage';
 
 type DataItem = {
   name: string;
@@ -41,11 +42,13 @@ const Page: React.FC = () => {
   let WxAppInfoPageList = useAjax((params) => apiWxAppInfoPageList(params), { type: 'table' }); //微信小程序分页列表
   let WxAppInfoRemove = useAjax((distributorId) => apiWxAppInfoRemove(distributorId)); //小程序删除
   let getWechatMchAll = useAjax(() => wechatMchAll()); //商户列表
+  let appPageListApi = useAjax((params) => appPageList(params), { type: 'noPage' });//页面模板列表
   let WxAppInfoWxAppConfigAddOrEdit = useAjax((distributorId) =>
     apiWxAppInfoWxAppConfigAddOrEdit(distributorId),
   ); //指派
   let DistributorInfoList = useAjax((params) => apiDistributorInfoList(params)); //分销商列表
   useEffect(() => {
+    appPageListApi.run()
     getWechatMchAll.run();
   }, []);
   // 删除
@@ -161,7 +164,7 @@ const Page: React.FC = () => {
         rowProps={{ gutter: [10, 10] }}
         layout="horizontal"
         onFinish={submit}
-        columns={formConfig(state?.enumList, getWechatMchAll?.data?.data)}
+        columns={formConfig(state?.enumList, getWechatMchAll?.data?.data,appPageListApi?.data?.data)}
         loading={WxAppInfoUpdate?.loading || WxAppInfo?.loading}
       />
       {/*指派  */}

+ 8 - 0
src/pages/distribution/miniprogram/weChatInfo/tableConfig.tsx

@@ -42,6 +42,14 @@ export const columns = (
       ellipsis: true,
       align: 'center',
     },
+    {
+      title: '小程序页面模板',
+      dataIndex: 'templateName',
+      key: 'templateName',
+      width: 80,
+      ellipsis: true,
+      align: 'center',
+    },
     {
       title: '小程序首页链接',
       dataIndex: 'homePage',

+ 35 - 0
src/services/distribution/pagesManage/index.tsx

@@ -0,0 +1,35 @@
+import { api } from '@/services/api';
+import { request } from '@umijs/max';
+
+type Data = {
+  templateName: string,
+  appPageConfigDTOList: {
+    id?: number,
+    "pageName": string,
+    "pageDesc": string,
+    "pagePath": string,
+    "readingContent": boolean,
+    "sharePicUrl": string,
+    "shareTitles": string,
+    "enabledComponent": boolean
+  }[]
+}
+/**
+ * 新增修改页面模板
+ * @param id
+ */
+export async function configAppPages(data: Data) {
+  return request(api + `/bookDistributionPlatform/admin/appPage/configAppPages`, {
+    method: 'POST',
+    data,
+  });
+}
+/**
+ * 页面模板列表
+ * @param id
+ */
+export async function appPageList(params?: any) {
+  return request(api + `/bookDistributionPlatform/admin/appPage/appPageList`, {
+    method: 'GET'
+  });
+}