+
+import { ref, watch } from 'vue';
+
+import { Empty, Spin, Table } from 'ant-design-vue';
+
+import { getUserBindListApi } from '#/views/business/store/settings/api';
+
+const props = defineProps<{
+ salespersonId: number;
+ open: boolean;
+}>();
+
+const loading = ref(false);
+const list = ref([]);
+const total = ref(0);
+const page = ref(1);
+const pageSize = ref(10);
+
+const columns = [
+ { title: '用户昵称', dataIndex: 'user_nick_name', key: 'user_nick_name' },
+ { title: '手机号', dataIndex: 'user_phone', key: 'user_phone' },
+ { title: '绑定时间', dataIndex: 'bind_at_text', key: 'bind_at_text' },
+];
+
+async function loadList() {
+ if (!props.salespersonId) return;
+ loading.value = true;
+ try {
+ const res = await getUserBindListApi({
+ salesperson_id: props.salespersonId,
+ page: page.value,
+ pageSize: pageSize.value,
+ });
+ list.value = res?.items ?? [];
+ total.value = res?.total ?? 0;
+ } finally {
+ loading.value = false;
+ }
+}
+
+watch(
+ () => [props.open, props.salespersonId],
+ ([open]) => {
+ if (open) {
+ page.value = 1;
+ loadList();
+ }
+ },
+ { immediate: true },
+);
+
+function onPageChange(p: number, ps: number) {
+ page.value = p;
+ pageSize.value = ps;
+ loadList();
+}
+
+
+
+
+
+
+
+
diff --git a/apps/web-antd/src/views/business/store/settings/config/form.ts b/apps/web-antd/src/views/business/store/settings/config/form.ts
index 8b401934..b7e3105a 100644
--- a/apps/web-antd/src/views/business/store/settings/config/form.ts
+++ b/apps/web-antd/src/views/business/store/settings/config/form.ts
@@ -101,15 +101,43 @@ export const salespersonModalFormProps: VbenFormProps = {
triggerFields: ['split_type'],
},
},
- // {
- // component: 'UploadImage',
- // fieldName: 'url',
- // label: '图片',
- // rules: 'required',
- // componentProps: {
- // maxCount: 5,
- // },
- // },
+ {
+ component: 'Divider',
+ fieldName: 'tcm_divider',
+ label: '中药推广分成',
+ formItemClass: 'col-span-12',
+ },
+ {
+ component: 'InputNumber',
+ fieldName: 'tcm_split',
+ label: '中药分成(%)',
+ componentProps: {
+ min: 0,
+ max: 100,
+ precision: 2,
+ class: 'w-full',
+ placeholder: '0 表示不分成',
+ },
+ defaultValue: 0,
+ },
+ {
+ component: 'RadioGroup',
+ fieldName: 'tcm_base_type',
+ label: '中药分成基数',
+ componentProps: {
+ options: [
+ { label: '药店利润', value: 0 },
+ { label: '处方总价', value: 1 },
+ ],
+ },
+ defaultValue: 0,
+ dependencies: {
+ show(values) {
+ return Number(values?.tcm_split ?? 0) > 0;
+ },
+ triggerFields: ['tcm_split'],
+ },
+ },
],
showDefaultActions: false,
};
diff --git a/apps/web-antd/src/views/business/store/settings/index.vue b/apps/web-antd/src/views/business/store/settings/index.vue
index 585c581d..25a748f0 100644
--- a/apps/web-antd/src/views/business/store/settings/index.vue
+++ b/apps/web-antd/src/views/business/store/settings/index.vue
@@ -734,7 +734,7 @@ const handleSwitchClinicType = () => {
>
固定金额需配置各药品每件佣金西药固定金额需配置各药品每件佣金;中药按处方单分成
diff --git a/apps/web-antd/src/views/doctor/doctor-reception/api/index.ts b/apps/web-antd/src/views/doctor/doctor-reception/api/index.ts
index a6c763d8..41ef80c6 100644
--- a/apps/web-antd/src/views/doctor/doctor-reception/api/index.ts
+++ b/apps/web-antd/src/views/doctor/doctor-reception/api/index.ts
@@ -75,8 +75,13 @@ export async function getMyStoreListApi() {
/**
* 获取当前诊所类型和委托诊所信息
*/
-export async function getCurrentStoreTypeApi() {
- return requestClient.get(`${prefix}get-current-store-type`);
+export async function getCurrentStoreTypeApi(params?: {
+ register_id?: number;
+ store_id?: number;
+}) {
+ return requestClient.get(`${prefix}get-current-store-type`, {
+ params,
+ });
}
/**
diff --git a/apps/web-antd/src/views/doctor/doctor-reception/index.vue b/apps/web-antd/src/views/doctor/doctor-reception/index.vue
index ec7e1a5e..18184b29 100644
--- a/apps/web-antd/src/views/doctor/doctor-reception/index.vue
+++ b/apps/web-antd/src/views/doctor/doctor-reception/index.vue
@@ -74,6 +74,11 @@ import {
// 转诊相关
import TransferPrescriptionCard from '#/views/doctor/online-consultation/components/TransferPrescriptionCard.vue';
import { getTransferPrescriptionByRegisterApi } from '#/views/business/chat/api/transferPrescription';
+import {
+ calcItemMarginPercent,
+ calcTotalMarginPercent,
+ isSeeRateEnabled,
+} from '#/utils/chinesePrescriptionMargin';
interface Patient {
id: number;
@@ -128,6 +133,50 @@ getMyStoreList();
const userStore = useUserStore();
const myStoreId = ref(userStore.userInfo.store_id);
+/** 当前取价门店是否允许查看毛利率(0/1) */
+const seeRate = ref(0);
+
+async function fetchStoreSeeRate() {
+ try {
+ const registerId = Number.parseInt(
+ localStorage.getItem('doctorReception-id') || '0',
+ 10,
+ );
+ const params: { register_id?: number; store_id?: number } = {
+ store_id: myStoreId.value,
+ };
+ if (registerId > 0) {
+ params.register_id = registerId;
+ }
+ const res = await getCurrentStoreTypeApi(params);
+ seeRate.value = Number(res?.see_rate ?? 0);
+ } catch (error) {
+ console.error('获取毛利率权限失败:', error);
+ }
+}
+
+watch(myStoreId, () => {
+ fetchStoreSeeRate();
+});
+
+const chineseGrossMarginPercent = computed(() => {
+ if (!isSeeRateEnabled(seeRate.value) || activeCategory.value !== 1) {
+ return null;
+ }
+ return calcTotalMarginPercent(currentDrugs.value, dosage.value);
+});
+
+function getChineseItemMargin(drug: {
+ price?: number | string;
+ buy_price?: number | string;
+}) {
+ if (!isSeeRateEnabled(seeRate.value)) {
+ return null;
+ }
+ return calcItemMarginPercent(drug.price, drug.buy_price);
+}
+
+fetchStoreSeeRate();
// userStore.userInfo?.nick_name
/**
@@ -782,6 +831,7 @@ async function handleSelectCommonPrescription(data: any, type: number) {
drug_name: recipe.drug_name || recipe.name,
number: recipe.number || 1,
price: recipe.price || 0,
+ buy_price: recipe.buy_price,
way_id: recipe.way_id || 0,
select_number: recipe.select_number ?? 1,
};
@@ -1027,7 +1077,14 @@ async function checkAndShowTransferTip() {
}
// 调用新接口获取当前诊所类型和委托诊所信息
- const storeInfo = await getCurrentStoreTypeApi();
+ const registerId = Number.parseInt(
+ localStorage.getItem('doctorReception-id') || '0',
+ 10,
+ );
+ const storeInfo = await getCurrentStoreTypeApi({
+ store_id: myStoreId.value,
+ ...(registerId > 0 ? { register_id: registerId } : {}),
+ });
// const storeInfo = res;
if (!storeInfo) {
@@ -1498,10 +1555,15 @@ const getDrugListByWesternModal = debounce(async (searchText = '') => {
getCurrentDrugs();
try {
+ const registerId = Number.parseInt(
+ localStorage.getItem('doctorReception-id') || '0',
+ 10,
+ );
const res = await getProductListDoctorReception({
- store_id: 2,
+ store_id: myStoreId.value,
type: activeCategory.value,
name: searchText,
+ ...(registerId > 0 ? { register_id: registerId } : {}),
});
drugList.value = res.map((item) => {
@@ -1592,6 +1654,7 @@ function selectOldDrugInfo(id) {
unit: drugUnit.value.find((item) => item.id === data.drug.unit_id),
// 药品价格
price: data.price,
+ buy_price: data.buy_price,
// 药品使用方式ID
way_id: data.drug?.way_id,
// 药品使用方式信息
@@ -1730,6 +1793,7 @@ function addProducts(data) {
unit: drugUnit.value.find((item) => item.id === data.drug.unit_id),
// 药品价格
price: data.price,
+ buy_price: data.buy_price,
// 药品使用方式ID
way_id: data.drug?.way_id,
// 药品使用方式信息
@@ -2302,6 +2366,12 @@ watch(
¥{{ (drug.price * drug.number).toFixed(2) }}
+
+ 毛利率 {{ getChineseItemMargin(drug) }}%
+