後端實作
在對應的 views 新增一個 API,取得此用戶的訂單紀錄。
1 2 3 4 5 6 7 8 9
|
@api_view(['GET']) @permission_classes([IsAuthenticated]) def getMyOrders(request): user = request.user orders = user.order_set.all() serializer = OrderSerializer(orders, many=True) return Response(serializer.data)
|
然後在 urls.py 新增一個路徑,對應到這個 API,記得要寫在 <str:pk>/
之前,因為 django 匹配路徑時,是從上往下找,匹配完成其他路徑就不會再繼續匹配。
1 2
| path('myorders/', views.getMyOrders, name='myorders'),
|
然後可以去 Postman 測試一下看後端是否建置成功,有的話應會出現此用戶的訂單列表回傳 JSON
前端實作
Constants 定義
先到 redux 裡面新增一個 orderConstants.js,定義取得此用戶的訂單紀錄的常數。
1 2 3 4 5 6
|
export const ORDER_LIST_MY_REQUEST = "ORDER_LIST_MY_REQUEST"; export const ORDER_LIST_MY_SUCCESS = "ORDER_LIST_MY_SUCCESS"; export const ORDER_LIST_MY_FAIL = "ORDER_LIST_MY_FAIL"; export const ORDER_LIST_MY_RESET = "ORDER_LIST_MY_RESET";
|
Reducers 實作
然後將這些常數引入 orderReducers.js,並撰寫相關程式來處理這些常數。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| import{ ... ORDER_LIST_MY_REQUEST, ORDER_LIST_MY_SUCCESS, ORDER_LIST_MY_FAIL, ORDER_LIST_MY_RESET, } from '../constants/orderConstants'
export const orderListMyReducer = (state = {orders:[]}, action) => { switch (action.type) { case ORDER_LIST_MY_REQUEST: return { loading: true, };
case ORDER_LIST_MY_SUCCESS: return { loading: false, orders: action.payload, };
case ORDER_LIST_MY_FAIL: return { loading: false, error: action.payload, };
case ORDER_LIST_MY_RESET: return { orders: [], }; default: return state; } };
|
然後在 store.js
引入這個 reducer
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { ...,orderListMyReducer } from "./reducers/orderReducers"; ... const store = configureStore({ reducer: { ... ... orderListMy:orderListMyReducer, }, preloadedState: initialState, middleware: middleware, });
|
Actions 實作
到 action 裡面新增一個 action 來取得此用戶的訂單紀錄,這個 action 就不需要 id,因為是取得此用戶的訂單紀錄,不像 payOrder 或 getOrderDetails 需要 id。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
export const listMyOrders = () => async (dispatch, getState) => { try { dispatch({ type: ORDER_LIST_MY_REQUEST, });
const { userLogin: { userInfo }, } = getState();
const config = { headers: { "Content-type": "application/json", Authorization: `Bearer ${userInfo.token}`, }, };
const { data } = await axios.get(`/api/orders/myorders/`, config);
dispatch({ type: ORDER_LIST_MY_SUCCESS, payload: data, }); } catch (error) { dispatch({ type: ORDER_LIST_MY_FAIL, payload: error.response && error.response.data.detail ? error.response.data.detail : error.message, }); } };
|
由於用戶登出後,要清空用戶的訂單紀錄,所以到 userActions.js 裡面新增一個 action 來清空用戶的訂單紀錄。
1 2 3 4 5 6
| export const logout = () => (dispatch) => { localStorage.removeItem("userInfo"); ... dispatch({ type: ORDER_LIST_MY_RESET }) };
|
訂單列表前端實作
接下來到 ProfilePage.js
來呼叫這個 action,並在 useEffect 裡面判斷是否有用戶登入,如果沒有登入就跳轉到登入頁面,如果有登入就取得此用戶的訂單紀錄。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| useEffect(() => { if (!userInfo) { navigate("/login"); } else { if (!user || !user.first_name || success) { ... dispatch(listMyOrders()); } else { ... } } }, [dispatch, navigate, userInfo, user, success]);
|
最後一步就是製作訂單列表的前端,這邊主要目的有:
- 訂單列表在個人檔案的右側並佔據 5/6 的寬度,所以我們使用
Col=10
包住訂單區塊
- 由於本身 Bootstrap 主題背景為白色,因此若要讓 Hover 效果明顯需要在
Table
加上 table-light
樣式,讓表格預設主題為淺白色
- 判斷訂單是否已付款,如果已付款則顯示付款日期,如果未付款則顯示紅色的 X
- 可以導向到訂單詳情頁面
由於 Table
標籤會導致此筆記頁面整個跑版,因此改用圖片代替
若您覺得這篇文章對您有幫助,歡迎分享出去讓更多人看到⊂◉‿◉つ~
留言版