Lijingyang 2 месяцев назад
Родитель
Сommit
f0247101a9
63 измененных файлов с 4368 добавлено и 5738 удалено
  1. 63 0
      src/api/classification/index.ts
  2. 86 0
      src/api/classification/types.ts
  3. 2 2
      src/api/product/afterSales/index.ts
  4. 63 0
      src/api/product/associate/index.ts
  5. 101 0
      src/api/product/associate/types.ts
  6. 0 5
      src/api/product/attributes/types.ts
  7. 22 2
      src/api/product/base/index.ts
  8. 0 48
      src/api/product/base/types.ts
  9. 63 0
      src/api/product/blacklist/index.ts
  10. 86 0
      src/api/product/blacklist/types.ts
  11. 11 0
      src/api/product/category/index.ts
  12. 63 0
      src/api/product/classification/index.ts
  13. 86 0
      src/api/product/classification/types.ts
  14. 1 1
      src/api/product/contracproduct/index.ts
  15. 0 0
      src/api/product/contracproduct/types.ts
  16. 63 0
      src/api/product/customization/index.ts
  17. 161 0
      src/api/product/customization/types.ts
  18. 28 6
      src/api/product/extend/index.ts
  19. 566 32
      src/api/product/extend/types.ts
  20. 24 2
      src/api/product/lable/index.ts
  21. 77 5
      src/api/product/lable/types.ts
  22. 40 3
      src/api/product/pool/index.ts
  23. 220 24
      src/api/product/pool/types.ts
  24. 132 0
      src/api/product/poolLink/index.ts
  25. 267 0
      src/api/product/poolLink/types.ts
  26. 63 0
      src/api/product/priceInventory/index.ts
  27. 206 0
      src/api/product/priceInventory/types.ts
  28. 63 0
      src/api/product/program/index.ts
  29. 210 0
      src/api/product/program/types.ts
  30. 63 0
      src/api/product/programLink/index.ts
  31. 71 0
      src/api/product/programLink/types.ts
  32. 24 2
      src/api/product/recommend/index.ts
  33. 100 8
      src/api/product/recommend/types.ts
  34. 63 0
      src/api/product/recommendLink/index.ts
  35. 71 0
      src/api/product/recommendLink/types.ts
  36. 63 0
      src/api/product/specs/index.ts
  37. 86 0
      src/api/product/specs/types.ts
  38. 63 0
      src/api/product/taxrate/index.ts
  39. 116 0
      src/api/product/taxrate/types.ts
  40. 63 0
      src/api/product/volumeUnit/index.ts
  41. 71 0
      src/api/product/volumeUnit/types.ts
  42. 0 63
      src/api/product/warehouseInventory/index.ts
  43. 0 176
      src/api/product/warehouseInventory/types.ts
  44. 63 0
      src/api/product/weightUnit/index.ts
  45. 71 0
      src/api/product/weightUnit/types.ts
  46. 63 0
      src/api/taxrate/index.ts
  47. 116 0
      src/api/taxrate/types.ts
  48. 63 0
      src/api/unit/index.ts
  49. 101 0
      src/api/unit/types.ts
  50. 63 0
      src/api/volumeUnit/index.ts
  51. 71 0
      src/api/volumeUnit/types.ts
  52. 63 0
      src/api/weightUnit/index.ts
  53. 71 0
      src/api/weightUnit/types.ts
  54. 0 256
      src/views/product/associate/index.vue
  55. 0 1661
      src/views/product/base/add.vue
  56. 0 595
      src/views/product/base/index.vue
  57. 0 559
      src/views/product/base/review.vue
  58. 0 529
      src/views/product/base/shelfReview.vue
  59. 2 2
      src/views/product/classification/index.vue
  60. 0 307
      src/views/product/customization/index.vue
  61. 0 295
      src/views/product/products/index.vue
  62. 0 491
      src/views/product/protocolInfo/index.vue
  63. 0 664
      src/views/product/protocolInfo/productManage.vue

+ 63 - 0
src/api/classification/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { ClassificationVO, ClassificationForm, ClassificationQuery } from '@/api/classification/types';
+
+/**
+ * 查询产品属性关联列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listClassification = (query?: ClassificationQuery): AxiosPromise<ClassificationVO[]> => {
+  return request({
+    url: '/product/classification/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品属性关联详细
+ * @param id
+ */
+export const getClassification = (id: string | number): AxiosPromise<ClassificationVO> => {
+  return request({
+    url: '/product/classification/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品属性关联
+ * @param data
+ */
+export const addClassification = (data: ClassificationForm) => {
+  return request({
+    url: '/product/classification',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品属性关联
+ * @param data
+ */
+export const updateClassification = (data: ClassificationForm) => {
+  return request({
+    url: '/product/classification',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品属性关联
+ * @param id
+ */
+export const delClassification = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/classification/' + id,
+    method: 'delete'
+  });
+};

+ 86 - 0
src/api/classification/types.ts

@@ -0,0 +1,86 @@
+export interface ClassificationVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 产品id
+   */
+  productId: string | number;
+
+  /**
+   * 分类编号
+   */
+  categoryId: string | number;
+
+  /**
+   * 属性列表(JSON或分号分隔等格式)
+   */
+  attributesList: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface ClassificationForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 分类编号
+   */
+  categoryId?: string | number;
+
+  /**
+   * 属性列表(JSON或分号分隔等格式)
+   */
+  attributesList?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface ClassificationQuery extends PageQuery {
+
+  /**
+   * 产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 分类编号
+   */
+  categoryId?: string | number;
+
+  /**
+   * 属性列表(JSON或分号分隔等格式)
+   */
+  attributesList?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 2 - 2
src/api/product/afterSales/index.ts

@@ -1,6 +1,6 @@
-import request from '../../../../../yoe-pms-web/src/utils/request';
+import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
-import { AfterSalesVO, AfterSalesForm, AfterSalesQuery } from './types';
+import { AfterSalesVO, AfterSalesForm, AfterSalesQuery } from '@/api/product/afterSales/types';
 
 /**
  * 查询产品售后服务项列表

+ 63 - 0
src/api/product/associate/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { AssociateVO, AssociateForm, AssociateQuery } from '@/api/product/associate/types';
+
+/**
+ * 查询产品关联列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listAssociate = (query?: AssociateQuery): AxiosPromise<AssociateVO[]> => {
+  return request({
+    url: '/product/associate/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品关联详细
+ * @param id
+ */
+export const getAssociate = (id: string | number): AxiosPromise<AssociateVO> => {
+  return request({
+    url: '/product/associate/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品关联
+ * @param data
+ */
+export const addAssociate = (data: AssociateForm) => {
+  return request({
+    url: '/product/associate',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品关联
+ * @param data
+ */
+export const updateAssociate = (data: AssociateForm) => {
+  return request({
+    url: '/product/associate',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品关联
+ * @param id
+ */
+export const delAssociate = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/associate/' + id,
+    method: 'delete'
+  });
+};

+ 101 - 0
src/api/product/associate/types.ts

@@ -0,0 +1,101 @@
+export interface AssociateVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 主产品id
+   */
+  productId: string | number;
+
+  /**
+   * 关联产品编号列表(如:用逗号分隔的产品编号)
+   */
+  productIds: string | number;
+
+  /**
+   * 是否单向关联:0=双向,1=单向
+   */
+  isUnidirectional: string | number;
+
+  /**
+   * 关联标题/展示名称
+   */
+  relatedTitle: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface AssociateForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 主产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 关联产品编号列表(如:用逗号分隔的产品编号)
+   */
+  productIds?: string | number;
+
+  /**
+   * 是否单向关联:0=双向,1=单向
+   */
+  isUnidirectional?: string | number;
+
+  /**
+   * 关联标题/展示名称
+   */
+  relatedTitle?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface AssociateQuery extends PageQuery {
+
+  /**
+   * 主产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 关联产品编号列表(如:用逗号分隔的产品编号)
+   */
+  productIds?: string | number;
+
+  /**
+   * 是否单向关联:0=双向,1=单向
+   */
+  isUnidirectional?: string | number;
+
+  /**
+   * 关联标题/展示名称
+   */
+  relatedTitle?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 0 - 5
src/api/product/attributes/types.ts

@@ -116,11 +116,6 @@ export interface AttributesQuery extends PageQuery {
    */
   categoryId?: string | number;
 
-  /**
-   * 分类名称(用于模糊搜索)
-   */
-  categoryName?: string;
-
   /**
    * 属性编码(用于系统识别)
    */

+ 22 - 2
src/api/product/base/index.ts

@@ -1,6 +1,6 @@
 import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
-import { BaseVO, BaseForm, BaseQuery } from '@/api/product/base/types';
+import { BaseVO, BaseForm, BaseQuery, StatusCountVo } from '@/api/product/base/types';
 import { CategoryQuery, categoryTreeVO, CategoryVO } from '../category/types';
 import { BrandQuery, BrandVO } from '../brand/types';
 import { AttributesVO } from '../attributes/types';
@@ -168,7 +168,7 @@ export const reviewBase = (data: BaseForm) => {
 };
 
 /**
- * 商品上下架 状态变更
+ * 商品上下架审核
  * @param data 审核信息(包含id、productStatus、shelfComments)
  */
 export const shelfReview = (data: BaseForm) => {
@@ -178,4 +178,24 @@ export const shelfReview = (data: BaseForm) => {
     data: data
   });
 };
+/**
+ * 获取所有商品各个状态数量
+ */
+export const getProductStatusCount = (): AxiosPromise<StatusCountVo> => {
+  return request({
+    url: '/product/base/getProductStatusCount',
+    method: 'get'
+  });
+};
+/**
+ * 商品类型改变  1=默认类型,2精选商品,3=停售商品
+ * @param data 停售信息(包含id、productStatus、shelfComments)
+ */
+export const changeProductType = (data: BaseForm) => {
+  return request({
+    url: '/product/base/changeProductType',
+    method: 'post',
+    data: data
+  });
+};
 

+ 0 - 48
src/api/product/base/types.ts

@@ -243,41 +243,6 @@ export interface BaseVO {
    */
   attributesList?: string;
 
-  /**
-   * 品牌名称
-   */
-  brandName?: string;
-
-  /**
-   * 分类名称
-   */
-  categoryName?: string;
-
-  /**
-   * 单位名称
-   */
-  unitName?: string;
-
-  /**
-   * 可用库存数
-   */
-  availableStock?: number;
-
-  /**
-   * 实际库存
-   */
-  actualStock?: number;
-
-  /**
-   * 虚拟库存
-   */
-  virtualStock?: number;
-
-  /**
-   * 对接状态
-   */
-  connectStatus?: string;
-
 }
 
 export interface BaseForm extends BaseEntity {
@@ -745,20 +710,7 @@ export interface BaseQuery extends PageQuery {
    */
   projectOrg?: string;
 
-  /**
-   * 游标分页 - 上次看到的ID
-   */
-  lastSeenId?: string | number;
 
-  /**
-   * 游标分页 - 第一个ID(用于上一页)
-   */
-  firstSeenId?: string | number;
-
-  /**
-   * 游标分页方向 0=上一页,1=下一页
-   */
-  way?: number;
 
     /**
      * 日期范围参数

+ 63 - 0
src/api/product/blacklist/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { BlacklistVO, BlacklistForm, BlacklistQuery } from '@/api/product/blacklist/types';
+
+/**
+ * 查询产品黑名单列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listBlacklist = (query?: BlacklistQuery): AxiosPromise<BlacklistVO[]> => {
+  return request({
+    url: '/product/blacklist/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品黑名单详细
+ * @param id
+ */
+export const getBlacklist = (id: string | number): AxiosPromise<BlacklistVO> => {
+  return request({
+    url: '/product/blacklist/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品黑名单
+ * @param data
+ */
+export const addBlacklist = (data: BlacklistForm) => {
+  return request({
+    url: '/product/blacklist',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品黑名单
+ * @param data
+ */
+export const updateBlacklist = (data: BlacklistForm) => {
+  return request({
+    url: '/product/blacklist',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品黑名单
+ * @param id
+ */
+export const delBlacklist = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/blacklist/' + id,
+    method: 'delete'
+  });
+};

+ 86 - 0
src/api/product/blacklist/types.ts

@@ -0,0 +1,86 @@
+export interface BlacklistVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 客户id(可为空,表示全局黑名单)
+   */
+  customerId: string | number;
+
+  /**
+   * 产品id(可为空,表示该客户对整个分类禁用)
+   */
+  productId: string | number;
+
+  /**
+   * 产品分类id(必填)
+   */
+  productCategoryId: string | number;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface BlacklistForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 客户id(可为空,表示全局黑名单)
+   */
+  customerId?: string | number;
+
+  /**
+   * 产品id(可为空,表示该客户对整个分类禁用)
+   */
+  productId?: string | number;
+
+  /**
+   * 产品分类id(必填)
+   */
+  productCategoryId?: string | number;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface BlacklistQuery extends PageQuery {
+
+  /**
+   * 客户id(可为空,表示全局黑名单)
+   */
+  customerId?: string | number;
+
+  /**
+   * 产品id(可为空,表示该客户对整个分类禁用)
+   */
+  productId?: string | number;
+
+  /**
+   * 产品分类id(必填)
+   */
+  productCategoryId?: string | number;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 11 - 0
src/api/product/category/index.ts

@@ -82,3 +82,14 @@ export const getProductCategoryList = () => {
     method: 'get'
   });
 };
+
+export const setCategoryReviewer = (categoryId: string | number, reviewerUserId: string | number) => {
+  return request({
+    url: '/product/category/setReviewer',
+    method: 'post',
+    data: {
+      categoryId,
+      reviewerUserId
+    }
+  });
+};

+ 63 - 0
src/api/product/classification/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { ClassificationVO, ClassificationForm, ClassificationQuery } from '@/api/product/classification/types';
+
+/**
+ * 查询产品属性关联列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listClassification = (query?: ClassificationQuery): AxiosPromise<ClassificationVO[]> => {
+  return request({
+    url: '/product/classification/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品属性关联详细
+ * @param id
+ */
+export const getClassification = (id: string | number): AxiosPromise<ClassificationVO> => {
+  return request({
+    url: '/product/classification/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品属性关联
+ * @param data
+ */
+export const addClassification = (data: ClassificationForm) => {
+  return request({
+    url: '/product/classification',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品属性关联
+ * @param data
+ */
+export const updateClassification = (data: ClassificationForm) => {
+  return request({
+    url: '/product/classification',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品属性关联
+ * @param id
+ */
+export const delClassification = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/classification/' + id,
+    method: 'delete'
+  });
+};

+ 86 - 0
src/api/product/classification/types.ts

@@ -0,0 +1,86 @@
+export interface ClassificationVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 产品id
+   */
+  productId: string | number;
+
+  /**
+   * 分类编号
+   */
+  categoryId: string | number;
+
+  /**
+   * 属性列表(JSON或分号分隔等格式)
+   */
+  attributesList: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface ClassificationForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 分类编号
+   */
+  categoryId?: string | number;
+
+  /**
+   * 属性列表(JSON或分号分隔等格式)
+   */
+  attributesList?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface ClassificationQuery extends PageQuery {
+
+  /**
+   * 产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 分类编号
+   */
+  categoryId?: string | number;
+
+  /**
+   * 属性列表(JSON或分号分隔等格式)
+   */
+  attributesList?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 1 - 1
src/api/product/contractproduct/index.ts → src/api/product/contracproduct/index.ts

@@ -1,6 +1,6 @@
 import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
-import { ContracproductVO, ContracproductForm, ContracproductQuery } from '@/api/product/contractproduct/types';
+import { ContracproductVO, ContracproductForm, ContracproductQuery } from '@/api/product/contracproduct/types';
 
 /**
  * 查询合同产品关联列表

+ 0 - 0
src/api/product/contractproduct/types.ts → src/api/product/contracproduct/types.ts


+ 63 - 0
src/api/product/customization/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { CustomizationVO, CustomizationForm, CustomizationQuery } from '@/api/product/customization/types';
+
+/**
+ * 查询产品定制信息列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listCustomization = (query?: CustomizationQuery): AxiosPromise<CustomizationVO[]> => {
+  return request({
+    url: '/product/customization/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品定制信息详细
+ * @param id
+ */
+export const getCustomization = (id: string | number): AxiosPromise<CustomizationVO> => {
+  return request({
+    url: '/product/customization/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品定制信息
+ * @param data
+ */
+export const addCustomization = (data: CustomizationForm) => {
+  return request({
+    url: '/product/customization',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品定制信息
+ * @param data
+ */
+export const updateCustomization = (data: CustomizationForm) => {
+  return request({
+    url: '/product/customization',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品定制信息
+ * @param id
+ */
+export const delCustomization = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/customization/' + id,
+    method: 'delete'
+  });
+};

+ 161 - 0
src/api/product/customization/types.ts

@@ -0,0 +1,161 @@
+export interface CustomizationVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 定制编号
+   */
+  customizationNo: string;
+
+  /**
+   * 产品id
+   */
+  productId: string | number;
+
+  /**
+   * 定制方式  支持多选,分隔  (0=包装定制,1=商品定制,2=开模定制)
+   */
+  customizedStyle: string;
+
+  /**
+   * 定制工艺  支持多选,分隔  (0=丝印,1=热转印,2=激光,烤花,压印)
+   */
+  customizedCraft: string;
+
+  /**
+   * 打样周期(天)
+   */
+  proofingPeriod: number;
+
+  /**
+   * 生产周期(天)
+   */
+  productionCycle: number;
+
+  /**
+   * 最小起订量(MOQ)
+   */
+  moq: number;
+
+  /**
+   * MOQ对应价格
+   */
+  moqPrice: number;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface CustomizationForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 定制编号
+   */
+  customizationNo?: string;
+
+  /**
+   * 产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 定制方式  支持多选,分隔  (0=包装定制,1=商品定制,2=开模定制)
+   */
+  customizedStyle?: string;
+
+  /**
+   * 定制工艺  支持多选,分隔  (0=丝印,1=热转印,2=激光,烤花,压印)
+   */
+  customizedCraft?: string;
+
+  /**
+   * 打样周期(天)
+   */
+  proofingPeriod?: number;
+
+  /**
+   * 生产周期(天)
+   */
+  productionCycle?: number;
+
+  /**
+   * 最小起订量(MOQ)
+   */
+  moq?: number;
+
+  /**
+   * MOQ对应价格
+   */
+  moqPrice?: number;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface CustomizationQuery extends PageQuery {
+
+  /**
+   * 定制编号
+   */
+  customizationNo?: string;
+
+  /**
+   * 产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 定制方式  支持多选,分隔  (0=包装定制,1=商品定制,2=开模定制)
+   */
+  customizedStyle?: string;
+
+  /**
+   * 定制工艺  支持多选,分隔  (0=丝印,1=热转印,2=激光,烤花,压印)
+   */
+  customizedCraft?: string;
+
+  /**
+   * 打样周期(天)
+   */
+  proofingPeriod?: number;
+
+  /**
+   * 生产周期(天)
+   */
+  productionCycle?: number;
+
+  /**
+   * 最小起订量(MOQ)
+   */
+  moq?: number;
+
+  /**
+   * MOQ对应价格
+   */
+  moqPrice?: number;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 28 - 6
src/api/product/extend/index.ts

@@ -2,6 +2,12 @@ import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
 import { ExtendVO, ExtendForm, ExtendQuery } from '@/api/product/extend/types';
 
+/**
+ * 查询产品扩展属性(低频访问字段)列表
+ * @param query
+ * @returns {*}
+ */
+
 export const listExtend = (query?: ExtendQuery): AxiosPromise<ExtendVO[]> => {
   return request({
     url: '/product/extend/list',
@@ -10,32 +16,48 @@ export const listExtend = (query?: ExtendQuery): AxiosPromise<ExtendVO[]> => {
   });
 };
 
-export const getExtend = (id: string | number): AxiosPromise<ExtendVO> => {
+/**
+ * 查询产品扩展属性(低频访问字段)详细
+ * @param productId
+ */
+export const getExtend = (productId: string | number): AxiosPromise<ExtendVO> => {
   return request({
-    url: '/product/extend/' + id,
+    url: '/product/extend/' + productId,
     method: 'get'
   });
 };
 
+/**
+ * 新增产品扩展属性(低频访问字段)
+ * @param data
+ */
 export const addExtend = (data: ExtendForm) => {
   return request({
     url: '/product/extend',
     method: 'post',
-    data
+    data: data
   });
 };
 
+/**
+ * 修改产品扩展属性(低频访问字段)
+ * @param data
+ */
 export const updateExtend = (data: ExtendForm) => {
   return request({
     url: '/product/extend',
     method: 'put',
-    data
+    data: data
   });
 };
 
-export const delExtend = (id: string | number | Array<string | number>) => {
+/**
+ * 删除产品扩展属性(低频访问字段)
+ * @param productId
+ */
+export const delExtend = (productId: string | number | Array<string | number>) => {
   return request({
-    url: '/product/extend/' + id,
+    url: '/product/extend/' + productId,
     method: 'delete'
   });
 };

+ 566 - 32
src/api/product/extend/types.ts

@@ -1,92 +1,626 @@
 export interface ExtendVO {
+  /**
+   * 关联 product_base.id
+   */
+  productId: string | number;
+
+  /**
+   * 促销标题
+   */
+  promotionTitle: string;
+
+  /**
+   * 发票名称
+   */
+  invoiceName: string;
+
+  /**
+   * 发票类型
+   */
+  invoiceType: string;
+
+  /**
+   * 规格代码
+   */
+  specificationsCode: string;
+
+  /**
+   * 条形码
+   */
+  barCoding: string;
+
+  /**
+   * 产品描述
+   */
+  productDescription: string;
+
+  /**
+   * 产品重量
+   */
+  productWeight: string;
+
+  /**
+   * 重量单位
+   */
+  weightUnit: string;
+
+  /**
+   * 产品体积
+   */
+  productVolume: string;
+
+  /**
+   * 体积单位
+   */
+  volumeUnit: string;
+
+  /**
+   * 售后服务
+   */
+  afterSalesService: string;
+
+  /**
+   * 服务保障  支持多选,分隔 (0=无忧退货,1=快速退款,2=免费包邮,3正品保障)
+   */
+  serviceGuarantee: string;
+
+  /**
+   * 是否安装服务:1=是,0=否
+   */
+  isInstallService: string;
+
+  /**
+   * 安装费用
+   */
+  installAmount: string;
+
+  /**
+   * 分销价格
+   */
+  distributionPrice: string;
+
+  /**
+   * 标准尺寸
+   */
+  standardSizes: string;
+
+  /**
+   * 克重
+   */
+  gramWeight: string;
+
+  /**
+   * 透明度
+   */
+  opacity: string;
+
+  /**
+   * 是否可定制:1=是,0=否
+   */
+  isCustomize: string;
+
+  /**
+   * 定制描述
+   */
+  customDescription: string;
+
+  /**
+   * 产品利润
+   */
+  productProfit: string;
+
+  /**
+   * 报告需求
+   */
+  reportRequire: string;
+
+  /**
+   * 审核评论
+   */
+  reviewComments: string;
+
+  /**
+   * 供应商编号
+   */
+  supplierNo: string;
+
+  /**
+   * 推送状态
+   */
+  pushStatus: string;
+
+  /**
+   * 数据来源
+   */
+  dataSource: string;
+
+  /**
+   * 发票规格
+   */
+  invoiceSpecs: string;
+
+  /**
+   * 增量
+   */
+  increment: number;
+
+  /**
+   * 采购编号
+   */
+  purchaseNo: string;
+
+  /**
+   * 采购名称
+   */
+  purchaseName: string;
+
+  /**
+   * 供应商名称
+   */
+  supplierName: string;
+
+  /**
+   * 采购经理编号
+   */
+  purchaseManagerNo: string;
+
+  /**
+   * 采购经理姓名
+   */
+  purchaseManagerName: string;
+
+  /**
+   * 参考链接
+   */
+  referenceLink: string;
+
+  /**
+   * 销售量
+   */
+  salesVolume: number;
+
+  /**
+   * 发货时效
+   */
+  deliveryTime: string;
+
+  /**
+   * PIT时间
+   */
+  pitTime: string;
+
+  /**
+   * 创建时的供应商标识
+   */
+  createSupplier: string;
+
+  /**
+   * 其他补充信息
+   */
+  otherInfo: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface ExtendForm extends BaseEntity {
+  /**
+   * 关联 product_base.id
+   */
   productId?: string | number;
+
+  /**
+   * 促销标题
+   */
   promotionTitle?: string;
+
+  /**
+   * 发票名称
+   */
   invoiceName?: string;
-  invoiceType?: string | number;
+
+  /**
+   * 发票类型
+   */
+  invoiceType?: string;
+
+  /**
+   * 规格代码
+   */
   specificationsCode?: string;
+
+  /**
+   * 条形码
+   */
   barCoding?: string;
+
+  /**
+   * 产品描述
+   */
   productDescription?: string;
-  productWeight?: string | number;
+
+  /**
+   * 产品重量
+   */
+  productWeight?: string;
+
+  /**
+   * 重量单位
+   */
   weightUnit?: string;
-  productVolume?: string | number;
+
+  /**
+   * 产品体积
+   */
+  productVolume?: string;
+
+  /**
+   * 体积单位
+   */
   volumeUnit?: string;
+
+  /**
+   * 售后服务
+   */
   afterSalesService?: string;
+
+  /**
+   * 服务保障  支持多选,分隔 (0=无忧退货,1=快速退款,2=免费包邮,3正品保障)
+   */
   serviceGuarantee?: string;
-  isInstallService?: string | number;
-  installAmount?: string | number;
-  distributionPrice?: string | number;
+
+  /**
+   * 是否安装服务:1=是,0=否
+   */
+  isInstallService?: string;
+
+  /**
+   * 安装费用
+   */
+  installAmount?: string;
+
+  /**
+   * 分销价格
+   */
+  distributionPrice?: string;
+
+  /**
+   * 标准尺寸
+   */
   standardSizes?: string;
-  gramWeight?: string | number;
-  opacity?: string | number;
-  isCustomize?: string | number;
+
+  /**
+   * 克重
+   */
+  gramWeight?: string;
+
+  /**
+   * 透明度
+   */
+  opacity?: string;
+
+  /**
+   * 是否可定制:1=是,0=否
+   */
+  isCustomize?: string;
+
+  /**
+   * 定制描述
+   */
   customDescription?: string;
-  productProfit?: string | number;
+
+  /**
+   * 产品利润
+   */
+  productProfit?: string;
+
+  /**
+   * 报告需求
+   */
   reportRequire?: string;
+
+  /**
+   * 审核评论
+   */
   reviewComments?: string;
+
+  /**
+   * 供应商编号
+   */
   supplierNo?: string;
-  pushStatus?: string | number;
+
+  /**
+   * 推送状态
+   */
+  pushStatus?: string;
+
+  /**
+   * 数据来源
+   */
   dataSource?: string;
+
+  /**
+   * 发票规格
+   */
   invoiceSpecs?: string;
-  increment?: string | number;
+
+  /**
+   * 增量
+   */
+  increment?: number;
+
+  /**
+   * 采购编号
+   */
   purchaseNo?: string;
+
+  /**
+   * 采购名称
+   */
   purchaseName?: string;
+
+  /**
+   * 供应商名称
+   */
   supplierName?: string;
+
+  /**
+   * 采购经理编号
+   */
   purchaseManagerNo?: string;
+
+  /**
+   * 采购经理姓名
+   */
   purchaseManagerName?: string;
+
+  /**
+   * 参考链接
+   */
   referenceLink?: string;
-  salesVolume?: string | number;
+
+  /**
+   * 销售量
+   */
+  salesVolume?: number;
+
+  /**
+   * 发货时效
+   */
   deliveryTime?: string;
+
+  /**
+   * PIT时间
+   */
   pitTime?: string;
+
+  /**
+   * 创建时的供应商标识
+   */
   createSupplier?: string;
+
+  /**
+   * 其他补充信息
+   */
   otherInfo?: string;
-  platformCode?: string;
+
+  /**
+   * 备注
+   */
   remark?: string;
+
 }
 
-export interface ExtendForm extends ExtendVO {}
+export interface ExtendQuery extends PageQuery {
 
-export interface ExtendQuery {
-  pageNum?: number;
-  pageSize?: number;
+  /**
+   * 促销标题
+   */
   promotionTitle?: string;
+
+  /**
+   * 发票名称
+   */
   invoiceName?: string;
-  invoiceType?: string | number;
+
+  /**
+   * 发票类型
+   */
+  invoiceType?: string;
+
+  /**
+   * 规格代码
+   */
   specificationsCode?: string;
+
+  /**
+   * 条形码
+   */
   barCoding?: string;
+
+  /**
+   * 产品描述
+   */
   productDescription?: string;
-  productWeight?: string | number;
+
+  /**
+   * 产品重量
+   */
+  productWeight?: string;
+
+  /**
+   * 重量单位
+   */
   weightUnit?: string;
-  productVolume?: string | number;
+
+  /**
+   * 产品体积
+   */
+  productVolume?: string;
+
+  /**
+   * 体积单位
+   */
   volumeUnit?: string;
+
+  /**
+   * 售后服务
+   */
   afterSalesService?: string;
+
+  /**
+   * 服务保障  支持多选,分隔 (0=无忧退货,1=快速退款,2=免费包邮,3正品保障)
+   */
   serviceGuarantee?: string;
-  isInstallService?: string | number;
-  installAmount?: string | number;
-  distributionPrice?: string | number;
+
+  /**
+   * 是否安装服务:1=是,0=否
+   */
+  isInstallService?: string;
+
+  /**
+   * 安装费用
+   */
+  installAmount?: string;
+
+  /**
+   * 分销价格
+   */
+  distributionPrice?: string;
+
+  /**
+   * 标准尺寸
+   */
   standardSizes?: string;
-  gramWeight?: string | number;
-  opacity?: string | number;
-  isCustomize?: string | number;
+
+  /**
+   * 克重
+   */
+  gramWeight?: string;
+
+  /**
+   * 透明度
+   */
+  opacity?: string;
+
+  /**
+   * 是否可定制:1=是,0=否
+   */
+  isCustomize?: string;
+
+  /**
+   * 定制描述
+   */
   customDescription?: string;
-  productProfit?: string | number;
+
+  /**
+   * 产品利润
+   */
+  productProfit?: string;
+
+  /**
+   * 报告需求
+   */
   reportRequire?: string;
+
+  /**
+   * 审核评论
+   */
   reviewComments?: string;
+
+  /**
+   * 供应商编号
+   */
   supplierNo?: string;
-  pushStatus?: string | number;
+
+  /**
+   * 推送状态
+   */
+  pushStatus?: string;
+
+  /**
+   * 数据来源
+   */
   dataSource?: string;
+
+  /**
+   * 发票规格
+   */
   invoiceSpecs?: string;
-  increment?: string | number;
+
+  /**
+   * 增量
+   */
+  increment?: number;
+
+  /**
+   * 采购编号
+   */
   purchaseNo?: string;
+
+  /**
+   * 采购名称
+   */
   purchaseName?: string;
+
+  /**
+   * 供应商名称
+   */
   supplierName?: string;
+
+  /**
+   * 采购经理编号
+   */
   purchaseManagerNo?: string;
+
+  /**
+   * 采购经理姓名
+   */
   purchaseManagerName?: string;
+
+  /**
+   * 参考链接
+   */
   referenceLink?: string;
-  salesVolume?: string | number;
+
+  /**
+   * 销售量
+   */
+  salesVolume?: number;
+
+  /**
+   * 发货时效
+   */
   deliveryTime?: string;
+
+  /**
+   * PIT时间
+   */
   pitTime?: string;
+
+  /**
+   * 创建时的供应商标识
+   */
   createSupplier?: string;
+
+  /**
+   * 其他补充信息
+   */
   otherInfo?: string;
+
+  /**
+   * 平台标识
+   */
   platformCode?: string;
-  params?: Record<string, any>;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
 }
+
+
+

+ 24 - 2
src/api/product/lable/index.ts

@@ -2,6 +2,12 @@ import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
 import { LableVO, LableForm, LableQuery } from '@/api/product/lable/types';
 
+/**
+ * 查询产品标签信息(注意:名疑似拼写错误,应为 product_label)列表
+ * @param query
+ * @returns {*}
+ */
+
 export const listLable = (query?: LableQuery): AxiosPromise<LableVO[]> => {
   return request({
     url: '/product/lable/list',
@@ -10,6 +16,10 @@ export const listLable = (query?: LableQuery): AxiosPromise<LableVO[]> => {
   });
 };
 
+/**
+ * 查询产品标签信息(注意:名疑似拼写错误,应为 product_label)详细
+ * @param id
+ */
 export const getLable = (id: string | number): AxiosPromise<LableVO> => {
   return request({
     url: '/product/lable/' + id,
@@ -17,22 +27,34 @@ export const getLable = (id: string | number): AxiosPromise<LableVO> => {
   });
 };
 
+/**
+ * 新增产品标签信息(注意:名疑似拼写错误,应为 product_label)
+ * @param data
+ */
 export const addLable = (data: LableForm) => {
   return request({
     url: '/product/lable',
     method: 'post',
-    data
+    data: data
   });
 };
 
+/**
+ * 修改产品标签信息(注意:名疑似拼写错误,应为 product_label)
+ * @param data
+ */
 export const updateLable = (data: LableForm) => {
   return request({
     url: '/product/lable',
     method: 'put',
-    data
+    data: data
   });
 };
 
+/**
+ * 删除产品标签信息(注意:名疑似拼写错误,应为 product_label)
+ * @param id
+ */
 export const delLable = (id: string | number | Array<string | number>) => {
   return request({
     url: '/product/lable/' + id,

+ 77 - 5
src/api/product/lable/types.ts

@@ -1,14 +1,86 @@
 export interface LableVO {
+  /**
+   * 主键,自增ID
+   */
+  id: string | number;
+
+  /**
+   * 产品标签编号(如:NEW2025、HOT、VIP_ONLY 等)
+   */
+  productLabelNo: string;
+
+  /**
+   * 标签显示名称(如:新品、热销、限时优惠)
+   */
+  productLabelName: string;
+
+  /**
+   * 使用该标签的产品数量(可用于统计或缓存)
+   */
+  productQuantity: number;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface LableForm extends BaseEntity {
+  /**
+   * 主键,自增ID
+   */
   id?: string | number;
+
+  /**
+   * 产品标签编号(如:NEW2025、HOT、VIP_ONLY 等)
+   */
+  productLabelNo?: string;
+
+  /**
+   * 标签显示名称(如:新品、热销、限时优惠)
+   */
   productLabelName?: string;
+
+  /**
+   * 使用该标签的产品数量(可用于统计或缓存)
+   */
   productQuantity?: number;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
 }
 
-export interface LableForm extends LableVO {}
+export interface LableQuery extends PageQuery {
+
+  /**
+   * 产品标签编号(如:NEW2025、HOT、VIP_ONLY 等)
+   */
+  productLabelNo?: string;
 
-export interface LableQuery {
-  pageNum?: number;
-  pageSize?: number;
+  /**
+   * 标签显示名称(如:新品、热销、限时优惠)
+   */
   productLabelName?: string;
-  params?: Record<string, any>;
+
+  /**
+   * 使用该标签的产品数量(可用于统计或缓存)
+   */
+  productQuantity?: number;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
 }
+
+
+

+ 40 - 3
src/api/product/pool/index.ts

@@ -1,6 +1,12 @@
 import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
-import { PoolVO, PoolQuery, PoolReviewForm } from '@/api/product/pool/types';
+import { PoolVO, PoolForm, PoolQuery } from '@/api/product/pool/types';
+
+/**
+ * 查询产品池列表
+ * @param query
+ * @returns {*}
+ */
 
 export const listPool = (query?: PoolQuery): AxiosPromise<PoolVO[]> => {
   return request({
@@ -10,6 +16,10 @@ export const listPool = (query?: PoolQuery): AxiosPromise<PoolVO[]> => {
   });
 };
 
+/**
+ * 查询产品池详细
+ * @param id
+ */
 export const getPool = (id: string | number): AxiosPromise<PoolVO> => {
   return request({
     url: '/product/pool/' + id,
@@ -17,10 +27,37 @@ export const getPool = (id: string | number): AxiosPromise<PoolVO> => {
   });
 };
 
-export const updatePool = (data: PoolReviewForm) => {
+/**
+ * 新增产品池
+ * @param data
+ */
+export const addPool = (data: PoolForm) => {
+  return request({
+    url: '/product/pool',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品池
+ * @param data
+ */
+export const updatePool = (data: PoolForm) => {
   return request({
     url: '/product/pool',
     method: 'put',
-    data
+    data: data
+  });
+};
+
+/**
+ * 删除产品池
+ * @param id
+ */
+export const delPool = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/pool/' + id,
+    method: 'delete'
   });
 };

+ 220 - 24
src/api/product/pool/types.ts

@@ -1,40 +1,236 @@
 export interface PoolVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 池编码
+   */
+  poolNo: string;
+
+  /**
+   * 项目id
+   */
+  itemId: string | number;
+
+  /**
+   * 分类id
+   */
+  categoryId: string | number;
+
+  /**
+   * 产品池类型 0普通产品池,1精选产品池,2协议产品池,3项目产品池,4分类产品池
+   */
+  type: number;
+
+  /**
+   * 池名称
+   */
+  name: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow: string;
+
+  /**
+   * 产品审核状态 0=待提交,1=待审核,2=审核通过,3=审核驳回
+   */
+  productReviewStatus: string;
+
+  /**
+   * 审核原因
+   */
+  reviewReason: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+  /**
+   * 商品数量
+   */
+  productCount?: number;
+
+  /**
+   * 待审核的产品数量
+   */
+  waitReviewCount?: number;
+
+  /**
+   * 已驳回的产品数量
+   */
+  rejectedCount?: number;
+
+  /**
+   * 已通过审核的产品数量
+   */
+  approvedCount?: number;
+
+  /**
+   * 待申请的产品数量
+   */
+  waitApplyCount?: number;
+
+  /**
+   * 创建时间
+   */
+  createTime?: string;
+
+  /**
+   * 创建人
+   */
+  createBy?: string;
+
+  /**
+   * 审核人
+   */
+  reviewBy?: string;
+
+}
+
+export interface PoolForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
   id?: string | number;
+
+  /**
+   * 池编码
+   */
   poolNo?: string;
-  itemId?: string | number;
-  categoryId?: string | number;
-  type?: number;
+
+  /**
+   * 项目id
+   */
+  itemId: string | number;
+
+  /**
+   * 分类id
+   */
+  categoryId: string | number;
+
+  /**
+   * 产品池类型 0普通产品池,1精选产品池,2协议产品池,3项目产品池,4分类产品池
+   */
+  type: number;
+
+  /**
+   * 池名称
+   */
   name?: string;
-  isShow?: string | number;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 产品审核状态 0=待提交,1=待审核,2=审核通过,3=审核驳回
+   */
   productReviewStatus?: string;
+
+  /**
+   * 审核原因
+   */
   reviewReason?: string;
-  createBy?: string;
-  reviewBy?: string;
+
+  /**
+   * 备注
+   */
   remark?: string;
-  waitApplyCount?: number;
-  waitReviewCount?: number;
-  approvedCount?: number;
-  rejectedCount?: number;
+
 }
 
-export interface PoolReviewForm {
-  id?: string | number;
-  itemId?: string | number;
-  categoryId?: string | number;
-  type?: number;
+export interface PoolQuery extends PageQuery {
+
+  /**
+   * 池编码
+   */
+  poolNo?: string;
+
+  /**
+   * 项目id
+   */
+  itemId: string | number;
+
+  /**
+   * 分类id
+   */
+  categoryId: string | number;
+
+  /**
+   * 产品池类型 0普通产品池,1精选产品池,2协议产品池,3项目产品池,4分类产品池
+   */
+  type: number;
+
+  /**
+   * 池名称
+   */
+  name?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 产品审核状态 0=待提交,1=待审核,2=审核通过,3=审核驳回
+   */
   productReviewStatus?: string;
+
+  /**
+   * 审核原因
+   */
   reviewReason?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+  /**
+   * 创建人
+   */
+  createBy?: string;
+
+  /**
+   * 审核人
+   */
+  reviewBy?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
 }
 
-export interface PoolQuery {
-  pageNum?: number;
-  pageSize?: number;
-  itemId?: string | number;
-  categoryId?: string | number;
-  type?: number;
+/**
+ * 产品池审核表单类型
+ */
+export interface PoolReviewForm {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 池名称(显示用)
+   */
   name?: string;
+
+  /**
+   * 产品审核状态 0=待提交,1=待审核,2=审核通过,3=审核驳回
+   */
   productReviewStatus?: string;
-  createBy?: string;
-  reviewBy?: string;
-  params?: Record<string, any>;
+
+  /**
+   * 审核原因
+   */
+  reviewReason?: string;
 }
+
+
+

+ 132 - 0
src/api/product/poolLink/index.ts

@@ -0,0 +1,132 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { PoolLinkVO, PoolLinkForm, PoolLinkQuery } from '@/api/product/poolLink/types';
+export type { PoolLinkForm };
+
+/**
+ * 查询产品池和产品关联列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listPoolLink = (query?: PoolLinkQuery): AxiosPromise<PoolLinkVO[]> => {
+  return request({
+    url: '/product/poolLink/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品池和产品关联详细
+ * @param id
+ */
+export const getPoolLink = (id: string | number): AxiosPromise<PoolLinkVO> => {
+  return request({
+    url: '/product/poolLink/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品池和产品关联
+ * @param data
+ */
+export const addPoolLink = (data: PoolLinkForm) => {
+  return request({
+    url: '/product/poolLink',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品池和产品关联
+ * @param data
+ */
+export const updatePoolLink = (data: PoolLinkForm) => {
+  return request({
+    url: '/product/poolLink',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品池和产品关联
+ * @param id
+ */
+export const delPoolLink = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/poolLink/' + id,
+    method: 'delete'
+  });
+};
+
+/**
+ * 批量添加商品到商品池
+ * @param data 批量添加参数
+ */
+export interface BatchAddProductData {
+  poolId: string | number;
+  products: Array<{
+    productId: string | number;
+    agreementPrice?: number;
+  }>;
+}
+
+export const batchAddProducts = (data: BatchAddProductData) => {
+  return request({
+    url: '/product/poolLink/batchAdd',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 批量审核商品进入商品池
+ * @param data 审核参数列表
+ */
+export const batchReview = (data: PoolLinkForm[]) => {
+  return request({
+    url: '/product/poolLink/batchReview',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 提交审核商品到商品池
+ * @param data 提交审核参数列表
+ */
+export const reSubmit = (data: PoolLinkForm[]) => {
+  return request({
+    url: '/product/poolLink/reSubmit',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 编辑商品价格
+ * @param data 价格参数
+ */
+export const editPrice = (data: PoolLinkForm) => {
+  return request({
+    url: '/product/poolLink/editPrice',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 编辑商品库存
+ * @param data 库存参数
+ */
+export const editStock = (data: PoolLinkForm) => {
+  return request({
+    url: '/product/poolLink/editStock',
+    method: 'post',
+    data: data
+  });
+};

+ 267 - 0
src/api/product/poolLink/types.ts

@@ -0,0 +1,267 @@
+export interface PoolLinkVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 所属池ID
+   */
+  poolId: string | number;
+
+  /**
+   * 产品池名称
+   */
+  poolName?: string;
+
+  /**
+   * 产品池类型 0普通产品池,1精选产品池,2协议产品池,3项目产品池,4分类产品池
+   */
+  type?: number;
+
+  /**
+   * 产品id
+   */
+  productId: string | number;
+
+  /**
+   * 产品价格
+   */
+  productPrice: number;
+
+  /**
+   * 是否在池中:1-是,0-否
+   */
+  isPoolStatus: string;
+
+  /**
+   * 产品审核状态 0=待提交,1=待审核,2=审核通过,3=审核驳回
+   */
+  productReviewStatus: string;
+
+  /**
+   * 审核原因
+   */
+  reviewReason: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+  /**
+   * 创建时间
+   */
+  createTime?: string;
+
+  /**
+   * 商品编号
+   */
+  productNo?: string;
+
+  /**
+   * 商品名称
+   */
+  itemName?: string;
+
+  /**
+   * 商品图片URL
+   */
+  productImageUrl?: string;
+
+  /**
+   * 品牌名称
+   */
+  brandName?: string;
+
+  /**
+   * 分类名称
+   */
+  categoryName?: string;
+
+  /**
+   * 单位名称
+   */
+  unitName?: string;
+
+  /**
+   * 库存
+   */
+  stock?: number;
+
+  /**
+   * 市场价
+   */
+  marketPrice?: number;
+
+  /**
+   * 平台售价
+   */
+  platformPrice?: number;
+
+  /**
+   * 最低售价
+   */
+  minPrice?: number;
+
+  /**
+   * 采购价
+   */
+  purchasePrice?: number;
+
+  /**
+   * 暂估毛利率
+   */
+  grossMargin?: number;
+
+  /**
+   * 商品状态:1=已上架,0=下架,2=上架中
+   */
+  productStatus?: string;
+
+  /**
+   * 供应商
+   */
+  supplier?: string;
+}
+
+export interface PoolLinkForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 所属池ID
+   */
+  poolId?: string | number;
+
+  /**
+   * 产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 产品价格
+   */
+  productPrice?: number;
+
+  /**
+   * 是否在池中:1-是,0-否
+   */
+  isPoolStatus?: string;
+
+  /**
+   * 产品审核状态 0=待提交,1=待审核,2=审核通过,3=审核驳回
+   */
+  productReviewStatus?: string;
+
+  /**
+   * 审核原因
+   */
+  reviewReason?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 库存
+   */
+  stock?: number;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface PoolLinkQuery extends PageQuery {
+
+  /**
+   * 所属池ID
+   */
+  poolId?: string | number;
+
+  /**
+   * 产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 产品价格
+   */
+  productPrice?: number;
+
+  /**
+   * 是否在池中:1-是,0-否
+   */
+  isPoolStatus?: string;
+
+  /**
+   * 产品审核状态 0=待提交,1=待审核,2=审核通过,3=审核驳回
+   */
+  productReviewStatus?: string;
+
+  /**
+   * 审核原因
+   */
+  reviewReason?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+  // ========== 查询扩展字段 ==========
+
+  /**
+   * 商品编号
+   */
+  productNo?: string;
+
+  /**
+   * 商品名称
+   */
+  itemName?: string;
+
+  /**
+   * 品牌ID
+   */
+  brandId?: string | number;
+
+  /**
+   * 分类ID
+   */
+  categoryId?: string | number;
+
+  /**
+   * 商品状态:1=已上架,0=下架,2=上架中
+   */
+  productStatus?: string;
+
+  /**
+   * 供应商
+   */
+  supplier?: string;
+
+  /**
+   * 日期范围参数
+   */
+  params?: any;
+}
+
+
+

+ 63 - 0
src/api/product/priceInventory/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { PriceInventoryVO, PriceInventoryForm, PriceInventoryQuery } from '@/api/product/priceInventory/types';
+
+/**
+ * 查询产品价格与库存信息列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listPriceInventory = (query?: PriceInventoryQuery): AxiosPromise<PriceInventoryVO[]> => {
+  return request({
+    url: '/product/priceInventory/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品价格与库存信息详细
+ * @param productId
+ */
+export const getPriceInventory = (productId: string | number): AxiosPromise<PriceInventoryVO> => {
+  return request({
+    url: '/product/priceInventory/' + productId,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品价格与库存信息
+ * @param data
+ */
+export const addPriceInventory = (data: PriceInventoryForm) => {
+  return request({
+    url: '/product/priceInventory',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品价格与库存信息
+ * @param data
+ */
+export const updatePriceInventory = (data: PriceInventoryForm) => {
+  return request({
+    url: '/product/priceInventory',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品价格与库存信息
+ * @param productId
+ */
+export const delPriceInventory = (productId: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/priceInventory/' + productId,
+    method: 'delete'
+  });
+};

+ 206 - 0
src/api/product/priceInventory/types.ts

@@ -0,0 +1,206 @@
+export interface PriceInventoryVO {
+  /**
+   * 关联 product_base.id
+   */
+  productId: string | number;
+
+  /**
+   * 市场价格
+   */
+  marketPrice: number;
+
+  /**
+   * 会员价格
+   */
+  memberPrice: number;
+
+  /**
+   * 最低销售价格
+   */
+  minSellingPrice: number;
+
+  /**
+   * 采购价格
+   */
+  purchasingPrice: number;
+
+  /**
+   * 最高采购价格
+   */
+  maxPurchasePrice: number;
+
+  /**
+   * 总库存量
+   */
+  totalInventory: number;
+
+  /**
+   * 当前可用库存
+   */
+  nowInventory: number;
+
+  /**
+   * 虚拟库存
+   */
+  virtualInventory: number;
+
+  /**
+   * 最小起订数量
+   */
+  minOrderQuantity: number;
+
+  /**
+   * 税率
+   */
+  taxRate: number;
+
+  /**
+   * 货币类型
+   */
+  currency: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface PriceInventoryForm extends BaseEntity {
+  /**
+   * 关联 product_base.id
+   */
+  productId?: string | number;
+
+  /**
+   * 市场价格
+   */
+  marketPrice?: number;
+
+  /**
+   * 会员价格
+   */
+  memberPrice?: number;
+
+  /**
+   * 最低销售价格
+   */
+  minSellingPrice?: number;
+
+  /**
+   * 采购价格
+   */
+  purchasingPrice?: number;
+
+  /**
+   * 最高采购价格
+   */
+  maxPurchasePrice?: number;
+
+  /**
+   * 总库存量
+   */
+  totalInventory?: number;
+
+  /**
+   * 当前可用库存
+   */
+  nowInventory?: number;
+
+  /**
+   * 虚拟库存
+   */
+  virtualInventory?: number;
+
+  /**
+   * 最小起订数量
+   */
+  minOrderQuantity?: number;
+
+  /**
+   * 税率
+   */
+  taxRate?: number;
+
+  /**
+   * 货币类型
+   */
+  currency?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface PriceInventoryQuery extends PageQuery {
+
+  /**
+   * 市场价格
+   */
+  marketPrice?: number;
+
+  /**
+   * 会员价格
+   */
+  memberPrice?: number;
+
+  /**
+   * 最低销售价格
+   */
+  minSellingPrice?: number;
+
+  /**
+   * 采购价格
+   */
+  purchasingPrice?: number;
+
+  /**
+   * 最高采购价格
+   */
+  maxPurchasePrice?: number;
+
+  /**
+   * 总库存量
+   */
+  totalInventory?: number;
+
+  /**
+   * 当前可用库存
+   */
+  nowInventory?: number;
+
+  /**
+   * 虚拟库存
+   */
+  virtualInventory?: number;
+
+  /**
+   * 最小起订数量
+   */
+  minOrderQuantity?: number;
+
+  /**
+   * 税率
+   */
+  taxRate?: number;
+
+  /**
+   * 货币类型
+   */
+  currency?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/product/program/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { ProgramVO, ProgramForm, ProgramQuery } from '@/api/product/program/types';
+
+/**
+ * 查询产品解决方案/项目方案列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listProgram = (query?: ProgramQuery): AxiosPromise<ProgramVO[]> => {
+  return request({
+    url: '/product/program/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品解决方案/项目方案详细
+ * @param id
+ */
+export const getProgram = (id: string | number): AxiosPromise<ProgramVO> => {
+  return request({
+    url: '/product/program/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品解决方案/项目方案
+ * @param data
+ */
+export const addProgram = (data: ProgramForm) => {
+  return request({
+    url: '/product/program',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品解决方案/项目方案
+ * @param data
+ */
+export const updateProgram = (data: ProgramForm) => {
+  return request({
+    url: '/product/program',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品解决方案/项目方案
+ * @param id
+ */
+export const delProgram = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/program/' + id,
+    method: 'delete'
+  });
+};

+ 210 - 0
src/api/product/program/types.ts

@@ -0,0 +1,210 @@
+export interface ProgramVO {
+  /**
+   * 主键,自增ID
+   */
+  id: string | number;
+
+  /**
+   * 方案编号(唯一标识)
+   */
+  programNo: string;
+
+  /**
+   * 方案标题
+   */
+  title: string;
+
+  /**
+   * 方案描述(注意:字段名为 SQL 关键字,建议未来重命名为 description)
+   */
+  describe: string;
+
+  /**
+   * 所属分类编号或名称
+   */
+  category: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow: string;
+
+  /**
+   * 封面图片URL(可存储较长路径)
+   */
+  coverImage: string;
+
+  /**
+   * 封面图片URL(可存储较长路径)Url
+   */
+  coverImageUrl: string;
+  /**
+   * 方案内容(如简介、详情等)
+   */
+  content: string;
+
+  /**
+   * 所属行业编号或名称
+   */
+  industry: string;
+
+  /**
+   * 适配产品/设备编号
+   */
+  adaptNo: string;
+
+  /**
+   * 标签
+   */
+  label: string;
+
+  /**
+   * 内部广告内容(如 Banner 文案或链接)
+   */
+  innerAdvert: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface ProgramForm extends BaseEntity {
+  /**
+   * 主键,自增ID
+   */
+  id?: string | number;
+
+  /**
+   * 方案编号(唯一标识)
+   */
+  programNo?: string;
+
+  /**
+   * 方案标题
+   */
+  title?: string;
+
+  /**
+   * 方案描述(注意:字段名为 SQL 关键字,建议未来重命名为 description)
+   */
+  describe?: string;
+
+  /**
+   * 所属分类编号或名称
+   */
+  category?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 封面图片URL(可存储较长路径)
+   */
+  coverImage?: string;
+
+  /**
+   * 方案内容(如简介、详情等)
+   */
+  content?: string;
+
+  /**
+   * 所属行业编号或名称
+   */
+  industry?: string;
+
+  /**
+   * 适配产品/设备编号
+   */
+  adaptNo?: string;
+
+  /**
+   * 标签
+   */
+  label?: string;
+
+  /**
+   * 内部广告内容(如 Banner 文案或链接)
+   */
+  innerAdvert?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface ProgramQuery extends PageQuery {
+
+  /**
+   * 方案编号(唯一标识)
+   */
+  programNo?: string;
+
+  /**
+   * 方案标题
+   */
+  title?: string;
+
+  /**
+   * 方案描述(注意:字段名为 SQL 关键字,建议未来重命名为 description)
+   */
+  describe?: string;
+
+  /**
+   * 所属分类编号或名称
+   */
+  category?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 封面图片URL(可存储较长路径)
+   */
+  coverImage?: string;
+
+  /**
+   * 方案内容(如简介、详情等)
+   */
+  content?: string;
+
+  /**
+   * 所属行业编号或名称
+   */
+  industry?: string;
+
+  /**
+   * 适配产品/设备编号
+   */
+  adaptNo?: string;
+
+  /**
+   * 标签
+   */
+  label?: string;
+
+  /**
+   * 内部广告内容(如 Banner 文案或链接)
+   */
+  innerAdvert?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/product/programLink/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { ProgramLinkVO, ProgramLinkForm, ProgramLinkQuery } from '@/api/product/programLink/types';
+
+/**
+ * 查询项目方案关联列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listProgramLink = (query?: ProgramLinkQuery): AxiosPromise<ProgramLinkVO[]> => {
+  return request({
+    url: '/product/programLink/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询项目方案关联详细
+ * @param id
+ */
+export const getProgramLink = (id: string | number): AxiosPromise<ProgramLinkVO> => {
+  return request({
+    url: '/product/programLink/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增项目方案关联
+ * @param data
+ */
+export const addProgramLink = (data: ProgramLinkForm) => {
+  return request({
+    url: '/product/programLink',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改项目方案关联
+ * @param data
+ */
+export const updateProgramLink = (data: ProgramLinkForm) => {
+  return request({
+    url: '/product/programLink',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除项目方案关联
+ * @param id
+ */
+export const delProgramLink = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/programLink/' + id,
+    method: 'delete'
+  });
+};

+ 71 - 0
src/api/product/programLink/types.ts

@@ -0,0 +1,71 @@
+export interface ProgramLinkVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 项目编号
+   */
+  programId: string | number;
+
+  /**
+   * 产品编号
+   */
+  productId: string | number;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface ProgramLinkForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 项目编号
+   */
+  programId?: string | number;
+
+  /**
+   * 产品编号
+   */
+  productId?: string | number;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface ProgramLinkQuery extends PageQuery {
+
+  /**
+   * 项目编号
+   */
+  programId?: string | number;
+
+  /**
+   * 产品编号
+   */
+  productId?: string | number;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 24 - 2
src/api/product/recommend/index.ts

@@ -2,6 +2,12 @@ import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
 import { RecommendVO, RecommendForm, RecommendQuery } from '@/api/product/recommend/types';
 
+/**
+ * 查询产品推荐位配置列表
+ * @param query
+ * @returns {*}
+ */
+
 export const listRecommend = (query?: RecommendQuery): AxiosPromise<RecommendVO[]> => {
   return request({
     url: '/product/recommend/list',
@@ -10,6 +16,10 @@ export const listRecommend = (query?: RecommendQuery): AxiosPromise<RecommendVO[
   });
 };
 
+/**
+ * 查询产品推荐位配置详细
+ * @param id
+ */
 export const getRecommend = (id: string | number): AxiosPromise<RecommendVO> => {
   return request({
     url: '/product/recommend/' + id,
@@ -17,22 +27,34 @@ export const getRecommend = (id: string | number): AxiosPromise<RecommendVO> =>
   });
 };
 
+/**
+ * 新增产品推荐位配置
+ * @param data
+ */
 export const addRecommend = (data: RecommendForm) => {
   return request({
     url: '/product/recommend',
     method: 'post',
-    data
+    data: data
   });
 };
 
+/**
+ * 修改产品推荐位配置
+ * @param data
+ */
 export const updateRecommend = (data: RecommendForm) => {
   return request({
     url: '/product/recommend',
     method: 'put',
-    data
+    data: data
   });
 };
 
+/**
+ * 删除产品推荐位配置
+ * @param id
+ */
 export const delRecommend = (id: string | number | Array<string | number>) => {
   return request({
     url: '/product/recommend/' + id,

+ 100 - 8
src/api/product/recommend/types.ts

@@ -1,24 +1,116 @@
 export interface RecommendVO {
+  /**
+   * 主键,自增ID
+   */
+  id: string | number;
+
+  /**
+   * 推荐编号(唯一标识)
+   */
+  recommendNo: string;
+
+  /**
+   * 推荐名称(如:首页爆款、新品专区等)
+   */
+  recommendName: string;
+
+  /**
+   * 推荐位描述(用于后台说明或前端提示)
+   */
+  recommendDescribe: string;
+
+  /**
+   * 是否显示:1=显示,0=隐藏
+   */
+  isShow: string;
+
+  /**
+   * 推荐封面图片路径或URL
+   */
+  recommendCoverphoto: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface RecommendForm extends BaseEntity {
+  /**
+   * 主键,自增ID
+   */
   id?: string | number;
+
+  /**
+   * 推荐编号(唯一标识)
+   */
   recommendNo?: string;
+
+  /**
+   * 推荐名称(如:首页爆款、新品专区等)
+   */
   recommendName?: string;
+
+  /**
+   * 推荐位描述(用于后台说明或前端提示)
+   */
   recommendDescribe?: string;
-  isShow?: string | number;
+
+  /**
+   * 是否显示:1=显示,0=隐藏
+   */
+  isShow?: string;
+
+  /**
+   * 推荐封面图片路径或URL
+   */
   recommendCoverphoto?: string;
+
+  /**
+   * 备注
+   */
   remark?: string;
-  platformCode?: string;
+
 }
 
-export interface RecommendForm extends RecommendVO {}
+export interface RecommendQuery extends PageQuery {
 
-export interface RecommendQuery {
-  pageNum?: number;
-  pageSize?: number;
+  /**
+   * 推荐编号(唯一标识)
+   */
   recommendNo?: string;
+
+  /**
+   * 推荐名称(如:首页爆款、新品专区等)
+   */
   recommendName?: string;
+
+  /**
+   * 推荐位描述(用于后台说明或前端提示)
+   */
   recommendDescribe?: string;
-  isShow?: string | number;
+
+  /**
+   * 是否显示:1=显示,0=隐藏
+   */
+  isShow?: string;
+
+  /**
+   * 推荐封面图片路径或URL
+   */
   recommendCoverphoto?: string;
+
+  /**
+   * 平台标识
+   */
   platformCode?: string;
-  params?: Record<string, any>;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
 }
+
+
+

+ 63 - 0
src/api/product/recommendLink/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { RecommendLinkVO, RecommendLinkForm, RecommendLinkQuery } from '@/api/product/recommendLink/types';
+
+/**
+ * 查询产品推荐关联列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listRecommendLink = (query?: RecommendLinkQuery): AxiosPromise<RecommendLinkVO[]> => {
+  return request({
+    url: '/product/recommendLink/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品推荐关联详细
+ * @param id
+ */
+export const getRecommendLink = (id: string | number): AxiosPromise<RecommendLinkVO> => {
+  return request({
+    url: '/product/recommendLink/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品推荐关联
+ * @param data
+ */
+export const addRecommendLink = (data: RecommendLinkForm) => {
+  return request({
+    url: '/product/recommendLink',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品推荐关联
+ * @param data
+ */
+export const updateRecommendLink = (data: RecommendLinkForm) => {
+  return request({
+    url: '/product/recommendLink',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品推荐关联
+ * @param id
+ */
+export const delRecommendLink = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/recommendLink/' + id,
+    method: 'delete'
+  });
+};

+ 71 - 0
src/api/product/recommendLink/types.ts

@@ -0,0 +1,71 @@
+export interface RecommendLinkVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 项目编号
+   */
+  recommendId: string | number;
+
+  /**
+   * 产品编号
+   */
+  productId: string | number;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface RecommendLinkForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 项目编号
+   */
+  recommendId?: string | number;
+
+  /**
+   * 产品编号
+   */
+  productId?: string | number;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface RecommendLinkQuery extends PageQuery {
+
+  /**
+   * 项目编号
+   */
+  recommendId?: string | number;
+
+  /**
+   * 产品编号
+   */
+  productId?: string | number;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/product/specs/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { SpecsVO, SpecsForm, SpecsQuery } from '@/api/product/specs/types';
+
+/**
+ * 查询产品规格关联列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listSpecs = (query?: SpecsQuery): AxiosPromise<SpecsVO[]> => {
+  return request({
+    url: '/product/specs/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品规格关联详细
+ * @param id
+ */
+export const getSpecs = (id: string | number): AxiosPromise<SpecsVO> => {
+  return request({
+    url: '/product/specs/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品规格关联
+ * @param data
+ */
+export const addSpecs = (data: SpecsForm) => {
+  return request({
+    url: '/product/specs',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品规格关联
+ * @param data
+ */
+export const updateSpecs = (data: SpecsForm) => {
+  return request({
+    url: '/product/specs',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品规格关联
+ * @param id
+ */
+export const delSpecs = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/specs/' + id,
+    method: 'delete'
+  });
+};

+ 86 - 0
src/api/product/specs/types.ts

@@ -0,0 +1,86 @@
+export interface SpecsVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 主产品编号
+   */
+  productId: string | number;
+
+  /**
+   * 关联的规格产品id列表(如:逗号分隔的产品id)
+   */
+  specsProductIds: string | number;
+
+  /**
+   * 是否单向关联:0=双向,1=单向
+   */
+  isUnidirectional: string | number;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface SpecsForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 主产品编号
+   */
+  productId?: string | number;
+
+  /**
+   * 关联的规格产品id列表(如:逗号分隔的产品id)
+   */
+  specsProductIds?: string | number;
+
+  /**
+   * 是否单向关联:0=双向,1=单向
+   */
+  isUnidirectional?: string | number;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface SpecsQuery extends PageQuery {
+
+  /**
+   * 主产品编号
+   */
+  productId?: string | number;
+
+  /**
+   * 关联的规格产品id列表(如:逗号分隔的产品id)
+   */
+  specsProductIds?: string | number;
+
+  /**
+   * 是否单向关联:0=双向,1=单向
+   */
+  isUnidirectional?: string | number;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/product/taxrate/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { TaxrateVO, TaxrateForm, TaxrateQuery } from '@/api/product/taxrate/types';
+
+/**
+ * 查询产品税率配置列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listTaxrate = (query?: TaxrateQuery): AxiosPromise<TaxrateVO[]> => {
+  return request({
+    url: '/product/taxrate/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品税率配置详细
+ * @param id
+ */
+export const getTaxrate = (id: string | number): AxiosPromise<TaxrateVO> => {
+  return request({
+    url: '/product/taxrate/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品税率配置
+ * @param data
+ */
+export const addTaxrate = (data: TaxrateForm) => {
+  return request({
+    url: '/product/taxrate',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品税率配置
+ * @param data
+ */
+export const updateTaxrate = (data: TaxrateForm) => {
+  return request({
+    url: '/product/taxrate',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品税率配置
+ * @param id
+ */
+export const delTaxrate = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/taxrate/' + id,
+    method: 'delete'
+  });
+};

+ 116 - 0
src/api/product/taxrate/types.ts

@@ -0,0 +1,116 @@
+export interface TaxrateVO {
+  /**
+   * 主键,自增ID
+   */
+  id: string | number;
+
+  /**
+   * 税率编号
+   */
+  taxrateNo: string;
+
+  /**
+   * 税率名称
+   */
+  taxrateName: string;
+
+  /**
+   * 税率值)
+   */
+  taxrate: number;
+
+  /**
+   * 数据来源
+   */
+  dataSource: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface TaxrateForm extends BaseEntity {
+  /**
+   * 主键,自增ID
+   */
+  id?: string | number;
+
+  /**
+   * 税率编号
+   */
+  taxrateNo?: string;
+
+  /**
+   * 税率名称
+   */
+  taxrateName?: string;
+
+  /**
+   * 税率值)
+   */
+  taxrate?: number;
+
+  /**
+   * 数据来源
+   */
+  dataSource?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface TaxrateQuery extends PageQuery {
+
+  /**
+   * 税率编号
+   */
+  taxrateNo?: string;
+
+  /**
+   * 税率名称
+   */
+  taxrateName?: string;
+
+  /**
+   * 税率值)
+   */
+  taxrate?: number;
+
+  /**
+   * 数据来源
+   */
+  dataSource?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/product/volumeUnit/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { VolumeUnitVO, VolumeUnitForm, VolumeUnitQuery } from '@/api/product/volumeUnit/types';
+
+/**
+ * 查询产品体积单位列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listVolumeUnit = (query?: VolumeUnitQuery): AxiosPromise<VolumeUnitVO[]> => {
+  return request({
+    url: '/product/volumeUnit/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品体积单位详细
+ * @param id
+ */
+export const getVolumeUnit = (id: string | number): AxiosPromise<VolumeUnitVO> => {
+  return request({
+    url: '/product/volumeUnit/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品体积单位
+ * @param data
+ */
+export const addVolumeUnit = (data: VolumeUnitForm) => {
+  return request({
+    url: '/product/volumeUnit',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品体积单位
+ * @param data
+ */
+export const updateVolumeUnit = (data: VolumeUnitForm) => {
+  return request({
+    url: '/product/volumeUnit',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品体积单位
+ * @param id
+ */
+export const delVolumeUnit = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/volumeUnit/' + id,
+    method: 'delete'
+  });
+};

+ 71 - 0
src/api/product/volumeUnit/types.ts

@@ -0,0 +1,71 @@
+export interface VolumeUnitVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 体积单位名称(如:立方米、升、立方厘米等)
+   */
+  unitName: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface VolumeUnitForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 体积单位名称(如:立方米、升、立方厘米等)
+   */
+  unitName?: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface VolumeUnitQuery extends PageQuery {
+
+  /**
+   * 体积单位名称(如:立方米、升、立方厘米等)
+   */
+  unitName?: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 0 - 63
src/api/product/warehouseInventory/index.ts

@@ -1,63 +0,0 @@
-import request from '@/utils/request';
-import { AxiosPromise } from 'axios';
-import { WarehouseInventoryVO, WarehouseInventoryForm, WarehouseInventoryQuery } from '@/api/product/warehouseInventory/types';
-
-/**
- * 查询仓库库存明细列表
- * @param query
- * @returns {*}
- */
-
-export const listWarehouseInventory = (query?: WarehouseInventoryQuery): AxiosPromise<WarehouseInventoryVO[]> => {
-  return request({
-    url: '/product/warehouseInventory/list',
-    method: 'get',
-    params: query
-  });
-};
-
-/**
- * 查询仓库库存明细详细
- * @param id
- */
-export const getWarehouseInventory = (id: string | number): AxiosPromise<WarehouseInventoryVO> => {
-  return request({
-    url: '/product/warehouseInventory/' + id,
-    method: 'get'
-  });
-};
-
-/**
- * 新增仓库库存明细
- * @param data
- */
-export const addWarehouseInventory = (data: WarehouseInventoryForm) => {
-  return request({
-    url: '/product/warehouseInventory',
-    method: 'post',
-    data: data
-  });
-};
-
-/**
- * 修改仓库库存明细
- * @param data
- */
-export const updateWarehouseInventory = (data: WarehouseInventoryForm) => {
-  return request({
-    url: '/product/warehouseInventory',
-    method: 'put',
-    data: data
-  });
-};
-
-/**
- * 删除仓库库存明细
- * @param id
- */
-export const delWarehouseInventory = (id: string | number | Array<string | number>) => {
-  return request({
-    url: '/product/warehouseInventory/' + id,
-    method: 'delete'
-  });
-};

+ 0 - 176
src/api/product/warehouseInventory/types.ts

@@ -1,176 +0,0 @@
-export interface WarehouseInventoryVO {
-  /**
-   * ID
-   */
-  id: string | number;
-
-  /**
-   * 商品ID
-   */
-  productId: string | number;
-
-  /**
-   * SKU ID
-   */
-  skuId: string | number;
-
-  /**
-   * 规格型号
-   */
-  specModel: string;
-
-  /**
-   * 仓库ID
-   */
-  warehouseId: string | number;
-
-  /**
-   * 仓库编号
-   */
-  warehouseNo: string;
-
-  /**
-   * 仓库名称
-   */
-  warehouseName: string;
-
-  /**
-   * 可用库存
-   */
-  nowInventory: number;
-
-  /**
-   * 锁定库存
-   */
-  lockInventory: number;
-
-  /**
-   * 状态(0正常 1停用)
-   */
-  status: string;
-
-  /**
-   * 备注
-   */
-  remark: string;
-
-}
-
-export interface WarehouseInventoryForm extends BaseEntity {
-  /**
-   * ID
-   */
-  id?: string | number;
-
-  /**
-   * 商品ID
-   */
-  productId?: string | number;
-
-  /**
-   * SKU ID
-   */
-  skuId?: string | number;
-
-  /**
-   * 规格型号
-   */
-  specModel?: string;
-
-  /**
-   * 仓库ID
-   */
-  warehouseId?: string | number;
-
-  /**
-   * 仓库编号
-   */
-  warehouseNo?: string;
-
-  /**
-   * 仓库名称
-   */
-  warehouseName?: string;
-
-  /**
-   * 可用库存
-   */
-  nowInventory?: number;
-
-  /**
-   * 锁定库存
-   */
-  lockInventory?: number;
-
-  /**
-   * 状态(0正常 1停用)
-   */
-  status?: string;
-
-  /**
-   * 备注
-   */
-  remark?: string;
-
-}
-
-export interface WarehouseInventoryQuery extends PageQuery {
-
-  /**
-   * 商品ID
-   */
-  productId?: string | number;
-
-  /**
-   * SKU ID
-   */
-  skuId?: string | number;
-
-  /**
-   * 规格型号
-   */
-  specModel?: string;
-
-  /**
-   * 仓库ID
-   */
-  warehouseId?: string | number;
-
-  /**
-   * 仓库编号
-   */
-  warehouseNo?: string;
-
-  /**
-   * 仓库名称
-   */
-  warehouseName?: string;
-
-  /**
-   * 可用库存
-   */
-  nowInventory?: number;
-
-  /**
-   * 锁定库存
-   */
-  lockInventory?: number;
-
-  /**
-   * 状态(0正常 1停用)
-   */
-  status?: string;
-
-  /**
-   * 平台标识
-   */
-  platformCode?: string;
-
-    /**
-     * 日期范围参数
-     */
-    params?: any;
-}
-
-
-

+ 63 - 0
src/api/product/weightUnit/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { WeightUnitVO, WeightUnitForm, WeightUnitQuery } from '@/api/product/weightUnit/types';
+
+/**
+ * 查询产品重量单位列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listWeightUnit = (query?: WeightUnitQuery): AxiosPromise<WeightUnitVO[]> => {
+  return request({
+    url: '/product/weightUnit/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品重量单位详细
+ * @param id
+ */
+export const getWeightUnit = (id: string | number): AxiosPromise<WeightUnitVO> => {
+  return request({
+    url: '/product/weightUnit/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品重量单位
+ * @param data
+ */
+export const addWeightUnit = (data: WeightUnitForm) => {
+  return request({
+    url: '/product/weightUnit',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品重量单位
+ * @param data
+ */
+export const updateWeightUnit = (data: WeightUnitForm) => {
+  return request({
+    url: '/product/weightUnit',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品重量单位
+ * @param id
+ */
+export const delWeightUnit = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/weightUnit/' + id,
+    method: 'delete'
+  });
+};

+ 71 - 0
src/api/product/weightUnit/types.ts

@@ -0,0 +1,71 @@
+export interface WeightUnitVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 重量单位名称(如:千克、克、吨、磅等)
+   */
+  unitName: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface WeightUnitForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 重量单位名称(如:千克、克、吨、磅等)
+   */
+  unitName?: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface WeightUnitQuery extends PageQuery {
+
+  /**
+   * 重量单位名称(如:千克、克、吨、磅等)
+   */
+  unitName?: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/taxrate/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { TaxrateVO, TaxrateForm, TaxrateQuery } from '@/api/product/taxrate/types';
+
+/**
+ * 查询产品税率配置列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listTaxrate = (query?: TaxrateQuery): AxiosPromise<TaxrateVO[]> => {
+  return request({
+    url: '/product/taxrate/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品税率配置详细
+ * @param id
+ */
+export const getTaxrate = (id: string | number): AxiosPromise<TaxrateVO> => {
+  return request({
+    url: '/product/taxrate/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品税率配置
+ * @param data
+ */
+export const addTaxrate = (data: TaxrateForm) => {
+  return request({
+    url: '/product/taxrate',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品税率配置
+ * @param data
+ */
+export const updateTaxrate = (data: TaxrateForm) => {
+  return request({
+    url: '/product/taxrate',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品税率配置
+ * @param id
+ */
+export const delTaxrate = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/taxrate/' + id,
+    method: 'delete'
+  });
+};

+ 116 - 0
src/api/taxrate/types.ts

@@ -0,0 +1,116 @@
+export interface TaxrateVO {
+  /**
+   * 主键,自增ID
+   */
+  id: string | number;
+
+  /**
+   * 税率编号
+   */
+  taxrateNo: string;
+
+  /**
+   * 税率名称
+   */
+  taxrateName: string;
+
+  /**
+   * 税率值)
+   */
+  taxrate: number;
+
+  /**
+   * 数据来源
+   */
+  dataSource: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface TaxrateForm extends BaseEntity {
+  /**
+   * 主键,自增ID
+   */
+  id?: string | number;
+
+  /**
+   * 税率编号
+   */
+  taxrateNo?: string;
+
+  /**
+   * 税率名称
+   */
+  taxrateName?: string;
+
+  /**
+   * 税率值)
+   */
+  taxrate?: number;
+
+  /**
+   * 数据来源
+   */
+  dataSource?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface TaxrateQuery extends PageQuery {
+
+  /**
+   * 税率编号
+   */
+  taxrateNo?: string;
+
+  /**
+   * 税率名称
+   */
+  taxrateName?: string;
+
+  /**
+   * 税率值)
+   */
+  taxrate?: number;
+
+  /**
+   * 数据来源
+   */
+  dataSource?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/unit/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { UnitVO, UnitForm, UnitQuery } from '@/api/product/unit/types';
+
+/**
+ * 查询产品计量单位列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listUnit = (query?: UnitQuery): AxiosPromise<UnitVO[]> => {
+  return request({
+    url: '/product/unit/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品计量单位详细
+ * @param id
+ */
+export const getUnit = (id: string | number): AxiosPromise<UnitVO> => {
+  return request({
+    url: '/product/unit/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品计量单位
+ * @param data
+ */
+export const addUnit = (data: UnitForm) => {
+  return request({
+    url: '/product/unit',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品计量单位
+ * @param data
+ */
+export const updateUnit = (data: UnitForm) => {
+  return request({
+    url: '/product/unit',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品计量单位
+ * @param id
+ */
+export const delUnit = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/unit/' + id,
+    method: 'delete'
+  });
+};

+ 101 - 0
src/api/unit/types.ts

@@ -0,0 +1,101 @@
+export interface UnitVO {
+  /**
+   * 主键,自增ID
+   */
+  id: string | number;
+
+  /**
+   * 单位编号
+   */
+  unitNo: string;
+
+  /**
+   * 单位名称(如:件、箱、千克等)
+   */
+  unitName: string;
+
+  /**
+   * 数据来源
+   */
+  dataSource: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface UnitForm extends BaseEntity {
+  /**
+   * 主键,自增ID
+   */
+  id?: string | number;
+
+  /**
+   * 单位编号
+   */
+  unitNo?: string;
+
+  /**
+   * 单位名称(如:件、箱、千克等)
+   */
+  unitName?: string;
+
+  /**
+   * 数据来源
+   */
+  dataSource?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface UnitQuery extends PageQuery {
+
+  /**
+   * 单位编号
+   */
+  unitNo?: string;
+
+  /**
+   * 单位名称(如:件、箱、千克等)
+   */
+  unitName?: string;
+
+  /**
+   * 数据来源
+   */
+  dataSource?: string;
+
+  /**
+   * 是否显示:1=是,0=否
+   */
+  isShow?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/volumeUnit/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { VolumeUnitVO, VolumeUnitForm, VolumeUnitQuery } from '@/api/product/volumeUnit/types';
+
+/**
+ * 查询产品体积单位列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listVolumeUnit = (query?: VolumeUnitQuery): AxiosPromise<VolumeUnitVO[]> => {
+  return request({
+    url: '/product/volumeUnit/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品体积单位详细
+ * @param id
+ */
+export const getVolumeUnit = (id: string | number): AxiosPromise<VolumeUnitVO> => {
+  return request({
+    url: '/product/volumeUnit/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品体积单位
+ * @param data
+ */
+export const addVolumeUnit = (data: VolumeUnitForm) => {
+  return request({
+    url: '/product/volumeUnit',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品体积单位
+ * @param data
+ */
+export const updateVolumeUnit = (data: VolumeUnitForm) => {
+  return request({
+    url: '/product/volumeUnit',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品体积单位
+ * @param id
+ */
+export const delVolumeUnit = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/volumeUnit/' + id,
+    method: 'delete'
+  });
+};

+ 71 - 0
src/api/volumeUnit/types.ts

@@ -0,0 +1,71 @@
+export interface VolumeUnitVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 体积单位名称(如:立方米、升、立方厘米等)
+   */
+  unitName: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface VolumeUnitForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 体积单位名称(如:立方米、升、立方厘米等)
+   */
+  unitName?: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface VolumeUnitQuery extends PageQuery {
+
+  /**
+   * 体积单位名称(如:立方米、升、立方厘米等)
+   */
+  unitName?: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/weightUnit/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { WeightUnitVO, WeightUnitForm, WeightUnitQuery } from '@/api/product/weightUnit/types';
+
+/**
+ * 查询产品重量单位列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listWeightUnit = (query?: WeightUnitQuery): AxiosPromise<WeightUnitVO[]> => {
+  return request({
+    url: '/product/weightUnit/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品重量单位详细
+ * @param id
+ */
+export const getWeightUnit = (id: string | number): AxiosPromise<WeightUnitVO> => {
+  return request({
+    url: '/product/weightUnit/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品重量单位
+ * @param data
+ */
+export const addWeightUnit = (data: WeightUnitForm) => {
+  return request({
+    url: '/product/weightUnit',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品重量单位
+ * @param data
+ */
+export const updateWeightUnit = (data: WeightUnitForm) => {
+  return request({
+    url: '/product/weightUnit',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品重量单位
+ * @param id
+ */
+export const delWeightUnit = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/product/weightUnit/' + id,
+    method: 'delete'
+  });
+};

+ 71 - 0
src/api/weightUnit/types.ts

@@ -0,0 +1,71 @@
+export interface WeightUnitVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 重量单位名称(如:千克、克、吨、磅等)
+   */
+  unitName: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface WeightUnitForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 重量单位名称(如:千克、克、吨、磅等)
+   */
+  unitName?: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface WeightUnitQuery extends PageQuery {
+
+  /**
+   * 重量单位名称(如:千克、克、吨、磅等)
+   */
+  unitName?: string;
+
+  /**
+   * 数据来源(如:系统配置、接口同步等)
+   */
+  dataSource?: string;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 0 - 256
src/views/product/associate/index.vue

@@ -1,256 +0,0 @@
-<template>
-  <div class="p-2">
-    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-      <div v-show="showSearch" class="mb-[10px]">
-        <el-card shadow="hover">
-          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
-            <el-form-item label="主产品id" prop="productId">
-              <el-input v-model="queryParams.productId" placeholder="请输入主产品id" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="关联产品编号列表" prop="productIds">
-              <el-input v-model="queryParams.productIds" placeholder="请输入关联产品编号列表" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="是否单向关联:0=双向,1=单向" prop="isUnidirectional">
-              <el-input v-model="queryParams.isUnidirectional" placeholder="请输入是否单向关联:0=双向,1=单向" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="关联标题/展示名称" prop="relatedTitle">
-              <el-input v-model="queryParams.relatedTitle" placeholder="请输入关联标题/展示名称" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="平台标识" prop="platformCode">
-              <el-input v-model="queryParams.platformCode" placeholder="请输入平台标识" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item>
-              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-            </el-form-item>
-          </el-form>
-        </el-card>
-      </div>
-    </transition>
-
-    <el-card shadow="never">
-      <template #header>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="1.5">
-            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['product:associate:add']">新增</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['product:associate:edit']">修改</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['product:associate:remove']">删除</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['product:associate:export']">导出</el-button>
-          </el-col>
-          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-        </el-row>
-      </template>
-
-      <el-table v-loading="loading" border :data="associateList" @selection-change="handleSelectionChange">
-        <el-table-column type="selection" width="55" align="center" />
-        <el-table-column label="主键ID" align="center" prop="id" v-if="true" />
-        <el-table-column label="主产品id" align="center" prop="productId" />
-        <el-table-column label="关联产品编号列表" align="center" prop="productIds" />
-        <el-table-column label="是否单向关联:0=双向,1=单向" align="center" prop="isUnidirectional" />
-        <el-table-column label="关联标题/展示名称" align="center" prop="relatedTitle" />
-        <el-table-column label="备注" align="center" prop="remark" />
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-          <template #default="scope">
-            <el-tooltip content="修改" placement="top">
-              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['product:associate:edit']"></el-button>
-            </el-tooltip>
-            <el-tooltip content="删除" placement="top">
-              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['product:associate:remove']"></el-button>
-            </el-tooltip>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-    </el-card>
-    <!-- 添加或修改产品关联对话框 -->
-    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-      <el-form ref="associateFormRef" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="主产品id" prop="productId">
-          <el-input v-model="form.productId" placeholder="请输入主产品id" />
-        </el-form-item>
-        <el-form-item label="关联产品编号列表" prop="productIds">
-            <el-input v-model="form.productIds" type="textarea" placeholder="请输入内容" />
-        </el-form-item>
-        <el-form-item label="是否单向关联:0=双向,1=单向" prop="isUnidirectional">
-          <el-input v-model="form.isUnidirectional" placeholder="请输入是否单向关联:0=双向,1=单向" />
-        </el-form-item>
-        <el-form-item label="关联标题/展示名称" prop="relatedTitle">
-          <el-input v-model="form.relatedTitle" placeholder="请输入关联标题/展示名称" />
-        </el-form-item>
-        <el-form-item label="备注" prop="remark">
-            <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
-          <el-button @click="cancel">取 消</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup name="Associate" lang="ts">
-import { listAssociate, getAssociate, delAssociate, addAssociate, updateAssociate } from '@/api/product/associate';
-import { AssociateVO, AssociateQuery, AssociateForm } from '@/api/product/associate/types';
-
-const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-
-const associateList = ref<AssociateVO[]>([]);
-const buttonLoading = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref<Array<string | number>>([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-
-const queryFormRef = ref<ElFormInstance>();
-const associateFormRef = ref<ElFormInstance>();
-
-const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
-});
-
-const initFormData: AssociateForm = {
-  id: undefined,
-  productId: undefined,
-  productIds: undefined,
-  isUnidirectional: undefined,
-  relatedTitle: undefined,
-  remark: undefined,
-}
-const data = reactive<PageData<AssociateForm, AssociateQuery>>({
-  form: {...initFormData},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    productId: undefined,
-    productIds: undefined,
-    isUnidirectional: undefined,
-    relatedTitle: undefined,
-    platformCode: undefined,
-    params: {
-    }
-  },
-  rules: {
-    productId: [
-      { required: true, message: "主产品id不能为空", trigger: "blur" }
-    ],
-    productIds: [
-      { required: true, message: "关联产品编号列表不能为空", trigger: "blur" }
-    ],
-    relatedTitle: [
-      { required: true, message: "关联标题/展示名称不能为空", trigger: "blur" }
-    ],
-    remark: [
-      { required: true, message: "备注不能为空", trigger: "blur" }
-    ],
-  }
-});
-
-const { queryParams, form, rules } = toRefs(data);
-
-/** 查询产品关联列表 */
-const getList = async () => {
-  loading.value = true;
-  const res = await listAssociate(queryParams.value);
-  associateList.value = res.rows;
-  total.value = res.total;
-  loading.value = false;
-}
-
-/** 取消按钮 */
-const cancel = () => {
-  reset();
-  dialog.visible = false;
-}
-
-/** 表单重置 */
-const reset = () => {
-  form.value = {...initFormData};
-  associateFormRef.value?.resetFields();
-}
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value?.resetFields();
-  handleQuery();
-}
-
-/** 多选框选中数据 */
-const handleSelectionChange = (selection: AssociateVO[]) => {
-  ids.value = selection.map(item => item.id);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-}
-
-/** 新增按钮操作 */
-const handleAdd = () => {
-  reset();
-  dialog.visible = true;
-  dialog.title = "添加产品关联";
-}
-
-/** 修改按钮操作 */
-const handleUpdate = async (row?: AssociateVO) => {
-  reset();
-  const _id = row?.id || ids.value[0]
-  const res = await getAssociate(_id);
-  Object.assign(form.value, res.data);
-  dialog.visible = true;
-  dialog.title = "修改产品关联";
-}
-
-/** 提交按钮 */
-const submitForm = () => {
-  associateFormRef.value?.validate(async (valid: boolean) => {
-    if (valid) {
-      buttonLoading.value = true;
-      if (form.value.id) {
-        await updateAssociate(form.value).finally(() =>  buttonLoading.value = false);
-      } else {
-        await addAssociate(form.value).finally(() =>  buttonLoading.value = false);
-      }
-      proxy?.$modal.msgSuccess("操作成功");
-      dialog.visible = false;
-      await getList();
-    }
-  });
-}
-
-/** 删除按钮操作 */
-const handleDelete = async (row?: AssociateVO) => {
-  const _ids = row?.id || ids.value;
-  await proxy?.$modal.confirm('是否确认删除产品关联编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
-  await delAssociate(_ids);
-  proxy?.$modal.msgSuccess("删除成功");
-  await getList();
-}
-
-/** 导出按钮操作 */
-const handleExport = () => {
-  proxy?.download('product/associate/export', {
-    ...queryParams.value
-  }, `associate_${new Date().getTime()}.xlsx`)
-}
-
-onMounted(() => {
-  getList();
-});
-</script>

+ 0 - 1661
src/views/product/base/add.vue

@@ -1,1661 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-card shadow="never" class="mb-3">
-      <div class="flex items-center justify-between">
-        <div class="flex items-center">
-          <el-button icon="ArrowLeft" @click="handleBack">返回</el-button>
-          <span class="ml-4 text-xl font-bold">{{ pageTitle }}</span>
-        </div>
-      </div>
-    </el-card>
-
-    <div class="product-wizard-page">
-      <!-- 步骤条 -->
-      <el-card shadow="never" class="mb-3">
-        <el-steps :active="currentStep" finish-status="success" align-center>
-          <el-step title="选择分类" description="选择商品分类" />
-          <el-step title="填写商品信息" description="填写商品基本信息" />
-          <el-step title="完成" description="确认提交" />
-        </el-steps>
-      </el-card>
-
-      <!-- 步骤内容 -->
-      <div class="step-content" v-loading="loading">
-        <!-- 步骤1: 选择分类 -->
-        <el-card v-show="currentStep === 0" shadow="never" class="step-card">
-          <template #header>
-            <div class="flex items-center">
-              <!-- <el-icon class="mr-2"><Warning /></el-icon> -->
-              <span class="text-lg font-bold">选择分类</span>
-            </div>
-          </template>
-
-          <div class="category-selection">
-            <el-row :gutter="20">
-              <!-- 一级分类 -->
-              <el-col :span="8">
-                <div class="category-box">
-                  <div class="category-header">选择一级分类</div>
-                  <div class="category-search">
-                    <el-input
-                      v-model="searchLevel1"
-                      placeholder="搜索一级分类"
-                      clearable
-                      prefix-icon="Search"
-                      size="small"
-                    />
-                  </div>
-                  <div class="category-list">
-                    <div
-                      v-for="item in filteredLevel1Categories"
-                      :key="item.id"
-                      :class="['category-item', { 'active': categoryForm.topCategoryId === item.id }]"
-                      @click="selectLevel1(item)"
-                    >
-                      <span>{{ item.label }}</span>
-                      <el-icon v-if="categoryForm.topCategoryId === item.id"><ArrowRight /></el-icon>
-                    </div>
-                    <el-empty v-if="filteredLevel1Categories.length === 0" description="暂无数据" :image-size="60" />
-                  </div>
-                </div>
-              </el-col>
-
-              <!-- 二级分类 -->
-              <el-col :span="8">
-                <div class="category-box">
-                  <div class="category-header">选择二级分类</div>
-                  <div class="category-search">
-                    <el-input
-                      v-model="searchLevel2"
-                      placeholder="搜索二级分类"
-                      clearable
-                      prefix-icon="Search"
-                      size="small"
-                    />
-                  </div>
-                  <div class="category-list">
-                    <div
-                      v-for="item in filteredLevel2Categories"
-                      :key="item.id"
-                      :class="['category-item', { 'active': categoryForm.mediumCategoryId === item.id }]"
-                      @click="selectLevel2(item)"
-                    >
-                      <span>{{ item.label }}</span>
-                      <el-icon v-if="categoryForm.mediumCategoryId === item.id"><ArrowRight /></el-icon>
-                    </div>
-                    <el-empty v-if="filteredLevel2Categories.length === 0" description="请先选择一级分类" :image-size="60" />
-                  </div>
-                </div>
-              </el-col>
-
-              <!-- 三级分类 -->
-              <el-col :span="8">
-                <div class="category-box">
-                  <div class="category-header">选择三级分类</div>
-                  <div class="category-search">
-                    <el-input
-                      v-model="searchLevel3"
-                      placeholder="搜索三级分类"
-                      clearable
-                      prefix-icon="Search"
-                      size="small"
-                    />
-                  </div>
-                  <div class="category-list">
-                    <div
-                      v-for="item in filteredLevel3Categories"
-                      :key="item.id"
-                      :class="['category-item', { 'active': categoryForm.bottomCategoryId === item.id }]"
-                      @click="selectLevel3(item)"
-                    >
-                      <span>{{ item.label }}</span>
-                      <el-icon v-if="categoryForm.bottomCategoryId === item.id"><Check /></el-icon>
-                    </div>
-                    <el-empty v-if="filteredLevel3Categories.length === 0" description="请先选择二级分类" :image-size="60" />
-                  </div>
-                </div>
-              </el-col>
-            </el-row>
-          </div>
-
-          <!-- 已选分类提示 -->
-          <!-- <div class="mt-4">
-            <el-checkbox v-model="autoCreateCategory" label="如果选择的分类不存在,自动创建分类" />
-          </div>
-          <div class="mt-2">
-            <el-input
-              v-model="manualCategoryInput"
-              placeholder="请输入入口类名称"
-              clearable
-              style="width: 400px;"
-            />
-          </div> -->
-        </el-card>
-
-        <!-- 步骤2: 填写商品信息 -->
-        <el-card v-show="currentStep === 1" shadow="never" class="step-card">
-          <template #header>
-            <span class="text-lg font-bold">基本信息</span>
-          </template>
-
-          <el-form ref="productFormRef" :model="productForm" :rules="productRules" label-width="120px" class="product-info-form">
-            <!-- 商品分类显示 -->
-            <el-form-item label="商品分类:">
-              <div class="category-display">
-                <span class="category-text">{{ getCategoryPath() }}</span>
-                <el-link type="primary" :underline="false" @click="currentStep = 0" class="ml-2">修改</el-link>
-                <el-link type="danger" :underline="false" @click="clearCategory" class="ml-2">删除</el-link>
-              </div>
-            </el-form-item>
-
-            <!-- 商品编号 -->
-            <el-row :gutter="20">
-              <el-col :span="12">
-                <el-form-item label="商品编号:" prop="productNo" required>
-                  <el-input
-                    v-model="productForm.productNo"
-                    placeholder="002169745"
-                    maxlength="20"
-                    show-word-limit
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="12">
-                <el-form-item label="状态:">
-                  <span class="category-text">上架在售</span>
-                </el-form-item>
-              </el-col>
-            </el-row>
-
-            <!-- 商品名称 -->
-            <el-form-item label="商品名称:" prop="itemName" required>
-              <el-input
-                v-model="productForm.itemName"
-                type="textarea"
-                :rows="2"
-                placeholder="请输入商品名称"
-                maxlength="200"
-                show-word-limit
-              />
-            </el-form-item>
-
-            <!-- A10产品名称 -->
-            <el-form-item label="A10产品名称:">
-              <el-input
-                v-model="productForm.a10ProductName"
-                type="textarea"
-                :rows="2"
-                placeholder="请输入A10产品名称"
-                maxlength="200"
-                show-word-limit
-              />
-              <div class="form-item-tip">
-                A10产品名称应包含该产品的关键词,本身的名称、本身的型号、产品的主要特点、产品的用途、产品的颜色、产品的规格等。可以A3时间 A4 单击
-              </div>
-            </el-form-item>
-
-            <!-- 规格型号 和 UPC(69)条码 -->
-            <el-row :gutter="20">
-              <el-col :span="12">
-                <el-form-item label="规格型号:">
-                  <el-input
-                    v-model="productForm.specification"
-                    placeholder="请输入规格型号"
-                    maxlength="20"
-                    show-word-limit
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="12">
-                <el-form-item label="UPC(69)条码:">
-                  <el-input
-                    v-model="productForm.upcBarcode"
-                    placeholder="请输入UPC(69)条码"
-                    maxlength="20"
-                    show-word-limit
-                  />
-                </el-form-item>
-              </el-col>
-            </el-row>
-
-            <!-- 发票名称 和 发票规格 -->
-            <el-row :gutter="20">
-              <el-col :span="12">
-                <el-form-item label="发票名称:">
-                  <el-input
-                    v-model="productForm.invoiceName"
-                    placeholder="请输入发票名称"
-                    maxlength="20"
-                    show-word-limit
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="12">
-                <el-form-item label="发票规格:">
-                  <el-input
-                    v-model="productForm.invoiceSpec"
-                    placeholder="请输入发票规格"
-                    maxlength="20"
-                    show-word-limit
-                  />
-                </el-form-item>
-              </el-col>
-            </el-row>
-            <el-row :gutter="20">
-              <!-- 商品品牌 -->
-               <el-col :span="12">
-                <el-form-item label="商品品牌:" prop="brandId" required>
-                  <el-select-v2
-                    v-model="productForm.brandId"
-                    :options="brandOptionsFormatted"
-                    placeholder="请选择商品品牌"
-                    clearable
-                    filterable
-                    class="w-full"
-                    :loading="brandLoading"
-                    @visible-change="handleBrandVisibleChange"
-                  />
-                </el-form-item>
-               </el-col>
-
-              <el-col :span="12">
-                <el-form-item label="单位:">
-                  <el-select v-model="productForm.unitId" placeholder="请选择" clearable class="w-full">
-                    <el-option
-                      v-for="option in unitOptions"
-                      :key="option.id"
-                      :label="option.unitName"
-                      :value="option.id"
-                    />
-                  </el-select>
-                </el-form-item>
-              </el-col>
-            </el-row>
-
-
-            <!-- 税率 和 币种 -->
-            <el-row :gutter="20">
-              <el-col :span="12">
-                <el-form-item label="税率:" required>
-                  <el-input v-model="productForm.taxRate" placeholder="请输入商品税率" type="number" />
-                </el-form-item>
-              </el-col>
-              <el-col :span="12">
-                <el-form-item label="币种:">
-                  <el-select v-model="productForm.currency" placeholder="请选择" class="w-full">
-                    <el-option label="人民币(RMB)" value="RMB" />
-                    <el-option label="美元(USD)" value="USD" />
-                    <el-option label="欧元(EUR)" value="EUR" />
-                  </el-select>
-                </el-form-item>
-              </el-col>
-            </el-row>
-
-            <!-- 销量人气 -->
-            <el-row :gutter="20">
-              <el-col :span="12">
-                <el-form-item label="销量人气:">
-                  <el-input
-                    v-model="productForm.salesVolume"
-                    type="number"
-                    placeholder="请输入销量人气"
-                    :min="0"
-                  />
-                </el-form-item>
-              </el-col>
-            </el-row>
-
-            <!-- 包装规格 -->
-            <el-form-item label="促销标题:">
-              <el-input
-                v-model="productForm.packagingSpec"
-                type="textarea"
-                :rows="3"
-                placeholder="请输入包装规格"
-                maxlength="300"
-                show-word-limit
-              />
-            </el-form-item>
-
-            <!-- 重量 和 体积 -->
-            <el-row :gutter="20">
-              <el-col :span="12">
-                <el-form-item label="商品重量:">
-                  <el-input
-                    v-model="productForm.weight"
-                    placeholder="0"
-                    maxlength="10"
-                    show-word-limit
-                  >
-                    <template #append>
-                      <el-select v-model="productForm.weightUnit" placeholder="请选择" style="width: 80px">
-                        <el-option label="kg" value="kg" />
-                        <el-option label="g" value="g" />
-                        <el-option label="t" value="t" />
-                      </el-select>
-                    </template>
-                  </el-input>
-                </el-form-item>
-              </el-col>
-              <el-col :span="12">
-                <el-form-item label="商品体积:">
-                  <el-input
-                    v-model="productForm.volume"
-                    placeholder="0"
-                    maxlength="10"
-                    show-word-limit
-                  >
-                    <template #append>
-                      <el-select v-model="productForm.volumeUnit" placeholder="请选择" style="width: 80px">
-                        <el-option label="m³" value="m3" />
-                        <el-option label="cm³" value="cm3" />
-                        <el-option label="L" value="L" />
-                      </el-select>
-                    </template>
-                  </el-input>
-                </el-form-item>
-              </el-col>
-            </el-row>
-
-            <!-- 参考链接 -->
-            <el-form-item label="参考链接">
-              <el-input
-                v-model="productForm.referenceLink"
-                type="textarea"
-                :rows="3"
-                placeholder="请输入参考链接"
-              />
-            </el-form-item>
-
-            <!-- 主供应商 -->
-            <el-form-item label="主供应商:" prop="mainLibraryIntro" required>
-              <el-select v-model="productForm.mainLibraryIntro" placeholder="请选择" clearable class="w-full" value-key="id">
-                <el-option
-                  v-for="option in supplierOptions"
-                  :key="option.id"
-                  :label="option.enterpriseName"
-                  :value="String(option.id)"
-                />
-              </el-select>
-            </el-form-item>
-
-            <!-- 售后服务 -->
-            <el-form-item label="售后服务:">
-              <el-select v-model="productForm.afterSalesService" placeholder="请选择" clearable class="w-full">
-                <el-option
-                  v-for="option in afterSalesOptions"
-                  :key="option.id"
-                  :label="option.afterSalesItems"
-                  :value="option.id"
-                />
-              </el-select>
-            </el-form-item>
-
-            <!-- 服务保障 -->
-            <el-form-item label="服务保障:">
-              <el-checkbox-group v-model="serviceGuarantees">
-                <el-checkbox
-                  v-for="option in serviceGuaranteeOptions"
-                  :key="option.id"
-                  :label="option.ensureName"
-                  :value="option.id"
-                />
-              </el-checkbox-group>
-            </el-form-item>
-
-            <!-- 安装服务 -->
-            <el-form-item label="安装服务:">
-              <el-checkbox-group v-model="installationServices">
-                <el-checkbox label="免费安装" value="freeInstallation" />
-              </el-checkbox-group>
-            </el-form-item>
-          </el-form>
-        </el-card>
-
-        <!-- 销售价格 -->
-        <el-card v-show="currentStep === 1" shadow="never" class="step-card mt-3">
-          <template #header>
-            <span class="text-lg font-bold">销售价格</span>
-          </template>
-
-          <el-form ref="priceFormRef" :model="productForm" :rules="productRules" label-width="120px" class="product-info-form">
-            <el-row :gutter="20">
-              <el-col :span="8">
-                <el-form-item label="市场价:" prop="midRangePrice" required>
-                  <el-input
-                    v-model="productForm.midRangePrice"
-                    type="number"
-                    placeholder="请输入市场价"
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="8">
-                <el-form-item label="平台售价:" prop="standardPrice" required>
-                  <el-input
-                    v-model="productForm.standardPrice"
-                    type="number"
-                    placeholder="请输入平台售价"
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="8">
-                <el-form-item label="最低售价:" prop="certificatePrice" required>
-                  <el-input
-                    v-model="productForm.certificatePrice"
-                    type="number"
-                    placeholder="请输入最低售价"
-                  />
-                </el-form-item>
-              </el-col>
-            </el-row>
-            <el-row :gutter="20">
-              <el-col :span="8">
-                <el-form-item label="最低起订量:" prop="minOrderQuantity" required>
-                  <el-input
-                    v-model="productForm.minOrderQuantity"
-                    type="number"
-                    placeholder="请输入最低起订量"
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="8">
-                <el-form-item label="备注:">
-                  <span class="currency-text">市场价>会员价>最低售价</span>
-                </el-form-item>
-              </el-col>
-            </el-row>
-
-          </el-form>
-        </el-card>
-
-        <!-- 采购价格 -->
-        <el-card v-show="currentStep === 1" shadow="never" class="step-card mt-3">
-          <template #header>
-            <span class="text-lg font-bold">采购价格</span>
-          </template>
-
-          <el-form ref="purchasePriceFormRef" :model="productForm" :rules="productRules" label-width="120px" class="product-info-form">
-            <el-row :gutter="20">
-              <el-col :span="12">
-                <el-form-item label="采购价:" prop="purchasePrice" required>
-                  <el-input
-                    v-model="productForm.purchasePrice"
-                    type="number"
-                    placeholder="请输入采购价"
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="12">
-                <el-form-item label="暂估采购价:">
-                  <el-input
-                    v-model="productForm.estimatedPurchasePrice"
-                    type="number"
-                    placeholder="请输入暂估采购价"
-                  />
-                </el-form-item>
-              </el-col>
-            </el-row>
-          </el-form>
-        </el-card>
-
-        <!-- 采购信息 -->
-        <el-card v-show="currentStep === 1" shadow="never" class="step-card mt-3">
-          <template #header>
-            <span class="text-lg font-bold">采购信息</span>
-          </template>
-
-          <el-form ref="purchaseInfoFormRef" :model="productForm" :rules="productRules" label-width="120px" class="product-info-form">
-            <el-row :gutter="20">
-              <el-col :span="12">
-                <el-form-item label="产品性质:" prop="productNature" required>
-                  <el-select v-model="productForm.productNature" placeholder="请选择" clearable class="w-full">
-                    <el-option label="自营" value="1" />
-                    <el-option label="代销" value="2" />
-                    <el-option label="定制" value="3" />
-                  </el-select>
-                </el-form-item>
-              </el-col>
-              <el-col :span="12">
-                <el-form-item label="采购人员:" prop="purchasingPersonnel" required>
-                  <el-select v-model="productForm.purchasingPersonnel" placeholder="请选择" clearable class="w-full" value-key="staffId">
-                    <el-option
-                      v-for="option in staffOptions"
-                      :key="option.staffId"
-                      :label="option.staffName"
-                      :value="String(option.staffId)"
-                    />
-                  </el-select>
-                </el-form-item>
-              </el-col>
-            </el-row>
-          </el-form>
-        </el-card>
-
-        <!-- 商品属性 -->
-        <el-card v-show="currentStep === 1" shadow="never" class="step-card mt-3">
-          <template #header>
-            <span class="text-lg font-bold">商品属性</span>
-          </template>
-
-          <el-form ref="attributeFormRef" :model="productForm" label-width="120px" class="product-info-form">
-            <div v-if="attributesList.length === 0" class="text-center text-gray-500 py-8">
-              该分类暂无属性配置
-            </div>
-            <template v-else>
-              <el-row :gutter="20" v-for="(row, rowIndex) in Math.ceil(attributesList.length / 2)" :key="rowIndex">
-                <el-col :span="12" v-for="colIndex in 2" :key="colIndex">
-                  <template v-if="attributesList[rowIndex * 2 + colIndex - 1]">
-                    <el-form-item
-                      :label="attributesList[rowIndex * 2 + colIndex - 1].productAttributesName + ':'"
-                      :required="attributesList[rowIndex * 2 + colIndex - 1].required === '1'"
-                    >
-                      <!-- 下拉选择 -->
-                      <el-select
-                        v-if="attributesList[rowIndex * 2 + colIndex - 1].entryMethod === '1'"
-                        v-model="productAttributesValues[attributesList[rowIndex * 2 + colIndex - 1].id]"
-                        placeholder="请选择"
-                        clearable
-                        class="w-full"
-                      >
-                        <el-option
-                          v-for="option in parseAttributesList(attributesList[rowIndex * 2 + colIndex - 1].attributesList)"
-                          :key="option"
-                          :label="option"
-                          :value="option"
-                        />
-                      </el-select>
-                      <!-- 多选 -->
-                      <el-select
-                        v-else-if="attributesList[rowIndex * 2 + colIndex - 1].entryMethod === '3'"
-                        v-model="productAttributesValues[attributesList[rowIndex * 2 + colIndex - 1].id]"
-                        placeholder="请选择"
-                        multiple
-                        clearable
-                        class="w-full"
-                      >
-                        <el-option
-                          v-for="option in parseAttributesList(attributesList[rowIndex * 2 + colIndex - 1].attributesList)"
-                          :key="option"
-                          :label="option"
-                          :value="option"
-                        />
-                      </el-select>
-                      <!-- 文本输入 -->
-                      <el-input
-                        v-else
-                        v-model="productAttributesValues[attributesList[rowIndex * 2 + colIndex - 1].id]"
-                        placeholder="请输入"
-                        clearable
-                      />
-                    </el-form-item>
-                  </template>
-                </el-col>
-              </el-row>
-            </template>
-          </el-form>
-        </el-card>
-
-        <!-- 商品详情 -->
-        <el-card v-show="currentStep === 1" shadow="never" class="step-card mt-3">
-          <template #header>
-            <span class="text-lg font-bold">商品详情</span>
-          </template>
-
-          <el-form ref="detailFormRef" :model="productForm" label-width="120px" class="product-info-form">
-            <!-- 商品主图 -->
-            <el-form-item label="商品主图:">
-              <div class="image-upload-container">
-                <div v-if="productForm.productImage" class="image-preview">
-                  <img :src="productForm.productImage" class="preview-image" />
-                  <div class="image-actions">
-                    <el-button size="small" @click="openMainImageSelector">重新选择</el-button>
-                    <el-button size="small" type="danger" @click="clearMainImage">删除</el-button>
-                  </div>
-                </div>
-                <div v-else class="image-upload-placeholder" @click="openMainImageSelector">
-                  <el-icon class="upload-icon"><Plus /></el-icon>
-                  <div class="upload-text">点击选择图片</div>
-                </div>
-              </div>
-              <div class="form-item-tip">
-                从图片库选择,建议尺寸300*300px
-              </div>
-            </el-form-item>
-
-            <!-- 商品详情 -->
-            <el-form-item label="商品详情:">
-              <el-tabs v-model="activeDetailTab" type="border-card">
-                <el-tab-pane label="电脑端详情" name="pc">
-                  <Editor v-model="productForm.pcDetail" :height="400" />
-                </el-tab-pane>
-                <el-tab-pane label="移动端详情" name="mobile">
-                  <Editor v-model="productForm.mobileDetail" :height="400" />
-                </el-tab-pane>
-              </el-tabs>
-            </el-form-item>
-          </el-form>
-        </el-card>
-
-        <!-- 定制说明 -->
-        <el-card v-show="currentStep === 1" shadow="never" class="step-card mt-3">
-          <template #header>
-            <span class="text-lg font-bold">定制说明</span>
-          </template>
-
-          <el-form ref="customFormRef" :model="customForm" label-width="120px" class="product-info-form">
-            <!-- 可定制开关 -->
-            <el-form-item label="可定制:">
-              <el-switch v-model="customForm.customizable" />
-            </el-form-item>
-
-            <!-- 定制内容 -->
-            <template v-if="customForm.customizable">
-              <!-- 定制方式 -->
-              <el-form-item label="定制方式:">
-                <div class="custom-options">
-                  <el-button
-                    v-for="option in customMethodOptions"
-                    :key="option.value"
-                    :type="customForm.selectedMethods.includes(option.value) ? 'primary' : 'default'"
-                    @click="toggleMethod(option.value)"
-                  >
-                    {{ option.label }}
-                  </el-button>
-                </div>
-              </el-form-item>
-
-              <!-- 定制工艺 -->
-              <el-form-item label="定制工艺:">
-                <div class="custom-options">
-                  <el-button
-                    v-for="craft in customCraftOptions"
-                    :key="craft.value"
-                    :type="customForm.selectedCrafts.includes(craft.value) ? 'primary' : 'default'"
-                    @click="toggleCraft(craft.value)"
-                  >
-                    {{ craft.label }}
-                  </el-button>
-                </div>
-              </el-form-item>
-
-              <!-- 定制方式表格 -->
-              <el-form-item label="" label-width="120">
-                <el-table :data="customForm.customDetails" border class="custom-table">
-                  <el-table-column label="装饰方法" width="120">
-                    <template #default="{ row }">
-                      <span>{{ row.decorationMethod }}</span>
-                    </template>
-                  </el-table-column>
-                  <el-table-column label="定制工艺" width="120">
-                    <template #default="{ row }">
-                      <span>{{ row.craft }}</span>
-                    </template>
-                  </el-table-column>
-                  <el-table-column label="起订数量" width="150">
-                    <template #default="{ row }">
-                      <el-input v-model="row.minOrderQty" placeholder="请输入" />
-                    </template>
-                  </el-table-column>
-                  <el-table-column label="起订价格" width="150">
-                    <template #default="{ row }">
-                      <el-input v-model="row.minOrderPrice" placeholder="请输入" />
-                    </template>
-                  </el-table-column>
-                  <el-table-column label="打样工期[天]" width="150">
-                    <template #default="{ row }">
-                      <el-input v-model="row.samplePeriod" placeholder="请输入" />
-                    </template>
-                  </el-table-column>
-                  <el-table-column label="生产周期[天]" width="150">
-                    <template #default="{ row }">
-                      <el-input v-model="row.productionPeriod" placeholder="请输入" />
-                    </template>
-                  </el-table-column>
-                  <el-table-column label="操作" width="100" fixed="right">
-                    <template #default="{ $index }">
-                      <el-link type="danger" :underline="false" @click="removeCustomDetail($index)">
-                        删除
-                      </el-link>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </el-form-item>
-
-              <!-- 定制说明 -->
-              <el-form-item label="定制说明:">
-                <el-input
-                  v-model="customForm.customDescription"
-                  type="textarea"
-                  :rows="5"
-                  placeholder="请输入定制说明"
-                />
-              </el-form-item>
-            </template>
-          </el-form>
-        </el-card>
-
-        <!-- 步骤3: 完成 -->
-        <el-card v-show="currentStep === 2" shadow="never" class="step-card completion-card">
-          <div class="completion-content">
-            <div class="success-icon">
-              <el-icon :size="80" color="#67c23a">
-                <CircleCheck />
-              </el-icon>
-            </div>
-            <div class="completion-text">
-              商品编辑完成,请点击返回,继续其他操作
-            </div>
-            <div class="completion-action">
-              <el-button type="primary" @click="handleBackToList">返回</el-button>
-            </div>
-          </div>
-        </el-card>
-      </div>
-
-      <!-- 底部操作按钮 -->
-      <el-card v-if="currentStep < 2" shadow="never" class="mt-3">
-        <div class="flex justify-center gap-4">
-          <el-button v-if="currentStep > 0" @click="prevStep">上一步</el-button>
-          <el-button v-if="currentStep < 2" type="primary" @click="nextStep">下一步</el-button>
-          <el-button @click="handleBack">取消</el-button>
-        </div>
-      </el-card>
-    </div>
-
-    <!-- 文件选择器组件 -->
-    <FileSelector
-      v-model="mainImageSelectorVisible"
-      :allowed-types="[1]"
-      :multiple="false"
-      title="选择商品主图"
-      @confirm="handleMainImageSelected"
-    />
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref, reactive, computed, onMounted, watch } from 'vue';
-import { useRoute, useRouter } from 'vue-router';
-import { ElMessage } from 'element-plus';
-import { Warning, ArrowRight, Check, Plus, CircleCheck } from '@element-plus/icons-vue';
-import Editor from '@/components/Editor/index.vue';
-import FileSelector from '@/components/FileSelector/index.vue';
-import { categoryTreeVO } from '@/api/product/category/types';
-import { BrandVO } from '@/api/product/brand/types';
-import { BaseForm } from '@/api/product/base/types';
-import { AttributesVO } from '@/api/product/attributes/types';
-import { addBase, updateBase, getBase, brandList, categoryTree, categoryAttributeList, getAfterSaleList, getServiceList, getUnitList } from '@/api/product/base';
-import { listInfo } from '@/api/customer/supplierInfo';
-import { InfoVO } from '@/api/customer/supplierInfo/types';
-import { listComStaff } from '@/api/system/comStaff';
-import { ComStaffVO } from '@/api/system/comStaff/types';
-
-const route = useRoute();
-const router = useRouter();
-
-const currentStep = ref(0);
-const loading = ref(false);
-const submitLoading = ref(false);
-const productFormRef = ref();
-
-// 服务保障和安装服务的多选框
-const serviceGuarantees = ref<(string | number)[]>([]);
-const installationServices = ref<string[]>([]);
-
-// 商品详情选项卡
-const activeDetailTab = ref('pc');
-
-// 文件选择器相关
-const mainImageSelectorVisible = ref(false);
-
-// 定制说明表单
-const customForm = reactive({
-  customizable: false,
-  selectedMethods: [] as string[],
-  selectedCrafts: [] as string[],
-  customDetails: [] as Array<{
-    decorationMethod: string;
-    craft: string;
-    minOrderQty: string;
-    minOrderPrice: string;
-    samplePeriod: string;
-    productionPeriod: string;
-  }>,
-  customDescription: ''
-});
-
-// 定制方式选项
-const customMethodOptions = [
-  { label: '包装定制', value: 'package' },
-  { label: '商品定制', value: 'product' },
-  { label: '开模定制', value: 'mold' }
-];
-
-// 定制工艺选项
-const customCraftOptions = [
-  { label: '丝印', value: 'silkScreen' },
-  { label: '热转印', value: 'thermalTransfer' },
-  { label: '激光', value: 'laser' },
-  { label: '烤花', value: 'baking' },
-  { label: '压印', value: 'embossing' }
-];
-
-// 定制方式映射
-const customMethodMap: Record<string, string> = {
-  'package': '包装定制',
-  'product': '商品定制',
-  'mold': '开模定制'
-};
-
-// 定制工艺映射
-const customCraftMap: Record<string, string> = {
-  'silkScreen': '丝印',
-  'thermalTransfer': '热转印',
-  'laser': '激光',
-  'baking': '烤花',
-  'embossing': '压印'
-};
-
-// 服务保障选择不需要watch,在提交时直接转换为逗号分隔字符串
-
-// 监听安装服务复选框变化,同步到表单
-watch(installationServices, (newVal) => {
-  productForm.freeInstallation = newVal.includes('freeInstallation') ? '1' : '0';
-}, { deep: true });
-
-// 监听定制方式和工艺选择变化,更新表格数据
-watch([() => customForm.selectedMethods, () => customForm.selectedCrafts], ([newMethods, newCrafts]) => {
-  const newDetails: typeof customForm.customDetails = [];
-
-  // 遍历所有选中的定制方式和工艺组合
-  newMethods.forEach(method => {
-    const decorationMethod = customMethodMap[method];
-
-    newCrafts.forEach(craft => {
-      const craftName = customCraftMap[craft];
-
-      // 查找是否已存在该组合的数据
-      const existing = customForm.customDetails.find(
-        item => item.decorationMethod === decorationMethod && item.craft === craftName
-      );
-
-      newDetails.push(existing || {
-        decorationMethod,
-        craft: craftName,
-        minOrderQty: '',
-        minOrderPrice: '',
-        samplePeriod: '',
-        productionPeriod: ''
-      });
-    });
-  });
-
-  customForm.customDetails = newDetails;
-}, { deep: true });
-
-// 切换定制方式选择
-const toggleMethod = (method: string) => {
-  const index = customForm.selectedMethods.indexOf(method);
-  if (index > -1) {
-    customForm.selectedMethods.splice(index, 1);
-  } else {
-    customForm.selectedMethods.push(method);
-  }
-};
-
-// 切换定制工艺选择
-const toggleCraft = (craft: string) => {
-  const index = customForm.selectedCrafts.indexOf(craft);
-  if (index > -1) {
-    customForm.selectedCrafts.splice(index, 1);
-  } else {
-    customForm.selectedCrafts.push(craft);
-  }
-};
-
-// 删除定制详情行
-const removeCustomDetail = (index: number) => {
-  customForm.customDetails.splice(index, 1);
-};
-
-const pageTitle = computed(() => {
-  return route.params.id ? '编辑商品' : '新增商品';
-});
-
-// 分类选择表单
-const categoryForm = reactive({
-  topCategoryId: undefined as string | number | undefined,
-  mediumCategoryId: undefined as string | number | undefined,
-  bottomCategoryId: undefined as string | number | undefined,
-});
-
-const autoCreateCategory = ref(false);
-const manualCategoryInput = ref('');
-
-// 商品信息表单
-const productForm = reactive<BaseForm>({
-  id: undefined,
-  productNo: undefined,
-  itemName: undefined,
-  brandId: undefined,
-  topCategoryId: undefined,
-  mediumCategoryId: undefined,
-  bottomCategoryId: undefined,
-  unitId: undefined,
-  productImage: undefined,
-  isSelf: 0,
-  productReviewStatus: 0,
-  homeRecommended: 0,
-  categoryRecommendation: 0,
-  cartRecommendation: 0,
-  recommendedProductOrder: 0,
-  isPopular: 0,
-  isNew: 0,
-  productStatus: '0',
-  remark: undefined,
-  a10ProductName: undefined,
-  specification: undefined,
-  upcBarcode: undefined,
-  invoiceName: undefined,
-  invoiceSpec: undefined,
-  packagingSpec: undefined,
-  referenceLink: undefined,
-  weight: undefined,
-  weightUnit: 'kg',
-  volume: undefined,
-  volumeUnit: 'm3',
-  mainLibraryIntro: undefined,
-  afterSalesService: undefined,
-  serviceGuarantee: undefined, // 服务保障ID列表,逗号分隔
-  freeInstallation: '0',
-  midRangePrice: undefined,
-  standardPrice: undefined,
-  certificatePrice: undefined,
-  purchasePrice: undefined,
-  estimatedPurchasePrice: undefined,
-  productNature: '1',
-  purchasingPersonnel: '1',
-  pcDetail: undefined,
-  mobileDetail: undefined,
-  taxRate: undefined,
-  currency: 'RMB',
-  minOrderQuantity: undefined,
-  salesVolume: undefined,
-});
-
-// 表单验证规则
-const productRules = {
-  productNo: [{ required: true, message: '商品编号不能为空', trigger: 'blur' }],
-  itemName: [{ required: true, message: '商品名称不能为空', trigger: 'blur' }],
-  brandId: [{ required: true, message: '商品品牌不能为空', trigger: 'change' }],
-  mainLibraryIntro: [{ required: true, message: '主供应商不能为空', trigger: 'change' }],
-  midRangePrice: [{ required: true, message: '市场价不能为空', trigger: 'blur' }],
-  standardPrice: [{ required: true, message: '平台售价不能为空', trigger: 'blur' }],
-  certificatePrice: [{ required: true, message: '最低售价不能为空', trigger: 'blur' }],
-  purchasePrice: [{ required: true, message: '采购价不能为空', trigger: 'blur' }],
-  productNature: [{ required: true, message: '产品性质不能为空', trigger: 'change' }],
-  purchasingPersonnel: [{ required: true, message: '采购人员不能为空', trigger: 'change' }],
-  taxRate: [{ required: true, message: '税率不能为空', trigger: 'blur' }],
-  minOrderQuantity: [{ required: true, message: '最低起订量不能为空', trigger: 'blur' }],
-};
-
-// 分类和品牌选项
-const categoryOptions = ref<categoryTreeVO[]>([]);
-const brandOptions = ref<BrandVO[]>([]);
-const brandLoading = ref(false);
-const brandOptionsFormatted = computed(() => {
-  return brandOptions.value.slice(0, 500).map(item => ({
-    label: item.brandName,
-    value: item.id
-  }));
-});
-
-// 商品属性列表
-const attributesList = ref<AttributesVO[]>([]);
-const productAttributesValues = ref<Record<string | number, any>>({});
-
-// 售后服务和服务保障选项
-const afterSalesOptions = ref<any[]>([]);
-const serviceGuaranteeOptions = ref<any[]>([]);
-
-// 单位选项
-const unitOptions = ref<any[]>([]);
-
-// 主供应商选项
-const supplierOptions = ref<InfoVO[]>([]);
-
-// 采购人员选项
-const staffOptions = ref<ComStaffVO[]>([]);
-
-// 搜索关键词
-const searchLevel1 = ref('');
-const searchLevel2 = ref('');
-const searchLevel3 = ref('');
-
-// 一级分类列表
-const level1Categories = computed(() => {
-  return categoryOptions.value || [];
-});
-
-// 二级分类列表
-const level2Categories = ref<categoryTreeVO[]>([]);
-
-// 三级分类列表
-const level3Categories = ref<categoryTreeVO[]>([]);
-
-// 过滤后的一级分类列表
-const filteredLevel1Categories = computed(() => {
-  if (!searchLevel1.value) {
-    return level1Categories.value;
-  }
-  return level1Categories.value.filter(item =>
-    item.label.toLowerCase().includes(searchLevel1.value.toLowerCase())
-  );
-});
-
-// 过滤后的二级分类列表
-const filteredLevel2Categories = computed(() => {
-  if (!searchLevel2.value) {
-    return level2Categories.value;
-  }
-  return level2Categories.value.filter(item =>
-    item.label.toLowerCase().includes(searchLevel2.value.toLowerCase())
-  );
-});
-
-// 过滤后的三级分类列表
-const filteredLevel3Categories = computed(() => {
-  if (!searchLevel3.value) {
-    return level3Categories.value;
-  }
-  return level3Categories.value.filter(item =>
-    item.label.toLowerCase().includes(searchLevel3.value.toLowerCase())
-  );
-});
-
-// 选中的分类名称
-const selectedLevel1Name = ref('');
-const selectedLevel2Name = ref('');
-const selectedLevel3Name = ref('');
-
-// 选择一级分类
-const selectLevel1 = (item: categoryTreeVO) => {
-  categoryForm.topCategoryId = item.id;
-  categoryForm.mediumCategoryId = undefined;
-  categoryForm.bottomCategoryId = undefined;
-  selectedLevel1Name.value = item.label;
-  selectedLevel2Name.value = '';
-  selectedLevel3Name.value = '';
-
-  level2Categories.value = item.children || [];
-  level3Categories.value = [];
-};
-
-// 选择二级分类
-const selectLevel2 = (item: categoryTreeVO) => {
-  categoryForm.mediumCategoryId = item.id;
-  categoryForm.bottomCategoryId = undefined;
-  selectedLevel2Name.value = item.label;
-  selectedLevel3Name.value = '';
-
-  level3Categories.value = item.children || [];
-};
-
-// 选择三级分类
-const selectLevel3 = async (item: categoryTreeVO) => {
-  categoryForm.bottomCategoryId = item.id;
-  selectedLevel3Name.value = item.label;
-
-  // 加载该分类下的属性列表
-  await loadCategoryAttributes(item.id);
-};
-
-// 获取分类路径
-const getCategoryPath = () => {
-  const parts = [];
-  if (selectedLevel1Name.value) parts.push(selectedLevel1Name.value);
-  if (selectedLevel2Name.value) parts.push(selectedLevel2Name.value);
-  if (selectedLevel3Name.value) parts.push(selectedLevel3Name.value);
-  return parts.join(' > ') || '请选择分类';
-};
-
-// 清除分类
-const clearCategory = () => {
-  categoryForm.topCategoryId = undefined;
-  categoryForm.mediumCategoryId = undefined;
-  categoryForm.bottomCategoryId = undefined;
-  selectedLevel1Name.value = '';
-  selectedLevel2Name.value = '';
-  selectedLevel3Name.value = '';
-  level2Categories.value = [];
-  level3Categories.value = [];
-  attributesList.value = [];
-  productAttributesValues.value = {};
-};
-
-// 下一步
-const nextStep = async () => {
-  if (currentStep.value === 0) {
-    // 验证分类选择
-    if (!categoryForm.topCategoryId) {
-      ElMessage.warning('请选择一级分类');
-      return;
-    }
-    if (!categoryForm.mediumCategoryId) {
-      ElMessage.warning('请选择二级分类');
-      return;
-    }
-    if (!categoryForm.bottomCategoryId) {
-      ElMessage.warning('请选择三级分类');
-      return;
-    }
-
-    // 将分类信息同步到商品表单
-    productForm.topCategoryId = categoryForm.topCategoryId;
-    productForm.mediumCategoryId = categoryForm.mediumCategoryId;
-    productForm.bottomCategoryId = categoryForm.bottomCategoryId;
-
-    currentStep.value++;
-  } else if (currentStep.value === 1) {
-    // 验证商品信息表单并提交
-    try {
-      await productFormRef.value?.validate();
-      // 调用提交函数
-      await handleSubmit();
-    } catch (error) {
-      ElMessage.warning('请完善商品信息');
-      return;
-    }
-  }
-};
-
-// 上一步
-const prevStep = () => {
-  if (currentStep.value > 0) {
-    currentStep.value--;
-  }
-};
-
-// 提交
-const handleSubmit = async () => {
-  try {
-    submitLoading.value = true;
-
-    // 准备提交数据,包含定制信息
-    const submitData = {
-      ...productForm,
-      // 将服务保障ID数组转换为逗号分隔字符串
-      serviceGuarantee: serviceGuarantees.value.map(id => String(id)).join(','),
-      // 将商品属性值转换为JSON字符串
-      attributesList: JSON.stringify(productAttributesValues.value),
-      customizable: customForm.customizable,
-      customizedStyle: customForm.selectedMethods.join(','),
-      customizedCraft: customForm.selectedCrafts.join(','),
-      customDescription: customForm.customDescription,
-      customDetailsJson: JSON.stringify(customForm.customDetails)
-    };
-
-    if (productForm.id) {
-      await updateBase(submitData);
-      ElMessage.success('修改成功');
-    } else {
-      await addBase(submitData);
-      ElMessage.success('新增成功');
-    }
-    // 跳转到完成页面(步骤3)
-    currentStep.value = 2;
-  } catch (error) {
-    console.error('提交失败:', error);
-  } finally {
-    submitLoading.value = false;
-  }
-};
-
-// 返回
-const handleBack = () => {
-  router.back();
-};
-
-// 返回列表
-const handleBackToList = () => {
-  router.push('/product/base');
-};
-
-// 打开主图选择器
-const openMainImageSelector = () => {
-  mainImageSelectorVisible.value = true;
-};
-
-// 处理主图选择
-const handleMainImageSelected = (files: any[]) => {
-  if (files && files.length > 0) {
-    productForm.productImage = files[0].url;
-  }
-};
-
-// 清除主图
-const clearMainImage = () => {
-  productForm.productImage = undefined;
-};
-
-// 获取分类树
-const getCategoryTree = async () => {
-  try {
-    const res = await categoryTree();
-    categoryOptions.value = res.data || [];
-  } catch (error) {
-    console.error('获取分类树失败:', error);
-  }
-};
-
-// 获取品牌列表(实时请求,每次只加载500条)
-const getBrandList = async () => {
-  try {
-    brandLoading.value = true;
-    const res = await brandList({ pageNum: 1, pageSize: 500 });
-    brandOptions.value = res.data || [];
-    // 如果是新增模式且有选项,设置第一个为默认值
-    if (!route.params.id && brandOptions.value.length > 0 && !productForm.brandId) {
-      productForm.brandId = brandOptions.value[0].id;
-    }
-  } catch (error) {
-    console.error('获取品牌列表失败:', error);
-  } finally {
-    brandLoading.value = false;
-  }
-};
-
-// 处理品牌下拉框显示/隐藏
-const handleBrandVisibleChange = (visible: boolean) => {
-  if (visible && brandOptions.value.length === 0) {
-    getBrandList();
-  }
-};
-
-// 获取售后服务列表
-const getAfterSalesOptions = async () => {
-  try {
-    const res = await getAfterSaleList();
-    afterSalesOptions.value = res.data || [];
-    // 如果是新增模式且有选项,设置第一个为默认值
-    if (!route.params.id && afterSalesOptions.value.length > 0 && !productForm.afterSalesService) {
-      productForm.afterSalesService = afterSalesOptions.value[0].id;
-    }
-  } catch (error) {
-    console.error('获取售后服务列表失败:', error);
-  }
-};
-
-// 获取服务保障列表
-const getServiceGuaranteeOptions = async () => {
-  try {
-    const res = await getServiceList();
-    serviceGuaranteeOptions.value = res.data || [];
-    // 如果是新增模式且有选项,设置第一个为默认选中
-    if (!route.params.id && serviceGuaranteeOptions.value.length > 0 && serviceGuarantees.value.length === 0) {
-      serviceGuarantees.value = [serviceGuaranteeOptions.value[0].id];
-    }
-  } catch (error) {
-    console.error('获取服务保障列表失败:', error);
-  }
-};
-
-// 获取单位列表
-const getUnitOptions = async () => {
-  try {
-    const res = await getUnitList();
-    unitOptions.value = res.data || [];
-    // 如果是新增模式且有选项,设置第一个为默认值
-    if (!route.params.id && unitOptions.value.length > 0 && !productForm.unitId) {
-      productForm.unitId = unitOptions.value[0].id;
-    }
-  } catch (error) {
-    console.error('获取单位列表失败:', error);
-  }
-};
-
-// 获取主供应商列表
-const getSupplierOptions = async () => {
-  try {
-    const res = await listInfo();
-    console.log('供应商接口返回:', res);
-    // 处理可能的数据结构: res.data 或 res.rows
-    const dataList = res.data || res.rows || [];
-    supplierOptions.value = dataList;
-    console.log('供应商列表:', supplierOptions.value);
-    // 如果有选项且当前没有选中值,设置第一个为默认值
-    if (supplierOptions.value.length > 0 && !productForm.mainLibraryIntro) {
-      productForm.mainLibraryIntro = String(supplierOptions.value[0].id);
-    }
-  } catch (error) {
-    console.error('获取主供应商列表失败:', error);
-  }
-};
-
-// 获取采购人员列表
-const getStaffOptions = async () => {
-  try {
-    const res = await listComStaff();
-    console.log('采购人员接口返回:', res);
-    // 处理可能的数据结构: res.data 或 res.rows
-    const dataList = res.data || res.rows || [];
-    staffOptions.value = dataList;
-    console.log('采购人员列表:', staffOptions.value);
-    // 如果有选项且当前没有选中值,设置第一个为默认值
-    if (staffOptions.value.length > 0 && !productForm.purchasingPersonnel) {
-      productForm.purchasingPersonnel = String(staffOptions.value[0].staffId);
-    }
-  } catch (error) {
-    console.error('获取采购人员列表失败:', error);
-  }
-};
-
-// 加载分类属性列表
-const loadCategoryAttributes = async (categoryId: string | number) => {
-  try {
-    const res = await categoryAttributeList(categoryId);
-    attributesList.value = res.data || [];
-    // 清空之前的属性值
-    productAttributesValues.value = {};
-
-    // 如果是新增模式,为有选项的属性设置默认值
-    if (!route.params.id) {
-      attributesList.value.forEach(attr => {
-        if (attr.entryMethod === '1' && attr.attributesList) { // 下拉选择
-          const options = parseAttributesList(attr.attributesList);
-          if (options.length > 0) {
-            productAttributesValues.value[attr.id] = options[0];
-          }
-        } else if (attr.entryMethod === '3' && attr.attributesList) { // 多选
-          const options = parseAttributesList(attr.attributesList);
-          if (options.length > 0) {
-            productAttributesValues.value[attr.id] = [options[0]];
-          }
-        }
-      });
-    }
-  } catch (error) {
-    console.error('加载分类属性失败:', error);
-    attributesList.value = [];
-  }
-};
-
-// 解析属性值列表(JSON数组或逗号分隔字符串)
-const parseAttributesList = (attributesListStr: string): string[] => {
-  if (!attributesListStr) return [];
-
-  try {
-    // 尝试解析为JSON数组
-    const parsed = JSON.parse(attributesListStr);
-    if (Array.isArray(parsed)) {
-      return parsed;
-    }
-  } catch (e) {
-    // 如果不是JSON,按逗号分隔
-    return attributesListStr.split(',').map(item => item.trim()).filter(item => item);
-  }
-
-  return [];
-};
-
-// 加载商品详情(编辑模式)
-const loadProductDetail = async () => {
-  const id = route.params.id;
-  if (id) {
-    try {
-      loading.value = true;
-      const res = await getBase(id as string);
-      Object.assign(productForm, res.data);
-
-      // 回显分类选择
-      categoryForm.topCategoryId = res.data.topCategoryId;
-      categoryForm.mediumCategoryId = res.data.mediumCategoryId;
-      categoryForm.bottomCategoryId = res.data.bottomCategoryId;
-
-      // 回显服务保障复选框 - 将逗号分隔的ID字符串转换为数组
-      if (res.data.serviceGuarantee) {
-        serviceGuarantees.value = res.data.serviceGuarantee.split(',').map((id: string) => {
-          // 尝试转换为数字,如果失败则保持字符串
-          const numId = Number(id.trim());
-          return isNaN(numId) ? id.trim() : numId;
-        });
-      } else {
-        serviceGuarantees.value = [];
-      }
-
-      // 回显安装服务复选框
-      const services: string[] = [];
-      if (res.data.freeInstallation === '1') services.push('freeInstallation');
-      installationServices.value = services;
-
-      // 回显商品属性值
-      if (res.data.attributesList) {
-        try {
-          const parsedAttributes = JSON.parse(res.data.attributesList);
-          productAttributesValues.value = parsedAttributes;
-        } catch (e) {
-          console.error('解析商品属性失败:', e);
-          productAttributesValues.value = {};
-        }
-      }
-
-      // 回显分类名称
-      if (categoryForm.topCategoryId) {
-        const level1 = level1Categories.value.find(item => item.id === categoryForm.topCategoryId);
-        if (level1) {
-          selectLevel1(level1);
-
-          if (categoryForm.mediumCategoryId) {
-            const level2 = level2Categories.value.find(item => item.id === categoryForm.mediumCategoryId);
-            if (level2) {
-              selectLevel2(level2);
-
-              if (categoryForm.bottomCategoryId) {
-                const level3 = level3Categories.value.find(item => item.id === categoryForm.bottomCategoryId);
-                if (level3) {
-                  await selectLevel3(level3);
-                }
-              }
-            }
-          }
-        }
-      }
-    } catch (error) {
-      console.error('加载商品详情失败:', error);
-      ElMessage.error('加载商品详情失败');
-    } finally {
-      loading.value = false;
-    }
-  }
-};
-
-onMounted(async () => {
-  await getCategoryTree();
-  await getUnitOptions();
-  await getAfterSalesOptions();
-  await getServiceGuaranteeOptions();
-  // 先加载商品详情(如果是编辑模式)
-  await loadProductDetail();
-  // 再加载下拉选项,这样如果详情中没有值,会自动设置第一个
-  await getSupplierOptions();
-  await getStaffOptions();
-});
-</script>
-
-<style scoped lang="scss">
-.product-wizard-page {
-  .category-selection {
-    margin-top: 12px;
-  }
-
-  .category-box {
-    border: 1px solid #e4e7ed;
-    border-radius: 4px;
-    overflow: hidden;
-
-    .category-header {
-      background-color: #f5f7fa;
-      padding: 10px 12px;
-      font-weight: 600;
-      border-bottom: 1px solid #e4e7ed;
-      text-align: center;
-      font-size: 14px;
-    }
-
-    .category-search {
-      padding: 10px;
-      border-bottom: 1px solid #e4e7ed;
-      background-color: #fff;
-    }
-
-    .category-list {
-      height: 280px;
-      overflow-y: auto;
-
-      .category-item {
-        padding: 10px 12px;
-        cursor: pointer;
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        border-bottom: 1px solid #f0f0f0;
-        transition: all 0.3s;
-
-        &:hover {
-          background-color: #f5f7fa;
-        }
-
-        &.active {
-          background-color: #ecf5ff;
-          color: #409eff;
-          font-weight: 600;
-        }
-
-        &:last-child {
-          border-bottom: none;
-        }
-      }
-    }
-  }
-
-  .confirm-info {
-    margin-top: 12px;
-    text-align: left;
-  }
-
-  .product-info-form {
-    .category-display {
-      display: flex;
-      align-items: center;
-
-      .category-text {
-        color: #606266;
-      }
-    }
-
-    .form-item-tip {
-      font-size: 12px;
-      color: #909399;
-      line-height: 1.5;
-      margin-top: 4px;
-    }
-
-    .currency-text {
-      color: #303133;
-      font-size: 14px;
-    }
-  }
-
-  .image-upload-container {
-    width: 178px;
-
-    .image-preview {
-      position: relative;
-
-      .preview-image {
-        width: 178px;
-        height: 178px;
-        display: block;
-        object-fit: cover;
-        border-radius: 6px;
-        border: 1px solid #dcdfe6;
-      }
-
-      .image-actions {
-        margin-top: 8px;
-        display: flex;
-        gap: 8px;
-      }
-    }
-
-    .image-upload-placeholder {
-      width: 178px;
-      height: 178px;
-      border: 1px dashed #d9d9d9;
-      border-radius: 6px;
-      cursor: pointer;
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-      justify-content: center;
-      transition: all 0.3s;
-      background-color: #fafafa;
-
-      &:hover {
-        border-color: #409eff;
-        background-color: #f5f7fa;
-      }
-
-      .upload-icon {
-        font-size: 28px;
-        color: #8c939d;
-        margin-bottom: 8px;
-      }
-
-      .upload-text {
-        color: #8c939d;
-        font-size: 14px;
-      }
-    }
-  }
-
-  .custom-options {
-    display: flex;
-    gap: 10px;
-    flex-wrap: wrap;
-  }
-
-  .custom-table {
-    width: 100%;
-    margin-top: 10px;
-  }
-
-  .completion-card {
-    min-height: 400px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-
-    .completion-content {
-      text-align: center;
-      padding: 40px 0;
-
-      .success-icon {
-        margin-bottom: 24px;
-      }
-
-      .completion-text {
-        font-size: 16px;
-        color: #606266;
-        margin-bottom: 32px;
-        line-height: 1.6;
-      }
-
-      .completion-action {
-        display: flex;
-        justify-content: center;
-      }
-    }
-  }
-}
-</style>

+ 0 - 595
src/views/product/base/index.vue

@@ -1,595 +0,0 @@
-<template>
-  <div class="p-2">
-    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-      <div v-show="showSearch" class="mb-[10px]">
-        <el-card shadow="hover">
-          <el-form ref="queryFormRef" :model="queryParams" label-width="90px">
-            <el-row :gutter="20">
-              <el-col :span="6">
-                <el-form-item label="商品编号" prop="productNo">
-                  <el-input v-model="queryParams.productNo" placeholder="请输入商品编号" clearable @keyup.enter="handleQuery" />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="商品名称" prop="itemName">
-                  <el-input v-model="queryParams.itemName" placeholder="请输入商品名称" clearable @keyup.enter="handleQuery" />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="商品品牌" prop="brandName">
-                  <el-input v-model="queryParams.brandName" placeholder="请输入商品品牌" clearable @keyup.enter="handleQuery" />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="商品来源" prop="purchaseNature">
-                  <el-input v-model="queryParams.itemName" placeholder="请输入商品来源" clearable @keyup.enter="handleQuery" />
-                </el-form-item>
-              </el-col>
-            </el-row>
-            <el-row :gutter="20">
-              <el-col :span="6">
-                <el-form-item label="商品分类" prop="bottomCategoryId">
-                  <el-tree-select
-                    v-model="queryParams.bottomCategoryId"
-                    :data="categoryOptions"
-                    :props="{ value: 'id', label: 'label', children: 'children' } as any"
-                    value-key="id"
-                    placeholder="请选择商品分类"
-                    clearable
-                    check-strictly
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="是否自营" prop="isSelf">
-                  <el-select v-model="queryParams.isSelf" placeholder="请选择" clearable>
-                    <el-option label="是" value="1" />
-                    <el-option label="否" value="0" />
-                  </el-select>
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="审核状态" prop="productReviewStatus">
-                  <el-select v-model="queryParams.productReviewStatus" placeholder="请选择" clearable>
-                    <el-option label="待采购审核" value="0" />
-                    <el-option label="审核通过" value="1" />
-                    <el-option label="驳回" value="2" />
-                    <el-option label="待营销审核" value="3" />
-                  </el-select>
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="上下架状态" prop="productStatus">
-                  <el-select v-model="queryParams.productStatus" placeholder="请选择" clearable>
-                    <el-option label="已上架" :value="1" />
-                    <el-option label="下架" :value="0" />
-                    <el-option label="上架中" :value="2" />
-                  </el-select>
-                </el-form-item>
-              </el-col>
-            </el-row>
-            <el-row>
-              <el-col :span="24" class="text-left">
-                <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-                <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-              </el-col>
-            </el-row>
-          </el-form>
-        </el-card>
-      </div>
-    </transition>
-
-    <!-- 统计信息区域 -->
-    <el-card shadow="never" class="mb-[10px]">
-      <div class="flex items-center text-sm text-gray-600">
-        <span>商品总数: </span>
-        <span class="text-blue-600 mx-1"
-          >总=<span class="text-red-600">{{ statistics.total || 0 }}</span
-          >条</span
-        >
-        <span class="mx-2">【上架/总数({{ statistics.onSale || 0 }}/{{ statistics.total || 0 }})】</span>
-        <span class="mx-2">审核状态: 待审核<span class="text-red-600">{{ statistics.waitAudit || 0 }}</span>条,通过<span class="text-green-600">{{ statistics.auditPass || 0 }}</span>条,驳回<span class="text-orange-600">{{ statistics.auditReject || 0 }}</span>条</span>
-        <span class="mx-2">上下架状态: 已上架<span class="text-green-600">{{ statistics.onSale || 0 }}</span>条,下架<span class="text-gray-600">{{ statistics.offSale || 0 }}</span>条</span>
-        <div class="ml-auto flex gap-2">
-          <el-button type="primary" icon="Plus" @click="handleAdd">商品新增</el-button>
-          <el-button type="warning" icon="Check" @click="handleGoReview">商品审核</el-button>
-          <el-button plain>批量操作</el-button>
-          <el-button plain icon="Download" @click="handleExport">导出</el-button>
-          <el-button circle icon="Refresh" @click="getList"></el-button>
-        </div>
-      </div>
-    </el-card>
-
-    <el-card shadow="never">
-      <el-table v-loading="loading" border :data="baseList" @selection-change="handleSelectionChange">
-        <el-table-column type="selection" width="55" align="center" />
-        <el-table-column label="商品编号" align="center" prop="productNo" width="120" fixed="left">
-          <template #default="scope">
-            <el-link type="primary" @click="handleView(scope.row)">{{ scope.row.productNo }}</el-link>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品图片" align="center" prop="productImage" width="100">
-          <template #default="scope">
-            <image-preview :src="scope.row.productImage" :width="60" :height="60" />
-          </template>
-        </el-table-column>
-        <el-table-column label="商品信息" align="center" width="250" show-overflow-tooltip>
-          <template #default="scope">
-            <div class="text-left">
-              <div>{{ scope.row.itemName }}</div>
-              <div class="text-gray-500" style="font-size: 12px">品牌: {{ scope.row.brandName || '-' }}</div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品分类" align="center" prop="categoryName" width="120" />
-        <el-table-column label="单位" align="center" prop="unitName" width="80" />
-        <el-table-column label="SKU价格" align="center" width="180">
-          <template #default="scope">
-            <div class="text-left" style="font-size: 12px">
-              <div>
-                <span class="text-gray-500">市场价:</span>
-                <span class="text-red-500">¥{{ scope.row.marketPrice || '0.00' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">会员价:</span>
-                <span class="text-red-500">¥{{ scope.row.memberPrice || '0.00' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">最低价:</span>
-                <span class="text-red-500">¥{{ scope.row.minSellingPrice || '0.00' }}</span>
-              </div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="成本情况" align="center" width="150">
-          <template #default="scope">
-            <div class="text-left" style="font-size: 12px">
-              <div>
-                <span class="text-gray-500">采购价:</span>
-                <span>¥{{ scope.row.purchasingPrice || '0.00' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">暂估毛利率:</span>
-                <span>{{ scope.row.tempGrossMargin || '0.0000' }}%</span>
-              </div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="数据来源" align="center" prop="dataSource" width="100">
-          <template #default="scope">
-            <span>{{ scope.row.dataSource || '-' }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="是否自营" align="center" width="100">
-          <template #default="scope">
-            <el-tag v-if="scope.row.isSelf === 1" type="success">是</el-tag>
-            <el-tag v-else-if="scope.row.isSelf === 0" type="info">否</el-tag>
-            <span v-else>-</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="审核状态" align="center" prop="productReviewStatus" width="100">
-          <template #default="scope">
-            <span v-if="scope.row.productReviewStatus === 0">待采购审核</span>
-            <span v-else-if="scope.row.productReviewStatus === 1">审核通过</span>
-            <span v-else-if="scope.row.productReviewStatus === 2">驳回</span>
-            <span v-else-if="scope.row.productReviewStatus === 3">待营销审核</span>
-            <span v-else>-</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="上下架状态" align="center" prop="productStatus" width="120">
-          <template #default="scope">
-            <el-tag v-if="scope.row.productStatus === 1" type="success">已上架</el-tag>
-            <el-tag v-else-if="scope.row.productStatus === 0" type="warning">下架</el-tag>
-            <el-tag v-else-if="scope.row.productStatus === 2" type="info">上架中</el-tag>
-            <el-tag v-else type="info">未知</el-tag>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" align="center" width="280" fixed="right">
-          <template #default="scope">
-            <!-- 待审核状态:只显示编辑 -->
-            <div v-if="scope.row.productReviewStatus !== 2" class="flex gap-1 justify-center">
-              <el-link type="primary" :underline="false" @click="handleUpdate(scope.row)">编辑</el-link>
-            </div>
-
-            <!-- 审核通过 -->
-            <div v-else-if="scope.row.productReviewStatus === 2" class="flex flex-col gap-1">
-              <!-- 下架状态:编辑、上架、停售、修改库存 -->
-              <div v-if="scope.row.productStatus === 0" class="flex gap-1 justify-center">
-                <el-link type="primary" :underline="false" @click="handleUpdate(scope.row)">编辑</el-link>
-                <el-link type="success" :underline="false" @click="handleShelf(scope.row)">上架</el-link>
-                <el-link type="danger" :underline="false" @click="handleDiscontinue(scope.row)">停售</el-link>
-              </div>
-              <div v-if="scope.row.productStatus === 0" class="flex gap-1 justify-center">
-                <el-link type="primary" :underline="false" @click="handleSupply(scope.row)">修改库存</el-link>
-              </div>
-
-              <!-- 上架状态:编辑、下架、停售、修改库存 -->
-              <div v-else-if="scope.row.productStatus === 1" class="flex gap-1 justify-center">
-                <el-link type="primary" :underline="false" @click="handleUpdate(scope.row)">编辑</el-link>
-                <el-link type="warning" :underline="false" @click="handleShelf(scope.row)">下架</el-link>
-                <el-link type="danger" :underline="false" @click="handleDiscontinue(scope.row)">停售</el-link>
-              </div>
-              <div v-else-if="scope.row.productStatus === 1" class="flex gap-1 justify-center">
-                <el-link type="primary" :underline="false" @click="handleSupply(scope.row)">修改库存</el-link>
-              </div>
-            </div>
-
-            <!-- 其他状态(待提交、审核驳回等):显示编辑 -->
-            <div v-else class="flex gap-1 justify-center">
-              <el-link type="primary" :underline="false" @click="handleUpdate(scope.row)">编辑</el-link>
-            </div>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <!-- 游标分页控制 -->
-      <pagination
-        v-show="baseList.length > 0"
-        v-model:page="queryParams.pageNum"
-        v-model:limit="queryParams.pageSize"
-        v-model:way="queryParams.way"
-        :cursor-mode="true"
-        :has-more="hasMore"
-        @pagination="getList"
-      />
-    </el-card>
-  </div>
-</template>
-
-<script setup name="Base" lang="ts">
-import { listBase, getBase, delBase, brandList, categoryTree, shelfReview, changeProductType, getProductStatusCount } from '@/api/product/base';
-import { BaseVO, BaseQuery, BaseForm, StatusCountVo } from '@/api/product/base/types';
-import { BrandVO } from '@/api/product/brand/types';
-import { categoryTreeVO } from '@/api/product/category/types';
-import { useRoute, useRouter } from 'vue-router';
-
-const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const router = useRouter();
-const route = useRoute();
-
-const baseList = ref<BaseVO[]>([]);
-const buttonLoading = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref<Array<string | number>>([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-const categoryOptions = ref<categoryTreeVO[]>([]);
-const hasMore = ref(true); // 是否还有更多数据
-// 页面历史记录,存储每页的第一个id和最后一个id,用于支持双向翻页
-const pageHistory = ref([]);
-
-// 统计信息
-const statistics = ref<StatusCountVo>({
-  total: 0,
-  onSale: 0,
-  offSale: 0,
-  waitAudit: 0,
-  auditPass: 0,
-  auditReject: 0
-});
-
-const queryFormRef = ref<ElFormInstance>();
-const baseFormRef = ref<ElFormInstance>();
-
-const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
-});
-
-const initFormData: BaseForm = {
-  id: undefined,
-  productNo: undefined,
-  itemName: undefined,
-  brandId: undefined,
-  topCategoryId: undefined,
-  mediumCategoryId: undefined,
-  bottomCategoryId: undefined,
-  unitId: undefined,
-  productImage: undefined,
-  isSelf: undefined,
-  productReviewStatus: undefined,
-  homeRecommended: undefined,
-  categoryRecommendation: undefined,
-  cartRecommendation: undefined,
-  recommendedProductOrder: undefined,
-  isPopular: undefined,
-  isNew: undefined,
-  productStatus: undefined,
-  remark: undefined
-};
-const data = reactive<PageData<BaseForm, BaseQuery>>({
-  form: { ...initFormData },
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    productNo: undefined,
-    itemName: undefined,
-    brandName: undefined,
-    productTag: undefined,
-    purchaseNature: undefined,
-    supplierType: undefined,
-    supplierNature: undefined,
-    projectOrg: undefined,
-    topCategoryId: undefined,
-    mediumCategoryId: undefined,
-    bottomCategoryId: undefined,
-    isSelf: undefined,
-    productReviewStatus: undefined,
-    productStatus: undefined,
-    lastSeenId: undefined, // 游标分页的lastSeenId
-    way: undefined,
-    params: {}
-  },
-  rules: {
-    productNo: [{ required: true, message: '产品编号不能为空', trigger: 'blur' }],
-    itemName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
-    brandId: [{ required: true, message: '品牌id不能为空', trigger: 'blur' }],
-    topCategoryId: [{ required: true, message: '顶级分类id不能为空', trigger: 'blur' }],
-    mediumCategoryId: [{ required: true, message: '中级分类id不能为空', trigger: 'blur' }],
-    bottomCategoryId: [{ required: true, message: '底层分类id不能为空', trigger: 'blur' }],
-    unitId: [{ required: true, message: '单位id不能为空', trigger: 'blur' }],
-    productImage: [{ required: true, message: '产品图片URL不能为空', trigger: 'blur' }],
-    productReviewStatus: [{ required: true, message: '产品审核状态 0=待采购审核,1=审核通过,2=驳回,3=待营销审核不能为空', trigger: 'change' }],
-    homeRecommended: [{ required: true, message: '首页推荐:1=推荐,0=不推荐不能为空', trigger: 'blur' }],
-    categoryRecommendation: [{ required: true, message: '分类推荐:1=推荐,0=不推荐不能为空', trigger: 'blur' }],
-    cartRecommendation: [{ required: true, message: '购物车推荐:1=推荐,0=不推荐不能为空', trigger: 'blur' }],
-    recommendedProductOrder: [{ required: true, message: '推荐产品顺序不能为空', trigger: 'blur' }],
-    isPopular: [{ required: true, message: '是否热门:1=是,0=否不能为空', trigger: 'blur' }],
-    isNew: [{ required: true, message: '是否新品:1=是,0=否不能为空', trigger: 'blur' }],
-    remark: [{ required: true, message: '备注不能为空', trigger: 'blur' }]
-  }
-});
-
-const { queryParams, form, rules } = toRefs(data);
-
-
-/** 查询产品基础信息列表 */
-const getList = async () => {
-  loading.value = true;
-  try {
-    const params = { ...queryParams.value };
-    const currentPageNum = queryParams.value.pageNum;
-
-    // 第一页不需要游标参数
-    if (currentPageNum === 1) {
-      delete params.lastSeenId;
-      delete params.way;
-    } else {
-      // way参数:0=上一页,1=下一页
-      if (queryParams.value.way === 0) {
-        // 上一页:使用目标页(即当前显示页)的firstId
-        const nextPageHistory = pageHistory.value[currentPageNum];
-        if (nextPageHistory) {
-          params.firstSeenId = nextPageHistory.firstId;
-          params.way = 0;
-        }
-      } else {
-        // 下一页:使用前一页的lastId作为lastSeenId
-        const prevPageHistory = pageHistory.value[currentPageNum - 1];
-        if (prevPageHistory) {
-          params.lastSeenId = prevPageHistory.lastId;
-          params.way = 1;
-        }
-      }
-    }
-
-    const res = await listBase(params);
-    baseList.value = res.rows || [];
-
-    // 判断是否还有更多数据
-    hasMore.value = baseList.value.length === queryParams.value.pageSize;
-
-    // 记录当前页的第一个id和最后一个id
-    if (baseList.value.length > 0) {
-      const firstItem = baseList.value[0];
-      const lastItem = baseList.value[baseList.value.length - 1];
-      //如果长度小于currentPageNum则创建
-
-      if (pageHistory.value.length <= currentPageNum) {
-        pageHistory.value[currentPageNum] = {
-          firstId: firstItem.id,
-          lastId: lastItem.id
-        };
-      }
-    }
-
-    total.value = res.total || 0;
-  } catch (error) {
-    console.error('获取列表失败:', error);
-  } finally {
-    loading.value = false;
-  }
-};
-
-/** 取消按钮 */
-const cancel = () => {
-  reset();
-  dialog.visible = false;
-};
-
-/** 初始化路由参数 */
-const initRouteParams = () => {
-  // 从路由参数中获取筛选条件
-  if (route.query.productReviewStatus) {
-    queryParams.value.productReviewStatus = Number(route.query.productReviewStatus);
-  }
-  if (route.query.brandName) {
-    queryParams.value.brandName = route.query.brandName as string;
-  }
-  if (route.query.bottomCategoryId) {
-    queryParams.value.bottomCategoryId = route.query.bottomCategoryId as string;
-  }
-  if (route.query.isSelf) {
-    queryParams.value.isSelf = Number(route.query.isSelf);
-  }
-  if (route.query.productCategory) {
-    queryParams.value.productCategory = Number(route.query.productCategory);
-  }
-};
-
-/** 表单重置 */
-const reset = () => {
-  form.value = { ...initFormData };
-  baseFormRef.value?.resetFields();
-};
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  // 同步查询参数到游标分页参数
-  queryParams.value = {
-    ...queryParams.value,
-    pageNum: 1,
-    productNo: queryParams.value.productNo,
-    itemName: queryParams.value.itemName,
-    brandName: queryParams.value.brandName,
-    bottomCategoryId: queryParams.value.bottomCategoryId,
-    isSelf: queryParams.value.isSelf,
-    productReviewStatus: queryParams.value.productReviewStatus,
-    productStatus: queryParams.value.productStatus,
-    lastSeenId: undefined
-  };
-  pageHistory.value = []; // 重置页面历史
-  getList();
-};
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value?.resetFields();
-  queryParams.value.lastSeenId = undefined;
-  pageHistory.value = []; // 重置页面历史
-  handleQuery();
-};
-
-/** 多选框选中数据 */
-const handleSelectionChange = (selection: BaseVO[]) => {
-  ids.value = selection.map((item) => item.id);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-};
-
-/** 新增按钮操作 */
-const handleAdd = () => {
-  router.push('/product/base/add');
-};
-
-/** 修改按钮操作 */
-const handleUpdate = async (row?: BaseVO) => {
-  const _id = row?.id || ids.value[0];
-  router.push(`/product/base/edit/${_id}`);
-};
-
-/** 删除按钮操作 */
-const handleDelete = async (row?: BaseVO) => {
-  const _ids = row?.id || ids.value;
-  await proxy?.$modal.confirm('是否确认删除产品基础信息编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
-  await delBase(_ids);
-  proxy?.$modal.msgSuccess('删除成功');
-  await getList();
-};
-
-/** 导出按钮操作 */
-const handleExport = () => {
-  proxy?.download(
-    'product/base/export',
-    {
-      ...queryParams.value
-    },
-    `base_${new Date().getTime()}.xlsx`
-  );
-};
-
-/** 查看商品详情 */
-const handleView = (row: BaseVO) => {
-  console.log('查看商品', row);
-  // TODO: 实现查看详情逻辑
-};
-
-/** 上下架操作 */
-const handleShelf = async (row: BaseVO) => {
-  // productStatus字段定义为string类型:1=已上架,0=下架,2=上架中
-  const isOnShelf = row.productStatus === '1';
-  const action = isOnShelf ? '下架' : '上架';
-  await proxy?.$modal.confirm(`确认${action}该商品吗?`);
-
-  try {
-    // 上架:状态改为2(上架中),下架:状态改为0(下架)
-    const productStatus = isOnShelf ? '0' : '2';
-    await shelfReview({
-      id: row.id,
-      productStatus: productStatus,
-      shelfComments: `${action}操作`
-    });
-    proxy?.$modal.msgSuccess(`${action}成功`);
-    await getList();
-  } catch (error) {
-    console.error(`${action}失败:`, error);
-    proxy?.$modal.msgError(`${action}失败`);
-  }
-};
-
-/** 价格设置 */
-const handlePrice = (row: BaseVO) => {
-  console.log('设置价格', row);
-  // TODO: 打开价格设置对话框
-};
-
-/** 供货存管理 */
-const handleSupply = (row: BaseVO) => {
-  console.log('供货存管理', row);
-  // TODO: 打开供货存管理对话框
-};
-
-/** 停售操作 */
-const handleDiscontinue = async (row: BaseVO) => {
-  await proxy?.$modal.confirm('确认停售该商品吗?停售后商品将无法正常售卖。');
-
-  try {
-    // 调用停售API,将商品类型改为3(停售商品)
-    await changeProductType({
-      id: row.id,
-      productCategory: 3
-    });
-    proxy?.$modal.msgSuccess('停售成功');
-    await getList();
-  } catch (error) {
-    console.error('停售失败:', error);
-    proxy?.$modal.msgError('停售失败');
-  }
-};
-
-/** 跳转到商品审核页面 */
-const handleGoReview = () => {
-  router.push({
-    path: '/product/base/review',
-    query: {
-      productReviewStatus: 1 // 默认显示待审核的商品
-    }
-  });
-};
-
-/** 查询分类树 */
-const getCategoryTree = async () => {
-  const res = await categoryTree();
-  categoryOptions.value = res.data || [];
-};
-
-/** 获取统计信息 */
-const getStatistics = async () => {
-  try {
-    const res = await getProductStatusCount();
-    if (res.data) {
-      statistics.value = res.data;
-    }
-  } catch (error) {
-    console.error('获取统计信息失败:', error);
-  }
-};
-
-onMounted(() => {
-  getList();
-  getCategoryTree();
-  getStatistics();
-});
-</script>

+ 0 - 559
src/views/product/base/review.vue

@@ -1,559 +0,0 @@
-<template>
-  <div class="app-container">
-    <!-- 搜索区域 -->
-    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-      <div v-show="showSearch" class="mb-[10px]">
-        <el-card shadow="hover">
-          <el-form ref="queryFormRef" :model="queryParams" label-width="100px">
-            <el-row :gutter="20">
-              <el-col :span="6">
-                <el-form-item label="商品编号" prop="productNo">
-                  <el-input v-model="queryParams.productNo" placeholder="请输入商品编号" clearable @keyup.enter="handleQuery" />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="商品名称" prop="itemName">
-                  <el-input v-model="queryParams.itemName" placeholder="请输入商品名称" clearable @keyup.enter="handleQuery" />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="商品类别" prop="bottomCategoryId">
-                  <el-tree-select
-                    v-model="queryParams.bottomCategoryId"
-                    :data="categoryOptions"
-                    :props="{ value: 'id', label: 'label', children: 'children' } as any"
-                    value-key="id"
-                    placeholder="请选择商品类别"
-                    clearable
-                    check-strictly
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="商品品牌" prop="brandName">
-                  <el-select-v2
-                    v-model="queryParams.brandName"
-                    :options="brandOptionsFormatted"
-                    placeholder="请选择商品品牌"
-                    clearable
-                    filterable
-                    :loading="brandLoading"
-                    @visible-change="handleBrandVisibleChange"
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="审核状态" prop="productReviewStatus">
-                  <el-select
-                    v-model="queryParams.productReviewStatus"
-                    placeholder="请选择审核状态"
-                    clearable
-                  >
-                    <el-option label="待采购审核" :value="0" />
-                    <el-option label="审核通过" :value="1" />
-                    <el-option label="驳回" :value="2" />
-                    <el-option label="待营销审核" :value="3" />
-                  </el-select>
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item>
-                  <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-                  <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-                </el-form-item>
-              </el-col>
-            </el-row>
-          </el-form>
-        </el-card>
-      </div>
-    </transition>
-
-    <!-- 审核商品信息列表 -->
-    <el-card shadow="never" class="table-card">
-      <template #header>
-        <div class="flex items-center justify-between">
-          <span class="font-semibold">审核商品信息列表</span>
-          <div class="flex gap-2">
-            <el-button type="primary" icon="Download" @click="handleExport">导出商品</el-button>
-            <el-button type="success" icon="Upload">导入商品</el-button>
-            <el-button circle icon="Refresh" @click="getList"></el-button>
-          </div>
-        </div>
-      </template>
-
-      <el-table v-loading="loading" border :data="baseList" :height="tableHeight" @selection-change="handleSelectionChange">
-        <el-table-column type="selection" width="55" align="center" />
-        <el-table-column label="商品图片" align="center" prop="productImage" width="100" >
-          <template #default="scope">
-            <image-preview :src="scope.row.productImage" :width="60" :height="60"/>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品编号" align="center" prop="productNo" width="120" >
-          <template #default="scope">
-            <el-link type="primary" @click="handleView(scope.row)">{{ scope.row.productNo }}</el-link>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品信息" align="center" min-width="250" show-overflow-tooltip>
-          <template #default="scope">
-            <div class="text-left">
-              <div>{{ scope.row.itemName }}</div>
-              <div class="text-gray-500" style="font-size: 12px;">品牌: {{ scope.row.brandName || '-' }}</div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="基本情况" align="center" width="180">
-          <template #default="scope">
-            <div class="text-left" style="font-size: 12px;">
-              <div>
-                <span class="text-gray-500">商品分类:</span>
-                <span>{{ scope.row.categoryName || '-' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">单位:</span>
-                <span>{{ scope.row.unitName || '-' }}</span>
-              </div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="SKU价格" align="center" width="180">
-          <template #default="scope">
-            <div class="text-left" style="font-size: 12px;">
-              <div>
-                <span class="text-gray-500">市场价:</span>
-                <span class="text-red-500">¥{{ scope.row.marketPrice || '0.00' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">会员价:</span>
-                <span class="text-red-500">¥{{ scope.row.memberPrice || '0.00' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">最低价:</span>
-                <span class="text-red-500">¥{{ scope.row.minSellingPrice || '0.00' }}</span>
-              </div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="成本预算" align="center" width="150">
-          <template #default="scope">
-            <div class="text-left" style="font-size: 12px;">
-              <div>
-                <span class="text-gray-500">采购价:</span>
-                <span>¥{{ scope.row.purchasingPrice || '0.00' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">暂估毛利率:</span>
-                <span>{{ scope.row.tempGrossMargin || '0.0000' }}%</span>
-              </div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品来源" align="center" width="100">
-          <template #default="scope">
-            <span>{{ scope.row.dataSource || '-' }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品状态" align="center" width="100">
-          <template #default="scope">
-            <el-tag v-if="scope.row.productReviewStatus === 0" type="info">待采购审核</el-tag>
-            <el-tag v-else-if="scope.row.productReviewStatus === 1" type="warning">审核通过</el-tag>
-            <el-tag v-else-if="scope.row.productReviewStatus === 2" type="success">驳回</el-tag>
-            <el-tag v-else-if="scope.row.productReviewStatus === 3" type="danger">待营销审核</el-tag>
-            <span v-else>-</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="审核意见" align="center" width="180" show-overflow-tooltip>
-          <template #default="scope">
-            <span>{{ scope.row.reviewComments || '-' }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" align="center" width="200" fixed="right" class-name="border-left">
-          <template #default="scope">
-            <div class="flex flex-col gap-1">
-              <!-- 根据审核状态显示不同按钮 -->
-              <template v-if="scope.row.productReviewStatus === 0">
-                <!-- 待采购审核 -->
-                <div class="flex gap-1 justify-center">
-                  <el-link type="primary" :underline="false" @click="handleEdit(scope.row)">编辑</el-link>
-                  <el-link type="success" :underline="false" @click="handlePurchaseReview(scope.row)">采购审核</el-link>
-                </div>
-              </template>
-              <template v-else-if="scope.row.productReviewStatus === 1">
-                <!-- 审核通过:不显示任何按钮 -->
-              </template>
-              <template v-else-if="scope.row.productReviewStatus === 2">
-                <!-- 驳回 -->
-                <div class="flex gap-1 justify-center">
-                  <el-link type="primary" :underline="false" @click="handleEdit(scope.row)">编辑</el-link>
-                  <el-link type="success" :underline="false" @click="handleReSubmit(scope.row)">重新提交</el-link>
-                </div>
-              </template>
-              <template v-else-if="scope.row.productReviewStatus === 3">
-                <!-- 待营销审核 -->
-                <div class="flex gap-1 justify-center">
-                  <el-link type="primary" :underline="false" @click="handleEdit(scope.row)">编辑</el-link>
-                  <el-link type="warning" :underline="false" @click="handleMarketingReview(scope.row)">营销审核</el-link>
-                </div>
-              </template>
-            </div>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <!-- 游标分页控制 -->
-      <pagination
-        v-show="baseList.length > 0"
-        v-model:page="queryParams.pageNum"
-        v-model:limit="queryParams.pageSize"
-        v-model:way="queryParams.way"
-        :cursor-mode="true"
-        :has-more="hasMore"
-        @pagination="getList"
-      />
-    </el-card>
-
-    <!-- 审核对话框 -->
-    <el-dialog v-model="reviewDialog.visible" :title="reviewDialog.title" width="600px" append-to-body>
-      <el-form ref="reviewFormRef" :model="reviewForm" :rules="reviewRules" label-width="100px">
-        <el-form-item label="商品编号">
-          <el-input v-model="reviewForm.productNo" disabled />
-        </el-form-item>
-        <el-form-item label="商品名称">
-          <el-input v-model="reviewForm.itemName" disabled />
-        </el-form-item>
-        <el-form-item label="审核结果" prop="reviewStatus">
-          <el-radio-group v-model="reviewForm.reviewStatus">
-            <el-radio :label="2">审核通过</el-radio>
-            <el-radio :label="3">审核驳回</el-radio>
-          </el-radio-group>
-        </el-form-item>
-        <el-form-item label="审核意见" prop="reviewComments">
-          <el-input v-model="reviewForm.reviewComments" type="textarea" :rows="4" placeholder="请输入审核意见" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="reviewDialog.visible = false">取消</el-button>
-          <el-button type="primary" @click="submitReview">确定</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup name="BaseReview" lang="ts">
-import { listBase, getBase, reviewBase, brandList, categoryTree } from '@/api/product/base';
-import { BaseVO, BaseQuery, BaseForm } from '@/api/product/base/types';
-import { BrandVO } from '@/api/product/brand/types';
-import { categoryTreeVO } from '@/api/product/category/types';
-import { useRouter, useRoute } from 'vue-router';
-
-const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const router = useRouter();
-const route = useRoute();
-
-const baseList = ref<BaseVO[]>([]);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref<Array<string | number>>([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-const brandOptions = ref<BrandVO[]>([]);
-const brandLoading = ref(false);
-const brandOptionsFormatted = computed(() => {
-  return brandOptions.value.slice(0, 500).map((item) => ({
-    label: item.brandName,
-    value: item.brandName // review.vue使用brandName作为value
-  }));
-});
-const categoryOptions = ref<categoryTreeVO[]>([]);
-const hasMore = ref(true); // 是否还有更多数据
-const pageHistory = ref([]);
-
-// 动态计算表格高度
-const tableHeight = computed(() => {
-  // 基础高度 = 视口高度 - 顶部导航(84) - 容器padding(16) - 搜索区域 - 卡片header(60) - 分页器(60)
-  const baseHeight = window.innerHeight - 84 - 16;
-  const searchHeight = showSearch.value ? 150 : 10; // 搜索区域高度
-  const cardHeaderHeight = 60; // 卡片header高度
-  const paginationHeight = 60; // 分页器高度
-  return baseHeight - searchHeight - cardHeaderHeight - paginationHeight;
-});
-
-const queryFormRef = ref<ElFormInstance>();
-const reviewFormRef = ref<ElFormInstance>();
-
-// 审核对话框
-const reviewDialog = reactive({
-  visible: false,
-  title: '商品审核'
-});
-
-// 审核表单
-const reviewForm = ref<any>({
-  id: undefined,
-  productNo: '',
-  itemName: '',
-  reviewStatus: 2,
-  reviewComments: ''
-});
-
-// 审核表单验证规则
-const reviewRules = ref({
-  reviewStatus: [{ required: true, message: '请选择审核结果', trigger: 'change' }],
-  reviewComments: [{ required: true, message: '请输入审核意见', trigger: 'blur' }]
-});
-
-const queryParams = ref<BaseQuery>({
-  pageNum: 1,
-  pageSize: 10,
-  way: undefined,
-  productNo: undefined,
-  itemName: undefined,
-  brandName: undefined,
-  purchaseNature: undefined,
-  bottomCategoryId: undefined,
-  isSelf: undefined,
-  productReviewStatus: undefined,
-  productStatus: undefined,
-  lastSeenId: undefined // 游标分页的lastSeenId
-});
-
-
-/** 查询商品列表 */
-const getList = async () => {
-  loading.value = true;
-  try {
-    const params = { ...queryParams.value };
-    const currentPageNum = queryParams.value.pageNum;
-
-    // 第一页不需要游标参数
-    if (currentPageNum === 1) {
-      delete params.lastSeenId;
-      delete params.way;
-    } else {
-      // way参数:0=上一页,1=下一页
-      if (queryParams.value.way === 0) {
-        // 上一页:使用目标页(即当前显示页)的firstId
-        const nextPageHistory = pageHistory.value[currentPageNum];
-        if (nextPageHistory) {
-          params.firstSeenId = nextPageHistory.firstId;
-          params.way = 0;
-        }
-      } else {
-        // 下一页:使用前一页的lastId作为lastSeenId
-        const prevPageHistory = pageHistory.value[currentPageNum - 1];
-        if (prevPageHistory) {
-          params.lastSeenId = prevPageHistory.lastId;
-          params.way = 1;
-        }
-      }
-    }
-
-    const res = await listBase(params);
-    baseList.value = res.rows || [];
-
-    // 判断是否还有更多数据
-    hasMore.value = baseList.value.length === queryParams.value.pageSize;
-
-    // 记录当前页的第一个id和最后一个id
-    if (baseList.value.length > 0) {
-      const firstItem = baseList.value[0];
-      const lastItem = baseList.value[baseList.value.length - 1];
-      //如果长度小于currentPageNum则创建
-
-      if (pageHistory.value.length <= currentPageNum) {
-        pageHistory.value[currentPageNum] = {
-          firstId: firstItem.id,
-          lastId: lastItem.id
-        };
-      }
-    }
-    total.value = res.total || 0;
-  } catch (error) {
-    console.error('获取列表失败:', error);
-  } finally {
-    loading.value = false;
-  }
-};
-
-/** 初始化路由参数 */
-const initRouteParams = () => {
-  // 从路由参数中获取筛选条件
-  if (route.query.productReviewStatus) {
-    queryParams.value.productReviewStatus = Number(route.query.productReviewStatus);
-  }
-  if (route.query.brandName) {
-    queryParams.value.brandName = route.query.brandName as string;
-  }
-  if (route.query.bottomCategoryId) {
-    queryParams.value.bottomCategoryId = route.query.bottomCategoryId as string;
-  }
-};
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  queryParams.value.lastSeenId = undefined;
-  pageHistory.value = [0]; // 重置页面历史
-  getList();
-};
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value?.resetFields();
-  queryParams.value.lastSeenId = undefined;
-  pageHistory.value = [0]; // 重置页面历史
-  handleQuery();
-};
-
-/** 多选框选中数据 */
-const handleSelectionChange = (selection: BaseVO[]) => {
-  ids.value = selection.map((item) => item.id);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-};
-
-/** 导出按钮操作 */
-const handleExport = () => {
-  proxy?.download(
-    'product/base/export',
-    {
-      ...queryParams.value
-    },
-    `base_review_${new Date().getTime()}.xlsx`
-  );
-};
-
-/** 查看商品详情 */
-const handleView = (row: BaseVO) => {
-  router.push(`/product/base/detail/${row.id}`);
-};
-
-/** 编辑商品 */
-const handleEdit = (row: BaseVO) => {
-  router.push(`/product/base/edit/${row.id}`);
-};
-
-/** 采购审核 */
-const handlePurchaseReview = (row: BaseVO) => {
-  reviewDialog.visible = true;
-  reviewDialog.title = '采购审核';
-  reviewForm.value = {
-    id: row.id,
-    productNo: row.productNo,
-    itemName: row.itemName,
-    reviewStatus: 3,
-    reviewComments: ''
-  };
-}
-
-/** 营销审核 */
-const handleMarketingReview = (row: BaseVO) => {
-  reviewDialog.visible = true;
-  reviewDialog.title = '营销审核';
-  reviewForm.value = {
-    id: row.id,
-    productNo: row.productNo,
-    itemName: row.itemName,
-    reviewStatus: 1,
-    reviewComments: ''
-  };
-};
-
-/** 重新提交 */
-const handleReSubmit = async (row: BaseVO) => {
-  await proxy?.$modal.confirm('确认重新提交该商品进行审核吗?');
-  const data: BaseForm = {
-    id: row.id,
-    productReviewStatus: 0 // 设置为待审核状态
-  };
-  await reviewBase(data);
-  proxy?.$modal.msgSuccess('重新提交成功');
-  await getList();
-};
-
-/** 提交审核 */
-const submitReview = async () => {
-  await reviewFormRef.value?.validate();
-  const data: BaseForm = {
-    id: reviewForm.value.id,
-    productReviewStatus: Number(reviewForm.value.reviewStatus),
-    reviewComments: reviewForm.value.reviewComments
-  };
-  await reviewBase(data);
-  proxy?.$modal.msgSuccess(reviewForm.value.reviewStatus === 2 ? '审核通过' : '审核驳回');
-  reviewDialog.visible = false;
-  await getList();
-};
-
-/** 查询品牌列表(实时请求,每次只加载500条) */
-const getBrandList = async () => {
-  try {
-    brandLoading.value = true;
-    const res = await brandList({ pageNum: 1, pageSize: 500 });
-    brandOptions.value = res.data || [];
-  } catch (error) {
-    console.error('获取品牌列表失败:', error);
-  } finally {
-    brandLoading.value = false;
-  }
-};
-
-/** 处理品牌下拉框显示/隐藏 */
-const handleBrandVisibleChange = (visible: boolean) => {
-  if (visible && brandOptions.value.length === 0) {
-    getBrandList();
-  }
-};
-
-/** 查询分类树 */
-const getCategoryTree = async () => {
-  const res = await categoryTree();
-  categoryOptions.value = res.data || [];
-};
-
-onMounted(() => {
-  getCategoryTree();
-  initRouteParams();
-  getList();
-});
-</script>
-
-<style scoped lang="scss">
-.app-container {
-  padding: 8px;
-  height: calc(100vh - 84px);
-  display: flex;
-  flex-direction: column;
-  overflow: hidden;
-}
-
-.table-card {
-  flex: 1;
-  display: flex;
-  flex-direction: column;
-  overflow: hidden;
-
-  :deep(.el-card__body) {
-    flex: 1;
-    display: flex;
-    flex-direction: column;
-    overflow: hidden;
-  }
-
-  :deep(.el-table) {
-    flex: 1;
-  }
-
-  // 确保固定列左侧有边框
-  :deep(.el-table__fixed-right) {
-    box-shadow: -1px 0 0 var(--el-table-border-color) !important;
-  }
-
-  // 固定列的单元格左边框
-  :deep(.el-table__fixed-right .el-table__cell) {
-    border-left: 1px solid var(--el-table-border-color) !important;
-  }
-}
-</style>

+ 0 - 529
src/views/product/base/shelfReview.vue

@@ -1,529 +0,0 @@
-<template>
-  <div class="app-container">
-    <!-- 搜索区域 -->
-    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-      <div v-show="showSearch" class="mb-[10px]">
-        <el-card shadow="hover">
-          <el-form ref="queryFormRef" :model="queryParams" label-width="100px">
-            <el-row :gutter="20">
-              <el-col :span="6">
-                <el-form-item label="商品编号" prop="productNo">
-                  <el-input v-model="queryParams.productNo" placeholder="请输入商品编号" clearable @keyup.enter="handleQuery" />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="商品名称" prop="itemName">
-                  <el-input v-model="queryParams.itemName" placeholder="请输入商品名称" clearable @keyup.enter="handleQuery" />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="商品类别" prop="bottomCategoryId">
-                  <el-tree-select
-                    v-model="queryParams.bottomCategoryId"
-                    :data="categoryOptions"
-                    :props="{ value: 'id', label: 'label', children: 'children' } as any"
-                    value-key="id"
-                    placeholder="请选择商品类别"
-                    clearable
-                    check-strictly
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="6">
-                <el-form-item label="商品品牌" prop="brandName">
-                  <el-select-v2
-                    v-model="queryParams.brandName"
-                    :options="brandOptionsFormatted"
-                    placeholder="请选择商品品牌"
-                    clearable
-                    filterable
-                    :loading="brandLoading"
-                    @visible-change="handleBrandVisibleChange"
-                  />
-                </el-form-item>
-              </el-col>
-
-              <el-col :span="6">
-                <el-form-item>
-                  <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-                  <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-                </el-form-item>
-              </el-col>
-            </el-row>
-          </el-form>
-        </el-card>
-      </div>
-    </transition>
-
-    <!-- 上下架审核商品信息列表 -->
-    <el-card shadow="never" class="table-card">
-      <template #header>
-        <div class="flex items-center justify-between">
-          <span class="font-semibold">上下架审核商品信息列表</span>
-          <div class="flex gap-2">
-            <el-button type="primary" icon="Download" @click="handleExport">导出商品</el-button>
-            <el-button type="success" icon="Upload">导入商品</el-button>
-            <el-button circle icon="Refresh" @click="getList"></el-button>
-          </div>
-        </div>
-      </template>
-
-      <el-table v-loading="loading" border :data="baseList" :height="tableHeight" @selection-change="handleSelectionChange">
-        <el-table-column type="selection" width="55" align="center" />
-        <el-table-column label="商品图片" align="center" prop="productImage" width="100" >
-          <template #default="scope">
-            <image-preview :src="scope.row.productImage" :width="60" :height="60"/>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品编号" align="center" prop="productNo" width="120" >
-          <template #default="scope">
-            <el-link type="primary" @click="handleView(scope.row)">{{ scope.row.productNo }}</el-link>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品信息" align="center" min-width="250" show-overflow-tooltip>
-          <template #default="scope">
-            <div class="text-left">
-              <div>{{ scope.row.itemName }}</div>
-              <div class="text-gray-500" style="font-size: 12px;">品牌: {{ scope.row.brandName || '-' }}</div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="基本情况" align="center" width="180">
-          <template #default="scope">
-            <div class="text-left" style="font-size: 12px;">
-              <div>
-                <span class="text-gray-500">商品分类:</span>
-                <span>{{ scope.row.categoryName || '-' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">单位:</span>
-                <span>{{ scope.row.unitName || '-' }}</span>
-              </div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="SKU价格" align="center" width="180">
-          <template #default="scope">
-            <div class="text-left" style="font-size: 12px;">
-              <div>
-                <span class="text-gray-500">市场价:</span>
-                <span class="text-red-500">¥{{ scope.row.marketPrice || '0.00' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">会员价:</span>
-                <span class="text-red-500">¥{{ scope.row.memberPrice || '0.00' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">最低价:</span>
-                <span class="text-red-500">¥{{ scope.row.minSellingPrice || '0.00' }}</span>
-              </div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="成本预算" align="center" width="150">
-          <template #default="scope">
-            <div class="text-left" style="font-size: 12px;">
-              <div>
-                <span class="text-gray-500">采购价:</span>
-                <span>¥{{ scope.row.purchasingPrice || '0.00' }}</span>
-              </div>
-              <div>
-                <span class="text-gray-500">暂估毛利率:</span>
-                <span>{{ scope.row.tempGrossMargin || '0.0000' }}%</span>
-              </div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品来源" align="center" width="100">
-          <template #default="scope">
-            <span>{{ scope.row.dataSource || '-' }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品状态" align="center" width="100">
-          <template #default="scope">
-            <el-tag v-if="scope.row.productStatus === '2' || scope.row.productStatus === 2" type="warning">上架中</el-tag>
-            <el-tag v-else-if="scope.row.productStatus === '1' || scope.row.productStatus === 1" type="success">已上架</el-tag>
-            <el-tag v-else-if="scope.row.productStatus === '0' || scope.row.productStatus === 0" type="info">已下架</el-tag>
-            <span v-else>-</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="审核意见" align="center" width="180" show-overflow-tooltip>
-          <template #default="scope">
-            <span>{{ scope.row.shelfComments || '-' }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" align="center" width="200" fixed="right" class-name="border-left">
-          <template #default="scope">
-            <div class="flex flex-col gap-1">
-              <!-- 根据商品状态显示不同按钮 -->
-              <template v-if="scope.row.productStatus === '2' || scope.row.productStatus === 2">
-                <!-- 上架中:显示上架审核按钮 -->
-                <div class="flex gap-1 justify-center">
-                  <el-link type="primary" :underline="false" @click="handleEdit(scope.row)">编辑</el-link>
-                  <el-link type="success" :underline="false" @click="handleShelfReview(scope.row)">上架审核</el-link>
-                </div>
-              </template>
-              <template v-else-if="scope.row.productStatus === '1' || scope.row.productStatus === 1">
-                <!-- 已上架:显示下架按钮 -->
-                <div class="flex gap-1 justify-center">
-                  <el-link type="primary" :underline="false" @click="handleEdit(scope.row)">编辑</el-link>
-                  <el-link type="danger" :underline="false" @click="handleOffShelf(scope.row)">下架</el-link>
-                </div>
-              </template>
-            </div>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <!-- 游标分页控制 -->
-      <pagination
-        v-show="baseList.length > 0"
-        v-model:page="queryParams.pageNum"
-        v-model:limit="queryParams.pageSize"
-        v-model:way="queryParams.way"
-        :cursor-mode="true"
-        :has-more="hasMore"
-        @pagination="getList"
-      />
-    </el-card>
-
-    <!-- 上架审核对话框 -->
-    <el-dialog v-model="reviewDialog.visible" :title="reviewDialog.title" width="600px" append-to-body>
-      <el-form ref="reviewFormRef" :model="reviewForm" :rules="reviewRules" label-width="100px">
-        <el-form-item label="商品编号">
-          <el-input v-model="reviewForm.productNo" disabled />
-        </el-form-item>
-        <el-form-item label="商品名称">
-          <el-input v-model="reviewForm.itemName" disabled />
-        </el-form-item>
-        <el-form-item label="审核结果" prop="productStatus">
-          <el-radio-group v-model="reviewForm.productStatus">
-            <el-radio :label="1">通过上架</el-radio>
-            <el-radio :label="0">驳回下架</el-radio>
-          </el-radio-group>
-        </el-form-item>
-        <el-form-item label="审核意见" prop="shelfComments">
-          <el-input v-model="reviewForm.shelfComments" type="textarea" :rows="4" placeholder="请输入审核意见" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="reviewDialog.visible = false">取消</el-button>
-          <el-button type="primary" @click="submitReview">确定</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup name="ShelfReview" lang="ts">
-import { listBase, getBase, shelfReview, brandList, categoryTree } from '@/api/product/base';
-import { BaseVO, BaseQuery, BaseForm } from '@/api/product/base/types';
-import { BrandVO } from '@/api/product/brand/types';
-import { categoryTreeVO } from '@/api/product/category/types';
-import { useRouter, useRoute } from 'vue-router';
-
-const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const router = useRouter();
-const route = useRoute();
-
-const baseList = ref<BaseVO[]>([]);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref<Array<string | number>>([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-const brandOptions = ref<BrandVO[]>([]);
-const brandLoading = ref(false);
-const brandOptionsFormatted = computed(() => {
-  return brandOptions.value.slice(0, 500).map((item) => ({
-    label: item.brandName,
-    value: item.brandName // review.vue使用brandName作为value
-  }));
-});
-const categoryOptions = ref<categoryTreeVO[]>([]);
-const hasMore = ref(true); // 是否还有更多数据
-const pageHistory = ref([]);
-
-// 动态计算表格高度
-const tableHeight = computed(() => {
-  // 基础高度 = 视口高度 - 顶部导航(84) - 容器padding(16) - 搜索区域 - 卡片header(60) - 分页器(60)
-  const baseHeight = window.innerHeight - 84 - 16;
-  const searchHeight = showSearch.value ? 150 : 10; // 搜索区域高度
-  const cardHeaderHeight = 60; // 卡片header高度
-  const paginationHeight = 60; // 分页器高度
-  return baseHeight - searchHeight - cardHeaderHeight - paginationHeight;
-});
-
-const queryFormRef = ref<ElFormInstance>();
-const reviewFormRef = ref<ElFormInstance>();
-
-// 审核对话框
-const reviewDialog = reactive({
-  visible: false,
-  title: '上架审核'
-});
-
-// 审核表单
-const reviewForm = ref<any>({
-  id: undefined,
-  productNo: '',
-  itemName: '',
-  productStatus: 1,
-  shelfComments: ''
-});
-
-// 审核表单验证规则
-const reviewRules = ref({
-  productStatus: [{ required: true, message: '请选择审核结果', trigger: 'change' }],
-  shelfComments: [{ required: true, message: '请输入审核意见', trigger: 'blur' }]
-});
-
-const queryParams = ref<BaseQuery>({
-  pageNum: 1,
-  pageSize: 10,
-  way: undefined,
-  productNo: undefined,
-  itemName: undefined,
-  brandName: undefined,
-  purchaseNature: undefined,
-  bottomCategoryId: undefined,
-  isSelf: undefined,
-  productReviewStatus: 1, // 只查询审核通过的数据
-  productStatus: 2, // 用于筛选商品状态
-  lastSeenId: undefined // 游标分页的lastSeenId
-});
-
-
-/** 查询商品列表 */
-const getList = async () => {
-  loading.value = true;
-  try {
-    const params = { ...queryParams.value };
-    const currentPageNum = queryParams.value.pageNum;
-
-    // 强制只查询审核通过的数据
-    params.productReviewStatus = 1;
-
-    // 如果没有选择商品状态,默认查询上架中和已上架的数据
-    // 后端需要支持多状态查询,这里通过不传productStatus让后端返回所有状态,前端再过滤
-    // 或者后端支持传入多个状态值
-
-    // 第一页不需要游标参数
-    if (currentPageNum === 1) {
-      delete params.lastSeenId;
-      delete params.way;
-    } else {
-      // way参数:0=上一页,1=下一页
-      if (queryParams.value.way === 0) {
-        // 上一页:使用目标页(即当前显示页)的firstId
-        const nextPageHistory = pageHistory.value[currentPageNum];
-        if (nextPageHistory) {
-          params.firstSeenId = nextPageHistory.firstId;
-          params.way = 0;
-        }
-      } else {
-        // 下一页:使用前一页的lastId作为lastSeenId
-        const prevPageHistory = pageHistory.value[currentPageNum - 1];
-        if (prevPageHistory) {
-          params.lastSeenId = prevPageHistory.lastId;
-          params.way = 1;
-        }
-      }
-    }
-
-    const res = await listBase(params);
-    baseList.value = res.rows || [];
-
-    // 判断是否还有更多数据
-    hasMore.value = baseList.value.length === queryParams.value.pageSize;
-
-    // 记录当前页的第一个id和最后一个id
-    if (baseList.value.length > 0) {
-      const firstItem = baseList.value[0];
-      const lastItem = baseList.value[baseList.value.length - 1];
-      //如果长度小于currentPageNum则创建
-
-      if (pageHistory.value.length <= currentPageNum) {
-        pageHistory.value[currentPageNum] = {
-          firstId: firstItem.id,
-          lastId: lastItem.id
-        };
-      }
-    }
-    total.value = res.total || 0;
-  } catch (error) {
-    console.error('获取列表失败:', error);
-  } finally {
-    loading.value = false;
-  }
-};
-
-/** 初始化路由参数 */
-const initRouteParams = () => {
-  // 从路由参数中获取筛选条件
-  if (route.query.productStatus) {
-    queryParams.value.productStatus = Number(route.query.productStatus);
-  }
-  if (route.query.brandName) {
-    queryParams.value.brandName = route.query.brandName as string;
-  }
-  if (route.query.bottomCategoryId) {
-    queryParams.value.bottomCategoryId = route.query.bottomCategoryId as string;
-  }
-};
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  queryParams.value.lastSeenId = undefined;
-  pageHistory.value = [0]; // 重置页面历史
-  getList();
-};
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value?.resetFields();
-  queryParams.value.lastSeenId = undefined;
-  pageHistory.value = [0]; // 重置页面历史
-  handleQuery();
-};
-
-/** 多选框选中数据 */
-const handleSelectionChange = (selection: BaseVO[]) => {
-  ids.value = selection.map((item) => item.id);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-};
-
-/** 导出按钮操作 */
-const handleExport = () => {
-  proxy?.download(
-    'product/base/export',
-    {
-      ...queryParams.value
-    },
-    `base_shelf_review_${new Date().getTime()}.xlsx`
-  );
-};
-
-/** 查看商品详情 */
-const handleView = (row: BaseVO) => {
-  router.push(`/product/base/detail/${row.id}`);
-};
-
-/** 编辑商品 */
-const handleEdit = (row: BaseVO) => {
-  router.push(`/product/base/edit/${row.id}`);
-};
-
-/** 上架审核 */
-const handleShelfReview = (row: BaseVO) => {
-  reviewDialog.visible = true;
-  reviewDialog.title = '上架审核';
-  reviewForm.value = {
-    id: row.id,
-    productNo: row.productNo,
-    itemName: row.itemName,
-    productStatus: 1,
-    shelfComments: ''
-  };
-}
-
-/** 下架操作 */
-const handleOffShelf = async (row: BaseVO) => {
-  await proxy?.$modal.confirm('确认下架该商品吗?');
-  const data: BaseForm = {
-    id: row.id,
-    productStatus: '0' // 设置为下架状态
-  };
-  await shelfReview(data);
-  proxy?.$modal.msgSuccess('下架成功');
-  await getList();
-};
-
-/** 提交审核 */
-const submitReview = async () => {
-  await reviewFormRef.value?.validate();
-  const data: BaseForm = {
-    id: reviewForm.value.id,
-    productStatus: String(reviewForm.value.productStatus),
-    shelfComments: reviewForm.value.shelfComments
-  };
-  await shelfReview(data);
-  proxy?.$modal.msgSuccess(reviewForm.value.productStatus === 1 ? '上架成功' : '驳回成功');
-  reviewDialog.visible = false;
-  await getList();
-};
-
-/** 查询品牌列表(实时请求,每次只加载500条) */
-const getBrandList = async () => {
-  try {
-    brandLoading.value = true;
-    const res = await brandList({ pageNum: 1, pageSize: 500 });
-    brandOptions.value = res.data || [];
-  } catch (error) {
-    console.error('获取品牌列表失败:', error);
-  } finally {
-    brandLoading.value = false;
-  }
-};
-
-/** 处理品牌下拉框显示/隐藏 */
-const handleBrandVisibleChange = (visible: boolean) => {
-  if (visible && brandOptions.value.length === 0) {
-    getBrandList();
-  }
-};
-
-/** 查询分类树 */
-const getCategoryTree = async () => {
-  const res = await categoryTree();
-  categoryOptions.value = res.data || [];
-};
-
-onMounted(() => {
-  getCategoryTree();
-  initRouteParams();
-  getList();
-});
-</script>
-
-<style scoped lang="scss">
-.app-container {
-  padding: 8px;
-  height: calc(100vh - 84px);
-  display: flex;
-  flex-direction: column;
-  overflow: hidden;
-}
-
-.table-card {
-  flex: 1;
-  display: flex;
-  flex-direction: column;
-  overflow: hidden;
-
-  :deep(.el-card__body) {
-    flex: 1;
-    display: flex;
-    flex-direction: column;
-    overflow: hidden;
-  }
-
-  :deep(.el-table) {
-    flex: 1;
-  }
-
-  // 确保固定列左侧有边框
-  :deep(.el-table__fixed-right) {
-    box-shadow: -1px 0 0 var(--el-table-border-color) !important;
-  }
-
-  // 固定列的单元格左边框
-  :deep(.el-table__fixed-right .el-table__cell) {
-    border-left: 1px solid var(--el-table-border-color) !important;
-  }
-}
-</style>

+ 2 - 2
src/views/product/classification/index.vue

@@ -92,8 +92,8 @@
 </template>
 
 <script setup name="Classification" lang="ts">
-import { listClassification, getClassification, delClassification, addClassification, updateClassification } from '@/api/product/classification';
-import { ClassificationVO, ClassificationQuery, ClassificationForm } from '@/api/product/classification/types';
+import { listClassification, getClassification, delClassification, addClassification, updateClassification } from '@/api/classification/index';
+import { ClassificationVO, ClassificationQuery, ClassificationForm } from '@/api/classification/types';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 

+ 0 - 307
src/views/product/customization/index.vue

@@ -1,307 +0,0 @@
-<template>
-  <div class="p-2">
-    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-      <div v-show="showSearch" class="mb-[10px]">
-        <el-card shadow="hover">
-          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
-            <el-form-item label="定制编号" prop="customizationNo">
-              <el-input v-model="queryParams.customizationNo" placeholder="请输入定制编号" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="产品id" prop="productId">
-              <el-input v-model="queryParams.productId" placeholder="请输入产品id" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="定制方式  支持多选,分隔  (0=包装定制,1=商品定制,2=开模定制)" prop="customizedStyle">
-              <el-input v-model="queryParams.customizedStyle" placeholder="请输入定制方式  支持多选,分隔  (0=包装定制,1=商品定制,2=开模定制)" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="定制工艺  支持多选,分隔  (0=丝印,1=热转印,2=激光,烤花,压印)" prop="customizedCraft">
-              <el-input v-model="queryParams.customizedCraft" placeholder="请输入定制工艺  支持多选,分隔  (0=丝印,1=热转印,2=激光,烤花,压印)" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="打样周期" prop="proofingPeriod">
-              <el-input v-model="queryParams.proofingPeriod" placeholder="请输入打样周期" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="生产周期" prop="productionCycle">
-              <el-input v-model="queryParams.productionCycle" placeholder="请输入生产周期" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="最小起订量" prop="moq">
-              <el-input v-model="queryParams.moq" placeholder="请输入最小起订量" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="MOQ对应价格" prop="moqPrice">
-              <el-input v-model="queryParams.moqPrice" placeholder="请输入MOQ对应价格" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="平台标识" prop="platformCode">
-              <el-input v-model="queryParams.platformCode" placeholder="请输入平台标识" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item>
-              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-            </el-form-item>
-          </el-form>
-        </el-card>
-      </div>
-    </transition>
-
-    <el-card shadow="never">
-      <template #header>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="1.5">
-            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['product:customization:add']">新增</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['product:customization:edit']">修改</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['product:customization:remove']">删除</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['product:customization:export']">导出</el-button>
-          </el-col>
-          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-        </el-row>
-      </template>
-
-      <el-table v-loading="loading" border :data="customizationList" @selection-change="handleSelectionChange">
-        <el-table-column type="selection" width="55" align="center" />
-        <el-table-column label="主键ID" align="center" prop="id" v-if="true" />
-        <el-table-column label="定制编号" align="center" prop="customizationNo" />
-        <el-table-column label="产品id" align="center" prop="productId" />
-        <el-table-column label="定制方式  支持多选,分隔  (0=包装定制,1=商品定制,2=开模定制)" align="center" prop="customizedStyle" />
-        <el-table-column label="定制工艺  支持多选,分隔  (0=丝印,1=热转印,2=激光,烤花,压印)" align="center" prop="customizedCraft" />
-        <el-table-column label="打样周期" align="center" prop="proofingPeriod" />
-        <el-table-column label="生产周期" align="center" prop="productionCycle" />
-        <el-table-column label="最小起订量" align="center" prop="moq" />
-        <el-table-column label="MOQ对应价格" align="center" prop="moqPrice" />
-        <el-table-column label="备注" align="center" prop="remark" />
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-          <template #default="scope">
-            <el-tooltip content="修改" placement="top">
-              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['product:customization:edit']"></el-button>
-            </el-tooltip>
-            <el-tooltip content="删除" placement="top">
-              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['product:customization:remove']"></el-button>
-            </el-tooltip>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-    </el-card>
-    <!-- 添加或修改产品定制信息对话框 -->
-    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-      <el-form ref="customizationFormRef" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="定制编号" prop="customizationNo">
-          <el-input v-model="form.customizationNo" placeholder="请输入定制编号" />
-        </el-form-item>
-        <el-form-item label="产品id" prop="productId">
-          <el-input v-model="form.productId" placeholder="请输入产品id" />
-        </el-form-item>
-        <el-form-item label="定制方式  支持多选,分隔  (0=包装定制,1=商品定制,2=开模定制)" prop="customizedStyle">
-          <el-input v-model="form.customizedStyle" placeholder="请输入定制方式  支持多选,分隔  (0=包装定制,1=商品定制,2=开模定制)" />
-        </el-form-item>
-        <el-form-item label="定制工艺  支持多选,分隔  (0=丝印,1=热转印,2=激光,烤花,压印)" prop="customizedCraft">
-          <el-input v-model="form.customizedCraft" placeholder="请输入定制工艺  支持多选,分隔  (0=丝印,1=热转印,2=激光,烤花,压印)" />
-        </el-form-item>
-        <el-form-item label="打样周期" prop="proofingPeriod">
-          <el-input v-model="form.proofingPeriod" placeholder="请输入打样周期" />
-        </el-form-item>
-        <el-form-item label="生产周期" prop="productionCycle">
-          <el-input v-model="form.productionCycle" placeholder="请输入生产周期" />
-        </el-form-item>
-        <el-form-item label="最小起订量" prop="moq">
-          <el-input v-model="form.moq" placeholder="请输入最小起订量" />
-        </el-form-item>
-        <el-form-item label="MOQ对应价格" prop="moqPrice">
-          <el-input v-model="form.moqPrice" placeholder="请输入MOQ对应价格" />
-        </el-form-item>
-        <el-form-item label="备注" prop="remark">
-            <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
-          <el-button @click="cancel">取 消</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup name="Customization" lang="ts">
-import { listCustomization, getCustomization, delCustomization, addCustomization, updateCustomization } from '@/api/product/customization';
-import { CustomizationVO, CustomizationQuery, CustomizationForm } from '@/api/product/customization/types';
-
-const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-
-const customizationList = ref<CustomizationVO[]>([]);
-const buttonLoading = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref<Array<string | number>>([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-
-const queryFormRef = ref<ElFormInstance>();
-const customizationFormRef = ref<ElFormInstance>();
-
-const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
-});
-
-const initFormData: CustomizationForm = {
-  id: undefined,
-  customizationNo: undefined,
-  productId: undefined,
-  customizedStyle: undefined,
-  customizedCraft: undefined,
-  proofingPeriod: undefined,
-  productionCycle: undefined,
-  moq: undefined,
-  moqPrice: undefined,
-  remark: undefined,
-}
-const data = reactive<PageData<CustomizationForm, CustomizationQuery>>({
-  form: {...initFormData},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    customizationNo: undefined,
-    productId: undefined,
-    customizedStyle: undefined,
-    customizedCraft: undefined,
-    proofingPeriod: undefined,
-    productionCycle: undefined,
-    moq: undefined,
-    moqPrice: undefined,
-    platformCode: undefined,
-    params: {
-    }
-  },
-  rules: {
-    customizationNo: [
-      { required: true, message: "定制编号不能为空", trigger: "blur" }
-    ],
-    productId: [
-      { required: true, message: "产品id不能为空", trigger: "blur" }
-    ],
-    customizedStyle: [
-      { required: true, message: "定制方式  支持多选,分隔  (0=包装定制,1=商品定制,2=开模定制)不能为空", trigger: "blur" }
-    ],
-    customizedCraft: [
-      { required: true, message: "定制工艺  支持多选,分隔  (0=丝印,1=热转印,2=激光,烤花,压印)不能为空", trigger: "blur" }
-    ],
-    proofingPeriod: [
-      { required: true, message: "打样周期不能为空", trigger: "blur" }
-    ],
-    productionCycle: [
-      { required: true, message: "生产周期不能为空", trigger: "blur" }
-    ],
-    moq: [
-      { required: true, message: "最小起订量不能为空", trigger: "blur" }
-    ],
-    moqPrice: [
-      { required: true, message: "MOQ对应价格不能为空", trigger: "blur" }
-    ],
-    remark: [
-      { required: true, message: "备注不能为空", trigger: "blur" }
-    ],
-  }
-});
-
-const { queryParams, form, rules } = toRefs(data);
-
-/** 查询产品定制信息列表 */
-const getList = async () => {
-  loading.value = true;
-  const res = await listCustomization(queryParams.value);
-  customizationList.value = res.rows;
-  total.value = res.total;
-  loading.value = false;
-}
-
-/** 取消按钮 */
-const cancel = () => {
-  reset();
-  dialog.visible = false;
-}
-
-/** 表单重置 */
-const reset = () => {
-  form.value = {...initFormData};
-  customizationFormRef.value?.resetFields();
-}
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value?.resetFields();
-  handleQuery();
-}
-
-/** 多选框选中数据 */
-const handleSelectionChange = (selection: CustomizationVO[]) => {
-  ids.value = selection.map(item => item.id);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-}
-
-/** 新增按钮操作 */
-const handleAdd = () => {
-  reset();
-  dialog.visible = true;
-  dialog.title = "添加产品定制信息";
-}
-
-/** 修改按钮操作 */
-const handleUpdate = async (row?: CustomizationVO) => {
-  reset();
-  const _id = row?.id || ids.value[0]
-  const res = await getCustomization(_id);
-  Object.assign(form.value, res.data);
-  dialog.visible = true;
-  dialog.title = "修改产品定制信息";
-}
-
-/** 提交按钮 */
-const submitForm = () => {
-  customizationFormRef.value?.validate(async (valid: boolean) => {
-    if (valid) {
-      buttonLoading.value = true;
-      if (form.value.id) {
-        await updateCustomization(form.value).finally(() =>  buttonLoading.value = false);
-      } else {
-        await addCustomization(form.value).finally(() =>  buttonLoading.value = false);
-      }
-      proxy?.$modal.msgSuccess("操作成功");
-      dialog.visible = false;
-      await getList();
-    }
-  });
-}
-
-/** 删除按钮操作 */
-const handleDelete = async (row?: CustomizationVO) => {
-  const _ids = row?.id || ids.value;
-  await proxy?.$modal.confirm('是否确认删除产品定制信息编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
-  await delCustomization(_ids);
-  proxy?.$modal.msgSuccess("删除成功");
-  await getList();
-}
-
-/** 导出按钮操作 */
-const handleExport = () => {
-  proxy?.download('product/customization/export', {
-    ...queryParams.value
-  }, `customization_${new Date().getTime()}.xlsx`)
-}
-
-onMounted(() => {
-  getList();
-});
-</script>

+ 0 - 295
src/views/product/products/index.vue

@@ -1,295 +0,0 @@
-<template>
-  <div class="p-2">
-    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-      <div v-show="showSearch" class="mb-[10px]">
-        <el-card shadow="hover">
-          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
-            <el-form-item label="协议编号" prop="protocolNo">
-              <el-input v-model="queryParams.protocolNo" placeholder="请输入协议编号" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="产品编号" prop="productNo">
-              <el-input v-model="queryParams.productNo" placeholder="请输入产品编号" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="协议价格" prop="agreementPrice">
-              <el-input v-model="queryParams.agreementPrice" placeholder="请输入协议价格" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="数据来源" prop="dataSource">
-              <el-input v-model="queryParams.dataSource" placeholder="请输入数据来源" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="客户ID" prop="customerId">
-              <el-input v-model="queryParams.customerId" placeholder="请输入客户ID" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="税率ID或税务编码" prop="taxId">
-              <el-input v-model="queryParams.taxId" placeholder="请输入税率ID或税务编码" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="平台标识" prop="platformCode">
-              <el-input v-model="queryParams.platformCode" placeholder="请输入平台标识" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item>
-              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-            </el-form-item>
-          </el-form>
-        </el-card>
-      </div>
-    </transition>
-
-    <el-card shadow="never">
-      <template #header>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="1.5">
-            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['product:products:add']">新增</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['product:products:edit']">修改</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['product:products:remove']">删除</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['product:products:export']">导出</el-button>
-          </el-col>
-          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-        </el-row>
-      </template>
-
-      <el-table v-loading="loading" border :data="productsList" @selection-change="handleSelectionChange">
-        <el-table-column type="selection" width="55" align="center" />
-        <el-table-column label="主键ID,自增" align="center" prop="id" v-if="true" />
-        <el-table-column label="协议编号" align="center" prop="protocolNo" />
-        <el-table-column label="产品编号" align="center" prop="productNo" />
-        <el-table-column label="协议价格" align="center" prop="agreementPrice" />
-        <el-table-column label="数据来源" align="center" prop="dataSource" />
-        <el-table-column label="客户ID" align="center" prop="customerId" />
-        <el-table-column label="备注信息" align="center" prop="remark" />
-        <el-table-column label="税率ID或税务编码" align="center" prop="taxId" />
-        <el-table-column label="类型" align="center" prop="type" />
-        <el-table-column label="状态" align="center" prop="status" />
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-          <template #default="scope">
-            <el-tooltip content="修改" placement="top">
-              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['product:products:edit']"></el-button>
-            </el-tooltip>
-            <el-tooltip content="删除" placement="top">
-              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['product:products:remove']"></el-button>
-            </el-tooltip>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-    </el-card>
-    <!-- 添加或修改协议产品关联对话框 -->
-    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-      <el-form ref="productsFormRef" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="协议编号" prop="protocolNo">
-          <el-input v-model="form.protocolNo" placeholder="请输入协议编号" />
-        </el-form-item>
-        <el-form-item label="产品编号" prop="productNo">
-          <el-input v-model="form.productNo" placeholder="请输入产品编号" />
-        </el-form-item>
-        <el-form-item label="协议价格" prop="agreementPrice">
-          <el-input v-model="form.agreementPrice" placeholder="请输入协议价格" />
-        </el-form-item>
-        <el-form-item label="数据来源" prop="dataSource">
-          <el-input v-model="form.dataSource" placeholder="请输入数据来源" />
-        </el-form-item>
-        <el-form-item label="客户ID" prop="customerId">
-          <el-input v-model="form.customerId" placeholder="请输入客户ID" />
-        </el-form-item>
-        <el-form-item label="备注信息" prop="remark">
-          <el-input v-model="form.remark" placeholder="请输入备注信息" />
-        </el-form-item>
-        <el-form-item label="税率ID或税务编码" prop="taxId">
-          <el-input v-model="form.taxId" placeholder="请输入税率ID或税务编码" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
-          <el-button @click="cancel">取 消</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup name="Products" lang="ts">
-import { listProducts, getProducts, delProducts, addProducts, updateProducts } from '@/api/product/products';
-import { ProductsVO, ProductsQuery, ProductsForm } from '@/api/product/products/types';
-
-const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-
-const productsList = ref<ProductsVO[]>([]);
-const buttonLoading = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref<Array<string | number>>([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-
-const queryFormRef = ref<ElFormInstance>();
-const productsFormRef = ref<ElFormInstance>();
-
-const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
-});
-
-const initFormData: ProductsForm = {
-  id: undefined,
-  protocolNo: undefined,
-  productNo: undefined,
-  agreementPrice: undefined,
-  dataSource: undefined,
-  customerId: undefined,
-  remark: undefined,
-  taxId: undefined,
-  type: undefined,
-  status: undefined,
-}
-const data = reactive<PageData<ProductsForm, ProductsQuery>>({
-  form: {...initFormData},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    protocolNo: undefined,
-    productNo: undefined,
-    agreementPrice: undefined,
-    dataSource: undefined,
-    customerId: undefined,
-    taxId: undefined,
-    type: undefined,
-    status: undefined,
-    platformCode: undefined,
-    params: {
-    }
-  },
-  rules: {
-    protocolNo: [
-      { required: true, message: "协议编号不能为空", trigger: "blur" }
-    ],
-    productNo: [
-      { required: true, message: "产品编号不能为空", trigger: "blur" }
-    ],
-    agreementPrice: [
-      { required: true, message: "协议价格不能为空", trigger: "blur" }
-    ],
-    dataSource: [
-      { required: true, message: "数据来源不能为空", trigger: "blur" }
-    ],
-    customerId: [
-      { required: true, message: "客户ID不能为空", trigger: "blur" }
-    ],
-    remark: [
-      { required: true, message: "备注信息不能为空", trigger: "blur" }
-    ],
-    taxId: [
-      { required: true, message: "税率ID或税务编码不能为空", trigger: "blur" }
-    ],
-    type: [
-      { required: true, message: "类型不能为空", trigger: "change" }
-    ],
-    status: [
-      { required: true, message: "状态不能为空", trigger: "change" }
-    ],
-  }
-});
-
-const { queryParams, form, rules } = toRefs(data);
-
-/** 查询协议产品关联列表 */
-const getList = async () => {
-  loading.value = true;
-  const res = await listProducts(queryParams.value);
-  productsList.value = res.rows;
-  total.value = res.total;
-  loading.value = false;
-}
-
-/** 取消按钮 */
-const cancel = () => {
-  reset();
-  dialog.visible = false;
-}
-
-/** 表单重置 */
-const reset = () => {
-  form.value = {...initFormData};
-  productsFormRef.value?.resetFields();
-}
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value?.resetFields();
-  handleQuery();
-}
-
-/** 多选框选中数据 */
-const handleSelectionChange = (selection: ProductsVO[]) => {
-  ids.value = selection.map(item => item.id);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-}
-
-/** 新增按钮操作 */
-const handleAdd = () => {
-  reset();
-  dialog.visible = true;
-  dialog.title = "添加协议产品关联";
-}
-
-/** 修改按钮操作 */
-const handleUpdate = async (row?: ProductsVO) => {
-  reset();
-  const _id = row?.id || ids.value[0]
-  const res = await getProducts(_id);
-  Object.assign(form.value, res.data);
-  dialog.visible = true;
-  dialog.title = "修改协议产品关联";
-}
-
-/** 提交按钮 */
-const submitForm = () => {
-  productsFormRef.value?.validate(async (valid: boolean) => {
-    if (valid) {
-      buttonLoading.value = true;
-      if (form.value.id) {
-        await updateProducts(form.value).finally(() =>  buttonLoading.value = false);
-      } else {
-        await addProducts(form.value).finally(() =>  buttonLoading.value = false);
-      }
-      proxy?.$modal.msgSuccess("操作成功");
-      dialog.visible = false;
-      await getList();
-    }
-  });
-}
-
-/** 删除按钮操作 */
-const handleDelete = async (row?: ProductsVO) => {
-  const _ids = row?.id || ids.value;
-  await proxy?.$modal.confirm('是否确认删除协议产品关联编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
-  await delProducts(_ids);
-  proxy?.$modal.msgSuccess("删除成功");
-  await getList();
-}
-
-/** 导出按钮操作 */
-const handleExport = () => {
-  proxy?.download('product/products/export', {
-    ...queryParams.value
-  }, `products_${new Date().getTime()}.xlsx`)
-}
-
-onMounted(() => {
-  getList();
-});
-</script>

+ 0 - 491
src/views/product/protocolInfo/index.vue

@@ -1,491 +0,0 @@
-<template>
-  <div class="p-2">
-    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-      <div v-show="showSearch" class="mb-[10px]">
-        <el-card shadow="hover">
-          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
-            <el-form-item label="客户编号" prop="customerNo">
-              <el-input v-model="queryParams.customerNo" placeholder="请输入客户编号" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="客户名称" prop="customerName">
-              <el-input v-model="queryParams.customerName" placeholder="请输入客户名称" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="状态" prop="protocolStatus">
-              <el-select v-model="queryParams.protocolStatus" placeholder="请选择" clearable>
-                <el-option label="生效" value="1" />
-                <el-option label="待审核" value="0" />
-                <el-option label="失效" value="2" />
-              </el-select>
-            </el-form-item>
-            <el-form-item>
-              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-              <el-button type="primary" icon="Refresh" @click="resetQuery">重置</el-button>
-            </el-form-item>
-          </el-form>
-        </el-card>
-      </div>
-    </transition>
-
-    <el-card shadow="never">
-      <template #header>
-        <el-row :gutter="10" class="mb8" justify="space-between">
-          <el-col :span="1.5">
-            <span class="table-title">协议商品信息列表</span>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="primary" icon="Download" @click="handleExport">导出</el-button>
-            <el-button type="primary" icon="Plus" @click="handleAdd">协议新增</el-button>
-            <!-- <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> -->
-          </el-col>
-        </el-row>
-      </template>
-
-      <el-table v-loading="loading" border :data="infoList" @selection-change="handleSelectionChange">
-        <el-table-column label="创建时间" align="center" prop="createTime" width="120">
-          <template #default="scope">
-            <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="客户编号" align="center" prop="customerNo" width="100" />
-        <el-table-column label="客户名称" align="center" prop="customerName" min-width="180" />
-        <el-table-column label="业务员" align="center" prop="salesmanName" width="100" />
-        <el-table-column label="客服" align="center" prop="serviceName" width="100" />
-        <el-table-column label="截止时间" align="center" prop="endTime" width="120">
-          <template #default="scope">
-            <span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品数量" align="center" prop="productNum" width="100" />
-        <el-table-column label="状态" align="center" prop="approvalStatus" width="80">
-          <template #default="scope">
-            <span>{{ getStatusLabel(scope.row.protocolStatus) }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" align="center" fixed="right" width="300" class-name="small-padding fixed-width">
-          <template #default="scope">
-            <el-button link type="primary" @click="handleDetail(scope.row)" >基本信息</el-button>
-            <el-button link type="primary" @click="handleProductManage(scope.row)" >商品管理</el-button>
-            <el-button link type="primary" @click="handleInvalid(scope.row)" v-if="scope.row.protocolStatus === 1" >失效</el-button>
-            <el-button link type="primary" @click="handleAudit(scope.row)" v-if="scope.row.protocolStatus === 0" >审核</el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-    </el-card>
-    <!-- 添加或修改协议信息对话框 -->
-    <el-dialog :title="dialog.title" v-model="dialog.visible" width="800px" append-to-body>
-      <el-form ref="infoFormRef" :model="form" :rules="rules" label-width="100px">
-        <el-form-item label="客户名称" prop="customerId">
-          <el-select
-            v-model="form.customerId"
-            placeholder="请选择"
-            clearable
-            filterable
-            :disabled="dialog.isView"
-            @change="handleCustomerChange"
-            style="width: 100%"
-          >
-            <el-option
-              v-for="item in customerList"
-              :key="item.id"
-              :label="item.customerName"
-              :value="item.id"
-            />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="所属公司" prop="companyId">
-          <el-input v-model="form.customerName" disabled />
-        </el-form-item>
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="业务员" prop="salesmanId">
-              <el-input v-model="form.salesmanName" disabled />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="客服" prop="serviceId">
-              <el-input v-model="form.serviceName" disabled />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="起始时间" prop="startTime">
-              <el-date-picker
-                v-model="form.startTime"
-                type="date"
-                placeholder="请选择"
-                value-format="YYYY-MM-DD"
-                :disabled="dialog.isView"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="截止时间" prop="endTime">
-              <el-date-picker
-                v-model="form.endTime"
-                type="date"
-                placeholder="请选择"
-                value-format="YYYY-MM-DD"
-                :disabled="dialog.isView"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-form-item label="附件" prop="protocolFile">
-          <file-upload v-model="form.protocolFile" :disabled="dialog.isView"/>
-        </el-form-item>
-        <el-form-item label="备注" prop="remark">
-          <el-input v-model="form.remark" type="textarea" :rows="4" placeholder="请输入内容" :disabled="dialog.isView" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button v-if="!dialog.isView" :loading="buttonLoading" type="primary" @click="submitForm">确认</el-button>
-          <el-button @click="cancel">{{ dialog.isView ? '关闭' : '取消' }}</el-button>
-        </div>
-      </template>
-    </el-dialog>
-
-    <!-- 审核对话框 -->
-    <el-dialog title="审核" v-model="auditDialog.visible" width="500px" append-to-body>
-      <el-form ref="auditFormRef" :model="auditForm" :rules="auditRules" label-width="80px">
-        <el-form-item label="审核:" prop="protocolStatus">
-          <el-select v-model="auditForm.protocolStatus" placeholder="请选择" style="width: 100%">
-            <el-option label="生效" :value="1" />
-            <el-option label="失效" :value="2" />
-          </el-select>
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button :loading="auditButtonLoading" type="primary" @click="submitAudit">确认</el-button>
-          <el-button @click="cancelAudit">取消</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup name="Info" lang="ts">
-import { listInfo, getInfo, delInfo, addInfo, updateInfo } from '@/api/product/protocolInfo';
-import { InfoVO, InfoQuery, InfoForm } from '@/api/product/protocolInfo/types';
-import { listCustomerInfo } from '@/api/customer/customerInfo';
-import { CustomerInfoVO } from '@/api/customer/customerInfo/types';
-
-const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const router = useRouter();
-
-const infoList = ref<InfoVO[]>([]);
-const customerList = ref<CustomerInfoVO[]>([]);
-const buttonLoading = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref<Array<string | number>>([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-
-const queryFormRef = ref<ElFormInstance>();
-const infoFormRef = ref<ElFormInstance>();
-const auditFormRef = ref<ElFormInstance>();
-
-const dialog = reactive<DialogOption & { isView?: boolean }>({
-  visible: false,
-  title: '',
-  isView: false
-});
-
-// 审核对话框
-const auditDialog = reactive({
-  visible: false
-});
-
-// 审核按钮loading
-const auditButtonLoading = ref(false);
-
-// 审核表单
-const auditForm = ref<any>({
-  id: undefined,
-  protocolStatus: undefined
-});
-
-// 审核表单验证规则
-const auditRules = ref({
-  protocolStatus: [{ required: true, message: '请选择审核结果', trigger: 'change' }]
-});
-
-const initFormData: InfoForm = {
-  id: undefined,
-  protocolNo: undefined,
-  customerNo: undefined,
-  customerId: undefined,
-  customerName: undefined,
-  reviewTime: undefined,
-  approvalStatus: undefined,
-  startTime: undefined,
-  endTime: undefined,
-  productNum: undefined,
-  remark: undefined,
-  protocolStatus: undefined,
-  salesmanId: undefined,
-  salesmanName: undefined,
-  companyId: undefined,
-  companyName: undefined,
-  serviceId: undefined,
-  serviceName: undefined,
-  dataSource: undefined,
-  protocolFile: undefined,
-  fileName: undefined,
-  status: undefined,
-}
-const data = reactive<PageData<InfoForm, InfoQuery>>({
-  form: {...initFormData},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    protocolNo: undefined,
-    customerNo: undefined,
-    customerId: undefined,
-    customerName: undefined,
-    reviewTime: undefined,
-    approvalStatus: undefined,
-    startTime: undefined,
-    endTime: undefined,
-    productNum: undefined,
-    protocolStatus: undefined,
-    salesmanId: undefined,
-    companyId: undefined,
-    serviceId: undefined,
-    dataSource: undefined,
-    protocolFile: undefined,
-    fileName: undefined,
-    status: undefined,
-    platformCode: undefined,
-    params: {
-    }
-  },
-  rules: {
-    customerId: [
-      { required: true, message: "客户名称不能为空", trigger: "change" }
-    ],
-    startTime: [
-      { required: true, message: "起始时间不能为空", trigger: "change" }
-    ],
-    endTime: [
-      { required: true, message: "截止时间不能为空", trigger: "change" }
-    ]
-  }
-});
-
-const { queryParams, form, rules } = toRefs(data);
-
-/** 查询协议信息列表 */
-const getList = async () => {
-  loading.value = true;
-  const res = await listInfo(queryParams.value);
-  infoList.value = res.rows;
-  total.value = res.total;
-  loading.value = false;
-}
-
-/** 加载客户列表 */
-const loadCustomerList = async () => {
-  const res = await listCustomerInfo({ pageNum: 1, pageSize: 1000 });
-  customerList.value = res.rows;
-}
-
-/** 客户选择改变 */
-const handleCustomerChange = (customerId: string | number) => {
-  const customer = customerList.value.find(item => item.id === customerId);
-  if (customer) {
-    form.value.customerNo = customer.customerNo;
-    form.value.customerName = customer.customerName;
-    // 公司名称显示客户名称
-    form.value.companyId = customer.belongCompanyId;
-    form.value.companyName = customer.customerName;
-
-    // 从客户信息中获取业务员和客服信息
-    if (customer.customerSalesInfoVo) {
-      form.value.salesmanId = customer.customerSalesInfoVo.salesPersonId;
-      form.value.salesmanName = customer.customerSalesInfoVo.salesPerson || '';
-      form.value.serviceId = customer.customerSalesInfoVo.serviceStaffId;
-      form.value.serviceName = customer.customerSalesInfoVo.serviceStaff || '';
-    } else {
-      form.value.salesmanId = undefined;
-      form.value.salesmanName = '';
-      form.value.serviceId = undefined;
-      form.value.serviceName = '';
-    }
-  }
-}
-
-/** 取消按钮 */
-const cancel = () => {
-  reset();
-  dialog.visible = false;
-}
-
-/** 表单重置 */
-const reset = () => {
-  form.value = {...initFormData};
-  infoFormRef.value?.resetFields();
-}
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
-}
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value?.resetFields();
-  handleQuery();
-}
-
-/** 多选框选中数据 */
-const handleSelectionChange = (selection: InfoVO[]) => {
-  ids.value = selection.map(item => item.id);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-}
-
-/** 新增按钮操作 */
-const handleAdd = () => {
-  reset();
-  dialog.visible = true;
-  dialog.title = "添加协议信息";
-  dialog.isView = false;
-}
-
-/** 修改按钮操作 */
-const handleUpdate = async (row?: InfoVO) => {
-  reset();
-  const _id = row?.id || ids.value[0]
-  const res = await getInfo(_id);
-  Object.assign(form.value, res.data);
-  dialog.visible = true;
-  dialog.title = "修改协议信息";
-  dialog.isView = false;
-}
-
-/** 提交按钮 */
-const submitForm = () => {
-  infoFormRef.value?.validate(async (valid: boolean) => {
-    if (valid) {
-      buttonLoading.value = true;
-      if (form.value.id) {
-        await updateInfo(form.value).finally(() =>  buttonLoading.value = false);
-      } else {
-        await addInfo(form.value).finally(() =>  buttonLoading.value = false);
-      }
-      proxy?.$modal.msgSuccess("操作成功");
-      dialog.visible = false;
-      await getList();
-    }
-  });
-}
-
-/** 删除按钮操作 */
-const handleDelete = async (row?: InfoVO) => {
-  const _ids = row?.id || ids.value;
-  await proxy?.$modal.confirm('是否确认删除协议信息编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
-  await delInfo(_ids);
-  proxy?.$modal.msgSuccess("删除成功");
-  await getList();
-}
-
-/** 导出按钮操作 */
-const handleExport = () => {
-  proxy?.download('product/info/export', {
-    ...queryParams.value
-  }, `info_${new Date().getTime()}.xlsx`)
-}
-
-/** 获取状态标签 */
-const getStatusLabel = (status: number) => {
-  const statusMap: Record<number, string> = {
-    0: '待审核',
-    1: '生效',
-    2: '失效'
-  };
-  console.log('status', statusMap[status] || status);
-  return statusMap[status] || status;
-}
-
-/** 查看基本信息 */
-const handleDetail = async (row: InfoVO) => {
-  reset();
-  const res = await getInfo(row.id);
-  Object.assign(form.value, res.data);
-  dialog.visible = true;
-  dialog.title = "查看基本信息";
-  dialog.isView = true;
-}
-
-/** 商品管理 */
-const handleProductManage = (row: InfoVO) => {
-  router.push({
-    path: '/product/protocolInfo/productManage',
-    query: { protocolId: row.id }
-  });
-}
-
-/** 失效操作 */
-const handleInvalid = async (row: InfoVO) => {
-  await proxy?.$modal.confirm('是否确认将该协议设为失效?');
-  // TODO: 调用失效接口
-  console.log('失效操作', row);
-  await getList();
-}
-
-/** 审核操作 */
-const handleAudit = (row: InfoVO) => {
-  auditForm.value = {
-    id: row.id,
-    protocolStatus: undefined
-  };
-  auditDialog.visible = true;
-}
-
-/** 取消审核 */
-const cancelAudit = () => {
-  auditForm.value = {
-    id: undefined,
-    protocolStatus: undefined
-  };
-  auditFormRef.value?.resetFields();
-  auditDialog.visible = false;
-}
-
-/** 提交审核 */
-const submitAudit = () => {
-  auditFormRef.value?.validate(async (valid: boolean) => {
-    if (valid) {
-      auditButtonLoading.value = true;
-      try {
-        // 构造更新数据
-        const updateData: InfoForm = {
-          id: auditForm.value.id,
-          protocolStatus: auditForm.value.protocolStatus
-        };
-        await updateInfo(updateData).finally(() => auditButtonLoading.value = false);
-        proxy?.$modal.msgSuccess("审核成功");
-        auditDialog.visible = false;
-        await getList();
-      } catch (error) {
-        auditButtonLoading.value = false;
-      }
-    }
-  });
-}
-
-onMounted(() => {
-  getList();
-  loadCustomerList();
-});
-</script>

+ 0 - 664
src/views/product/protocolInfo/productManage.vue

@@ -1,664 +0,0 @@
-<template>
-  <div class="p-2">
-    <!-- 头部信息 -->
-    <el-card shadow="hover" class="mb-[10px]">
-      <div class="flex items-center">
-        <el-button link type="primary" @click="handleBack">
-          <el-icon class="mr-1"><ArrowLeft /></el-icon>
-          返回
-        </el-button>
-        <el-divider direction="vertical" />
-        <span class="mr-4">客户编号: {{ protocolInfo.customerNo }}</span>
-        <span class="mr-4">客户名称: {{ protocolInfo.customerName }}</span>
-        <span>截止日期: {{ protocolInfo.endTime }}</span>
-      </div>
-    </el-card>
-
-    <!-- 搜索区域 -->
-    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-      <div v-show="showSearch" class="mb-[10px]">
-        <el-card shadow="hover">
-          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
-            <el-form-item label="产品编号" prop="productNo">
-              <el-input v-model="queryParams.productNo" placeholder="请输入产品编号" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="产品名称" prop="productName">
-              <el-input v-model="queryParams.productName" placeholder="请输入产品名称" clearable @keyup.enter="handleQuery" />
-            </el-form-item>
-            <el-form-item label="商品品牌" prop="brandId">
-              <el-select v-model="queryParams.brandId" placeholder="请选择" clearable style="width: 200px">
-                <el-option v-for="item in brandList" :key="item.id" :label="item.brandName" :value="item.id" />
-              </el-select>
-            </el-form-item>
-            <el-form-item label="商品状态" prop="productStatus">
-              <el-select v-model="queryParams.productStatus" placeholder="请选择" clearable style="width: 200px">
-                <el-option label="上架" value="1" />
-                <el-option label="下架" value="0" />
-              </el-select>
-            </el-form-item>
-            <el-form-item>
-              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-              <el-button type="primary" icon="Refresh" @click="resetQuery">重置</el-button>
-              <el-button type="primary" icon="Plus" @click="handleAdd">添加商品</el-button>
-              <el-button type="primary" icon="Upload" @click="handleImport">导入商品</el-button>
-              <el-button type="primary" icon="Download" @click="handleExport">导出商品</el-button>
-            </el-form-item>
-          </el-form>
-        </el-card>
-      </div>
-    </transition>
-
-    <!-- 列表区域 -->
-    <el-card shadow="never">
-      <template #header>
-        <el-row :gutter="10" class="mb8" justify="space-between">
-          <el-col :span="1.5">
-            <span class="table-title">协议商品详细信息列表</span>
-          </el-col>
-        </el-row>
-      </template>
-
-      <el-table v-loading="loading" border :data="productsList">
-        <el-table-column label="产品编号" align="center" prop="productNo" width="120" />
-        <el-table-column label="商品图片" align="center" width="100">
-          <template #default="scope">
-            <image-preview :src="scope.row.productImageUrl" :width="60" :height="60"/>
-          </template>
-        </el-table-column>
-        <el-table-column label="商品名称" align="center" min-width="180">
-          <template #default="scope">
-            <div>
-              <div class="text-primary">{{ scope.row.itemName }}</div>
-              <div class="text-gray-400 text-sm">{{ scope.row.brandName }}</div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="产品类别" align="center" prop="categoryName" width="100" />
-        <el-table-column label="单位" align="center" prop="unitName" width="80" />
-        <el-table-column label="Sku价格" align="center" width="140">
-          <template #default="scope">
-            <div class="text-left">
-              <div>市场价: ¥{{ scope.row.marketPrice || 0 }}</div>
-              <div class="text-red-500">平台价: ¥{{ scope.row.memberPrice || 0 }}</div>
-              <div>标准成本: ¥{{ scope.row.purchasingPrice || 0 }}</div>
-              <div>最低售价: ¥{{ scope.row.minSellingPrice || 0 }}</div>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="毛利预估" align="center" prop="tempGrossMargin" width="100" />
-        <el-table-column label="产品来源" align="center" prop="dataSource" width="100" />
-        <el-table-column label="状态" align="center" width="80">
-          <template #default="scope">
-            <span :class="scope.row.productStatus === '1' ? 'text-green-500' : 'text-red-500'">
-              {{ scope.row.productStatus === '1' ? '上架' : '下架' }}
-            </span>
-          </template>
-        </el-table-column>
-        <el-table-column label="协议供货价" align="center" width="120">
-          <template #default="scope">
-            <el-input-number
-              v-model="scope.row.agreementPrice"
-              :min="0"
-              :precision="2"
-              size="small"
-              controls-position="right"
-              @change="handlePriceChange(scope.row)"
-            />
-          </template>
-        </el-table-column>
-        <el-table-column label="供货价毛利率" align="center" width="120">
-          <template #default="scope">
-            {{ calculateMargin(scope.row) }}
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" align="center" fixed="right" width="80">
-          <template #default="scope">
-            <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <pagination
-        v-show="total > 0"
-        :total="total"
-        v-model:page="queryParams.pageNum"
-        v-model:limit="queryParams.pageSize"
-        @pagination="getList"
-      />
-    </el-card>
-
-    <!-- 添加商品对话框 -->
-    <el-dialog title="添加商品" v-model="addProductDialog.visible" width="1400px" append-to-body top="5vh">
-      <div class="add-product-dialog">
-        <!-- 搜索区域 -->
-        <el-form :model="addProductQuery" :inline="true" class="mb-4">
-          <el-form-item>
-            <el-button type="primary" icon="Plus" @click="handleBatchAdd">加入清单</el-button>
-          </el-form-item>
-          <el-form-item label="商品名称:">
-            <el-input v-model="addProductQuery.itemName" placeholder="商品名称" clearable style="width: 200px" />
-          </el-form-item>
-          <el-form-item label="商品编号:">
-            <el-input v-model="addProductQuery.productNo" placeholder="商品编号" clearable style="width: 200px" />
-          </el-form-item>
-          <el-form-item>
-            <el-button type="primary" icon="Search" @click="handleSearchProducts">搜索</el-button>
-          </el-form-item>
-        </el-form>
-
-        <!-- 商品列表 -->
-        <el-table
-          ref="addProductTableRef"
-          v-loading="addProductDialog.loading"
-          :data="addProductDialog.productList"
-          border
-          @selection-change="handleSelectionChange"
-          max-height="500"
-        >
-          <el-table-column type="selection" width="55" align="center" :selectable="checkSelectable" />
-          <el-table-column label="商品编号" align="center" prop="productNo" width="120" />
-          <el-table-column label="商品图片" align="center" prop="productImageUrl" width="100">
-            <template #default="scope">
-              <image-preview :src="scope.row.productImageUrl" :width="60" :height="60"/>
-            </template>
-          </el-table-column>
-          <el-table-column label="商品信息" align="center" min-width="200">
-            <template #default="scope">
-              <div class="text-left" style="font-size: 12px;">
-                <div>{{ scope.row.itemName }}</div>
-                <div class="text-gray-500">品牌:{{ scope.row.brandName || '-' }}</div>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="商品分类" align="center" width="150">
-            <template #default="scope">
-              <div class="text-left" style="font-size: 12px;">
-                <div>{{ scope.row.categoryName || '-' }}</div>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="单位" align="center" width="100">
-            <template #default="scope">
-              <div class="text-left" style="font-size: 12px;">
-                <div>单位:{{ scope.row.unitName || '-' }}</div>
-                <div>起订量:{{ scope.row.minOrderQuantity || 1 }}</div>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="SKU价格" align="center" width="150">
-            <template #default="scope">
-              <div class="text-left" style="font-size: 12px;">
-                <div>
-                  <span class="text-gray-500">市场价:</span>
-                  <span>¥{{ scope.row.midRangePrice || scope.row.marketPrice || '0.00' }}</span>
-                </div>
-                <div>
-                  <span class="text-gray-500">平台价:</span>
-                  <span class="text-red-500">¥{{ scope.row.standardPrice || scope.row.memberPrice || '0.00' }}</span>
-                </div>
-                <div>
-                  <span class="text-gray-500">最低价:</span>
-                  <span>¥{{ scope.row.certificatePrice || scope.row.minSellingPrice || '0.00' }}</span>
-                </div>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="状态" align="center" width="100">
-            <template #default="scope">
-              <el-tag v-if="isProductAdded(scope.row.id)" type="info">已添加</el-tag>
-              <el-tag v-else-if="scope.row.productStatus === '1'" type="success">上架</el-tag>
-              <el-tag v-else type="warning">下架</el-tag>
-            </template>
-          </el-table-column>
-          <el-table-column label="操作" align="center" width="100" fixed="right">
-            <template #default="scope">
-              <el-link
-                v-if="!isProductAdded(scope.row.id)"
-                type="primary"
-                :underline="false"
-                @click="handleAddSingleProduct(scope.row)"
-              >加入清单</el-link>
-              <span v-else class="text-gray-400">已添加</span>
-            </template>
-          </el-table-column>
-        </el-table>
-
-        <!-- 分页 -->
-        <pagination
-          v-show="addProductDialog.productList.length > 0"
-          v-model:page="addProductQuery.pageNum"
-          v-model:limit="addProductQuery.pageSize"
-          v-model:way="addProductQuery.way"
-          :cursor-mode="true"
-          :has-more="addProductHasMore"
-          @pagination="getProductListForAdd"
-        />
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup name="ProductManage" lang="ts">
-import { listProducts, delProducts, updateProducts, addProducts, getProtocolProductIds } from '@/api/product/products';
-import { ProductsQuery, ProductsForm } from '@/api/product/products/types';
-import { getInfo } from '@/api/product/protocolInfo';
-import { listBrand } from '@/api/product/brand';
-import { BrandVO } from '@/api/product/brand/types';
-import { BaseVO, BaseQuery } from '@/api/product/base/types';
-import { listBase } from '@/api/product/base';
-import { ArrowLeft } from '@element-plus/icons-vue';
-
-const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const router = useRouter();
-const route = useRoute();
-
-// 协议ID
-const protocolId = ref<string | number>('');
-// 协议编号
-const protocolNo = ref<string>('');
-// 协议信息
-const protocolInfo = ref<any>({
-  customerNo: '',
-  customerName: '',
-  endTime: ''
-});
-
-const productsList = ref<BaseVO[]>([]);
-const brandList = ref<BrandVO[]>([]);
-const loading = ref(true);
-const showSearch = ref(true);
-const total = ref(0);
-
-const queryFormRef = ref<ElFormInstance>();
-
-const queryParams = ref<ProductsQuery>({
-  pageNum: 1,
-  pageSize: 10,
-  protocolId: route.query.protocolId as string | number,
-  protocolNo: undefined,
-  productNo: undefined,
-  productName: undefined,
-  brandId: undefined,
-  productStatus: undefined
-});
-
-// 已关联的产品ID列表
-const addedProductIds = ref<Set<string | number>>(new Set());
-
-// 添加商品对话框
-const addProductDialog = reactive({
-  visible: false,
-  loading: false,
-  productList: [] as BaseVO[],
-  total: 0
-});
-
-// 游标分页相关变量
-const addProductHasMore = ref(true);
-const addProductPageHistory = ref<Array<{ firstId: string | number; lastId: string | number }>>([]);
-
-// 添加商品查询参数
-const addProductQuery = ref<BaseQuery>({
-  pageNum: 1,
-  pageSize: 10,
-  way: undefined,
-  productNo: undefined,
-  itemName: undefined,
-  lastSeenId: undefined
-});
-
-// 选中的商品
-const selectedProducts = ref<BaseVO[]>([]);
-const addProductTableRef = ref<any>();
-
-/** 查询协议商品列表 */
-const getList = async () => {
-  loading.value = true;
-  try {
-    const res = await listProducts(queryParams.value);
-    productsList.value = res.rows || [];
-    total.value = res.total || 0;
-  } finally {
-    loading.value = false;
-  }
-};
-
-/** 加载协议信息 */
-const loadProtocolInfo = async () => {
-  if (!protocolId.value) return;
-  const res = await getInfo(protocolId.value);
-  if (res.data) {
-    protocolInfo.value = {
-      customerNo: res.data.customerNo || '',
-      customerName: res.data.customerName || '',
-      endTime: res.data.endTime ? parseTime(res.data.endTime, '{y}/{m}/{d} {h}:{i}:{s}') : ''
-    };
-    // 设置协议编号用于查询
-    protocolNo.value = res.data.protocolNo || '';
-    queryParams.value.protocolNo = res.data.protocolNo;
-  }
-};
-
-/** 加载品牌列表 */
-const loadBrandList = async () => {
-  const res = await listBrand({ pageNum: 1, pageSize: 1000 });
-  brandList.value = res.rows || [];
-};
-
-/** 加载已关联的产品ID列表 */
-const loadAddedProductIds = async () => {
-  const protocolId = route.query.protocolId as string | number;
-  try {
-    const res = await getProtocolProductIds(protocolId);
-    addedProductIds.value = new Set(res.data || []);
-  } catch (error) {
-    console.error('获取已关联产品ID失败:', error);
-    addedProductIds.value = new Set();
-  }
-};
-
-/** 判断商品是否已添加 */
-const isProductAdded = (productId: string | number): boolean => {
-  return addedProductIds.value.has(String(productId)) || addedProductIds.value.has(Number(productId));
-};
-
-/** 检查行是否可选择 */
-const checkSelectable = (row: BaseVO): boolean => {
-  return !isProductAdded(row.id);
-};
-
-/** 格式化时间 */
-const parseTime = (time: any, pattern?: string) => {
-  if (!time) return '';
-  const date = new Date(time);
-  const fmt = pattern || '{y}-{m}-{d} {h}:{i}:{s}';
-  const o: Record<string, number> = {
-    y: date.getFullYear(),
-    m: date.getMonth() + 1,
-    d: date.getDate(),
-    h: date.getHours(),
-    i: date.getMinutes(),
-    s: date.getSeconds()
-  };
-  return fmt.replace(/{([ymdhis])+}/g, (match, key) => {
-    const val = o[key];
-    return val.toString().padStart(2, '0');
-  });
-};
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
-};
-
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value?.resetFields();
-  // 保留协议编号
-  const pNo = queryParams.value.protocolNo;
-  queryParams.value = {
-    pageNum: 1,
-    pageSize: 10,
-    protocolNo: pNo,
-    productNo: undefined,
-    productName: undefined,
-    brandId: undefined,
-    productStatus: undefined
-  };
-  handleQuery();
-};
-
-/** 返回按钮 */
-const handleBack = () => {
-  router.back();
-};
-
-/** 添加商品按钮 */
-const handleAdd = async () => {
-  addProductDialog.visible = true;
-  // 重置查询条件
-  addProductQuery.value = {
-    pageNum: 1,
-    pageSize: 10,
-    way: undefined,
-    productNo: undefined,
-    itemName: undefined,
-    lastSeenId: undefined
-  };
-  // 重置游标分页状态
-  addProductPageHistory.value = [];
-  addProductHasMore.value = true;
-  selectedProducts.value = [];
-  // 先加载已关联的产品ID
-  await loadAddedProductIds();
-  // 再加载商品列表
-  getProductListForAdd();
-};
-
-/** 获取商品列表用于添加 */
-const getProductListForAdd = async () => {
-  addProductDialog.loading = true;
-  try {
-    const params = { ...addProductQuery.value };
-    const currentPageNum = addProductQuery.value.pageNum;
-
-    // 第一页不需要游标参数
-    if (currentPageNum === 1) {
-      delete params.lastSeenId;
-      delete params.firstSeenId;
-      delete params.way;
-    } else {
-      // way参数:0=上一页,1=下一页
-      if (addProductQuery.value.way === 0) {
-        // 上一页:使用目标页的firstId
-        const nextPageHistory = addProductPageHistory.value[currentPageNum];
-        if (nextPageHistory) {
-          params.firstSeenId = nextPageHistory.firstId;
-          params.way = 0;
-        }
-      } else {
-        // 下一页:使用前一页的lastId作为lastSeenId
-        const prevPageHistory = addProductPageHistory.value[currentPageNum - 1];
-        if (prevPageHistory) {
-          params.lastSeenId = prevPageHistory.lastId;
-          params.way = 1;
-        }
-      }
-    }
-
-    const res = await listBase(params);
-    // 兼容两种返回结构
-    if (res.rows) {
-      addProductDialog.productList = res.rows;
-      addProductDialog.total = res.total || 0;
-    } else if (res.data) {
-      addProductDialog.productList = Array.isArray(res.data) ? res.data : [];
-      addProductDialog.total = addProductDialog.productList.length;
-    } else {
-      addProductDialog.productList = [];
-      addProductDialog.total = 0;
-    }
-
-    // 判断是否还有更多数据
-    addProductHasMore.value = addProductDialog.productList.length === addProductQuery.value.pageSize;
-
-    // 记录当前页的第一个id和最后一个id
-    if (addProductDialog.productList.length > 0) {
-      const firstItem = addProductDialog.productList[0];
-      const lastItem = addProductDialog.productList[addProductDialog.productList.length - 1];
-      // 如果长度小于currentPageNum则创建
-      if (addProductPageHistory.value.length <= currentPageNum) {
-        addProductPageHistory.value[currentPageNum] = {
-          firstId: firstItem.id,
-          lastId: lastItem.id
-        };
-      }
-    }
-  } catch (error) {
-    console.error('获取商品列表失败:', error);
-    addProductDialog.productList = [];
-    addProductDialog.total = 0;
-  } finally {
-    addProductDialog.loading = false;
-  }
-};
-
-/** 搜索商品 */
-const handleSearchProducts = () => {
-  addProductQuery.value.pageNum = 1;
-  addProductQuery.value.lastSeenId = undefined;
-  addProductPageHistory.value = []; // 重置页面历史
-  addProductHasMore.value = true;
-  getProductListForAdd();
-};
-
-/** 选择变化 */
-const handleSelectionChange = (selection: BaseVO[]) => {
-  selectedProducts.value = selection;
-};
-
-/** 批量加入清单 */
-const handleBatchAdd = async () => {
-  if (selectedProducts.value.length === 0) {
-    proxy?.$modal.msgWarning('请先选择要添加的商品');
-    return;
-  }
-
-  try {
-    // 逐个添加商品
-    for (const product of selectedProducts.value) {
-      const data: ProductsForm = {
-        protocolNo: protocolNo.value,
-        protocolId: route.query.protocolId as string | number,
-        productNo: product.productNo,
-        productId: product.id,
-        agreementPrice: product.standardPrice || product.midRangePrice || product.memberPrice || 0,
-        customerId: protocolInfo.value.customerId,
-        dataSource: product.dataSource
-      };
-      await addProducts(data);
-    }
-
-    proxy?.$modal.msgSuccess(`成功添加 ${selectedProducts.value.length} 个商品`);
-    addProductDialog.visible = false;
-    // 清空选中项
-    selectedProducts.value = [];
-    if (addProductTableRef.value) {
-      addProductTableRef.value.clearSelection();
-    }
-    // 刷新列表
-    await loadAddedProductIds();
-    await getList();
-  } catch (error) {
-    console.error('添加商品失败:', error);
-    proxy?.$modal.msgError('添加商品失败');
-  }
-};
-
-/** 添加单个商品 */
-const handleAddSingleProduct = async (row: BaseVO) => {
-  try {
-    const data: ProductsForm = {
-      protocolNo: protocolNo.value,
-      protocolId: route.query.protocolId as string | number,
-      productNo: row.productNo,
-      productId: row.id,
-      agreementPrice: row.standardPrice || row.midRangePrice || row.memberPrice || 0,
-      customerId: protocolInfo.value.customerId,
-      dataSource: row.dataSource
-    };
-    await addProducts(data);
-
-    proxy?.$modal.msgSuccess('添加成功');
-    // 更新已添加的产品ID列表
-    addedProductIds.value.add(row.id);
-    // 刷新主列表
-    await getList();
-  } catch (error) {
-    console.error('添加商品失败:', error);
-    proxy?.$modal.msgError('添加商品失败');
-  }
-};
-
-/** 导入商品按钮 */
-const handleImport = () => {
-  proxy?.$modal.msgWarning('导入商品功能待实现');
-};
-
-/** 导出商品按钮 */
-const handleExport = () => {
-  proxy?.download('product/products/export', {
-    ...queryParams.value
-  }, `products_${new Date().getTime()}.xlsx`);
-};
-
-/** 删除按钮操作 */
-const handleDelete = async (row: any) => {
-  await proxy?.$modal.confirm('是否确认删除该商品?');
-  await delProducts(row.id);
-  proxy?.$modal.msgSuccess('删除成功');
-  await getList();
-};
-
-/** 协议供货价变更 */
-const handlePriceChange = async (row: any) => {
-  try {
-    await updateProducts({
-      id: row.id,
-      agreementPrice: row.agreementPrice
-    });
-    proxy?.$modal.msgSuccess('价格更新成功');
-  } catch (error) {
-    proxy?.$modal.msgError('价格更新失败');
-  }
-};
-
-/** 计算供货价毛利率 */
-const calculateMargin = (row: any) => {
-  if (!row.agreementPrice || !row.purchasingPrice || row.purchasingPrice === 0) {
-    return '-';
-  }
-  const margin = ((row.agreementPrice - row.purchasingPrice) / row.agreementPrice * 100).toFixed(2);
-  return margin;
-};
-
-onMounted(() => {
-  // 从路由参数获取协议ID
-  protocolId.value = route.query.protocolId as string || route.params.id as string || '';
-  if (protocolId.value) {
-    loadProtocolInfo();
-    loadBrandList();
-    getList();
-  } else {
-    proxy?.$modal.msgError('缺少协议ID参数');
-    router.back();
-  }
-});
-</script>
-
-<style scoped>
-.text-primary {
-  color: #409eff;
-}
-.text-gray-400 {
-  color: #909399;
-}
-.text-gray-500 {
-  color: #909399;
-}
-.text-red-500 {
-  color: #f56c6c;
-}
-.text-green-500 {
-  color: #67c23a;
-}
-.text-sm {
-  font-size: 12px;
-}
-.add-product-dialog {
-  :deep(.el-form--inline .el-form-item) {
-    margin-right: 10px;
-  }
-}
-</style>