Browse Source

合并代码

chenying2100 2 tháng trước cách đây
mục cha
commit
dd5e9b0e43

+ 1 - 0
package.json

@@ -71,6 +71,7 @@
     "typescript": "~5.8.3",
     "unocss": "66.0.0",
     "unplugin-auto-import": "19.1.2",
+    "unplugin-element-plus": "^0.10.0",
     "unplugin-icons": "22.1.0",
     "unplugin-vue-components": "28.5.0",
     "unplugin-vue-setup-extend-plus": "1.0.1",

+ 18 - 0
product.txt

@@ -0,0 +1,18 @@
++------------------------------------------------------------------+
+|                        产品分类管理                                  |
++------------------------------------------------------------------+
+|                                                                    |
+| 分类名称: [____________]  [查询]  [重置]                            |
+|                                                                    |
++------------------------------------------------------------------+
+|                                                                    |
+| [新增]  [关闭所有]                                                 |
+|                                                                    |
+| +--------------------------------------------------------------+ |
+| |  分类名称    |    操作                                         | |
+| |--------------------------------------------------------------|  |
+| |  肠内营养    |    [编辑] [删除]                               | |
+| |  产品        |    [编辑] [删除]                               | |
+| +--------------------------------------------------------------+ |
+|                                                                    |
++------------------------------------------------------------------+ 

+ 63 - 0
src/api/warehouse/productCategory/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { CategoryVO, CategoryForm, CategoryQuery } from '@/api/warehouse/productCategory/types'
+
+/**
+ * 查询产品分类列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listCategory = (query?: CategoryQuery): AxiosPromise<CategoryVO[]> => {
+  return request({
+    url: '/warehouse/productCategory/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询产品分类详细
+ * @param categoryId
+ */
+export const getCategory = (categoryId: string | number): AxiosPromise<CategoryVO> => {
+  return request({
+    url: '/warehouse/productCategory/' + categoryId,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增产品分类
+ * @param data
+ */
+export const addCategory = (data: CategoryForm) => {
+  return request({
+    url: '/warehouse/productCategory',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改产品分类
+ * @param data
+ */
+export const updateCategory = (data: CategoryForm) => {
+  return request({
+    url: '/warehouse/productCategory',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除产品分类
+ * @param categoryId
+ */
+export const delCategory = (categoryId: string | number | Array<string | number>) => {
+  return request({
+    url: '/warehouse/productCategory/' + categoryId,
+    method: 'delete'
+  });
+};

+ 71 - 0
src/api/warehouse/productCategory/types.ts

@@ -0,0 +1,71 @@
+export interface CategoryVO {
+  /**
+   * 产品分类ID
+   */
+  categoryId: string | number;
+
+  /**
+   * 父产品分类id
+   */
+  parentId: string | number;
+
+  /**
+   * 产品分类名称
+   */
+  categoryName: string;
+
+  /**
+   * 显示顺序
+   */
+  orderNum: number;
+
+}
+
+export interface CategoryForm extends BaseEntity {
+  /**
+   * 产品分类ID
+   */
+  categoryId?: string | number;
+
+  /**
+   * 父产品分类id
+   */
+  parentId?: string | number;
+
+  /**
+   * 产品分类名称
+   */
+  categoryName?: string;
+
+  /**
+   * 显示顺序
+   */
+  orderNum?: number;
+
+}
+
+export interface CategoryQuery extends PageQuery {
+
+  /**
+   * 父产品分类id
+   */
+  parentId?: string | number;
+
+  /**
+   * 产品分类名称
+   */
+  categoryName?: string;
+
+  /**
+   * 显示顺序
+   */
+  orderNum?: number;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/warehouse/productNutrition/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { NutritionVO, NutritionForm, NutritionQuery } from '@/api/warehouse/productNutrition/types';
+
+/**
+ * 查询营养产品信息列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listNutrition = (query?: NutritionQuery): AxiosPromise<NutritionVO[]> => {
+  return request({
+    url: '/warehouse/nutrition/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询营养产品信息详细
+ * @param id
+ */
+export const getNutrition = (id: string | number): AxiosPromise<NutritionVO> => {
+  return request({
+    url: '/warehouse/nutrition/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增营养产品信息
+ * @param data
+ */
+export const addNutrition = (data: NutritionForm) => {
+  return request({
+    url: '/warehouse/nutrition',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改营养产品信息
+ * @param data
+ */
+export const updateNutrition = (data: NutritionForm) => {
+  return request({
+    url: '/warehouse/nutrition',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除营养产品信息
+ * @param id
+ */
+export const delNutrition = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/warehouse/nutrition/' + id,
+    method: 'delete'
+  });
+};

+ 1692 - 0
src/api/warehouse/productNutrition/types.ts

@@ -0,0 +1,1692 @@
+export interface NutritionVO {
+    /**
+     * 主键ID
+     */
+    id: string | number;
+
+    /**
+     * 产品名称
+     */
+    productName: string;
+
+    /**
+     * 院方系统编码
+     */
+    hospitalSystemCode: string;
+
+    /**
+     * 商品编码
+     */
+    productCode: string;
+
+    /**
+     * 产品所属分类
+     */
+    productCategory: string;
+
+    productCategoryList?: string[];
+
+    /**
+     * 生产厂商
+     */
+    manufacturer: string;
+
+    /**
+     * 品牌
+     */
+    brand: string;
+
+    /**
+     * 产品所属标签
+     */
+    productLabel: string;
+
+    /**
+     * 许可证有效期提醒
+     */
+    licenseExpiryReminder: string;
+
+    /**
+     * 商品许可证有效期至
+     */
+    productLicenseExpiry: string;
+
+    /**
+     * 商品资质
+     */
+    productQualification: string;
+
+    /**
+     * 批准文号
+     */
+    approvalNumber: string;
+
+    /**
+     * 口味
+     */
+    taste: string;
+
+    /**
+     * 剂型/形态
+     */
+    dosageForm: string;
+
+    /**
+     * 供应商
+     */
+    supplier: string;
+
+    /**
+     * 产品适用科室
+     */
+    applicableDepartment: string;
+
+    /**
+     * 禁忌症所属标签
+     */
+    contraindicationLabel: string;
+
+    /**
+     * 保质期临期提醒
+     */
+    shelfLifeReminder: string;
+
+    /**
+     * 保质期
+     */
+    shelfLife: string;
+
+    /**
+     * 入货价格
+     */
+    purchasePrice: number;
+
+    /**
+     * 入货单位
+     */
+    purchaseUnit: string;
+
+    /**
+     * 默认用法
+     */
+    defaultUsage: string;
+
+    /**
+     * 预包装单位
+     */
+    packageUnit: string;
+
+    /**
+     * 商品规格
+     */
+    productSpec: string;
+
+    /**
+     * 预包装销售价
+     */
+    packagePrice: number;
+
+    /**
+     * 最小包装单位
+     */
+    minUnit: string;
+
+    /**
+     * 最小包装规格
+     */
+    minSpec: string;
+
+    /**
+     * 净含量/规格
+     */
+    netContent: string;
+
+    /**
+     * 配置销售价格
+     */
+    configSalePrice: number;
+
+    /**
+     * 配置损耗率
+     */
+    configLossRate: number;
+
+    /**
+     * 热量
+     */
+    calorie: number;
+
+    /**
+     * 碳水化合物
+     */
+    carbohydrate: number;
+
+    /**
+     * 热能
+     */
+    heatEnergy: number;
+
+    /**
+     * 蛋白质
+     */
+    protein: number;
+
+    /**
+     * 脂肪
+     */
+    fat: number;
+
+    /**
+     * 钙
+     */
+    ca: number;
+
+    /**
+     * 磷
+     */
+    p: number;
+
+    /**
+     * 钾
+     */
+    k: number;
+
+    /**
+     * 钠
+     */
+    na: number;
+
+    /**
+     * 镁
+     */
+    mg: number;
+
+    /**
+     * 氯
+     */
+    cl: number;
+
+    /**
+     * 铁
+     */
+    fe: number;
+
+    /**
+     * 锌
+     */
+    zn: number;
+
+    /**
+     * 硒
+     */
+    se: number;
+
+    /**
+     * 铜
+     */
+    cu: number;
+
+    /**
+     * 锰
+     */
+    mn: number;
+
+    /**
+     * 碘
+     */
+    i: number;
+
+    /**
+     * 氟
+     */
+    f: number;
+
+    /**
+     * 铬
+     */
+    cr: number;
+
+    /**
+     * 钼
+     */
+    mo: number;
+
+    /**
+     * 异亮氨酸
+     */
+    isoleucine: number;
+
+    /**
+     * 色氨酸
+     */
+    tryptophan: number;
+
+    /**
+     * 含硫氨基酸
+     */
+    sulfurAminoAcid: string | number;
+
+    /**
+     * 组氨酸
+     */
+    histidine: string | number;
+
+    /**
+     * 芳香族氨基酸
+     */
+    aromaticAminoAcid: string | number;
+
+    /**
+     * 谷氨酸
+     */
+    glutamicAcid: string | number;
+
+    /**
+     * 苏氨酸
+     */
+    threonine: number;
+
+    /**
+     * 丝氨酸
+     */
+    serine: number;
+
+    /**
+     * 精氨酸
+     */
+    arginine: number;
+
+    /**
+     * 赖氨酸
+     */
+    lysine: number;
+
+    /**
+     * 天冬氨酸
+     */
+    asparticAcid: string | number;
+
+    /**
+     * 胱氨酸
+     */
+    cysteine: number;
+
+    /**
+     * 脯氨酸
+     */
+    proline: number;
+
+    /**
+     * 酪氨酸
+     */
+    tyrosine: number;
+
+    /**
+     * 亮氨酸
+     */
+    leucine: number;
+
+    /**
+     * 缬氨酸
+     */
+    valine: number;
+
+    /**
+     * 蛋氨酸
+     */
+    methionine: number;
+
+    /**
+     * 丙氨酸
+     */
+    alanine: number;
+
+    /**
+     * 苯丙氨酸
+     */
+    phenylalanine: number;
+
+    /**
+     * 甘氨酸
+     */
+    glycine: number;
+
+    /**
+     * 脂肪酸
+     */
+    fattyAcid: string | number;
+
+    /**
+     * 饱和脂肪酸
+     */
+    saturatedFattyAcid: string | number;
+
+    /**
+     * 单不饱和脂肪酸
+     */
+    monounsaturatedFattyAcid: string | number;
+
+    /**
+     * 多不饱和脂肪酸
+     */
+    polyunsaturatedFattyAcid: string | number;
+
+    /**
+     * 维生素A
+     */
+    vitaminA: number;
+
+    /**
+     * 维生素A(胡萝卜素)
+     */
+    vitaminACarotene: number;
+
+    /**
+     * 维生素A醇
+     */
+    vitaminAAlcohol: number;
+
+    /**
+     * 维生素D
+     */
+    vitaminD: number;
+
+    /**
+     * 维生素E
+     */
+    vitaminE: number;
+
+    /**
+     * 维生素E(生育酚)
+     */
+    vitaminETocopherol: number;
+
+    /**
+     * 维生素K
+     */
+    vitaminK: number;
+
+    /**
+     * 维生素B1
+     */
+    vitaminBOne: number;
+
+    /**
+     * 维生素B2
+     */
+    vitaminBTwo: number;
+
+    /**
+     * 维生素B6
+     */
+    vitaminBSix: number;
+
+    /**
+     * 维生素B12
+     */
+    vitaminBTwelve: number;
+
+    /**
+     * 烟酸(尼克酸)
+     */
+    niacin: number;
+
+    /**
+     * 维生素C
+     */
+    vitaminC: number;
+
+    /**
+     * 叶酸
+     */
+    folicAcid: string | number;
+
+    /**
+     * 胆碱
+     */
+    choline: number;
+
+    /**
+     * 生物素
+     */
+    biotin: number;
+
+    /**
+     * 泛酸
+     */
+    pantothenicAcid: string | number;
+
+    /**
+     * 胆固醇
+     */
+    cholesterol: number;
+
+    /**
+     * 血糖生成指数
+     */
+    bloodGlucoseIndex: number;
+
+    /**
+     * 不可溶性膳食纤维
+     */
+    insolubleDietaryFiber: number;
+
+    /**
+     * 膳食纤维
+     */
+    dietaryFiber: number;
+
+    /**
+     * 灰分
+     */
+    ash: number;
+
+    /**
+     * 可溶性膳食纤维
+     */
+    solubleDietaryFiber: number;
+
+    /**
+     * 适用人群
+     */
+    applicableCrowd: string;
+
+    /**
+     * 不适用人群
+     */
+    unsuitableCrowd: string;
+
+    /**
+     * 渗透压
+     */
+    osmoticPressure: number;
+
+    /**
+     * 原料
+     */
+    rawMaterial: string;
+
+    /**
+     * 适应症及禁忌
+     */
+    indicationsContraindications: string;
+
+    /**
+     * 食用方法和食用量
+     */
+    usageAndDosage: string;
+
+    /**
+     * 产品特点
+     */
+    productFeatures: string;
+
+    /**
+     * 储存条件
+     */
+    storageConditions: string;
+
+    /**
+     * 警示说明及注意事项
+     */
+    warningInstructions: string;
+
+    /**
+     * 商品附件
+     */
+    productAttachments: string;
+
+    /**
+     * 状态(1:启用 0:禁用)
+     */
+    status: number;
+
+    /**
+     * 上架 
+     */
+    putFlag: string;
+
+    /**
+     * 出库文号
+     */
+    outboundNumber: string;
+
+    /**
+     * 水分
+     */
+    moisture: number;
+
+}
+
+export interface NutritionForm extends BaseEntity {
+    /**
+     * 主键ID
+     */
+    id?: string | number;
+
+    /**
+     * 产品名称
+     */
+    productName?: string;
+
+    /**
+     * 院方系统编码
+     */
+    hospitalSystemCode?: string;
+
+    /**
+     * 商品编码
+     */
+    productCode?: string;
+
+    /**
+     * 产品所属分类
+     */
+    productCategory?: string;
+
+    productCategoryList?: string[];
+
+    /**
+     * 生产厂商
+     */
+    manufacturer?: string;
+
+    /**
+     * 品牌
+     */
+    brand?: string;
+
+    /**
+     * 产品所属标签
+     */
+    productLabel?: string;
+
+    /**
+     * 许可证有效期提醒
+     */
+    licenseExpiryReminder?: string;
+
+    /**
+     * 商品许可证有效期至
+     */
+    productLicenseExpiry?: string;
+
+    /**
+     * 商品资质
+     */
+    productQualification?: string;
+
+    /**
+     * 批准文号
+     */
+    approvalNumber?: string;
+
+    /**
+     * 口味
+     */
+    taste?: string;
+
+    /**
+     * 剂型/形态
+     */
+    dosageForm?: string;
+
+    /**
+     * 供应商
+     */
+    supplier?: string;
+
+    /**
+     * 产品适用科室
+     */
+    applicableDepartment?: string;
+
+    /**
+     * 禁忌症所属标签
+     */
+    contraindicationLabel?: string;
+
+    /**
+     * 保质期临期提醒
+     */
+    shelfLifeReminder?: string;
+
+    /**
+     * 保质期
+     */
+    shelfLife?: string;
+
+    /**
+     * 入货价格
+     */
+    purchasePrice?: number;
+
+    /**
+     * 入货单位
+     */
+    purchaseUnit?: string;
+
+    /**
+     * 默认用法
+     */
+    defaultUsage?: string;
+
+    /**
+     * 预包装单位
+     */
+    packageUnit?: string;
+
+    /**
+     * 商品规格
+     */
+    productSpec?: string;
+
+    /**
+     * 商品规格-数值
+     */
+    productSpecValue?: string;
+
+    /**
+     * 商品规格-单位
+     */
+    productSpecUnit?: string;
+
+    /**
+     * 预包装销售价
+     */
+    packagePrice?: number;
+
+    /**
+     * 最小包装单位
+     */
+    minUnit?: string;
+
+    /**
+     * 最小包装规格
+     */
+    minSpec?: string;
+
+    /**
+     * 净含量/规格
+     */
+    netContent?: string;
+
+    /**
+     * 配置销售价格
+     */
+    configSalePrice?: number;
+
+    /**
+     * 配置损耗率
+     */
+    configLossRate?: number;
+
+    /**
+     * 热量
+     */
+    calorie?: number;
+
+    /**
+     * 碳水化合物
+     */
+    carbohydrate?: number;
+
+    /**
+     * 热能
+     */
+    heatEnergy?: number;
+
+    /**
+     * 蛋白质
+     */
+    protein?: number;
+
+    /**
+     * 脂肪
+     */
+    fat?: number;
+
+    /**
+     * 钙
+     */
+    ca?: number;
+
+    /**
+     * 磷
+     */
+    p?: number;
+
+    /**
+     * 钾
+     */
+    k?: number;
+
+    /**
+     * 钠
+     */
+    na?: number;
+
+    /**
+     * 镁
+     */
+    mg?: number;
+
+    /**
+     * 氯
+     */
+    cl?: number;
+
+    /**
+     * 铁
+     */
+    fe?: number;
+
+    /**
+     * 锌
+     */
+    zn?: number;
+
+    /**
+     * 硒
+     */
+    se?: number;
+
+    /**
+     * 铜
+     */
+    cu?: number;
+
+    /**
+     * 锰
+     */
+    mn?: number;
+
+    /**
+     * 碘
+     */
+    i?: number;
+
+    /**
+     * 氟
+     */
+    f?: number;
+
+    /**
+     * 铬
+     */
+    cr?: number;
+
+    /**
+     * 钼
+     */
+    mo?: number;
+
+    /**
+     * 异亮氨酸
+     */
+    isoleucine?: number;
+
+    /**
+     * 色氨酸
+     */
+    tryptophan?: number;
+
+    /**
+     * 含硫氨基酸
+     */
+    sulfurAminoAcid?: string | number;
+
+    /**
+     * 组氨酸
+     */
+    histidine?: string | number;
+
+    /**
+     * 芳香族氨基酸
+     */
+    aromaticAminoAcid?: string | number;
+
+    /**
+     * 谷氨酸
+     */
+    glutamicAcid?: string | number;
+
+    /**
+     * 苏氨酸
+     */
+    threonine?: number;
+
+    /**
+     * 丝氨酸
+     */
+    serine?: number;
+
+    /**
+     * 精氨酸
+     */
+    arginine?: number;
+
+    /**
+     * 赖氨酸
+     */
+    lysine?: number;
+
+    /**
+     * 天冬氨酸
+     */
+    asparticAcid?: string | number;
+
+    /**
+     * 胱氨酸
+     */
+    cysteine?: number;
+
+    /**
+     * 脯氨酸
+     */
+    proline?: number;
+
+    /**
+     * 酪氨酸
+     */
+    tyrosine?: number;
+
+    /**
+     * 亮氨酸
+     */
+    leucine?: number;
+
+    /**
+     * 缬氨酸
+     */
+    valine?: number;
+
+    /**
+     * 蛋氨酸
+     */
+    methionine?: number;
+
+    /**
+     * 丙氨酸
+     */
+    alanine?: number;
+
+    /**
+     * 苯丙氨酸
+     */
+    phenylalanine?: number;
+
+    /**
+     * 甘氨酸
+     */
+    glycine?: number;
+
+    /**
+     * 脂肪酸
+     */
+    fattyAcid?: string | number;
+
+    /**
+     * 饱和脂肪酸
+     */
+    saturatedFattyAcid?: string | number;
+
+    /**
+     * 单不饱和脂肪酸
+     */
+    monounsaturatedFattyAcid?: string | number;
+
+    /**
+     * 多不饱和脂肪酸
+     */
+    polyunsaturatedFattyAcid?: string | number;
+
+    /**
+     * 维生素A
+     */
+    vitaminA?: number;
+
+    /**
+     * 维生素A(胡萝卜素)
+     */
+    vitaminACarotene?: number;
+
+    /**
+     * 维生素A醇
+     */
+    vitaminAAlcohol?: number;
+
+    /**
+     * 维生素D
+     */
+    vitaminD?: number;
+
+    /**
+     * 维生素E
+     */
+    vitaminE?: number;
+
+    /**
+     * 维生素E(生育酚)
+     */
+    vitaminETocopherol?: number;
+
+    /**
+     * 维生素K
+     */
+    vitaminK?: number;
+
+    /**
+     * 维生素B1
+     */
+    vitaminBOne?: number;
+
+    /**
+     * 维生素B2
+     */
+    vitaminBTwo?: number;
+
+    /**
+     * 维生素B6
+     */
+    vitaminBSix?: number;
+
+    /**
+     * 维生素B12
+     */
+    vitaminBTwelve?: number;
+
+    /**
+     * 烟酸(尼克酸)
+     */
+    niacin?: number;
+
+    /**
+     * 维生素C
+     */
+    vitaminC?: number;
+
+    /**
+     * 叶酸
+     */
+    folicAcid?: string | number;
+
+    /**
+     * 胆碱
+     */
+    choline?: number;
+
+    /**
+     * 生物素
+     */
+    biotin?: number;
+
+    /**
+     * 泛酸
+     */
+    pantothenicAcid?: string | number;
+
+    /**
+     * 胆固醇
+     */
+    cholesterol?: number;
+
+    /**
+     * 血糖生成指数
+     */
+    bloodGlucoseIndex?: number;
+
+    /**
+     * 不可溶性膳食纤维
+     */
+    insolubleDietaryFiber?: number;
+
+    /**
+     * 膳食纤维
+     */
+    dietaryFiber?: number;
+
+    /**
+     * 灰分
+     */
+    ash?: number;
+
+    /**
+     * 可溶性膳食纤维
+     */
+    solubleDietaryFiber?: number;
+
+    /**
+     * 适用人群
+     */
+    applicableCrowd?: string;
+
+    /**
+     * 不适用人群
+     */
+    unsuitableCrowd?: string;
+
+    /**
+     * 渗透压
+     */
+    osmoticPressure?: number;
+
+    /**
+     * 原料
+     */
+    rawMaterial?: string;
+
+    /**
+     * 适应症及禁忌
+     */
+    indicationsContraindications?: string;
+
+    /**
+     * 食用方法和食用量
+     */
+    usageAndDosage?: string;
+
+    /**
+     * 产品特点
+     */
+    productFeatures?: string;
+
+    /**
+     * 储存条件
+     */
+    storageConditions?: string;
+
+    /**
+     * 警示说明及注意事项
+     */
+    warningInstructions?: string;
+
+    /**
+     * 商品附件
+     */
+    productAttachments?: string;
+
+    /**
+     * 状态(1:启用 0:禁用)
+     */
+    status?: number;
+
+    /**
+     * 上架 
+     */
+    putFlag?: string;
+
+    /**
+     * 出库文号
+     */
+    outboundNumber?: string;
+
+    /**
+     * 水分
+     */
+    moisture?: number;
+
+}
+
+export interface NutritionQuery extends PageQuery {
+
+    /**
+     * 产品名称
+     */
+    productName?: string;
+
+    /**
+     * 院方系统编码
+     */
+    hospitalSystemCode?: string;
+
+    /**
+     * 商品编码
+     */
+    productCode?: string;
+
+    /**
+     * 产品所属分类
+     */
+    productCategory?: string;
+
+    productCategoryList?: string[];
+
+    /**
+     * 生产厂商
+     */
+    manufacturer?: string;
+
+    /**
+     * 品牌
+     */
+    brand?: string;
+
+    /**
+     * 产品所属标签
+     */
+    productLabel?: string;
+
+    /**
+     * 许可证有效期提醒
+     */
+    licenseExpiryReminder?: string;
+
+    /**
+     * 商品许可证有效期至
+     */
+    productLicenseExpiry?: string;
+
+    /**
+     * 商品资质
+     */
+    productQualification?: string;
+
+    /**
+     * 批准文号
+     */
+    approvalNumber?: string;
+
+    /**
+     * 口味
+     */
+    taste?: string;
+
+    /**
+     * 剂型/形态
+     */
+    dosageForm?: string;
+
+    /**
+     * 供应商
+     */
+    supplier?: string;
+
+    /**
+     * 产品适用科室
+     */
+    applicableDepartment?: string;
+
+    /**
+     * 禁忌症所属标签
+     */
+    contraindicationLabel?: string;
+
+    /**
+     * 保质期临期提醒
+     */
+    shelfLifeReminder?: string;
+
+    /**
+     * 保质期
+     */
+    shelfLife?: string;
+
+    /**
+     * 入货价格
+     */
+    purchasePrice?: number;
+
+    /**
+     * 入货单位
+     */
+    purchaseUnit?: string;
+
+    /**
+     * 默认用法
+     */
+    defaultUsage?: string;
+
+    /**
+     * 预包装单位
+     */
+    packageUnit?: string;
+
+    /**
+     * 商品规格
+     */
+    productSpec?: string;
+
+    /**
+     * 预包装销售价
+     */
+    packagePrice?: number;
+
+    /**
+     * 最小包装单位
+     */
+    minUnit?: string;
+
+    /**
+     * 最小包装规格
+     */
+    minSpec?: string;
+
+    /**
+     * 净含量/规格
+     */
+    netContent?: string;
+
+    /**
+     * 配置销售价格
+     */
+    configSalePrice?: number;
+
+    /**
+     * 配置损耗率
+     */
+    configLossRate?: number;
+
+    /**
+     * 热量
+     */
+    calorie?: number;
+
+    /**
+     * 碳水化合物
+     */
+    carbohydrate?: number;
+
+    /**
+     * 热能
+     */
+    heatEnergy?: number;
+
+    /**
+     * 蛋白质
+     */
+    protein?: number;
+
+    /**
+     * 脂肪
+     */
+    fat?: number;
+
+    /**
+     * 钙
+     */
+    ca?: number;
+
+    /**
+     * 磷
+     */
+    p?: number;
+
+    /**
+     * 钾
+     */
+    k?: number;
+
+    /**
+     * 钠
+     */
+    na?: number;
+
+    /**
+     * 镁
+     */
+    mg?: number;
+
+    /**
+     * 氯
+     */
+    cl?: number;
+
+    /**
+     * 铁
+     */
+    fe?: number;
+
+    /**
+     * 锌
+     */
+    zn?: number;
+
+    /**
+     * 硒
+     */
+    se?: number;
+
+    /**
+     * 铜
+     */
+    cu?: number;
+
+    /**
+     * 锰
+     */
+    mn?: number;
+
+    /**
+     * 碘
+     */
+    i?: number;
+
+    /**
+     * 氟
+     */
+    f?: number;
+
+    /**
+     * 铬
+     */
+    cr?: number;
+
+    /**
+     * 钼
+     */
+    mo?: number;
+
+    /**
+     * 异亮氨酸
+     */
+    isoleucine?: number;
+
+    /**
+     * 色氨酸
+     */
+    tryptophan?: number;
+
+    /**
+     * 含硫氨基酸
+     */
+    sulfurAminoAcid?: string | number;
+
+    /**
+     * 组氨酸
+     */
+    histidine?: string | number;
+
+    /**
+     * 芳香族氨基酸
+     */
+    aromaticAminoAcid?: string | number;
+
+    /**
+     * 谷氨酸
+     */
+    glutamicAcid?: string | number;
+
+    /**
+     * 苏氨酸
+     */
+    threonine?: number;
+
+    /**
+     * 丝氨酸
+     */
+    serine?: number;
+
+    /**
+     * 精氨酸
+     */
+    arginine?: number;
+
+    /**
+     * 赖氨酸
+     */
+    lysine?: number;
+
+    /**
+     * 天冬氨酸
+     */
+    asparticAcid?: string | number;
+
+    /**
+     * 胱氨酸
+     */
+    cysteine?: number;
+
+    /**
+     * 脯氨酸
+     */
+    proline?: number;
+
+    /**
+     * 酪氨酸
+     */
+    tyrosine?: number;
+
+    /**
+     * 亮氨酸
+     */
+    leucine?: number;
+
+    /**
+     * 缬氨酸
+     */
+    valine?: number;
+
+    /**
+     * 蛋氨酸
+     */
+    methionine?: number;
+
+    /**
+     * 丙氨酸
+     */
+    alanine?: number;
+
+    /**
+     * 苯丙氨酸
+     */
+    phenylalanine?: number;
+
+    /**
+     * 甘氨酸
+     */
+    glycine?: number;
+
+    /**
+     * 脂肪酸
+     */
+    fattyAcid?: string | number;
+
+    /**
+     * 饱和脂肪酸
+     */
+    saturatedFattyAcid?: string | number;
+
+    /**
+     * 单不饱和脂肪酸
+     */
+    monounsaturatedFattyAcid?: string | number;
+
+    /**
+     * 多不饱和脂肪酸
+     */
+    polyunsaturatedFattyAcid?: string | number;
+
+    /**
+     * 维生素A
+     */
+    vitaminA?: number;
+
+    /**
+     * 维生素A(胡萝卜素)
+     */
+    vitaminACarotene?: number;
+
+    /**
+     * 维生素A醇
+     */
+    vitaminAAlcohol?: number;
+
+    /**
+     * 维生素D
+     */
+    vitaminD?: number;
+
+    /**
+     * 维生素E
+     */
+    vitaminE?: number;
+
+    /**
+     * 维生素E(生育酚)
+     */
+    vitaminETocopherol?: number;
+
+    /**
+     * 维生素K
+     */
+    vitaminK?: number;
+
+    /**
+     * 维生素B1
+     */
+    vitaminBOne?: number;
+
+    /**
+     * 维生素B2
+     */
+    vitaminBTwo?: number;
+
+    /**
+     * 维生素B6
+     */
+    vitaminBSix?: number;
+
+    /**
+     * 维生素B12
+     */
+    vitaminBTwelve?: number;
+
+    /**
+     * 烟酸(尼克酸)
+     */
+    niacin?: number;
+
+    /**
+     * 维生素C
+     */
+    vitaminC?: number;
+
+    /**
+     * 叶酸
+     */
+    folicAcid?: string | number;
+
+    /**
+     * 胆碱
+     */
+    choline?: number;
+
+    /**
+     * 生物素
+     */
+    biotin?: number;
+
+    /**
+     * 泛酸
+     */
+    pantothenicAcid?: string | number;
+
+    /**
+     * 胆固醇
+     */
+    cholesterol?: number;
+
+    /**
+     * 血糖生成指数
+     */
+    bloodGlucoseIndex?: number;
+
+    /**
+     * 不可溶性膳食纤维
+     */
+    insolubleDietaryFiber?: number;
+
+    /**
+     * 膳食纤维
+     */
+    dietaryFiber?: number;
+
+    /**
+     * 灰分
+     */
+    ash?: number;
+
+    /**
+     * 可溶性膳食纤维
+     */
+    solubleDietaryFiber?: number;
+
+    /**
+     * 适用人群
+     */
+    applicableCrowd?: string;
+
+    /**
+     * 不适用人群
+     */
+    unsuitableCrowd?: string;
+
+    /**
+     * 渗透压
+     */
+    osmoticPressure?: number;
+
+    /**
+     * 原料
+     */
+    rawMaterial?: string;
+
+    /**
+     * 适应症及禁忌
+     */
+    indicationsContraindications?: string;
+
+    /**
+     * 食用方法和食用量
+     */
+    usageAndDosage?: string;
+
+    /**
+     * 产品特点
+     */
+    productFeatures?: string;
+
+    /**
+     * 储存条件
+     */
+    storageConditions?: string;
+
+    /**
+     * 警示说明及注意事项
+     */
+    warningInstructions?: string;
+
+    /**
+     * 商品附件
+     */
+    productAttachments?: string;
+
+    /**
+     * 状态(1:启用 0:禁用)
+     */
+    status?: number;
+
+    /**
+     * 上架 
+     */
+    putFlag?: string;
+
+    /**
+     * 出库文号
+     */
+    outboundNumber?: string;
+
+    /**
+     * 水分
+     */
+    moisture?: number;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/warehouse/suppliesCategory/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { CategoryVO, CategoryForm, CategoryQuery } from '@/api/warehouse/suppliesCategory/types';
+
+/**
+ * 查询耗材分类列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listSuppliesCategory = (query?: CategoryQuery): AxiosPromise<CategoryVO[]> => {
+  return request({
+    url: '/warehouse/supplies/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询耗材分类详细
+ * @param categoryId
+ */
+export const getSuppliesCategory = (categoryId: string | number): AxiosPromise<CategoryVO> => {
+  return request({
+    url: '/warehouse/supplies/' + categoryId,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增耗材分类
+ * @param data
+ */
+export const addSuppliesCategory = (data: CategoryForm) => {
+  return request({
+    url: '/warehouse/supplies',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改耗材分类
+ * @param data
+ */
+export const updateSuppliesCategory = (data: CategoryForm) => {
+  return request({
+    url: '/warehouse/supplies',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除耗材分类
+ * @param categoryId
+ */
+export const delSuppliesCategory = (categoryId: string | number | Array<string | number>) => {
+  return request({
+    url: '/warehouse/supplies/' + categoryId,
+    method: 'delete'
+  });
+};

+ 71 - 0
src/api/warehouse/suppliesCategory/types.ts

@@ -0,0 +1,71 @@
+export interface CategoryVO {
+  /**
+   * 耗材分类ID
+   */
+  categoryId: string | number;
+
+  /**
+   * 父耗材分类id
+   */
+  parentId: string | number;
+
+  /**
+   * 耗材分类名称
+   */
+  categoryName: string;
+
+  /**
+   * 显示顺序
+   */
+  orderNum: number;
+
+}
+
+export interface CategoryForm extends BaseEntity {
+  /**
+   * 耗材分类ID
+   */
+  categoryId?: string | number;
+
+  /**
+   * 父耗材分类id
+   */
+  parentId?: string | number;
+
+  /**
+   * 耗材分类名称
+   */
+  categoryName?: string;
+
+  /**
+   * 显示顺序
+   */
+  orderNum?: number;
+
+}
+
+export interface CategoryQuery extends PageQuery {
+
+  /**
+   * 父耗材分类id
+   */
+  parentId?: string | number;
+
+  /**
+   * 耗材分类名称
+   */
+  categoryName?: string;
+
+  /**
+   * 显示顺序
+   */
+  orderNum?: number;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/workbench/treatmentUser/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { TreatmentUserVo, TreatmentUserForm, TreatmentUserQuery } from '@/api/workbench/treatmentUser/types';
+
+/**
+ * 查询待诊患者列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listTreatmentUser = (query?: TreatmentUserQuery): AxiosPromise<TreatmentUserVo[]> => {
+    return request({
+        url: '/workbench/treatmentUser/list',
+        method: 'get',
+        params: query
+    });
+};
+
+/**
+ * 查询待诊患者详细
+ * @param id
+ */
+export const getTreatmentUser = (id: string | number): AxiosPromise<TreatmentUserVo> => {
+    return request({
+        url: '/workbench/treatmentUser/' + id,
+        method: 'get'
+    });
+};
+
+/**
+ * 新增待诊患者
+ * @param data
+ */
+export const addTreatmentUser = (data: TreatmentUserForm) => {
+    return request({
+        url: '/workbench/treatmentUser',
+        method: 'post',
+        data: data
+    });
+};
+
+/**
+ * 修改待诊患者
+ * @param data
+ */
+export const updateTreatmentUser = (data: TreatmentUserForm) => {
+    return request({
+        url: '/workbench/treatmentUser',
+        method: 'put',
+        data: data
+    });
+};
+
+/**
+ * 删除待诊患者
+ * @param id
+ */
+export const delTreatmentUser = (id: string | number | Array<string | number>) => {
+    return request({
+        url: '/workbench/treatmentUser/' + id,
+        method: 'delete'
+    });
+};

+ 296 - 0
src/api/workbench/treatmentUser/types.ts

@@ -0,0 +1,296 @@
+export interface TreatmentUserVo {
+  /**
+   * 
+   */
+  id: string | number;
+
+  /**
+   * 看诊类型
+   */
+  type: string;
+
+  /**
+   * 诊疗卡号
+   */
+  treatNum: string;
+
+  /**
+   * 门诊号
+   */
+  outpatientNo: string;
+
+  /**
+   * 科室
+   */
+  doorId: string | number;
+
+  /**
+   * 姓名
+   */
+  treatName: string;
+
+  /**
+   * 出生日期
+   */
+  birthday: string;
+
+  /**
+   * 联系电话
+   */
+  phoneNum: string;
+
+  /**
+   * 性别 
+   */
+  sex: string;
+
+  /**
+   * 身份证号
+   */
+  idCard: string | number;
+
+  /**
+   * 年龄
+   */
+  age: string;
+
+  /**
+   * 身高
+   */
+  height: string;
+
+  /**
+   * 体重
+   */
+  weight: string;
+
+  /**
+   * 过敏食物
+   */
+  allergyFoot: string;
+
+  /**
+   * 过敏药物
+   */
+  allergyDrug: string;
+
+  /**
+   * 体力活动
+   */
+  activity: string;
+
+  /**
+   * 床号
+   */
+  bedNo: string;
+
+  /**
+   * 病区
+   */
+  inpatientWard: string;
+
+  /**
+   * 入院时间
+   */
+  admissionDate: string;
+
+}
+
+export interface TreatmentUserForm extends BaseEntity {
+ /**
+   * 
+   */
+  id?: string | number;
+
+  /**
+   * 看诊类型
+   */
+  type?: string;
+
+  /**
+   * 诊疗卡号
+   */
+  treatNum?: string;
+
+  /**
+   * 门诊号
+   */
+  outpatientNo?: string;
+
+  /**
+   * 科室
+   */
+  doorId?: string | number;
+
+  /**
+   * 姓名
+   */
+  treatName?: string;
+
+  /**
+   * 出生日期
+   */
+  birthday?: string;
+
+  /**
+   * 联系电话
+   */
+  phoneNum?: string;
+
+  /**
+   * 性别 
+   */
+  sex?: string;
+
+  /**
+   * 身份证号
+   */
+  idCard?: string | number;
+
+  /**
+   * 年龄
+   */
+  age?: string;
+
+  /**
+   * 身高
+   */
+  height?: string;
+
+  /**
+   * 体重
+   */
+  weight?: string;
+
+  /**
+   * 过敏食物
+   */
+  allergyFoot?: string;
+
+  /**
+   * 过敏药物
+   */
+  allergyDrug?: string;
+
+  /**
+   * 体力活动
+   */
+  activity?: string;
+
+  /**
+   * 床号
+   */
+  bedNo?: string;
+
+  /**
+   * 病区
+   */
+  inpatientWard?: string;
+
+  /**
+   * 入院时间
+   */
+  admissionDate?: string;
+
+}
+
+export interface TreatmentUserQuery extends PageQuery {
+
+ /**
+   * 看诊类型
+   */
+  type?: string;
+
+  /**
+   * 诊疗卡号
+   */
+  treatNum?: string;
+
+  /**
+   * 门诊号
+   */
+  outpatientNo?: string;
+
+  /**
+   * 科室
+   */
+  doorId?: string | number;
+
+  /**
+   * 姓名
+   */
+  treatName?: string;
+
+  /**
+   * 出生日期
+   */
+  birthday?: string;
+
+  /**
+   * 联系电话
+   */
+  phoneNum?: string;
+
+  /**
+   * 性别 
+   */
+  sex?: string;
+
+  /**
+   * 身份证号
+   */
+  idCard?: string | number;
+
+  /**
+   * 年龄
+   */
+  age?: string;
+
+  /**
+   * 身高
+   */
+  height?: string;
+
+  /**
+   * 体重
+   */
+  weight?: string;
+
+  /**
+   * 过敏食物
+   */
+  allergyFoot?: string;
+
+  /**
+   * 过敏药物
+   */
+  allergyDrug?: string;
+
+  /**
+   * 体力活动
+   */
+  activity?: string;
+
+  /**
+   * 床号
+   */
+  bedNo?: string;
+
+  /**
+   * 病区
+   */
+  inpatientWard?: string;
+
+  /**
+   * 入院时间
+   */
+  admissionDate?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

BIN
src/assets/images/empty.png


+ 50 - 0
src/utils/tree.ts

@@ -0,0 +1,50 @@
+import type { CategoryVO } from '@/api/warehouse/productCategory/types';
+
+interface TreeNode extends CategoryVO {
+  children?: TreeNode[];
+}
+
+/**
+ * 构造树型结构数据
+ * @param {Array} data 数据源
+ * @param {string} id id字段 默认 'id'
+ * @param {string} parentId 父节点字段 默认 'parentId'
+ * @param {string} children 孩子节点字段 默认 'children'
+ */
+export const handleTree = (data: TreeNode[], id = 'id', parentId = 'parentId', children = 'children'): TreeNode[] => {
+  const config = {
+    id,
+    parentId,
+    children
+  };
+
+  const childrenListMap = new Map();
+  const nodeIds = new Set();
+  const tree: TreeNode[] = [];
+
+  for (const item of data) {
+    const pId = item[config.parentId];
+    if (childrenListMap.has(pId)) {
+      childrenListMap.get(pId).push(item);
+    } else {
+      childrenListMap.set(pId, [item]);
+    }
+    nodeIds.add(item[config.id]);
+  }
+
+  for (const item of data) {
+    if (!nodeIds.has(item[config.parentId])) {
+      tree.push(item);
+    }
+  }
+
+  for (const [, children] of childrenListMap) {
+    for (const node of children) {
+      if (childrenListMap.has(node[config.id])) {
+        node[config.children] = childrenListMap.get(node[config.id]);
+      }
+    }
+  }
+
+  return tree;
+} 

+ 1 - 1
src/views/system/dict/data.vue

@@ -169,7 +169,7 @@ const initFormData: DictDataForm = {
   dictLabel: '',
   dictValue: '',
   cssClass: '',
-  listClass: 'primary',
+  listClass: 'default',
   dictSort: 0,
   remark: ''
 };

+ 192 - 209
src/views/system/user/index.vue

@@ -142,16 +142,10 @@
             </el-table-column>
           </el-table>
 
-          <pagination
-            v-show="total > 0"
-            v-model:page="queryParams.pageNum"
-            v-model:limit="queryParams.pageSize"
-            :total="total"
-            @pagination="getList"
-          />
-        </el-card>
-      </el-col>
-    </el-row>
+                    <pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
+                </el-card>
+            </el-col>
+        </el-row>
 
     <!-- 添加或修改用户配置对话框 -->
     <el-dialog ref="formDialogRef" v-model="dialog.visible" :title="dialog.title" width="800px" append-to-body @close="closeDialog">
@@ -334,40 +328,30 @@
       </template>
     </el-dialog>
 
-    <!-- 用户导入对话框 -->
-    <el-dialog v-model="upload.open" :title="upload.title" width="400px" append-to-body>
-      <el-upload
-        ref="uploadRef"
-        :limit="1"
-        accept=".xlsx, .xls"
-        :headers="upload.headers"
-        :action="upload.url + '?updateSupport=' + upload.updateSupport"
-        :disabled="upload.isUploading"
-        :on-progress="handleFileUploadProgress"
-        :on-success="handleFileSuccess"
-        :auto-upload="false"
-        drag
-      >
-        <el-icon class="el-icon--upload">
-          <i-ep-upload-filled />
-        </el-icon>
-        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
-        <template #tip>
-          <div class="text-center el-upload__tip">
-            <div class="el-upload__tip"><el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据</div>
-            <span>仅允许导入xls、xlsx格式文件。</span>
-            <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link>
-          </div>
-        </template>
-      </el-upload>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button type="primary" @click="submitFileForm">确 定</el-button>
-          <el-button @click="upload.open = false">取 消</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
+        <!-- 用户导入对话框 -->
+        <el-dialog v-model="upload.open" :title="upload.title" width="400px" append-to-body>
+            <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
+                <el-icon class="el-icon--upload">
+                    <i-ep-upload-filled />
+                </el-icon>
+                <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+                <template #tip>
+                    <div class="text-center el-upload__tip">
+                        <div class="el-upload__tip">
+                            <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据</div>
+                        <span>仅允许导入xls、xlsx格式文件。</span>
+                        <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link>
+                    </div>
+                </template>
+            </el-upload>
+            <template #footer>
+                <div class="dialog-footer">
+                    <el-button type="primary" @click="submitFileForm">确 定</el-button>
+                    <el-button @click="upload.open = false">取 消</el-button>
+                </div>
+            </template>
+        </el-dialog>
+    </div>
 </template>
 
 <script setup name="User" lang="ts">
@@ -428,11 +412,11 @@ const columns = ref<FieldOption[]>([
   { key: 6, label: `创建时间`, visible: true, children: [] }
 ]);
 
-const deptTreeRef = ref<ElTreeInstance>();
-const queryFormRef = ref<ElFormInstance>();
-const userFormRef = ref<ElFormInstance>();
-const uploadRef = ref<ElUploadInstance>();
-const formDialogRef = ref<ElDialogInstance>();
+    const deptTreeRef = ref < ElTreeInstance > ();
+    const queryFormRef = ref < ElFormInstance > ();
+    const userFormRef = ref < ElFormInstance > ();
+    const uploadRef = ref < ElUploadInstance > ();
+    const formDialogRef = ref < ElDialogInstance > ();
 
 const dialog = reactive<DialogOption>({
   visible: false,
@@ -440,20 +424,20 @@ const dialog = reactive<DialogOption>({
   title: ''
 });
 
-const initFormData: UserForm = {
-  userId: undefined,
-  deptId: undefined,
-  userName: '',
-  nickName: undefined,
-  password: '',
-  phonenumber: undefined,
-  email: undefined,
-  sex: undefined,
-  status: '0',
-  remark: '',
-  postIds: [],
-  roleIds: []
-};
+    const initFormData: UserForm = {
+        userId: undefined,
+        deptId: undefined,
+        userName: '',
+        nickName: undefined,
+        password: '',
+        phonenumber: undefined,
+        email: undefined,
+        sex: undefined,
+        status: '0',
+        remark: '',
+        postIds: [],
+        roleIds: []
+    };
 
 const initData: PageData<UserForm, UserQuery> = {
   form: { ...initFormData },
@@ -505,7 +489,7 @@ const initData: PageData<UserForm, UserQuery> = {
 };
 const data = reactive<PageData<UserForm, UserQuery>>(initData);
 
-const { queryParams, form, rules } = toRefs<PageData<UserForm, UserQuery>>(data);
+    const { queryParams, form, rules } = toRefs < PageData < UserForm, UserQuery >> (data);
 
 /** 通过条件过滤节点  */
 const filterNode = (value: string, data: any) => {
@@ -524,14 +508,14 @@ watchEffect(
 
 
 
-/** 查询用户列表 */
-const getList = async () => {
-  loading.value = true;
-  const res = await api.listUser(proxy?.addDateRange(queryParams.value, dateRange.value));
-  loading.value = false;
-  userList.value = res.rows;
-  total.value = res.total;
-};
+    /** 查询用户列表 */
+    const getList = async () => {
+        loading.value = true;
+        const res = await api.listUser(proxy ?.addDateRange(queryParams.value, dateRange.value));
+        loading.value = false;
+        userList.value = res.rows;
+        total.value = res.total;
+    };
 
 /** 查询科室下拉树结构 */
 const getDeptTree = async () => {
@@ -555,11 +539,11 @@ const filterDisabledDept = (deptList: DeptTreeVO[]) => {
   });
 };
 
-/** 节点单击事件 */
-const handleNodeClick = (data: DeptVO) => {
-  queryParams.value.deptId = data.id;
-  handleQuery();
-};
+    /** 节点单击事件 */
+    const handleNodeClick = (data: DeptVO) => {
+        queryParams.value.deptId = data.id;
+        handleQuery();
+    };
 
 /** 搜索按钮操作 */
 const handleQuery = () => {
@@ -592,113 +576,112 @@ const resetQuery = () => {
   handleQuery();
 };
 
-/** 删除按钮操作 */
-const handleDelete = async (row?: UserVO) => {
-  const userIds = row?.userId || ids.value;
-  const [err] = await to(proxy?.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?') as any);
-  if (!err) {
-    await api.delUser(userIds);
-    await getList();
-    proxy?.$modal.msgSuccess('删除成功');
-  }
-};
-
-/** 用户状态修改  */
-const handleStatusChange = async (row: UserVO) => {
-  const text = row.status === '0' ? '启用' : '停用';
-  try {
-    await proxy?.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?');
-    await api.changeUserStatus(row.userId, row.status);
-    proxy?.$modal.msgSuccess(text + '成功');
-  } catch (err) {
-    row.status = row.status === '0' ? '1' : '0';
-  }
-};
-/** 跳转角色分配 */
-const handleAuthRole = (row: UserVO) => {
-  const userId = row.userId;
-  router.push('/system/user-auth/role/' + userId);
-};
-
-/** 重置密码按钮操作 */
-const handleResetPwd = async (row: UserVO) => {
-  const [err, res] = await to(
-    ElMessageBox.prompt('请输入"' + row.userName + '"的新密码', '提示', {
-      confirmButtonText: '确定',
-      cancelButtonText: '取消',
-      closeOnClickModal: false,
-      inputPattern: /^.{5,20}$/,
-      inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
-      inputValidator: (value) => {
-        if (/<|>|"|'|\||\\/.test(value)) {
-          return '不能包含非法字符:< > " \' \\ |';
+    /** 删除按钮操作 */
+    const handleDelete = async (row ? : UserVO) => {
+        const userIds = row ?.userId || ids.value;
+        const [err] = await to(proxy ?.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?') as any);
+        if (!err) {
+            await api.delUser(userIds);
+            await getList();
+            proxy ?.$modal.msgSuccess('删除成功');
         }
-      }
-    })
-  );
-  if (!err && res) {
-    await api.resetUserPwd(row.userId, res.value);
-    proxy?.$modal.msgSuccess('修改成功,新密码是:' + res.value);
-  }
-};
-
-/** 选择条数  */
-const handleSelectionChange = (selection: UserVO[]) => {
-  ids.value = selection.map((item) => item.userId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-};
-
-/** 导入按钮操作 */
-const handleImport = () => {
-  upload.title = '用户导入';
-  upload.open = true;
-};
-/** 导出按钮操作 */
-const handleExport = () => {
-  proxy?.download(
-    'system/user/export',
-    {
-      ...queryParams.value
-    },
-    `user_${new Date().getTime()}.xlsx`
-  );
-};
-/** 下载模板操作 */
-const importTemplate = () => {
-  proxy?.download('system/user/importTemplate', {}, `user_template_${new Date().getTime()}.xlsx`);
-};
-
-/**文件上传中处理 */
-const handleFileUploadProgress = () => {
-  upload.isUploading = true;
-};
-/** 文件上传成功处理 */
-const handleFileSuccess = (response: any, file: UploadFile) => {
-  upload.open = false;
-  upload.isUploading = false;
-  uploadRef.value?.handleRemove(file);
-  ElMessageBox.alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + '</div>', '导入结果', {
-    dangerouslyUseHTMLString: true
-  });
-  getList();
-};
-
-/** 提交上传文件 */
-function submitFileForm() {
-  uploadRef.value?.submit();
-}
+    };
+
+    /** 用户状态修改  */
+    const handleStatusChange = async (row: UserVO) => {
+        const text = row.status === '0' ? '启用' : '停用';
+        try {
+            await proxy ?.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?');
+            await api.changeUserStatus(row.userId, row.status);
+            proxy ?.$modal.msgSuccess(text + '成功');
+        } catch (err) {
+            row.status = row.status === '0' ? '1' : '0';
+        }
+    };
+    /** 跳转角色分配 */
+    const handleAuthRole = (row: UserVO) => {
+        const userId = row.userId;
+        router.push('/system/user-auth/role/' + userId);
+    };
+
+    /** 重置密码按钮操作 */
+    const handleResetPwd = async (row: UserVO) => {
+        const [err, res] = await to(
+            ElMessageBox.prompt('请输入"' + row.userName + '"的新密码', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                closeOnClickModal: false,
+                inputPattern: /^.{5,20}$/,
+                inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
+                inputValidator: (value) => {
+                    if (/<|>|"|'|\||\\/.test(value)) {
+                        return '不能包含非法字符:< > " \' \\ |';
+                    }
+                }
+            })
+        );
+        if (!err && res) {
+            await api.resetUserPwd(row.userId, res.value);
+            proxy ?.$modal.msgSuccess('修改成功,新密码是:' + res.value);
+        }
+    };
+
+    /** 选择条数  */
+    const handleSelectionChange = (selection: UserVO[]) => {
+        ids.value = selection.map((item) => item.userId);
+        single.value = selection.length != 1;
+        multiple.value = !selection.length;
+    };
+
+    /** 导入按钮操作 */
+    const handleImport = () => {
+        upload.title = '用户导入';
+        upload.open = true;
+    };
+    /** 导出按钮操作 */
+    const handleExport = () => {
+        proxy ?.download(
+            'system/user/export', {
+                ...queryParams.value
+            },
+            `user_${new Date().getTime()}.xlsx`
+        );
+    };
+    /** 下载模板操作 */
+    const importTemplate = () => {
+        proxy ?.download('system/user/importTemplate', {}, `user_template_${new Date().getTime()}.xlsx`);
+    };
+
+    /**文件上传中处理 */
+    const handleFileUploadProgress = () => {
+        upload.isUploading = true;
+    };
+    /** 文件上传成功处理 */
+    const handleFileSuccess = (response: any, file: UploadFile) => {
+        upload.open = false;
+        upload.isUploading = false;
+        uploadRef.value ?.handleRemove(file);
+        ElMessageBox.alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + '</div>', '导入结果', {
+            dangerouslyUseHTMLString: true
+        });
+        getList();
+    };
+
+    /** 提交上传文件 */
+    function submitFileForm() {
+        uploadRef.value ?.submit();
+    }
 
-/** 重置操作表单 */
-const reset = () => {
-  form.value = { ...initFormData };
-  userFormRef.value?.resetFields();
-};
-/** 取消按钮 */
-const cancel = () => {
-  dialog.visible = false;
-  reset();
-};
+    /** 重置操作表单 */
+    const reset = () => {
+        form.value = { ...initFormData };
+        userFormRef.value ?.resetFields();
+    };
+    /** 取消按钮 */
+    const cancel = () => {
+        dialog.visible = false;
+        reset();
+    };
 
 /** 新增按钮操作 */
 const handleAdd = async () => {
@@ -728,32 +711,32 @@ const handleUpdate = async (disabled:boolean,row?: UserForm ) => {
   form.value.password = '';
 };
 
-/** 提交按钮 */
-const submitForm = () => {
-  userFormRef.value?.validate(async (valid: boolean) => {
-    if (valid) {
-      form.value.userId ? await api.updateUser(form.value) : await api.addUser(form.value);
-      proxy?.$modal.msgSuccess('操作成功');
-      dialog.visible = false;
-      await getList();
-    }
-  });
-};
-
-/**
- * 关闭用户弹窗
- */
-const closeDialog = () => {
-  dialog.visible = false;
-  resetForm();
-};
-
-/**
- * 重置表单
- */
-const resetForm = () => {
-  userFormRef.value?.resetFields();
-  userFormRef.value?.clearValidate();
+    /** 提交按钮 */
+    const submitForm = () => {
+        userFormRef.value ?.validate(async (valid: boolean) => {
+            if (valid) {
+                form.value.userId ? await api.updateUser(form.value) : await api.addUser(form.value);
+                proxy ?.$modal.msgSuccess('操作成功');
+                dialog.visible = false;
+                await getList();
+            }
+        });
+    };
+
+    /**
+     * 关闭用户弹窗
+     */
+    const closeDialog = () => {
+        dialog.visible = false;
+        resetForm();
+    };
+
+    /**
+     * 重置表单
+     */
+    const resetForm = () => {
+        userFormRef.value ?.resetFields();
+        userFormRef.value ?.clearValidate();
 
   form.value.id = undefined;
   form.value.status = '1';
@@ -774,4 +757,4 @@ async function handleDeptChange(value: number | string) {
   let dept=deptJson.value[value.toString()]
   form.value.deptCode=dept.deptCategory;  
 }
-</script>
+</script>

+ 1537 - 0
src/views/warehouse/nutriProduct/index.vue

@@ -0,0 +1,1537 @@
+<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="productCategory">
+                            <el-cascader v-model="queryParams.productCategoryList" :options="categoryOptions" :props="{ checkStrictly: false, emitPath: true, value: 'value', label: 'label', children: 'children' }" placeholder="请选择" clearable filterable style="width: 200px" />
+                        </el-form-item>
+                        <el-form-item>
+                            <el-input v-model="queryParams.productName" placeholder="请输入名称/编码" clearable @keyup.enter="handleQuery" />
+                        </el-form-item>
+                        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+                        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+                    </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="['warehouse:nutrition:add']">新增营养产品</el-button>
+                    </el-col>
+                    <!-- <el-col :span="1.5">
+                        <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['warehouse:nutrition:edit']">修改</el-button>
+                    </el-col>
+                    <el-col :span="1.5">
+                        <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['warehouse:nutrition:remove']">删除</el-button>
+                    </el-col> -->
+                    <el-col :span="1.5">
+                        <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['warehouse:nutrition: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="nutritionList" @selection-change="handleSelectionChange">
+                <el-table-column type="selection" width="55" align="center" />
+                <el-table-column label="产品名称" align="center" prop="productName" />
+                <el-table-column label="商品编码" align="center" prop="productCode" />
+                <el-table-column label="产品分类" align="center">
+                    <template #default="{ row }">
+                        {{ getCategoryName(row.productCategory) }}
+                    </template>
+                </el-table-column>
+                <el-table-column label="规格" align="center" prop="productSpec" />
+                <el-table-column label="剂型/形态" align="center">
+                    <template #default="{ row }">
+                        {{ dosage_form.find(item => item.value === row.dosageForm)?.label || row.dosageForm }}
+                    </template>
+                </el-table-column>
+                <el-table-column label="许可证临期提醒" align="center" prop="productLicenseExpiry" width="180">
+                    <template #default="scope">
+                        <span>{{ scope.row.productLicenseExpiry ? parseTime(scope.row.productLicenseExpiry, '{y}-{m}-{d}') : '--' }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="保质期临期提醒" align="center" prop="shelfLife" width="180">
+                    <template #default="scope">
+                        <span>{{ scope.row.shelfLife || '--' }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="上架状态" align="center" prop="putFlag" width="100">
+                    <template #default="{ row }">
+                        {{ put_flag.find(item => item.value === row.putFlag)?.label || row.putFlag }}
+                    </template>
+                </el-table-column>
+                <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
+                    <template #default="scope">
+                        <el-button v-if="scope.row.putFlag === '1'" link type="danger" @click="handlePutFlag(scope.row, '0')">下架</el-button>
+                        <el-button v-else link type="success" @click="handlePutFlag(scope.row, '1')">上架</el-button>
+                        <el-button link type="primary" @click="handleDetail(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="dialog.title" v-model="dialog.visible" width="70%" append-to-body class="nutrition-dialog">
+            <el-tabs v-model="activeTab">
+                <el-scrollbar height="calc(70vh - 120px)">
+                    <el-tab-pane label="基本信息" name="basic">
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px">
+                            <el-divider content-position="left">基本信息:</el-divider>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="产品名称:" prop="productName">
+                                        <el-input v-model="form.productName" placeholder="请输入" />
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="商品资质:" prop="productQualification">
+                                        <el-select v-model="form.productQualification" placeholder="请选择" clearable>
+                                            <el-option v-for="dict in product_qualification" :key="dict.value" :label="dict.label" :value="dict.value" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="院方系统编码:" prop="hospitalSystemCode">
+                                        <el-input v-model="form.hospitalSystemCode" placeholder="请输入" />
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="批准文号:" prop="approvalNumber">
+                                        <el-input v-model="form.approvalNumber" placeholder="请输入" />
+                                    </el-form-item>
+                                </el-col>
+
+                            </el-row>
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="商品编码:" prop="productCode">
+                                        <el-input v-model="form.productCode" placeholder="请输入" />
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="口味:" prop="taste">
+                                        <el-input v-model="form.taste" placeholder="请输入" />
+                                    </el-form-item>
+                                </el-col>
+
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="产品所属分类:" prop="productCategory">
+                                        <el-cascader v-model="form.productCategoryList" :options="categoryOptions" :props="{ checkStrictly: false, emitPath: true, value: 'value', label: 'label', children: 'children' }" placeholder="请选择" clearable filterable style="width: 100%" />
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="剂型/形态:" prop="dosageForm">
+                                        <el-select v-model="form.dosageForm" placeholder="请选择" clearable>
+                                            <el-option v-for="dict in dosage_form" :key="dict.value" :label="dict.label" :value="dict.value" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="生产厂商:" prop="manufacturer">
+                                        <el-select v-model="form.manufacturer" placeholder="请选择">
+                                            <el-option label="请选择" value="" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="供应商:" prop="supplier">
+                                        <el-select v-model="form.supplier" placeholder="请选择" clearable>
+                                            <el-option v-for="dict in product_supplier" :key="dict.value" :label="dict.label" :value="dict.value" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="品牌:" prop="brand">
+                                        <el-input v-model="form.brand" placeholder="请输入" />
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="产品适用科室:" prop="applicableDepartment">
+                                        <el-select v-model="form.applicableDepartment" placeholder="请选择">
+                                            <el-option label="请选择" value="" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="产品所属标签:" prop="productLabel">
+                                        <el-select v-model="form.productLabel" placeholder="请选择">
+                                            <el-option label="请选择" value="" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="禁忌症所属标签:" prop="contraindicationLabel">
+                                        <el-select v-model="form.contraindicationLabel" placeholder="请选择">
+                                            <el-option label="请选择" value="" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="许可证临期提醒:" prop="licenseExpiryReminder">
+                                        <el-input v-model="form.licenseExpiryReminder" placeholder="请输入">
+                                            <template #append>个月</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="保质期临期提醒:" prop="shelfLifeReminder">
+                                        <el-input v-model="form.shelfLifeReminder" placeholder="请输入">
+                                            <template #append>个月</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="商品许可证有效期至:" prop="productLicenseExpiry">
+                                        <el-date-picker v-model="form.productLicenseExpiry" type="date" placeholder="请选择" value-format="YYYY-MM-DD" />
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="保质期:" prop="shelfLife">
+                                        <el-input v-model="form.shelfLife" placeholder="请输入">
+                                            <template #append>个月</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <!-- 入货配置部分 -->
+                            <el-divider content-position="left">入货信息:</el-divider>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="入货价格:" prop="purchasePrice" required>
+                                        <el-input v-model="form.purchasePrice" placeholder="请输入">
+                                            <template #append>元/盒</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="入货单位:" prop="purchaseUnit" required>
+                                        <el-select v-model="form.purchaseUnit" placeholder="请选择" clearable>
+                                            <el-option v-for="dict in product_package_unit" :key="dict.value" :label="dict.label" :value="dict.value" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="商品规格:" prop="productSpec" required>
+                                        <div style="display: flex; align-items: center;">
+                                            <el-input v-model="form.productSpec" placeholder="请输入" style="width: 500px; border-top-right-radius: 0; border-bottom-right-radius: 0;" :maxlength="10" />
+                                            <el-select v-model="form.productSpecUnit" style="width: 80px; border-radius: 0; border-left: none; border-top-left-radius: 0; border-bottom-left-radius: 0;" :popper-append-to-body="false" size="default" @change="onSpecUnitChange">
+                                                <el-option label="g" value="g" />
+                                                <el-option label="ml" value="ml" />
+                                                <el-option label="mg" value="mg" />
+                                            </el-select>
+                                            <span style="margin-left: 8px; color: #606266; font-size: 14px;">/包</span>
+                                        </div>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="预包装单位:" prop="packageUnit">
+                                        <el-select v-model="form.packageUnit" placeholder="请选择" clearable>
+                                            <el-option v-for="dict in product_package_unit" :key="dict.value" :label="dict.label" :value="dict.value" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                            <el-divider content-position="left">预包装销售设置:</el-divider>
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="预包装销售价:" prop="packagePrice" required>
+                                        <el-input v-model="form.packagePrice" placeholder="请输入">
+                                            <template #append>元/盒</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="最小包装单位:" prop="minUnit">
+                                        <el-select v-model="form.minUnit" placeholder="请选择" clearable>
+                                            <el-option v-for="dict in product_package_unit" :key="dict.value" :label="dict.label" :value="dict.value" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="最小包装规格:" prop="minSpec">
+                                        <el-input v-model="form.minSpec" placeholder="请输入">
+                                            <template #append>g/包</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="净含量/规格:" prop="minUnit">
+                                        <span>--</span>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                            <el-divider content-position="left">配置销售设置::</el-divider>
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="配置销售价格:" prop="configSalePrice" required>
+                                        <el-input v-model="form.configSalePrice" placeholder="请输入">
+                                            <template #append>元/g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="配置损耗率:" prop="configLossRate">
+                                        <el-input v-model="form.configLossRate" placeholder="请输入">
+                                            <template #append>%</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                        </el-form>
+                    </el-tab-pane>
+
+                    <el-tab-pane label="热能及三大营养素" name="nutrition">
+                        <span style="color: red; font-size: 16px; margin-bottom: 20px">注:每100(g/ml) 含量</span>
+
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px">
+                            <el-row :gutter="20" style="margin-top:20px">
+                                <el-col :span="12">
+                                    <el-form-item label="热量:" prop="calorie">
+                                        <el-input v-model="form.calorie" placeholder="请输入">
+                                            <template #append>kcal</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="蛋白质:" prop="protein">
+                                        <el-input v-model="form.protein" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="脂肪:" prop="fat">
+                                        <el-input v-model="form.fat" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="碳水化合物:" prop="carbohydrate">
+                                        <el-input v-model="form.carbohydrate" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="热能:" prop="heatEnergy">
+                                        <el-input v-model="form.heatEnergy" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                        </el-form>
+                    </el-tab-pane>
+
+                    <el-tab-pane label="常量元素" name="macroElements">
+                        <span style="color: red; font-size: 16px; margin-bottom: 10px">注:每100(g/ml) 含量</span>
+
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px">
+                            <el-row :gutter="20" style="margin-top:20px">
+                                <el-col :span="12">
+                                    <el-form-item label="钙:" prop="ca">
+                                        <el-input v-model="form.ca" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="磷:" prop="p">
+                                        <el-input v-model="form.p" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="钾:" prop="k">
+                                        <el-input v-model="form.k" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="钠:" prop="na">
+                                        <el-input v-model="form.na" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="镁:" prop="mg">
+                                        <el-input v-model="form.mg" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="氯:" prop="cl">
+                                        <el-input v-model="form.cl" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                        </el-form>
+                    </el-tab-pane>
+
+                    <el-tab-pane label="微量元素" name="microElements">
+                        <span style="color: red; font-size: 16px; margin-bottom: 10px">注:每100(g/ml) 含量</span>
+
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px">
+                            <el-row :gutter="20" style="margin-top:20px">
+                                <el-col :span="12">
+                                    <el-form-item label="铁:" prop="fe">
+                                        <el-input v-model="form.fe" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="锌:" prop="zn">
+                                        <el-input v-model="form.zn" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="硒:" prop="se">
+                                        <el-input v-model="form.se" placeholder="请输入">
+                                            <template #append>μg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="铜:" prop="cu">
+                                        <el-input v-model="form.cu" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="锰:" prop="mn">
+                                        <el-input v-model="form.mn" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="碘:" prop="i">
+                                        <el-input v-model="form.i" placeholder="请输入">
+                                            <template #append>μg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="氟:" prop="f">
+                                        <el-input v-model="form.f" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="铬:" prop="cr">
+                                        <el-input v-model="form.cr" placeholder="请输入">
+                                            <template #append>μg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="钼:" prop="mo">
+                                        <el-input v-model="form.mo" placeholder="请输入">
+                                            <template #append>μg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                        </el-form>
+                    </el-tab-pane>
+
+                    <el-tab-pane label="氨基酸" name="aminoAcids">
+                        <span style="color: red; font-size: 16px; margin-bottom: 10px">注:每100(g/ml) 含量</span>
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px">
+                            <el-row :gutter="20" style="margin-top:20px">
+                                <el-col :span="12">
+                                    <el-form-item label="异亮氨酸:" prop="isoleucine">
+                                        <el-input v-model="form.isoleucine" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="亮氨酸:" prop="leucine">
+                                        <el-input v-model="form.leucine" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="赖氨酸:" prop="lysine">
+                                        <el-input v-model="form.lysine" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="蛋氨酸:" prop="methionine">
+                                        <el-input v-model="form.methionine" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="苯丙氨酸:" prop="phenylalanine">
+                                        <el-input v-model="form.phenylalanine" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="苏氨酸:" prop="threonine">
+                                        <el-input v-model="form.threonine" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="色氨酸:" prop="tryptophan">
+                                        <el-input v-model="form.tryptophan" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="缬氨酸:" prop="valine">
+                                        <el-input v-model="form.valine" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="组氨酸:" prop="histidine">
+                                        <el-input v-model="form.histidine" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="精氨酸:" prop="arginine">
+                                        <el-input v-model="form.arginine" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                        </el-form>
+                    </el-tab-pane>
+
+                    <el-tab-pane label="脂肪酸" name="fattyAcids">
+                        <span style="color: red; font-size: 16px; margin-bottom: 10px">注:每100(g/ml) 含量</span>
+
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px">
+                            <el-row :gutter="20" style="margin-top:20px">
+                                <el-col :span="12">
+                                    <el-form-item label="饱和脂肪酸:" prop="saturatedFattyAcid">
+                                        <el-input v-model="form.saturatedFattyAcid" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="单不饱和脂肪酸:" prop="monounsaturatedFattyAcid">
+                                        <el-input v-model="form.monounsaturatedFattyAcid" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="多不饱和脂肪酸:" prop="polyunsaturatedFattyAcid">
+                                        <el-input v-model="form.polyunsaturatedFattyAcid" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                        </el-form>
+                    </el-tab-pane>
+
+                    <el-tab-pane label="维生素" name="vitamins">
+                        <span style="color: red; font-size: 16px; margin-bottom: 10px">注:每100(g/ml) 含量</span>
+
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px">
+                            <el-row :gutter="20" style="margin-top:20px">
+                                <el-col :span="12">
+                                    <el-form-item label="维生素A:" prop="vitaminA">
+                                        <el-input v-model="form.vitaminA" placeholder="请输入">
+                                            <template #append>μg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="维生素D:" prop="vitaminD">
+                                        <el-input v-model="form.vitaminD" placeholder="请输入">
+                                            <template #append>μg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="维生素E:" prop="vitaminE">
+                                        <el-input v-model="form.vitaminE" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="维生素K:" prop="vitaminK">
+                                        <el-input v-model="form.vitaminK" placeholder="请输入">
+                                            <template #append>μg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="维生素B1:" prop="vitaminBOne">
+                                        <el-input v-model="form.vitaminBOne" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="维生素B2:" prop="vitaminBTwo">
+                                        <el-input v-model="form.vitaminBTwo" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="维生素B6:" prop="vitaminBSix">
+                                        <el-input v-model="form.vitaminBSix" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="维生素B12:" prop="vitaminBTwelve">
+                                        <el-input v-model="form.vitaminBTwelve" placeholder="请输入">
+                                            <template #append>μg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="维生素C:" prop="vitaminC">
+                                        <el-input v-model="form.vitaminC" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="叶酸:" prop="folicAcid">
+                                        <el-input v-model="form.folicAcid" placeholder="请输入">
+                                            <template #append>μg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                        </el-form>
+                    </el-tab-pane>
+
+                    <el-tab-pane label="脂类" name="lipids">
+                        <span style="color: red; font-size: 16px; margin-bottom: 10px">注:每100(g/ml) 含量</span>
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px">
+                            <el-row :gutter="20" style="margin-top:20px">
+                                <el-col :span="12">
+                                    <el-form-item label="胆固醇:" prop="cholesterol">
+                                        <el-input v-model="form.cholesterol" placeholder="请输入">
+                                            <template #append>mg</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                        </el-form>
+                    </el-tab-pane>
+
+                    <el-tab-pane label="其他" name="others">
+                        <span style="color: red; font-size: 16px; margin-bottom: 10px">注:每100(g/ml) 含量</span>
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px" style="margin-top:20px">
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="膳食纤维:" prop="dietaryFiber">
+                                        <el-input v-model="form.dietaryFiber" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="灰分:" prop="ash">
+                                        <el-input v-model="form.ash" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="不可溶性膳食纤维:" prop="insolubleDietaryFiber">
+                                        <el-input v-model="form.insolubleDietaryFiber" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="可溶性膳食纤维:" prop="solubleDietaryFiber">
+                                        <el-input v-model="form.solubleDietaryFiber" placeholder="请输入">
+                                            <template #append>g</template>
+                                        </el-input>
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+                            <el-row :gutter="20">
+                                <el-col :span="12">
+                                    <el-form-item label="血糖生成指数:" prop="bloodGlucoseIndex">
+                                        <el-input v-model="form.bloodGlucoseIndex" placeholder="请输入" />
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="渗透压:" prop="osmoticPressure">
+                                        <el-input v-model="form.osmoticPressure" placeholder="请输入" />
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+                        </el-form>
+                    </el-tab-pane>
+
+                    <el-tab-pane label="商品说明" name="productDescription">
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px">
+
+                            <el-row :gutter="20" style="margin-top:20px">
+                                <el-col :span="12">
+                                    <el-form-item label="适用人群:" prop="applicableCrowd">
+                                        <el-input v-model="form.applicableCrowd" type="textarea" maxlength="300" show-word-limit :rows="4" placeholder="请输入" />
+                                    </el-form-item>
+                                    <el-form-item label="原料:" prop="storageConditions">
+                                        <el-input v-model="form.storageConditions" type="textarea" maxlength="300" show-word-limit :rows="4" placeholder="请输入" />
+                                    </el-form-item>
+                                    <el-form-item label="食用方法和食用量:" prop="usageAndDosage">
+                                        <el-input v-model="form.usageAndDosage" type="textarea" maxlength="300" show-word-limit :rows="4" placeholder="请输入" />
+                                    </el-form-item>
+                                    <el-form-item label="储存条件:" prop="storageConditions">
+                                        <el-input v-model="form.storageConditions" type="textarea" maxlength="300" show-word-limit :rows="4" placeholder="请输入" />
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="不适用人群:" prop="unsuitableCrowd">
+                                        <el-input v-model="form.unsuitableCrowd" type="textarea" maxlength="300" show-word-limit :rows="4" placeholder="请输入" />
+                                    </el-form-item>
+                                    <el-form-item label="渗透压:" prop="unsuitableCrowd">
+                                        <el-input v-model="form.unsuitableCrowd" type="textarea" maxlength="300" show-word-limit :rows="4" placeholder="请输入" />
+                                    </el-form-item>
+                                    <el-form-item label="适应症及禁忌:" prop="indicationsContraindications">
+                                        <el-input v-model="form.indicationsContraindications" type="textarea" maxlength="300" show-word-limit :rows="4" placeholder="请输入" />
+                                    </el-form-item>
+                                    <el-form-item label="产品特点:" prop="productFeatures">
+                                        <el-input v-model="form.productFeatures" type="textarea" maxlength="300" show-word-limit :rows="4" placeholder="请输入" />
+                                    </el-form-item>
+                                    <el-form-item label="警示说明及注意事项:" prop="warningInstructions">
+                                        <el-input v-model="form.warningInstructions" type="textarea" maxlength="300" show-word-limit :rows="4" placeholder="请输入" />
+                                    </el-form-item>
+                                </el-col>
+                            </el-row>
+
+
+                        </el-form>
+                    </el-tab-pane>
+
+                    <el-tab-pane label="商品附件" name="productAttachments">
+                        <el-form ref="nutritionFormRef" :model="form" :rules="rules" label-width="200px" style="margin-top: 30px">
+                            <el-form-item label="商品附件" prop="productAttachments">
+                                <el-upload class="upload-demo" action="#" :auto-upload="false" :on-change="handleFileChange" :file-list="fileList" multiple>
+                                    <el-button type="primary">选择文件</el-button>
+                                    <template #tip>
+                                        <div class="el-upload__tip">支持上传jpg/png/pdf文件</div>
+                                    </template>
+                                </el-upload>
+                            </el-form-item>
+                        </el-form>
+                    </el-tab-pane>
+                </el-scrollbar>
+            </el-tabs>
+            <template #footer>
+                <div class="dialog-footer" style="text-align: center">
+                    <el-button type="primary" @click="submitForm">保存</el-button>
+                    <el-button type="primary" @click="submitFormAndPutaway">保存并上架</el-button>
+                </div>
+            </template>
+        </el-dialog>
+        <!-- 新增详情弹窗,内容全部静态分组展示,仿照a1.png -->
+        <el-dialog title="营养产品详情" v-model="detailDialogVisible" width="60%" append-to-body class="nutrition-dialog">
+            <el-tabs v-model="activeTab">
+                <el-scrollbar height="calc(80vh - 120px)">
+                    <el-tab-pane label="基本信息" name="basic">
+                        <el-divider content-position="left">基本信息:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>产品名称:</b>{{ form.productName || '--' }}</div>
+                                <div><b>院方系统编码:</b>{{ form.hospitalSystemCode || '--' }}</div>
+                                <div><b>商品编码:</b>{{ form.productCode || '--' }}</div>
+                                <div><b>产品所属分类:</b>{{ form.productCategory || '--' }}</div>
+                                <div><b>生产厂商:</b>{{ form.manufacturer || '--' }}</div>
+                                <div><b>品牌:</b>{{ form.brand || '--' }}</div>
+                                <div><b>产品所属标签:</b>{{ form.productLabel || '--' }}</div>
+                                <div><b>许可证临期提醒:</b>{{ form.licenseExpiryReminder || '--' }}</div>
+                                <div><b>商品许可证有效期至:</b>{{ form.productLicenseExpiry || '--' }}</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>商品资质:</b>{{ form.productQualification || '--' }}</div>
+                                <div><b>批准文号:</b>{{ form.approvalNumber || '--' }}</div>
+                                <div><b>口味:</b>{{ form.taste || '--' }}</div>
+                                <div><b>剂型/形态:</b>{{ form.dosageForm || '--' }}</div>
+                                <div><b>供应商:</b>{{ form.supplier || '--' }}</div>
+                                <div><b>产品适用科室:</b>{{ form.applicableDepartment || '--' }}</div>
+                                <div><b>禁忌症所属标签:</b>{{ form.contraindicationLabel || '--' }}</div>
+                                <div><b>保质期临期提醒:</b>{{ form.shelfLifeReminder || '--' }}</div>
+                                <div><b>保质期:</b>{{ form.shelfLife || '--' }}</div>
+                            </el-col>
+                        </el-row>
+                        <el-divider content-position="left">入货信息:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>入货价格:</b>{{ form.purchasePrice || '--' }} 元</div>
+                                <div><b>默认入货单位:</b>{{ form.purchaseUnit || '--' }}</div>
+                                <div><b>商品规格:</b>{{ form.productSpec || '--' }}/{{ form.productSpecUnit || '--' }}</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>入货单位:</b>{{ form.purchaseUnit || '--' }}</div>
+                                <div><b>预包装单位:</b>{{ form.packageUnit || '--' }}</div>
+                            </el-col>
+                        </el-row>
+                        <el-divider content-position="left">预包装销售设置:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>预包装销售价:</b>{{ form.packagePrice || '--' }} 元/袋</div>
+                                <div><b>最小包装规格:</b>{{ form.minSpec || '--' }} g/包</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>最小包装单位:</b>{{ form.minUnit || '--' }}</div>
+                                <div><b>净含量/规格:</b>{{ form.netContent || '--' }}</div>
+                            </el-col>
+                        </el-row>
+                        <el-divider content-position="left">配置销售设置:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>配置销售价格:</b>{{ form.configSalePrice || '--' }} 元/g</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>配置损耗率:</b>{{ form.configLossRate || '--' }} %</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                    <el-tab-pane label="热能及三大营养素" name="nutrition">
+                        <el-divider content-position="left">热能及三大营养素:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>热量:</b>{{ form.calorie || '--' }} kcal</div>
+                                <div><b>脂肪:</b>{{ form.fat || '--' }} g</div>
+                                <div><b>热能:</b>{{ form.heatEnergy || '--' }} g</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>蛋白质:</b>{{ form.protein || '--' }} g</div>
+                                <div><b>碳水化合物:</b>{{ form.carbohydrate || '--' }} g</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                    <el-tab-pane label="常量元素" name="macroElements">
+                        <el-divider content-position="left">常量元素:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>钙:</b>{{ form.ca || '--' }} mg</div>
+                                <div><b>钾:</b>{{ form.k || '--' }} mg</div>
+                                <div><b>镁:</b>{{ form.mg || '--' }} mg</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>磷:</b>{{ form.p || '--' }} mg</div>
+                                <div><b>钠:</b>{{ form.na || '--' }} mg</div>
+                                <div><b>氯:</b>{{ form.cl || '--' }} mg</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                    <el-tab-pane label="微量元素" name="microElements">
+                        <el-divider content-position="left">微量元素:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>铁:</b>{{ form.fe || '--' }} mg</div>
+                                <div><b>硒:</b>{{ form.se || '--' }} μg</div>
+                                <div><b>锰:</b>{{ form.mn || '--' }} mg</div>
+                                <div><b>氟:</b>{{ form.f || '--' }} mg</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>锌:</b>{{ form.zn || '--' }} mg</div>
+                                <div><b>铜:</b>{{ form.cu || '--' }} mg</div>
+                                <div><b>碘:</b>{{ form.i || '--' }} μg</div>
+                                <div><b>铬:</b>{{ form.cr || '--' }} μg</div>
+                            </el-col>
+                        </el-row>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>钼:</b>{{ form.mo || '--' }} μg</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                    <el-tab-pane label="氨基酸" name="aminoAcids">
+                        <el-divider content-position="left">氨基酸:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>异亮氨酸:</b>{{ form.isoleucine || '--' }} mg</div>
+                                <div><b>赖氨酸:</b>{{ form.lysine || '--' }} mg</div>
+                                <div><b>苯丙氨酸:</b>{{ form.phenylalanine || '--' }} mg</div>
+                                <div><b>组氨酸:</b>{{ form.histidine || '--' }} mg</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>亮氨酸:</b>{{ form.leucine || '--' }} mg</div>
+                                <div><b>蛋氨酸:</b>{{ form.methionine || '--' }} mg</div>
+                                <div><b>苏氨酸:</b>{{ form.threonine || '--' }} mg</div>
+                                <div><b>精氨酸:</b>{{ form.arginine || '--' }} mg</div>
+                            </el-col>
+                        </el-row>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>色氨酸:</b>{{ form.tryptophan || '--' }} mg</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>缬氨酸:</b>{{ form.valine || '--' }} mg</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                    <el-tab-pane label="脂肪酸" name="fattyAcids">
+                        <el-divider content-position="left">脂肪酸:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>饱和脂肪酸:</b>{{ form.saturatedFattyAcid || '--' }} g</div>
+                                <div><b>多不饱和脂肪酸:</b>{{ form.polyunsaturatedFattyAcid || '--' }} g</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>单不饱和脂肪酸:</b>{{ form.monounsaturatedFattyAcid || '--' }} g</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                    <el-tab-pane label="维生素" name="vitamins">
+                        <el-divider content-position="left">维生素:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>维生素A:</b>{{ form.vitaminA || '--' }} μg</div>
+                                <div><b>维生素E:</b>{{ form.vitaminE || '--' }} mg</div>
+                                <div><b>维生素B1:</b>{{ form.vitaminBOne || '--' }} mg</div>
+                                <div><b>维生素B6:</b>{{ form.vitaminBSix || '--' }} mg</div>
+                                <div><b>维生素C:</b>{{ form.vitaminC || '--' }} mg</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>维生素D:</b>{{ form.vitaminD || '--' }} μg</div>
+                                <div><b>维生素K:</b>{{ form.vitaminK || '--' }} μg</div>
+                                <div><b>维生素B2:</b>{{ form.vitaminBTwo || '--' }} mg</div>
+                                <div><b>维生素B12:</b>{{ form.vitaminBTwelve || '--' }} μg</div>
+                                <div><b>叶酸:</b>{{ form.folicAcid || '--' }} μg</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                    <el-tab-pane label="脂类" name="lipids">
+                        <el-divider content-position="left">脂类:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>胆固醇:</b>{{ form.cholesterol || '--' }} mg</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                    <el-tab-pane label="其他" name="others">
+                        <el-divider content-position="left">其他:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>膳食纤维:</b>{{ form.dietaryFiber || '--' }} g</div>
+                                <div><b>不可溶性膳食纤维:</b>{{ form.insolubleDietaryFiber || '--' }} g</div>
+                                <div><b>血糖生成指数:</b>{{ form.bloodGlucoseIndex || '--' }}</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>灰分:</b>{{ form.ash || '--' }} g</div>
+                                <div><b>可溶性膳食纤维:</b>{{ form.solubleDietaryFiber || '--' }} g</div>
+                                <div><b>渗透压:</b>{{ form.osmoticPressure || '--' }}</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                    <el-tab-pane label="商品说明" name="productDescription">
+                        <el-divider content-position="left">商品说明:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="12">
+                                <div><b>适用人群:</b>{{ form.applicableCrowd || '--' }}</div>
+                                <div><b>原料:</b>{{ form.rawMaterial || '--' }}</div>
+                                <div><b>食用方法和食用量:</b>{{ form.usageAndDosage || '--' }}</div>
+                                <div><b>储存条件:</b>{{ form.storageConditions || '--' }}</div>
+                            </el-col>
+                            <el-col :span="12">
+                                <div><b>不适用人群:</b>{{ form.unsuitableCrowd || '--' }}</div>
+                                <div><b>适应症及禁忌:</b>{{ form.indicationsContraindications || '--' }}</div>
+                                <div><b>产品特点:</b>{{ form.productFeatures || '--' }}</div>
+                                <div><b>警示说明及注意事项:</b>{{ form.warningInstructions || '--' }}</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                    <el-tab-pane label="商品附件" name="productAttachments">
+                        <el-divider content-position="left">商品附件:</el-divider>
+                        <el-row :gutter="40">
+                            <el-col :span="24">
+                                <div v-if="form.productAttachments && form.productAttachments.length">
+                                    <div v-for="(file, idx) in form.productAttachments" :key="idx">
+                                        <a :href="file.url" target="_blank">{{ file.name }}</a>
+                                    </div>
+                                </div>
+                                <div v-else>--</div>
+                            </el-col>
+                        </el-row>
+                    </el-tab-pane>
+                </el-scrollbar>
+            </el-tabs>
+        </el-dialog>
+    </div>
+</template>
+
+<script setup name="Nutrition" lang="ts">
+    import { listNutrition, getNutrition, delNutrition, addNutrition, updateNutrition } from '@/api/warehouse/productNutrition/index';
+    import { NutritionVO, NutritionQuery, NutritionForm } from '@/api/warehouse/productNutrition/types';
+    import { listCategory } from '@/api/warehouse/productCategory/index';
+
+    import { FormInstance, ElMessageBox, UploadFile, UploadFiles } from 'element-plus';
+    import { getCurrentInstance, ComponentInternalInstance, ref, reactive, toRefs, onMounted } from 'vue';
+    import { log } from 'console';
+
+    const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+    const { product_qualification, dosage_form, product_package_unit, product_supplier, put_flag } = toRefs < any > (proxy ?.useDict('product_qualification', 'dosage_form', 'product_package_unit', 'product_supplier', 'put_flag'));
+
+
+    const nutritionList = ref < NutritionVO[] > ([]);
+    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 activeTab = ref('basic');
+    const fileList = ref < UploadFiles > ([]);
+    const detailDialogVisible = ref(false);
+
+    const treeData = ref([]); // 定义 treeData
+
+    const queryFormRef = ref < FormInstance > ();
+    const nutritionFormRef = ref < FormInstance > ();
+
+    const dialog = reactive < DialogOption > ({
+        visible: false,
+        title: ''
+    });
+
+    const initFormData: NutritionForm = {
+        id: undefined,
+        productName: undefined,
+        hospitalSystemCode: undefined,
+        productCode: undefined,
+        productCategory: undefined,
+        productCategoryList: undefined,
+        manufacturer: undefined,
+        brand: undefined,
+        productLabel: undefined,
+        licenseExpiryReminder: undefined,
+        productLicenseExpiry: undefined,
+        productQualification: undefined,
+        approvalNumber: undefined,
+        taste: undefined,
+        dosageForm: undefined,
+        supplier: undefined,
+        applicableDepartment: undefined,
+        contraindicationLabel: undefined,
+        shelfLifeReminder: undefined,
+        shelfLife: undefined,
+        purchasePrice: undefined,
+        purchaseUnit: '袋',
+        defaultUsage: undefined,
+        packageUnit: '袋',
+        productSpec: undefined,
+        productSpecValue: undefined,
+        productSpecUnit: 'g',
+        packagePrice: undefined,
+        minUnit: '包',
+        minSpec: undefined,
+        netContent: undefined,
+        configSalePrice: undefined,
+        configLossRate: undefined,
+        calorie: undefined,
+        carbohydrate: undefined,
+        heatEnergy: undefined,
+        protein: undefined,
+        fat: undefined,
+        moisture: undefined,
+        ca: undefined,
+        p: undefined,
+        k: undefined,
+        na: undefined,
+        mg: undefined,
+        cl: undefined,
+        fe: undefined,
+        zn: undefined,
+        se: undefined,
+        cu: undefined,
+        mn: undefined,
+        i: undefined,
+        f: undefined,
+        cr: undefined,
+        mo: undefined,
+        isoleucine: undefined,
+        tryptophan: undefined,
+        sulfurAminoAcid: undefined,
+        histidine: undefined,
+        aromaticAminoAcid: undefined,
+        glutamicAcid: undefined,
+        threonine: undefined,
+        serine: undefined,
+        arginine: undefined,
+        lysine: undefined,
+        asparticAcid: undefined,
+        cysteine: undefined,
+        proline: undefined,
+        tyrosine: undefined,
+        leucine: undefined,
+        valine: undefined,
+        methionine: undefined,
+        alanine: undefined,
+        phenylalanine: undefined,
+        glycine: undefined,
+        fattyAcid: undefined,
+        saturatedFattyAcid: undefined,
+        monounsaturatedFattyAcid: undefined,
+        polyunsaturatedFattyAcid: undefined,
+        vitaminA: undefined,
+        vitaminACarotene: undefined,
+        vitaminAAlcohol: undefined,
+        vitaminD: undefined,
+        vitaminE: undefined,
+        vitaminETocopherol: undefined,
+        vitaminK: undefined,
+        vitaminBOne: undefined,
+        vitaminBTwo: undefined,
+        vitaminBSix: undefined,
+        vitaminBTwelve: undefined,
+        niacin: undefined,
+        vitaminC: undefined,
+        folicAcid: undefined,
+        choline: undefined,
+        biotin: undefined,
+        pantothenicAcid: undefined,
+        cholesterol: undefined,
+        bloodGlucoseIndex: undefined,
+        insolubleDietaryFiber: undefined,
+        dietaryFiber: undefined,
+        ash: undefined,
+        solubleDietaryFiber: undefined,
+        applicableCrowd: undefined,
+        unsuitableCrowd: undefined,
+        osmoticPressure: undefined,
+        rawMaterial: undefined,
+        indicationsContraindications: undefined,
+        usageAndDosage: undefined,
+        productFeatures: undefined,
+        storageConditions: undefined,
+        warningInstructions: undefined,
+        productAttachments: undefined,
+        status: undefined,
+        putFlag: undefined,
+        outboundNumber: undefined
+    };
+
+    const data = reactive < PageData < NutritionForm,
+        NutritionQuery >> ({
+            form: { ...initFormData },
+            queryParams: {
+                pageNum: 1,
+                pageSize: 10,
+                productName: undefined,
+                productCategory: undefined,
+                productCategoryList: [],
+            },
+            rules: {
+                productName: [
+                    { required: true, message: "产品名称不能为空", trigger: "blur" }
+                ],
+                hospitalSystemCode: [
+                    { required: true, message: "院方系统编码不能为空", trigger: "blur" }
+                ],
+                productCode: [
+                    { required: true, message: "商品编码不能为空", trigger: "blur" }
+                ],
+                productCategory: [
+                    { required: true, message: "产品所属分类不能为空", trigger: "blur" }
+                ],
+                productQualification: [
+                    { required: true, message: "商品资质不能为空", trigger: "blur" }
+                ],
+                shelfLifeReminder: [
+                    { required: true, message: "保质期临期提醒不能为空", trigger: "blur" }
+                ],
+                shelfLife: [
+                    { required: true, message: "保质期不能为空", trigger: "blur" }
+                ],
+                purchasePrice: [
+                    { required: true, message: "入货价格不能为空", trigger: "blur" }
+                ],
+                purchaseUnit: [
+                    { required: true, message: "入货单位不能为空", trigger: "blur" }
+                ],
+                productSpec: [
+                    { required: true, message: "商品规格不能为空", trigger: "blur" }
+                ],
+                configSalePrice: [
+                    { required: true, message: "配置销售价格不能为空", trigger: "blur" }
+                ],
+                packagePrice: [
+                    { required: true, message: "预包装价格不能为空", trigger: "blur" }
+                ],
+            }
+        });
+
+    const { queryParams, form, rules } = toRefs(data);
+
+    const categoryOptions = ref([]);
+
+    function buildCategoryTree(flatList) {
+        const idMap = {};
+        const tree = [];
+        flatList.forEach(item => {
+            idMap[item.categoryId] = {
+                label: item.categoryName,
+                value: item.categoryId,
+                children: []
+            };
+        });
+        flatList.forEach(item => {
+            if (item.parentId && item.parentId !== 0 && idMap[item.parentId]) {
+                idMap[item.parentId].children.push(idMap[item.categoryId]);
+            } else if (item.parentId === 0) {
+                tree.push(idMap[item.categoryId]);
+            }
+        });
+        // 去除没有children的children字段
+        function clean(node) {
+            if (node.children && node.children.length === 0) {
+                delete node.children;
+            } else if (node.children) {
+                node.children.forEach(clean);
+            }
+        }
+        tree.forEach(clean);
+        return tree;
+    }
+
+    /** 查询营养产品信息列表 */
+    const getList = async () => {
+
+        loading.value = true;
+        const res = await listNutrition(queryParams.value);
+        nutritionList.value = res.rows;
+        total.value = res.total;
+        loading.value = false;
+    }
+
+    /** 取消按钮 */
+    const cancel = () => {
+        reset();
+        dialog.visible = false;
+    }
+
+    /** 表单重置 */
+    const reset = () => {
+        form.value = { ...initFormData };
+        nutritionFormRef.value ?.resetFields();
+        fileList.value = [];
+    }
+
+    /** 搜索按钮操作 */
+    const handleQuery = () => {
+        // 取最后一级分类ID传给后端
+        if (queryParams.value.productCategoryList && queryParams.value.productCategoryList.length) {
+            queryParams.value.productCategory = queryParams.value.productCategoryList.slice(-1)[0];
+        } else {
+            queryParams.value.productCategory = undefined;
+        }
+        queryParams.value.pageNum = 1;
+        getList();
+    }
+
+    /** 重置按钮操作 */
+    const resetQuery = () => {
+        queryFormRef.value?.resetFields();
+        queryParams.value.productCategoryList = [];
+        queryParams.value.productCategory = undefined;
+        queryParams.value.productName = undefined;
+        handleQuery();
+    }
+
+    /** 多选框选中数据 */
+    const handleSelectionChange = (selection: NutritionVO[]) => {
+        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 ? : NutritionVO) => {
+        reset();
+        const _id = row ?.id || ids.value[0]
+        const res = await getNutrition(_id);
+        Object.assign(form.value, res.data);
+        dialog.visible = true;
+        dialog.title = "修改营养产品信息";
+    }
+
+    /** 提交按钮 */
+    const submitForm = () => {
+        nutritionFormRef.value ?.validate(async (valid: boolean) => {
+            if (valid) {
+                buttonLoading.value = true;
+                // form.value.productSpec = form.value.productSpec && form.value.productSpecUnit ? `${form.value.productSpec}${form.value.productSpecUnit}` : '';
+                if (form.value.id) {
+                    await updateNutrition(form.value).finally(() => buttonLoading.value = false);
+                } else {
+                    await addNutrition(form.value).finally(() => buttonLoading.value = false);
+                }
+                proxy ?.$modal.msgSuccess("操作成功");
+                dialog.visible = false;
+                await getList();
+            }
+        });
+    }
+
+    /** 保存并上架按钮操作 */
+    const submitFormAndPutaway = () => {
+        nutritionFormRef.value ?.validate(async (valid: boolean) => {
+            if (valid) {
+                buttonLoading.value = true;
+                form.value.putFlag = '1';
+                form.value.productSpec = form.value.productSpec && form.value.productSpecUnit ? `${form.value.productSpec}${form.value.productSpecUnit}` : '';
+                if (form.value.id) {
+                    await updateNutrition(form.value).finally(() => buttonLoading.value = false);
+                } else {
+                    await addNutrition(form.value).finally(() => buttonLoading.value = false);
+                }
+                proxy ?.$modal.msgSuccess("操作成功");
+                dialog.visible = false;
+                await getList();
+            }
+        });
+    }
+
+    /** 删除按钮操作 */
+    const handleDelete = async (row ? : NutritionVO) => {
+        const _ids = row ?.id || ids.value;
+        await proxy ?.$modal.confirm('是否确认删除营养产品信息编号为"' + _ids + '"的数据项?');
+        await delNutrition(_ids);
+        proxy ?.$modal.msgSuccess("删除成功");
+        await getList();
+    }
+
+    /** 导出按钮操作 */
+    const handleExport = () => {
+        proxy ?.download('warehouse/nutrition/export', {
+            ...queryParams.value
+        }, `nutrition_${new Date().getTime()}.xlsx`)
+    }
+
+    /** 文件上传相关操作 */
+    const handleFileChange = (file: UploadFile, uploadFiles: UploadFiles) => {
+        fileList.value = uploadFiles;
+    }
+
+    const onSpecUnitChange = () => {
+        if (!form.value.productSpecUnit) form.value.productSpecUnit = 'g';
+    }
+
+    // 详情弹窗逻辑
+    const handleDetail = async (row: NutritionVO) => {
+        reset();
+        const res = await getNutrition(row.id);
+        Object.assign(form.value, res.data);
+        detailDialogVisible.value = true;
+        activeTab.value = 'basic';
+    };
+
+    // 上下架切换
+    const handlePutFlag = async (row: NutritionVO, flag: string) => {
+        await proxy ?.$modal.confirm(`是否确认${flag === '1' ? '上架' : '下架'}该产品?`);
+        const updateData = { ...row, putFlag: flag };
+        await updateNutrition(updateData);
+        proxy ?.$modal.msgSuccess(`${flag === '1' ? '上架' : '下架'}成功`);
+        await getList();
+    };
+
+    onMounted(async () => {
+        getList();
+        const res = await listCategory();
+        categoryOptions.value = buildCategoryTree(res.rows || []);
+        if (!form.value.productSpecUnit) form.value.productSpecUnit = 'g';
+    });
+
+    const getCategoryName = (categoryIds) => {
+        if (!categoryIds) return '--';
+
+        // 处理多个分类ID的情况
+        const ids = categoryIds.toString().split(',');
+        const categoryNames = ids.map(id => {
+            const findCategory = (categories, targetId) => {
+                for (const category of categories) {
+                    if (category.value.toString() === targetId.toString()) {
+                        return category.label;
+                    }
+                    if (category.children) {
+                        const found = findCategory(category.children, targetId);
+                        if (found) return found;
+                    }
+                }
+                return null;
+            };
+            return findCategory(categoryOptions.value, id);
+        }).filter(name => name !== null);
+
+        return categoryNames.length > 0 ? categoryNames.join('/') : '--';
+    };
+</script>
+
+<style lang="scss" scoped>
+    .nutrition-dialog {
+        :deep(.el-dialog) {
+            height: 70vh;
+            margin-top: 15vh !important;
+
+            .el-dialog__body {
+                height: calc(100% - 120px);
+                padding: 10px 20px;
+                overflow: hidden;
+            }
+
+            .el-tabs {
+                height: 100%;
+
+                .el-tabs__content {
+                    height: calc(100% - 40px);
+                    overflow: hidden;
+                }
+            }
+
+            .el-scrollbar {
+                height: 100%;
+
+                .el-scrollbar__wrap {
+                    overflow-x: hidden;
+                }
+            }
+
+            .el-form {
+                padding: 20px;
+            }
+        }
+    }
+
+    .dialog-footer {
+        padding: 20px;
+        text-align: right;
+    }
+</style>

+ 308 - 0
src/views/warehouse/productCategory/index.vue

@@ -0,0 +1,308 @@
+<template>
+    <div class="p-2">
+        <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+            <div v-show="showSearch">
+                <el-form ref="queryFormRef" :model="queryParams" :inline="true" class="bg-[#f8f8f9] p-[10px] mb-[10px]">
+                    <el-form-item label="分类名称" prop="categoryName">
+                        <el-input v-model="queryParams.categoryName" placeholder="请输入" clearable style="width: 180px" @keyup.enter="handleQuery" />
+                    </el-form-item>
+                    <el-form-item>
+                        <el-button type="primary" class="ml-2" @click="handleQuery">查询</el-button>
+                        <el-button class="ml-2" @click="resetQuery">重置</el-button>
+                    </el-form-item>
+                </el-form>
+            </div>
+        </transition>
+
+        <el-card>
+            <template #header>
+                <el-row :gutter="10" class="mb-[10px]">
+                    <el-col :span="1.5">
+                        <el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
+                    </el-col>
+                    <el-col :span="1.5">
+                        <el-button type="primary" plain icon="CaretBottom" @click="handleExpandAll">{{ isExpanded ? '收起' : '展开' }}所有</el-button>
+                    </el-col>
+                </el-row>
+            </template>
+
+            <el-table ref="tableRef" v-loading="loading" :data="categoryTreeData" row-key="categoryId" border :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" class="custom-table">
+                <el-table-column label="分类名称" align="left" prop="categoryName" min-width="180" />
+                <el-table-column label="操作" align="center" width="180">
+                    <template #default="scope">
+                        <!-- <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" class="table-operation-button">编辑</el-button> -->
+                        <el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" class="table-operation-button">删除</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" class="mt-[15px]" />
+        </el-card>
+
+        <!-- 添加或修改产品分类对话框 -->
+        <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body :close-on-click-modal="false" destroy-on-close>
+            <el-form ref="categoryFormRef" :model="form" :rules="rules" label-width="100px" class="mt-[20px]">
+                <el-form-item label="上级分类" prop="parentId">
+                    <el-tree-select v-model="form.parentId" :data="categoryOptions" placeholder="请选择" clearable :props="{ 
+                            label: 'categoryName',
+                            value: 'categoryId',
+                            children: 'children'
+                        }" style="width: 100%" />
+                </el-form-item>
+                <el-form-item label="分类名称" prop="categoryName">
+                    <el-input v-model="form.categoryName" placeholder="请输入" />
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <div class="dialog-footer">
+                    <el-button @click="cancel">关闭</el-button>
+                    <el-button :loading="buttonLoading" type="primary" @click="submitForm">保存</el-button>
+                </div>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script setup name="ProductCategory" lang="ts">
+    import { listCategory, getCategory, delCategory, addCategory, updateCategory } from '@/api/warehouse/productCategory/index';
+    import { CategoryVO, CategoryQuery, CategoryForm } from '@/api/warehouse/productCategory/types';
+    import { handleTree } from '@/utils/tree';
+    import { getCurrentInstance, reactive, ref, onMounted, toRefs } from 'vue';
+    import type { FormInstance, ElTable } from 'element-plus';
+    import type { ComponentInternalInstance } from 'vue';
+
+    const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+    const categoryList = ref < CategoryVO[] > ([]);
+    const categoryTreeData = ref < CategoryVO[] > ([]);
+    const loading = ref(false);
+    const showSearch = ref(true);
+    const total = ref(0);
+    const buttonLoading = ref(false);
+    const categoryOptions = ref < CategoryVO[] > ([]);
+
+    const queryFormRef = ref < FormInstance > ();
+    const categoryFormRef = ref < FormInstance > ();
+    const tableRef = ref < InstanceType < typeof ElTable >> ();
+    const isExpanded = ref(false);
+
+    const data = reactive < {
+        form: CategoryForm;
+        queryParams: CategoryQuery & {
+            pageNum: number;
+            pageSize: number;
+        };
+        rules: Record < string,
+        any[] > ;
+        dialog: {
+            visible: boolean;
+            title: string;
+        };
+    } > ({
+        form: {
+            categoryId: undefined,
+            parentId: undefined,
+            categoryName: ''
+        },
+        queryParams: {
+            pageNum: 1,
+            pageSize: 10,
+            categoryName: ''
+        },
+        rules: {
+            categoryName: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }]
+        },
+        dialog: {
+            visible: false,
+            title: ''
+        }
+    });
+
+    const { form, queryParams, rules, dialog } = toRefs(data);
+
+    /** 查询分类列表 */
+    const getList = async () => {
+        loading.value = true;
+        try {
+            const res = await listCategory(queryParams.value);
+            categoryList.value = res.rows;
+            total.value = res.total;
+            // 构建树形数据
+            categoryTreeData.value = handleTree(res.rows, 'categoryId', 'parentId');
+            // 构建选择项数据
+            categoryOptions.value = handleTree(res.rows, 'categoryId', 'parentId');
+        } catch (error) {
+            console.error(error);
+        } finally {
+            loading.value = false;
+        }
+    }
+
+    /** 取消按钮 */
+    const cancel = () => {
+        reset();
+        dialog.value.visible = false;
+    }
+
+    /** 表单重置 */
+    const reset = () => {
+        form.value = {
+            categoryId: undefined,
+            parentId: undefined,
+            categoryName: ''
+        };
+        categoryFormRef.value ?.resetFields();
+    }
+
+    /** 搜索按钮操作 */
+    const handleQuery = () => {
+        queryParams.value.pageNum = 1;
+        getList();
+    }
+
+    /** 重置按钮操作 */
+    const resetQuery = () => {
+        queryFormRef.value ?.resetFields();
+        handleQuery();
+    }
+
+    /** 新增按钮操作 */
+    const handleAdd = () => {
+        reset();
+        dialog.value.visible = true;
+        dialog.value.title = '新增';
+    }
+
+    /** 修改按钮操作 */
+    const handleUpdate = async (row: CategoryVO) => {
+        reset();
+        const id = row.categoryId;
+        const res = await getCategory(id);
+        Object.assign(form.value, res.data);
+        dialog.value.visible = true;
+        dialog.value.title = '修改分类';
+    }
+
+    /** 提交按钮 */
+    const submitForm = async () => {
+        categoryFormRef.value ?.validate(async (valid: boolean) => {
+            if (valid) {
+                buttonLoading.value = true;
+                try {
+                    if (form.value.categoryId) {
+                        await updateCategory(form.value);
+                    } else {
+                        await addCategory(form.value);
+                    }
+                    proxy ?.$modal.msgSuccess('操作成功');
+                    dialog.value.visible = false;
+                    await getList();
+                } catch (error) {
+                    console.error(error);
+                } finally {
+                    buttonLoading.value = false;
+                }
+            }
+        });
+    }
+
+    /** 删除按钮操作 */
+    const handleDelete = async (row: CategoryVO) => {
+        const categoryIds = [row.categoryId];
+        proxy ?.$modal.confirm('是否确认删除分类编号为"' + categoryIds + '"的数据项?').then(async () => {
+            try {
+                await delCategory(categoryIds);
+                proxy ?.$modal.msgSuccess('删除成功');
+                await getList();
+            } catch (error) {
+                console.error(error);
+            }
+        });
+    }
+
+    /** 展开/收起所有 */
+    const handleExpandAll = () => {
+        if (!tableRef.value) return;
+
+        const status = !isExpanded.value;
+        isExpanded.value = status;
+
+        categoryTreeData.value.forEach((row) => {
+            tableRef.value ?.toggleRowExpansion(row, status);
+        });
+    };
+
+    // 替换原来的handleCloseAll函数
+    const handleCloseAll = handleExpandAll;
+
+    onMounted(() => {
+        getList();
+    });
+</script>
+
+<style lang="scss" scoped>
+    .custom-table {
+        :deep(.el-table__border) {
+            border-color: #ebeef5;
+        }
+
+        :deep(.el-table__inner-wrapper::before) {
+            background-color: #ebeef5;
+        }
+
+        :deep(.el-table__row) {
+            height: 50px;
+        }
+
+        :deep(.el-table__cell) {
+            padding: 8px 0;
+        }
+
+        :deep(.table-operation-button) {
+            padding: 0 12px;
+            font-size: 14px;
+
+            &.el-button--danger {
+                color: #ff4d4f;
+                margin-left: 16px;
+
+                &:hover {
+                    color: #ff7875;
+                }
+            }
+        }
+    }
+
+    :deep(.el-card) {
+        border-radius: 4px;
+
+        .el-card__header {
+            padding: 12px 20px;
+            border-bottom: 1px solid #ebeef5;
+        }
+    }
+
+    :deep(.el-dialog) {
+        border-radius: 8px;
+
+        .el-dialog__header {
+            margin: 0;
+            padding: 15px 20px;
+            border-bottom: 1px solid #dcdfe6;
+        }
+
+        .el-dialog__title {
+            font-size: 15px;
+            font-weight: 500;
+        }
+
+        .el-dialog__body {
+            padding: 20px;
+        }
+
+        .el-dialog__footer {
+            padding: 15px 20px;
+            border-top: 1px solid #dcdfe6;
+        }
+    }
+</style>

+ 303 - 0
src/views/warehouse/suppliesCategory/index.vue

@@ -0,0 +1,303 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div v-show="showSearch">
+        <el-form ref="queryFormRef" :model="queryParams" :inline="true" class="bg-[#f8f8f9] p-[10px] mb-[10px]">
+          <el-form-item label="分类名称" prop="categoryName">
+            <el-input v-model="queryParams.categoryName" placeholder="请输入" clearable style="width: 180px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" class="ml-2" @click="handleQuery">查询</el-button>
+            <el-button class="ml-2" @click="resetQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card>
+      <template #header>
+        <el-row :gutter="10" class="mb-[10px]">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="CaretBottom" @click="handleExpandAll">{{ isExpanded ? '收起' : '展开' }}所有</el-button>
+          </el-col>
+        </el-row>
+      </template>
+
+      <el-table ref="tableRef" v-loading="loading" :data="categoryTreeData" row-key="categoryId" border :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" class="custom-table">
+        <el-table-column label="耗材分类名称" align="left" prop="categoryName" min-width="180" />
+        <el-table-column label="操作" align="center" width="180">
+          <template #default="scope">
+            <el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" class="table-operation-button">删除</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" class="mt-[15px]" />
+    </el-card>
+
+    <!-- 添加或修改耗材分类对话框 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body :close-on-click-modal="false" destroy-on-close>
+      <el-form ref="categoryFormRef" :model="form" :rules="rules" label-width="150px" class="mt-[20px]">
+        <el-form-item label="上级分类" prop="parentId">
+          <el-tree-select v-model="form.parentId" :data="categoryOptions" placeholder="请选择" clearable :props="{ 
+                  label: 'categoryName',
+                  value: 'categoryId',
+                  children: 'children'
+              }" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="耗材分类名称" prop="categoryName">
+          <el-input v-model="form.categoryName" placeholder="请输入" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="cancel">关闭</el-button>
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">保存</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="SuppliesCategory" lang="ts">
+import { listSuppliesCategory, getSuppliesCategory, delSuppliesCategory, addSuppliesCategory, updateSuppliesCategory } from '@/api/warehouse/suppliesCategory/index';
+import { CategoryVO, CategoryQuery, CategoryForm } from '@/api/warehouse/suppliesCategory/types';
+import { handleTree } from '@/utils/tree';
+import { getCurrentInstance, reactive, ref, onMounted, toRefs } from 'vue';
+import type { FormInstance, ElTable } from 'element-plus';
+import type { ComponentInternalInstance } from 'vue';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const categoryList = ref<CategoryVO[]>([]);
+const categoryTreeData = ref<CategoryVO[]>([]);
+const loading = ref(false);
+const showSearch = ref(true);
+const total = ref(0);
+const buttonLoading = ref(false);
+const categoryOptions = ref<CategoryVO[]>([]);
+
+const queryFormRef = ref<FormInstance>();
+const categoryFormRef = ref<FormInstance>();
+const tableRef = ref<InstanceType<typeof ElTable>>();
+const isExpanded = ref(false);
+
+const data = reactive<{
+    form: CategoryForm;
+    queryParams: CategoryQuery & {
+        pageNum: number;
+        pageSize: number;
+    };
+    rules: Record<string, any[]>;
+    dialog: {
+        visible: boolean;
+        title: string;
+    };
+}>({
+    form: {
+        categoryId: undefined,
+        parentId: undefined,
+        categoryName: ''
+    },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        categoryName: ''
+    },
+    rules: {
+        categoryName: [{ required: true, message: '耗材分类名称不能为空', trigger: 'blur' }]
+    },
+    dialog: {
+        visible: false,
+        title: ''
+    }
+});
+
+const { form, queryParams, rules, dialog } = toRefs(data);
+
+/** 查询分类列表 */
+const getList = async () => {
+    loading.value = true;
+    try {
+        const res = await listSuppliesCategory(queryParams.value);
+        categoryList.value = res.rows;
+        total.value = res.total;
+        // 构建树形数据
+        categoryTreeData.value = handleTree(res.rows, 'categoryId', 'parentId');
+        // 构建选择项数据
+        categoryOptions.value = handleTree(res.rows, 'categoryId', 'parentId');
+    } catch (error) {
+        console.error(error);
+    } finally {
+        loading.value = false;
+    }
+}
+
+/** 取消按钮 */
+const cancel = () => {
+    reset();
+    dialog.value.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+    form.value = {
+        categoryId: undefined,
+        parentId: undefined,
+        categoryName: ''
+    };
+    categoryFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+    queryParams.value.pageNum = 1;
+    getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+    queryFormRef.value?.resetFields();
+    handleQuery();
+}
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+    reset();
+    dialog.value.visible = true;
+    dialog.value.title = '新增';
+}
+
+/** 修改按钮操作 */
+const handleUpdate = async (row: CategoryVO) => {
+    reset();
+    const id = row.categoryId;
+    const res = await getSuppliesCategory(id);
+    Object.assign(form.value, res.data);
+    dialog.value.visible = true;
+    dialog.value.title = '修改分类';
+}
+
+/** 提交按钮 */
+const submitForm = async () => {
+    categoryFormRef.value?.validate(async (valid: boolean) => {
+        if (valid) {
+            buttonLoading.value = true;
+            try {
+                if (form.value.categoryId) {
+                    await updateSuppliesCategory(form.value);
+                } else {
+                    await addSuppliesCategory(form.value);
+                }
+                proxy?.$modal.msgSuccess('操作成功');
+                dialog.value.visible = false;
+                await getList();
+            } catch (error) {
+                console.error(error);
+            } finally {
+                buttonLoading.value = false;
+            }
+        }
+    });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row: CategoryVO) => {
+    const categoryIds = [row.categoryId];
+    proxy?.$modal.confirm('是否确认删除分类编号为"' + categoryIds + '"的数据项?').then(async () => {
+        try {
+            await delSuppliesCategory(categoryIds);
+            proxy?.$modal.msgSuccess('删除成功');
+            await getList();
+        } catch (error) {
+            console.error(error);
+        }
+    });
+}
+
+/** 展开/收起所有 */
+const handleExpandAll = () => {
+    if (!tableRef.value) return;
+
+    const status = !isExpanded.value;
+    isExpanded.value = status;
+
+    categoryTreeData.value.forEach((row) => {
+        tableRef.value?.toggleRowExpansion(row, status);
+    });
+};
+
+onMounted(() => {
+    getList();
+});
+</script>
+
+<style lang="scss" scoped>
+    .custom-table {
+        :deep(.el-table__border) {
+            border-color: #ebeef5;
+        }
+
+        :deep(.el-table__inner-wrapper::before) {
+            background-color: #ebeef5;
+        }
+
+        :deep(.el-table__row) {
+            height: 50px;
+        }
+
+        :deep(.el-table__cell) {
+            padding: 8px 0;
+        }
+
+        :deep(.table-operation-button) {
+            padding: 0 12px;
+            font-size: 14px;
+
+            &.el-button--danger {
+                color: #ff4d4f;
+                margin-left: 16px;
+
+                &:hover {
+                    color: #ff7875;
+                }
+            }
+        }
+    }
+
+    :deep(.el-card) {
+        border-radius: 4px;
+
+        .el-card__header {
+            padding: 12px 20px;
+            border-bottom: 1px solid #ebeef5;
+        }
+    }
+
+    :deep(.el-dialog) {
+        border-radius: 8px;
+
+        .el-dialog__header {
+            margin: 0;
+            padding: 15px 20px;
+            border-bottom: 1px solid #dcdfe6;
+        }
+
+        .el-dialog__title {
+            font-size: 15px;
+            font-weight: 500;
+        }
+
+        .el-dialog__body {
+            padding: 20px;
+        }
+
+        .el-dialog__footer {
+            padding: 15px 20px;
+            border-top: 1px solid #dcdfe6;
+        }
+    }
+</style>

+ 873 - 0
src/views/workbench/treatmentUser/index.vue

@@ -0,0 +1,873 @@
+<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="type">
+                            <el-select v-model="queryParams.type" clearable>
+                                <el-option v-for="dict in treatment_user_type" :key="dict.value" :label="dict.label" :value="dict.value" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="科室" prop="doorId">
+                            <el-tree-select v-model="queryParams.doorId" :data="treeData" :props="treeProps" placeholder="请选择" check-strictly node-key="id" @keyup.enter="handleQuery" />
+                        </el-form-item>
+                        <el-form-item label="患者状态" prop="treatmentUserStatus" v-if="showStatusSearch">
+                            <el-select v-model="queryParams.treatmentUserStatus" clearable>
+                                <el-option v-for="dict in treatment_user_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="评估状态" prop="evaluationStatus">
+                            <el-select v-model="queryParams.evaluationStatus" clearable>
+                                <el-option v-for="dict in evaluation_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item prop="searchFlag">
+                            <el-input v-model="queryParams.searchFlag" placeholder="姓名/门诊号/身份证号/医生" clearable @keyup.enter="handleQuery" />
+                        </el-form-item>
+                        <el-form-item>
+                            <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
+                            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:user:add']">添加患者</el-button>
+                        </el-form-item>
+                    </el-form>
+                </el-card>
+            </div>
+        </transition>
+
+        <el-card shadow="never">
+            <div class="status-tabs">
+                <div class="tab-item" :class="{ 'active': activeTab === 'waiting' }" @click="handleTabClick('waiting')">
+                    待诊
+                    <el-badge :value="waitingCount" class="tab-badge" />
+                </div>
+                <div class="tab-item" :class="{ 'active': activeTab === 'treating' }" @click="handleTabClick('treating')">
+                    诊中
+                    <el-badge :value="treatingCount" class="tab-badge" />
+                </div>
+                <div class="tab-item" :class="{ 'active': activeTab === 'treated' }" @click="handleTabClick('treated')">
+                    已诊
+                    <el-badge :value="treatedCount" class="tab-badge" />
+                </div>
+                <div class="tab-item" :class="{ 'active': activeTab === 'reapply' }" @click="handleTabClick('reapply')">
+                    处方重申
+                    <el-badge :value="reapplyCount" class="tab-badge" />
+                </div>
+            </div>
+
+            <div class="patient-cards-container" v-if="userList.length > 0">
+                <el-row :gutter="20">
+                    <el-col v-for="(patient, index) in userList" :key="index" :xs="24" :sm="12" :md="8" :lg="6" :xl="4">
+                        <el-card class="patient-card" shadow="hover" @click="showPatientDetail(patient)">
+                            <div class="patient-status-bar" :class="getStatusBarClass(patient)">
+                                {{ getStatusText(patient) }}
+                            </div>
+                            <div class="patient-info">
+                                <div class="patient-header">
+                                    <div class="patient-name-age">
+                                        <span class="patient-name">{{ patient.treatName }}</span>
+                                        <span class="patient-age">{{ patient.age }}</span>
+                                    </div>
+                                    <span class="gender-icon" :class="patient.sex === '1' ? 'male' : 'female'">
+                                        {{ patient.sex === '1' ? '♂' : '♀' }}
+                                    </span>
+                                </div>
+                                <div class="patient-detail">
+                                    <span class="detail-label">门诊号:</span>
+                                    <span>{{ patient.outpatientNo }}</span>
+                                </div>
+                                <div class="patient-detail">
+                                    <span class="detail-label">科室:</span>
+                                    <span>{{ patient.deptName }}</span>
+                                </div>
+                                <div class="evaluation-info">
+                                    <span class="evaluation-score" v-if="patient.treatmentUserStatus==='4'">营养筛查得分:{{ patient.score }}</span>
+                                    <span class="evaluation-status" :class="patient.evaluationStatus === '1' ? 'evaluated' : 'not-evaluated'">
+                                        {{ patient.evaluationStatus === '1' ? '已评估' : '未评估' }}
+                                    </span>
+                                </div>
+                            </div>
+                        </el-card>
+                    </el-col>
+                </el-row>
+            </div>
+            <div v-else class="empty-state">
+                <img src="@/assets/images/empty.png" alt="暂无数据" />
+                <p>暂无数据</p>
+            </div>
+        </el-card>
+        <!-- 添加或修改【待诊患者】对话框 -->
+        <el-dialog :title="dialog.title" v-model="dialog.visible" width="800px" append-to-body>
+            <el-form ref="userFormRef" :model="form" :rules="rules" label-width="80px">
+                <el-form-item label="看诊类型" prop="type">
+                    <el-radio-group v-model="form.type">
+                        <el-radio label="1">住院</el-radio>
+                        <el-radio label="0">门诊</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-row :gutter="10">
+                    <el-col :span="12">
+                        <el-form-item label="诊疗卡号" prop="treatNum">
+                            <el-input v-model="form.treatNum" placeholder="系统生成" disabled />
+                        </el-form-item>
+                    </el-col>
+                    <el-col :span="12">
+                        <el-form-item label="门诊号" prop="outpatientNo">
+                            <el-input v-model="form.outpatientNo" placeholder="系统生成" disabled />
+                        </el-form-item>
+                    </el-col>
+                </el-row>
+                <el-row :gutter="10">
+                    <el-col :span="12">
+                        <el-form-item label="科室" prop="doorId">
+                            <el-tree-select v-model="form.doorId" :data="treeData" :props="treeProps" placeholder="请选择" check-strictly node-key="id" />
+                        </el-form-item>
+                    </el-col>
+                </el-row>
+                <div v-show="form.type == '1'">
+                    <el-row :gutter="10">
+                        <el-col :span="12">
+                            <el-form-item label="床号" prop="bedNum">
+                                <el-input v-model="form.bedNum" placeholder="请输入" />
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="病区" prop="inpatientWard">
+                                <el-select v-model="form.inpatientWard" placeholder="请选择">
+
+                                </el-select>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row :gutter="10">
+                        <el-col :span="12">
+                            <el-form-item v-if="data.form.type === '1'" label="入院日期" prop="admissionDate" :required="data.form.type === '1'">
+                                <el-date-picker v-model="data.form.admissionDate" type="date" placeholder="请选择" value-format="YYYY-MM-DD" style="width: 100%" />
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                </div>
+                <el-row :gutter="10">
+                    <el-col :span="12">
+                        <el-form-item label="姓名" prop="treatName">
+                            <el-input v-model="form.treatName" placeholder="请输入" />
+                        </el-form-item>
+                        <el-form-item label="身份证" prop="idCard">
+                            <el-input v-model="form.idCard" placeholder="请输入" @input="handleIdCardChange" />
+                        </el-form-item>
+                        <el-form-item label="年龄" prop="age">
+                            <el-input v-model="form.age" placeholder="请输入" disabled />
+                        </el-form-item>
+                        <el-form-item label="身高" prop="height">
+                            <el-input v-model="form.height" placeholder="请输入" min="0" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: calc(100% - 40px)">
+                                <template #append>cm</template>
+                            </el-input>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :span="12">
+                        <el-form-item label="性别" prop="sex">
+                            <el-select v-model="form.sex" placeholder="请选择" clearable>
+                                <el-option v-for="dict in user_sex" :key="dict.value" :label="dict.label" :value="dict.value" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="出生日期" prop="birthday">
+                            <el-input v-model="form.birthday" placeholder="请输入" disabled />
+                        </el-form-item>
+                        <el-form-item label="联系电话" prop="phoneNum">
+                            <el-input v-model="form.phoneNum" placeholder="请输入" />
+                        </el-form-item>
+                        <el-form-item label="体重" prop="weight">
+                            <el-input v-model="form.weight" placeholder="请输入" style="width: calc(100% - 40px)">
+                                <template #append>kg</template>
+                            </el-input>
+                        </el-form-item>
+                    </el-col>
+                </el-row>
+                <el-form-item label="过敏食物" prop="allergyFoot">
+                    <el-input type="textarea" v-model="form.allergyFoot" placeholder="请输入" maxlength="120" show-word-limit @input="handleTextareaInput" />
+                </el-form-item>
+                <el-form-item label="过敏药物" prop="allergyDrug">
+                    <el-input type="textarea" v-model="form.allergyDrug" placeholder="请输入" maxlength="120" show-word-limit @input="handleTextareaInput" />
+                </el-form-item>
+                <el-row :gutter="10">
+                    <el-col :span="12">
+                        <el-form-item label="体力活动" prop="activity">
+                            <el-select v-model="form.activity" placeholder="请选择" clearable>
+                                <el-option v-for="dict in physical_activity" :key="dict.value" :label="dict.label" :value="dict.value" />
+                            </el-select>
+                        </el-form-item>
+                    </el-col>
+                </el-row>
+            </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>
+        <!-- 新增:患者详情弹窗 -->
+        <el-dialog v-model="showDetail" :visible="showDetail" title="查看门诊患者信息" width="900px" append-to-body>
+            <div style="padding: 20px 30px;">
+                <el-row :gutter="24">
+                    
+                    <el-col :span="12">
+                        <div><b>看诊类型:</b>{{ detailData.type === '0' ? '门诊' : '住院' }}</div>
+                        <div><b>诊疗卡号:</b>{{ detailData.treatNum || '--' }}</div>
+                        <div><b>科室:</b>{{ detailData.deptName || '--' }}</div>
+                        <div><b>姓名:</b>{{ detailData.treatName || '--' }}</div>
+                        <div><b>身份证:</b>{{ detailData.idCard || '--' }}</div>
+                        <div><b>年龄:</b>{{ detailData.age || '--' }}</div>
+                        <div><b>身高:</b>{{ detailData.height ? detailData.height + 'cm' : '--' }}</div>
+                        <div><b>BMI:</b>{{ detailData.bmi || '--' }}</div>
+                        <div><b>过敏食物:</b>{{ detailData.allergyFoot || '--' }}</div>
+                        <div><b>过敏药物:</b>{{ detailData.allergyDrug || '--' }}</div>
+                        <div><b>体力活动:</b>{{ getDictLabel(physical_activity.value, detailData.activity) || '--' }}</div>
+                    </el-col>
+                    <el-col :span="12">
+                        <div><b>门诊号:</b>{{ detailData.outpatientNo || '--' }}</div>
+                        <div><b>性别:</b>{{ detailData.sex === '1' ? '男' : detailData.sex === '2' ? '女' : '--' }}</div>
+                        <div><b>出生日期:</b>{{ detailData.birthday || '--' }}</div>
+                        <div><b>联系电话:</b>{{ detailData.phoneNum || '--' }}</div>
+                        <div><b>体重:</b>{{ detailData.weight ? detailData.weight + 'kg' : '--' }}</div>
+                    </el-col>
+                </el-row>
+            </div>
+            <template #footer>
+                <el-button @click="showDetail = false">关闭</el-button>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script setup name="TreatmentUser" lang="ts">
+    import { listTreatmentUser, getTreatmentUser, delTreatmentUser, addTreatmentUser, updateTreatmentUser } from '@/api/workbench/treatmentUser';
+    import { listDept } from '@/api/system/dept';
+    import { TreatmentUserVo, TreatmentUserForm, TreatmentUserQuery } from '@/api/workbench/treatmentUser/types';
+    import { log } from 'console';
+import { get } from 'http';
+    const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+    const { treatment_user_type, treatment_user_status, evaluation_status, physical_activity, user_sex } = toRefs < any > (proxy ?.useDict('treatment_user_type', 'treatment_user_status', 'evaluation_status', 'physical_activity', 'user_sex'));
+    const userList = ref < TreatmentUserVo[] > ([]);
+    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 treeData = ref([]); // 定义 treeData
+
+    const waitingCount = ref(0);
+    const treatingCount = ref(0);
+    const treatedCount = ref(0);
+    const reapplyCount = ref(0);
+    const showStatusSearch = computed(() => activeTab.value !== 'reapply');
+
+    // 当前选中的标签
+    const activeTab = ref('waiting');
+
+    // 点击标签切换
+    const handleTabClick = (tabType: string) => {
+        activeTab.value = tabType;
+        getList(); // 重新加载数据
+    };
+
+    const queryFormRef = ref < ElFormInstance > ();
+    const userFormRef = ref < ElFormInstance > ();
+
+    const dialog = reactive < DialogOption > ({
+        visible: false,
+        title: ''
+    });
+
+    const treeProps = ref({
+        value: 'deptId', // 对应部门的 deptId
+        label: 'deptName', // 对应部门的 deptName
+        children: 'children' // 保持原有的父子结构
+    });
+
+    const initFormData: TreatmentUserForm = {
+        id: undefined,
+        type: '0',
+        treatNum: undefined,
+        outpatientNo: undefined,
+        doorId: undefined,
+        treatName: undefined,
+        sex: undefined,
+        idCard: undefined,
+        phoneNum: undefined,
+        birthday: undefined,
+        age: undefined,
+        height: undefined,
+        weight: undefined,
+        allergyFoot: undefined,
+        allergyDrug: undefined,
+        activity: undefined,
+    }
+    const data = reactive < PageData < TreatmentUserForm,
+        TreatmentUserQuery >> ({
+            form: { ...initFormData },
+
+            queryParams: {
+                pageNum: 1,
+                pageSize: 10,
+                type: '0',
+                doorId: undefined,
+                treatNum: undefined,
+                searchFlag: undefined,
+                outpatientNo: undefined,
+                evaluationStatus: undefined,
+                treatmentUserStatus: undefined,
+
+                params: {}
+            },
+            // 状态计数(独立 ref)
+
+            rules: {
+                type: [{ required: true, message: '看诊类型为空', trigger: 'blur' }],
+                doorId: [{ required: true, message: '科室不能为空', trigger: 'blur' }],
+                treatName: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
+                sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
+                idCard: [{ required: true, message: '身份证不能为空', trigger: 'blur' }],
+                admissionDate: [{
+                    validator: (rule, value, callback) => {
+                        // 只有当 type 为 '1' 时才验证
+                        if (data.form.type === '1' && !value) {
+                            callback(new Error('入院时间不能为空'));
+                        } else {
+                            callback();
+                        }
+                    },
+                    trigger: 'blur'
+                }]
+
+            }
+        });
+
+    const { queryParams, form, rules } = toRefs(data);
+
+
+    /** 查询【待诊患者】列表 */
+    const getList = async () => {
+        loading.value = true;
+        try {
+            const res = await listTreatmentUser(queryParams.value);
+            // 获取部门数据
+            const deptMap = new Map();
+            treeData.value.forEach(dept => {
+                deptMap.set(dept.deptId, dept.deptName);
+                if (dept.children) {
+                    dept.children.forEach(child => {
+                        deptMap.set(child.deptId, child.deptName);
+                    });
+                }
+            });
+            
+            // 为每个患者添加科室名称
+            userList.value = res.rows.map(patient => ({
+                ...patient,
+                deptName: deptMap.get(patient.doorId) || '未知科室'
+            }));
+            total.value = res.total;
+            loading.value = false;
+            waitingCount.value = res.total;
+        } catch (error) {
+            console.error('获取列表失败:', error);
+            loading.value = false;
+        }
+    }
+   const getDeptList = async () => {
+    loading.value = true;
+    try {
+        const res = await listDept({});
+        if (!res.data) {
+            console.warn("部门数据为空");
+            treeData.value = [];
+            return;
+        }
+        
+        // 处理树形数据
+        const processedData = proxy?.handleTree(res.data, 'deptId');
+        if (!processedData) {
+            console.warn("树形数据处理失败");
+            treeData.value = [];
+            return;
+        }
+        
+        treeData.value = processedData;
+        
+    } catch (error) {
+        console.error('获取部门列表失败:', error);
+        treeData.value = [];
+    } finally {
+        loading.value = false;
+    }
+};
+    const getDictLabel = (dictList, value) => {
+        if (!Array.isArray(dictList)) return value || '--';
+        const item = dictList.find(item => item.value === value);
+        return item ? item.label : (value || '--');
+    };
+    const handleTextareaInput = () => {
+        if (form.allergyFoot.length > 120) {
+            form.allergyFoot = form.allergyFoot.slice(0, 120); // 强制截断
+        }
+        if (form.allergyDrug.length > 120) {
+            form.allergyDrug = form.allergyDrug.slice(0, 120); // 强制截断
+        }
+    };
+    const handleIdCardChange = (idCard: string) => {
+        if (!validateIdCard(idCard)) {
+            return;
+        }
+        // 当身份证号长度足够时(18位或15位)
+        if (idCard.length === 18 || idCard.length === 15) {
+            // 提取出生日期
+            let birthdayStr = '';
+            if (idCard.length === 18) {
+                birthdayStr = idCard.substring(6, 14);
+                form.value.birthday = `${birthdayStr.substring(0, 4)}-${birthdayStr.substring(4, 6)}-${birthdayStr.substring(6, 8)}`;
+            } else if (idCard.length === 15) {
+                birthdayStr = '19' + idCard.substring(6, 12);
+                form.value.birthday = `${birthdayStr.substring(0, 4)}-${birthdayStr.substring(4, 6)}-${birthdayStr.substring(6, 8)}`;
+            }
+
+            // 计算年龄
+            if (birthdayStr) {
+                const birthYear = parseInt(birthdayStr.substring(0, 4));
+                const birthMonth = parseInt(birthdayStr.substring(4, 6)) - 1;
+                const birthDay = parseInt(birthdayStr.substring(6, 8));
+
+                const today = new Date();
+                const birthDate = new Date(birthYear, birthMonth, birthDay);
+
+                let age = today.getFullYear() - birthDate.getFullYear();
+                if (today.getMonth() < birthDate.getMonth() || (today.getMonth() === birthDate.getMonth() && today.getDate() < birthDate.getDate())) {
+                    age--;
+                }
+
+                // 设置为"xx岁x月"的格式
+                form.value.age = `${age}岁${today.getMonth() - birthDate.getMonth()}月`;
+            }
+
+            // 根据身份证倒数第二位判断性别(奇数为男,偶数为女)
+            const genderNum = parseInt(idCard.length === 18 ? idCard.charAt(16) : idCard.charAt(14));
+            form.value.sex = (genderNum % 2 === 1 ? '1' : '2').toString();
+        }
+    }
+
+    const validateIdCard = (idCard: string) => {
+        // 18位身份证正则
+        const reg18 = /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
+        // 15位身份证正则
+        const reg15 = /^[1-9]\d{5}\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}$/;
+
+        return reg18.test(idCard) || reg15.test(idCard);
+    }
+
+    /** 取消按钮 */
+    const cancel = () => {
+        reset();
+        dialog.visible = false;
+    }
+
+    /** 表单重置 */
+    const reset = () => {
+        form.value = { ...initFormData };
+        userFormRef.value ?.resetFields();
+    }
+
+    /** 搜索按钮操作 */
+    const handleQuery = () => {
+        queryParams.value.pageNum = 1;
+        getList();
+    }
+
+    /** 重置按钮操作 */
+    const resetQuery = () => {
+        queryFormRef.value ?.resetFields();
+        handleQuery();
+    }
+
+    /** 多选框选中数据 */
+    const handleSelectionChange = (selection: TreatmentUserVo[]) => {
+        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 ? : TreatmentUserVo) => {
+        reset();
+        const _id = row ?.id || ids.value[0]
+        const res = await getTreatmentUser(_id);
+        Object.assign(form.value, res.data);
+        dialog.visible = true;
+        dialog.title = "修改门诊患者";
+    }
+
+    /** 提交按钮 */
+    const submitForm = () => {
+        userFormRef.value ?.validate(async (valid: boolean) => {
+            if (valid) {
+                buttonLoading.value = true;
+                if (form.value.id) {
+                    await updateTreatmentUser(form.value).finally(() => buttonLoading.value = false);
+                } else {
+                    await addTreatmentUser(form.value).finally(() => buttonLoading.value = false);
+                }
+                proxy ?.$modal.msgSuccess("操作成功");
+                dialog.visible = false;
+                await getList();
+            }
+        });
+    }
+
+    /** 删除按钮操作 */
+    const handleDelete = async (row ? : TreatmentUserVo) => {
+        const _ids = row ?.id || ids.value;
+        await proxy ?.$modal.confirm('是否确认删除门诊患者编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+        await delTreatmentUser(_ids);
+        proxy ?.$modal.msgSuccess("删除成功");
+        await getList();
+    }
+
+    /** 导出按钮操作 */
+    const handleExport = () => {
+        proxy ?.download('workbench/treatmentUser/export', {
+            ...queryParams.value
+        }, `user_${new Date().getTime()}.xlsx`)
+    }
+
+    const getStatusBarClass = (patient) => {
+        if (patient.treatmentUserStatus === '0') {
+            return 'need-intervention'
+        }
+        return 'not-checked';
+    };
+
+    const getStatusText = (patient) => {
+        if (patient.treatmentUserStatus === '0') {
+            return '需进行营养干预'
+        }
+        if (patient.treatmentUserStatus === '1') {
+            return '已过复筛日'
+        }
+        if (patient.treatmentUserStatus === '2') {
+            return '待筛查'
+        }
+        if (patient.treatmentUserStatus === '3') {
+            return '未筛查'
+        }
+        if (patient.treatmentUserStatus === '4') {
+            return '已筛查'
+        }
+        if (patient.treatmentUserStatus === '5') {
+            return '复筛提醒'
+        }
+        if (patient.treatmentUserStatus === '6') {
+            return '今日复筛'
+        }
+        return '';
+    };
+
+    const getAge = (birthday) => {
+        if (!birthday) return 0;
+        const birthDate = new Date(birthday);
+        const today = new Date();
+        let age = today.getFullYear() - birthDate.getFullYear();
+        if (today.getMonth() < birthDate.getMonth() || (today.getMonth() === birthDate.getMonth() && today.getDate() < birthDate.getDate())) {
+            age--;
+        }
+        return age;
+    };
+
+    const getMonths = (birthday) => {
+        if (!birthday) return 0;
+        const birthDate = new Date(birthday);
+        const today = new Date();
+        const months = (today.getFullYear() - birthDate.getFullYear()) * 12 +
+            (today.getMonth() - birthDate.getMonth());
+        return months % 12;
+    };
+    onMounted(() => {
+        getList();
+        getDeptList(); // 初始化时加载部门数据
+    });
+
+    const showDetail = ref(false);
+    const detailData = ref({});
+    const showPatientDetail = async (patient) => {
+        
+        // 这里可以根据需要请求详情接口,或直接用patient
+        detailData.value = { ...patient };
+        showDetail.value = true;
+    };
+
+</script>
+<style scoped>
+    .item {
+        cursor: pointer;
+        padding: 8px 12px;
+        border-radius: 4px;
+        transition: all 0.3s;
+    }
+
+    .item:hover {
+        background-color: #f5f5f5;
+    }
+
+    .active-tab {
+        font-weight: 300;
+        /* 激活标签文字加粗 */
+        border-bottom: 6px solid var(--el-color-primary);
+        padding-bottom: 6px;
+        /* 调整下划线间距 */
+    }
+
+    .active-tab .el-badge__content {
+        background-color: white;
+        color: var(--el-color-primary);
+    }
+
+    .fade-enter-active,
+    .fade-leave-active {
+        transition: opacity 0.3s;
+    }
+
+    .fade-enter-from,
+    .fade-leave-to {
+        opacity: 0;
+    }
+
+    .word-count {
+        text-align: right;
+        font-size: 12px;
+        color: #999;
+        margin-top: 4px;
+    }
+
+    .patient-cards-container {
+        margin-top: 20px;
+    }
+
+    .patient-card {
+        margin-bottom: 20px;
+        border: 1px solid #e4e7ed;
+        transition: all 0.3s;
+        position: relative;
+        overflow: hidden;
+        border-radius: 4px;
+        height: 100%;
+    }
+
+    .patient-card:hover {
+        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+    }
+
+    .patient-status-bar {
+        position: absolute;
+        left: 0;
+        top: 0;
+        bottom: 0;
+        width: 32px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        color: white;
+        font-size: 16px;
+        writing-mode: vertical-lr;
+        text-orientation: upright;
+        letter-spacing: 4px;
+        text-align: center;
+        padding: 10px 0;
+    }
+
+    .patient-status-bar.need-intervention {
+        background-color: #ff4949;
+    }
+
+    .patient-status-bar.not-checked {
+        background-color: #409eff;
+    }
+
+    .patient-info {
+        padding: 15px 15px 15px 42px;
+        margin-left: 32px;
+    }
+
+    .patient-header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 10px;
+    }
+
+    .patient-name-age {
+        display: flex;
+        align-items: center;
+        gap: 60px;
+    }
+
+    .patient-name {
+        font-size: 18px;
+        font-weight: bold;
+    }
+
+    .patient-age {
+        font-size: 18px;
+        color: #606266;
+        white-space: nowrap;
+    }
+
+    .gender-icon {
+        font-size: 25px;
+        font-weight:bold;
+    }
+
+    .gender-icon.female {
+        color: #ff4949;
+    }
+
+    .gender-icon.male {
+        color: #409eff;
+    }
+
+    .patient-detail {
+        margin: 8px 0;
+        font-size: 14px;
+        color: #606266;
+    }
+
+    .detail-label {
+        color: #909399;
+        margin-right: 4px;
+        font-size: 16px;
+    }
+
+    .evaluation-info {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-top: 12px;
+        font-size: 16px;
+        position: relative;
+        min-height: 24px;
+    }
+
+    .evaluation-score {
+        flex: 1;
+        font-size: 16px;
+    }
+
+    .evaluation-status {
+        padding: 2px 8px;
+        border-radius: 4px;
+        position: absolute;
+        right: 0;
+        font-size: 16px;
+    }
+
+    .evaluation-status.evaluated {
+        color: #67c23a;
+        background-color: #f0f9eb;
+    }
+
+    .evaluation-status.not-evaluated {
+        color: #909399;
+        background-color: #f4f4f5;
+    }
+
+    .status-text {
+        writing-mode: vertical-lr;
+        text-orientation: mixed;
+        white-space: nowrap;
+        color: #fff;
+        font-size: 14px;
+        letter-spacing: 1px;
+    }
+
+    .search-form {
+        margin-bottom: 20px;
+    }
+
+    .search-form .el-form-item {
+        margin-bottom: 18px;
+        margin-right: 18px;
+    }
+
+    .search-form .el-input,
+    .search-form .el-select,
+    .search-form .el-tree-select {
+        width: 200px;
+    }
+
+    .search-form .el-button {
+        margin-left: 10px;
+    }
+
+    .status-tabs {
+        display: flex;
+        border-bottom: 1px solid #e4e7ed;
+        margin-bottom: 20px;
+        padding: 0 25px;
+    }
+
+    .tab-item {
+        position: relative;
+        padding: 0 20px 16px;
+        font-size: 22px;
+        cursor: pointer;
+        color: #606266;
+        margin-right: 32px;
+    }
+
+    .tab-item.active {
+        color: var(--el-color-primary);
+        font-weight: 500;
+    }
+
+    .tab-item.active::after {
+        content: '';
+        position: absolute;
+        bottom: -1px;
+        left: 0;
+        width: 100%;
+        height: 6px;
+        background-color: var(--el-color-primary);
+        border-radius: 3px 3px 0 0;
+    }
+
+    .tab-badge {
+        position: absolute;
+        top: -8px;
+        right: 0;
+        transform: translateX(50%);
+    }
+
+    .tab-badge :deep(.el-badge__content) {
+        background-color: #ff4949;
+    }
+
+    .empty-state {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        padding: 40px 0;
+        color: #909399;
+    }
+
+    .empty-state img {
+        width: 160px;
+        height: 160px;
+        margin-bottom: 16px;
+    }
+</style>

+ 9 - 2
vite.config.ts

@@ -2,8 +2,10 @@ import { defineConfig, loadEnv } from 'vite';
 import createPlugins from './vite/plugins';
 import autoprefixer from 'autoprefixer'; // css自动添加兼容性前缀
 import path from 'path';
+import ElementPlus from 'unplugin-element-plus/vite'; // 新增导入
 
 export default defineConfig(({ mode, command }) => {
+    
   const env = loadEnv(mode, process.cwd());
   return {
     // 部署生产环境和开发环境下的URL。
@@ -17,7 +19,10 @@ export default defineConfig(({ mode, command }) => {
       extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
     },
     // https://cn.vitejs.dev/config/#resolve-extensions
-    plugins: createPlugins(env, command === 'build'),
+    plugins: [
+      ...createPlugins(env, command === 'build'), // 保留原有插件
+      ElementPlus({ useSource: true }), // 新增 ElementPlus 自动导入样式
+    ],
     server: {
       host: '0.0.0.0',
       port: Number(env.VITE_APP_PORT),
@@ -41,6 +46,7 @@ export default defineConfig(({ mode, command }) => {
       },
       postcss: {
         plugins: [
+      
           // 浏览器兼容性
           autoprefixer(),
           {
@@ -50,7 +56,8 @@ export default defineConfig(({ mode, command }) => {
                 atRule.remove();
               }
             }
-          }
+          },
+          
         ]
       }
     },