Browse Source

上传文件&列表数据获取

daxia 1 year ago
parent
commit
440f1bc835

BIN
20_React.js_VIP22/day-0/note/loader-action-redux数据流.png


+ 16 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/api/todos.js

@@ -0,0 +1,16 @@
+import http from '../utils/http';
+
+export function addTodo(todo) {
+  return http.post('/todos/add', todo);
+}
+
+/**
+ *
+ * @param {Object} params
+ ** params; count每页条数; title查询的代办标题; status查代办的状态:all | active | completed
+ */
+export function getTodoList(params) {
+  return http.get('/todos/page', {
+    params,
+  });
+}

+ 33 - 9
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/TodoList/TodoAdd.jsx

@@ -2,7 +2,8 @@ import PageHeader from '../../components/PageHeader';
 import { Input, Button, Form, Upload } from 'antd';
 import { PlusOutlined } from '@ant-design/icons';
 import './TodoAdd.scss';
-import { useSubmit } from 'react-router-dom';
+import { redirect, useSubmit } from 'react-router-dom';
+import { addTodo } from '../../api/todos';
 
 const { TextArea } = Input;
 
@@ -10,11 +11,15 @@ function TodoAdd() {
   let [form] = Form.useForm();
   const submit = useSubmit();
   function onFinish() {
-    console.log(form);
-    form.setFieldValue('cover', '/public/favicon.ico');
-    setTimeout(() => {
-      submit(document.querySelector('#addForm'), { method: 'post' });
-    }, 0);
+    submit(document.querySelector('#addForm'), { method: 'post' });
+  }
+
+  function handleUpload({ file }) {
+    let { status } = file;
+    if (status == 'done') {
+      let { code, data } = file.response;
+      code == 0 && form.setFieldValue('cover', data.dir);
+    }
   }
   return (
     <>
@@ -57,7 +62,23 @@ function TodoAdd() {
             />
           </Form.Item>
           <Form.Item label="代办封面">
-            <Upload listType="picture-card" accept="image/*">
+            <Upload
+              listType="picture-card"
+              accept="image/*"
+              name="cover"
+              action={'/api/v1/upload'}
+              data={{ folder: 'covers' }}
+              method="put"
+              headers={{
+                Authorization: sessionStorage.getItem('token'),
+              }}
+              maxCount={1}
+              onChange={handleUpload}
+              showUploadList={{
+                showPreviewIcon: false, //! 是否显示预览图标
+                showRemoveIcon: true, //! 是否显示删除图标
+              }}
+            >
               <div>
                 <PlusOutlined />
                 <div
@@ -95,8 +116,11 @@ export async function todoAddAction({ request }) {
   //! 在添加代办时 会发起当前路由的一个post请求,下面是获取请求体数据
   let formData = await request.formData();
 
-  let data = Object.fromEntries(formData);
+  let newTodo = Object.fromEntries(formData);
+
+  let { code } = await addTodo(newTodo);
+
+  if (code == 0) return redirect('/todo/list');
 
-  console.log(data);
   return null;
 }

+ 8 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/TodoList/index.jsx

@@ -1,4 +1,6 @@
 import PageHeader from '../../components/PageHeader';
+import store from '../../store';
+import { fetchTodoList } from './todoSlice';
 
 function TodoList() {
   return (
@@ -9,3 +11,9 @@ function TodoList() {
 }
 
 export default TodoList;
+
+export async function todoListLoader() {
+  store.dispatch(fetchTodoList());
+
+  return null;
+}

+ 48 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/TodoList/todoSlice.js

@@ -0,0 +1,48 @@
+import { createSlice } from '@reduxjs/toolkit';
+import { getTodoList } from '../../api/todos';
+
+export const todoSlice = createSlice({
+  name: 'todo',
+  initialState: {
+    filter: {
+      title: '',
+      status: 'all',
+    },
+    page: {
+      current: 1,
+      count: 10,
+      total: 0,
+      pages: 0,
+      activeCount: 0,
+    },
+    list: [],
+  },
+  reducers: {
+    // payload = {current: 2}
+    setPage(state, { payload }) {
+      state.page = { ...state.page, ...payload };
+    },
+    setList(state, { payload }) {
+      state.list = payload;
+    },
+  },
+});
+
+export const { setPage, setList } = todoSlice.actions;
+
+export default todoSlice.reducer;
+
+export const fetchTodoList = () => async (dispatch, getState) => {
+  let {
+    todos: {
+      filter,
+      page: { current, count },
+    },
+  } = getState();
+  console.log({ ...filter, current, count });
+  let { code, data } = await getTodoList({ ...filter, current, count });
+  if (code == 0) {
+    dispatch(setPage(data.page));
+    dispatch(setList(data.list));
+  }
+};

+ 2 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/router/index.js

@@ -10,6 +10,7 @@ import withSuspense from '../utils/withSuspense';
 import { goodsLoader } from '../pages/GoodsList';
 
 import { todoAddAction } from '../pages/TodoList/TodoAdd';
+import { todoListLoader } from '../pages/TodoList';
 
 const About = lazy(() => import('../pages/About'));
 const Login = lazy(() => import('../pages/Login'));
@@ -45,6 +46,7 @@ const router = createBrowserRouter([
       },
       {
         path: 'todo/list',
+        loader: todoListLoader,
         element: withSuspense(TodoList),
       },
       {

+ 2 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/store/index.js

@@ -2,12 +2,14 @@ import { configureStore } from '@reduxjs/toolkit';
 import loadingReducer from './slice/loading';
 import userReducer from './slice/user';
 import goodsReducr from '../pages/GoodsList/goodsSlice';
+import todoReducer from '../pages/TodoList/todoSlice';
 
 const store = configureStore({
   reducer: {
     loader: loadingReducer,
     user: userReducer,
     goods: goodsReducr,
+    todos: todoReducer,
   },
 });
 

+ 112 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/todos.js

@@ -0,0 +1,112 @@
+export default class TodosController {
+  /**
+   *! [分页获取todo]
+   ** 请求体中包含分页信息:current页码 and count 每页条数 以及可选参数:title 用于检索
+   */
+  static async getTodosByPage(ctx) {
+    let { current, count, title = '', status = 'all' } = ctx.query;
+
+    current = current - 0;
+    count = count - 0;
+
+    let statusList = [0, 1];
+    let start = (current - 1) * count;
+    let userId = ctx.session.user.id;
+
+    switch (status) {
+      case 'active':
+        statusList = [0, 0];
+        break;
+      case 'completed':
+        statusList = [1, 1];
+        break;
+      default:
+        statusList = [0, 1];
+    }
+
+    let sql =
+      'select * from Todos where uid = ? and title like ? and status in (?, ?) order by create_time desc limit ?, ?;';
+    let tsql =
+      'select count(id) as total from Todos where uid = ? and title like ? and status in (?, ?);';
+    let atsql =
+      'select count(id) as activeCount from Todos where uid = ? and title like ? and status = 0;';
+
+    let [rows] = await ctx.db.query(sql, [
+      userId,
+      `%${title}%`,
+      ...statusList,
+      start,
+      count - 0,
+    ]);
+
+    let [[{ total = 0 }]] = await ctx.db.query(tsql, [
+      userId,
+      `%${title}%`,
+      ...statusList,
+    ]);
+
+    let [[{ activeCount = 0 }]] = await ctx.db.query(atsql, [
+      userId,
+      `%${title}%`,
+    ]);
+
+    ctx.body = {
+      code: 0,
+      msg: '查询成功',
+      data: {
+        page: {
+          current,
+          count,
+          total,
+          pages: Math.ceil(total / count),
+          activeCount,
+        },
+        list: rows,
+      },
+    };
+  }
+  // 添加todo
+  static async addTodo(ctx) {
+    let { title, description, cover } = ctx.request.body;
+    let uid = ctx.session.user.id;
+
+    const sql =
+      'insert into Todos(title, description, cover, uid, create_time) values (?, ?, ?, ?, now());';
+
+    let res = await ctx.db.query(sql, [title, description, cover, uid]);
+
+    console.log(res);
+
+    ctx.body = {
+      code: 0,
+      msg: '添加成功',
+    };
+  }
+  static async editTodo(ctx) {
+    let { id, title, description, cover, status } = ctx.request.body;
+    let sql =
+      'update Todos set title = ?, description = ?, cover = ?, status = ? where id = ?;';
+
+    let res = await ctx.db.query(sql, [title, description, cover, status, id]);
+
+    console.log(res);
+
+    ctx.body = {
+      code: 0,
+      msg: '更新成功',
+    };
+  }
+  static async deleteTodo(ctx) {
+    let todoId = ctx.params.id;
+    let sql = 'delete from Todos where id = ?;';
+
+    let res = await ctx.db.query(sql, [todoId]);
+
+    console.log(res);
+
+    ctx.body = {
+      code: 0,
+      msg: '删除成功',
+    };
+  }
+}