Эх сурвалжийг харах

代办检索与删除与状态修改

daxia 1 жил өмнө
parent
commit
0d1b96b333
45 өөрчлөгдсөн 1244 нэмэгдсэн , 99 устгасан
  1. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/.gitignore
  2. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/README.md
  3. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/package.json
  4. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/public/favicon.ico
  5. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/public/index.html
  6. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/public/logo192.png
  7. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/public/logo512.png
  8. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/public/manifest.json
  9. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/public/robots.txt
  10. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/Layout/index.jsx
  11. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/Layout/index.scss
  12. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/api/goods.js
  13. 8 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/api/todos.js
  14. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/api/user.js
  15. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/components/LoadingElement.jsx
  16. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/components/PageHeader.jsx
  17. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/components/PageHeader.scss
  18. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/components/RequireAuth.jsx
  19. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/index.css
  20. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/index.js
  21. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/About.jsx
  22. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/GoodsList/goods.scss
  23. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/GoodsList/goodsSlice.js
  24. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/GoodsList/index.jsx
  25. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/Home.jsx
  26. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/Home.module.scss
  27. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/Login/index.jsx
  28. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/Login/index.scss
  29. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/Login/login.bg.gif
  30. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/TodoList/TodoAdd.jsx
  31. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/TodoList/TodoAdd.scss
  32. 241 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/TodoList/index.jsx
  33. 5 2
      20_React.js_VIP22/day-10/code/react-project-demo/src/pages/TodoList/todoSlice.js
  34. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/reportWebVitals.js
  35. 16 2
      20_React.js_VIP22/day-10/code/react-project-demo/src/router/index.js
  36. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/setupProxy.js
  37. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/store/index.js
  38. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/store/slice/loading.js
  39. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/store/slice/user.js
  40. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/todos.js
  41. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/utils/http.js
  42. 0 0
      20_React.js_VIP22/day-10/code/react-project-demo/src/utils/withSuspense.jsx
  43. 974 0
      20_React.js_VIP22/day-10/note/React项目接口文档.html
  44. 0 0
      20_React.js_VIP22/day-10/note/loader-action-redux数据流.png
  45. 0 95
      20_React.js_VIP22/day-9/code/react-project-demo/src/pages/TodoList/index.jsx

+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/.gitignore → 20_React.js_VIP22/day-10/code/react-project-demo/.gitignore


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/README.md → 20_React.js_VIP22/day-10/code/react-project-demo/README.md


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/package.json → 20_React.js_VIP22/day-10/code/react-project-demo/package.json


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/public/favicon.ico → 20_React.js_VIP22/day-10/code/react-project-demo/public/favicon.ico


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/public/index.html → 20_React.js_VIP22/day-10/code/react-project-demo/public/index.html


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/public/logo192.png → 20_React.js_VIP22/day-10/code/react-project-demo/public/logo192.png


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/public/logo512.png → 20_React.js_VIP22/day-10/code/react-project-demo/public/logo512.png


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/public/manifest.json → 20_React.js_VIP22/day-10/code/react-project-demo/public/manifest.json


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/public/robots.txt → 20_React.js_VIP22/day-10/code/react-project-demo/public/robots.txt


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/Layout/index.jsx → 20_React.js_VIP22/day-10/code/react-project-demo/src/Layout/index.jsx


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/Layout/index.scss → 20_React.js_VIP22/day-10/code/react-project-demo/src/Layout/index.scss


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/api/goods.js → 20_React.js_VIP22/day-10/code/react-project-demo/src/api/goods.js


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

@@ -14,3 +14,11 @@ export function getTodoList(params) {
     params,
   });
 }
+
+export function deleteTodo(todoId) {
+  return http.delete(`/todos/delete/${todoId}`);
+}
+
+export function editTodo(todo) {
+  return http.post('/todos/edit', todo);
+}

+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/api/user.js → 20_React.js_VIP22/day-10/code/react-project-demo/src/api/user.js


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/components/LoadingElement.jsx → 20_React.js_VIP22/day-10/code/react-project-demo/src/components/LoadingElement.jsx


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/components/PageHeader.jsx → 20_React.js_VIP22/day-10/code/react-project-demo/src/components/PageHeader.jsx


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/components/PageHeader.scss → 20_React.js_VIP22/day-10/code/react-project-demo/src/components/PageHeader.scss


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/components/RequireAuth.jsx → 20_React.js_VIP22/day-10/code/react-project-demo/src/components/RequireAuth.jsx


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/index.css → 20_React.js_VIP22/day-10/code/react-project-demo/src/index.css


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


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/About.jsx → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/About.jsx


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/GoodsList/goods.scss → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/GoodsList/goods.scss


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/GoodsList/goodsSlice.js → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/GoodsList/goodsSlice.js


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/GoodsList/index.jsx → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/GoodsList/index.jsx


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/Home.jsx → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/Home.jsx


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/Home.module.scss → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/Home.module.scss


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/Login/index.jsx → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/Login/index.jsx


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/Login/index.scss → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/Login/index.scss


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/Login/login.bg.gif → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/Login/login.bg.gif


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


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/TodoList/TodoAdd.scss → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/TodoList/TodoAdd.scss


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

@@ -0,0 +1,241 @@
+import PageHeader from '../../components/PageHeader';
+import store from '../../store';
+import { fetchTodoList } from './todoSlice';
+import { useSelector } from 'react-redux';
+import {
+  Col,
+  Row,
+  Switch,
+  Card,
+  Typography,
+  Pagination,
+  Segmented,
+  Input,
+  Button,
+  Popconfirm,
+  Space,
+  message,
+} from 'antd';
+import { EditOutlined, DeleteOutlined } from '@ant-design/icons';
+
+import { useDispatch } from 'react-redux';
+import { setPage, setFilter } from './todoSlice';
+
+import { useFetcher } from 'react-router-dom';
+import { deleteTodo, editTodo } from '../../api/todos';
+
+const { Meta } = Card;
+const { Paragraph } = Typography;
+
+function TodoList() {
+  const fetcher = useFetcher();
+  const submit = fetcher.submit;
+  const dispatch = useDispatch();
+  let filter = useSelector(({ todos }) => todos.filter);
+  let page = useSelector(({ todos }) => todos.page);
+  let list = useSelector(({ todos }) => todos.list);
+
+  function onPageChange(page, pageSize) {
+    dispatch(setPage({ current: page, count: pageSize }));
+    submit(null, { method: 'get' });
+  }
+
+  function onSelectChange(status) {
+    dispatch(setFilter({ status }));
+    submit(null, { method: 'get' });
+  }
+
+  function onTitleChange(e) {
+    dispatch(setFilter({ title: e.target.value }));
+  }
+
+  function onDeleteTodo(id) {
+    // console.log(id);
+    submit(null, { method: 'DELETE', action: `/todo/delete/${id}` });
+  }
+
+  function onStatusChange(status, todo) {
+    // console.log(todo);
+    let newTodo = { ...todo, status };
+    let formData = new FormData();
+
+    for (var name in newTodo) {
+      formData.append(name, newTodo[name]);
+    }
+
+    fetcher.submit(formData, { method: 'post', action: '/todo/change' });
+  }
+
+  return (
+    <div className="todo-list">
+      <PageHeader addRoute={'/todo/add'}>代办列表</PageHeader>
+      <div
+        style={{
+          backgroundColor: '#fff',
+          borderRadius: '12px',
+          height: '50px',
+          display: 'flex',
+          justifyContent: 'center',
+          alignItems: 'center',
+        }}
+      >
+        <Space>
+          <Input
+            placeholder="根据标题筛选..."
+            style={{ minWidth: '240px' }}
+            value={filter.title}
+            onChange={onTitleChange}
+          />
+          <Button
+            type="primary"
+            onClick={() => {
+              submit(null, { method: 'get' });
+            }}
+          >
+            查询
+          </Button>
+        </Space>
+      </div>
+      <div className="list">
+        <div style={{ width: '70%', margin: '12px auto' }}>
+          <Segmented
+            value={filter.status}
+            onChange={onSelectChange}
+            block
+            options={[
+              {
+                label: (
+                  <div
+                    style={{
+                      padding: 4,
+                    }}
+                  >
+                    <div>所有</div>
+                  </div>
+                ),
+                value: 'all',
+              },
+              {
+                label: (
+                  <div
+                    style={{
+                      padding: 4,
+                    }}
+                  >
+                    <div>进行中</div>
+                  </div>
+                ),
+                value: 'active',
+              },
+              {
+                label: (
+                  <div
+                    style={{
+                      padding: 4,
+                    }}
+                  >
+                    <div>已完成</div>
+                  </div>
+                ),
+                value: 'completed',
+              },
+            ]}
+          />
+        </div>
+        <Row>
+          {list.map((todo) => (
+            <Col key={todo.id} span={8}>
+              <Card
+                hoverable
+                style={{
+                  width: 300,
+                  marginBottom: 12,
+                  marginLeft: 'auto',
+                  marginRight: 'auto',
+                }}
+                cover={
+                  <img
+                    alt="代办封面"
+                    src={todo.cover}
+                    style={{ width: '100%', height: '200px' }}
+                  />
+                }
+                actions={[
+                  <EditOutlined key="edit" />,
+                  <Popconfirm
+                    title="删除"
+                    description="您确定删除当前代办吗?"
+                    onConfirm={() => {
+                      onDeleteTodo(todo.id);
+                    }}
+                    okText="确定"
+                    cancelText="取消"
+                  >
+                    <DeleteOutlined />
+                  </Popconfirm>,
+                  <Switch
+                    checkedChildren="已完成"
+                    unCheckedChildren="进行中"
+                    checked={!!todo.status}
+                    onChange={(status) => {
+                      onStatusChange(status - 0, todo);
+                    }}
+                  />,
+                ]}
+              >
+                <Meta
+                  title={todo.title}
+                  description={
+                    <Paragraph
+                      style={{ width: '100%' }}
+                      ellipsis={{
+                        rows: 1,
+                        tooltip: todo.description,
+                      }}
+                    >
+                      {todo.description}
+                    </Paragraph>
+                  }
+                />
+              </Card>
+            </Col>
+          ))}
+        </Row>
+        {!!page.total && (
+          <Pagination
+            current={page.current}
+            total={page.total}
+            onChange={onPageChange}
+            pageSize={page.count}
+          />
+        )}
+      </div>
+    </div>
+  );
+}
+
+export default TodoList;
+
+export async function todoListLoader() {
+  store.dispatch(fetchTodoList());
+
+  return null;
+}
+
+export async function deleteTodoAction({ params }) {
+  let { code, msg } = await deleteTodo(params.id);
+
+  // . []
+  // code = 0 => message['success'] ; code=1 ==> message['error']
+  message[code ? 'error' : 'success'](msg);
+  return null;
+}
+
+export async function changeTodoAction({ request }) {
+  let todo = await request.formData();
+  todo = Object.fromEntries(todo);
+
+  await editTodo(todo);
+
+  return null;
+}

+ 5 - 2
20_React.js_VIP22/day-9/code/react-project-demo/src/pages/TodoList/todoSlice.js → 20_React.js_VIP22/day-10/code/react-project-demo/src/pages/TodoList/todoSlice.js

@@ -25,10 +25,13 @@ export const todoSlice = createSlice({
     setList(state, { payload }) {
       state.list = payload;
     },
+    setFilter(state, { payload }) {
+      state.filter = { ...state.filter, ...payload };
+    },
   },
 });
 
-export const { setPage, setList } = todoSlice.actions;
+export const { setPage, setList, setFilter } = todoSlice.actions;
 
 export default todoSlice.reducer;
 
@@ -39,7 +42,7 @@ export const fetchTodoList = () => async (dispatch, getState) => {
       page: { current, count },
     },
   } = getState();
-  console.log({ ...filter, current, count });
+
   let { code, data } = await getTodoList({ ...filter, current, count });
   if (code == 0) {
     dispatch(setPage(data.page));

+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/reportWebVitals.js → 20_React.js_VIP22/day-10/code/react-project-demo/src/reportWebVitals.js


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

@@ -1,4 +1,4 @@
-import { createBrowserRouter } from 'react-router-dom';
+import { Navigate, createBrowserRouter } from 'react-router-dom';
 
 import { lazy } from 'react';
 import LayoutAdmin from '../Layout';
@@ -10,7 +10,11 @@ import withSuspense from '../utils/withSuspense';
 import { goodsLoader } from '../pages/GoodsList';
 
 import { todoAddAction } from '../pages/TodoList/TodoAdd';
-import { todoListLoader } from '../pages/TodoList';
+import {
+  todoListLoader,
+  deleteTodoAction,
+  changeTodoAction,
+} from '../pages/TodoList';
 
 const About = lazy(() => import('../pages/About'));
 const Login = lazy(() => import('../pages/Login'));
@@ -54,6 +58,16 @@ const router = createBrowserRouter([
         action: todoAddAction,
         element: withSuspense(TodoAdd),
       },
+      {
+        path: 'todo/delete/:id',
+        action: deleteTodoAction,
+        element: <Navigate to={'/todo/list'} />,
+      },
+      {
+        path: 'todo/change',
+        action: changeTodoAction,
+        element: <Navigate to={'/todo/list'} />,
+      },
     ],
   },
 ]);

+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/setupProxy.js → 20_React.js_VIP22/day-10/code/react-project-demo/src/setupProxy.js


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


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/store/slice/loading.js → 20_React.js_VIP22/day-10/code/react-project-demo/src/store/slice/loading.js


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/store/slice/user.js → 20_React.js_VIP22/day-10/code/react-project-demo/src/store/slice/user.js


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


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/utils/http.js → 20_React.js_VIP22/day-10/code/react-project-demo/src/utils/http.js


+ 0 - 0
20_React.js_VIP22/day-9/code/react-project-demo/src/utils/withSuspense.jsx → 20_React.js_VIP22/day-10/code/react-project-demo/src/utils/withSuspense.jsx


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 974 - 0
20_React.js_VIP22/day-10/note/React项目接口文档.html


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


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

@@ -1,95 +0,0 @@
-import PageHeader from '../../components/PageHeader';
-import store from '../../store';
-import { fetchTodoList } from './todoSlice';
-import { useSelector } from 'react-redux';
-import { Col, Row, Switch, Card, Typography, Pagination } from 'antd';
-import { EditOutlined, DeleteOutlined } from '@ant-design/icons';
-
-import { useDispatch } from 'react-redux';
-import { setPage } from './todoSlice';
-
-import { useSubmit } from 'react-router-dom';
-
-const { Meta } = Card;
-const { Paragraph } = Typography;
-
-function TodoList() {
-  const submit = useSubmit();
-  const dispatch = useDispatch();
-  let filter = useSelector(({ todos }) => todos.filter);
-  let page = useSelector(({ todos }) => todos.page);
-  let list = useSelector(({ todos }) => todos.list);
-
-  function onPageChange(page, pageSize) {
-    dispatch(setPage({ current: page, count: pageSize }));
-    submit(null, { method: 'get' });
-  }
-
-  return (
-    <div className="todo-list">
-      <PageHeader addRoute={'/todo/add'}>代办列表</PageHeader>
-      <div className="list">
-        <Row>
-          {list.map((todo) => (
-            <Col key={todo.id} span={8}>
-              <Card
-                hoverable
-                style={{
-                  width: 300,
-                  marginBottom: 12,
-                  marginLeft: 'auto',
-                  marginRight: 'auto',
-                }}
-                cover={
-                  <img
-                    alt="代办封面"
-                    src={todo.cover}
-                    style={{ width: '100%', height: '200px' }}
-                  />
-                }
-                actions={[
-                  <EditOutlined key="edit" />,
-                  <DeleteOutlined />,
-                  <Switch
-                    checkedChildren="已完成"
-                    unCheckedChildren="进行中"
-                    checked={!!todo.status}
-                  />,
-                ]}
-              >
-                <Meta
-                  title={todo.title}
-                  description={
-                    <Paragraph
-                      style={{ width: '100%' }}
-                      ellipsis={{
-                        rows: 1,
-                        tooltip: todo.description,
-                      }}
-                    >
-                      {todo.description}
-                    </Paragraph>
-                  }
-                />
-              </Card>
-            </Col>
-          ))}
-        </Row>
-        <Pagination
-          current={page.current}
-          total={page.total}
-          onChange={onPageChange}
-          pageSize={page.count}
-        />
-      </div>
-    </div>
-  );
-}
-
-export default TodoList;
-
-export async function todoListLoader() {
-  store.dispatch(fetchTodoList());
-
-  return null;
-}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно