diff --git a/apps/web-antd/src/views/business/product/health-food/api/index.ts b/apps/web-antd/src/views/business/product/health-food/api/index.ts new file mode 100644 index 00000000..9989928f --- /dev/null +++ b/apps/web-antd/src/views/business/product/health-food/api/index.ts @@ -0,0 +1,79 @@ +// 导入请求客户端 +import { requestClient } from '#/api/request'; + +// API前缀:保健食品管理接口路径 +const prefix = 'health-food/'; + +/** + * 分页查询保健食品列表 + * @param data - 查询参数对象,包含分页信息和其他筛选条件 + * @returns 返回保健食品列表数据 + */ +export async function getHealthFoodList(data: any) { + return requestClient.get(`${prefix}list`, { params: data }); +} + +/** + * 获取保健食品下拉选项列表 + * 用于下拉选择框等场景 + * @param data - 查询参数对象 + * @returns 返回保健食品选项列表 + */ +export async function getHealthFoodOption(data: any) { + return requestClient.get(`${prefix}option`, { params: data }); +} + +/** + * 获取保健食品详情 + * @param id - 保健食品ID + * @returns 返回保健食品详细信息 + */ +export async function getHealthFoodInfo(id: number) { + return requestClient.get(`${prefix}detail`, { params: { id } }); +} + +/** + * 导出保健食品数据 + * 将保健食品数据导出为Excel文件 + * @returns 返回Excel文件数据流 + */ +export async function exportHealthFoodApi() { + return requestClient.download(`${prefix}export`); +} + +/** + * 新增保健食品 + * @param data - 保健食品数据对象,包含所有必填字段 + * @returns 返回创建结果 + */ +export async function createHealthFood(data: Record) { + return requestClient.post(`${prefix}create`, data); +} + +/** + * 编辑保健食品 + * @param data - 保健食品数据对象,必须包含id字段 + * @returns 返回更新结果 + */ +export async function updateHealthFood(data: Record) { + return requestClient.post(`${prefix}update`, data); +} + +/** + * 删除保健食品 + * @param data - 删除参数对象,包含ids数组(要删除的保健食品ID列表) + * @returns 返回删除结果 + */ +export async function deleteHealthFood(data: Record) { + return requestClient.post(`${prefix}delete`, data); +} + +/** + * 导入保健食品数据 + * 通过Excel文件批量导入保健食品数据 + * @param data - 上传参数对象,包含file字段(Excel文件) + * @returns 返回导入结果 + */ +export async function importHealthFoodApi(data: Record) { + return requestClient.upload(`${prefix}import`, data); +} diff --git a/apps/web-antd/src/views/business/product/health-food/components/ExcelUpload.vue b/apps/web-antd/src/views/business/product/health-food/components/ExcelUpload.vue new file mode 100644 index 00000000..3f58f6ab --- /dev/null +++ b/apps/web-antd/src/views/business/product/health-food/components/ExcelUpload.vue @@ -0,0 +1,194 @@ + + diff --git a/apps/web-antd/src/views/business/product/health-food/components/modal.vue b/apps/web-antd/src/views/business/product/health-food/components/modal.vue new file mode 100644 index 00000000..b346d61e --- /dev/null +++ b/apps/web-antd/src/views/business/product/health-food/components/modal.vue @@ -0,0 +1,149 @@ + + diff --git a/apps/web-antd/src/views/business/product/health-food/config/form.ts b/apps/web-antd/src/views/business/product/health-food/config/form.ts new file mode 100644 index 00000000..b45a473c --- /dev/null +++ b/apps/web-antd/src/views/business/product/health-food/config/form.ts @@ -0,0 +1,250 @@ +// 导入Vben表单配置类型 +import type {VbenFormProps} from '#/adapter/form'; + +// 导入供应商选项API +import {getSupplierOption} from '#/views/system/supplier/api'; + +/** + * 保健食品管理表单配置 + * 用于新增和编辑保健食品的弹窗表单 + * 注意: + * 1. 已移除function字段(药品主治功能),因为保健食品不需要功效字段 + * 2. 已移除对应症状(indications)、使用时间(time_id)、使用方法(type_id)、频率(frequency_id)字段,因为保健食品不需要这些字段 + */ +export const modalFormProps: VbenFormProps = { + // 表单布局:12栅格系统 + wrapperClass: 'grid-cols-12', + // 通用配置 + commonConfig: { + // 所有表单项默认占满整行(12列) + formItemClass: 'col-span-12', + // 所有表单项的组件属性 + componentProps: { + class: 'w-full', + }, + }, + // 表单布局方式:水平布局 + layout: 'horizontal', + // 表单字段配置数组 + schema: [ + { + // ID字段:隐藏字段,用于编辑时标识记录 + component: 'VbenInput', + fieldName: 'id', + label: 'ID', + formItemClass: 'col-span-6', + dependencies: { + show: false, // 隐藏显示 + triggerFields: ['id'], + }, + }, + { + // 显示选择字段:隐藏字段,用于内部逻辑控制 + component: 'VbenInput', + fieldName: 'showSelect', + label: 'ID', + formItemClass: 'col-span-6', + dependencies: { + show: false, // 隐藏显示 + triggerFields: ['id'], + }, + }, + { + // 产品图片字段:必填,用于上传保健食品的主图 + component: 'Avatar', + fieldName: 'image', + label: '产品图片', + rules: 'required', // 必填验证 + formItemClass: 'col-span-6', + }, + { + // 所属供应商字段:必填,下拉选择供应商 + component: 'ApiSelect', + componentProps: { + allowClear: true, // 允许清空 + showSearch: true, // 显示搜索框 + // 自定义过滤逻辑:根据供应商名称进行搜索 + filterOption: (input: string, option: any) => { + return option?.label.toLowerCase().indexOf(input.toLowerCase()) >= 0; + }, + // 接口返回数据转换为options格式 + afterFetch: (data: { id: number; name: string }[]) => { + return data.map((item: any) => ({ + label: item.name, + value: item.id, + })); + }, + api: getSupplierOption, // 调用供应商选项API + placeholder: '请选择', + }, + fieldName: 'supplier_id', + formItemClass: 'col-span-6', + label: '所属供应商', + rules: 'required', // 必填验证 + }, + { + // 保健食品昵称字段:必填,保健食品的常用名称 + component: 'VbenInput', + componentProps: { + placeholder: '请输入保健食品昵称', + }, + fieldName: 'drug_name', + formItemClass: 'col-span-6', + label: '保健食品昵称', + rules: 'required', // 必填验证 + }, + { + // 保健食品别名字段:必填,保健食品的其他名称 + component: 'VbenInput', + componentProps: { + placeholder: '请输入保健食品别名', + }, + fieldName: 'drug_alias', + formItemClass: 'col-span-6', + label: '保健食品别名', + rules: 'required', // 必填验证 + }, + { + // 保健食品编号字段:必填,保健食品的唯一编号 + component: 'VbenInput', + componentProps: { + placeholder: '请输入保健食品编号', + }, + fieldName: 'drug_number', + formItemClass: 'col-span-6', + label: '保健食品编号', + rules: 'required', // 必填验证 + }, + { + // 规格字段:必填,保健食品的规格信息 + component: 'VbenInput', + componentProps: { + placeholder: '请输入规格', + }, + fieldName: 'specification', + formItemClass: 'col-span-6', + label: '规格', + rules: 'required', // 必填验证 + }, + { + // 单位字段:必填,下拉选择单位选项 + component: 'VbenSelect', + componentProps: { + options: [], // 选项通过动态加载填充 + placeholder: '请选择', + }, + fieldName: 'unit_id', + formItemClass: 'col-span-6', + label: '单位', + rules: 'required', // 必填验证 + }, + // 注意:已移除使用时间(time_id)、使用方法(type_id)、频率(frequency_id)字段,因为保健食品不需要这些字段 + { + // 商品状态字段:必填,单选按钮组,选择商品状态 + component: 'RadioGroup', + componentProps: { + placeholder: '请选择', + options: [ + { + label: '草稿', + value: 1, + }, + { + label: '下架', + value: 2, + }, + { + label: '上架', + value: 3, + }, + ], + }, + defaultValue: 1, // 默认值为草稿 + formItemClass: 'col-span-12', + fieldName: 'status', + label: '商品状态', + rules: 'required', // 必填验证 + }, + { + // 是否处方药字段:必填,单选按钮组,选择是否为处方药 + component: 'RadioGroup', + componentProps: { + placeholder: '请选择', + options: [ + { + label: '是', + value: 0, + }, + { + label: '否', + value: 1, + }, + ], + }, + defaultValue: 1, // 默认值为否 + formItemClass: 'col-span-12', + fieldName: 'is_otc', + label: '是否处方药', + rules: 'required', // 必填验证 + }, + // 注意:已移除function字段(药品主治功能)和对应症状(indications)字段,因为保健食品不需要这些字段 + { + // 产品说明书字段:必填,用于上传保健食品的说明书图片 + component: 'Avatar', + fieldName: 'instruction', + label: '产品说明书', + rules: 'required', // 必填验证 + formItemClass: 'col-span-6', + }, + { + // 商品介绍图字段:可选,支持上传多张图片,最多20张 + component: 'UploadImageSortable', + fieldName: 'introduction_images', + label: '商品介绍图', + formItemClass: 'col-span-12', + componentProps: { + maxCount: 20, // 最多上传20张图片 + multiple: true, // 支持多选 + }, + }, + ], + // 不显示默认的表单操作按钮(确认、取消),由弹窗组件控制 + showDefaultActions: false, +}; + +/** + * Excel上传表单配置 + * 用于批量导入保健食品数据的弹窗表单 + */ +export const uploadExcelProps: VbenFormProps = { + // 表单布局:12栅格系统 + wrapperClass: 'grid-cols-12', + // 通用配置 + commonConfig: { + // 所有表单项默认占满整行(12列) + formItemClass: 'col-span-12', + // 所有表单项的组件属性 + componentProps: { + class: 'w-full', + }, + }, + // 表单布局方式:水平布局 + layout: 'horizontal', + // 表单字段配置数组 + schema: [ + { + // Excel文件上传字段:必填,用于选择要导入的Excel文件 + component: 'Upload', + componentProps: { + placeholder: '请选择', + multiple: true, // 支持多选(虽然通常只上传一个文件) + }, + fieldName: 'frequency_id', + formItemClass: 'col-span-12', + label: '导入excel', + rules: 'file', // 文件验证规则 + }, + ], + // 不显示默认的表单操作按钮(确认、取消),由弹窗组件控制 + showDefaultActions: false, +}; diff --git a/apps/web-antd/src/views/business/product/health-food/config/search.ts b/apps/web-antd/src/views/business/product/health-food/config/search.ts new file mode 100644 index 00000000..15b7f8ab --- /dev/null +++ b/apps/web-antd/src/views/business/product/health-food/config/search.ts @@ -0,0 +1,43 @@ +// 导入Vben表单配置类型 +import type { VbenFormProps } from '#/adapter/form'; + +/** + * 保健食品管理搜索表单配置 + * 用于在列表页面顶部进行搜索筛选 + */ +export const formOptions: VbenFormProps = { + // 默认展开搜索表单(不折叠) + collapsed: false, + // 搜索表单字段配置数组 + schema: [ + { + // 保健食品名称搜索字段:支持模糊搜索 + component: 'VbenInput', + componentProps: { + placeholder: '输入名称', + }, + defaultValue: '', // 默认值为空字符串 + fieldName: 'name', + label: '保健食品名称', + }, + // 注意:可以根据需要添加更多搜索字段,如时间范围等 + // { + // component: 'RangePicker', + // componentProps: { + // format: 'YYYY-MM-DD', // 确保格式与你需要的一致 + // }, + // fieldName: 'search_time', + // label: '时间范围', + // }, + ], + // 控制表单是否显示折叠按钮 + showCollapseButton: true, + // 提交按钮配置 + submitButtonOptions: { + content: '查询', // 按钮文字 + }, + // 是否在字段值改变时自动提交表单 + submitOnChange: true, + // 按下回车时是否提交表单 + submitOnEnter: false, +}; diff --git a/apps/web-antd/src/views/business/product/health-food/config/table.ts b/apps/web-antd/src/views/business/product/health-food/config/table.ts new file mode 100644 index 00000000..b876c971 --- /dev/null +++ b/apps/web-antd/src/views/business/product/health-food/config/table.ts @@ -0,0 +1,105 @@ +// 导入VxeGrid配置类型 +import type { VxeGridProps } from '#/adapter/vxe-table'; + +// 导入保健食品列表查询API +import { getHealthFoodList } from '../api'; + +/** + * 表格行数据类型定义 + */ +interface RowType { + id: string; // 保健食品ID + name: string; // 保健食品名称 + logo: string; // 保健食品Logo + introduce: string; // 保健食品介绍 + created_at: string; // 创建时间 +} + +/** + * 保健食品管理表格配置 + * 定义表格的列、分页、查询等配置 + */ +export const gridOptions: VxeGridProps = { + // 复选框配置 + checkboxConfig: { + highlight: true, // 高亮选中行 + labelField: '', // 标签字段 + }, + // 列配置 + columnConfig: { + useKey: true, // 使用key作为列的唯一标识 + }, + // 行配置 + rowConfig: { + useKey: true, // 使用key作为行的唯一标识 + }, + // 表格列定义数组 + columns: [ + { type: 'checkbox', width: 60 }, // 复选框列 + { field: 'id', align: 'left', title: 'ID', width: 100 }, // ID列 + { field: 'drug_name', align: 'left', title: '保健食品名称' }, // 保健食品名称列 + { field: 'pinyin_simple', title: '拼音' }, // 拼音列 + { field: 'supplier.name', title: '供应商', slots: { default: 'supplier' } }, // 供应商列,使用插槽自定义显示 + { + field: 'image', + align: 'left', + title: '产品图片', + slots: { default: 'image' }, // 使用插槽显示图片 + width: 130, + }, + { + field: 'instruction', + align: 'left', + title: '说明书', + slots: { default: 'instruction' }, // 使用插槽显示说明书 + width: 130, + }, + // 注意:已移除function列(主要功能),因为保健食品不需要功效字段 + { field: 'specification', title: '规格' }, // 规格列 + { field: 'status', title: '状态', slots: { default: 'status' } }, // 状态列,使用插槽显示标签 + { field: 'created_at', title: '发布时间' }, // 发布时间列 + { type: 'html', title: '操作', width: 230, slots: { default: 'action' } }, // 操作列,使用插槽显示操作按钮 + ], + // 保持数据源 + keepSource: true, + // 分页配置 + pagerConfig: {}, + // 代理配置:用于数据请求 + proxyConfig: { + ajax: { + // 请求后端接口方法 + // 当表格需要加载数据时,会调用此方法 + query: async ({ page }, formValues) => { + // 调用保健食品列表查询API + return await getHealthFoodList({ + page: page.currentPage, // 当前页码 + pageSize: page.pageSize, // 每页条数 + ...formValues, // 合并搜索表单的值 + }); + }, + }, + }, + // 表格高度:自动适应 + height: 'auto', + // 是否显示边框 + border: false, + // 工具栏配置 + toolbarConfig: { + // 是否显示搜索表单控制按钮 + // @ts-ignore 正式环境时有完整的类型声明 + search: true, + refresh: true, // 显示刷新按钮 + print: false, // 不显示打印按钮 + export: false, // 不显示导出按钮(使用自定义导出按钮) + zoom: true, // 显示最大化最小化按钮 + slots: { + buttons: 'toolbar-buttons', // 自定义工具栏按钮插槽 + }, + custom: { + // 自定义列-图标 + icon: 'vxe-icon-menu', + }, + }, + // 是否显示溢出内容 + showOverflow: false, +}; diff --git a/apps/web-antd/src/views/business/product/health-food/index.vue b/apps/web-antd/src/views/business/product/health-food/index.vue new file mode 100644 index 00000000..e37c31cd --- /dev/null +++ b/apps/web-antd/src/views/business/product/health-food/index.vue @@ -0,0 +1,223 @@ + + +