shaogen1995 2 年 前
コミット
8790b8e215

+ 16 - 2
src/assets/styles/base.css

@@ -63,9 +63,15 @@ a {
   color: var(--themeColor);
 }
 
+
+/* 普通按钮的颜色 */
+.ant-btn-text {
+  color: #2f489a;
+}
+
 /* 按钮的危险颜色 */
 .ant-btn-text.ant-btn-dangerous {
-  color: #2f489a;
+  color: var(--themeColor);
 }
 
 /* antd分页器样式 */
@@ -134,7 +140,7 @@ img {
 }
 
 /* 表格的图片居中 */
-.tableImgAuto{
+.tableImgAuto {
   display: flex;
   justify-content: center;
 }
@@ -182,4 +188,12 @@ img {
   width: 5px;
   height: 24px;
   background-color: var(--themeColor);
+}
+
+#upInput {
+  display: none;
+}
+
+#upInput2 {
+  display: none;
 }

+ 10 - 2
src/pages/Goods/index.module.scss

@@ -1,7 +1,8 @@
 .Goods {
+  position: relative;
   :global {
     .goodsTop {
-      height: 400px;
+      height: 140px;
       background-color: #fff;
       border-radius: 10px;
 
@@ -12,7 +13,7 @@
           display: flex;
           align-items: center;
           flex-wrap: wrap;
-          margin-bottom: 12px;
+          margin-top: 5px;
           .row {
             margin-right: 30px;
             margin-bottom: 15px;
@@ -20,5 +21,12 @@
         }
       }
     }
+    .tableBox{
+      margin-top: 15px;
+      padding: 15px 15px 0;
+      height: calc(100% - 150px);
+      background-color: #fff;
+      border-radius: 10px;
+    }
   }
 }

+ 46 - 40
src/pages/Goods/index.tsx

@@ -6,7 +6,7 @@ import {
   goodsRemoveAPI,
 } from "@/store/action/goods";
 import { GoodsTableSearch } from "@/types";
-import history from "@/utils/history";
+import { typeChangeObj } from "@/utils/changeData";
 import {
   Input,
   Select,
@@ -25,24 +25,43 @@ import React, {
   useState,
 } from "react";
 import { useDispatch, useSelector } from "react-redux";
-import { useLocation } from "react-router-dom";
 import GoodsAdd from "../GoodsAdd";
 import styles from "./index.module.scss";
 
 const { RangePicker } = DatePicker;
 
 function Goods() {
-  // 获取地址栏参数
-  const location = useLocation();
-
   const dispatch = useDispatch();
 
   const pageNumRef = useRef(1);
   const pagePageRef = useRef(10);
 
+  // 0------------点击新增或者编辑出来的页面
+  const [editPageShow, setEditPageShow] = useState(false);
+  const editId = useRef(0);
+
+  const openEditPageFu = useCallback((id: number) => {
+    editId.current = id;
+    setEditPageShow(true);
+  }, []);
 
-  // 点击新增或者编辑出来的页面
-  const [editPageShow,setEditPageShow] =useState(false)
+  // 点击新增,新增成功之后的回调
+  const addTableListFu = useCallback(() => {
+    setTableSelect({
+      name: "",
+      num: "",
+      dictTexture: "",
+      dictAge: "",
+      dictLevel: "",
+      dictSource: "",
+      startTime: "",
+      endTime: "",
+      topic: -1,
+      display: -1,
+      pageSize: 10,
+      pageNum: 1,
+    });
+  }, []);
 
   // 从仓库获取下拉列表数据
   const dictList = useSelector((state: RootState) => state.loginStore.dictList);
@@ -52,16 +71,6 @@ function Goods() {
     (state: RootState) => state.goodsReducer.tableInfo
   );
 
-  // 如果有参数 根据参数页码在次发送请求
-  useEffect(() => {
-    const urlParam = location.state || {};
-    setTableSelect({
-      ...tableSelect,
-      pageNum: Number(urlParam.k) ? Number(urlParam.k) : 1,
-    });
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [location]);
-
   // 顶部筛选
   const [tableSelect, setTableSelect] = useState<GoodsTableSearch>({
     name: "",
@@ -208,12 +217,12 @@ function Goods() {
 
   const columns = useMemo(() => {
     return [
-      {
-        width: 80,
-        title: "序号",
-        render: (text: any, record: any, index: any) =>
-          index + 1 + (pageNumRef.current - 1) * pagePageRef.current,
-      },
+      // {
+      //   width: 80,
+      //   title: "序号",
+      //   render: (text: any, record: any, index: any) =>
+      //     index + 1 + (pageNumRef.current - 1) * pagePageRef.current,
+      // },
       {
         title: "名称",
         dataIndex: "name",
@@ -237,7 +246,7 @@ function Goods() {
       {
         title: "来源",
         dataIndex: "dictSource",
-      },  
+      },
       {
         title: "简介",
         render: (item: GoodsTableSearch) =>
@@ -263,7 +272,7 @@ function Goods() {
       },
       {
         title: "类型",
-        dataIndex: "dictSource",
+        render: (item: GoodsTableSearch) => typeChangeObj[item.type!],
       },
       {
         title: "最近编辑时间",
@@ -292,11 +301,7 @@ function Goods() {
             <Button
               size="small"
               type="text"
-              onClick={() =>
-                history.push(
-                  `/goods/edit?k=${pageNumRef.current}&id=${item.id}`
-                )
-              }
+              onClick={() => openEditPageFu(item.id!)}
             >
               编辑
             </Button>
@@ -314,7 +319,7 @@ function Goods() {
         ),
       },
     ];
-  }, [delTableFu, isEnabledClickFu]);
+  }, [delTableFu, isEnabledClickFu, openEditPageFu]);
 
   return (
     <div className={styles.Goods}>
@@ -437,12 +442,7 @@ function Goods() {
             <div className="row">
               <Button onClick={resetSelectFu}>重置</Button>{" "}
               &emsp;&emsp;&emsp;&emsp;
-              <Button
-                type="primary"
-                onClick={() =>
-                  history.push(`/goods/edit?k=${pageNumRef.current}`)
-                }
-              >
+              <Button type="primary" onClick={() => openEditPageFu(0)}>
                 新增
               </Button>
             </div>
@@ -468,9 +468,15 @@ function Goods() {
         />
       </div>
 
-          {/* 点击新增或者编辑出来的页面 */}
-          {editPageShow?<GoodsAdd />:null}
-
+      {/* 点击新增或者编辑出来的页面 */}
+      {editPageShow ? (
+        <GoodsAdd
+          id={editId.current}
+          closePage={() => setEditPageShow(false)}
+          upTableList={getList}
+          addTableList={() => addTableListFu()}
+        />
+      ) : null}
     </div>
   );
 }

+ 138 - 0
src/pages/GoodsAdd/index.module.scss

@@ -0,0 +1,138 @@
+.GoodsAdd {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  top: 0;
+  left: 0;
+  z-index: 10;
+  background-color: #fff;
+  border-radius: 10px;
+  padding-right: 15px;
+
+  :global {
+    .formBox {
+      padding: 10px 0;
+      width: 100%;
+      height: calc(100% - 50px);
+      overflow-y: auto;
+
+      .formBoxSon {
+        width: 800px;
+
+        .fileBoxRow_up {
+          cursor: pointer;
+          font-size: 30px;
+          width: 100px;
+          height: 100px;
+          background-color: #fafafa;
+          border: 1px dashed #ccc;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+        }
+
+        .fileBoxRow_r_img {
+          width: 100px;
+          height: 100px;
+          position: relative;
+
+          .clearCover {
+            cursor: pointer;
+            z-index: 10;
+            position: absolute;
+            width: 50px;
+            height: 50px;
+            top: 50%;
+            transform: translateY(-50%);
+            right: -50px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            font-size: 24px;
+          }
+        }
+
+        .fileBoxRow_tit {
+          width: 133.33px;
+          text-align: right;
+          position: relative;
+
+          &::before {
+            content: '*';
+            position: absolute;
+            right: 60px;
+            top: 2px;
+            color: #ff4d4f;
+            z-index: 10;
+          }
+        }
+
+        .formRow {
+          margin-top: -28px;
+          display: flex;
+        }
+
+        .formRow2 {
+          margin-top: 10px;
+          display: flex;
+
+          .fileBoxRow_tit {
+            &::before {
+              right: 74px;
+            }
+          }
+        }
+
+        .upFileBox {
+          margin-top: 15px;
+          padding-left: 133.33px;
+
+          .fileBoxRow_r_tit {
+            padding-left: 0;
+          }
+
+          .fileRowBox {
+            display: flex;
+            align-items: center;
+            margin-top: 8px;
+
+            .clearCover {
+              cursor: pointer;
+              font-size: 20px;
+              margin-left: 24px;
+            }
+          }
+        }
+
+        .fileBoxRow_r_tit {
+          padding-left: 133.33px;
+          margin-top: 8px;
+          font-size: 14px;
+          color: rgb(126, 124, 124);
+        }
+      }
+    }
+
+    .formBox::-webkit-scrollbar {
+      /*滚动条整体样式*/
+      width: 5px;
+      /*高宽分别对应横竖滚动条的尺寸*/
+      height: 1px;
+    }
+
+    .formBox::-webkit-scrollbar-thumb {
+      /*滚动条里面小方块*/
+      border-radius: 10px;
+      -webkit-box-shadow: inset 0 0 5px transparent;
+      background: var(--themeColor);
+    }
+
+    .formBox::-webkit-scrollbar-track {
+      /*滚动条里面轨道*/
+      -webkit-box-shadow: inset 0 0 5px transparent;
+      border-radius: 10px;
+      background: transparent;
+    }
+
+  }
+}

+ 25 - 29
src/pages/GoodsAdd/index.tsx

@@ -1,6 +1,5 @@
 import { RootState } from "@/store";
 import { GoodsTableSearch } from "@/types";
-import history, { urlParameter } from "@/utils/history";
 import { Button, Form, Input, message, Popconfirm, Radio, Select } from "antd";
 import TextArea from "antd/es/input/TextArea";
 import React, { useCallback, useEffect, useRef, useState } from "react";
@@ -11,7 +10,6 @@ import {
   PlayCircleOutlined,
 } from "@ant-design/icons";
 import { useDispatch, useSelector } from "react-redux";
-import { useLocation } from "react-router-dom";
 import styles from "./index.module.scss";
 import ImageLazy from "@/components/ImageLazy";
 import {
@@ -25,25 +23,16 @@ import { baseURL } from "@/utils/http";
 const UpAsyncLodingDom: any = document.querySelector("#UpAsyncLoding");
 const progressDom: any = document.querySelector("#progress");
 
-type Props ={
-  id:number
-}
+type Props = {
+  id: any;
+  closePage: () => void;
+  upTableList: () => void;
+  addTableList: () => void;
+};
 
-function GoodsAdd({id}:Props) {
+function GoodsAdd({ id, closePage, upTableList, addTableList }: Props) {
   const dispatch = useDispatch();
 
-  // 获取地址栏参数
-  const location = useLocation();
-  const urlParamRef = useRef<any>({});
-
-  const [id, SetId] = useState<any>(null);
-
-  useEffect(() => {
-    urlParamRef.current = urlParameter(location.search);
-    if (urlParamRef.current.id) SetId(Number(urlParamRef.current.id));
-    // console.log("地址栏参数", urlParamRef.current);
-  }, [location]);
-
   // 从仓库获取下拉列表数据
   const dictList = useSelector((state: RootState) => state.loginStore.dictList);
 
@@ -111,14 +100,6 @@ function GoodsAdd({id}:Props) {
   // 视频的附件信息
   const [videoFile, setVideoFile] = useState({ fileName: "", filePath: "" });
 
-  // 点击取消
-  const btnX = useCallback(() => {
-    history.push({
-      pathname: `/goods`,
-      state: { k: urlParamRef.current.k ? urlParamRef.current.k : "1" },
-    });
-  }, []);
-
   // 通过校验点击确定
   const onFinish = useCallback(
     async (values: GoodsTableSearch) => {
@@ -152,12 +133,27 @@ function GoodsAdd({id}:Props) {
 
       if (res.code === 0) {
         message.success(id ? "编辑成功!" : "新增成功!");
-        btnX();
+        if (id) upTableList();
+        else addTableList();
+
+        closePage();
       }
 
       console.log("通过校验,点击确定", res);
     },
-    [audioFile, btnX, cover, dirCode, id, imgFile, modelSrc, type, videoFile]
+    [
+      addTableList,
+      audioFile,
+      closePage,
+      cover,
+      dirCode,
+      id,
+      imgFile,
+      modelSrc,
+      type,
+      upTableList,
+      videoFile,
+    ]
   );
 
   // 上传封面图
@@ -572,7 +568,7 @@ function GoodsAdd({id}:Props) {
                 title="放弃编辑后,信息将不会保存!"
                 okText="放弃"
                 cancelText="取消"
-                onConfirm={btnX}
+                onConfirm={closePage}
               >
                 <Button>取消</Button>
               </Popconfirm>

+ 6 - 8
src/pages/Layout/index.tsx

@@ -23,7 +23,7 @@ import { useDispatch } from "react-redux";
 function Layout() {
   const dispatch = useDispatch();
 
-  const list = useMemo(() => {
+  const listTemp = useMemo(() => {
     return [
       {
         id: 1,
@@ -70,6 +70,8 @@ function Layout() {
     ];
   }, []);
 
+  const [list, setList] = useState(listTemp);
+
   // 进页面获取所有下拉信息
   useEffect(() => {
     dispatch(getDictListAPI());
@@ -181,14 +183,10 @@ function Layout() {
         <div className="mainBoxR">
           <React.Suspense fallback={<SpinLoding />}>
             <Switch>
-              {list.map((v: any, i: number) => (
-                <AuthRoute
-                  key={v.id}
-                  exact={i === 0 ? true : false}
-                  path={v.path}
-                  component={v.Com}
-                />
+              {list.map((v) => (
+                <AuthRoute key={v.id} exact path={v.path} component={v.Com} />
               ))}
+
               <Route path="*" component={NotFound} />
             </Switch>
           </React.Suspense>

+ 0 - 3
src/pages/Wall/WallAdd/index.css

@@ -6,9 +6,6 @@
   padding-top: 15px;
   width: 100%;
 }
-.wallAdd .wallAddMain #upInput {
-  display: none;
-}
 .wallAdd .wallAddMain .fileBoxRow_up {
   cursor: pointer;
   font-size: 30px;

+ 1 - 3
src/pages/Wall/WallAdd/index.less

@@ -8,9 +8,7 @@
     padding-top: 15px;
     width: 100%;
 
-    #upInput {
-      display: none;
-    }
+
 
     .fileBoxRow_up {
       cursor: pointer;

+ 2 - 2
src/pages/Wall/WallAdd/index.tsx

@@ -119,13 +119,13 @@ function WallAdd({ id, closeFu, upList }: Props) {
 
   // 点击确定
   const btnOkFu = useCallback(async () => {
-    if (name === "") return message.warning("名称不能为空!");
+    if (name === "") return message.warning("请输入名称!");
 
     if (
       (type === "img" && cover.fileName === "") ||
       (type === "video" && video.fileName === "")
     )
-      return message.warning("附件不能为空!");
+      return message.warning("请上传附件!");
 
     const obj: WallUpSaveAPI = {
       fileName: type === "img" ? cover.fileName : video.fileName,

+ 5 - 8
src/pages/Wall/WallTable/index.tsx

@@ -76,11 +76,11 @@ function WallTable() {
 
   const columns = useMemo(() => {
     return [
-      {
-        width: 80,
-        title: "序号",
-        render: (text: any, record: any, index: any) => index + 1,
-      },
+      // {
+      //   width: 80,
+      //   title: "序号",
+      //   render: (text: any, record: any, index: any) => index + 1,
+      // },
       {
         width: 100,
         title: "内容类型",
@@ -133,7 +133,6 @@ function WallTable() {
             <Button
               size="small"
               type="text"
-              danger
               disabled={index === 0}
               onClick={() => srotFu(item.id, results[index - 1].id)}
             >
@@ -142,7 +141,6 @@ function WallTable() {
             <Button
               size="small"
               type="text"
-              danger
               disabled={index === results.length - 1}
               onClick={() => srotFu(item.id, results[index + 1].id)}
             >
@@ -151,7 +149,6 @@ function WallTable() {
             <Button
               size="small"
               type="text"
-              danger
               onClick={() => editTableFu(item.id)}
             >
               编辑

+ 62 - 0
src/store/action/goods.ts

@@ -0,0 +1,62 @@
+import { GoodsTableSearch } from "@/types";
+import http from "@/utils/http";
+import { AppDispatch } from "..";
+/**
+ * 获取列表数据
+ */
+export const getGoodsList = (data: any) => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post("cms/goods/pageList", data);
+    dispatch({
+      type: "goods/getList",
+      payload: { list: res.data.records, total: res.data.total },
+    });
+  };
+};
+
+// 上传附件的进度条
+const UpAsyncLodingDom: any = document.querySelector("#UpAsyncLoding");
+const progressDom: any = document.querySelector("#progress");
+
+/**
+ * 上传封面图和附件
+ */
+export const goodsUploadAPI = (data: any) => {
+  UpAsyncLodingDom.style.opacity = 1;
+
+  return http.post("cms/goods/upload", data, {
+    // 显示进度条
+    onUploadProgress: (e: any) => {
+      const complete = (e.loaded / e.total) * 100 || 0;
+      progressDom.style.width = complete + "%";
+    },
+  });
+};
+
+/**
+ * 新增编辑藏品
+ */
+export const goodsSaveAPI = (data: GoodsTableSearch) => {
+  return http.post("cms/goods/save", data);
+};
+
+/**
+ * 删除藏品
+ */
+export const goodsRemoveAPI = (id: number) => {
+  return http.get(`cms/goods/remove/${id}`);
+};
+
+/**
+ * 内容-是否显示
+ */
+export const goodsDisplayAPI = (id: number, display: number) => {
+  return http.get(`cms/goods/display/${id}/${display}`);
+};
+
+/**
+ * 通过id获取详情
+ */
+export const goodsDetailById = (id: number) => {
+  return http.get(`cms/goods/detail/${id}`);
+};

+ 30 - 0
src/store/reducer/goods.ts

@@ -0,0 +1,30 @@
+import { GoodsTableSearch } from "@/types";
+
+// 初始化状态
+const initState = {
+  // 列表数据
+  tableInfo: {
+    list: [] as GoodsTableSearch[],
+    total: 0,
+  },
+};
+
+// 定义 action 类型
+type GoodsActionType = {
+  type: "goods/getList";
+  payload: { list: GoodsTableSearch[]; total: number };
+};
+
+// 频道 reducer
+export default function goodsReducer(
+  state = initState,
+  action: GoodsActionType
+) {
+  switch (action.type) {
+    // 获取列表数据
+    case "goods/getList":
+      return { ...state, tableInfo: action.payload };
+    default:
+      return state;
+  }
+}

+ 3 - 1
src/store/reducer/index.ts

@@ -1,5 +1,6 @@
 // 导入合并reducer的依赖
 import { combineReducers } from 'redux'
+import goodsReducer from './goods'
 
 // 导入 登录 模块的 reducer
 import loginReducer from './login'
@@ -8,7 +9,8 @@ import wallReducer from './wall'
 // 合并 reducer
 const rootReducer = combineReducers({
   loginStore: loginReducer,
-  wallReducer:wallReducer
+  wallReducer:wallReducer,
+  goodsReducer:goodsReducer
 })
 
 // 默认导出

+ 7 - 0
src/types/api/goods.d.ts

@@ -11,4 +11,11 @@ export type GoodsTableSearch ={
   display: -1 | 0 | 1;
   pageSize: number;
   pageNum: number;
+  description?:string
+  dirCode?:string
+  fileName?:string
+  filePath?:string
+  id?:number
+  thumb?:string
+  type?:"model" | "img" | "audio" | "video"
 }

+ 6 - 0
src/utils/changeData.ts

@@ -0,0 +1,6 @@
+export const typeChangeObj = {
+  img: "图片",
+  model: "模型",
+  audio: "音频",
+  video: "视频",
+};

+ 15 - 1
src/utils/history.ts

@@ -3,4 +3,18 @@
 // 根据公司要求自己选择,createBrowserHistory在项目上线的时候需要服务器映射等处理。
 import { createHashHistory  } from 'history'
 const history = createHashHistory()
-export default history
+export default history
+
+export const urlParameter = (data: string) => {
+  if (data) {
+    const query = data.substring(data.indexOf("?") + 1);
+    const arr = query.split("&");
+    const params = {} as any;
+    arr.forEach((v) => {
+      const key = v.substring(0, v.indexOf("="));
+      const val = v.substring(v.indexOf("=") + 1);
+      params[key] = val;
+    });
+    return params;
+  } else return {};
+};

+ 5 - 5
src/utils/http.ts

@@ -9,8 +9,8 @@ export const baseURL =
   // process.env.NODE_ENV === "development"
   //   ? "http://192.168.20.55:8038/api/"
   //   : "";
-  // process.env.NODE_ENV === "development" ? "https://xuzhouwall.4dage.com" : "";
-  process.env.NODE_ENV === "development" ? "http://192.168.20.55:8039" : "";
+  process.env.NODE_ENV === "development" ? "https://xuzhouwall.4dage.com" : "";
+  // process.env.NODE_ENV === "development" ? "http://192.168.20.55:8039" : "";
 
 // 创建 axios 实例
 const http = axios.create({
@@ -74,9 +74,9 @@ http.interceptors.response.use(
     store.dispatch({ type: "login/asyncLoding", payload: false });
 
     // 响应错误也要取消 上传文件的进度条
-    UpAsyncLodingDom.style.opacity = 0;
-    progressDom.style.width = "0%";
-
+    if(UpAsyncLodingDom) UpAsyncLodingDom.style.opacity = 0;
+    if(progressDom) progressDom.style.width = "0%";
+    
     // 如果因为网络原因,response没有,给提示消息
     if (!err.response) {
       message.warning("网络繁忙,请稍后重试!");