Files
2026-07-07 08:50:05 +08:00

215 lines
7.6 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<page-layout :is-platform="ctx.isPlatform" :title="isUpdate ? '编辑推广员' : '新增推广员'" :show-back="true">
<view class="page">
<store-search-picker v-if="ctx.isPlatform && !isUpdate" v-model="form.store_id" :api="ctx.api" />
<view class="field">
<text class="label">手机号</text>
<input class="input" v-model="form.phone" type="number" maxlength="11" placeholder="请输入手机号" :disabled="isUpdate" />
</view>
<view class="field">
<text class="label">名称</text>
<input class="input" v-model="form.nick_name" placeholder="请输入名称" />
</view>
<view class="field">
<text class="label">西药分成类型</text>
<picker :range="splitTypeLabels" :value="splitTypeIndex" @change="onSplitType">
<view class="picker-val">{{ splitTypeLabels[splitTypeIndex] }}</view>
</picker>
</view>
<view v-if="Number(form.split_type) === 1" class="field">
<text class="label">分成比例%</text>
<input class="input" v-model="form.split" type="digit" placeholder="0-100" />
</view>
<view v-else class="field link" @click="goDrugCommission">
<text class="label">药品佣金配置</text>
<text class="link-text">去配置元/件分成 ></text>
</view>
<view class="section-title">中药推广分成</view>
<view class="field">
<text class="label">中药分成%</text>
<input class="input" v-model="form.tcm_split" type="digit" placeholder="0 表示不分成" />
</view>
<view v-if="Number(form.tcm_split) > 0" class="field">
<text class="label">中药分成基数</text>
<picker :range="tcmBaseLabels" :value="tcmBaseIndex" @change="onTcmBase">
<view class="picker-val">{{ tcmBaseLabels[tcmBaseIndex] }}</view>
</picker>
</view>
<view class="section-title">邀请关系可选</view>
<view class="field-col">
<text class="label block">邀请人推广员</text>
<salesperson-picker
v-model="form.parent_salesperson_id"
:exclude-id="form.id"
:store-id="form.store_id"
:fetch-options="fetchSalespersonOptions"
:initial-selected="parentInitial"
/>
</view>
<view v-if="Number(form.parent_salesperson_id) > 0" class="field">
<text class="label">邀请分成%</text>
<input class="input" v-model="form.inviter_split" type="digit" placeholder="上级从订单利润中获得的比例" />
</view>
<view class="submit-btn" @click="submit">保存</view>
</view>
</page-layout>
</template>
<script>
import PageLayout from './components/PageLayout.vue';
import StoreSearchPicker from './components/StoreSearchPicker.vue';
import SalespersonPicker from './components/SalespersonPicker.vue';
import { getSalespersonManageContext, resolveManageMode } from './common/context.js';
import { SPLIT_TYPE_OPTIONS, TCM_BASE_OPTIONS } from './common/labels.js';
const ROOT = '/subPackages/sub_salesperson_manage';
export default {
components: { PageLayout, StoreSearchPicker, SalespersonPicker },
data() {
return {
ctx: getSalespersonManageContext('clinic'),
isUpdate: false,
parentInitial: null,
form: {
id: 0,
store_id: 0,
phone: '',
nick_name: '',
split_type: 0,
split: 0,
tcm_split: 0,
tcm_base_type: 0,
parent_salesperson_id: 0,
inviter_split: 0,
},
splitTypeLabels: SPLIT_TYPE_OPTIONS.map((o) => o.label),
tcmBaseLabels: TCM_BASE_OPTIONS.map((o) => o.label),
};
},
computed: {
splitTypeIndex() {
return SPLIT_TYPE_OPTIONS.findIndex((o) => o.value === Number(this.form.split_type));
},
tcmBaseIndex() {
return TCM_BASE_OPTIONS.findIndex((o) => o.value === Number(this.form.tcm_base_type));
},
},
onLoad(options) {
this.ctx = getSalespersonManageContext(resolveManageMode(options));
this.isUpdate = !!options.id;
if (options.id) {
this.form.id = Number(options.id);
this.form.store_id = Number(options.store_id || 0);
this.loadDetail(options);
}
},
methods: {
fetchSalespersonOptions(params) {
return this.ctx.api.getSalespersonOptions(params);
},
async loadDetail(options) {
const wrap = await this.ctx.api.getList({ page: 1, pageSize: 100 });
if (!wrap || !wrap.ok) return;
const item = (wrap.data.items || []).find((r) => Number(r.id) === Number(options.id));
if (!item) return;
this.form.phone = item.phone || '';
this.form.nick_name = item.nick_name || '';
this.form.split_type = Number(item.split_type) || 0;
this.form.split = item.split || 0;
this.form.tcm_split = item.tcm_split || 0;
this.form.tcm_base_type = Number(item.tcm_base_type) || 0;
this.form.parent_salesperson_id = Number(item.parent_salesperson_id) || 0;
this.form.inviter_split = item.inviter_split || 0;
if (this.form.parent_salesperson_id > 0) {
this.parentInitial = {
id: this.form.parent_salesperson_id,
nick_name: item.parent_nick_name,
phone: item.parent_phone,
};
}
if (!this.form.store_id && item.qr_code) {
this.form.store_id = item.qr_code.store_id || 0;
}
},
onSplitType(e) {
const idx = Number(e.detail.value);
this.form.split_type = SPLIT_TYPE_OPTIONS[idx].value;
},
onTcmBase(e) {
const idx = Number(e.detail.value);
this.form.tcm_base_type = TCM_BASE_OPTIONS[idx].value;
},
goDrugCommission() {
const id = this.form.id || '';
const storeId = this.form.store_id || '';
uni.navigateTo({
url: `${ROOT}/drug-commission/index?mode=${this.ctx.mode}&salesperson_id=${id}&store_id=${storeId}`,
});
},
async submit() {
if (!this.form.phone || !this.form.nick_name) {
uni.showToast({ title: '请填写手机号和名称', icon: 'none' });
return;
}
if (this.ctx.isPlatform && !this.isUpdate && !this.form.store_id) {
uni.showToast({ title: '请选择诊所', icon: 'none' });
return;
}
if (Number(this.form.parent_salesperson_id) > 0 && !(Number(this.form.inviter_split) > 0)) {
uni.showToast({ title: '请填写邀请分成比例', icon: 'none' });
return;
}
const payload = { ...this.form };
if (Number(payload.split_type) === 0) payload.split = 0;
if (!(Number(payload.parent_salesperson_id) > 0)) {
payload.parent_salesperson_id = 0;
payload.inviter_split = 0;
}
uni.showLoading({ title: '保存中' });
try {
const wrap = this.isUpdate
? await this.ctx.api.update(payload)
: await this.ctx.api.create(payload);
if (wrap && wrap.ok) {
if (!this.isUpdate && wrap.data && wrap.data.admin_account_created === false) {
uni.showToast({ title: '已创建,请手动开通后台', icon: 'none', duration: 2500 });
} else {
uni.showToast({ title: '保存成功', icon: 'success' });
}
setTimeout(() => uni.navigateBack(), 500);
}
} finally {
uni.hideLoading();
}
},
},
};
</script>
<style lang="scss" scoped>
.page { padding: 24rpx; }
.field {
display: flex; align-items: center; background: #fff; border-radius: 16rpx;
padding: 24rpx; margin-bottom: 16rpx;
}
.field.link { justify-content: space-between; }
.label { width: 200rpx; font-size: 28rpx; color: #333; flex-shrink: 0; }
.input { flex: 1; font-size: 28rpx; text-align: right; }
.picker-val { flex: 1; font-size: 28rpx; text-align: right; color: #333; }
.link-text { font-size: 26rpx; color: #6ACDBB; }
.section-title { font-size: 26rpx; color: #999; margin: 24rpx 0 12rpx 8rpx; }
.field-col { background: #fff; border-radius: 16rpx; padding: 24rpx; margin-bottom: 16rpx; }
.label.block { display: block; width: auto; margin-bottom: 16rpx; }
.submit-btn {
margin-top: 40rpx; background: linear-gradient(90deg, #00BFA6, #6ACDBB);
color: #fff; text-align: center; padding: 24rpx; border-radius: 16rpx; font-size: 30rpx;
}
</style>