Bladeren bron

feat:适配服务端新的api,并修复一些问题

yangyi 4 maanden geleden
bovenliggende
commit
c4f1d86c25
42 gewijzigde bestanden met toevoegingen van 584 en 270 verwijderingen
  1. 26 21
      src/api/endpoints/categories.ts
  2. 38 35
      src/api/endpoints/items.ts
  3. 14 11
      src/api/endpoints/messages.ts
  4. 32 24
      src/api/endpoints/orders.ts
  5. 20 15
      src/api/endpoints/reviews.ts
  6. 19 14
      src/api/endpoints/user-management.ts
  7. 7 7
      src/api/endpoints/users.ts
  8. 1 1
      src/api/models/getMessageHistoryParams.ts
  9. 9 9
      src/api/models/index.ts
  10. 1 1
      src/api/models/listBoughtOrdersParams.ts
  11. 11 0
      src/api/models/listItemsByCategoryParams.ts
  12. 1 1
      src/api/models/listItemsParams.ts
  13. 11 0
      src/api/models/listPendingItemReviewsParams.ts
  14. 11 0
      src/api/models/listPendingUserReviewsParams.ts
  15. 1 1
      src/api/models/listSoldOrdersParams.ts
  16. 12 0
      src/api/models/listUsersParams.ts
  17. 0 11
      src/api/models/pendingItemsParams.ts
  18. 0 11
      src/api/models/pendingUsersParams.ts
  19. 1 1
      src/api/models/searchItemsParams.ts
  20. 0 11
      src/api/models/soldParams.ts
  21. 2 3
      src/api/models/submitAuthBody.ts
  22. 6 0
      src/layout/AdminLayout.vue
  23. 15 4
      src/layout/UserLayout.vue
  24. 2 1
      src/main.ts
  25. 3 12
      src/router/index.ts
  26. 7 2
      src/store/user.ts
  27. 12 1
      src/util/axios-instance.ts
  28. 2 2
      src/view/Chat.vue
  29. 3 3
      src/view/Home.vue
  30. 2 2
      src/view/ItemDetail.vue
  31. 1 1
      src/view/Messages.vue
  32. 82 15
      src/view/MyItems.vue
  33. 150 18
      src/view/MyOrders.vue
  34. 20 8
      src/view/OrderDetail.vue
  35. 36 4
      src/view/Profile.vue
  36. 2 2
      src/view/Publish.vue
  37. 4 4
      src/view/Search.vue
  38. 4 4
      src/view/admin/CategoryManage.vue
  39. 3 3
      src/view/admin/ReviewItem.vue
  40. 3 3
      src/view/admin/ReviewUser.vue
  41. 4 4
      src/view/admin/UserManage.vue
  42. 6 0
      src/vite-env.d.ts

+ 26 - 21
src/api/endpoints/categories.ts

@@ -17,7 +17,7 @@ export const getCategories = () => {
   /**
    * @summary 修改分类
    */
-  const update = (id: number, categoryRequest: CategoryRequest) => {
+  const updateCategory = (id: number, categoryRequest: CategoryRequest) => {
     return customAxiosInstance<ResultVoid>({
       url: `/admin/categories/${id}`,
       method: "PUT",
@@ -28,7 +28,7 @@ export const getCategories = () => {
   /**
    * @summary 启用/禁用分类
    */
-  const toggleStatus = (id: number, statusRequest: StatusRequest) => {
+  const toggleCategoryStatus = (id: number, statusRequest: StatusRequest) => {
     return customAxiosInstance<ResultVoid>({
       url: `/admin/categories/${id}/status`,
       method: "PUT",
@@ -36,19 +36,10 @@ export const getCategories = () => {
       data: statusRequest,
     });
   };
-  /**
-   * @summary 分类列表
-   */
-  const list1 = () => {
-    return customAxiosInstance<ResultListCategory>({
-      url: `/admin/categories`,
-      method: "GET",
-    });
-  };
   /**
    * @summary 新增分类
    */
-  const create1 = (categoryRequest: CategoryRequest) => {
+  const createCategory = (categoryRequest: CategoryRequest) => {
     return customAxiosInstance<ResultLong>({
       url: `/admin/categories`,
       method: "POST",
@@ -56,17 +47,31 @@ export const getCategories = () => {
       data: categoryRequest,
     });
   };
-  return { update, toggleStatus, list1, create1 };
+  /**
+   * @summary 获取所有分类列表
+   */
+  const listCategories = () => {
+    return customAxiosInstance<ResultListCategory>({
+      url: `/categories`,
+      method: "GET",
+    });
+  };
+  return {
+    updateCategory,
+    toggleCategoryStatus,
+    createCategory,
+    listCategories,
+  };
 };
-export type UpdateResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getCategories>["update"]>>
+export type UpdateCategoryResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getCategories>["updateCategory"]>>
 >;
-export type ToggleStatusResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getCategories>["toggleStatus"]>>
+export type ToggleCategoryStatusResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getCategories>["toggleCategoryStatus"]>>
 >;
-export type List1Result = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getCategories>["list1"]>>
+export type CreateCategoryResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getCategories>["createCategory"]>>
 >;
-export type Create1Result = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getCategories>["create1"]>>
+export type ListCategoriesResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getCategories>["listCategories"]>>
 >;

+ 38 - 35
src/api/endpoints/items.ts

@@ -5,15 +5,15 @@
  * OpenAPI spec version: v0
  */
 import type {
-  ByCategoryParams,
   ItemPublishRequest,
-  ListParams,
+  ListItemsByCategoryParams,
+  ListItemsParams,
   ResultItemVO,
   ResultListItemVO,
   ResultLong,
   ResultPageResultItemVO,
   ResultVoid,
-  SearchParams,
+  SearchItemsParams,
 } from "../models";
 import { customAxiosInstance } from "../../util/axios-instance";
 
@@ -22,7 +22,7 @@ export const getItems = () => {
    * 卖家下架自己的物品
    * @summary 下架物品
    */
-  const offline = (id: number) => {
+  const offlineItem = (id: number) => {
     return customAxiosInstance<ResultVoid>({
       url: `/items/${id}/offline`,
       method: "PUT",
@@ -32,7 +32,7 @@ export const getItems = () => {
    * 按发布时间倒序,分页返回
    * @summary 首页物品列表
    */
-  const list = (params?: ListParams) => {
+  const listItems = (params?: ListItemsParams) => {
     return customAxiosInstance<ResultPageResultItemVO>({
       url: `/items`,
       method: "GET",
@@ -43,7 +43,7 @@ export const getItems = () => {
    * 需要实名认证,图片以 multipart 上传
    * @summary 发布物品
    */
-  const publish = (itemPublishRequest: ItemPublishRequest) => {
+  const publishItem = (itemPublishRequest: ItemPublishRequest) => {
     const formData = new FormData();
     formData.append("title", itemPublishRequest.title);
     if (itemPublishRequest.description !== undefined) {
@@ -70,7 +70,7 @@ export const getItems = () => {
   /**
    * @summary 物品详情
    */
-  const detail = (id: number) => {
+  const getItemDetail = (id: number) => {
     return customAxiosInstance<ResultItemVO>({
       url: `/items/${id}`,
       method: "GET",
@@ -80,7 +80,7 @@ export const getItems = () => {
    * 卖家删除自己的物品
    * @summary 删除物品
    */
-  const _delete = (id: number) => {
+  const deleteItem = (id: number) => {
     return customAxiosInstance<ResultVoid>({
       url: `/items/${id}`,
       method: "DELETE",
@@ -90,7 +90,7 @@ export const getItems = () => {
    * 按标题/描述模糊匹配
    * @summary 搜索物品
    */
-  const search = (params: SearchParams) => {
+  const searchItems = (params: SearchItemsParams) => {
     return customAxiosInstance<ResultPageResultItemVO>({
       url: `/items/search`,
       method: "GET",
@@ -100,7 +100,7 @@ export const getItems = () => {
   /**
    * @summary 我的发布列表
    */
-  const myItems = () => {
+  const listMyItems = () => {
     return customAxiosInstance<ResultListItemVO>({
       url: `/items/my`,
       method: "GET",
@@ -109,7 +109,10 @@ export const getItems = () => {
   /**
    * @summary 按分类筛选
    */
-  const byCategory = (id: number, params?: ByCategoryParams) => {
+  const listItemsByCategory = (
+    id: number,
+    params?: ListItemsByCategoryParams,
+  ) => {
     return customAxiosInstance<ResultPageResultItemVO>({
       url: `/items/category/${id}`,
       method: "GET",
@@ -117,37 +120,37 @@ export const getItems = () => {
     });
   };
   return {
-    offline,
-    list,
-    publish,
-    detail,
-    _delete,
-    search,
-    myItems,
-    byCategory,
+    offlineItem,
+    listItems,
+    publishItem,
+    getItemDetail,
+    deleteItem,
+    searchItems,
+    listMyItems,
+    listItemsByCategory,
   };
 };
-export type OfflineResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getItems>["offline"]>>
+export type OfflineItemResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getItems>["offlineItem"]>>
 >;
-export type ListResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getItems>["list"]>>
+export type ListItemsResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getItems>["listItems"]>>
 >;
-export type PublishResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getItems>["publish"]>>
+export type PublishItemResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getItems>["publishItem"]>>
 >;
-export type DetailResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getItems>["detail"]>>
+export type GetItemDetailResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getItems>["getItemDetail"]>>
 >;
-export type _DeleteResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getItems>["_delete"]>>
+export type DeleteItemResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getItems>["deleteItem"]>>
 >;
-export type SearchResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getItems>["search"]>>
+export type SearchItemsResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getItems>["searchItems"]>>
 >;
-export type MyItemsResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getItems>["myItems"]>>
+export type ListMyItemsResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getItems>["listMyItems"]>>
 >;
-export type ByCategoryResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getItems>["byCategory"]>>
+export type ListItemsByCategoryResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getItems>["listItemsByCategory"]>>
 >;

+ 14 - 11
src/api/endpoints/messages.ts

@@ -5,7 +5,7 @@
  * OpenAPI spec version: v0
  */
 import type {
-  HistoryParams,
+  GetMessageHistoryParams,
   ResultListConversationVO,
   ResultLong,
   ResultPageResultMessageVO,
@@ -17,7 +17,7 @@ export const getMessages = () => {
   /**
    * @summary 发送消息
    */
-  const send = (sendMessageRequest: SendMessageRequest) => {
+  const sendMessage = (sendMessageRequest: SendMessageRequest) => {
     return customAxiosInstance<ResultLong>({
       url: `/messages`,
       method: "POST",
@@ -29,7 +29,10 @@ export const getMessages = () => {
    * 与指定用户的聊天记录,分页
    * @summary 聊天记录
    */
-  const history = (userId: number, params?: HistoryParams) => {
+  const getMessageHistory = (
+    userId: number,
+    params?: GetMessageHistoryParams,
+  ) => {
     return customAxiosInstance<ResultPageResultMessageVO>({
       url: `/messages/${userId}`,
       method: "GET",
@@ -40,20 +43,20 @@ export const getMessages = () => {
    * 返回当前用户的所有会话及最后一条消息
    * @summary 会话列表
    */
-  const conversations = () => {
+  const listConversations = () => {
     return customAxiosInstance<ResultListConversationVO>({
       url: `/messages/conversations`,
       method: "GET",
     });
   };
-  return { send, history, conversations };
+  return { sendMessage, getMessageHistory, listConversations };
 };
-export type SendResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getMessages>["send"]>>
+export type SendMessageResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getMessages>["sendMessage"]>>
 >;
-export type HistoryResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getMessages>["history"]>>
+export type GetMessageHistoryResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getMessages>["getMessageHistory"]>>
 >;
-export type ConversationsResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getMessages>["conversations"]>>
+export type ListConversationsResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getMessages>["listConversations"]>>
 >;

+ 32 - 24
src/api/endpoints/orders.ts

@@ -5,12 +5,12 @@
  * OpenAPI spec version: v0
  */
 import type {
-  BoughtParams,
   CreateOrderRequest,
+  ListBoughtOrdersParams,
+  ListSoldOrdersParams,
   ResultLong,
   ResultPageResultOrderVO,
   ResultVoid,
-  SoldParams,
 } from "../models";
 import { customAxiosInstance } from "../../util/axios-instance";
 
@@ -18,7 +18,7 @@ export const getOrders = () => {
   /**
    * @summary 卖家拒单
    */
-  const reject = (id: number) => {
+  const rejectOrder = (id: number) => {
     return customAxiosInstance<ResultVoid>({
       url: `/orders/${id}/reject`,
       method: "PUT",
@@ -27,7 +27,7 @@ export const getOrders = () => {
   /**
    * @summary 卖家确认交货
    */
-  const deliver = (id: number) => {
+  const deliverOrder = (id: number) => {
     return customAxiosInstance<ResultVoid>({
       url: `/orders/${id}/deliver`,
       method: "PUT",
@@ -36,7 +36,7 @@ export const getOrders = () => {
   /**
    * @summary 买家确认收货
    */
-  const confirm = (id: number) => {
+  const confirmOrder = (id: number) => {
     return customAxiosInstance<ResultVoid>({
       url: `/orders/${id}/confirm`,
       method: "PUT",
@@ -45,7 +45,7 @@ export const getOrders = () => {
   /**
    * @summary 卖家接单
    */
-  const accept = (id: number) => {
+  const acceptOrder = (id: number) => {
     return customAxiosInstance<ResultVoid>({
       url: `/orders/${id}/accept`,
       method: "PUT",
@@ -55,7 +55,7 @@ export const getOrders = () => {
    * 买家点击『我想要』生成订单
    * @summary 生成订单
    */
-  const create = (createOrderRequest: CreateOrderRequest) => {
+  const createOrder = (createOrderRequest: CreateOrderRequest) => {
     return customAxiosInstance<ResultLong>({
       url: `/orders`,
       method: "POST",
@@ -66,7 +66,7 @@ export const getOrders = () => {
   /**
    * @summary 我卖出的订单
    */
-  const sold = (params?: SoldParams) => {
+  const listSoldOrders = (params?: ListSoldOrdersParams) => {
     return customAxiosInstance<ResultPageResultOrderVO>({
       url: `/orders/sold`,
       method: "GET",
@@ -76,33 +76,41 @@ export const getOrders = () => {
   /**
    * @summary 我买到的订单
    */
-  const bought = (params?: BoughtParams) => {
+  const listBoughtOrders = (params?: ListBoughtOrdersParams) => {
     return customAxiosInstance<ResultPageResultOrderVO>({
       url: `/orders/bought`,
       method: "GET",
       params,
     });
   };
-  return { reject, deliver, confirm, accept, create, sold, bought };
+  return {
+    rejectOrder,
+    deliverOrder,
+    confirmOrder,
+    acceptOrder,
+    createOrder,
+    listSoldOrders,
+    listBoughtOrders,
+  };
 };
-export type RejectResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getOrders>["reject"]>>
+export type RejectOrderResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getOrders>["rejectOrder"]>>
 >;
-export type DeliverResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getOrders>["deliver"]>>
+export type DeliverOrderResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getOrders>["deliverOrder"]>>
 >;
-export type ConfirmResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getOrders>["confirm"]>>
+export type ConfirmOrderResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getOrders>["confirmOrder"]>>
 >;
-export type AcceptResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getOrders>["accept"]>>
+export type AcceptOrderResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getOrders>["acceptOrder"]>>
 >;
-export type CreateResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getOrders>["create"]>>
+export type CreateOrderResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getOrders>["createOrder"]>>
 >;
-export type SoldResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getOrders>["sold"]>>
+export type ListSoldOrdersResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getOrders>["listSoldOrders"]>>
 >;
-export type BoughtResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getOrders>["bought"]>>
+export type ListBoughtOrdersResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getOrders>["listBoughtOrders"]>>
 >;

+ 20 - 15
src/api/endpoints/reviews.ts

@@ -5,8 +5,8 @@
  * OpenAPI spec version: v0
  */
 import type {
-  PendingItemsParams,
-  PendingUsersParams,
+  ListPendingItemReviewsParams,
+  ListPendingUserReviewsParams,
   ResultPageResultItemVO,
   ResultPageResultUser,
   ResultVoid,
@@ -18,7 +18,7 @@ export const getReviews = () => {
   /**
    * @summary 审核用户实名认证
    */
-  const reviewUser = (id: number, reviewRequest: ReviewRequest) => {
+  const reviewUserAuth = (id: number, reviewRequest: ReviewRequest) => {
     return customAxiosInstance<ResultVoid>({
       url: `/admin/review/user/${id}`,
       method: "POST",
@@ -29,7 +29,7 @@ export const getReviews = () => {
   /**
    * @summary 审核物品上架
    */
-  const reviewItem = (id: number, reviewRequest: ReviewRequest) => {
+  const reviewItemListing = (id: number, reviewRequest: ReviewRequest) => {
     return customAxiosInstance<ResultVoid>({
       url: `/admin/review/item/${id}`,
       method: "POST",
@@ -40,7 +40,7 @@ export const getReviews = () => {
   /**
    * @summary 待审核用户列表
    */
-  const pendingUsers = (params?: PendingUsersParams) => {
+  const listPendingUserReviews = (params?: ListPendingUserReviewsParams) => {
     return customAxiosInstance<ResultPageResultUser>({
       url: `/admin/review/users`,
       method: "GET",
@@ -50,24 +50,29 @@ export const getReviews = () => {
   /**
    * @summary 待审核物品列表
    */
-  const pendingItems = (params?: PendingItemsParams) => {
+  const listPendingItemReviews = (params?: ListPendingItemReviewsParams) => {
     return customAxiosInstance<ResultPageResultItemVO>({
       url: `/admin/review/items`,
       method: "GET",
       params,
     });
   };
-  return { reviewUser, reviewItem, pendingUsers, pendingItems };
+  return {
+    reviewUserAuth,
+    reviewItemListing,
+    listPendingUserReviews,
+    listPendingItemReviews,
+  };
 };
-export type ReviewUserResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getReviews>["reviewUser"]>>
+export type ReviewUserAuthResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getReviews>["reviewUserAuth"]>>
 >;
-export type ReviewItemResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getReviews>["reviewItem"]>>
+export type ReviewItemListingResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getReviews>["reviewItemListing"]>>
 >;
-export type PendingUsersResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getReviews>["pendingUsers"]>>
+export type ListPendingUserReviewsResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getReviews>["listPendingUserReviews"]>>
 >;
-export type PendingItemsResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getReviews>["pendingItems"]>>
+export type ListPendingItemReviewsResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getReviews>["listPendingItemReviews"]>>
 >;

+ 19 - 14
src/api/endpoints/user-management.ts

@@ -4,14 +4,18 @@
  * OpenAPI definition
  * OpenAPI spec version: v0
  */
-import type { List2Params, ResultPageResultUser, ResultVoid } from "../models";
+import type {
+  ListUsersParams,
+  ResultPageResultUser,
+  ResultVoid,
+} from "../models";
 import { customAxiosInstance } from "../../util/axios-instance";
 
 export const getUserManagement = () => {
   /**
    * @summary 解封用户
    */
-  const unban = (id: number) => {
+  const unbanUser = (id: number) => {
     return customAxiosInstance<ResultVoid>({
       url: `/admin/users/${id}/unban`,
       method: "PUT",
@@ -20,7 +24,7 @@ export const getUserManagement = () => {
   /**
    * @summary 封禁用户
    */
-  const ban = (id: number) => {
+  const banUser = (id: number) => {
     return customAxiosInstance<ResultVoid>({
       url: `/admin/users/${id}/ban`,
       method: "PUT",
@@ -30,33 +34,34 @@ export const getUserManagement = () => {
    * 重置为默认密码 123456
    * @summary 重置用户密码
    */
-  const resetPassword = (id: number) => {
+  const resetUserPassword = (id: number) => {
     return customAxiosInstance<ResultVoid>({
       url: `/admin/users/${id}/reset-password`,
       method: "POST",
     });
   };
   /**
+   * 支持按用户名模糊搜索
    * @summary 用户列表
    */
-  const list2 = (params?: List2Params) => {
+  const listUsers = (params?: ListUsersParams) => {
     return customAxiosInstance<ResultPageResultUser>({
       url: `/admin/users`,
       method: "GET",
       params,
     });
   };
-  return { unban, ban, resetPassword, list2 };
+  return { unbanUser, banUser, resetUserPassword, listUsers };
 };
-export type UnbanResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getUserManagement>["unban"]>>
+export type UnbanUserResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getUserManagement>["unbanUser"]>>
 >;
-export type BanResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getUserManagement>["ban"]>>
+export type BanUserResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getUserManagement>["banUser"]>>
 >;
-export type ResetPasswordResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getUserManagement>["resetPassword"]>>
+export type ResetUserPasswordResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getUserManagement>["resetUserPassword"]>>
 >;
-export type List2Result = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getUserManagement>["list2"]>>
+export type ListUsersResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getUserManagement>["listUsers"]>>
 >;

+ 7 - 7
src/api/endpoints/users.ts

@@ -11,7 +11,7 @@ export const getUsers = () => {
   /**
    * @summary 获取个人资料
    */
-  const profile = () => {
+  const getUserProfile = () => {
     return customAxiosInstance<ResultUserProfileVO>({
       url: `/user/profile`,
       method: "GET",
@@ -21,7 +21,7 @@ export const getUsers = () => {
    * 支持修改昵称、个性签名、头像
    * @summary 修改个人资料
    */
-  const updateProfile = (userProfileRequest: UserProfileRequest) => {
+  const updateUserProfile = (userProfileRequest: UserProfileRequest) => {
     const formData = new FormData();
     if (userProfileRequest.nickname !== undefined) {
       formData.append("nickname", userProfileRequest.nickname);
@@ -40,11 +40,11 @@ export const getUsers = () => {
       data: formData,
     });
   };
-  return { profile, updateProfile };
+  return { getUserProfile, updateUserProfile };
 };
-export type ProfileResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getUsers>["profile"]>>
+export type GetUserProfileResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getUsers>["getUserProfile"]>>
 >;
-export type UpdateProfileResult = NonNullable<
-  Awaited<ReturnType<ReturnType<typeof getUsers>["updateProfile"]>>
+export type UpdateUserProfileResult = NonNullable<
+  Awaited<ReturnType<ReturnType<typeof getUsers>["updateUserProfile"]>>
 >;

+ 1 - 1
src/api/models/list2Params.ts → src/api/models/getMessageHistoryParams.ts

@@ -5,7 +5,7 @@
  * OpenAPI spec version: v0
  */
 
-export type List2Params = {
+export type GetMessageHistoryParams = {
   pageNum?: number;
   pageSize?: number;
 };

+ 9 - 9
src/api/models/index.ts

@@ -5,19 +5,22 @@
  * OpenAPI spec version: v0
  */
 
-export * from "./boughtParams";
-export * from "./byCategoryParams";
 export * from "./category";
 export * from "./categoryRequest";
 export * from "./changePasswordRequest";
 export * from "./conversationVO";
 export * from "./createOrderRequest";
-export * from "./historyParams";
+export * from "./getMessageHistoryParams";
 export * from "./itemPublishRequest";
 export * from "./itemPublishRequestTradeMethod";
 export * from "./itemVO";
-export * from "./list2Params";
-export * from "./listParams";
+export * from "./listBoughtOrdersParams";
+export * from "./listItemsByCategoryParams";
+export * from "./listItemsParams";
+export * from "./listPendingItemReviewsParams";
+export * from "./listPendingUserReviewsParams";
+export * from "./listSoldOrdersParams";
+export * from "./listUsersParams";
 export * from "./loginRequest";
 export * from "./messageVO";
 export * from "./orderVO";
@@ -25,8 +28,6 @@ export * from "./pageResultItemVO";
 export * from "./pageResultMessageVO";
 export * from "./pageResultOrderVO";
 export * from "./pageResultUser";
-export * from "./pendingItemsParams";
-export * from "./pendingUsersParams";
 export * from "./registerRequest";
 export * from "./resultItemVO";
 export * from "./resultListCategory";
@@ -41,9 +42,8 @@ export * from "./resultUserProfileVO";
 export * from "./resultVoid";
 export * from "./reviewRequest";
 export * from "./reviewRequestResult";
-export * from "./searchParams";
+export * from "./searchItemsParams";
 export * from "./sendMessageRequest";
-export * from "./soldParams";
 export * from "./statusRequest";
 export * from "./submitAuthBody";
 export * from "./user";

+ 1 - 1
src/api/models/historyParams.ts → src/api/models/listBoughtOrdersParams.ts

@@ -5,7 +5,7 @@
  * OpenAPI spec version: v0
  */
 
-export type HistoryParams = {
+export type ListBoughtOrdersParams = {
   pageNum?: number;
   pageSize?: number;
 };

+ 11 - 0
src/api/models/listItemsByCategoryParams.ts

@@ -0,0 +1,11 @@
+/**
+ * Generated by orval v7.0.1 🍺
+ * Do not edit manually.
+ * OpenAPI definition
+ * OpenAPI spec version: v0
+ */
+
+export type ListItemsByCategoryParams = {
+  pageNum?: number;
+  pageSize?: number;
+};

+ 1 - 1
src/api/models/boughtParams.ts → src/api/models/listItemsParams.ts

@@ -5,7 +5,7 @@
  * OpenAPI spec version: v0
  */
 
-export type BoughtParams = {
+export type ListItemsParams = {
   pageNum?: number;
   pageSize?: number;
 };

+ 11 - 0
src/api/models/listPendingItemReviewsParams.ts

@@ -0,0 +1,11 @@
+/**
+ * Generated by orval v7.0.1 🍺
+ * Do not edit manually.
+ * OpenAPI definition
+ * OpenAPI spec version: v0
+ */
+
+export type ListPendingItemReviewsParams = {
+  pageNum?: number;
+  pageSize?: number;
+};

+ 11 - 0
src/api/models/listPendingUserReviewsParams.ts

@@ -0,0 +1,11 @@
+/**
+ * Generated by orval v7.0.1 🍺
+ * Do not edit manually.
+ * OpenAPI definition
+ * OpenAPI spec version: v0
+ */
+
+export type ListPendingUserReviewsParams = {
+  pageNum?: number;
+  pageSize?: number;
+};

+ 1 - 1
src/api/models/byCategoryParams.ts → src/api/models/listSoldOrdersParams.ts

@@ -5,7 +5,7 @@
  * OpenAPI spec version: v0
  */
 
-export type ByCategoryParams = {
+export type ListSoldOrdersParams = {
   pageNum?: number;
   pageSize?: number;
 };

+ 12 - 0
src/api/models/listUsersParams.ts

@@ -0,0 +1,12 @@
+/**
+ * Generated by orval v7.0.1 🍺
+ * Do not edit manually.
+ * OpenAPI definition
+ * OpenAPI spec version: v0
+ */
+
+export type ListUsersParams = {
+  pageNum?: number;
+  pageSize?: number;
+  username?: string;
+};

+ 0 - 11
src/api/models/pendingItemsParams.ts

@@ -1,11 +0,0 @@
-/**
- * Generated by orval v7.0.1 🍺
- * Do not edit manually.
- * OpenAPI definition
- * OpenAPI spec version: v0
- */
-
-export type PendingItemsParams = {
-  pageNum?: number;
-  pageSize?: number;
-};

+ 0 - 11
src/api/models/pendingUsersParams.ts

@@ -1,11 +0,0 @@
-/**
- * Generated by orval v7.0.1 🍺
- * Do not edit manually.
- * OpenAPI definition
- * OpenAPI spec version: v0
- */
-
-export type PendingUsersParams = {
-  pageNum?: number;
-  pageSize?: number;
-};

+ 1 - 1
src/api/models/searchParams.ts → src/api/models/searchItemsParams.ts

@@ -5,7 +5,7 @@
  * OpenAPI spec version: v0
  */
 
-export type SearchParams = {
+export type SearchItemsParams = {
   keyword: string;
   pageNum?: number;
   pageSize?: number;

+ 0 - 11
src/api/models/soldParams.ts

@@ -1,11 +0,0 @@
-/**
- * Generated by orval v7.0.1 🍺
- * Do not edit manually.
- * OpenAPI definition
- * OpenAPI spec version: v0
- */
-
-export type SoldParams = {
-  pageNum?: number;
-  pageSize?: number;
-};

+ 2 - 3
src/api/models/listParams.ts → src/api/models/submitAuthBody.ts

@@ -5,7 +5,6 @@
  * OpenAPI spec version: v0
  */
 
-export type ListParams = {
-  pageNum?: number;
-  pageSize?: number;
+export type SubmitAuthBody = {
+  campusCardImage: Blob;
 };

+ 6 - 0
src/layout/AdminLayout.vue

@@ -9,6 +9,9 @@
         router
         :collapse="isCollapse"
         default-active="/admin/review/user"
+        background-color="#304156"
+        text-color="#bfcbd9"
+        active-text-color="#409EFF"
       >
         <el-menu-item index="/admin/review/user">
           <el-icon><UserFilled /></el-icon>
@@ -107,6 +110,9 @@ const logoutHandler = () => {
   font-size: 18px;
   white-space: nowrap;
 }
+.sidebar .el-menu {
+  border-right: none;
+}
 .header {
   display: flex;
   align-items: center;

+ 15 - 4
src/layout/UserLayout.vue

@@ -15,6 +15,15 @@
           <el-menu-item index="/home">
             <template #title>首页</template>
           </el-menu-item>
+          <el-menu-item index="/my/items">
+            <template #title>我的发布</template>
+          </el-menu-item>
+          <el-menu-item index="/messages">
+            <template #title>消息</template>
+          </el-menu-item>
+          <el-menu-item index="/profile">
+            <template #title>我的</template>
+          </el-menu-item>
           <el-menu-item v-if="isAdmin" index="/admin">
             <template #title>后台管理</template>
           </el-menu-item>
@@ -51,9 +60,9 @@
             <el-icon><HomeFilled /></el-icon>
             <span>首页</span>
           </el-col>
-          <el-col :span="6" @click="router.push('/publish')">
+          <el-col :span="6" @click="router.push('/my/items')">
             <el-icon><Plus /></el-icon>
-            <span>发布</span>
+            <span>我的发布</span>
           </el-col>
           <el-col :span="6" @click="router.push('/messages')">
             <el-icon><ChatDotSquare /></el-icon>
@@ -70,7 +79,8 @@
 </template>
 
 <script setup lang="ts">
-import { computed, ref } from 'vue'
+import { computed } from 'vue'
+import { useRoute } from 'vue-router'
 import { useUserStore, useMetaStore } from '../store'
 import router from '../router'
 import {
@@ -85,7 +95,8 @@ const metaStore = useMetaStore()
 const userStore = useUserStore()
 const login = computed(() => userStore.state.isLoggedIn)
 const isAdmin = computed(() => userStore.state.role === 'ADMIN')
-const activeIndex = ref('/home')
+const route = useRoute()
+const activeIndex = computed(() => route.path)
 
 const logoutHandler = () => {
   userStore.logout()

+ 2 - 1
src/main.ts

@@ -1,6 +1,7 @@
 import { createApp } from 'vue'
 import ElementPlus from 'element-plus'
 import 'element-plus/dist/index.css'
+import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
 import './style.css'
 import App from './App.vue'
 import router from "./router";
@@ -11,6 +12,6 @@ const app = createApp(App)
 const pinia = createPinia()
 pinia.use(piniaPluginPersistedState)
 app.use(router)
-app.use(ElementPlus)
+app.use(ElementPlus, { locale: zhCn })
 app.use(pinia)
 app.mount('#app')

+ 3 - 12
src/router/index.ts

@@ -13,18 +13,6 @@ const routes: RouteRecordRaw[] = [
     component: () => import('../view/Login.vue'),
     meta: { noAuth: true },
   },
-  {
-    path: '/register',
-    name: 'register',
-    component: () => import('../view/Register.vue'),
-    meta: { noAuth: true },
-  },
-  {
-    path: '/admin/login',
-    name: 'adminLogin',
-    component: () => import('../view/admin/Login.vue'),
-    meta: { noAuth: true },
-  },
 
   // C端 — UserLayout
   {
@@ -150,6 +138,9 @@ router.beforeEach((to, _from, next) => {
   } else if (to.meta.requiresAuth && !to.meta.noAuth) {
     if (!userStore.state.isLoggedIn) {
       next({ path: '/login', query: { redirect: to.fullPath } })
+    } else if (to.meta.requiresVerified && userStore.state.authStatus !== 'AUTHENTICATED') {
+      ElMessage.warning('请先完成实名认证')
+      next({ path: '/profile', query: { verify: '1' } })
     } else {
       next()
     }

+ 7 - 2
src/store/user.ts

@@ -5,6 +5,7 @@ export const useUserStore = defineStore('user', () => {
   const state = reactive({
     userId: null as number | null,
     nickname: '',
+    signature: '',
     avatarUrl: '',
     role: '',
     authStatus: '',
@@ -17,12 +18,14 @@ export const useUserStore = defineStore('user', () => {
   function login(user: {
     id: number
     nickname: string
+    signature?: string
     avatarUrl?: string
     role: string
     authStatus: string
   }) {
     state.userId = user.id
     state.nickname = user.nickname
+    state.signature = user.signature ?? ''
     state.avatarUrl = user.avatarUrl ?? ''
     state.role = user.role
     state.authStatus = user.authStatus
@@ -32,14 +35,16 @@ export const useUserStore = defineStore('user', () => {
   function logout() {
     state.userId = null
     state.nickname = ''
+    state.signature = ''
     state.avatarUrl = ''
     state.role = ''
     state.authStatus = ''
     state.isLoggedIn = false
   }
 
-  function updateProfile(profile: { nickname?: string; avatarUrl?: string }) {
+  function updateProfile(profile: { nickname?: string; signature?: string; avatarUrl?: string }) {
     if (profile.nickname !== undefined) state.nickname = profile.nickname
+    if (profile.signature !== undefined) state.signature = profile.signature
     if (profile.avatarUrl !== undefined) state.avatarUrl = profile.avatarUrl
   }
 
@@ -56,4 +61,4 @@ export const useUserStore = defineStore('user', () => {
     updateProfile,
     updateAuthStatus,
   }
-})
+}, { persist: true })

+ 12 - 1
src/util/axios-instance.ts

@@ -1,5 +1,6 @@
 import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios'
 import router from '@/router'
+import { useUserStore } from '@/store'
 
 export interface CustomInstanceConfig extends AxiosRequestConfig {
   skipAuth?: boolean
@@ -14,7 +15,15 @@ const axiosInstance: AxiosInstance = axios.create({
   },
 })
 
-axiosInstance.interceptors.request.use((config) => config, (error) => Promise.reject(error))
+axiosInstance.interceptors.request.use(
+  (config) => {
+    if (config.data instanceof FormData) {
+      delete config.headers['Content-Type']
+    }
+    return config
+  },
+  (error) => Promise.reject(error),
+)
 
 axiosInstance.interceptors.response.use(
   (response: AxiosResponse) => {
@@ -26,6 +35,8 @@ axiosInstance.interceptors.response.use(
   },
   (error) => {
     if (error.response?.status === 401) {
+      const userStore = useUserStore()
+      userStore.logout()
       router.push('/login')
     }
     return Promise.reject(error)

+ 2 - 2
src/view/Chat.vue

@@ -70,7 +70,7 @@ const scrollToBottom = async () => {
 const loadMessages = async () => {
   loading.value = true
   try {
-    const res = await getMessages().history(targetUserId)
+    const res = await getMessages().getMessageHistory(targetUserId)
     if (res.code === 200) {
       messages.value = (res.data?.list ?? []).reverse()
       if (messages.value.length > 0) {
@@ -88,7 +88,7 @@ const loadMessages = async () => {
 const handleSend = async () => {
   if (!text.value.trim()) return
   try {
-    const res = await getMessages().send({ toUserId: targetUserId, content: text.value.trim() })
+    const res = await getMessages().sendMessage({ toUserId: targetUserId, content: text.value.trim() })
     if (res.code === 200) {
       messages.value.push({
         id: res.data,

+ 3 - 3
src/view/Home.vue

@@ -98,8 +98,8 @@ const loadItems = async () => {
     const api = getItems()
     const params = { pageNum: pageNum.value, pageSize }
     const res = categoryId
-      ? await api.byCategory(categoryId, params)
-      : await api.list(params)
+      ? await api.listItemsByCategory(categoryId, params)
+      : await api.listItems(params)
     if (res.code === 200) {
       itemList.value = res.data?.list ?? []
       total.value = res.data?.total ?? 0
@@ -127,7 +127,7 @@ const goDetail = (id?: number) => {
 onMounted(async () => {
   await loadItems()
   try {
-    const res = await getCategories().list1()
+    const res = await getCategories().listCategories()
     if (res.code === 200) {
       categories.value = res.data ?? []
     }

+ 2 - 2
src/view/ItemDetail.vue

@@ -57,7 +57,7 @@ const loadItem = async () => {
   loading.value = true
   try {
     const id = Number(route.params.id)
-    const res = await getItems().detail(id)
+    const res = await getItems().getItemDetail(id)
     if (res.code === 200) {
       item.value = res.data!
     }
@@ -86,7 +86,7 @@ const handleBuy = async () => {
   if (!item.value?.id) return
   try {
     await ElMessageBox.confirm('确定要下单这件物品吗?', '确认下单')
-    const res = await getOrders().create({ itemId: item.value.id })
+    const res = await getOrders().createOrder({ itemId: item.value.id })
     if (res.code === 200) {
       ElMessage.success('下单成功')
       router.push(`/order/${res.data}`)

+ 1 - 1
src/view/Messages.vue

@@ -45,7 +45,7 @@ const loading = ref(false)
 onMounted(async () => {
   loading.value = true
   try {
-    const res = await getMessages().conversations()
+    const res = await getMessages().listConversations()
     if (res.code === 200) {
       conversations.value = res.data ?? []
     }

+ 82 - 15
src/view/MyItems.vue

@@ -1,8 +1,13 @@
 <template>
   <div class="my-items">
-    <h1 class="page-title">我的发布</h1>
+    <div class="page-header">
+      <h1 class="page-title">我的发布</h1>
+      <el-button type="primary" @click="router.push('/publish')">
+        <el-icon><Plus /></el-icon>发布新物品
+      </el-button>
+    </div>
 
-    <el-tabs v-model="activeTab" @tab-change="loadItems">
+    <el-tabs v-model="activeTab" @tab-change="onTabChange">
       <el-tab-pane label="售卖中" name="ON_SALE" />
       <el-tab-pane label="已下架" name="OFF_SHELF" />
       <el-tab-pane label="已售出" name="SOLD" />
@@ -10,7 +15,7 @@
     </el-tabs>
 
     <div v-loading="loading">
-      <div v-for="item in itemList" :key="item.id" class="item-row">
+      <div v-for="item in paginatedItems" :key="item.id" class="item-row">
         <el-card shadow="hover" class="item-card">
           <div class="item-content">
             <el-image
@@ -38,30 +43,59 @@
               <el-button v-if="item.status !== 'SOLD'" size="small" type="danger" @click="handleDelete(item.id)">
                 删除
               </el-button>
+              <el-button v-if="item.status === 'SOLD'" size="small" type="primary" @click="handleViewOrder(item.id)">
+                查看订单
+              </el-button>
             </div>
           </div>
         </el-card>
       </div>
     </div>
 
-    <div v-if="!loading && itemList.length === 0" class="empty-state">
+    <div v-if="!loading && filteredList.length === 0" class="empty-state">
       <el-empty description="暂无物品" />
     </div>
 
-    
+    <el-pagination
+      v-if="total > pageSize"
+      v-model:current-page="pageNum"
+      :total="total"
+      :page-size="pageSize"
+      layout="prev, pager, next"
+      class="pagination"
+    />
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue'
+import { ref, computed, onMounted } from 'vue'
+import { useRouter } from 'vue-router'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import { Picture } from '@element-plus/icons-vue'
+import { Picture, Plus } from '@element-plus/icons-vue'
 import { getItems } from '../api/endpoints/items'
-import type { ItemVO } from '../api/models'
+import { getOrders } from '../api/endpoints/orders'
+import type { ItemVO, OrderVO } from '../api/models'
+
+const router = useRouter()
 
 const activeTab = ref('ON_SALE')
 const itemList = ref<ItemVO[]>([])
 const loading = ref(false)
+const pageNum = ref(1)
+const pageSize = 10
+
+const soldOrders = ref<OrderVO[]>([])
+
+const filteredList = computed(() =>
+  itemList.value.filter((i) => !activeTab.value || i.status === activeTab.value),
+)
+
+const total = computed(() => filteredList.value.length)
+
+const paginatedItems = computed(() => {
+  const start = (pageNum.value - 1) * pageSize
+  return filteredList.value.slice(start, start + pageSize)
+})
 
 const statusLabel = (status?: string) => {
   const map: Record<string, string> = {
@@ -83,25 +117,50 @@ const statusTagType = (status?: string) => {
   return map[status ?? ''] || 'info'
 }
 
+const onTabChange = () => {
+  pageNum.value = 1
+  loadItems()
+}
+
 const loadItems = async () => {
   loading.value = true
   try {
-    const res = await getItems().myItems()
+    const res = await getItems().listMyItems()
     if (res.code === 200) {
-      itemList.value = (res.data ?? []).filter(
-        (i) => !activeTab.value || i.status === activeTab.value,
-      )
+      itemList.value = res.data ?? []
+    }
+    if (activeTab.value === 'SOLD') {
+      await loadSoldOrders()
     }
   } finally {
     loading.value = false
   }
 }
 
+const loadSoldOrders = async () => {
+  try {
+    const res = await getOrders().listSoldOrders({ pageNum: 1, pageSize: 100 })
+    if (res.code === 200) {
+      soldOrders.value = res.data?.list ?? []
+    }
+  } catch { /* ignore */ }
+}
+
+const handleViewOrder = (itemId?: number) => {
+  if (!itemId) return
+  const order = soldOrders.value.find((o) => o.itemId === itemId)
+  if (order?.id) {
+    router.push(`/order/${order.id}`)
+  } else {
+    ElMessage.warning('未找到对应订单')
+  }
+}
+
 const handleOffline = async (id?: number) => {
   if (!id) return
   try {
     await ElMessageBox.confirm('确定下架该物品?', '确认')
-    const res = await getItems().offline(id)
+    const res = await getItems().offlineItem(id)
     if (res.code === 200) {
       ElMessage.success('已下架')
       loadItems()
@@ -113,13 +172,15 @@ const handleDelete = async (id?: number) => {
   if (!id) return
   try {
     await ElMessageBox.confirm('确定删除该物品?删除后不可恢复', '确认', { type: 'warning' })
-    const res = await getItems()._delete(id)
+    const res = await getItems().deleteItem(id)
     if (res.code === 200) {
       ElMessage.success('已删除')
       loadItems()
     }
   } catch { /* cancelled */ }
 }
+
+onMounted(loadItems)
 </script>
 
 <style scoped>
@@ -128,9 +189,15 @@ const handleDelete = async (id?: number) => {
   margin: 0 auto;
   padding: 20px;
 }
+.page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
 .page-title {
   font-size: 24px;
-  margin-bottom: 20px;
+  margin: 0;
 }
 .item-row {
   margin-bottom: 12px;

+ 150 - 18
src/view/MyOrders.vue

@@ -2,14 +2,23 @@
   <div class="my-orders">
     <h1 class="page-title">我的订单</h1>
 
-    <el-tabs v-model="activeTab" @tab-change="loadOrders">
+    <el-tabs v-model="activeTab" @tab-change="onTabChange">
       <el-tab-pane label="我买到的" name="bought" />
       <el-tab-pane label="我卖出的" name="sold" />
     </el-tabs>
 
+    <el-radio-group v-model="statusFilter" size="small" class="status-filter" @change="onFilterChange">
+      <el-radio-button label="">全部</el-radio-button>
+      <el-radio-button label="PENDING">待接单</el-radio-button>
+      <el-radio-button label="CONFIRMED">待面交</el-radio-button>
+      <el-radio-button label="DELIVERED">待收货</el-radio-button>
+      <el-radio-button label="COMPLETED">已完成</el-radio-button>
+      <el-radio-button label="CANCELLED">已取消</el-radio-button>
+    </el-radio-group>
+
     <div v-loading="loading">
-      <div v-for="order in orderList" :key="order.id" class="order-row">
-        <el-card shadow="hover" class="order-card" @click="router.push(`/order/${order.id}`)">
+      <div v-for="order in paginatedOrders" :key="order.id" class="order-row">
+        <el-card shadow="hover" class="order-card" @click="goToDetail(order)">
           <div class="order-content">
             <el-image
               :src="order.itemImage"
@@ -28,18 +37,42 @@
               <span class="order-trader">
                 {{ activeTab === 'bought' ? '卖家:' + order.sellerNickname : '买家:' + order.buyerNickname }}
               </span>
-            </div>
-            <div class="order-status">
-              <el-tag :type="statusTagType(order.status)" size="large">
+              <el-tag :type="statusTagType(order.status)" size="small" class="order-tag">
                 {{ statusLabel(order.status) }}
               </el-tag>
             </div>
+            <div class="order-actions" @click.stop>
+              <el-button
+                v-if="activeTab === 'sold' && order.status === 'PENDING'"
+                size="small" type="primary" @click="handleAccept(order)"
+              >
+                接单
+              </el-button>
+              <el-button
+                v-if="activeTab === 'sold' && order.status === 'PENDING'"
+                size="small" type="danger" @click="handleReject(order)"
+              >
+                拒单
+              </el-button>
+              <el-button
+                v-if="activeTab === 'sold' && order.status === 'CONFIRMED'"
+                size="small" type="primary" @click="handleDeliver(order)"
+              >
+                确认交货
+              </el-button>
+              <el-button
+                v-if="activeTab === 'bought' && order.status === 'DELIVERED'"
+                size="small" type="success" @click="handleConfirm(order)"
+              >
+                确认收货
+              </el-button>
+            </div>
           </div>
         </el-card>
       </div>
     </div>
 
-    <div v-if="!loading && orderList.length === 0" class="empty-state">
+    <div v-if="!loading && filteredOrders.length === 0" class="empty-state">
       <el-empty description="暂无订单" />
     </div>
 
@@ -50,25 +83,37 @@
       :page-size="pageSize"
       layout="prev, pager, next"
       class="pagination"
-      @current-change="loadOrders"
     />
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue'
+import { ref, computed, onMounted } from 'vue'
 import { useRouter } from 'vue-router'
+import { ElMessage, ElMessageBox } from 'element-plus'
 import { Picture } from '@element-plus/icons-vue'
 import { getOrders } from '../api/endpoints/orders'
 import type { OrderVO } from '../api/models'
 
 const router = useRouter()
 const activeTab = ref('bought')
-const orderList = ref<OrderVO[]>([])
-const total = ref(0)
+const allOrders = ref<OrderVO[]>([])
+const loading = ref(false)
 const pageNum = ref(1)
 const pageSize = 10
-const loading = ref(false)
+const statusFilter = ref('')
+
+const filteredOrders = computed(() => {
+  if (!statusFilter.value) return allOrders.value
+  return allOrders.value.filter((o) => o.status === statusFilter.value)
+})
+
+const total = computed(() => filteredOrders.value.length)
+
+const paginatedOrders = computed(() => {
+  const start = (pageNum.value - 1) * pageSize
+  return filteredOrders.value.slice(start, start + pageSize)
+})
 
 const statusLabel = (status?: string) => {
   const map: Record<string, string> = {
@@ -92,22 +137,94 @@ const statusTagType = (status?: string) => {
   return map[status ?? ''] || 'info'
 }
 
+const onTabChange = () => {
+  pageNum.value = 1
+  statusFilter.value = ''
+  loadOrders()
+}
+
+const onFilterChange = () => {
+  pageNum.value = 1
+}
+
 const loadOrders = async () => {
   loading.value = true
   try {
     const api = getOrders()
-    const params = { pageNum: pageNum.value, pageSize }
+    const params = { pageNum: 1, pageSize: 100 }
     const res = activeTab.value === 'bought'
-      ? await api.bought(params)
-      : await api.sold(params)
+      ? await api.listBoughtOrders(params)
+      : await api.listSoldOrders(params)
     if (res.code === 200) {
-      orderList.value = res.data?.list ?? []
-      total.value = res.data?.total ?? 0
+      allOrders.value = res.data?.list ?? []
     }
   } finally {
     loading.value = false
   }
 }
+
+const goToDetail = (order: OrderVO) => {
+  router.push({
+    path: `/order/${order.id}`,
+    state: { orderData: JSON.parse(JSON.stringify(order)) },
+  })
+}
+
+const handleAccept = async (order: OrderVO) => {
+  if (!order.id) return
+  try {
+    const res = await getOrders().acceptOrder(order.id)
+    if (res.code === 200) {
+      ElMessage.success('已接单')
+      loadOrders()
+    }
+  } catch (err: unknown) {
+    if (err && typeof err === 'object' && 'message' in err) {
+      ElMessage.error((err as { message: string }).message)
+    }
+  }
+}
+
+const handleReject = async (order: OrderVO) => {
+  if (!order.id) return
+  try {
+    await ElMessageBox.confirm('确定拒绝该订单?', '确认')
+    const res = await getOrders().rejectOrder(order.id)
+    if (res.code === 200) {
+      ElMessage.success('已拒单')
+      loadOrders()
+    }
+  } catch { /* cancelled */ }
+}
+
+const handleDeliver = async (order: OrderVO) => {
+  if (!order.id) return
+  try {
+    const res = await getOrders().deliverOrder(order.id)
+    if (res.code === 200) {
+      ElMessage.success('已确认交货,等待买家收货')
+      loadOrders()
+    }
+  } catch (err: unknown) {
+    if (err && typeof err === 'object' && 'message' in err) {
+      ElMessage.error((err as { message: string }).message)
+    }
+  }
+}
+
+const handleConfirm = async (order: OrderVO) => {
+  if (!order.id) return
+  try {
+    await ElMessageBox.confirm('确定已收到物品?', '确认收货')
+    const res = await getOrders().confirmOrder(order.id)
+    if (res.code === 200) {
+      ElMessage.success('交易完成')
+      loadOrders()
+    }
+  } catch { /* cancelled */ }
+}
+
+onMounted(loadOrders)
 </script>
 
 <style scoped>
@@ -120,8 +237,16 @@ const loadOrders = async () => {
   font-size: 24px;
   margin-bottom: 20px;
 }
+.status-filter {
+  margin-bottom: 16px;
+  display: flex;
+  flex-wrap: wrap;
+  gap: 4px;
+}
 .order-row {
   margin-bottom: 12px;
+}
+.order-card {
   cursor: pointer;
 }
 .order-content {
@@ -147,6 +272,7 @@ const loadOrders = async () => {
 }
 .order-info {
   flex: 1;
+  min-width: 0;
 }
 .order-title {
   margin: 0 0 4px;
@@ -164,8 +290,14 @@ const loadOrders = async () => {
   display: block;
   margin-top: 4px;
 }
-.order-status {
+.order-tag {
+  margin-top: 4px;
+}
+.order-actions {
   flex-shrink: 0;
+  display: flex;
+  flex-direction: column;
+  gap: 6px;
 }
 .empty-state {
   padding: 40px 0;

+ 20 - 8
src/view/OrderDetail.vue

@@ -136,7 +136,7 @@ const timelineSteps = computed(() => {
 const handleAccept = async () => {
   if (!order.value?.id) return
   try {
-    const res = await getOrders().accept(order.value.id)
+    const res = await getOrders().acceptOrder(order.value.id)
     if (res.code === 200) {
       ElMessage.success('已接单')
       await loadOrder()
@@ -152,7 +152,7 @@ const handleReject = async () => {
   if (!order.value?.id) return
   try {
     await ElMessageBox.confirm('确定拒绝该订单?', '确认')
-    const res = await getOrders().reject(order.value.id)
+    const res = await getOrders().rejectOrder(order.value.id)
     if (res.code === 200) {
       ElMessage.success('已拒单')
       await loadOrder()
@@ -163,7 +163,7 @@ const handleReject = async () => {
 const handleDeliver = async () => {
   if (!order.value?.id) return
   try {
-    const res = await getOrders().deliver(order.value.id)
+    const res = await getOrders().deliverOrder(order.value.id)
     if (res.code === 200) {
       ElMessage.success('已确认交货,等待买家收货')
       await loadOrder()
@@ -179,7 +179,7 @@ const handleConfirm = async () => {
   if (!order.value?.id) return
   try {
     await ElMessageBox.confirm('确定已收到物品?', '确认收货')
-    const res = await getOrders().confirm(order.value.id)
+    const res = await getOrders().confirmOrder(order.value.id)
     if (res.code === 200) {
       ElMessage.success('交易完成')
       await loadOrder()
@@ -194,14 +194,26 @@ const handleContact = () => {
 }
 
 const loadOrder = async () => {
+  const id = Number(route.params.id)
+
+  const stateOrder = (history.state as Record<string, any>)?.orderData as OrderVO | undefined
+  if (stateOrder?.id === id) {
+    order.value = stateOrder
+    return
+  }
+
   loading.value = true
   try {
-    const id = Number(route.params.id)
     const api = getOrders()
-    const [boughtRes, soldRes] = await Promise.all([api.bought(), api.sold()])
+    const [boughtRes, soldRes] = await Promise.all([
+      api.listBoughtOrders({ pageNum: 1, pageSize: 100 }),
+      api.listSoldOrders({ pageNum: 1, pageSize: 100 }),
+    ])
+    const list1 = boughtRes.data?.list ?? []
+    const list2 = soldRes.data?.list ?? []
     order.value =
-      boughtRes.data?.list?.find((o) => o.id === id) ??
-      soldRes.data?.list?.find((o) => o.id === id) ??
+      list1.find((o) => o.id === id) ??
+      list2.find((o) => o.id === id) ??
       null
   } finally {
     loading.value = false

+ 36 - 4
src/view/Profile.vue

@@ -62,6 +62,13 @@
       </div>
     </el-card>
 
+    <el-card class="entry-card" @click="router.push('/my/orders')">
+      <div class="entry-item">
+        <span>我的订单</span>
+        <el-icon><ArrowRight /></el-icon>
+      </div>
+    </el-card>
+
     <el-dialog v-model="dialogVisible" title="实名认证" width="420px" :close-on-click-modal="false">
       <el-form label-width="100px">
         <el-form-item label="校园卡照片">
@@ -91,7 +98,7 @@
 import { ref, computed, onMounted } from 'vue'
 import { useRouter, useRoute } from 'vue-router'
 import { ElMessage } from 'element-plus'
-import { Plus } from '@element-plus/icons-vue'
+import { Plus, ArrowRight } from '@element-plus/icons-vue'
 import type { UploadFile, UploadRawFile, UploadUserFile } from 'element-plus'
 import { useUserStore } from '../store'
 import { getUsers } from '../api/endpoints/users'
@@ -186,22 +193,37 @@ const handleAvatarChange = (event: Event) => {
   }
 }
 
-onMounted(() => {
+onMounted(async () => {
   if (route.query.verify === '1') {
     dialogVisible.value = true
   }
+  try {
+    const res = await getUsers().getUserProfile()
+    if (res.code === 200 && res.data) {
+      nickname.value = res.data.nickname ?? ''
+      signature.value = res.data.signature ?? ''
+      if (res.data.avatarUrl) {
+        userStore.updateProfile({ avatarUrl: res.data.avatarUrl })
+      }
+    }
+  } catch {
+    // ignore
+  }
 })
 
 const handleSave = async () => {
   saving.value = true
   try {
-    const res = await getUsers().updateProfile({
+    const res = await getUsers().updateUserProfile({
       nickname: nickname.value,
       signature: signature.value,
       ...(avatarFile.value ? { avatar: avatarFile.value } : {}),
     })
     if (res.code === 200) {
-      userStore.updateProfile({ nickname: nickname.value })
+      userStore.updateProfile({
+        nickname: nickname.value,
+        signature: signature.value,
+      })
       if (res.data?.avatarUrl) {
         userStore.updateProfile({ avatarUrl: res.data.avatarUrl })
       }
@@ -246,4 +268,14 @@ const handleSave = async () => {
   color: #909399;
   margin-top: 8px;
 }
+.entry-card {
+  margin-top: 16px;
+  cursor: pointer;
+}
+.entry-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 16px;
+}
 </style>

+ 2 - 2
src/view/Publish.vue

@@ -98,7 +98,7 @@ const handlePublish = async () => {
 
   submitting.value = true
   try {
-    const res = await getItems().publish({
+    const res = await getItems().publishItem({
       title: form.title,
       description: form.description,
       price: form.price,
@@ -121,7 +121,7 @@ const handlePublish = async () => {
 
 onMounted(async () => {
   try {
-    const res = await getCategories().list1()
+    const res = await getCategories().listCategories()
     if (res.code === 200) categories.value = res.data ?? []
   } catch { /* ignore */ }
 })

+ 4 - 4
src/view/Search.vue

@@ -91,11 +91,11 @@ const doSearch = async () => {
     const params = { pageNum: pageNum.value, pageSize }
     let res
     if (keyword.value.trim()) {
-      res = await api.search({ keyword: keyword.value.trim(), ...params })
+      res = await api.searchItems({ keyword: keyword.value.trim(), ...params })
     } else if (categoryId.value) {
-      res = await api.byCategory(categoryId.value, params)
+      res = await api.listItemsByCategory(categoryId.value, params)
     } else {
-      res = await api.list(params)
+      res = await api.listItems(params)
     }
     if (res.code === 200) {
       itemList.value = res.data?.list ?? []
@@ -116,7 +116,7 @@ onMounted(async () => {
     doSearch()
   }
   try {
-    const res = await getCategories().list1()
+    const res = await getCategories().listCategories()
     if (res.code === 200) categories.value = res.data ?? []
   } catch { /* ignore */ }
 })

+ 4 - 4
src/view/admin/CategoryManage.vue

@@ -77,7 +77,7 @@ const rules: FormRules = {
 const loadCategories = async () => {
   loading.value = true
   try {
-    const res = await getCategories().list1()
+    const res = await getCategories().listCategories()
     if (res.code === 200) {
       categories.value = res.data ?? []
     }
@@ -108,10 +108,10 @@ const handleSave = async () => {
   saving.value = true
   try {
     if (dialog.isEdit) {
-      const res = await getCategories().update(dialog.editId, { name: dialog.form.name, sortOrder: dialog.form.sortOrder })
+      const res = await getCategories().updateCategory(dialog.editId, { name: dialog.form.name, sortOrder: dialog.form.sortOrder })
       if (res.code === 200) ElMessage.success('修改成功')
     } else {
-      const res = await getCategories().create1({ name: dialog.form.name, sortOrder: dialog.form.sortOrder })
+      const res = await getCategories().createCategory({ name: dialog.form.name, sortOrder: dialog.form.sortOrder })
       if (res.code === 200) ElMessage.success('新增成功')
     }
     dialog.visible = false
@@ -128,7 +128,7 @@ const handleSave = async () => {
 const handleToggleStatus = async (row: Category) => {
   const newStatus = row.status === 'ENABLED' ? 'DISABLED' : 'ENABLED'
   try {
-    const res = await getCategories().toggleStatus(row.id ?? 0, { status: newStatus })
+    const res = await getCategories().toggleCategoryStatus(row.id ?? 0, { status: newStatus })
     if (res.code === 200) {
       ElMessage.success(newStatus === 'ENABLED' ? '已启用' : '已禁用')
       loadCategories()

+ 3 - 3
src/view/admin/ReviewItem.vue

@@ -56,7 +56,7 @@ const rejectDialog = reactive({
 const loadItems = async () => {
   loading.value = true
   try {
-    const res = await getReviews().pendingItems({ pageNum: pageNum.value, pageSize })
+    const res = await getReviews().listPendingItemReviews({ pageNum: pageNum.value, pageSize })
     if (res.code === 200) {
       itemList.value = res.data?.list ?? []
       total.value = res.data?.total ?? 0
@@ -70,7 +70,7 @@ onMounted(loadItems)
 
 const handleApprove = async (id: number) => {
   try {
-    const res = await getReviews().reviewItem(id, { result: 'APPROVED' })
+    const res = await getReviews().reviewItemListing(id, { result: 'APPROVED' })
     if (res.code === 200) {
       ElMessage.success('已上架')
       loadItems()
@@ -90,7 +90,7 @@ const handleReject = (id: number) => {
 
 const confirmReject = async () => {
   try {
-    const res = await getReviews().reviewItem(rejectDialog.itemId, { result: 'REJECTED', reason: rejectDialog.reason })
+    const res = await getReviews().reviewItemListing(rejectDialog.itemId, { result: 'REJECTED', reason: rejectDialog.reason })
     if (res.code === 200) {
       ElMessage.success('已驳回')
       rejectDialog.visible = false

+ 3 - 3
src/view/admin/ReviewUser.vue

@@ -68,7 +68,7 @@ const rejectDialog = reactive({
 const loadUsers = async () => {
   loading.value = true
   try {
-    const res = await getReviews().pendingUsers({ pageNum: pageNum.value, pageSize })
+    const res = await getReviews().listPendingUserReviews({ pageNum: pageNum.value, pageSize })
     if (res.code === 200) {
       userList.value = res.data?.list ?? []
       total.value = res.data?.total ?? 0
@@ -82,7 +82,7 @@ onMounted(loadUsers)
 
 const handleApprove = async (id: number) => {
   try {
-    const res = await getReviews().reviewUser(id, { result: 'APPROVED' })
+    const res = await getReviews().reviewUserAuth(id, { result: 'APPROVED' })
     if (res.code === 200) {
       ElMessage.success('已通过')
       loadUsers()
@@ -102,7 +102,7 @@ const handleReject = (id: number) => {
 
 const confirmReject = async () => {
   try {
-    const res = await getReviews().reviewUser(rejectDialog.userId, { result: 'REJECTED', reason: rejectDialog.reason })
+    const res = await getReviews().reviewUserAuth(rejectDialog.userId, { result: 'REJECTED', reason: rejectDialog.reason })
     if (res.code === 200) {
       ElMessage.success('已驳回')
       rejectDialog.visible = false

+ 4 - 4
src/view/admin/UserManage.vue

@@ -19,7 +19,7 @@ const statusFilter = ref('')
 const fetchData = async () => {
   loading.value = true
   try {
-    const res = await getUserManagement().list2({ pageNum: pagination.pageNum, pageSize: pagination.pageSize })
+    const res = await getUserManagement().listUsers({ pageNum: pagination.pageNum, pageSize: pagination.pageSize })
     if (res.code === 200) {
       tableData.value = res.data?.list ?? []
       pagination.total = res.data?.total ?? 0
@@ -59,8 +59,8 @@ const handleToggleBan = async (row: User) => {
   try {
     await ElMessageBox.confirm(`确定${isBanned ? '解封' : '封禁'}用户 ${row.nickname || row.name || row.studentId}?`, '确认')
     const res = isBanned
-      ? await getUserManagement().unban(row.id)
-      : await getUserManagement().ban(row.id)
+      ? await getUserManagement().unbanUser(row.id)
+      : await getUserManagement().banUser(row.id)
     if (res.code === 200) {
       ElMessage.success(isBanned ? '已解封' : '已封禁')
       fetchData()
@@ -72,7 +72,7 @@ const handleResetPassword = async (row: User) => {
   if (!row.id) return
   try {
     await ElMessageBox.confirm(`确定重置用户 ${row.nickname || row.name || row.studentId} 的密码为 123456?`, '确认')
-    const res = await getUserManagement().resetPassword(row.id)
+    const res = await getUserManagement().resetUserPassword(row.id)
     if (res.code === 200) {
       ElMessage.success('密码已重置为 123456')
     }

+ 6 - 0
src/vite-env.d.ts

@@ -1 +1,7 @@
 /// <reference types="vite/client" />
+
+declare module 'element-plus/dist/locale/zh-cn.mjs' {
+  import type { Language } from 'element-plus/es/locale'
+  const zhCn: Language
+  export default zhCn
+}