176 lines
5.7 KiB
Vue
176 lines
5.7 KiB
Vue
<template>
|
|
<page-layout :is-platform="ctx.isPlatform" title="药品佣金配置" :show-back="true">
|
|
<view class="page">
|
|
<view class="toolbar">
|
|
<input class="search" v-model="keyword" placeholder="搜索药品" @confirm="reload" />
|
|
<view class="search-btn" @click="reload">搜索</view>
|
|
</view>
|
|
|
|
<view v-if="salespersonId > 0" class="copy-row">
|
|
<picker :range="copyLabels" :value="copyIndex" @change="onCopyFrom">
|
|
<view class="copy-picker">{{ copyLabels[copyIndex] || '从其他推广员复制' }}</view>
|
|
</picker>
|
|
</view>
|
|
|
|
<view v-if="!list.length && !loading" class="empty">暂无药品</view>
|
|
<view v-for="item in list" :key="item.drug_id" class="row">
|
|
<view class="drug-info">
|
|
<text class="drug-name">{{ item.drug_name }}</text>
|
|
<text class="spec">{{ item.drug_spec }}</text>
|
|
<text class="price">售价 ¥{{ item.price }} / 供货 ¥{{ item.buy_price }}</text>
|
|
</view>
|
|
<input
|
|
class="commission-input"
|
|
v-model="dirtyMap[item.drug_id]"
|
|
type="digit"
|
|
placeholder="元/件"
|
|
@input="onCommissionInput(item.drug_id, $event)"
|
|
/>
|
|
</view>
|
|
|
|
<view v-if="salespersonId > 0" class="save-btn" @click="save">保存修改</view>
|
|
<view v-else class="hint">请先保存推广员基本信息后再配置药品佣金</view>
|
|
</view>
|
|
</page-layout>
|
|
</template>
|
|
|
|
<script>
|
|
import PageLayout from '../components/PageLayout.vue';
|
|
import { getSalespersonManageContext, resolveManageMode } from '../common/context.js';
|
|
|
|
export default {
|
|
components: { PageLayout },
|
|
data() {
|
|
return {
|
|
ctx: getSalespersonManageContext('clinic'),
|
|
salespersonId: 0,
|
|
storeId: 0,
|
|
keyword: '',
|
|
list: [],
|
|
loading: false,
|
|
dirtyMap: {},
|
|
copyOptions: [],
|
|
copyIndex: 0,
|
|
};
|
|
},
|
|
computed: {
|
|
copyLabels() {
|
|
return ['从其他推广员复制', ...this.copyOptions.map((o) => o.label)];
|
|
},
|
|
},
|
|
onLoad(options) {
|
|
this.ctx = getSalespersonManageContext(resolveManageMode(options));
|
|
this.salespersonId = Number(options.salesperson_id || 0);
|
|
this.storeId = Number(options.store_id || 0);
|
|
this.reload();
|
|
if (this.salespersonId > 0) this.loadCopyOptions();
|
|
},
|
|
methods: {
|
|
async reload() {
|
|
if (!this.salespersonId) return;
|
|
this.loading = true;
|
|
try {
|
|
const params = {
|
|
salesperson_id: this.salespersonId,
|
|
keyword: this.keyword,
|
|
page: 1,
|
|
pageSize: 100,
|
|
};
|
|
if (this.storeId > 0) params.store_id = this.storeId;
|
|
const wrap = await this.ctx.api.getDrugCommissionList(params);
|
|
const items = (wrap && wrap.ok && wrap.data && wrap.data.items) ? wrap.data.items : [];
|
|
this.list = items;
|
|
const map = { ...this.dirtyMap };
|
|
items.forEach((row) => {
|
|
if (map[row.drug_id] === undefined) {
|
|
map[row.drug_id] = row.commission || '';
|
|
}
|
|
});
|
|
this.dirtyMap = map;
|
|
} finally {
|
|
this.loading = false;
|
|
}
|
|
},
|
|
async loadCopyOptions() {
|
|
const wrap = await this.ctx.api.getList({ page: 1, pageSize: 100 });
|
|
if (!wrap || !wrap.ok) return;
|
|
this.copyOptions = (wrap.data.items || [])
|
|
.filter((sp) => Number(sp.id) !== this.salespersonId)
|
|
.map((sp) => ({
|
|
label: sp.nick_name || sp.phone || `推广员#${sp.id}`,
|
|
value: Number(sp.id),
|
|
}));
|
|
},
|
|
onCommissionInput(drugId, e) {
|
|
this.$set(this.dirtyMap, drugId, e.detail.value);
|
|
},
|
|
async onCopyFrom(e) {
|
|
const idx = Number(e.detail.value);
|
|
this.copyIndex = idx;
|
|
if (idx <= 0 || !this.copyOptions[idx - 1]) return;
|
|
const fromId = this.copyOptions[idx - 1].value;
|
|
const wrap = await this.ctx.api.getDrugCommissionCopyFrom(fromId);
|
|
if (!wrap || !wrap.ok) return;
|
|
const items = wrap.data.items || [];
|
|
const map = { ...this.dirtyMap };
|
|
items.forEach((row) => {
|
|
map[row.drug_id] = row.commission || '';
|
|
});
|
|
this.dirtyMap = map;
|
|
uni.showToast({ title: '已复制', icon: 'success' });
|
|
},
|
|
async save() {
|
|
const items = Object.keys(this.dirtyMap)
|
|
.filter((drugId) => this.dirtyMap[drugId] !== '' && this.dirtyMap[drugId] != null)
|
|
.map((drugId) => ({
|
|
drug_id: Number(drugId),
|
|
commission: String(this.dirtyMap[drugId]),
|
|
}));
|
|
if (!items.length) {
|
|
uni.showToast({ title: '无修改', icon: 'none' });
|
|
return;
|
|
}
|
|
uni.showLoading({ title: '保存中' });
|
|
try {
|
|
const wrap = await this.ctx.api.saveDrugCommission({
|
|
salesperson_id: this.salespersonId,
|
|
items,
|
|
});
|
|
if (wrap && wrap.ok) {
|
|
uni.showToast({ title: '保存成功', icon: 'success' });
|
|
}
|
|
} finally {
|
|
uni.hideLoading();
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.page { padding: 24rpx; padding-bottom: 120rpx; }
|
|
.toolbar { display: flex; gap: 12rpx; margin-bottom: 16rpx; }
|
|
.search { flex: 1; background: #fff; border-radius: 12rpx; padding: 16rpx 20rpx; font-size: 26rpx; }
|
|
.search-btn { background: #6ACDBB; color: #fff; padding: 16rpx 24rpx; border-radius: 12rpx; font-size: 26rpx; }
|
|
.copy-row { margin-bottom: 16rpx; }
|
|
.copy-picker { background: #fff; padding: 20rpx; border-radius: 12rpx; font-size: 26rpx; color: #6ACDBB; }
|
|
.row {
|
|
display: flex; align-items: center; background: #fff; border-radius: 16rpx;
|
|
padding: 20rpx; margin-bottom: 12rpx;
|
|
}
|
|
.drug-info { flex: 1; }
|
|
.drug-name { display: block; font-size: 28rpx; font-weight: 600; }
|
|
.spec, .price { font-size: 22rpx; color: #999; display: block; margin-top: 4rpx; }
|
|
.commission-input {
|
|
width: 140rpx; text-align: center; background: #f5f5f5; border-radius: 8rpx;
|
|
padding: 12rpx; font-size: 26rpx;
|
|
}
|
|
.save-btn {
|
|
position: fixed; left: 24rpx; right: 24rpx; bottom: 48rpx;
|
|
background: linear-gradient(90deg, #00BFA6, #6ACDBB); color: #fff;
|
|
text-align: center; padding: 24rpx; border-radius: 16rpx; font-size: 30rpx;
|
|
}
|
|
.hint { text-align: center; color: #999; padding: 40rpx; }
|
|
.empty { text-align: center; color: #999; padding: 80rpx 0; }
|
|
</style>
|