chenlei 1 год назад
Родитель
Сommit
69770a6d1c

+ 16 - 0
src/api/collection.ts

@@ -0,0 +1,16 @@
+import { requestByGet, requestByPost } from "@dage/service";
+
+export const collectionApi = {
+  getList(data: any) {
+    return requestByPost("/api/cms/goods/pageList", data);
+  },
+  save(data: any) {
+    return requestByPost("/api/cms/goods/save", data);
+  },
+  delete(id: number) {
+    return requestByGet(`/api/cms/goods/remove/${id}`);
+  },
+  getDetail(id: string) {
+    return requestByGet(`/api/cms/goods/detail/${id}`);
+  },
+};

+ 16 - 0
src/api/exhibition.ts

@@ -0,0 +1,16 @@
+import { requestByGet, requestByPost } from "@dage/service";
+
+export const exhibitionApi = {
+  getList(data: any) {
+    return requestByPost("/api/cms/exhibition/pageList", data);
+  },
+  save(data: any) {
+    return requestByPost("/api/cms/exhibition/save", data);
+  },
+  delete(id: number) {
+    return requestByGet(`/api/cms/exhibition/remove/${id}`);
+  },
+  getDetail(id: string) {
+    return requestByGet(`/api/cms/exhibition/detail/${id}`);
+  },
+};

+ 3 - 0
src/api/index.ts

@@ -17,3 +17,6 @@ export * from "./log";
 export * from "./user";
 export * from "./banner";
 export * from "./information";
+export * from "./exhibition";
+export * from "./collection";
+export * from "./message";

+ 10 - 0
src/api/message.ts

@@ -0,0 +1,10 @@
+import { requestByGet, requestByPost } from "@dage/service";
+
+export const messageApi = {
+  getList(data: any) {
+    return requestByPost("/api/cms/message/pageList", data);
+  },
+  delete(id: number) {
+    return requestByGet(`/api/cms/message/remove/${id}`);
+  },
+};

+ 1 - 0
src/components/FormPageFooter/index.scss

@@ -14,6 +14,7 @@
     height: $height;
     background: white;
     border-top: 1px solid var(--border-color);
+    z-index: 1;
 
     > *:not(:first-child) {
       margin-left: 20px;

+ 14 - 0
src/pages/Collection/constants.ts

@@ -0,0 +1,14 @@
+export const LEVEL_TYPE = [
+  {
+    label: "一级",
+    value: "一级",
+  },
+  {
+    label: "二级",
+    value: "二级",
+  },
+  {
+    label: "三级",
+    value: "三级",
+  },
+];

+ 85 - 34
src/pages/Collection/create-or-edit/index.tsx

@@ -6,11 +6,13 @@ import {
   DageUpload,
   DageUploadConsumer,
   DageUploadProvider,
-  DageUploadType,
 } from "@dage/pc-components";
 import { DatePicker, Form, FormInstance, Input, Select } from "antd";
-import { useCallback, useRef, useState } from "react";
+import { useCallback, useEffect, useRef, useState } from "react";
 import { useNavigate, useParams } from "react-router-dom";
+import { LEVEL_TYPE } from "../constants";
+import { collectionApi } from "@/api";
+import { dayjs, formatDate } from "@dage/utils";
 
 export default function CollectionCreateOrEditPage() {
   const dageFileCheckboxRef = useRef<DageFileCheckboxMethods>(null);
@@ -19,10 +21,47 @@ export default function CollectionCreateOrEditPage() {
   const navigate = useNavigate();
   const params = useParams();
   const [loading, setLoading] = useState(false);
-  const richTxtRef = useRef<any>(null);
-  const [check, setCheck] = useState(false);
-  // 文件的code码
-  const [dirCode, setDirCode] = useState("");
+
+  const getDetail = useCallback(async () => {
+    setLoading(true);
+    try {
+      const {
+        entity: { thumb, publishDate, ...rest },
+        file,
+      } = await collectionApi.getDetail(params.id as string);
+
+      if (thumb) {
+        rest.thumb = [
+          {
+            uid: thumb,
+            url: `${process.env.REACT_APP_API_URL}${process.env.REACT_APP_IMG_PUBLIC}${thumb}`,
+            name: thumb,
+            status: "done",
+          },
+        ];
+      }
+      formRef.current?.setFieldsValue({
+        publishDate: dayjs(publishDate),
+        ...rest,
+      });
+      dageFileCheckboxRef.current?.setFileList(
+        file.map((i: any) => ({
+          uid: i.id + "",
+          url: `${process.env.REACT_APP_API_URL}${process.env.REACT_APP_IMG_PUBLIC}${i.filePath}`,
+          thumbUrl: `${process.env.REACT_APP_API_URL}${process.env.REACT_APP_IMG_PUBLIC}${i.filePath}`,
+          name: i.fileName,
+          dType: i.type,
+          status: "done",
+        }))
+      );
+    } finally {
+      setLoading(false);
+    }
+  }, [params.id]);
+
+  useEffect(() => {
+    !!params.id && getDetail();
+  }, [getDetail, params.id]);
 
   const handleCancel = useCallback(() => {
     navigate(-1);
@@ -31,12 +70,25 @@ export default function CollectionCreateOrEditPage() {
   const handleSubmit = useCallback(async () => {
     if (!(await formRef.current?.validateFields())) return;
 
-    const { banner = [], ...rest } = formRef.current?.getFieldsValue();
+    const {
+      thumb = [],
+      publishDate,
+      ...rest
+    } = formRef.current?.getFieldsValue();
 
     if (params.id) {
       rest.id = params.id;
     }
 
+    await collectionApi.save({
+      ...rest,
+      publishDate: formatDate(publishDate),
+      thumb: thumb[0].response ? thumb[0].response.filePath : thumb[0].name,
+      fileIds: fileList.current
+        .map((i) => (i.response ? i.response.id : i.uid))
+        .join(),
+    });
+
     handleCancel();
   }, [handleCancel, params]);
 
@@ -51,10 +103,16 @@ export default function CollectionCreateOrEditPage() {
         <DageUploadConsumer>
           {(data) => (
             <>
-              <Form ref={formRef} labelCol={{ span: 2 }}>
+              <Form
+                ref={formRef}
+                labelCol={{ span: 2 }}
+                initialValues={{
+                  dictLevel: LEVEL_TYPE[0].value,
+                }}
+              >
                 <Form.Item
                   label="标题"
-                  name="title"
+                  name="name"
                   rules={[{ required: true, message: "请输入内容" }]}
                 >
                   <Input
@@ -64,7 +122,7 @@ export default function CollectionCreateOrEditPage() {
                     showCount
                   />
                 </Form.Item>
-                <Form.Item label="时代" name="title">
+                <Form.Item label="时代" name="dictAge">
                   <Input
                     className="w220"
                     placeholder="请输入内容"
@@ -72,7 +130,7 @@ export default function CollectionCreateOrEditPage() {
                     showCount
                   />
                 </Form.Item>
-                <Form.Item label="质地" name="title">
+                <Form.Item label="质地" name="dictTexture">
                   <Input
                     className="w220"
                     placeholder="请输入内容"
@@ -80,23 +138,14 @@ export default function CollectionCreateOrEditPage() {
                     showCount
                   />
                 </Form.Item>
-                <Form.Item label="级别" name="type">
-                  <Select
-                    defaultValue="lucy"
-                    style={{ width: 220 }}
-                    options={[
-                      { value: "jack", label: "Jack" },
-                      { value: "lucy", label: "Lucy" },
-                      { value: "Yiminghe", label: "yiminghe" },
-                      { value: "disabled", label: "Disabled", disabled: true },
-                    ]}
-                  />
-                </Form.Item>
                 <Form.Item
-                  label="来源"
-                  name="title"
-                  rules={[{ required: true, message: "请输入内容" }]}
+                  label="级别"
+                  name="dictLevel"
+                  rules={[{ required: true, message: "请选择" }]}
                 >
+                  <Select style={{ width: 220 }} options={LEVEL_TYPE} />
+                </Form.Item>
+                <Form.Item label="来源" name="dictSource">
                   <Input
                     className="w220"
                     placeholder="请输入内容"
@@ -104,7 +153,7 @@ export default function CollectionCreateOrEditPage() {
                     showCount
                   />
                 </Form.Item>
-                <Form.Item label="简介" name="content">
+                <Form.Item label="简介" name="description">
                   <Input.TextArea
                     className="w450"
                     placeholder="请输入内容,最多200字"
@@ -115,13 +164,13 @@ export default function CollectionCreateOrEditPage() {
                 </Form.Item>
                 <Form.Item
                   label="封面图"
-                  name="banner"
+                  name="thumb"
                   rules={[{ required: true, message: "请上传封面图" }]}
                 >
                   <DageUpload
                     tips="支持png、jpg和jpeg格式;最多1张,最大20M"
                     action={
-                      process.env.REACT_APP_API_URL + "/api/cms/history/upload"
+                      process.env.REACT_APP_API_URL + "/api/cms/goods/upload"
                     }
                     maxSize={20}
                     maxCount={1}
@@ -129,8 +178,9 @@ export default function CollectionCreateOrEditPage() {
                 </Form.Item>
                 <Form.Item
                   label="文件类型"
-                  name="fileTypes"
+                  name="fileType"
                   rules={[
+                    { required: true, message: "" },
                     {
                       validator: (...args) => {
                         dageFileCheckboxRef.current!.validate(...args);
@@ -141,17 +191,18 @@ export default function CollectionCreateOrEditPage() {
                 >
                   <DageFileCheckbox
                     ref={dageFileCheckboxRef}
-                    hasMobileModel={true}
-                    action="https://sit-shgybwg.4dage.com/api/cms/goods/upload"
+                    action={
+                      process.env.REACT_APP_API_URL + "/api/cms/goods/upload"
+                    }
                     onFileChange={handleFileChange}
                   />
                 </Form.Item>
                 <Form.Item
                   label="发布日期"
-                  name="date"
+                  name="publishDate"
                   rules={[{ required: true, message: "请选择发布日期" }]}
                 >
-                  <DatePicker className="w220" />
+                  <DatePicker className="w220" format="YYYY-MM-DD" />
                 </Form.Item>
               </Form>
 

+ 90 - 32
src/pages/Collection/index.tsx

@@ -1,74 +1,136 @@
-import { Button, Form, FormInstance, Input, Radio, Select, Table } from "antd";
-import { useCallback, useMemo, useRef, useState } from "react";
+import { Button, Form, FormInstance, Input, Select, Table, Image } from "antd";
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
 import { debounce } from "lodash";
 import { DageTableActions } from "@dage/pc-components";
-import { useNavigate } from "react-router-dom";
+import { useNavigate, useSearchParams } from "react-router-dom";
+import { LEVEL_TYPE } from "./constants";
+import { collectionApi } from "@/api";
+
+const ALL_LEVEL_TYPE = [
+  {
+    label: "全部",
+    value: "",
+  },
+  ...LEVEL_TYPE,
+];
 
 const DEFAULT_PARAMS = {
   pageNum: 1,
   pageSize: 20,
+  searchKey: "",
+  dictLevel: ALL_LEVEL_TYPE[0].value,
 };
 
 export default function CollectionPage() {
   const navigate = useNavigate();
+  const [searchParams, setSearchParams] = useSearchParams();
   const formRef = useRef<FormInstance>(null);
   const [loading, setLoading] = useState(false);
   const [list, setList] = useState<[]>([]);
   const [params, setParams] = useState({
     ...DEFAULT_PARAMS,
+    searchKey: searchParams.get("searchKey") || "",
+    dictLevel: searchParams.get("dictLevel") || ALL_LEVEL_TYPE[0].value,
   });
   const [total, setTotal] = useState(0);
 
+  const getList = useCallback(async () => {
+    setLoading(true);
+    try {
+      const data = await collectionApi.getList(params);
+      setList(data.records);
+      setTotal(data.total);
+    } finally {
+      setLoading(false);
+    }
+  }, [params]);
+
+  const handleDelete = useCallback(
+    async (id: number) => {
+      await collectionApi.delete(id);
+      getList();
+    },
+    [getList]
+  );
+
   const COLUMNS = useMemo(() => {
     return [
       {
         title: "标题",
-        dataIndex: "title",
+        dataIndex: "name",
       },
       {
         title: "年代",
-        dataIndex: "nickName",
-      },
-      {
-        title: "类别",
-        dataIndex: "date",
+        dataIndex: "dictAge",
       },
       {
         title: "级别",
-        dataIndex: "date",
+        dataIndex: "dictLevel",
       },
       {
         title: "来源",
-        dataIndex: "date",
+        dataIndex: "dictSource",
       },
       {
         title: "封面",
-        dataIndex: "date",
+        render: (item: any) => {
+          return (
+            <Image
+              height={60}
+              src={`${process.env.REACT_APP_API_URL}${process.env.REACT_APP_IMG_PUBLIC}${item.thumb}`}
+            />
+          );
+        },
       },
       {
         title: "简介",
-        dataIndex: "date",
+        width: 250,
+        render: (item: any) => {
+          return <p className="limit-line line-2">{item.description}</p>;
+        },
       },
       {
         title: "发布日期",
-        dataIndex: "date",
+        dataIndex: "publishDate",
       },
       {
         title: "操作",
         render: (item: any) => {
-          return <DageTableActions onEdit={() => {}} onDelete={() => {}} />;
+          return (
+            <DageTableActions
+              onEdit={() => navigate(`/collection/edit/${item.id}`)}
+              onDelete={handleDelete.bind(undefined, item.id)}
+            />
+          );
         },
       },
     ];
-  }, []);
+  }, [navigate, handleDelete]);
+
+  useEffect(() => {
+    setSearchParams({
+      searchKey: params.searchKey,
+      dictLevel: params.dictLevel,
+    });
+  }, [params.searchKey, params.dictLevel, setSearchParams]);
+
+  useEffect(() => {
+    getList();
+  }, [getList]);
 
   const handleReset = useCallback(() => {
-    formRef.current?.resetFields();
+    setParams({ ...DEFAULT_PARAMS });
+    setTimeout(() => {
+      formRef.current?.resetFields();
+    });
   }, [formRef]);
 
   const debounceSearch = useMemo(
-    () => debounce((changedVal: unknown, vals: any) => {}, 500),
-    []
+    () =>
+      debounce((changedVal: unknown, vals: any) => {
+        setParams({ ...params, ...vals });
+      }, 500),
+    [params]
   );
 
   const paginationChange = useCallback(
@@ -80,21 +142,17 @@ export default function CollectionPage() {
 
   return (
     <div className="information">
-      <Form ref={formRef} layout="inline" onValuesChange={debounceSearch}>
-        <Form.Item label="搜索项" name="stage">
+      <Form
+        ref={formRef}
+        layout="inline"
+        initialValues={params}
+        onValuesChange={debounceSearch}
+      >
+        <Form.Item label="搜索项" name="searchKey">
           <Input placeholder="请输入" maxLength={10} showCount allowClear />
         </Form.Item>
-        <Form.Item label="级别" name="type">
-          <Select
-            defaultValue="lucy"
-            style={{ width: 220 }}
-            options={[
-              { value: "jack", label: "Jack" },
-              { value: "lucy", label: "Lucy" },
-              { value: "Yiminghe", label: "yiminghe" },
-              { value: "disabled", label: "Disabled", disabled: true },
-            ]}
-          />
+        <Form.Item label="级别" name="dictLevel">
+          <Select style={{ width: 220 }} options={ALL_LEVEL_TYPE} />
         </Form.Item>
         <Form.Item>
           <Button type="primary" onClick={() => navigate("/collection/create")}>

+ 14 - 0
src/pages/Exhibition/constants.ts

@@ -0,0 +1,14 @@
+export const TYPE_LIST = [
+  {
+    label: "常设展览",
+    value: "long",
+  },
+  {
+    label: "专题展览",
+    value: "topic",
+  },
+  {
+    label: "临时展览",
+    value: "temp",
+  },
+];

+ 194 - 0
src/pages/Exhibition/create-or-edit/index.tsx

@@ -0,0 +1,194 @@
+import { FormPageFooter, MemoSpinLoding } from "@/components";
+import {
+  DageUpload,
+  DageUploadConsumer,
+  DageUploadProvider,
+} from "@dage/pc-components";
+import { DatePicker, Form, FormInstance, Input, Select } from "antd";
+import { useCallback, useEffect, useRef, useState } from "react";
+import { useNavigate, useParams } from "react-router-dom";
+import RichText from "@/components/Z_RichText";
+import { dayjs, formatDate } from "@dage/utils";
+import { exhibitionApi } from "@/api";
+import { TYPE_LIST } from "../constants";
+
+export default function ExhibitionCreateOrEditPage() {
+  const formRef = useRef<FormInstance>(null);
+  const navigate = useNavigate();
+  const params = useParams();
+  const [loading, setLoading] = useState(false);
+  const richTxtRef = useRef<any>(null);
+  // 文件的code码
+  const [dirCode, setDirCode] = useState("");
+
+  const getDetail = useCallback(async () => {
+    setLoading(true);
+    try {
+      setDirCode(params.id as string);
+
+      const { thumb, publishDate, richText, ...rest } =
+        await exhibitionApi.getDetail(params.id as string);
+
+      formRef.current?.setFieldsValue({
+        publishDate: dayjs(publishDate),
+        fileIds: [
+          {
+            uid: thumb,
+            url: `${process.env.REACT_APP_API_URL}${process.env.REACT_APP_IMG_PUBLIC}${thumb}`,
+            name: thumb,
+          },
+        ],
+        ...rest,
+      });
+
+      richTxtRef.current.ritxtShowFu(richText);
+    } finally {
+      setLoading(false);
+    }
+  }, [params.id]);
+
+  useEffect(() => {
+    !!params.id && getDetail();
+  }, [getDetail, params.id]);
+
+  const handleCancel = useCallback(() => {
+    navigate(-1);
+  }, [navigate]);
+
+  const handleSubmit = useCallback(async () => {
+    if (!(await formRef.current?.validateFields())) return;
+
+    const { val, flag } = richTxtRef.current.fatherBtnOkFu();
+    const {
+      fileIds = [],
+      publishDate,
+      richText,
+      ...rest
+    } = formRef.current?.getFieldsValue();
+
+    if (flag) return;
+
+    if (params.id) {
+      rest.id = params.id;
+    }
+
+    await exhibitionApi.save({
+      ...rest,
+      publishDate: formatDate(publishDate),
+      richText: val,
+      thumb: fileIds[0].response
+        ? fileIds[0].response.filePath
+        : fileIds[0].name,
+    });
+
+    handleCancel();
+  }, [handleCancel, params]);
+
+  return (
+    <div style={{ position: "relative" }}>
+      {loading && <MemoSpinLoding />}
+      <DageUploadProvider>
+        <DageUploadConsumer>
+          {(data) => (
+            <>
+              <Form
+                ref={formRef}
+                labelCol={{ span: 2 }}
+                initialValues={{
+                  publishDate: dayjs(),
+                  type: TYPE_LIST[0].value,
+                }}
+              >
+                <Form.Item
+                  label="标题"
+                  name="name"
+                  rules={[{ required: true, message: "请输入内容" }]}
+                >
+                  <Input
+                    className="w450"
+                    placeholder="请输入内容,最多20字"
+                    maxLength={20}
+                    showCount
+                  />
+                </Form.Item>
+                <Form.Item
+                  label="类型"
+                  name="type"
+                  rules={[{ required: true, message: "请选择" }]}
+                >
+                  <Select style={{ width: 220 }} options={TYPE_LIST} />
+                </Form.Item>
+                <Form.Item label="位置" name="address">
+                  <Input
+                    className="w450"
+                    placeholder="请输入内容,最多20字"
+                    maxLength={20}
+                    showCount
+                  />
+                </Form.Item>
+                <Form.Item label="简介" name="description">
+                  <Input.TextArea
+                    className="w450"
+                    placeholder="请输入内容,最多100字"
+                    maxLength={100}
+                    showCount
+                    rows={3}
+                  />
+                </Form.Item>
+                <Form.Item
+                  label="正文"
+                  name="richText"
+                  rules={[{ required: true, message: "请输入正文" }]}
+                >
+                  <RichText
+                    myUrl="/api/cms/news/upload"
+                    ref={richTxtRef}
+                    dirCode={dirCode}
+                    isLook={false}
+                  />
+                </Form.Item>
+                <Form.Item
+                  label="发布日期"
+                  name="publishDate"
+                  rules={[{ required: true, message: "请选择发布日期" }]}
+                >
+                  <DatePicker className="w220" format="YYYY-MM-DD" />
+                </Form.Item>
+                <Form.Item
+                  label="封面图"
+                  name="fileIds"
+                  rules={[{ required: true, message: "请上传封面图" }]}
+                >
+                  <DageUpload
+                    tips="支持png、jpg和jpeg格式;最多1张,最大20M"
+                    action={
+                      process.env.REACT_APP_API_URL + "/api/cms/news/upload"
+                    }
+                    maxSize={20}
+                    maxCount={1}
+                  />
+                </Form.Item>
+                <Form.Item label="虚拟展厅" name="link">
+                  <Input
+                    className="w450"
+                    placeholder="请输入场景码,最多30个字"
+                    maxLength={20}
+                    showCount
+                  />
+                </Form.Item>
+              </Form>
+
+              {!loading && (
+                <FormPageFooter
+                  disabled={data?.uploading}
+                  onSubmit={handleSubmit}
+                  onCancel={handleCancel}
+                />
+              )}
+            </>
+          )}
+        </DageUploadConsumer>
+      </DageUploadProvider>
+    </div>
+  );
+}

+ 82 - 26
src/pages/Exhibition/index.tsx

@@ -1,62 +1,122 @@
-import { Button, Form, FormInstance, Input, Radio, Select, Table } from "antd";
-import { useCallback, useMemo, useRef, useState } from "react";
+import { Button, Form, FormInstance, Input, Select, Table, Image } from "antd";
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
 import { debounce } from "lodash";
 import { DageTableActions } from "@dage/pc-components";
-import { useNavigate } from "react-router-dom";
+import { useNavigate, useSearchParams } from "react-router-dom";
+import { TYPE_LIST } from "./constants";
+import { exhibitionApi } from "@/api";
 
 const DEFAULT_PARAMS = {
   pageNum: 1,
   pageSize: 20,
+  searchKey: "",
+  type: TYPE_LIST[0].value,
 };
 
 export default function InformationPage() {
   const navigate = useNavigate();
+  const [searchParams, setSearchParams] = useSearchParams();
   const formRef = useRef<FormInstance>(null);
   const [loading, setLoading] = useState(false);
   const [list, setList] = useState<[]>([]);
   const [params, setParams] = useState({
     ...DEFAULT_PARAMS,
+    searchKey: searchParams.get("searchKey") || "",
+    type: searchParams.get("type") || TYPE_LIST[0].value,
   });
   const [total, setTotal] = useState(0);
 
+  const getList = useCallback(async () => {
+    setLoading(true);
+    try {
+      const data = await exhibitionApi.getList(params);
+      setList(data.records);
+      setTotal(data.total);
+    } finally {
+      setLoading(false);
+    }
+  }, [params]);
+
+  useEffect(() => {
+    setSearchParams({
+      searchKey: params.searchKey,
+      type: params.type,
+    });
+  }, [params.searchKey, params.type, setSearchParams]);
+
+  useEffect(() => {
+    getList();
+  }, [getList]);
+
+  const handleDelete = useCallback(
+    async (id: number) => {
+      await exhibitionApi.delete(id);
+      getList();
+    },
+    [getList]
+  );
+
   const COLUMNS = useMemo(() => {
     return [
       {
         title: "展览标题",
-        dataIndex: "title",
+        dataIndex: "name",
       },
       {
         title: "展览类型",
-        dataIndex: "nickName",
+        render: (item: any) => {
+          return TYPE_LIST.find((i) => i.value === item.type)?.label;
+        },
       },
       {
         title: "展览封面",
-        dataIndex: "date",
+        render: (item: any) => {
+          return (
+            <Image
+              height={60}
+              src={`${process.env.REACT_APP_API_URL}${process.env.REACT_APP_IMG_PUBLIC}${item.thumb}`}
+            />
+          );
+        },
       },
       {
         title: "展览位置",
-        dataIndex: "date",
+        width: 250,
+        render: (item: any) => {
+          return <p className="limit-line line-2">{item.address}</p>;
+        },
       },
       {
         title: "发布日期",
-        dataIndex: "date",
+        dataIndex: "publishDate",
       },
       {
         title: "操作",
         render: (item: any) => {
-          return <DageTableActions onEdit={() => {}} onDelete={() => {}} />;
+          return (
+            <DageTableActions
+              onEdit={() => navigate(`/exhibition/edit/${item.id}`)}
+              onDelete={handleDelete.bind(undefined, item.id)}
+            />
+          );
         },
       },
     ];
-  }, []);
+  }, [navigate, handleDelete]);
 
   const handleReset = useCallback(() => {
-    formRef.current?.resetFields();
+    setParams({ ...DEFAULT_PARAMS });
+    setTimeout(() => {
+      formRef.current?.resetFields();
+    });
   }, [formRef]);
 
   const debounceSearch = useMemo(
-    () => debounce((changedVal: unknown, vals: any) => {}, 500),
-    []
+    () =>
+      debounce((changedVal: unknown, vals: any) => {
+        setParams({ ...params, ...vals });
+      }, 500),
+    [params]
   );
 
   const paginationChange = useCallback(
@@ -67,22 +127,18 @@ export default function InformationPage() {
   );
 
   return (
-    <div className="information">
-      <Form ref={formRef} layout="inline" onValuesChange={debounceSearch}>
-        <Form.Item label="搜索项" name="stage">
+    <div className="exhibition">
+      <Form
+        ref={formRef}
+        layout="inline"
+        initialValues={params}
+        onValuesChange={debounceSearch}
+      >
+        <Form.Item label="搜索项" name="searchKey">
           <Input placeholder="请输入" maxLength={10} showCount allowClear />
         </Form.Item>
         <Form.Item label="展览类型" name="type">
-          <Select
-            defaultValue="lucy"
-            style={{ width: 220 }}
-            options={[
-              { value: "jack", label: "Jack" },
-              { value: "lucy", label: "Lucy" },
-              { value: "Yiminghe", label: "yiminghe" },
-              { value: "disabled", label: "Disabled", disabled: true },
-            ]}
-          />
+          <Select style={{ width: 220 }} options={TYPE_LIST} />
         </Form.Item>
         <Form.Item>
           <Button type="primary" onClick={() => navigate("/exhibition/create")}>

+ 1 - 1
src/pages/Information/create-or-edit/index.tsx

@@ -121,7 +121,7 @@ export default function InformationCreateOrEditPage() {
                   rules={[{ required: true, message: "请输入内容" }]}
                 >
                   <Input
-                    className="w220"
+                    className="w450"
                     placeholder="请输入内容,最多20字"
                     maxLength={20}
                     showCount

+ 12 - 6
src/pages/Information/index.tsx

@@ -2,7 +2,7 @@ import { Button, Form, FormInstance, Input, Radio, Table } from "antd";
 import { useCallback, useEffect, useMemo, useRef, useState } from "react";
 import { debounce } from "lodash";
 import { DageTableActions } from "@dage/pc-components";
-import { useNavigate } from "react-router-dom";
+import { useNavigate, useSearchParams } from "react-router-dom";
 import { informationApi } from "@/api";
 import { TYPE_LIST } from "./constants";
 
@@ -15,14 +15,24 @@ const DEFAULT_PARAMS = {
 
 export default function InformationPage() {
   const navigate = useNavigate();
+  const [searchParams, setSearchParams] = useSearchParams();
   const formRef = useRef<FormInstance>(null);
   const [loading, setLoading] = useState(false);
   const [list, setList] = useState<[]>([]);
   const [params, setParams] = useState({
     ...DEFAULT_PARAMS,
+    searchKey: searchParams.get("searchKey") || "",
+    type: searchParams.get("type") || TYPE_LIST[0].value,
   });
   const [total, setTotal] = useState(0);
 
+  useEffect(() => {
+    setSearchParams({
+      searchKey: params.searchKey,
+      type: params.type,
+    });
+  }, [params.searchKey, params.type, setSearchParams]);
+
   const getList = useCallback(async () => {
     setLoading(true);
     try {
@@ -85,12 +95,8 @@ export default function InformationPage() {
     () =>
       debounce((changedVal: unknown, vals: any) => {
         setParams({ ...params, ...vals });
-        navigate("/information", {
-          replace: true,
-          state: vals,
-        });
       }, 500),
-    [params, navigate]
+    [params]
   );
 
   const paginationChange = useCallback(

+ 48 - 14
src/pages/Message/index.tsx

@@ -1,16 +1,16 @@
-import { Button, Form, FormInstance, Input, Select, Table } from "antd";
-import { useCallback, useMemo, useRef, useState } from "react";
+import { Button, Form, FormInstance, Input, Table } from "antd";
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
 import { debounce } from "lodash";
 import { DageTableActions } from "@dage/pc-components";
-import { useNavigate } from "react-router-dom";
+import { messageApi } from "@/api";
 
 const DEFAULT_PARAMS = {
   pageNum: 1,
   pageSize: 20,
+  searchKey: "",
 };
 
 export default function MessagePage() {
-  const navigate = useNavigate();
   const formRef = useRef<FormInstance>(null);
   const [loading, setLoading] = useState(false);
   const [list, setList] = useState<[]>([]);
@@ -19,40 +19,74 @@ export default function MessagePage() {
   });
   const [total, setTotal] = useState(0);
 
+  const getList = useCallback(async () => {
+    setLoading(true);
+    try {
+      const data = await messageApi.getList(params);
+      setList(data.records);
+      setTotal(data.total);
+    } finally {
+      setLoading(false);
+    }
+  }, [params]);
+
+  useEffect(() => {
+    getList();
+  }, [getList]);
+
+  const handleDelete = useCallback(
+    async (id: number) => {
+      await messageApi.delete(id);
+      getList();
+    },
+    [getList]
+  );
+
   const COLUMNS = useMemo(() => {
     return [
       {
         title: "留言时间",
-        dataIndex: "title",
+        dataIndex: "updateTime",
       },
       {
         title: "称号",
-        dataIndex: "nickName",
+        dataIndex: "name",
       },
       {
         title: "联系方式",
-        dataIndex: "date",
+        dataIndex: "phone",
       },
       {
         title: "正文",
-        dataIndex: "date",
+        dataIndex: "content",
       },
       {
         title: "操作",
         render: (item: any) => {
-          return <DageTableActions onDelete={() => {}} />;
+          return (
+            <DageTableActions
+              showEdit={false}
+              onDelete={handleDelete.bind(undefined, item.id)}
+            />
+          );
         },
       },
     ];
-  }, []);
+  }, [handleDelete]);
 
   const handleReset = useCallback(() => {
-    formRef.current?.resetFields();
+    setParams({ ...DEFAULT_PARAMS });
+    setTimeout(() => {
+      formRef.current?.resetFields();
+    });
   }, [formRef]);
 
   const debounceSearch = useMemo(
-    () => debounce((changedVal: unknown, vals: any) => {}, 500),
-    []
+    () =>
+      debounce((changedVal: unknown, vals: any) => {
+        setParams({ ...params, ...vals });
+      }, 500),
+    [params]
   );
 
   const paginationChange = useCallback(
@@ -65,7 +99,7 @@ export default function MessagePage() {
   return (
     <div className="information">
       <Form ref={formRef} layout="inline" onValuesChange={debounceSearch}>
-        <Form.Item label="搜索项" name="stage">
+        <Form.Item label="搜索项" name="searchKey">
           <Input placeholder="请输入" maxLength={10} showCount allowClear />
         </Form.Item>
         <Form.Item>

+ 26 - 0
src/router/index.tsx

@@ -50,6 +50,24 @@ export const DEFAULT_ADMIN_MENU: DageRouteItem[] = [
     path: "/exhibition",
     title: "展厅管理",
     Component: React.lazy(() => import("../pages/Exhibition")),
+    children: [
+      {
+        path: "/exhibition/create",
+        title: "新增",
+        hide: true,
+        Component: React.lazy(
+          () => import("../pages/Exhibition/create-or-edit")
+        ),
+      },
+      {
+        path: "/exhibition/edit/:id",
+        title: "编辑",
+        hide: true,
+        Component: React.lazy(
+          () => import("../pages/Exhibition/create-or-edit")
+        ),
+      },
+    ],
   },
   {
     path: "/collection",
@@ -64,6 +82,14 @@ export const DEFAULT_ADMIN_MENU: DageRouteItem[] = [
           () => import("../pages/Collection/create-or-edit")
         ),
       },
+      {
+        path: "/collection/edit/:id",
+        title: "编辑",
+        hide: true,
+        Component: React.lazy(
+          () => import("../pages/Collection/create-or-edit")
+        ),
+      },
     ],
   },
   {