diff --git a/api/clinicSalesperson.js b/api/clinicSalesperson.js
index 3c407ed..b6623d3 100644
--- a/api/clinicSalesperson.js
+++ b/api/clinicSalesperson.js
@@ -37,3 +37,35 @@ export function getClinicSalespersonSettlementDetail(id) {
export function getClinicSalespersonUserBindList(params) {
return clinicSalespersonRequest({ url: `${PREFIX}/user-bind-list`, method: 'GET', data: params });
}
+
+export function getClinicSalespersonSeePriceConfig() {
+ return clinicSalespersonRequest({ url: `${PREFIX}/see-price-config`, method: 'GET' });
+}
+
+export function getClinicSalespersonChineseDrugList(params) {
+ return clinicSalespersonRequest({ url: `${PREFIX}/chinese-drug-list`, method: 'GET', data: params });
+}
+
+export function getClinicSalespersonDiseaseList(params) {
+ return clinicSalespersonRequest({ url: `${PREFIX}/disease-list`, method: 'GET', data: params });
+}
+
+export function getClinicSalespersonProcessRuleList(params) {
+ return clinicSalespersonRequest({ url: `${PREFIX}/process-rule-list`, method: 'GET', data: params });
+}
+
+export function getClinicSalespersonChineseMedicineQuickGrams() {
+ return clinicSalespersonRequest({ url: `${PREFIX}/chinese-medicine-quick-grams`, method: 'GET' });
+}
+
+export function createClinicSalespersonTransferPrescription(data) {
+ return clinicSalespersonRequest({ url: `${PREFIX}/transfer-prescription-create`, method: 'POST', data });
+}
+
+export function getClinicSalespersonTransferPrescriptionList(params) {
+ return clinicSalespersonRequest({ url: `${PREFIX}/transfer-prescription-list`, method: 'GET', data: params });
+}
+
+export function getClinicSalespersonTransferPrescriptionDetail(id) {
+ return clinicSalespersonRequest({ url: `${PREFIX}/transfer-prescription-detail`, method: 'GET', data: { id } });
+}
diff --git a/api/platformStore.js b/api/platformStore.js
new file mode 100644
index 0000000..a4e0813
--- /dev/null
+++ b/api/platformStore.js
@@ -0,0 +1,116 @@
+import { req } from '@/common/js/index.js';
+import { unwrapClinicRes } from '@/api/clinicAdmin.js';
+
+const STORE_PREFIX = '/newApi/platform-admin-store';
+const CONFIG_PREFIX = '/newApi/platform-admin-salesperson-store-config';
+
+function platformRequest(options) {
+ return req.request({
+ ...options,
+ header: {
+ ...(options.header || {}),
+ _platformAdmin: '1',
+ },
+ }).then((res) => {
+ const data = unwrapClinicRes(res);
+ const ok = res && (res.code === 0 || (res.errcode != null && Number(res.errcode) !== -1));
+ return { res, data, ok };
+ });
+}
+
+export function getPlatformStoreList(params) {
+ return platformRequest({ url: `${STORE_PREFIX}/list`, method: 'GET', data: params });
+}
+
+export function getPlatformStoreDetail(id) {
+ return platformRequest({ url: `${STORE_PREFIX}/detail`, method: 'GET', data: { id } });
+}
+
+export function updatePlatformStore(data) {
+ return platformRequest({ url: `${STORE_PREFIX}/update`, method: 'POST', data });
+}
+
+export function deletePlatformStore(id) {
+ return platformRequest({ url: `${STORE_PREFIX}/delete`, method: 'POST', data: { id } });
+}
+
+export function openStorePcWindows(id) {
+ return platformRequest({ url: `${STORE_PREFIX}/open-pc-windows`, method: 'POST', data: { id } });
+}
+
+export function openStoreQrCode(id) {
+ return platformRequest({ url: `${STORE_PREFIX}/open-qr-code`, method: 'POST', data: { id } });
+}
+
+export function updateStoreShippingFree(id) {
+ return platformRequest({ url: `${STORE_PREFIX}/update-shipping-free`, method: 'POST', data: { id } });
+}
+
+export function updateStoreSubscribeStatus(id) {
+ return platformRequest({ url: `${STORE_PREFIX}/update-subscribe-status`, method: 'POST', data: { id } });
+}
+
+export function updateStoreSeeRate(id) {
+ return platformRequest({ url: `${STORE_PREFIX}/update-see-rate`, method: 'POST', data: { id } });
+}
+
+export function updateStoreAllowInsurance(id) {
+ return platformRequest({ url: `${STORE_PREFIX}/update-allow-insurance-category`, method: 'POST', data: { id } });
+}
+
+export function updateStoreClinicType(id, clinicType) {
+ return platformRequest({
+ url: `${STORE_PREFIX}/update-clinic-type`,
+ method: 'POST',
+ data: { id, clinic_type: clinicType },
+ });
+}
+
+export function toggleSalespersonSeePrice(storeId) {
+ return platformRequest({
+ url: `${CONFIG_PREFIX}/toggle-see-price`,
+ method: 'POST',
+ data: { store_id: storeId },
+ });
+}
+
+export function getStoreDrugsByType(storeId, type) {
+ return platformRequest({
+ url: `${STORE_PREFIX}/get-store-drugs-by-type`,
+ method: 'GET',
+ data: { store_id: storeId, type },
+ });
+}
+
+export function updateStoreDrugPrices(data) {
+ return platformRequest({ url: `${STORE_PREFIX}/update-store-drug-prices`, method: 'POST', data });
+}
+
+export function getDoctorOption(storeId) {
+ return platformRequest({
+ url: `${STORE_PREFIX}/doctor-option`,
+ method: 'GET',
+ data: storeId ? { store_id: storeId } : {},
+ });
+}
+
+export function getInternetMedicalStoreOption() {
+ return platformRequest({ url: `${STORE_PREFIX}/internet-medical-store-option`, method: 'GET' });
+}
+
+export function bindOnlineConsultation(data) {
+ return platformRequest({ url: `${STORE_PREFIX}/bind-online-consultation`, method: 'POST', data });
+}
+
+export function updateStoreExternalField(data) {
+ return platformRequest({ url: `${STORE_PREFIX}/update-store-external-field`, method: 'POST', data });
+}
+
+export const DRUG_TYPE_OPTIONS = [
+ { label: '中药', value: 1 },
+ { label: '西药', value: 2 },
+ { label: '保健食品', value: 3 },
+ { label: '产品服务包', value: 5 },
+ { label: '非药品', value: 6 },
+ { label: '医疗器械', value: 7 },
+];
diff --git a/api/reception.js b/api/reception.js
index 0aafe7e..cf8704b 100644
--- a/api/reception.js
+++ b/api/reception.js
@@ -314,6 +314,15 @@ export function getCurrentStoreTypeApi(data) {
})
}
+// 接诊页匹配推广员传方
+export function getSalespersonTransferByRegisterApi(registerId) {
+ return req.request({
+ url: '/newApi/transfer-prescription/get-salesperson-by-register',
+ method: 'GET',
+ data: { register_id: registerId }
+ })
+}
+
// 切换诊所
export function switchStoreApi(data) {
return req.request({
diff --git a/api/salespersonManage.js b/api/salespersonManage.js
new file mode 100644
index 0000000..f86d3a7
--- /dev/null
+++ b/api/salespersonManage.js
@@ -0,0 +1,133 @@
+import { req } from '@/common/js/index.js';
+import { unwrapClinicRes } from '@/api/clinicAdmin.js';
+
+const PLATFORM_PREFIX = '/newApi/platform-admin-salesperson';
+const PLATFORM_CONFIG_PREFIX = '/newApi/platform-admin-salesperson-store-config';
+const CLINIC_PREFIX = '/newApi/clinic-admin-salesperson';
+const CLINIC_CONFIG_PREFIX = '/newApi/clinic-admin-salesperson-store-config';
+
+function createRequest(prefix, headerKey) {
+ return function bizRequest(options) {
+ return req.request({
+ ...options,
+ header: {
+ ...(options.header || {}),
+ [headerKey]: '1',
+ },
+ }).then((res) => {
+ const data = unwrapClinicRes(res);
+ const ok = res && (res.code === 0 || (res.errcode != null && Number(res.errcode) !== -1));
+ return { res, data, ok };
+ });
+ };
+}
+
+const platformRequest = createRequest(PLATFORM_PREFIX, '_platformAdmin');
+const clinicRequest = createRequest(CLINIC_PREFIX, '_clinicAdmin');
+const platformConfigRequest = createRequest(PLATFORM_CONFIG_PREFIX, '_platformAdmin');
+const clinicConfigRequest = createRequest(CLINIC_CONFIG_PREFIX, '_clinicAdmin');
+
+export function createSalespersonManageApi(mode) {
+ const isPlatform = mode === 'platform';
+ const request = isPlatform ? platformRequest : clinicRequest;
+ const configRequest = isPlatform ? platformConfigRequest : clinicConfigRequest;
+ const prefix = isPlatform ? PLATFORM_PREFIX : CLINIC_PREFIX;
+
+ return {
+ mode,
+ prefix,
+
+ getList(params) {
+ const url = isPlatform ? `${prefix}/platform-list` : `${prefix}/list`;
+ return request({ url, method: 'GET', data: params });
+ },
+
+ create(data) {
+ const url = isPlatform ? `${prefix}/platform-create` : `${prefix}/create`;
+ return request({ url, method: 'POST', data });
+ },
+
+ update(data) {
+ return request({ url: `${prefix}/update`, method: 'POST', data });
+ },
+
+ getPlatformStoreOptions(keyword) {
+ return request({
+ url: `${prefix}/platform-store-options`,
+ method: 'GET',
+ data: { keyword: keyword || '' },
+ });
+ },
+
+ openAdminAccount(data) {
+ return request({ url: `${prefix}/open-admin-account`, method: 'POST', data });
+ },
+
+ getDrugCommissionList(params) {
+ return request({ url: `${prefix}/drug-commission-list`, method: 'GET', data: params });
+ },
+
+ saveDrugCommission(data) {
+ return request({ url: `${prefix}/save-drug-commission`, method: 'POST', data });
+ },
+
+ getDrugCommissionCopyFrom(fromSalespersonId) {
+ return request({
+ url: `${prefix}/drug-commission-copy-from`,
+ method: 'GET',
+ data: { from_salesperson_id: fromSalespersonId },
+ });
+ },
+
+ getCommissionList(params) {
+ return request({ url: `${prefix}/commission-list`, method: 'GET', data: params });
+ },
+
+ getCommissionOrderList(params) {
+ return request({ url: `${prefix}/commission-order-list`, method: 'GET', data: params });
+ },
+
+ getSettlementPreview(params) {
+ return request({ url: `${prefix}/settlement-preview`, method: 'GET', data: params });
+ },
+
+ confirmSettlement(data) {
+ return request({ url: `${prefix}/settlement`, method: 'POST', data });
+ },
+
+ getSettlementList(params) {
+ return request({ url: `${prefix}/settlement-list`, method: 'GET', data: params });
+ },
+
+ getSettlementDetail(params) {
+ return request({ url: `${prefix}/settlement-detail`, method: 'GET', data: params });
+ },
+
+ getUserBindList(params) {
+ return request({ url: `${prefix}/user-bind-list`, method: 'GET', data: params });
+ },
+
+ toggleSeePrice(storeId) {
+ const configPrefix = isPlatform ? PLATFORM_CONFIG_PREFIX : CLINIC_CONFIG_PREFIX;
+ return configRequest({
+ url: `${configPrefix}/toggle-see-price`,
+ method: 'POST',
+ data: { store_id: storeId },
+ });
+ },
+
+ getSeePriceDetail(storeId) {
+ const configPrefix = isPlatform ? PLATFORM_CONFIG_PREFIX : CLINIC_CONFIG_PREFIX;
+ return configRequest({
+ url: `${configPrefix}/detail`,
+ method: 'GET',
+ data: storeId ? { store_id: storeId } : {},
+ });
+ },
+ };
+}
+
+export function getSalespersonManageApiByLoginMode() {
+ const mode = uni.getStorageSync('loginMode');
+ return createSalespersonManageApi(mode === 'platform_admin' ? 'platform' : 'clinic');
+}
diff --git a/api/upload.js b/api/upload.js
index 5258f31..ab122df 100644
--- a/api/upload.js
+++ b/api/upload.js
@@ -2,6 +2,7 @@ import { req } from '@/common/js/index.js';
const SALESPERSON_PREFIX = '/newApi/salesperson-upload/';
const PLATFORM_PREFIX = '/newApi/platform-admin-upload/';
+const CLINIC_ADMIN_PREFIX = '/newApi/clinic-admin-upload/';
function uploadChatFileByPrefix(prefix, headerKey, params) {
return req.request({
@@ -31,6 +32,13 @@ export function uploadPlatformAdminChatFileApi(params) {
return uploadChatFileByPrefix(PLATFORM_PREFIX, '_platformAdmin', params);
}
+/**
+ * 诊所管理员上传(结算凭证等)
+ */
+export function uploadClinicAdminChatFileApi(params) {
+ return uploadChatFileByPrefix(CLINIC_ADMIN_PREFIX, '_clinicAdmin', params);
+}
+
/**
* 按当前 loginMode 选择上传接口
*/
@@ -39,9 +47,23 @@ export function uploadBusinessChatFileApi(params) {
if (mode === 'platform_admin') {
return uploadPlatformAdminChatFileApi(params);
}
+ if (mode === 'clinic_admin') {
+ return uploadClinicAdminChatFileApi(params);
+ }
return uploadSalespersonChatFileApi(params);
}
+/**
+ * 推广员管理结算凭证上传(超管/诊所)
+ */
+export function uploadSalespersonManageFileApi(params) {
+ const mode = uni.getStorageSync('loginMode');
+ if (mode === 'platform_admin') {
+ return uploadPlatformAdminChatFileApi(params);
+ }
+ return uploadClinicAdminChatFileApi(params);
+}
+
function unwrapUploadResult(res) {
if (res == null) return null;
if (res.result !== undefined && res.result !== null) return res.result;
diff --git a/components/account-switch/account-switch-panel.vue b/components/account-switch/account-switch-panel.vue
index 7095847..d0bb66c 100644
--- a/components/account-switch/account-switch-panel.vue
+++ b/components/account-switch/account-switch-panel.vue
@@ -13,7 +13,7 @@
mode="bottom"
length="80%"
border-radius="24"
- z-index="10078"
+ z-index="10090"
:closeable="true"
:mask-close-able="true"
:safe-area-inset-bottom="true"
@@ -76,7 +76,7 @@ export default {
normalizeAccounts(accounts) {
return (accounts || []).map((item, index) => ({
...item,
- _rowKey: `${item.account_type}_${item.id}_${index}`,
+ _rowKey: `${item.account_type}_${item.id}_${item.login_persona || 'admin'}_${index}`,
}));
},
resolveDefaultSelection(accounts, options = {}) {
@@ -113,6 +113,10 @@ export default {
if (Array.isArray(accounts)) {
this.accounts = this.normalizeAccounts(accounts);
+ if (!this.accounts.length) {
+ uni.showToast({ title: '暂无可选账号', icon: 'none' });
+ return Promise.resolve();
+ }
this.selected = this.resolveDefaultSelection(this.accounts, options);
this.showPanel();
return Promise.resolve();
@@ -171,6 +175,7 @@ export default {
switchDoctorWxAccount({
account_type: this.selected.account_type,
account_id: this.selected.id,
+ login_persona: this.selected.login_persona || undefined,
}).then((wrap) => {
if (!wrap || !wrap.ok || !wrap.data || !wrap.data.token) {
return Promise.reject({
diff --git a/components/doctor-login/doctor-login.vue b/components/doctor-login/doctor-login.vue
index 4e7f662..a1724d2 100644
--- a/components/doctor-login/doctor-login.vue
+++ b/components/doctor-login/doctor-login.vue
@@ -162,14 +162,23 @@ export default {
return Promise.reject(new Error(res.message || res.msg || '登录失败'));
}
const result = res.result;
- if (result.need_select && result.accounts && result.accounts.length) {
+ if (result.need_select) {
+ const accounts = Array.isArray(result.accounts) ? result.accounts : [];
+ if (!accounts.length) {
+ return Promise.reject(new Error('请选择登录账号'));
+ }
this.pendingLoginPayload = payload;
- this.$emit('need-select', {
- accounts: result.accounts,
- defaultAccountId: result.default_account_id,
- defaultAccountType: result.default_account_type,
+ this.loading = false;
+ return new Promise((resolve) => {
+ this.$nextTick(() => {
+ this.$emit('need-select', {
+ accounts,
+ defaultAccountId: result.default_account_id,
+ defaultAccountType: result.default_account_type,
+ });
+ resolve(null);
+ });
});
- return null;
}
return this.finishLogin(result);
})
@@ -184,6 +193,7 @@ export default {
this.doLogin({
account_type: account.account_type,
account_id: account.id,
+ login_persona: account.login_persona || undefined,
});
},
async finishLogin(result) {
diff --git a/pages.json b/pages.json
index 82fe7c2..2fdd1f6 100644
--- a/pages.json
+++ b/pages.json
@@ -476,11 +476,28 @@
{ "path": "home/index", "style": { "navigationBarTitleText": "工作台", "navigationStyle": "custom" } },
{ "path": "my/index", "style": { "navigationBarTitleText": "我的", "navigationStyle": "custom" } },
{ "path": "withdrawal/audit/index", "style": { "navigationBarTitleText": "提现审核", "navigationStyle": "custom" } },
+ { "path": "store/index", "style": { "navigationBarTitleText": "门店管理", "navigationStyle": "custom" } },
+ { "path": "store/detail", "style": { "navigationBarTitleText": "门店详情", "navigationStyle": "custom" } },
+ { "path": "store/edit", "style": { "navigationBarTitleText": "编辑诊所", "navigationStyle": "custom" } },
+ { "path": "store/drug-price", "style": { "navigationBarTitleText": "药品价格", "navigationStyle": "custom" } },
+ { "path": "store/consultation", "style": { "navigationBarTitleText": "在线复诊", "navigationStyle": "custom" } },
{ "path": "store-input/audit/index", "style": { "navigationBarTitleText": "门店审核", "navigationStyle": "custom" } },
{ "path": "store-input/audit/detail", "style": { "navigationBarTitleText": "审核详情", "navigationStyle": "custom" } },
{ "path": "doctor-input/audit/index", "style": { "navigationBarTitleText": "医生审核", "navigationStyle": "custom" } },
{ "path": "doctor-input/audit/detail", "style": { "navigationBarTitleText": "审核详情", "navigationStyle": "custom" } }
]
+ }, {
+ "root": "subPackages/sub_salesperson_manage",
+ "pages": [
+ { "path": "index", "style": { "navigationBarTitleText": "推广员管理", "navigationStyle": "custom" } },
+ { "path": "form", "style": { "navigationBarTitleText": "推广员", "navigationStyle": "custom" } },
+ { "path": "drug-commission/index", "style": { "navigationBarTitleText": "药品佣金", "navigationStyle": "custom" } },
+ { "path": "leads/index", "style": { "navigationBarTitleText": "获客记录", "navigationStyle": "custom" } },
+ { "path": "commission/index", "style": { "navigationBarTitleText": "分成与结算", "navigationStyle": "custom" } },
+ { "path": "settlement/preview", "style": { "navigationBarTitleText": "按时间段结算", "navigationStyle": "custom" } },
+ { "path": "settlement/confirm", "style": { "navigationBarTitleText": "确认结算", "navigationStyle": "custom" } },
+ { "path": "settlement/detail", "style": { "navigationBarTitleText": "结算详情", "navigationStyle": "custom" } }
+ ]
}, {
"root": "subPackages/sub_salesperson",
"pages": [
@@ -501,7 +518,9 @@
{ "path": "earnings/index", "style": { "navigationBarTitleText": "我的收益", "navigationStyle": "custom" } },
{ "path": "leads/index", "style": { "navigationBarTitleText": "获客记录", "navigationStyle": "custom" } },
{ "path": "commission/index", "style": { "navigationBarTitleText": "分成记录", "navigationStyle": "custom" } },
- { "path": "settlement/index", "style": { "navigationBarTitleText": "结算记录", "navigationStyle": "custom" } }
+ { "path": "settlement/index", "style": { "navigationBarTitleText": "结算记录", "navigationStyle": "custom" } },
+ { "path": "transfer-prescription/form", "style": { "navigationBarTitleText": "传方", "navigationStyle": "custom" } },
+ { "path": "transfer-prescription/list", "style": { "navigationBarTitleText": "传方记录", "navigationStyle": "custom" } }
]
}, {
"root": "subPackages/sub_agreement",
diff --git a/pages/login/index.vue b/pages/login/index.vue
index 7fd7bae..f84adea 100644
--- a/pages/login/index.vue
+++ b/pages/login/index.vue
@@ -5,6 +5,7 @@
ref="accountSwitchPanel"
mode="login"
@confirm="onAccountPicked"
+ @cancel="pendingAccountSelect = false"
/>
@@ -16,17 +17,25 @@ import { redirectIfLoggedIn } from '@/utils/loginSession.js';
export default {
components: { DoctorLogin, AccountSwitchPanel },
+ data() {
+ return {
+ pendingAccountSelect: false,
+ };
+ },
onShow() {
+ if (this.pendingAccountSelect) return;
redirectIfLoggedIn();
},
methods: {
openAccountPicker({ accounts, defaultAccountId, defaultAccountType }) {
+ this.pendingAccountSelect = true;
this.$refs.accountSwitchPanel.open(accounts, {
defaultAccountId,
defaultAccountType,
});
},
onAccountPicked(account) {
+ this.pendingAccountSelect = false;
this.$refs.doctorLogin.onAccountPicked(account);
},
},
diff --git a/subPackages/sub_clinic_admin/home/index.vue b/subPackages/sub_clinic_admin/home/index.vue
index 17310b4..ea2d0d6 100644
--- a/subPackages/sub_clinic_admin/home/index.vue
+++ b/subPackages/sub_clinic_admin/home/index.vue
@@ -81,6 +81,10 @@ const BUSINESS_MENUS = [
{ key: 'order', label: '商品订单', desc: '全平台订单概览', icon: 'bag-fill', theme: GLOBAL_THEMES[3], path: '/subPackages/sub_clinic_admin/order/index' },
]
+const SALESPERSON_MENUS = [
+ { key: 'salesperson-manage', label: '推广员管理', desc: '添加与结算推广员', icon: 'account-fill', theme: GLOBAL_THEMES[2], path: '/subPackages/sub_salesperson_manage/index?mode=clinic' },
+]
+
const WAREHOUSE_FALLBACK = {
key: 'warehouse',
label: '仓库管理',
@@ -105,6 +109,7 @@ export default {
return [
{ key: 'finance', title: '财务管理', items: FINANCE_MENUS },
{ key: 'business', title: '业务管理', items: BUSINESS_MENUS },
+ { key: 'salesperson', title: '门店推广员', items: SALESPERSON_MENUS },
{ key: 'warehouse', title: '仓库管理', items: this.warehouseMenus },
]
},
diff --git a/subPackages/sub_clinic_salesperson/home/index.vue b/subPackages/sub_clinic_salesperson/home/index.vue
index cead460..8e16d75 100644
--- a/subPackages/sub_clinic_salesperson/home/index.vue
+++ b/subPackages/sub_clinic_salesperson/home/index.vue
@@ -123,7 +123,9 @@ export default {
profileInfo: null,
stats: {},
menuItems: [
- { key: 'earnings', label: '我的收益', path: `${ROOT}/earnings/index` },
+ { key: 'transfer', label: '传方', path: '/subPackages/sub_workbench/prescription_v2/index?salesperson_transfer=1&initial_category=1' },
+ // { key: 'transfer-list', label: '传方记录', path: `${ROOT}/transfer-prescription/list` },
+ // { key: 'earnings', label: '我的收益', path: `${ROOT}/earnings/index` },
{ key: 'leads', label: '获客记录', path: `${ROOT}/leads/index` },
{ key: 'commission', label: '分成记录', path: `${ROOT}/commission/index` },
{ key: 'settlement', label: '结算记录', path: `${ROOT}/settlement/index` },
@@ -134,6 +136,8 @@ export default {
// 动态注入多彩主题和增强文案,使用 uView 图标名称
enrichedMenuItems() {
const themes = [
+ { bg: 'linear-gradient(135deg, #ECFDF5, #D1FAE5)', color: '#10B981', desc: '线下中药传方', icon: 'edit-pen-fill' },
+ { bg: 'linear-gradient(135deg, #F0F9FF, #E0F2FE)', color: '#0EA5E9', desc: '历史传方记录', icon: 'file-text-fill' },
// 收益:使用钻石/钱包相关图标
{ bg: 'linear-gradient(135deg, #FFF7ED, #FFEDD5)', color: '#F97316', desc: '查看收益明细', icon: 'red-packet-fill' },
// 获客:使用目标/数据相关图标
diff --git a/subPackages/sub_clinic_salesperson/my/index.vue b/subPackages/sub_clinic_salesperson/my/index.vue
index 20fcee1..7ef3bc4 100644
--- a/subPackages/sub_clinic_salesperson/my/index.vue
+++ b/subPackages/sub_clinic_salesperson/my/index.vue
@@ -1,215 +1,430 @@
-
-
-
-
-
- {{ avatarText }}
-
-
- {{ displayName }}
-
- 推广员
-
- {{ phone }}
- {{ storeName }}
-
-
-
-
-
- 所属诊所
- {{ storeName || '-' }}
-
-
-
-
-
-
- 退出登录
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ {{ avatarText }}
+
+
+
+
+
+ {{ displayName }}
+
+
+
+ 推广员
+
+
+
+ {{ phone }}
+
+ {{ storeName }}
+
+
+
+
+
+
+
+
+
+
+
+ 所属诊所
+
+ {{ storeName || '-' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 退出登录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/subPackages/sub_clinic_salesperson/transfer-prescription/form.vue b/subPackages/sub_clinic_salesperson/transfer-prescription/form.vue
new file mode 100644
index 0000000..b1ff105
--- /dev/null
+++ b/subPackages/sub_clinic_salesperson/transfer-prescription/form.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/subPackages/sub_clinic_salesperson/transfer-prescription/list.vue b/subPackages/sub_clinic_salesperson/transfer-prescription/list.vue
new file mode 100644
index 0000000..b7e9e83
--- /dev/null
+++ b/subPackages/sub_clinic_salesperson/transfer-prescription/list.vue
@@ -0,0 +1,55 @@
+
+
+
+ 暂无传方记录
+
+
+ {{ item.patient_name }} {{ item.patient_mobile }}
+
+
+ 诊断:{{ item.clinical_diagnose || '-' }}
+ {{ item.transfer_time_text }}
+
+ 新建传方
+
+
+
+
+
+
+
diff --git a/subPackages/sub_platform_admin/components/store-page-layout.vue b/subPackages/sub_platform_admin/components/store-page-layout.vue
new file mode 100644
index 0000000..6388562
--- /dev/null
+++ b/subPackages/sub_platform_admin/components/store-page-layout.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/subPackages/sub_platform_admin/home/index.vue b/subPackages/sub_platform_admin/home/index.vue
index 768f9eb..ed28880 100644
--- a/subPackages/sub_platform_admin/home/index.vue
+++ b/subPackages/sub_platform_admin/home/index.vue
@@ -105,6 +105,16 @@ export default {
key: 'order', label: '商品订单', desc: '全平台订单概览', path: `${shared}/order/index`,
icon: 'bag-fill',
theme: { bg: 'linear-gradient(135deg, #F0FDF4, #DCFCE7)', color: '#22C55E' } // 安全绿
+ },
+ {
+ key: 'store-manage', label: '门店管理', desc: '诊所列表与价格配置', path: `${root}/store/index`,
+ icon: 'home-fill',
+ theme: { bg: 'linear-gradient(135deg, #ECFEFF, #CFFAFE)', color: '#06B6D4' }
+ },
+ {
+ key: 'salesperson-manage', label: '推广员管理', desc: '全平台推广员', path: '/subPackages/sub_salesperson_manage/index?mode=platform',
+ icon: 'account-fill',
+ theme: { bg: 'linear-gradient(135deg, #FAF5FF, #F3E8FF)', color: '#A855F7' }
}
],
},
diff --git a/subPackages/sub_platform_admin/store/consultation.vue b/subPackages/sub_platform_admin/store/consultation.vue
new file mode 100644
index 0000000..c1147b1
--- /dev/null
+++ b/subPackages/sub_platform_admin/store/consultation.vue
@@ -0,0 +1,154 @@
+
+
+
+
+ 互联网诊疗资质
+
+
+
+
+ 委托诊所
+
+ {{ storeLabels[delegateIndex] || '请选择' }}
+
+
+
+
+ 复诊负责人
+
+ {{ doctorLabels[doctorIndex] || '请选择' }}
+
+
+
+ 保存配置
+
+
+
+
+
+
+
diff --git a/subPackages/sub_platform_admin/store/detail.vue b/subPackages/sub_platform_admin/store/detail.vue
new file mode 100644
index 0000000..cec73e9
--- /dev/null
+++ b/subPackages/sub_platform_admin/store/detail.vue
@@ -0,0 +1,200 @@
+
+
+
+
+ {{ store.name }}
+ ID {{ store.id }} · {{ clinicTypeText(store.clinic_type) }}
+ {{ store.position || '暂无地址' }}
+
+
+
+ 门店配置
+
+ 推广员可见价格
+
+
+
+ 包邮
+
+
+
+ 订阅价格波动
+
+
+
+ 查看毛利率
+
+
+
+ 开方可选医保
+
+
+
+ 诊所类型
+
+ {{ clinicTypeLabels[clinicTypeIndex] }}
+
+
+
+
+
+ 快捷操作
+
+ 编辑资料
+ 修改药品价格
+ 在线复诊配置
+ 管理推广员
+ 诊所二维码
+ 开通后台
+
+
+
+
+ 在线复诊
+ 委托诊所:{{ store.delegate_store_name }}
+ 负责人:{{ store.online_consultation_doctor_name }}
+
+
+
+
+
+
+
+
diff --git a/subPackages/sub_platform_admin/store/drug-price.vue b/subPackages/sub_platform_admin/store/drug-price.vue
new file mode 100644
index 0000000..ae0f34c
--- /dev/null
+++ b/subPackages/sub_platform_admin/store/drug-price.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
+ {{ typeLabels[typeIndex] }}
+
+ 保存
+
+
+ 暂无药品
+
+
+ {{ item.drug_name || item.name }}
+ {{ item.drug_spec || item.spec || '' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/subPackages/sub_platform_admin/store/edit.vue b/subPackages/sub_platform_admin/store/edit.vue
new file mode 100644
index 0000000..9254939
--- /dev/null
+++ b/subPackages/sub_platform_admin/store/edit.vue
@@ -0,0 +1,111 @@
+
+
+
+
+ 诊所名称
+
+
+
+ 联系人
+
+
+
+ 联系电话
+
+
+
+ 详细地址
+
+
+
+ 营业开始
+
+
+
+ 营业结束
+
+
+
+ 销售倍率
+
+
+ 保存
+
+
+
+
+
+
+
diff --git a/subPackages/sub_platform_admin/store/index.vue b/subPackages/sub_platform_admin/store/index.vue
new file mode 100644
index 0000000..994eb08
--- /dev/null
+++ b/subPackages/sub_platform_admin/store/index.vue
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+ 查询
+
+
+ 加载中...
+ 暂无门店
+
+
+
+ {{ item.name }}
+ {{ clinicTypeText(item.clinic_type) }}
+
+ {{ item.position || '暂无地址' }}
+
+ ID {{ item.id }}
+ 电话 {{ item.mobile }}
+
+
+ 推广员可见价格
+ 包邮
+
+
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/commission/index.vue b/subPackages/sub_salesperson_manage/commission/index.vue
new file mode 100644
index 0000000..49da638
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/commission/index.vue
@@ -0,0 +1,235 @@
+
+
+
+
+ {{ tab.label }}
+
+
+
+
+ 查询
+
+
+
+
+ 按时间段结算
+ 结算选中订单
+
+
+
+
+ {{ item.order_no }}
+ 明细 {{ item.item_count }} 条 · {{ item.order_pay_at_text }}
+
+ ¥{{ item.commission_amount }}
+
+
+
+
+
+
+ {{ item.order_no }}
+ 明细 {{ item.item_count }} 条 · {{ item.order_pay_at_text }}
+
+ ¥{{ item.commission_amount }}
+
+
+
+
+
+
+ {{ item.settlement_no }}
+ {{ item.settlement_type_text }} · {{ item.created_at_text }}
+
+ ¥{{ item.amount }}
+
+
+
+ 暂无数据
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/common/context.js b/subPackages/sub_salesperson_manage/common/context.js
new file mode 100644
index 0000000..783d4b4
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/common/context.js
@@ -0,0 +1,23 @@
+import { createSalespersonManageApi } from '@/api/salespersonManage.js';
+
+const ROOT = '/subPackages/sub_salesperson_manage';
+
+export function resolveManageMode(options) {
+ const mode = (options && options.mode) || '';
+ if (mode === 'platform' || mode === 'clinic') return mode;
+ const loginMode = uni.getStorageSync('loginMode');
+ return loginMode === 'platform_admin' ? 'platform' : 'clinic';
+}
+
+export function getSalespersonManageContext(mode) {
+ const api = createSalespersonManageApi(mode);
+ return {
+ mode,
+ api,
+ isPlatform: mode === 'platform',
+ listPath: `${ROOT}/index?mode=${mode}`,
+ homePath: mode === 'platform'
+ ? '/subPackages/sub_platform_admin/home/index'
+ : '/subPackages/sub_clinic_admin/home/index',
+ };
+}
diff --git a/subPackages/sub_salesperson_manage/common/labels.js b/subPackages/sub_salesperson_manage/common/labels.js
new file mode 100644
index 0000000..c740170
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/common/labels.js
@@ -0,0 +1,17 @@
+export function splitTypeLabel(type) {
+ return Number(type) === 1 ? '百分比' : '固定金额';
+}
+
+export function tcmBaseLabel(type) {
+ return Number(type) === 1 ? '处方总价' : '药店利润';
+}
+
+export const SPLIT_TYPE_OPTIONS = [
+ { label: '元/件(固定金额)', value: 0 },
+ { label: '百分比(%)', value: 1 },
+];
+
+export const TCM_BASE_OPTIONS = [
+ { label: '药店利润', value: 0 },
+ { label: '处方总价', value: 1 },
+];
diff --git a/subPackages/sub_salesperson_manage/components/PageLayout.vue b/subPackages/sub_salesperson_manage/components/PageLayout.vue
new file mode 100644
index 0000000..35568e9
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/components/PageLayout.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/components/ProofImageUploader.vue b/subPackages/sub_salesperson_manage/components/ProofImageUploader.vue
new file mode 100644
index 0000000..2ab199f
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/components/ProofImageUploader.vue
@@ -0,0 +1,83 @@
+
+
+ 结算凭证(至少1张)
+
+
+
+ ×
+
+
+
+
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/components/StoreSearchPicker.vue b/subPackages/sub_salesperson_manage/components/StoreSearchPicker.vue
new file mode 100644
index 0000000..a2befc8
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/components/StoreSearchPicker.vue
@@ -0,0 +1,93 @@
+
+
+
+ 所属诊所
+ {{ selectedLabel || '请选择诊所' }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/drug-commission/index.vue b/subPackages/sub_salesperson_manage/drug-commission/index.vue
new file mode 100644
index 0000000..ffa49de
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/drug-commission/index.vue
@@ -0,0 +1,175 @@
+
+
+
+
+
+ 搜索
+
+
+
+
+ {{ copyLabels[copyIndex] || '从其他推广员复制' }}
+
+
+
+ 暂无药品
+
+
+ {{ item.drug_name }}
+ {{ item.drug_spec }}
+ 售价 ¥{{ item.price }} / 供货 ¥{{ item.buy_price }}
+
+
+
+
+ 保存修改
+ 请先保存推广员基本信息后再配置药品佣金
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/form.vue b/subPackages/sub_salesperson_manage/form.vue
new file mode 100644
index 0000000..af89a87
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/form.vue
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+ 手机号
+
+
+
+ 名称
+
+
+
+
+ 西药分成类型
+
+ {{ splitTypeLabels[splitTypeIndex] }}
+
+
+
+ 分成比例(%)
+
+
+
+ 药品佣金配置
+ 去配置元/件分成 >
+
+
+ 中药推广分成
+
+ 中药分成(%)
+
+
+
+ 中药分成基数
+
+ {{ tcmBaseLabels[tcmBaseIndex] }}
+
+
+
+ 保存
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/index.vue b/subPackages/sub_salesperson_manage/index.vue
new file mode 100644
index 0000000..5b9e58e
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/index.vue
@@ -0,0 +1,226 @@
+
+
+
+
+
+
+
+ 查询
+
+
+
+ 推广员可见价格
+
+
+
+
+ + 新增推广员
+
+
+ 加载中...
+ 暂无推广员
+
+
+
+
+ {{ item.nick_name || '未知' }}
+ {{ item.store_name }}
+
+
+ {{ splitLabel(item.split_type) }}
+ 中药 {{ item.tcm_split }}%
+
+
+
+ {{ item.phone }}
+
+ 累计获客
+ {{ (item.count && item.count.user_number) || 0 }}
+
+
+ 待结算
+ ¥{{ (item.count && item.count.pending_amount) || '0.00' }}
+
+
+ 后台账号
+ {{ item.has_admin_account ? '已开通' : '未开通' }}
+
+
+
+ 编辑
+ 分成与结算
+ 二维码
+ 获客
+ 开通后台
+
+
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/leads/index.vue b/subPackages/sub_salesperson_manage/leads/index.vue
new file mode 100644
index 0000000..304e47e
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/leads/index.vue
@@ -0,0 +1,71 @@
+
+
+
+ 暂无获客记录
+
+
+ {{ (item.user && item.user.nickname) || '用户' }}
+ {{ (item.user && item.user.mobile) || '' }}
+
+ {{ item.created_at_text || '' }}
+
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/settlement/confirm.vue b/subPackages/sub_salesperson_manage/settlement/confirm.vue
new file mode 100644
index 0000000..af2a4de
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/settlement/confirm.vue
@@ -0,0 +1,122 @@
+
+
+
+
+ 共 {{ recordCount }} 条明细
+ 结算金额 ¥{{ amount }}
+
+
+
+
+
+ 备注
+
+
+
+ 确认结算
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/settlement/detail.vue b/subPackages/sub_salesperson_manage/settlement/detail.vue
new file mode 100644
index 0000000..96f68b0
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/settlement/detail.vue
@@ -0,0 +1,97 @@
+
+
+
+
+ {{ detail.settlement_no }}
+ 结算方式{{ detail.settlement_type_text }}
+ 结算金额¥{{ detail.amount }}
+ 明细数{{ detail.record_count }}
+ 时间{{ detail.created_at_text }}
+ 备注{{ detail.remark }}
+
+
+
+ 结算凭证
+
+
+
+
+
+
+ 明细
+
+ {{ line.order_no }}
+ {{ line.drug_info }}
+ ¥{{ line.commission_amount }}
+
+
+
+
+
+
+
+
+
diff --git a/subPackages/sub_salesperson_manage/settlement/preview.vue b/subPackages/sub_salesperson_manage/settlement/preview.vue
new file mode 100644
index 0000000..d75b80d
--- /dev/null
+++ b/subPackages/sub_salesperson_manage/settlement/preview.vue
@@ -0,0 +1,114 @@
+
+
+
+
+ 开始日期
+
+ {{ dateStart || '请选择' }}
+
+
+
+ 结束日期
+
+ {{ dateEnd || '请选择' }}
+
+
+
+
+ 共 {{ preview.record_count }} 条明细
+ 涉及 {{ preview.order_count }} 个订单
+ 结算金额 ¥{{ preview.amount }}
+
+
+ 下一步:上传凭证
+
+
+
+
+
+
+
diff --git a/subPackages/sub_workbench/prescription_v2/components/modals/ChineseMedicineModal.vue b/subPackages/sub_workbench/prescription_v2/components/modals/ChineseMedicineModal.vue
index 43e2b9d..eb379ba 100644
--- a/subPackages/sub_workbench/prescription_v2/components/modals/ChineseMedicineModal.vue
+++ b/subPackages/sub_workbench/prescription_v2/components/modals/ChineseMedicineModal.vue
@@ -71,7 +71,12 @@
-
+
+
@@ -174,6 +179,7 @@
+
+
diff --git a/subPackages/sub_workbench/prescription_v2/index.vue b/subPackages/sub_workbench/prescription_v2/index.vue
index f6b88e1..7f8a36d 100644
--- a/subPackages/sub_workbench/prescription_v2/index.vue
+++ b/subPackages/sub_workbench/prescription_v2/index.vue
@@ -8,11 +8,11 @@
/>
-
+
-
+
-
+
{{ registerModeHint }}
+
+ 自费
+ 医保
+
+
+
+ 查看传方
+
+
@@ -192,7 +201,7 @@
-
- 诊疗费
-
- ¥
-
+
+ 本店已关闭推广员查看费用
+ 提交后由接诊医生确认价格
+
+
+
+ 诊疗费
+
+ ¥
+
+
-
-
- 加工费
- ¥{{processingFee.toFixed(2)}}
-
-
-
-
- 商品计费
- 毛利率 {{ grossMarginText }}%
+
+ 加工费
+ ¥{{processingFee.toFixed(2)}}
- ¥{{totalProductCost.toFixed(2)}}
-
-
-
- 合计
- ¥{{totalPrice}}
-
+
+
+ 商品计费
+ 毛利率 {{ grossMarginText }}%
+
+ ¥{{totalProductCost.toFixed(2)}}
+
+
+
+ 合计
+ ¥{{totalPrice}}
+
+
@@ -379,7 +397,7 @@
- 另存常用方
+ 另存常用方
- {{ isCommonPrescription ? '保存常用方' : '发送处方' }}
+ {{ isCommonPrescription ? '保存常用方' : (isSalespersonTransferMode ? '提交传方' : '发送处方') }}
@@ -407,6 +425,7 @@
@@ -439,9 +458,18 @@
:initial-search-key="chineseModalInitialKeyword"
:register-id="registerId"
:see-rate="seeRate"
+ :salesperson-transfer-mode="isSalespersonTransferMode"
+ :show-drug-price="showSalespersonTransferPrice"
@select="handleSelectChineseDrug"
/>
+
+
0
+ || this.diagnoses.length > 0
+ || !!(this.medicalAdvice && String(this.medicalAdvice).trim());
+ },
+ shouldEnablePageBackGuard() {
+ return this.hasPrescriptionOverlay;
+ },
+ scrollStyle() {
+ try {
+ const sys = uni.getSystemInfoSync();
+ const rpxRatio = sys.windowWidth / 750;
+ const topRpx = this.isSalespersonTransferMode ? 500 : 600;
+ const bottomRpx = 200;
+ const heightPx = sys.windowHeight - topRpx * rpxRatio - bottomRpx * rpxRatio;
+ return {
+ height: `${Math.max(Math.floor(heightPx), 200)}px`,
+ marginBottom: '200rpx',
+ };
+ } catch (e) {
+ const topRpx = this.isSalespersonTransferMode ? 500 : 600;
+ return {
+ height: `calc(100vh - ${topRpx}rpx)`,
+ marginBottom: '200rpx',
+ };
+ }
+ },
onlineTcmDiseasesLabel() {
const data = this.traditionalTcmData;
const id = this.onlineTcmDiseasesId;
@@ -749,13 +836,27 @@ export default {
if (!val) this.chineseModalInitialKeyword = '';
},
// #ifdef MP-WEIXIN
- hasPrescriptionOverlay(val) {
- this.pageBackGuardShow = !!val;
+ shouldEnablePageBackGuard(val) {
+ this.setPageBackGuardShow(!!val, { suppressLeave: !val });
+ this.syncSalespersonTransferUnloadAlert();
+ },
+ hasTransferDraft() {
+ this.syncSalespersonTransferUnloadAlert();
},
// #endif
},
+ created() {
+ // u-navbar 在小程序内 bind($parent) 可能拿不到页面实例,用箭头函数固定 this
+ this.boundCustomBack = () => this.handleCustomBack();
+ },
onLoad(options) {
- this.registerId = options.register_id || '';
+ this.isSalespersonTransferMode = String(options.salesperson_transfer) === '1';
+ if (this.isSalespersonTransferMode) {
+ this.registerId = SALESPERSON_TRANSFER_STORAGE_KEY;
+ this._presetActiveCategory = 1;
+ } else {
+ this.registerId = options.register_id || '';
+ }
this.patientId = options.patient_id || '';
this.pendingReusePrescriptionId = options.reuse_prescription_id ? String(options.reuse_prescription_id) : '';
this.isCommonPrescription = String(options.save_common) === '1';
@@ -773,33 +874,86 @@ export default {
if (this.activeCategory === 1 && this.chineseConfig.ruleType === 2) {
await this.hydrateChineseProcessRuleListsFromConfig();
}
- if (this.activeCategory === 1) await this.checkAndShowTransferTip();
+ if (!this.isSalespersonTransferMode && this.activeCategory === 1) {
+ await this.checkAndShowTransferTip();
+ }
},
onUnload() {
if (this.isCommonPrescription) {
uni.removeStorageSync('add');
}
+ // #ifdef MP-WEIXIN
+ if (this.isSalespersonTransferMode) {
+ uni.disableAlertBeforeUnload();
+ }
+ // #endif
},
methods: {
+ // #ifdef MP-WEIXIN
+ setPageBackGuardShow(show, { suppressLeave = false } = {}) {
+ if (suppressLeave) this._suppressPageBackGuardLeave = true;
+ this.pageBackGuardShow = !!show;
+ },
+ syncSalespersonTransferUnloadAlert() {
+ if (!this.isSalespersonTransferMode) return;
+ if (this.hasTransferDraft && !this.hasPrescriptionOverlay) {
+ uni.enableAlertBeforeUnload({ message: '有未提交的传方内容,确定退出?' });
+ } else {
+ uni.disableAlertBeforeUnload();
+ }
+ },
+ // #endif
async initializePageData() {
try {
this.restoreFromLocalStorage();
- await this.loadPatientInfo();
- await this.loadRegisterOrderType();
- await this.loadBasicConfigData();
- await this.loadRegisterStoreInfo();
+ if (this.isSalespersonTransferMode) {
+ await this.loadSalespersonTransferConfig();
+ await this.loadBasicConfigDataForTransfer();
+ } else {
+ await this.loadPatientInfo();
+ await this.loadRegisterOrderType();
+ await this.loadBasicConfigData();
+ await this.loadRegisterStoreInfo();
+ }
this.loadCurrentCategoryDrugs();
if (this.activeCategory === 1 && this.chineseConfig.ruleType === 2) {
await this.hydrateChineseProcessRuleListsFromConfig();
}
- await this.maybeApplyReusePrescription();
- if (this.activeCategory === 1) await this.checkAndShowTransferTip();
- this.applyPendingExperienceDrugFromChat();
+ if (!this.isSalespersonTransferMode) {
+ await this.maybeApplyReusePrescription();
+ if (this.activeCategory === 1) await this.checkAndShowTransferTip();
+ this.applyPendingExperienceDrugFromChat();
+ }
+ // #ifdef MP-WEIXIN
+ this.$nextTick(() => {
+ this.setPageBackGuardShow(this.shouldEnablePageBackGuard);
+ this.syncSalespersonTransferUnloadAlert();
+ });
+ // #endif
} catch (error) {
console.error('初始化页面数据失败:', error);
this.$toast('初始化失败,请重试');
}
},
+ async loadSalespersonTransferConfig() {
+ try {
+ const wrap = await getClinicSalespersonSeePriceConfig();
+ if (wrap && wrap.ok) {
+ this.salespersonSeePrice = Number(wrap.data?.see_price ?? 0);
+ }
+ } catch (error) {
+ console.error('获取推广员价格配置失败:', error);
+ }
+ },
+ async loadBasicConfigDataForTransfer() {
+ try {
+ if (this.activeCategory === 1 && this.processRuleList.length === 0) {
+ await this.loadProcessRuleList(0, 0);
+ }
+ } catch (error) {
+ console.error('加载基础配置数据失败:', error);
+ }
+ },
restoreFromLocalStorage() {
if (this._presetActiveCategory !== null && this._presetActiveCategory !== undefined && !Number.isNaN(this._presetActiveCategory)) {
this.activeCategory = this._presetActiveCategory;
@@ -972,6 +1126,10 @@ export default {
if (res) {
this.registerStoreInfo = res;
this.seeRate = Number(res.see_rate ?? 0);
+ if (Number(res.allow_insurance_category ?? 0) !== 1) {
+ this.feeCategory = 1;
+ }
+ this.checkSalespersonTransfer();
if (res.is_from_transfer === 1 && res.delegate_store_id) {
this.selectedStoreId = res.delegate_store_id;
this.sendMode = 1;
@@ -984,11 +1142,65 @@ export default {
console.error('获取挂号诊所信息失败:', error);
}
},
+ async checkSalespersonTransfer() {
+ if (!this.registerId) {
+ this.hasSalespersonTransfer = false;
+ return;
+ }
+ try {
+ const res = await getSalespersonTransferByRegisterApi(this.registerId);
+ const list = res?.result || res?.data || res;
+ this.hasSalespersonTransfer = Array.isArray(list) && list.length > 0;
+ } catch {
+ this.hasSalespersonTransfer = false;
+ }
+ },
+ async openSalespersonTransfer() {
+ try {
+ const res = await getSalespersonTransferByRegisterApi(this.registerId);
+ const list = res?.result || res?.data || res;
+ if (!Array.isArray(list) || !list.length) {
+ this.$toast('暂无待导入传方');
+ return;
+ }
+ const item = list[0];
+ const parsed = parseTransferPrescriptionContent(item);
+ if (!parsed || !parsed.drugList?.length) {
+ this.$toast('传方数据无效');
+ return;
+ }
+ this.salespersonTransferPrescriptionId = item.id;
+ this.activeCategory = 1;
+ parsed.drugList.forEach((drug) => {
+ this.currentDrugs.push({
+ index_id: drug.index_id ?? drug.drug_id ?? drug.id,
+ id: drug.drug_id || drug.id,
+ drug_id: drug.drug_id || drug.id,
+ drug_name: drug.drug_name || drug.name,
+ name: drug.drug_name || drug.name,
+ number: drug.number || 1,
+ way_id: drug.way_id || 0,
+ price: drug.price ?? 0,
+ buy_price: drug.buy_price,
+ });
+ });
+ if (parsed.clinical_diagnose) {
+ this.diagnoses = [{ id: Date.now(), name: parsed.clinical_diagnose }];
+ }
+ if (parsed.doctor_order) this.medicalAdvice = parsed.doctor_order;
+ this.saveToLocalStorage();
+ this.$toast('传方已导入');
+ } catch (e) {
+ console.error(e);
+ this.$toast('加载传方失败');
+ }
+ },
async handleSwitchCategory(category) {
this.saveToLocalStorage();
this.activeCategory = category;
this.loadCurrentCategoryDrugs();
if (category === 1) {
+ await this.checkSalespersonTransfer();
await this.checkAndShowTransferTip();
if (this.processRuleList.length === 0) await this.loadProcessRuleList(0, 0);
}
@@ -1436,8 +1648,16 @@ export default {
async loadProcessRuleList(pid = 0, ruleId = 0) {
try {
const data = ruleId === 0 ? { pid } : { rule_id: ruleId };
- const res = await getProcessRuleList(data);
- const list = res?.data || res?.result || res || [];
+ let list = [];
+ if (this.isSalespersonTransferMode) {
+ const wrap = await getClinicSalespersonProcessRuleList(data);
+ if (wrap && wrap.ok) {
+ list = Array.isArray(wrap.data) ? wrap.data : [];
+ }
+ } else {
+ const res = await getProcessRuleList(data);
+ list = res?.data || res?.result || res || [];
+ }
if (ruleId !== 0) {
this.processRuleNoteList = list;
} else if (pid === 0) {
@@ -1643,6 +1863,11 @@ export default {
const validation = this.validatePrescriptionData();
if (!validation.valid) { this.$toast(validation.message); return; }
+ if (this.isSalespersonTransferMode) {
+ this.showTransferPatientDrawer = true;
+ return;
+ }
+
this.isSubmitting = true;
try {
if (!this.registerStoreInfo) await this.loadRegisterStoreInfo();
@@ -1741,7 +1966,8 @@ export default {
}
const params = {
- patient: patientData, drugs: drugsData, diagnosis: clinical_diagnose, medicalAdvice: this.medicalAdvice, total: parseFloat(this.totalPrice), category: 1, drug_type: 2, register_id: parseInt(this.registerId), treatment_price: parseFloat(this.treatmentPrice || 0), prescription_type: this.activeCategory, doctor_second_sign: doctorSecondSignValue, send_mode: finalSendMode, custom_store_id: finalSendMode === 1 ? finalStoreId : null
+ patient: patientData, drugs: drugsData, diagnosis: clinical_diagnose, medicalAdvice: this.medicalAdvice, total: parseFloat(this.totalPrice), category: this.feeCategory, drug_type: 2, register_id: parseInt(this.registerId), treatment_price: parseFloat(this.treatmentPrice || 0), prescription_type: this.activeCategory, doctor_second_sign: doctorSecondSignValue, send_mode: finalSendMode, custom_store_id: finalSendMode === 1 ? finalStoreId : null,
+ salesperson_transfer_prescription_id: this.salespersonTransferPrescriptionId || undefined,
};
if (this.activeCategory === 1) {
params.package_method_id = this.chineseConfig.packageMethodId || null; params.process_rule_id = this.chineseConfig.processRuleId || null; params.process_rule_note_id = this.chineseConfig.processRuleNoteId || null; params.child_process_rule_id = this.chineseConfig.childProcessRuleId || null; params.process_rule_type = this.chineseConfig.ruleType || 1; params.processing_fee = this.processingFee; params.dosage = this.chineseConfig.dosage || 7; params.day_dosage = this.chineseConfig.dayDosage || 2;
@@ -1848,6 +2074,97 @@ export default {
if (this.isCommonPrescription) { uni.removeStorageSync('add'); this.safeNavigateBack(400); }
} catch (error) { console.error('保存常用方失败:', error); this.$toast('保存常用方失败,请重试'); }
},
+ buildSalespersonTransferPayload(patientData) {
+ const clinicalDiagnose = this.diagnosisText || this.diagnoses.map((item) => item.name).join(',');
+ const drugs = this.currentDrugs.map((drug) => ({
+ drug_id: drug.id || drug.drug_id || drug.index_id,
+ drug_name: drug.drug_name || drug.name,
+ number: drug.number || drug._quantity || 1,
+ way_id: drug.way_id || 0,
+ }));
+ return {
+ patient_name: patientData.patient_name,
+ patient_mobile: patientData.patient_mobile,
+ patient_address: patientData.patient_address,
+ prescription_images: patientData.prescription_images || [],
+ clinical_diagnose: clinicalDiagnose,
+ doctor_order: this.medicalAdvice || '',
+ dosage: this.chineseConfig.dosage || 7,
+ day_dosage: this.chineseConfig.dayDosage || 2,
+ drugs,
+ };
+ },
+ async handleTransferPatientConfirm(patientData) {
+ this.transferDrawerSubmitting = true;
+ try {
+ const wrap = await createClinicSalespersonTransferPrescription(
+ this.buildSalespersonTransferPayload(patientData)
+ );
+ if (wrap && wrap.ok) {
+ PrescriptionStorage.clearAllPrescriptionData(SALESPERSON_TRANSFER_STORAGE_KEY);
+ this.showTransferPatientDrawer = false;
+ if (this.$refs.transferPatientDrawer && this.$refs.transferPatientDrawer.resetForm) {
+ this.$refs.transferPatientDrawer.resetForm();
+ }
+ // #ifdef MP-WEIXIN
+ this.setPageBackGuardShow(false, { suppressLeave: true });
+ uni.disableAlertBeforeUnload();
+ // #endif
+ this.$toast('提交成功');
+ setTimeout(() => {
+ uni.navigateTo({ url: '/subPackages/sub_clinic_salesperson/transfer-prescription/list' });
+ }, 500);
+ } else {
+ this.$toast(wrap?.res?.msg || wrap?.res?.message || '提交失败');
+ }
+ } catch (error) {
+ console.error('提交传方失败:', error);
+ this.$toast('提交传方失败,请重试');
+ } finally {
+ this.transferDrawerSubmitting = false;
+ }
+ },
+ tryLeaveSalespersonTransferPage(onConfirm) {
+ if (this.hasTransferDraft) {
+ uni.showModal({
+ title: '提示',
+ content: '有未提交的传方内容,确定退出?',
+ success: ({ confirm }) => {
+ if (confirm) {
+ // #ifdef MP-WEIXIN
+ this.setPageBackGuardShow(false, { suppressLeave: true });
+ uni.disableAlertBeforeUnload();
+ // #endif
+ if (typeof onConfirm === 'function') onConfirm();
+ } else {
+ // #ifdef MP-WEIXIN
+ this.setPageBackGuardShow(this.shouldEnablePageBackGuard, {
+ suppressLeave: !this.shouldEnablePageBackGuard,
+ });
+ // #endif
+ }
+ },
+ });
+ return;
+ }
+ // #ifdef MP-WEIXIN
+ this.setPageBackGuardShow(false, { suppressLeave: true });
+ uni.disableAlertBeforeUnload();
+ // #endif
+ if (typeof onConfirm === 'function') onConfirm();
+ },
+ navigateToSalespersonWorkbench() {
+ const pages = getCurrentPages();
+ if (pages.length > 1) {
+ this.safeNavigateBack(0);
+ return;
+ }
+ // #ifdef MP-WEIXIN
+ this.setPageBackGuardShow(false, { suppressLeave: true });
+ uni.disableAlertBeforeUnload();
+ // #endif
+ uni.reLaunch({ url: SALESPERSON_HOME_URL });
+ },
/** 若有弹层打开则关闭第一个并返回 true(用于导航返回 / 微信 page-container leave 先关抽屉) */
closeTopOverlayIfAny() {
for (let i = 0; i < PRESCRIPTION_OVERLAY_KEYS.length; i++) {
@@ -1863,7 +2180,7 @@ export default {
safeNavigateBack(delayMs = 0) {
const runNav = () => {
// #ifdef MP-WEIXIN
- this.pageBackGuardShow = false;
+ this.setPageBackGuardShow(false, { suppressLeave: true });
setTimeout(() => {
uni.navigateBack();
}, 16);
@@ -1880,14 +2197,31 @@ export default {
},
// #ifdef MP-WEIXIN
onPageBackGuardLeave() {
- this.closeTopOverlayIfAny();
- this.$nextTick(() => {
- this.pageBackGuardShow = this.hasPrescriptionOverlay;
- });
+ if (this._suppressPageBackGuardLeave) {
+ this._suppressPageBackGuardLeave = false;
+ return;
+ }
+ if (this.closeTopOverlayIfAny()) {
+ this.$nextTick(() => {
+ this.setPageBackGuardShow(this.shouldEnablePageBackGuard, { suppressLeave: true });
+ this.syncSalespersonTransferUnloadAlert();
+ });
+ return;
+ }
+ this.setPageBackGuardShow(false);
+ if (this.isSalespersonTransferMode) {
+ this.tryLeaveSalespersonTransferPage(() => this.navigateToSalespersonWorkbench());
+ return;
+ }
+ this.safeNavigateBack(0);
},
// #endif
handleCustomBack() {
if (this.closeTopOverlayIfAny()) return;
+ if (this.isSalespersonTransferMode) {
+ this.tryLeaveSalespersonTransferPage(() => this.navigateToSalespersonWorkbench());
+ return;
+ }
this.safeNavigateBack(0);
}
}