f
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
</div>
|
||||
|
||||
<div class="border-b border-gray-200">
|
||||
<wd-input v-model="price" type="number" label="¥" label-width="28px" size="large"
|
||||
<wd-input v-model="price" type="digit" label="¥" label-width="28px" size="large"
|
||||
:placeholder="priceRangePlaceholder" @blur="onBlurPrice" custom-class="wd-input" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between mt-2">
|
||||
|
||||
@@ -51,6 +51,7 @@ const currentPromoteData = computed(() => {
|
||||
const currentTeamData = computed(() => {
|
||||
const range = dateRangeMap[selectedTeamDate.value]
|
||||
return data.value?.active_reward?.[range] || {
|
||||
active_reward: 0,
|
||||
sub_promote_reward: 0,
|
||||
sub_upgrade_reward: 0,
|
||||
sub_withdraw_reward: 0
|
||||
@@ -72,7 +73,7 @@ const getData = async () => {
|
||||
if (res.code === 200) {
|
||||
data.value = res.data
|
||||
}
|
||||
} catch {}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
@@ -195,6 +196,9 @@ function toWithdrawDetails() {
|
||||
<view class="flex items-center">
|
||||
<text class="text-lg font-bold text-gray-800">活跃下级奖励</text>
|
||||
</view>
|
||||
<view class="text-right">
|
||||
<text class="text-2xl text-green-600 font-bold">¥ {{ (data?.active_reward?.total_reward || 0).toFixed(2) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="grid grid-cols-3 gap-2 mb-6">
|
||||
@@ -209,37 +213,44 @@ function toWithdrawDetails() {
|
||||
</view>
|
||||
|
||||
<view class="grid grid-cols-2 gap-2 mb-6">
|
||||
<view class="bg-green-50/60 p-3 rounded-lg backdrop-blur-sm">
|
||||
<view class="flex items-center text-sm text-gray-500">
|
||||
<text>{{ teamTimeText }}奖励</text>
|
||||
</view>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentTeamData.active_reward || 0).toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="bg-green-50/60 p-3 rounded-lg backdrop-blur-sm">
|
||||
<view class="flex items-center text-sm text-gray-500">
|
||||
<text>{{ teamTimeText }}下级推广奖励</text>
|
||||
</view>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentTeamData.sub_promote_reward || 0).toFixed(2) }}</text>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentTeamData.sub_promote_reward ||
|
||||
0).toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="bg-green-50/60 p-3 rounded-lg backdrop-blur-sm">
|
||||
<view class="flex items-center text-sm text-gray-500">
|
||||
<text>{{ teamTimeText }}下级转化奖励</text>
|
||||
</view>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentTeamData.sub_upgrade_reward || 0).toFixed(2) }}</text>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentTeamData.sub_upgrade_reward ||
|
||||
0).toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="bg-green-50/60 p-3 rounded-lg backdrop-blur-sm">
|
||||
<view class="flex items-center text-sm text-gray-500">
|
||||
<text>{{ teamTimeText }}下级提现奖励</text>
|
||||
</view>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentTeamData.sub_withdraw_reward || 0).toFixed(2) }}</text>
|
||||
<text class="text-xl text-green-600 font-bold mt-1">¥ {{ (currentTeamData.sub_withdraw_reward ||
|
||||
0).toFixed(2) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||
<view
|
||||
class="w-full rounded-full border border-gray-200/80 bg-white/90 py-3 px-4 text-center text-sm text-gray-600 font-medium shadow-sm"
|
||||
@click="goToRewardsDetail"
|
||||
>
|
||||
@click="goToRewardsDetail">
|
||||
<text>查看奖励明细</text>
|
||||
</view>
|
||||
<view
|
||||
class="w-full rounded-full bg-gradient-to-r from-green-500 to-emerald-500 py-3 px-4 text-center text-sm text-white font-medium shadow-sm"
|
||||
@click="toSubordinateList"
|
||||
>
|
||||
@tap="toSubordinateList">
|
||||
<text>查看我的下级</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -247,11 +258,7 @@ function toWithdrawDetails() {
|
||||
</view>
|
||||
|
||||
<!-- 公众号二维码弹窗 -->
|
||||
<GzhQrcode
|
||||
:visible="showGzhQrcode"
|
||||
type="withdraw"
|
||||
@close="closeGzhQrcode"
|
||||
/>
|
||||
<GzhQrcode :visible="showGzhQrcode" type="withdraw" @close="closeGzhQrcode" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -44,9 +44,14 @@
|
||||
<wd-form>
|
||||
<!-- 加价金额 -->
|
||||
|
||||
<wd-form-item label="加价金额" prop="price_increase_amount">
|
||||
<wd-form-item label="加价金额" prop="price_increase_amount" custom-class="vip-form-item">
|
||||
<view class="vip-input-row">
|
||||
<view class="vip-input-wrap">
|
||||
<wd-input v-model="configData.price_increase_amount" type="number" placeholder="0"
|
||||
@blur="validateDecimal('price_increase_amount')" />
|
||||
custom-class="vip-wd-input" @blur="validateDecimal('price_increase_amount')" />
|
||||
</view>
|
||||
<text class="vip-input-unit">元</text>
|
||||
</view>
|
||||
</wd-form-item>
|
||||
<view class="text-xs text-gray-400 mt-1">
|
||||
<text class="block">提示:最大加价金额为{{ priceIncreaseAmountMax }}元</text>
|
||||
@@ -61,9 +66,14 @@
|
||||
</view>
|
||||
|
||||
<!-- 定价区间最低 -->
|
||||
<wd-form-item label="定价区间最低" prop="price_range_from">
|
||||
<wd-form-item label="定价区间最低" prop="price_range_from" custom-class="vip-form-item">
|
||||
<view class="vip-input-row">
|
||||
<view class="vip-input-wrap">
|
||||
<wd-input v-model="configData.price_range_from" type="number" placeholder="0"
|
||||
@blur="() => { validateDecimal('price_range_from'); validateRange(); }" />
|
||||
custom-class="vip-wd-input" @blur="() => { validateDecimal('price_range_from'); validateRange(); }" />
|
||||
</view>
|
||||
<text class="vip-input-unit">元</text>
|
||||
</view>
|
||||
</wd-form-item>
|
||||
<view class="text-xs text-gray-400 mt-1">
|
||||
<text class="block">提示:定价区间最低金额不能低于(基础最低 {{ productConfigData?.price_range_min || 0 }}元 + 加价金额)</text>
|
||||
@@ -71,9 +81,14 @@
|
||||
</view>
|
||||
|
||||
<!-- 定价区间最高 -->
|
||||
<wd-form-item label="定价区间最高" prop="price_range_to">
|
||||
<wd-input v-model="configData.price_range_to" type="number" placeholder="0"
|
||||
<wd-form-item label="定价区间最高" prop="price_range_to" custom-class="vip-form-item">
|
||||
<view class="vip-input-row">
|
||||
<view class="vip-input-wrap">
|
||||
<wd-input v-model="configData.price_range_to" type="number" placeholder="0" custom-class="vip-wd-input"
|
||||
@blur="() => { validateDecimal('price_range_to'); validateRange(); }" />
|
||||
</view>
|
||||
<text class="vip-input-unit">元</text>
|
||||
</view>
|
||||
</wd-form-item>
|
||||
<view class="text-xs text-gray-400 mt-1">
|
||||
<text class="block">提示:定价区间最高金额不能超过上限({{ productConfigData?.price_range_max || 0 }}元)和大于定价区间最低金额({{
|
||||
@@ -83,8 +98,14 @@
|
||||
</view>
|
||||
|
||||
<!-- 收取比例 -->
|
||||
<wd-form-item label="收取比例" prop="price_ratio">
|
||||
<wd-input v-model="configData.price_ratio" type="number" placeholder="0" @blur="validateRatio" />
|
||||
<wd-form-item label="收取比例" prop="price_ratio" custom-class="vip-form-item">
|
||||
<view class="vip-input-row">
|
||||
<view class="vip-input-wrap">
|
||||
<wd-input v-model="configData.price_ratio" type="number" placeholder="0" custom-class="vip-wd-input"
|
||||
@blur="validateRatio" />
|
||||
</view>
|
||||
<text class="vip-input-unit">%</text>
|
||||
</view>
|
||||
</wd-form-item>
|
||||
<view class="text-xs text-gray-400 mt-1">
|
||||
<text class="block">提示:最大收取比例为{{ priceRatioMax }}%</text>
|
||||
@@ -357,7 +378,8 @@ const loadReportOptions = async () => {
|
||||
if (res.code !== 200 || !res.data)
|
||||
return
|
||||
const list = res.data.agent_product_config || res.data.AgentProductConfig || []
|
||||
reportOptions.value = list
|
||||
reportOptions.value = [...list]
|
||||
.sort((a, b) => Number(a.product_id) - Number(b.product_id))
|
||||
.map(p => ({
|
||||
label: p.product_name || `报告${p.product_id}`,
|
||||
value: p.product_id,
|
||||
@@ -367,7 +389,7 @@ const loadReportOptions = async () => {
|
||||
if (!reportOptions.value.find(o => o.value === selectedReportId.value))
|
||||
selectedReportId.value = reportOptions.value[0].value
|
||||
}
|
||||
} catch {}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -377,7 +399,7 @@ onMounted(async () => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<style lang="scss" scoped>
|
||||
.card {
|
||||
border-radius: 24rpx;
|
||||
background-color: white;
|
||||
@@ -391,13 +413,55 @@ onMounted(async () => {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.space-y-6 > view {
|
||||
.space-y-6>view {
|
||||
margin-bottom: 48rpx;
|
||||
}
|
||||
|
||||
.space-y-6 > view:last-child {
|
||||
.space-y-6>view:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
:deep(.wd-cell__title) {
|
||||
line-height: 34px !important;
|
||||
}
|
||||
|
||||
.vip-input-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 16rpx;
|
||||
padding: 0 24rpx;
|
||||
background: #FAFAFA;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.vip-input-wrap:focus-within {
|
||||
border-color: #93c5fd;
|
||||
background: #FAFAFA;
|
||||
box-shadow: 0 0 0 6rpx rgba(59, 130, 246, 0.32);
|
||||
}
|
||||
|
||||
.vip-input-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vip-input-unit {
|
||||
margin-left: 12rpx;
|
||||
color: #3b82f6;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
:deep(.vip-wd-input.wd-input),
|
||||
:deep(.vip-wd-input.wd-input:after),
|
||||
:deep(.vip-wd-input .wd-input),
|
||||
:deep(.vip-wd-input .wd-input__body),
|
||||
:deep(.vip-wd-input .wd-input__inner),
|
||||
:deep(.vip-wd-input .wd-input__value),
|
||||
:deep(.vip-wd-input .wd-input__clear) {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
</style>
|
||||
<route type="page" lang="json">{
|
||||
"layout": "page",
|
||||
|
||||
@@ -95,7 +95,8 @@ const formData = ref({
|
||||
const reportTypes = computed(() => {
|
||||
if (!productConfig.value?.length)
|
||||
return []
|
||||
return productConfig.value
|
||||
return [...productConfig.value]
|
||||
.sort((a, b) => Number(a.product_id) - Number(b.product_id))
|
||||
.map(item => ({
|
||||
id: item.product_id,
|
||||
label: item.product_name || `产品${item.product_id}`,
|
||||
|
||||
@@ -7,6 +7,16 @@ export function safeTruncate(num, decimals = 2) {
|
||||
return (scaled / factor).toFixed(decimals)
|
||||
}
|
||||
|
||||
function toTruncatedCents(num) {
|
||||
if (Number.isNaN(num) || !Number.isFinite(num))
|
||||
return 0
|
||||
return Math.trunc((num + Number.EPSILON) * 100)
|
||||
}
|
||||
|
||||
function centsToFixed(cents) {
|
||||
return (cents / 100).toFixed(2)
|
||||
}
|
||||
|
||||
function calculatePlatformOverpricingCost(price, config) {
|
||||
if (price <= config.p_pricing_standard)
|
||||
return 0
|
||||
@@ -37,10 +47,12 @@ export function calculatePromotionPricing(priceInput, config) {
|
||||
const platformOverpricingCost = calculatePlatformOverpricingCost(price, config)
|
||||
const superiorOverpricingCost = calculateSuperiorOverpricingCost(price, config)
|
||||
const totalCost = baseCost + platformOverpricingCost + superiorOverpricingCost
|
||||
const revenue = price - totalCost
|
||||
const priceCents = toTruncatedCents(price)
|
||||
const costCents = toTruncatedCents(totalCost)
|
||||
const revenueCents = priceCents - costCents
|
||||
|
||||
return {
|
||||
costPrice: safeTruncate(totalCost),
|
||||
promotionRevenue: safeTruncate(revenue),
|
||||
costPrice: centsToFixed(costCents),
|
||||
promotionRevenue: centsToFixed(revenueCents),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user