feat: 金方相关
feat: 患者信息身份证改成非必填
This commit is contained in:
@@ -18,13 +18,21 @@ export async function getDeliveryWarehouseProductInfo(id: number) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 平台审核:status 必为 2 下架或 3 上架;需填 zone_id
|
||||
* 平台审核(一次提交):
|
||||
* 主数据审过 + 总仓供货价/售价同步门店 + 绑仓三费 + 可选初始入库
|
||||
*/
|
||||
export async function auditDeliveryWarehouseProduct(data: {
|
||||
id: number;
|
||||
status: 2 | 3;
|
||||
zone_id: number;
|
||||
category_id?: number;
|
||||
drug_number: string;
|
||||
market_price: number;
|
||||
price: number;
|
||||
quote: number;
|
||||
promo_fee: number;
|
||||
platform_fee: number;
|
||||
initial_stock?: number;
|
||||
}) {
|
||||
return requestClient.post<any>(`${prefix}audit`, data);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* 平台仓品审核弹窗
|
||||
* 必选上架/下架 + 所属分区;审核成功后由列表页打开仓药绑定弹窗
|
||||
* 平台仓品审核弹窗(单次提交)
|
||||
* 分区/分类/上下架 + ERP + 总仓供货价/售价 + 绑仓三费 + 可选初始库存
|
||||
* 提交后由后端一次性完成主数据审过、总仓同步门店、绑仓与入库
|
||||
*/
|
||||
import { nextTick, ref } from 'vue';
|
||||
import { h, onUnmounted, ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { Descriptions, Image, message, Tag } from 'ant-design-vue';
|
||||
import { Button, Descriptions, Image, message, Tag } from 'ant-design-vue';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { getDrugCategoriesTree, getZoneOptions } from '#/views/business/product/drug-categories/api';
|
||||
import {
|
||||
calcFeeSum,
|
||||
isFeeOverSalePrice,
|
||||
registerFeeOverTipHandler,
|
||||
resetAutoPromoFeeKey,
|
||||
syncFeeSumDisplay,
|
||||
} from '#/views/system/delivery-warehouse-drug/config/form';
|
||||
|
||||
import {
|
||||
auditDeliveryWarehouseProduct,
|
||||
@@ -19,8 +27,10 @@ import {
|
||||
|
||||
const gridApi = ref();
|
||||
const detail = ref<Record<string, any> | null>(null);
|
||||
/** 审核成功后回传给列表页,用于打开绑仓弹窗 */
|
||||
const onBindPreset = ref<((preset: Record<string, any>) => void) | null>(null);
|
||||
/** 三费超售价红色提示 */
|
||||
const feeOverTip = ref('');
|
||||
/** 记录已按售价自动填过平台费的售价,避免反复覆盖手改 */
|
||||
const lastAutoPlatformSale = ref(0);
|
||||
|
||||
const [Form, formApi] = useVbenForm({
|
||||
wrapperClass: 'grid-cols-12',
|
||||
@@ -96,12 +106,153 @@ const [Form, formApi] = useVbenForm({
|
||||
fieldName: 'status',
|
||||
label: '审核结果',
|
||||
rules: 'selectRequired',
|
||||
help: '审核通过后按所选结果上架或下架,并打开绑仓弹窗',
|
||||
help: '主数据上下架;总仓/绑仓状态同步跟随',
|
||||
},
|
||||
{
|
||||
component: 'VbenInput',
|
||||
componentProps: {
|
||||
placeholder: '请输入 ERP 编号,无则点右侧「非erp」',
|
||||
allowClear: true,
|
||||
},
|
||||
fieldName: 'drug_number',
|
||||
label: 'ERP编号',
|
||||
rules: 'required',
|
||||
help: '可填真实编号;无 ERP 点「非erp」填入 -1',
|
||||
// 渲染时再点选,此时 formApi 已就绪
|
||||
suffix: () =>
|
||||
h(
|
||||
Button,
|
||||
{
|
||||
size: 'small',
|
||||
type: 'link',
|
||||
onClick: (e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
formApi.setFieldValue('drug_number', '-1');
|
||||
},
|
||||
},
|
||||
{ default: () => '非erp' },
|
||||
),
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
placeholder: '请输入仓库供货价',
|
||||
min: 0,
|
||||
precision: 4,
|
||||
class: 'w-full',
|
||||
},
|
||||
fieldName: 'market_price',
|
||||
label: '仓库供货价',
|
||||
rules: 'required',
|
||||
help: '写入总仓并同步到门店供货价',
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
placeholder: '请输入售价',
|
||||
min: 0,
|
||||
precision: 4,
|
||||
class: 'w-full',
|
||||
},
|
||||
fieldName: 'price',
|
||||
label: '售价',
|
||||
rules: 'required',
|
||||
help: '写入总仓销售价;三费合计不得超过该值',
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
placeholder: '请输入绑定仓库报价',
|
||||
min: 0,
|
||||
precision: 4,
|
||||
class: 'w-full',
|
||||
},
|
||||
fieldName: 'quote',
|
||||
label: '绑仓报价',
|
||||
rules: 'required',
|
||||
help: '默认取仓侧上传报价,可修改',
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
placeholder: '请输入平台费',
|
||||
min: 0,
|
||||
precision: 4,
|
||||
class: 'w-full',
|
||||
},
|
||||
fieldName: 'platform_fee',
|
||||
label: '平台费',
|
||||
rules: 'required',
|
||||
help: '默认售价的 5%,可改',
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
placeholder: '自动=售价−报价−平台费',
|
||||
min: 0,
|
||||
precision: 4,
|
||||
class: 'w-full',
|
||||
},
|
||||
fieldName: 'promo_fee',
|
||||
label: '推广费',
|
||||
rules: 'required',
|
||||
help: '有售价时自动计算,可微调',
|
||||
},
|
||||
{
|
||||
component: 'VbenInput',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
placeholder: '报价+推广费+平台费',
|
||||
},
|
||||
fieldName: '_fee_sum',
|
||||
label: '费用合计',
|
||||
// 把 price 映射为仓药绑定逻辑里的 sale_price,复用三费联动
|
||||
dependencies: {
|
||||
async trigger(values, formApiInst) {
|
||||
const sale = Number(values.price) || 0;
|
||||
// 售价变化时默认平台费 = 售价 * 5%(仅该售价首次自动填)
|
||||
if (sale > 0 && lastAutoPlatformSale.value !== sale) {
|
||||
const platform = Number((sale * 0.05).toFixed(4));
|
||||
await formApiInst.setFieldValue('platform_fee', platform);
|
||||
lastAutoPlatformSale.value = sale;
|
||||
values = { ...values, platform_fee: platform };
|
||||
}
|
||||
syncFeeSumDisplay(
|
||||
{
|
||||
...values,
|
||||
sale_price: sale,
|
||||
},
|
||||
formApiInst,
|
||||
);
|
||||
},
|
||||
triggerFields: ['quote', 'promo_fee', 'platform_fee', 'price'],
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
placeholder: '选填,默认 0',
|
||||
min: 0,
|
||||
precision: 0,
|
||||
class: 'w-full',
|
||||
},
|
||||
fieldName: 'initial_stock',
|
||||
label: '初始库存',
|
||||
help: '大于 0 时绑仓后自动入库并记流水',
|
||||
defaultValue: 0,
|
||||
},
|
||||
],
|
||||
showDefaultActions: false,
|
||||
});
|
||||
|
||||
registerFeeOverTipHandler((tip) => {
|
||||
feeOverTip.value = tip;
|
||||
});
|
||||
onUnmounted(() => {
|
||||
registerFeeOverTipHandler(null);
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
fullscreenButton: false,
|
||||
draggable: true,
|
||||
@@ -121,21 +272,45 @@ const [Modal, modalApi] = useVbenModal({
|
||||
message.warning('请选择所属分区');
|
||||
return;
|
||||
}
|
||||
const drugNumber = String(values.drug_number || '').trim();
|
||||
if (!drugNumber) {
|
||||
message.warning('请填写 ERP 编号(无 ERP 可点「非erp」填 -1)');
|
||||
return;
|
||||
}
|
||||
const feeValues = {
|
||||
quote: values.quote,
|
||||
promo_fee: values.promo_fee,
|
||||
platform_fee: values.platform_fee,
|
||||
sale_price: values.price,
|
||||
};
|
||||
if (isFeeOverSalePrice(feeValues)) {
|
||||
message.warning(
|
||||
`三费合计已超过售价 ¥${Number(values.price).toFixed(4)}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (Number(calcFeeSum(feeValues)) <= 0) {
|
||||
message.warning('报价/推广费/平台费合计必须大于0');
|
||||
return;
|
||||
}
|
||||
modalApi.setState({ loading: true, confirmLoading: true });
|
||||
auditDeliveryWarehouseProduct({
|
||||
id: Number(values.id),
|
||||
status: status as 2 | 3,
|
||||
zone_id: Number(values.zone_id),
|
||||
category_id: Number(values.category_id || 0),
|
||||
drug_number: drugNumber,
|
||||
market_price: Number(values.market_price),
|
||||
price: Number(values.price),
|
||||
quote: Number(values.quote),
|
||||
promo_fee: Number(values.promo_fee),
|
||||
platform_fee: Number(values.platform_fee),
|
||||
initial_stock: Number(values.initial_stock || 0),
|
||||
})
|
||||
.then((res: any) => {
|
||||
message.success('审核成功,请完成仓药绑定');
|
||||
.then(() => {
|
||||
message.success('审核成功,已完成总仓同步与仓药绑定');
|
||||
gridApi.value?.query?.() ?? gridApi.value?.reload?.();
|
||||
const preset = res?.bind_preset || res?.data?.bind_preset;
|
||||
modalApi.close();
|
||||
if (preset && onBindPreset.value) {
|
||||
nextTick(() => onBindPreset.value?.(preset));
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
modalApi.setState({ loading: false, confirmLoading: false });
|
||||
@@ -145,31 +320,53 @@ const [Modal, modalApi] = useVbenModal({
|
||||
await formApi.validateAndSubmitForm();
|
||||
},
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
||||
onBindPreset.value = isOpen ? modalApi.getData()?.onBindPreset || null : null;
|
||||
if (!isOpen) {
|
||||
detail.value = null;
|
||||
feeOverTip.value = '';
|
||||
return;
|
||||
}
|
||||
await formApi.resetForm();
|
||||
const data = modalApi.getData<Record<string, any>>() || {};
|
||||
gridApi.value = data.gridApi ?? null;
|
||||
resetAutoPromoFeeKey();
|
||||
lastAutoPlatformSale.value = 0;
|
||||
feeOverTip.value = '';
|
||||
await formApi.resetForm();
|
||||
const id = Number(data.id || data.values?.id || 0);
|
||||
await formApi.setValues({ id, status: undefined, zone_id: undefined, category_id: undefined });
|
||||
let row = data.values || { id };
|
||||
if (id > 0) {
|
||||
const row = data.values || { id };
|
||||
try {
|
||||
const info = await getDeliveryWarehouseProductInfo(id);
|
||||
detail.value = { ...row, ...(info || {}) };
|
||||
row = { ...row, ...(info || {}) };
|
||||
} catch {
|
||||
detail.value = row;
|
||||
// 详情失败仍用列表行
|
||||
}
|
||||
}
|
||||
detail.value = row;
|
||||
const uploadQuote = Number(row.upload_quote || 0);
|
||||
await formApi.setValues({
|
||||
id,
|
||||
status: undefined,
|
||||
zone_id: undefined,
|
||||
category_id: undefined,
|
||||
// 仓侧默认常为 -1,保留回填,也可点「非erp」重填
|
||||
drug_number:
|
||||
row.drug_number != null && String(row.drug_number) !== ''
|
||||
? String(row.drug_number)
|
||||
: '',
|
||||
market_price: undefined,
|
||||
price: undefined,
|
||||
quote: uploadQuote > 0 ? uploadQuote : undefined,
|
||||
platform_fee: undefined,
|
||||
promo_fee: undefined,
|
||||
initial_stock: 0,
|
||||
_fee_sum: uploadQuote > 0 ? String(uploadQuote.toFixed(4)) : '',
|
||||
});
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal title="仓品审核" class="w-[80%] md:w-[50%] lg:w-[40%]">
|
||||
<Modal title="仓品审核" class="w-[80%] md:w-[560px] lg:w-[520px]">
|
||||
<div v-if="detail" class="mb-4">
|
||||
<Descriptions :column="1" size="small" bordered>
|
||||
<Descriptions.Item label="药品名称">
|
||||
@@ -196,5 +393,12 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</Descriptions>
|
||||
</div>
|
||||
<Form />
|
||||
<div
|
||||
v-if="feeOverTip"
|
||||
class="mt-2 text-sm"
|
||||
style="color: hsl(var(--destructive))"
|
||||
>
|
||||
{{ feeOverTip }}
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* 平台「仓品审核」列表页
|
||||
* 审核通过后自动打开仓药绑定弹窗,预填本仓+药品+报价
|
||||
* 审核弹窗一次提交:主数据 + 总仓同步 + 绑仓三费/入库
|
||||
*/
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
|
||||
@@ -9,7 +9,6 @@ import { Image, Tag } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { TableAction } from '#/components/table-action';
|
||||
import BindModalDemo from '#/views/system/delivery-warehouse-drug/components/modal.vue';
|
||||
|
||||
import AuditModalDemo from './components/audit-modal.vue';
|
||||
import { formOptions } from './config/search';
|
||||
@@ -26,37 +25,6 @@ const [AuditModal, auditModalApi] = useVbenModal({
|
||||
connectedComponent: AuditModalDemo,
|
||||
});
|
||||
|
||||
const [BindModal, bindModalApi] = useVbenModal({
|
||||
connectedComponent: BindModalDemo,
|
||||
});
|
||||
|
||||
/**
|
||||
* 审核成功后打开仓药绑定:锁定药品、预填仓库与报价
|
||||
*/
|
||||
function openBindFromPreset(preset: Record<string, any>) {
|
||||
if (!preset?.drug_id || !preset?.warehouse_id) {
|
||||
return;
|
||||
}
|
||||
bindModalApi.setData({
|
||||
update: false,
|
||||
lockDrug: true,
|
||||
presetDrug: preset.presetDrug || {
|
||||
id: preset.drug_id,
|
||||
drug_name: preset.drug_name,
|
||||
specification: preset.specification,
|
||||
image: preset.image,
|
||||
},
|
||||
values: {
|
||||
warehouse_id: preset.warehouse_id,
|
||||
drug_id: preset.drug_id,
|
||||
quote: preset.quote,
|
||||
status: 2,
|
||||
},
|
||||
gridApi,
|
||||
});
|
||||
bindModalApi.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开审核弹窗(仅待审可点)
|
||||
*/
|
||||
@@ -68,7 +36,6 @@ function openAudit(row: Record<string, any>) {
|
||||
id: row.id,
|
||||
values: row,
|
||||
gridApi,
|
||||
onBindPreset: openBindFromPreset,
|
||||
});
|
||||
auditModalApi.open();
|
||||
}
|
||||
@@ -81,7 +48,6 @@ function auditTagColor(status: number) {
|
||||
<template>
|
||||
<Page auto-content-height title="仓品审核">
|
||||
<AuditModal />
|
||||
<BindModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<TableAction :actions="[]" :drop-down-actions="[]" />
|
||||
|
||||
Reference in New Issue
Block a user