1. 管理员管理模块拆分
2. 图片上传自动压缩(大于850kb) 3. 省市区选择组件重构,支持搜索
This commit is contained in:
@@ -2,6 +2,8 @@ import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
import { getWarehouseProductTypeOptions } from '#/views/business/warehouse-drug-management/admin/api';
|
||||
|
||||
import {
|
||||
getStoreDrugsByTypeApi,
|
||||
updateStoreDrugPricesApi,
|
||||
@@ -16,11 +18,21 @@ export interface DrugItem {
|
||||
buy_price: number;
|
||||
}
|
||||
|
||||
export interface ProductTypeOption {
|
||||
label: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
const TCM_PLACEHOLDER_IMAGE =
|
||||
'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk_upload_20250510/cd470ebf97e31c4048ba502ba71b66a3.jpg';
|
||||
|
||||
export async function fetchProductTypeOptions(): Promise<ProductTypeOption[]> {
|
||||
const data = await getWarehouseProductTypeOptions();
|
||||
return Array.isArray(data) ? data : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 单行保存函数
|
||||
* @param row 当前行数据
|
||||
* @param storeId 诊所ID
|
||||
* @param gridApi 表格API实例
|
||||
*/
|
||||
export const handleSaveRow = async (
|
||||
row: DrugItem,
|
||||
@@ -28,12 +40,11 @@ export const handleSaveRow = async (
|
||||
gridApi: any,
|
||||
) => {
|
||||
if (!storeId) {
|
||||
message.error('诊所ID不能为空');
|
||||
message.error('门店ID不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取当前行的最新数据(从表格中获取,包含编辑后的值)
|
||||
const tableData = gridApi?.grid?.getTableData?.();
|
||||
const fullData = tableData?.fullData || [];
|
||||
const currentRow = fullData.find((item: DrugItem) => item.id === row.id);
|
||||
@@ -43,7 +54,6 @@ export const handleSaveRow = async (
|
||||
return;
|
||||
}
|
||||
|
||||
// 构建提交数据(只提交当前行)
|
||||
const drugs = [
|
||||
{
|
||||
id: currentRow.id,
|
||||
@@ -52,7 +62,6 @@ export const handleSaveRow = async (
|
||||
},
|
||||
];
|
||||
|
||||
// 验证数据
|
||||
for (const drug of drugs) {
|
||||
if (drug.price < 0 || drug.buy_price < 0) {
|
||||
message.error('价格不能为负数');
|
||||
@@ -70,7 +79,6 @@ export const handleSaveRow = async (
|
||||
});
|
||||
|
||||
message.success('保存成功');
|
||||
// 刷新表格数据
|
||||
gridApi?.reload?.();
|
||||
} catch (error: any) {
|
||||
message.error(error?.message || '保存失败');
|
||||
@@ -79,24 +87,17 @@ export const handleSaveRow = async (
|
||||
|
||||
/**
|
||||
* 批量保存函数(只保存修改的数据)
|
||||
* @param gridApi 表格API实例
|
||||
* @param storeId 诊所ID
|
||||
*/
|
||||
export const handleBatchSave = async (
|
||||
gridApi: any,
|
||||
storeId: number,
|
||||
) => {
|
||||
export const handleBatchSave = async (gridApi: any, storeId: number) => {
|
||||
if (!storeId) {
|
||||
message.error('诊所ID不能为空');
|
||||
message.error('门店ID不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 使用getRecordset获取修改的记录
|
||||
const recordset = gridApi?.grid?.getRecordset?.();
|
||||
const updateRecords = recordset?.updateRecords || [];
|
||||
|
||||
// 如果getRecordset没有返回修改记录,尝试获取所有数据
|
||||
if (updateRecords.length === 0) {
|
||||
const tableData = gridApi?.grid?.getTableData?.();
|
||||
const fullData = tableData?.fullData || [];
|
||||
@@ -106,14 +107,12 @@ export const handleBatchSave = async (
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果没有修改记录,提交所有数据
|
||||
const drugs = fullData.map((row: DrugItem) => ({
|
||||
id: row.id,
|
||||
price: parseFloat(String(row.price)) || 0,
|
||||
buy_price: parseFloat(String(row.buy_price)) || 0,
|
||||
}));
|
||||
|
||||
// 验证数据
|
||||
for (const drug of drugs) {
|
||||
if (drug.price < 0 || drug.buy_price < 0) {
|
||||
message.error('价格不能为负数');
|
||||
@@ -135,17 +134,12 @@ export const handleBatchSave = async (
|
||||
return;
|
||||
}
|
||||
|
||||
// 构建提交数据(只提交修改过的数据)
|
||||
const dataToSave = updateRecords;
|
||||
|
||||
// 构建提交数据
|
||||
const drugs = dataToSave.map((row: DrugItem) => ({
|
||||
const drugs = updateRecords.map((row: DrugItem) => ({
|
||||
id: row.id,
|
||||
price: parseFloat(String(row.price)) || 0,
|
||||
buy_price: parseFloat(String(row.buy_price)) || 0,
|
||||
}));
|
||||
|
||||
// 验证数据
|
||||
for (const drug of drugs) {
|
||||
if (drug.price < 0 || drug.buy_price < 0) {
|
||||
message.error('价格不能为负数');
|
||||
@@ -163,7 +157,6 @@ export const handleBatchSave = async (
|
||||
});
|
||||
|
||||
message.success('保存成功');
|
||||
// 刷新表格数据
|
||||
gridApi?.reload?.();
|
||||
} catch (error: any) {
|
||||
message.error(error?.message || '保存失败');
|
||||
@@ -171,103 +164,29 @@ export const handleBatchSave = async (
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取中药表格配置
|
||||
* @param storeId 诊所ID
|
||||
* @param onSaveRow 单行保存回调函数
|
||||
* @returns 表格配置对象
|
||||
* 按 ProductTypeEnum 获取改价表格配置
|
||||
*/
|
||||
export const getChinaMedicineGridOptions = (
|
||||
storeId: number,
|
||||
export const getDrugPriceGridOptions = (
|
||||
getStoreId: () => number,
|
||||
getProductType: () => number,
|
||||
onSaveRow: (row: DrugItem) => Promise<void>,
|
||||
): VxeGridProps<DrugItem> => ({
|
||||
columns: [
|
||||
): VxeGridProps<DrugItem> => {
|
||||
const showImage = getProductType() !== 1;
|
||||
|
||||
const columns: VxeGridProps<DrugItem>['columns'] = [
|
||||
{ type: 'seq', width: 60, title: '序号' },
|
||||
{ field: 'drug_name', title: '药品名称' },
|
||||
{
|
||||
field: 'price',
|
||||
title: '零售价',
|
||||
editRender: { name: 'input', props: { type: 'number', step: 0.01, min: 0 } },
|
||||
formatter: ({ cellValue }) => {
|
||||
if (cellValue === null || cellValue === undefined || cellValue === '') {
|
||||
return '0.00';
|
||||
}
|
||||
const num = parseFloat(String(cellValue));
|
||||
return isNaN(num) ? '0.00' : num.toFixed(2);
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'buy_price',
|
||||
title: '供货价',
|
||||
editRender: { name: 'input', props: { type: 'number', step: 0.01, min: 0 } },
|
||||
formatter: ({ cellValue }) => {
|
||||
if (cellValue === null || cellValue === undefined || cellValue === '') {
|
||||
return '0.00';
|
||||
}
|
||||
const num = parseFloat(String(cellValue));
|
||||
return isNaN(num) ? '0.00' : num.toFixed(2);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
slots: { default: 'china-action' },
|
||||
},
|
||||
],
|
||||
editConfig: {
|
||||
mode: 'cell',
|
||||
trigger: 'click',
|
||||
showStatus: true,
|
||||
},
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page }, formValues) => {
|
||||
if (!storeId) {
|
||||
return { items: [], total: 0 };
|
||||
}
|
||||
const res = await getStoreDrugsByTypeApi(storeId, 1);
|
||||
let items = res || [];
|
||||
];
|
||||
|
||||
// 如果有关键词搜索,进行过滤
|
||||
if (formValues?.drug_name) {
|
||||
const keyword = String(formValues.drug_name).toLowerCase();
|
||||
items = items.filter((item: DrugItem) =>
|
||||
item.drug_name?.toLowerCase().includes(keyword),
|
||||
);
|
||||
}
|
||||
|
||||
return { items, total: items.length };
|
||||
},
|
||||
},
|
||||
},
|
||||
toolbarConfig: {
|
||||
search: true,
|
||||
refresh: true,
|
||||
zoom: true,
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
},
|
||||
},
|
||||
height: 500,
|
||||
showOverflow: true,
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取西药表格配置
|
||||
* @param storeId 诊所ID
|
||||
* @param onSaveRow 单行保存回调函数
|
||||
* @returns 表格配置对象
|
||||
*/
|
||||
export const getWesternMedicineGridOptions = (
|
||||
storeId: number,
|
||||
onSaveRow: (row: DrugItem) => Promise<void>,
|
||||
): VxeGridProps<DrugItem> => ({
|
||||
columns: [
|
||||
{ type: 'seq', width: 60, title: '序号' },
|
||||
{ field: 'drug_name', title: '药品名称' },
|
||||
{
|
||||
if (showImage) {
|
||||
columns.push({
|
||||
field: 'image',
|
||||
title: '图片',
|
||||
slots: { default: 'western-image' },
|
||||
},
|
||||
slots: { default: 'drug-image' },
|
||||
});
|
||||
}
|
||||
|
||||
columns.push(
|
||||
{
|
||||
field: 'price',
|
||||
title: '零售价',
|
||||
@@ -294,43 +213,50 @@ export const getWesternMedicineGridOptions = (
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
slots: { default: 'western-action' },
|
||||
slots: { default: 'row-action' },
|
||||
},
|
||||
],
|
||||
editConfig: {
|
||||
mode: 'cell',
|
||||
trigger: 'click',
|
||||
showStatus: true,
|
||||
},
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page }, formValues) => {
|
||||
if (!storeId) {
|
||||
return { items: [], total: 0 };
|
||||
}
|
||||
const res = await getStoreDrugsByTypeApi(storeId, 2);
|
||||
let items = res || [];
|
||||
);
|
||||
|
||||
// 如果有关键词搜索,进行过滤
|
||||
if (formValues?.drug_name) {
|
||||
const keyword = String(formValues.drug_name).toLowerCase();
|
||||
items = items.filter((item: DrugItem) =>
|
||||
item.drug_name?.toLowerCase().includes(keyword),
|
||||
);
|
||||
}
|
||||
return {
|
||||
columns,
|
||||
editConfig: {
|
||||
mode: 'cell',
|
||||
trigger: 'click',
|
||||
showStatus: true,
|
||||
},
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async (_ctx, formValues) => {
|
||||
const storeId = getStoreId();
|
||||
const productType = getProductType();
|
||||
if (!storeId) {
|
||||
return { items: [], total: 0 };
|
||||
}
|
||||
const res = await getStoreDrugsByTypeApi(storeId, productType);
|
||||
let items = res || [];
|
||||
|
||||
return { items, total: items.length };
|
||||
if (formValues?.drug_name) {
|
||||
const keyword = String(formValues.drug_name).toLowerCase();
|
||||
items = items.filter((item: DrugItem) =>
|
||||
item.drug_name?.toLowerCase().includes(keyword),
|
||||
);
|
||||
}
|
||||
|
||||
return { items, total: items.length };
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
toolbarConfig: {
|
||||
search: true,
|
||||
refresh: true,
|
||||
zoom: true,
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
toolbarConfig: {
|
||||
search: true,
|
||||
refresh: true,
|
||||
zoom: true,
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
},
|
||||
},
|
||||
},
|
||||
height: 500,
|
||||
showOverflow: true,
|
||||
});
|
||||
height: 500,
|
||||
showOverflow: true,
|
||||
};
|
||||
};
|
||||
|
||||
export { TCM_PLACEHOLDER_IMAGE };
|
||||
|
||||
Reference in New Issue
Block a user