Files

215 lines
7.6 KiB
Vue
Raw Permalink Normal View History

2026-06-09 17:02:13 +08:00
<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>
2026-07-07 08:50:05 +08:00
<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>
2026-06-09 17:02:13 +08:00
<view class="submit-btn" @click="submit">保存</view>
</view>
</page-layout>
</template>
<script>
import PageLayout from './components/PageLayout.vue';
import StoreSearchPicker from './components/StoreSearchPicker.vue';
2026-07-07 08:50:05 +08:00
import SalespersonPicker from './components/SalespersonPicker.vue';
2026-06-09 17:02:13 +08:00
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 {
2026-07-07 08:50:05 +08:00
components: { PageLayout, StoreSearchPicker, SalespersonPicker },
2026-06-09 17:02:13 +08:00
data() {
return {
ctx: getSalespersonManageContext('clinic'),
isUpdate: false,
2026-07-07 08:50:05 +08:00
parentInitial: null,
2026-06-09 17:02:13 +08:00
form: {
id: 0,
store_id: 0,
phone: '',
nick_name: '',
split_type: 0,
split: 0,
tcm_split: 0,
tcm_base_type: 0,
2026-07-07 08:50:05 +08:00
parent_salesperson_id: 0,
inviter_split: 0,
2026-06-09 17:02:13 +08:00
},
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: {
2026-07-07 08:50:05 +08:00
fetchSalespersonOptions(params) {
return this.ctx.api.getSalespersonOptions(params);
},
2026-06-09 17:02:13 +08:00
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;
2026-07-07 08:50:05 +08:00
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,
};
}
2026-06-09 17:02:13 +08:00
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;
}
2026-07-07 08:50:05 +08:00
if (Number(this.form.parent_salesperson_id) > 0 && !(Number(this.form.inviter_split) > 0)) {
uni.showToast({ title: '请填写邀请分成比例', icon: 'none' });
return;
}
2026-06-09 17:02:13 +08:00
const payload = { ...this.form };
if (Number(payload.split_type) === 0) payload.split = 0;
2026-07-07 08:50:05 +08:00
if (!(Number(payload.parent_salesperson_id) > 0)) {
payload.parent_salesperson_id = 0;
payload.inviter_split = 0;
}
2026-06-09 17:02:13 +08:00
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; }
2026-07-07 08:50:05 +08:00
.field-col { background: #fff; border-radius: 16rpx; padding: 24rpx; margin-bottom: 16rpx; }
.label.block { display: block; width: auto; margin-bottom: 16rpx; }
2026-06-09 17:02:13 +08:00
.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>