shenwu 7 months ago
parent
commit
890a8b758c

+ 2 - 2
config/config.ts

@@ -1,6 +1,6 @@
 // https://umijs.org/config/
 import { defineConfig } from '@umijs/max';
-import { join,resolve } from 'path';
+import { join, resolve } from 'path';
 import defaultSettings from './defaultSettings';
 import proxy from './proxy';
 import routes from './routes';
@@ -10,7 +10,7 @@ let isBuild = process.env.npm_lifecycle_event?.includes("build")
 export default defineConfig({
   // favicons:['../public/logo.svg'],//浏览器tab栏上的logo
   history: {
-    type: 'hash'
+    type: 'browser'
   },
   /**
    * @name 开启 hash 模式

+ 15 - 0
miniApp/adBack/index.html

@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Document</title>
+</head>
+<body>
+    <script>
+        window.onload=()=>{
+            location.href = location.href.replace('https://testdistribution.zanxiangwl.com/',"https://testdistribution.zanxiangwl.com/#/")
+        }
+    </script>
+</body>
+</html>

+ 1 - 1
src/app.tsx

@@ -22,7 +22,7 @@ export async function getInitialState(): Promise<{
   loading?: boolean;
   menuType: "distributor" | "miniApp",
   navTheme?: "2" | "3",
-  selectApp?: { appId: string, id: string, appName: string, appType: number, appCategory: 1 | 2 } | null,
+  selectApp?: { appId: string, id: string, appName: string, appType: number, appCategory: 1 | 2 ,appKey:string} | null,
   token: any,
 }> {
   // 如果不是登录页面,执行

+ 34 - 0
src/components/DownLoadImg/index.tsx

@@ -0,0 +1,34 @@
+
+import { DownloadOutlined } from '@ant-design/icons'
+import {Image, Tooltip} from 'antd'
+import React from 'react'
+/**
+ * 图片预览并支持下载
+ * @param props
+ * @param props.imgUrl 图片地址
+ * @param props.style 图片样式
+ * */ 
+function DownLoadImg(props:{imgUrl:string,style:React.CSSProperties}){
+    let {imgUrl,style} = props
+    return <Image src={imgUrl} style={style} preview={{
+        toolbarRender: (originalNode) => {
+            return React.cloneElement(
+                originalNode,
+                {
+                    // 保留原有的属性
+                    ...originalNode.props
+                },
+                <>
+                    {originalNode.props.children}
+                    <Tooltip title="下载">
+                        <div style={{ width: 22, marginLeft: 12 }}>
+                            <a href={imgUrl}><DownloadOutlined style={{ fontSize: 18 }} /></a>
+                        </div>
+                    </Tooltip>
+                </>
+            )
+        }
+    }} />
+}
+
+export default DownLoadImg

+ 1 - 1
src/components/MenuChange.tsx

@@ -1,5 +1,5 @@
 import { useModel, history } from "@umijs/max"
-type Props = { menuType: "distributor" | "miniApp", children: any, data: { appId: string, id: string, appName: string, appType: number,appCategory:1|2 } | null }
+type Props = { menuType: "distributor" | "miniApp", children: any, data: { appId: string, id: string, appName: string, appType: number,appCategory:1|2,appKey:string } | null }
 //切换菜单展示
 const MenuChange: React.FC<Props> = (props) => {
     let { menuType, children, data } = props

+ 1 - 1
src/global.tsx

@@ -5,7 +5,7 @@ import { createFromIconfontCN } from '@ant-design/icons';
 import nocover from '../public/nocover.jpg'
 const { pwa } = defaultSettings;
 const isHttps = document.location.protocol === 'https:';
-export let scriptUrl = "//at.alicdn.com/t/c/font_4644725_zdmv8tw2lp.js"//线上icon
+export let scriptUrl = "//at.alicdn.com/t/c/font_4644725_pxyssjkzrz9.js"//线上icon
 // 自定义icon组件用于线上icon
 export const MyIcon = createFromIconfontCN({
   scriptUrl// 在 iconfont.cn 上生成

+ 5 - 3
src/pages/MiniApp/EmsCnpl/Auth/index.tsx

@@ -1,12 +1,14 @@
 import { PageContainer } from "@ant-design/pro-components"
 import { useAjax } from "@/Hook/useAjax"
 import { history, useModel } from "@umijs/max"
-import { Avatar, Image, Card, Col, message, Row, Space, Badge, Button, Empty } from "antd"
-import {  PlusOutlined, RedoOutlined } from "@ant-design/icons"
+import { Avatar, Image, Card, Col, message, Row, Space, Badge, Button, Empty, Tooltip } from "antd"
+import { DownloadOutlined, PlusOutlined, RedoOutlined } from "@ant-design/icons"
 import { authSuccess, getMpAccount, preAuth } from "@/services/miniApp/emsCnpl"
 import { useEffect, useState } from "react"
 import { searchToObj } from "@/utils"
 import { Typography } from 'antd';
+import React from "react"
+import DownLoadImg from "@/components/DownLoadImg"
 const { Title, Text } = Typography;
 const Page: React.FC = () => {
     let { initialState } = useModel("@@initialState")
@@ -83,7 +85,7 @@ const Page: React.FC = () => {
                     </Col>
                     <Col span={6}>
                         <Title level={5} style={{ marginBottom: 0 }}>二维码</Title>
-                        <Image src={data?.qrcodeUrl} style={{ width: 25 }} />
+                        <DownLoadImg imgUrl={data?.qrcodeUrl} style={{ width: 35 }} />
                     </Col>
                     <Col span={6}>
                         <Title level={5} style={{ marginBottom: 0 }}>授权状态</Title>

+ 52 - 17
src/pages/MiniApp/EntWeChat/Auth/index.tsx

@@ -1,43 +1,74 @@
-import { PageContainer, ProTable } from "@ant-design/pro-components"
+import { ActionType, PageContainer, ProTable } from "@ant-design/pro-components"
 import { columns } from "./tableConfig"
 import { useAjax } from "@/Hook/useAjax"
 import { useModel } from "@umijs/max"
-import { getAllAvailableKfs, getAllBindKfs } from "@/services/miniApp/entWeChat"
-import { Button, Modal, Space, Tag } from "antd"
+import { configUser, getAllAvailableKfs, getAllBindKfs, revoke } from "@/services/miniApp/entWeChat"
+import { Button, message, Modal, Space, Tag } from "antd"
 import { PlusOutlined } from "@ant-design/icons"
-import { useState } from "react"
+import { useRef, useState } from "react"
 
 const Page: React.FC = () => {
     let { initialState } = useModel("@@initialState")
     let [open, setOpen] = useState(false)
+    const actionRef = useRef<ActionType>();
     const [editSelectedRow, setEditSelectedRow] = useState<any[]>([]); //选择
     let getList = useAjax((params) => getAllBindKfs(params), { type: 'table' })//已授权列表
     let getNoAuthList = useAjax((params) => getAllAvailableKfs(params), { type: 'table' })//未授权列表
-
+    let ConfigUser = useAjax((params) => configUser(params))//批量授权
+    let Revoke = useAjax((params) => revoke(params))//取消授权
+    let publicData = {
+        appId: initialState?.selectApp?.id || "",
+        appType: initialState?.selectApp?.appType || ""
+    }
+    // 批量授权
     const auth = () => {
-        if(editSelectedRow.length>0){
-
+        if (editSelectedRow.length > 0) {
+            let corpUserList = editSelectedRow?.map(item => ({ corpId: item.corpId, corpUserId: item.corpUserId }))
+            ConfigUser.run({
+                ...publicData,
+                corpUserList
+            }).then(res => {
+                if (res.code === 200) {
+                    setOpen(false)
+                    setEditSelectedRow([])
+                    message.success("授权成功!")
+                    actionRef?.current?.reload()
+                }
+            })
+        }
+    }
+    // 取消授权
+    const offAuth = (user: { corpId: any, corpUserId: any }) => {
+        let corpUserList: any = []
+        if (user) {
+            corpUserList = [{ corpId: user.corpId, corpUserId: user.corpUserId }]
+        }
+        if (corpUserList.length > 0) {
+            Revoke.run({ ...publicData, corpUserList }).then(res => {
+                if (res.code === 200) {
+                    message.success("取消授权成功!")
+                    actionRef?.current?.reload()
+                }
+            })
         }
     }
     return <PageContainer
         title={false}
     >
         <ProTable<any, any>
+            actionRef={actionRef}
             scroll={{ x: true }}
             toolBarRender={() => [
                 <Button type="primary" onClick={() => { setOpen(true) }} ><PlusOutlined />添加授权</Button>,
             ]}
-            params={{
-                appId: initialState?.selectApp?.id || "",
-                appType: initialState?.selectApp?.appType || ""
-            }}
+            params={publicData}
             headerTitle={"已授权客服号列表"}
-            rowKey={(r) => r.openid}
-            search={false}
+            rowKey={(r) => r.corpUserId}
+            search={{labelWidth:0}}
             request={async (params) => {
                 return await getList.run(params)
             }}
-            columns={columns(true)}
+            columns={columns(true,offAuth)}
         // bordered
         />
         <Modal
@@ -46,6 +77,8 @@ const Page: React.FC = () => {
             onCancel={() => { setOpen(false) }}
             onOk={auth}
             width={"40%"}
+            loading={ConfigUser?.loading}
+            destroyOnClose
         >
             <ProTable<any, any>
                 scroll={{ x: true, y: 600 }}
@@ -95,7 +128,7 @@ const Page: React.FC = () => {
                             </span>
                             <span style={{ color: 'red' }}>
                                 {selectedRows
-                                    ?.map((item: { corpName:string,name: string, corpUserId: any }) => <Tag
+                                    ?.map((item: { corpName: string, name: string, corpUserId: any }) => <Tag
                                         closable
                                         key={item?.corpUserId}
                                         onClose={() => {
@@ -108,9 +141,11 @@ const Page: React.FC = () => {
                     );
                 }}
                 toolBarRender={false}
-                headerTitle={false}
+                // headerTitle={false}
                 rowKey={(r) => r.corpUserId}
-                search={false}
+                search={{
+                    labelWidth: 0,
+                }}
                 request={async (params) => {
                     return await getNoAuthList.run(params)
                 }}

+ 37 - 8
src/pages/MiniApp/EntWeChat/Auth/tableConfig.tsx

@@ -1,6 +1,7 @@
+import DownLoadImg from "@/components/DownLoadImg";
 import { ProColumns } from "@ant-design/pro-components";
-import {Image } from 'antd'
-export const columns = (showNum?:boolean): ProColumns<any>[] => {
+import { Popconfirm } from 'antd'
+export const columns = (showNum?: boolean, offAuth?: (user: any) => void): ProColumns<any>[] => {
     return [
         {
             title: "企微名称",
@@ -14,7 +15,7 @@ export const columns = (showNum?:boolean): ProColumns<any>[] => {
             align: "center",
             hideInSearch: true,
         },
-     
+
         {
             title: "客服ID",
             dataIndex: 'corpUserId',
@@ -26,23 +27,51 @@ export const columns = (showNum?:boolean): ProColumns<any>[] => {
             dataIndex: 'customNum',
             align: "center",
             hideInSearch: true,
-            hideInTable:!showNum
+            hideInTable: !showNum
         },
         {
             title: "删除用户数",
             dataIndex: 'delCustomNum',
             hideInSearch: true,
             align: "center",
-            hideInTable:!showNum
+            hideInTable: !showNum
         },
         {
             title: "二维码",
             dataIndex: 'qrCode',
             hideInSearch: true,
             align: "center",
-            hideInTable:!showNum,
-            render:(_,row)=>{
-                return   <Image src={row?.qrCode} style={{ width: 25 }} />
+            hideInTable: !showNum,
+            render: (_, row) => {
+                return row.qrCode ? <DownLoadImg imgUrl={row.qrCode} style={{ width: 25 }} /> : "-"
+            }
+        },
+        {
+            title: "操作",
+            dataIndex: 'cz',
+            hideInSearch: true,
+            align: "center",
+            hideInTable: !showNum,
+            render: (_, row) => {
+                return <Popconfirm
+                    title={<div>是否要取消<strong style={{ color: 'red' }}>{row?.name}</strong>的授权</div>}
+                    onConfirm={() => { offAuth?.(row) }}
+                >
+                    <a >取消授权</a>
+                </Popconfirm>
+            }
+        },
+        // 搜索
+        {
+            title: "企微/客服名称",
+            dataIndex: 'corpNameOrCorpUserName',
+            hideInTable: true,
+            align: "center",
+            proFieldProps: {
+                placeholder: "请输入企微/客服名称搜索",
+            },
+            formItemProps: {
+                style: { width: 500 }
             }
         },
     ];

+ 39 - 0
src/pages/MiniApp/EntWeChat/Users/index.tsx

@@ -0,0 +1,39 @@
+import { PageContainer, ProTable } from "@ant-design/pro-components"
+import { columns } from "./tableConfig"
+import { useAjax } from "@/Hook/useAjax"
+import { useModel } from "@umijs/max"
+import { getAllKfs, getCustoms } from "@/services/miniApp/entWeChat"
+import { useEffect } from "react"
+
+const Page: React.FC = () => {
+    let { initialState } = useModel("@@initialState")
+    let getList = useAjax((params) => getCustoms(params), { type: 'table' })
+    let GetAllKfs = useAjax((params) => getAllKfs(params))
+    let publicData = {
+        appId: initialState?.selectApp?.id || "",
+        appType: initialState?.selectApp?.appType || ""
+    }
+    useEffect(()=>{
+        GetAllKfs.run(publicData)
+    },[])
+    return <PageContainer title={false}
+    >
+        <ProTable<any, any>
+            scroll={{ x: true}}
+            params={publicData}
+            headerTitle={"企微用户列表"}
+            rowKey={(r) => r.corpUserId}
+            search={{
+                labelWidth: 120,
+            }}
+            request={async (params) => {
+                if(params.corpId){
+                    return await getList.run(params)
+                }
+            }}
+            columns={columns(GetAllKfs?.data?.data)}
+        />
+    </PageContainer>
+
+}
+export default Page

+ 70 - 0
src/pages/MiniApp/EntWeChat/Users/tableConfig.tsx

@@ -0,0 +1,70 @@
+import { ProColumns } from "@ant-design/pro-components";
+import { useModel } from "@umijs/max";
+import { useState } from "react";
+export const columns = (list: any[]): ProColumns<any>[] => {
+    let {getEnum} = useModel("global")
+    let [users, setUsers] = useState<any>([])
+    return [
+        {
+            title: "企微名称",
+            dataIndex: 'corpName',
+            align: "center",
+            hideInSearch: true,
+        },
+        {
+            title: "客服名称",
+            dataIndex: 'corpUserName',
+            align: "center",
+            hideInSearch: true,
+        },
+        {
+            title: "客户名称",
+            dataIndex: 'remark',
+            hideInSearch: true,
+            align: "center",
+            render: (_, row) => {
+                return <span>{`${row?.remark}${row?.remarkCorpName ? "-" + row?.remarkCorpName : ""}`}</span>
+            }
+        },
+        {
+            title: "添加方式",
+            dataIndex: 'addWay',
+            align: "center",
+            hideInSearch: true,
+            valueEnum:getEnum("ADD_WAY","map")
+        },
+        {
+            title: "添加时间",
+            dataIndex: 'createTime',
+            align: "center",
+            hideInSearch: true,
+        },
+        // 搜索
+        {
+            title: "企微名称",
+            dataIndex: 'corpId',
+            align: "center",
+            valueType: 'select',
+            hideInTable: true,
+            fieldProps: {
+                placeholder:"请选择企业才能查询数据",
+                options: list?.map(item => ({ ...item, label: item.corpName, value: item.corpId })),
+                onChange: (a: any, row: any) => {
+                    setUsers(row ? row.corpUserList : [])
+                }
+            },
+        },
+        {
+            title: "客服名称",
+            dataIndex: 'corpUserId',
+            align: "center",
+            valueType: 'select',
+            hideInSearch: users?.length === 0,
+            hideInTable: true,
+            fieldProps: {
+                placeholder:"请选择对应企业客服才能查询数据",
+                options: users?.map((item: { name: any; corpUserId: any; }) => ({ ...item, label: item.name, value: item.corpUserId }))
+            },
+        },
+    ];
+}

+ 31 - 0
src/pages/MiniApp/EntWeChat/Welcome/content.less

@@ -0,0 +1,31 @@
+.content {
+    width: 40%;
+    margin: 0 auto;
+    display: flex;
+    flex-flow: column;
+    .box {
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+        margin-bottom: 20px;
+        .card {
+            width: 96%;
+        }
+        .btnBox {
+            width: 3%;
+            display: flex;
+            flex-flow: column;
+            >button{
+                margin-top: 6px;
+            }
+        }
+    }
+    .add {
+        width: 96%;
+    }
+    .footer{
+        display: flex;
+        justify-content: center;
+        margin-top: 20px;
+    }
+}

+ 137 - 0
src/pages/MiniApp/EntWeChat/Welcome/content.tsx

@@ -0,0 +1,137 @@
+import { Form } from "antd"
+import { forwardRef, useEffect, useImperativeHandle, } from "react"
+import { ProForm, ProFormSelect, ProFormText } from "@ant-design/pro-components"
+import { useModel } from "@umijs/max"
+import UploadImg from "@/components/uploadImg"
+
+
+const MyForm = forwardRef((props: { index: any, arr: any[], appId: any, set: (v: any) => void }, ref) => {
+    let { index, arr, appId, set } = props
+    let { getEnum } = useModel("global")
+    const [form] = Form.useForm();
+    // 将子组件的 ref 暴露给父组件
+    useImperativeHandle(ref, () => ({
+       form
+    }));
+    useEffect(() => {
+        console.log("arr[index]",arr[index])
+        form?.setFieldsValue(arr[index])
+    }, [arr])
+    return <ProForm
+        form={form}  // 绑定 form 实例
+        layout="horizontal"
+        submitter={false}
+        labelCol={{ span: 3 }}
+        onValuesChange={(changedValues: any, values: any) => {
+            console.log("values",values)
+            let newArrCopy: any = JSON.parse(JSON.stringify(arr));
+            newArrCopy[index] = values
+            set(newArrCopy)
+        }}
+    >
+        <Form.Item noStyle shouldUpdate>
+            {(form) => {
+                return (
+                    <ProFormSelect
+                        options={getEnum("MEDIA_TYPE", "arr")}
+                        width="md"
+                        name="mediaType"
+                        label={`消息类型`}
+                        onChange={(value) => {
+                            if (value === "miniprogram") {
+                                form?.setFieldsValue({ "miniprogramAppid": appId, "miniprogramPage": "pages/index/index" })
+                            }
+                        }}
+                        rules={[
+                            {
+                                required: true,
+                                message: '此项为必填项',
+                            }
+                        ]}
+                    />
+                );
+            }}
+        </Form.Item>
+        {/* 小程序卡片 */}
+        <Form.Item noStyle shouldUpdate>
+            {({ getFieldValue }) => {
+                let mediaType = getFieldValue("mediaType")
+                switch (mediaType) {
+                    case "text":
+                        return <>文本</>
+                    case "link":
+                        return <>图文</>
+                    case "miniprogram":
+                        return <div >
+                            <ProFormText
+                                label="标题"
+                                name="miniprogramTitle"
+                                rules={[
+                                    {
+                                        max: 21
+                                    },
+                                    {
+                                        required: true,
+                                        message: '此项为必填项',
+                                    }
+                                ]}
+                            />
+                            <ProFormText
+                                label="路径"
+                                name="miniprogramPage"
+                                rules={[
+                                    {
+                                        required: true,
+                                        message: '此项为必填项',
+                                    }
+                                ]}
+                                fieldProps={{ placeholder: "pages/index/index" }}
+                            />
+                            <Form.Item label="图片" name="miniprogramPicurl" rules={[
+                                {
+                                    required: true,
+                                    message: '此项为必填项',
+                                }
+                            ]}>
+                                <UploadImg
+                                    size={{
+                                        width: 500,
+                                        height: 400,
+                                        evalW: '!=',
+                                        evalH: '!=',
+                                        msg: '需要图片大小690*248',
+                                    }}
+                                    isEdit={true}
+                                    type="image"
+                                    isCropper
+                                />
+                            </Form.Item>
+                            <Form.Item hidden={true} >
+                                <ProFormText
+                                    label="小程序ID"
+                                    name="miniprogramAppid"
+                                    rules={[
+                                        {
+                                            max: 21
+                                        },
+                                        {
+                                            required: true,
+                                            message: '此项为必填项',
+                                        }
+                                    ]}
+                                />
+                            </Form.Item>
+                            <Form.Item hidden={true} >
+                                <ProFormText
+                                    label="ID"
+                                    name="id"
+                                />
+                            </Form.Item>
+                        </div>
+                }
+            }}
+        </Form.Item>
+    </ProForm>
+})
+
+export default MyForm

+ 185 - 0
src/pages/MiniApp/EntWeChat/Welcome/index.tsx

@@ -0,0 +1,185 @@
+import { PageContainer, ProTable } from "@ant-design/pro-components"
+import { useAjax } from "@/Hook/useAjax"
+import { useModel } from "@umijs/max"
+import { useEffect, useRef, useState } from "react"
+import styles from './content.less'
+import { Button, Card, message, Popconfirm, Space, Tooltip } from "antd"
+import { MyIcon } from "@/global"
+import { ArrowDownOutlined, ArrowUpOutlined, DeleteOutlined, EyeOutlined, PlusOutlined } from "@ant-design/icons"
+import MyForm from "./content"
+import { corpWelcomeMsgAddOrUpdate, corpWelcomeMsgList } from "@/services/miniApp/entWeChat"
+
+const Page: React.FC = () => {
+    let { initialState } = useModel("@@initialState")
+    let { getEnum } = useModel("global")
+    let [key, setKey] = useState(getEnum("WELCOME_TYPE", 'arr')?.[0]?.value?.toString())
+    let CorpWelcomeMsgList = useAjax((parmas) => corpWelcomeMsgList(parmas))
+    let CorpWelcomeMsgAddOrUpdate = useAjax((parmas) => corpWelcomeMsgAddOrUpdate(parmas))
+    let [arr, setArr] = useState<any[]>([])//存放数据
+    let [mediaContentList, setMediaContentList] = useState<any[]>([])//存放线上数据
+    const childRefs = useRef<any[]>([]);//存放每个MyForm的表单实例用于验证登操作
+    let publicData = {
+        appId: initialState?.selectApp?.id || "",
+        appType: initialState?.selectApp?.appType || ""
+    }
+    // 切换tab获取对应数据
+    useEffect(() => {
+        if (key) {
+            getConfig()
+        }
+    }, [key])
+    // 获取配置
+    let getConfig = () => {
+        CorpWelcomeMsgList.run({ ...publicData, welcomeType: key }).then(res => {
+            if (res.code === 200) {
+                let newArr = res?.data?.mediaContentList?.map((item: any) => {
+                    let obj: any = {}
+                    Object.keys(item).forEach(key => {
+                        if (item[key]) {
+                            obj[key] = item[key]
+                        }
+                    })
+                    return obj
+                })
+                setArr(newArr || [])
+                setMediaContentList(newArr || [])
+            }
+        })
+    }
+
+    // 新增
+    let add = () => {
+        setArr([...arr, {}])
+    }
+    // 删除
+    let del = (eq: number) => {
+        let newArr = arr.filter((item, index) => index !== eq)
+        setArr(newArr)
+    }
+    // 移动
+    let move = (moveEq: number, targetEq: number) => {
+        let newArrCopy: any = JSON.parse(JSON.stringify(arr));
+        [newArrCopy[moveEq], newArrCopy[targetEq]] = [newArrCopy[targetEq], newArrCopy[moveEq]];
+        console.log("newArrCopy", newArrCopy)
+        setArr(newArrCopy)
+    }
+    // 提交
+    let submit = async () => {
+        let isOk = true
+        console.log({
+            ...publicData,
+            welcomeType: key,
+            mediaContentList: arr
+        })
+        for (let item of childRefs?.current) {
+            try {
+                // 验证字段,返回 Promise
+                await item?.form?.validateFields();
+            } catch (errorInfo) {
+                console.log(1111111, errorInfo)
+                // 验证失败,errorInfo 会包含错误信息
+                isOk = false
+            }
+        }
+        if (isOk) {
+            CorpWelcomeMsgAddOrUpdate.run({
+                ...publicData,
+                welcomeType: key,
+                mediaContentList: arr
+            }).then(res => {
+                if (res.code === 200) {
+                    message.success("操作成功")
+                    getConfig()
+                }
+            })
+        } else {
+            message.error("还有必填数据未填写完成!")
+        }
+    }
+    console.log("mediaContentList", mediaContentList)
+    return <PageContainer
+        title={false}
+        tabList={getEnum("WELCOME_TYPE", 'arr')}
+        onTabChange={async (ak) => {
+            let isOk = true
+            for (let item of childRefs?.current) {
+                try {
+                    // 验证字段,返回 Promise
+                    await item?.form?.validateFields();
+                } catch (errorInfo) {
+                    // 验证失败,errorInfo 会包含错误信息
+                    isOk = false
+                }
+            }
+            if (isOk) {
+                if (JSON.stringify(mediaContentList) !== JSON.stringify(arr)) {
+                    message.warning("请先保存或取消当前未保存配置!!")
+                } else {
+                    setKey(ak)
+                }
+            } else {
+                message.error("请填写完整当前配置,或清除不需要的配置再切换")
+            }
+
+        }}
+        tabActiveKey={key}
+    >
+        <div className={styles.content}>
+            {
+                arr?.map((item, index) => {
+                    return <div key={index} className={styles.box}>
+                        <Card
+                            title={"消息" + (index + 1)}
+                            className={styles.card}
+                            extra={item.mediaType === 'miniprogram' && <Tooltip
+                                title={
+                                    <div style={{ border: "1px solid #dedee0", borderRadius: 5 }}>
+                                        <div style={{ color: "#00000073", margin: "0 14px 5px" }}>{initialState?.selectApp?.appName}</div>
+                                        <div style={{ color: "#000", margin: "0 14px 12px" }}>{item?.miniprogramTitle}</div>
+                                        <img src={item?.miniprogramPicurl} style={{ width: 200, height: 160, margin: "0 14px 12px" }} />
+                                        <div style={{ borderTop: "1px solid #ececed", color: "#b0b0b0", padding: "0 12px" }}>
+                                            <MyIcon type="icon-weixinxiaochengxu" /> 小程序
+                                        </div>
+                                    </div>
+                                }
+                                color={"#fff"}
+                                placement="bottom"
+                            >
+                                <a><EyeOutlined /> 预览</a>
+                            </Tooltip>}
+                        >
+                            <MyForm index={index} arr={arr} set={setArr} appId={initialState?.selectApp?.appKey} ref={(el) => childRefs.current[index] = el} />
+                        </Card>
+                        <div className={styles.btnBox}>
+                            <Popconfirm
+                                title="确定要删除!"
+                                onConfirm={() => { del(index) }}
+                            >
+                                <Button><DeleteOutlined /></Button>
+                            </Popconfirm>
+                            {index > 0 && <Button onClick={() => { move(index, index - 1) }}><ArrowUpOutlined /></Button>}
+                            {index !== arr.length - 1 && <Button onClick={() => { move(index, index + 1) }}><ArrowDownOutlined /></Button>}
+                        </div>
+                    </div>
+                })
+            }
+
+            <Button type="dashed" className={styles.add} onClick={add}><PlusOutlined />增加一条</Button>
+            <div className={styles.footer}>
+                <Space>
+                    <Button type="primary" onClick={submit} disabled={JSON.stringify(mediaContentList) === JSON.stringify(arr)}>保存</Button>
+                    <Popconfirm
+                        title="是否要取消当前未保存配置!"
+                        onConfirm={()=>{
+                            setArr(mediaContentList)
+                        }}
+                    >
+                        <Button disabled={JSON.stringify(mediaContentList) === JSON.stringify(arr)}>取消</Button>
+                    </Popconfirm>
+                </Space>
+            </div>
+        </div>
+    </PageContainer>
+
+}
+export default Page

+ 17 - 4
src/services/miniApp/entWeChat/index.tsx

@@ -17,7 +17,8 @@ type Params = {
     appId: string,
     appType: any,
     pageNum: number,//
-    pageSize: number
+    pageSize: number,
+    corpNameOrCorpUserName:string,//模糊搜索
 }
 /**已授权企微客服列表 */
 export async function getAllBindKfs(params: Params) {
@@ -35,8 +36,10 @@ export async function getAllAvailableKfs(params: Params) {
 }
 /**批量授权客服号给指定小程序 */
 export async function configUser(data: {
-    corpId: any,
-    corpUserIds: any[],
+    corpUserList: {
+        corpId:string,
+        corpUserId:string
+    }[],
     appId: any,
     appType: any
 }) {
@@ -48,7 +51,7 @@ export async function configUser(data: {
 /**取消授权 */
 export async function revoke(data: {
     corpId: any,
-    corpUserIds: any[],
+    corpUserList: any[],
     appId: any,
     appType: any
 }) {
@@ -57,6 +60,16 @@ export async function revoke(data: {
         data
     });
 }
+/**获取全部企业和客服 */
+export async function getAllKfs(params: {
+    appId: any,
+    appType: any
+}) {
+    return request(api + '/admin/corp/getAllKfs', {
+        method: 'GET',
+        params
+    });
+}
 
 
 /**欢迎语列表 */