Forráskód Böngészése

feat: 新增申请管理页面

liaojiaxing 2 hónapja
szülő
commit
afbfd8fe08
4 módosított fájl, 344 hozzáadás és 14 törlés
  1. 5 0
      .umirc.ts
  2. 67 0
      src/api/apply.ts
  3. 249 0
      src/pages/apply/index.tsx
  4. 23 14
      src/pages/detail/index.tsx

+ 5 - 0
.umirc.ts

@@ -67,6 +67,11 @@ export default defineConfig({
       component: 'ai',
       layout: false
     },
+    {
+      path: '/apply',
+      component: 'apply',
+      layout: false
+    },
     {
       path: '*',
       component: '404',

+ 67 - 0
src/api/apply.ts

@@ -0,0 +1,67 @@
+import { request } from "umi";
+import type { commonParams } from "@/api/index";
+
+/**
+ * 获取咨询申请列表
+ * @param commonParams
+ * @returns
+ */
+export const GetApplyList = (data: commonParams) => {
+  return request("/api/appStore/consultationForm/list", {
+    method: "POST",
+    data,
+  });
+};
+
+/**
+ * 获取咨询申请详情
+ * @param {id: string}
+ * @returns
+ */
+export const GetApplyDetail = (data: {id: string}) => {
+  return request("/api/appStore/consultationForm/detail", {
+    method: "POST",
+    data,
+  });
+};
+
+/**
+ * 提交咨询申请
+ * @param ApplyItem
+ * @returns
+ */
+export const SubmitApply = (data: ApplyItem) => {
+  return request("/api/appStore/consultationForm/add", {
+    method: "POST",
+    data,
+  });
+};
+
+/**
+ * 处理咨询申请
+ * @param ApplyItem
+ * @returns
+ */
+export const HandleApply = (data: ApplyHandle) => {
+  return request("/api/appStore/consultationForm/process", {
+    method: "POST",
+    data,
+  });
+};
+
+export type ApplyItem = {
+  name: string;
+  tel: string;
+  companyName: string;
+  companySize: string;
+  jobTitle: string;
+  templateId: string;
+  // 0: 应用模版 1: 模块模板
+  type: number;
+}
+
+export type ApplyHandle = {
+  id: string;
+  status: number;
+  processRemark: string;
+}

+ 249 - 0
src/pages/apply/index.tsx

@@ -0,0 +1,249 @@
+import { useState, useRef, useMemo } from "react";
+import {
+  ActionType,
+  ProColumns,
+  ModalForm,
+  ProDescriptions,
+  ProFormSelect,
+  ProFormTextArea,
+} from "@ant-design/pro-components";
+import { ProTable } from "@ant-design/pro-components";
+import { Tag, message, Modal, Skeleton } from "antd";
+import { useRequest } from "umi";
+import { GetApplyList, GetApplyDetail, HandleApply } from "@/api/apply";
+
+const handleStatusEnum = {
+  0: {
+    text: "待审核",
+    status: "default",
+  },
+  1: {
+    text: "跟踪中",
+    status: "processing",
+  },
+  2: {
+    text: "已购买",
+    status: "success",
+  },
+  3: {
+    text: "未购买",
+    status: "error",
+  },
+};
+
+export default () => {
+  const actionRef = useRef<ActionType>();
+  const [openDetail, setOpenDetail] = useState(false);
+  const [openProcess, setOpenProcess] = useState(false);
+  const [processId, setProcessId] = useState<string>("");
+
+  const { data, loading, run } = useRequest(GetApplyDetail, {
+    defaultParams: [{ id: "" }],
+    manual: true,
+  });
+
+  const columns: ProColumns<any>[] = [
+    {
+      title: "客户名称",
+      dataIndex: "name",
+      ellipsis: true,
+    },
+    {
+      title: "联系方式",
+      dataIndex: "tel",
+      ellipsis: true,
+      copyable: true,
+    },
+    {
+      title: "企业名称",
+      dataIndex: "companyName",
+      ellipsis: true,
+    },
+    {
+      title: "模版类型",
+      dataIndex: "type",
+      search: false,
+      renderText: (text) => {
+        return text === 0 ? "应用模版" : "模块模版";
+      },
+    },
+    {
+      title: "处理状态",
+      dataIndex: "status",
+      valueType: "select",
+      valueEnum: handleStatusEnum,
+    },
+    {
+      title: "备注",
+      dataIndex: "processRemark",
+      search: false,
+      ellipsis: true,
+    },
+    {
+      title: "申请时间",
+      dataIndex: "createTime",
+      search: false,
+    },
+    {
+      title: "最后处理时间",
+      dataIndex: "processTime",
+      search: false,
+    },
+    {
+      title: "操作",
+      valueType: "option",
+      key: "option",
+      width: 180,
+      render: (text, record, _,) => [
+        <a key="edit" onClick={() => showDetail(record.id)}>
+          详情
+        </a>,
+        <a
+          target="_blank"
+          rel="noopener noreferrer"
+          key="view"
+          onClick={() => {
+            setProcessId(record.id);
+            setOpenProcess(true);
+          }}
+        >
+          处理
+        </a>,
+      ],
+    },
+  ];
+
+  const showDetail = (id: string) => {
+    setOpenDetail(true);
+    run({ id: id });
+  };
+
+  const handleProcessFinish = async (values: any) => {
+    await HandleApply({
+      ...values,
+      status: Number(values.status),
+      id: processId,
+    });
+    message.success('处理成功');
+    actionRef.current?.reload();
+    return true;
+  }
+
+  return (
+    <>
+      <ProTable
+        columns={columns}
+        actionRef={actionRef}
+        cardBordered
+        headerTitle="应用/模版申请列表"
+        request={async (params, sort, filter) => {
+          console.log(params, sort, filter);
+          const isOnMarket =
+            params?.isOnMarket === "on"
+              ? 1
+              : params?.isOnMarket === "off"
+                ? 0
+                : undefined;
+          const res = await GetApplyList({
+            currentPage: params.current || 1,
+            pageSize: params.pageSize || 10,
+            filters: [
+              { name: "name", value: params?.name },
+              { name: "tel", value: params?.tel },
+              { name: "companyName", value: params?.companyName },
+              { name: "status", value: params?.status },
+              { name: "isOnMarket", value: isOnMarket },
+              { name: "isDel", value: 0 },
+            ],
+          });
+          const data = res?.result || {};
+          return {
+            data: data.model || [],
+            success: true,
+            total: data.totalCount || 0,
+          };
+        }}
+        columnsState={{
+          persistenceKey: "shalu-marketplace",
+          persistenceType: "localStorage",
+          defaultValue: {
+            option: { fixed: "right", disable: true },
+          },
+        }}
+        rowKey="id"
+        search={{
+          labelWidth: "auto",
+        }}
+        options={{
+          setting: {
+            listsHeight: 400,
+          },
+        }}
+        pagination={{
+          pageSize: 10,
+        }}
+        dateFormatter="string"
+      />
+
+      {/* 详情弹窗 */}
+      <Modal
+        open={openDetail}
+        width={800}
+        footer={null}
+        onCancel={() => setOpenDetail(false)}
+      >
+        <Skeleton loading={loading}>
+          <ProDescriptions
+            title="基本信息"
+            column={2}
+            dataSource={data?.result || {}}
+          >
+            <ProDescriptions.Item label="申请名称" dataIndex="name" />
+            <ProDescriptions.Item label="联系方式" dataIndex="tel" copyable />
+            <ProDescriptions.Item label="公司名称" dataIndex="companyName" />
+            <ProDescriptions.Item label="公司规模" dataIndex="companySize" />
+            <ProDescriptions.Item label="职位名称" dataIndex="jobTitle" />
+            <ProDescriptions.Item label="申请时间" dataIndex="createTime" />
+          </ProDescriptions>
+          <ProDescriptions
+            className="mt-12px"
+            title="申请产品"
+            column={2}
+            dataSource={data?.result || {}}
+          >
+            <ProDescriptions.Item
+              label="应用类型"
+              dataIndex="type"
+              renderText={(text) => (text === 0 ? "应用模版" : "模块模版")}
+            />
+            <ProDescriptions.Item label="模版名称" dataIndex="name" />
+          </ProDescriptions>
+        </Skeleton>
+      </Modal>
+
+      {/* 处理弹窗 */}
+      <ModalForm
+        open={openProcess}
+        onOpenChange={setOpenProcess}
+        width={440}
+        onFinish={handleProcessFinish}
+      >
+        <ProFormSelect
+          name="status"
+          label="处理结果"
+          rules={[{ required: true, message: "请选择处理结果" }]}
+          valueEnum={{
+            1: handleStatusEnum[1],
+            2: handleStatusEnum[2],
+            3: handleStatusEnum[3],
+          }}
+        />
+        <ProFormTextArea
+          name="processRemark"
+          label="处理备注"
+          rules={[{ required: true, message: "请输入处理备注" }]}
+        />
+      </ModalForm>
+    </>
+  );
+};

+ 23 - 14
src/pages/detail/index.tsx

@@ -1,4 +1,4 @@
-import { Button, Form, Image, Input, Modal, Select, Skeleton, Breadcrumb } from "antd";
+import { Button, Form, Image, Input, Modal, Select, Skeleton, Breadcrumb, message, notification } from "antd";
 import type { BreadcrumbProps } from "antd";
 import { useMemo, useState } from "react";
 import { useParams, useRequest, history } from "umi";
@@ -6,18 +6,12 @@ import { GetAppDetail } from "@/api/appStore";
 import { GetTemplateDetail } from "@/api/templateStore";
 import styles from "./index.less";
 import { LeftOutlined } from "@ant-design/icons";
+import { SubmitApply } from "@/api/apply";
 
 export default function detail() {
   const [showAdvisory, setShowAdvisory] = useState(false);
   const [form] = Form.useForm();
 
-  const handleSubmit = () => {
-    form.validateFields().then((values) => {
-
-      setShowAdvisory(false);
-    });
-  };
-
   const { id, type } = useParams();
 
   const { data, loading } = useRequest<{result: any}>(type === 'application' ? GetAppDetail : GetTemplateDetail, {
@@ -36,6 +30,21 @@ export default function detail() {
     history.back();
   }
 
+  // 提交申请
+  const handleSubmit = () => {
+    form.validateFields().then(async (values) => {
+      await SubmitApply({
+        ...values,
+        type: type === 'application' ? 0 : 1,
+        templateId: id,
+      });
+      notification.success({
+        message: '您的申请已提交,后续会有专员与您联系!~',
+      });
+      setShowAdvisory(false);
+    });
+  };
+
   const breadcrumbItems: BreadcrumbProps['items'] = useMemo(() => {
     return [
       { key: 'all', title: <a onClick={handleBack}><LeftOutlined/><span className="m-l-4px">返回</span></a>},
@@ -85,7 +94,7 @@ export default function detail() {
         
       </div>
       <Modal title="购买咨询" width={500} open={showAdvisory} onCancel={() => setShowAdvisory(false)} onOk={handleSubmit}>
-        <Form labelCol={{ span: 5 }} autoComplete="off" form={form}>
+        <Form labelCol={{ span: 6 }} autoComplete="off" form={form}>
           <Form.Item
             label="如何称呼您?"
             name="name"
@@ -95,15 +104,15 @@ export default function detail() {
           </Form.Item>
           <Form.Item
             label="联系方式"
-            name="phone"
-            rules={[{ required: true, message: "请输入您的联系方式!" }]}
+            name="tel"
+            rules={[{ required: true, message: "请输入您的联系方式!", max: 20 }]}
           >
             <Input placeholder="请输入" maxLength={20} />
           </Form.Item>
-          <Form.Item label="公司名称" name="company">
+          <Form.Item label="公司名称" name="companyName">
             <Input placeholder="请输入" maxLength={100} />
           </Form.Item>
-          <Form.Item label="企业规模" name="scale">
+          <Form.Item label="企业规模" name="companySize">
             <Select
               placeholder="请选择"
               options={[
@@ -114,7 +123,7 @@ export default function detail() {
               ]}
             />
           </Form.Item>
-          <Form.Item label="您的职务" name="position">
+          <Form.Item label="您的职务" name="jobTitle">
             <Input placeholder="请输入" maxLength={20} />
           </Form.Item>
         </Form>