f-4-30
This commit is contained in:
@@ -7,12 +7,12 @@ export default defineUniPages({
|
|||||||
{ path: 'pages/privacy-consent', style: { navigationStyle: 'custom', navigationBarTitleText: '隐私政策授权' } },
|
{ path: 'pages/privacy-consent', style: { navigationStyle: 'custom', navigationBarTitleText: '隐私政策授权' } },
|
||||||
{ path: 'pages/agent', style: { navigationBarTitleText: '代理中心' } },
|
{ path: 'pages/agent', style: { navigationBarTitleText: '代理中心' } },
|
||||||
{ path: 'pages/agent-manage-agreement', style: { navigationBarTitleText: '代理管理协议', navigationStyle: 'default' } },
|
{ path: 'pages/agent-manage-agreement', style: { navigationBarTitleText: '代理管理协议', navigationStyle: 'default' } },
|
||||||
{ path: 'pages/agent-promote-details', auth: true, style: { navigationBarTitleText: '直推收益明细' } },
|
{ path: 'pages/agent-promote-details', auth: true, style: { navigationBarTitleText: '收益明细' } },
|
||||||
{ path: 'pages/agent-rewards-details', auth: true, style: { navigationBarTitleText: '代理奖励收益明细' } },
|
{ path: 'pages/agent-rewards-details', auth: true, style: { navigationBarTitleText: '奖励明细' } },
|
||||||
{ path: 'pages/agent-service-agreement', style: { navigationBarTitleText: '信息技术服务合同', navigationStyle: 'default' } },
|
{ path: 'pages/agent-service-agreement', style: { navigationBarTitleText: '信息技术服务合同', navigationStyle: 'default' } },
|
||||||
{ path: 'pages/agent-vip', auth: true, style: { navigationBarTitleText: '代理会员' } },
|
{ path: 'pages/agent-vip', auth: true, style: { navigationBarTitleText: '代理会员' } },
|
||||||
{ path: 'pages/agent-vip-apply', auth: true, style: { navigationBarTitleText: 'VIP申请' } },
|
{ path: 'pages/agent-vip-apply', auth: true, style: { navigationBarTitleText: 'VIP代理申请' } },
|
||||||
{ path: 'pages/agent-vip-config', auth: true, style: { navigationBarTitleText: 'VIP配置' } },
|
{ path: 'pages/agent-vip-config', auth: true, style: { navigationBarTitleText: '代理会员报告配置' } },
|
||||||
{ path: 'pages/authorization', style: { navigationBarTitleText: '授权书', navigationStyle: 'default' } },
|
{ path: 'pages/authorization', style: { navigationBarTitleText: '授权书', navigationStyle: 'default' } },
|
||||||
{ path: 'pages/help', style: { navigationBarTitleText: '帮助中心' } },
|
{ path: 'pages/help', style: { navigationBarTitleText: '帮助中心' } },
|
||||||
{ path: 'pages/help-detail', style: { navigationBarTitleText: '帮助详情' } },
|
{ path: 'pages/help-detail', style: { navigationBarTitleText: '帮助详情' } },
|
||||||
@@ -27,11 +27,11 @@ export default defineUniPages({
|
|||||||
{ path: 'pages/not-found', style: { navigationBarTitleText: '页面不存在' } },
|
{ path: 'pages/not-found', style: { navigationBarTitleText: '页面不存在' } },
|
||||||
{ path: 'pages/payment-result', auth: true, style: { navigationBarTitleText: '支付结果' } },
|
{ path: 'pages/payment-result', auth: true, style: { navigationBarTitleText: '支付结果' } },
|
||||||
{ path: 'pages/privacy-policy', style: { navigationBarTitleText: '隐私政策', navigationStyle: 'default' } },
|
{ path: 'pages/privacy-policy', style: { navigationBarTitleText: '隐私政策', navigationStyle: 'default' } },
|
||||||
{ path: 'pages/promote', auth: true, style: { navigationBarTitleText: '推广管理' } },
|
{ path: 'pages/promote', auth: true, style: { navigationBarTitleText: '推广' } },
|
||||||
{ path: 'pages/report-example-webview', style: { navigationBarTitleText: '示例报告', navigationStyle: 'default' } },
|
{ path: 'pages/report-example-webview', style: { navigationBarTitleText: '示例报告', navigationStyle: 'default' } },
|
||||||
{ path: 'pages/report-result-webview', auth: true, style: { navigationBarTitleText: '报告结果', navigationStyle: 'default' } },
|
{ path: 'pages/report-result-webview', auth: true, style: { navigationBarTitleText: '报告结果', navigationStyle: 'default' } },
|
||||||
{ path: 'pages/report-share', style: { navigationBarTitleText: '报告分享', navigationStyle: 'default' } },
|
{ path: 'pages/report-share', style: { navigationBarTitleText: '报告分享', navigationStyle: 'default' } },
|
||||||
{ path: 'pages/subordinate-detail', auth: true, style: { navigationBarTitleText: '下级详情' } },
|
{ path: 'pages/subordinate-detail', auth: true, style: { navigationBarTitleText: '下级贡献详情' } },
|
||||||
{ path: 'pages/subordinate-list', auth: true, style: { navigationBarTitleText: '我的下级' } },
|
{ path: 'pages/subordinate-list', auth: true, style: { navigationBarTitleText: '我的下级' } },
|
||||||
{ path: 'pages/user-agreement', style: { navigationBarTitleText: '用户协议', navigationStyle: 'default' } },
|
{ path: 'pages/user-agreement', style: { navigationBarTitleText: '用户协议', navigationStyle: 'default' } },
|
||||||
{ path: 'pages/withdraw', auth: true, style: { navigationBarTitleText: '提现' } },
|
{ path: 'pages/withdraw', auth: true, style: { navigationBarTitleText: '提现' } },
|
||||||
|
|||||||
1
src/components.d.ts
vendored
1
src/components.d.ts
vendored
@@ -10,6 +10,7 @@ declare module 'vue' {
|
|||||||
AccountCancelAgreement: typeof import('./components/AccountCancelAgreement.vue')['default']
|
AccountCancelAgreement: typeof import('./components/AccountCancelAgreement.vue')['default']
|
||||||
AgentApplicationForm: typeof import('./components/AgentApplicationForm.vue')['default']
|
AgentApplicationForm: typeof import('./components/AgentApplicationForm.vue')['default']
|
||||||
BindPhoneDialog: typeof import('./components/BindPhoneDialog.vue')['default']
|
BindPhoneDialog: typeof import('./components/BindPhoneDialog.vue')['default']
|
||||||
|
EmptyState: typeof import('./components/EmptyState.vue')['default']
|
||||||
ImageSaveGuide: typeof import('./components/ImageSaveGuide.vue')['default']
|
ImageSaveGuide: typeof import('./components/ImageSaveGuide.vue')['default']
|
||||||
InquireForm: typeof import('./components/InquireForm.vue')['default']
|
InquireForm: typeof import('./components/InquireForm.vue')['default']
|
||||||
LoginDialog: typeof import('./components/LoginDialog.vue')['default']
|
LoginDialog: typeof import('./components/LoginDialog.vue')['default']
|
||||||
|
|||||||
12
src/components/EmptyState.vue
Normal file
12
src/components/EmptyState.vue
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<template>
|
||||||
|
<view class="flex flex-col items-center justify-center py-16">
|
||||||
|
<image src="/static/images/empty.svg" mode="aspectFit" class="w-48 h-48 mb-4" />
|
||||||
|
<text class="text-gray-400 text-base">{{ text }}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
defineProps({
|
||||||
|
text: { type: String, default: '暂无数据' }
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -242,11 +242,9 @@ onReachBottom(() => {
|
|||||||
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
|
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
|
||||||
加载中...
|
加载中...
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="!data.list.length" class="py-4 text-center text-sm text-gray-400">
|
<EmptyState v-else-if="!data.list.length" text="暂无收益明细" />
|
||||||
暂无记录
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<wd-loadmore :state="loadMoreState" @reload="getData" />
|
<wd-loadmore v-if="data.list.length > 0" :state="loadMoreState" @reload="getData" />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -138,11 +138,9 @@ onReachBottom(() => {
|
|||||||
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
|
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
|
||||||
加载中...
|
加载中...
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="!data.list.length" class="py-4 text-center text-sm text-gray-400">
|
<EmptyState v-else-if="!data.list.length" text="暂无奖励明细" />
|
||||||
暂无记录
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<wd-loadmore :state="loadMoreState" @reload="getData" />
|
<wd-loadmore v-if="data.list.length > 0" :state="loadMoreState" @reload="getData" />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,135 @@
|
|||||||
|
<template>
|
||||||
|
<view class="p-4 mx-auto min-h-screen">
|
||||||
|
<!-- 标题部分 -->
|
||||||
|
<view class="card mb-4 p-4 bg-gradient-to-r from-blue-500 to-blue-600 rounded-lg shadow-lg text-white">
|
||||||
|
<text class="text-2xl font-extrabold mb-2 block">专业报告定价配置</text>
|
||||||
|
<text class="opacity-90 block">请选择报告类型并设置定价策略,助您实现精准定价</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="mb-4 bg-white rounded-lg overflow-hidden px-4 flex items-center justify-between">
|
||||||
|
<span class="text-blue-600 font-medium text-sm">📝 选择报告</span>
|
||||||
|
<wd-picker custom-class="flex-1" v-model="selectedReportId" :columns="[reportOptions]" title="选择报告类型"
|
||||||
|
placeholder="请选择报告类型" :disabled="!reportOptions.length" @confirm="onConfirmType" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="selectedReportText" class="space-y-6">
|
||||||
|
<!-- 配置卡片 -->
|
||||||
|
<view class="card">
|
||||||
|
<!-- 当前报告标题 -->
|
||||||
|
<view class="flex items-center mb-6">
|
||||||
|
<text class="text-xl font-semibold text-gray-800">
|
||||||
|
{{ selectedReportText }}配置
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 显示当前产品的基础成本信息 -->
|
||||||
|
<view v-if="productConfigData && productConfigData.cost_price"
|
||||||
|
class="px-4 py-2 mb-4 bg-gray-50 border border-gray-200 rounded-lg shadow-sm">
|
||||||
|
<text class="text-lg font-semibold text-gray-700 block">报告基础配置信息</text>
|
||||||
|
<view class="mt-1 text-sm text-gray-600">
|
||||||
|
<text class="block">基础成本价:<text class="font-medium">{{ productConfigData.cost_price }}</text> 元</text>
|
||||||
|
<text class="block">最高设定金额上限:<text class="font-medium">{{ productConfigData.price_range_max }}</text>
|
||||||
|
元</text>
|
||||||
|
<text class="block">最高设定比例上限:<text class="font-medium">{{ priceRatioMax }}</text> %</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 分隔线 -->
|
||||||
|
<view class="my-6 flex items-center justify-center">
|
||||||
|
<view class="bg-gray-200 h-px flex-1" />
|
||||||
|
<text class="mx-2 text-gray-400 text-sm">成本策略配置</text>
|
||||||
|
<view class="bg-gray-200 h-px flex-1" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 表单部分 -->
|
||||||
|
<wd-form>
|
||||||
|
<!-- 加价金额 -->
|
||||||
|
<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"
|
||||||
|
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>
|
||||||
|
<text class="block">说明:加价金额是在基础成本价上增加的额外费用,决定下级报告的最低定价,您将获得所有输入的金额利润。</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 分隔线 -->
|
||||||
|
<view class="my-6 flex items-center justify-center">
|
||||||
|
<view class="bg-gray-200 h-px flex-1" />
|
||||||
|
<text class="mx-2 text-gray-400 text-sm">定价策略配置</text>
|
||||||
|
<view class="bg-gray-200 h-px flex-1" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 定价区间最低 -->
|
||||||
|
<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"
|
||||||
|
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>
|
||||||
|
<text class="block">说明:设定的定价区间最低为定价区间的起始值,若下级设定的报告金额在区间内,则区间内部分将按比例获得收益。</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 定价区间最高 -->
|
||||||
|
<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 }}元)和大于定价区间最低({{
|
||||||
|
priceIncreaseMax
|
||||||
|
}}元)</text>
|
||||||
|
<text class="block">说明:设定的定价区间最高为定价区间的结束值,若下级设定的报告金额在区间内,则区间内部分将按比例获得收益。</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收取比例 -->
|
||||||
|
<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>
|
||||||
|
<text class="block">说明:收取比例表示对定价区间内(即报告金额超过定价区间最低,小于定价区间最高的部分)的金额,按此比例进行利润分成。</text>
|
||||||
|
</view>
|
||||||
|
</wd-form>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 保存按钮 -->
|
||||||
|
<button type="primary" class="bg-blue-500 text-white py-1 rounded-xl w-full" @click="handleSubmit">
|
||||||
|
保存当前报告配置
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 未选择提示 -->
|
||||||
|
<view v-else class="text-center py-12">
|
||||||
|
<text class="text-gray-400 text-4xl block mb-4">⚠️</text>
|
||||||
|
<text class="text-gray-500 block">请先选择需要配置的报告类型</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onMounted, reactive, ref } from 'vue'
|
import { computed, onMounted, ref } from 'vue'
|
||||||
definePage({ layout: 'default', auth: true })
|
definePage({ layout: 'default', auth: true })
|
||||||
|
|
||||||
// 报告类型选项:由后端动态返回
|
// 报告类型选项:由后端动态返回
|
||||||
@@ -26,7 +156,6 @@ const priceRatioMax = ref(null)
|
|||||||
const rangeError = ref(false)
|
const rangeError = ref(false)
|
||||||
const ratioError = ref(false)
|
const ratioError = ref(false)
|
||||||
const increaseError = ref(false)
|
const increaseError = ref(false)
|
||||||
const activeField = ref('')
|
|
||||||
|
|
||||||
function showToast(message) {
|
function showToast(message) {
|
||||||
if (!message)
|
if (!message)
|
||||||
@@ -70,30 +199,21 @@ function validateDecimal(field) {
|
|||||||
|
|
||||||
// 价格区间验证(在 @blur 中调用)
|
// 价格区间验证(在 @blur 中调用)
|
||||||
function validateRange() {
|
function validateRange() {
|
||||||
if (
|
if (!productConfigData.value || priceIncreaseMax.value == null)
|
||||||
configData.value.price_range_from === null
|
return
|
||||||
|| configData.value.price_range_to === null
|
if (isNaN(configData.value.price_range_from) || isNaN(configData.value.price_range_to))
|
||||||
) {
|
|
||||||
rangeError.value = false
|
|
||||||
return
|
return
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
isNaN(configData.value.price_range_from)
|
|
||||||
|| isNaN(configData.value.price_range_to)
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const additional = configData.value.price_increase_amount || 0
|
const additional = configData.value.price_increase_amount || 0
|
||||||
const minAllowed = Number.parseFloat(
|
const minAllowed = Number.parseFloat(
|
||||||
(
|
(
|
||||||
Number(productConfigData.value.cost_price) + Number(additional)
|
Number(productConfigData.value.cost_price) + Number(additional)
|
||||||
).toFixed(2),
|
).toFixed(2),
|
||||||
) // 使用成本价作为最小值
|
)
|
||||||
const maxAllowed = productConfigData.value.price_range_max // 使用产品配置中的最大价格作为最大值
|
const maxAllowed = productConfigData.value.price_range_max
|
||||||
if (configData.value.price_range_from < minAllowed) {
|
if (configData.value.price_range_from < minAllowed) {
|
||||||
configData.value.price_range_from = minAllowed
|
configData.value.price_range_from = minAllowed
|
||||||
showToast(`最低金额不能低于成本价 ${minAllowed}元`)
|
showToast(`定价区间最低不能低于成本价 ${minAllowed}元`)
|
||||||
rangeError.value = true
|
rangeError.value = true
|
||||||
closeRangeError()
|
closeRangeError()
|
||||||
|
|
||||||
@@ -107,7 +227,7 @@ function validateRange() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (configData.value.price_range_to < configData.value.price_range_from) {
|
if (configData.value.price_range_to < configData.value.price_range_from) {
|
||||||
showToast('最高金额不能低于最低金额')
|
showToast('定价区间最高不能低于定价区间最低')
|
||||||
if (
|
if (
|
||||||
configData.value.price_range_from + priceIncreaseMax.value
|
configData.value.price_range_from + priceIncreaseMax.value
|
||||||
> maxAllowed
|
> maxAllowed
|
||||||
@@ -116,7 +236,7 @@ function validateRange() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
configData.value.price_range_to
|
configData.value.price_range_to
|
||||||
= configData.value.price_range_from + priceIncreaseMax.value
|
= configData.value.price_range_from + priceIncreaseMax.value
|
||||||
}
|
}
|
||||||
rangeError.value = true
|
rangeError.value = true
|
||||||
closeRangeError()
|
closeRangeError()
|
||||||
@@ -130,20 +250,18 @@ function validateRange() {
|
|||||||
if (diff > priceIncreaseMax.value) {
|
if (diff > priceIncreaseMax.value) {
|
||||||
showToast(`价格区间最大差值为${priceIncreaseMax.value}元`)
|
showToast(`价格区间最大差值为${priceIncreaseMax.value}元`)
|
||||||
configData.value.price_range_to
|
configData.value.price_range_to
|
||||||
= configData.value.price_range_from + priceIncreaseMax.value
|
= configData.value.price_range_from + priceIncreaseMax.value
|
||||||
closeRangeError()
|
closeRangeError()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configData.value.price_range_to > maxAllowed) {
|
if (configData.value.price_range_to > maxAllowed) {
|
||||||
configData.value.price_range_to = maxAllowed
|
configData.value.price_range_to = maxAllowed
|
||||||
showToast(`最高金额不能超过 ${maxAllowed}元`)
|
showToast(`定价区间最高不能超过 ${maxAllowed}元`)
|
||||||
closeRangeError()
|
closeRangeError()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rangeError.value) {
|
rangeError.value = false
|
||||||
rangeError.value = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收取比例验证(修改为保留两位小数,不再四舍五入取整)
|
// 收取比例验证(修改为保留两位小数,不再四舍五入取整)
|
||||||
@@ -193,17 +311,15 @@ async function getConfig() {
|
|||||||
id: respConfigData.product_id,
|
id: respConfigData.product_id,
|
||||||
price_range_from: respConfigData.price_range_from || null,
|
price_range_from: respConfigData.price_range_from || null,
|
||||||
price_range_to: respConfigData.price_range_to || null,
|
price_range_to: respConfigData.price_range_to || null,
|
||||||
price_ratio: respConfigData.price_ratio * 100 || null, // 转换为百分比
|
price_ratio: respConfigData.price_ratio != null ? respConfigData.price_ratio * 100 : null,
|
||||||
price_increase_amount:
|
price_increase_amount:
|
||||||
respConfigData.price_increase_amount || null,
|
respConfigData.price_increase_amount || null,
|
||||||
}
|
}
|
||||||
// const respProductConfigData = data.value.data.product_config
|
|
||||||
productConfigData.value = data.value.data.product_config
|
productConfigData.value = data.value.data.product_config
|
||||||
// 设置动态限制值
|
|
||||||
priceIncreaseMax.value = data.value.data.price_increase_max
|
priceIncreaseMax.value = data.value.data.price_increase_max
|
||||||
priceIncreaseAmountMax.value
|
priceIncreaseAmountMax.value
|
||||||
= data.value.data.price_increase_amount
|
= data.value.data.price_increase_amount
|
||||||
priceRatioMax.value = data.value.data.price_ratio * 100
|
priceRatioMax.value = data.value.data.price_ratio != null ? data.value.data.price_ratio * 100 : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
@@ -242,35 +358,31 @@ async function handleSubmit() {
|
|||||||
showToast('保存失败,请稍后重试')
|
showToast('保存失败,请稍后重试')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最终验证函数
|
// 最终验证函数
|
||||||
function finalValidation() {
|
function finalValidation() {
|
||||||
// 校验最低金额:不能为空且大于0
|
|
||||||
if (
|
if (
|
||||||
!configData.value.price_range_from
|
!configData.value.price_range_from
|
||||||
|| configData.value.price_range_from <= 0
|
|| configData.value.price_range_from <= 0
|
||||||
) {
|
) {
|
||||||
showToast('最低金额不能为空')
|
showToast('定价区间最低不能为空')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 校验最高金额:不能为空且大于0
|
|
||||||
if (
|
if (
|
||||||
!configData.value.price_range_to
|
!configData.value.price_range_to
|
||||||
|| configData.value.price_range_to <= 0
|
|| configData.value.price_range_to <= 0
|
||||||
) {
|
) {
|
||||||
showToast('最高金额不能为空')
|
showToast('定价区间最高不能为空')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 校验收取比例:不能为空且大于0
|
|
||||||
if (!configData.value.price_ratio || configData.value.price_ratio <= 0) {
|
if (!configData.value.price_ratio || configData.value.price_ratio <= 0) {
|
||||||
showToast('收取比例不能为空')
|
showToast('收取比例不能为空')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 验证最低金额必须小于最高金额
|
|
||||||
if (configData.value.price_range_from >= configData.value.price_range_to) {
|
if (configData.value.price_range_from >= configData.value.price_range_to) {
|
||||||
showToast('最低金额必须小于最高金额')
|
showToast('定价区间最低必须小于定价区间最高')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 验证价格区间差值不能超过最大允许差值
|
|
||||||
const finalDiff = Number.parseFloat(
|
const finalDiff = Number.parseFloat(
|
||||||
(
|
(
|
||||||
configData.value.price_range_to - configData.value.price_range_from
|
configData.value.price_range_to - configData.value.price_range_from
|
||||||
@@ -280,24 +392,22 @@ function finalValidation() {
|
|||||||
showToast(`价格区间最大差值为${priceIncreaseMax.value}元`)
|
showToast(`价格区间最大差值为${priceIncreaseMax.value}元`)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 验证最高金额不能超过产品配置中设定的上限
|
|
||||||
if (
|
if (
|
||||||
configData.value.price_range_to
|
configData.value.price_range_to
|
||||||
> productConfigData.value.price_range_max
|
> productConfigData.value.price_range_max
|
||||||
) {
|
) {
|
||||||
showToast(
|
showToast(
|
||||||
`最高金额不能超过${productConfigData.value.price_range_max}元`,
|
`定价区间最高不能超过${productConfigData.value.price_range_max}元`,
|
||||||
)
|
)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// 验证最低金额不能低于成本价+加价金额(加价金额允许为空)
|
|
||||||
const additional = configData.value.price_increase_amount || 0
|
const additional = configData.value.price_increase_amount || 0
|
||||||
if (
|
if (
|
||||||
configData.value.price_range_from
|
configData.value.price_range_from
|
||||||
< productConfigData.value.cost_price + additional
|
< productConfigData.value.cost_price + additional
|
||||||
) {
|
) {
|
||||||
showToast(
|
showToast(
|
||||||
`最低金额不能低于成本价${productConfigData.value.cost_price + additional
|
`定价区间最低不能低于成本价${productConfigData.value.cost_price + additional
|
||||||
}元`,
|
}元`,
|
||||||
)
|
)
|
||||||
return false
|
return false
|
||||||
@@ -326,20 +436,13 @@ function onConfirmType(e) {
|
|||||||
|
|
||||||
getConfig()
|
getConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeRangeError() {
|
function closeRangeError() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
rangeError.value = false
|
rangeError.value = false
|
||||||
}, 2000)
|
}, 2000)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFieldFocus(field) {
|
|
||||||
activeField.value = field
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFieldBlur(field) {
|
|
||||||
if (activeField.value === field)
|
|
||||||
activeField.value = ''
|
|
||||||
}
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadReportOptions()
|
loadReportOptions()
|
||||||
})
|
})
|
||||||
@@ -381,358 +484,72 @@ async function loadReportOptions() {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<view class="mx-auto max-w-3xl min-h-screen p-4">
|
|
||||||
<!-- 标题部分 -->
|
|
||||||
<view class="card mb-4 rounded-lg from-blue-500 to-blue-600 bg-gradient-to-r p-4 text-white shadow-lg">
|
|
||||||
<text class="mb-2 text-2xl font-extrabold">
|
|
||||||
专业报告定价配置
|
|
||||||
</text>
|
|
||||||
<text class="opacity-90">
|
|
||||||
请选择报告类型并设置定价策略,助您实现精准定价
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="mb-4">
|
|
||||||
<wd-picker
|
|
||||||
v-model="selectedReportId"
|
|
||||||
label="报告类型"
|
|
||||||
label-width="100px"
|
|
||||||
title="选择报告类型"
|
|
||||||
:columns="[reportOptions]"
|
|
||||||
placeholder="请选择报告类型"
|
|
||||||
:disabled="!reportOptions.length"
|
|
||||||
@confirm="onConfirmType"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view v-if="selectedReportText" class="space-y-6">
|
|
||||||
<!-- 配置卡片 -->
|
|
||||||
<view class="card">
|
|
||||||
<!-- 当前报告标题 -->
|
|
||||||
<view class="mb-6 flex items-center">
|
|
||||||
<text class="text-xl text-gray-800 font-semibold">
|
|
||||||
{{ selectedReportText }}配置
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 显示当前产品的基础成本信息 -->
|
|
||||||
<view
|
|
||||||
v-if="productConfigData && productConfigData.cost_price"
|
|
||||||
class="mb-4 border border-gray-200 rounded-lg bg-gray-50 px-4 py-2 shadow-sm"
|
|
||||||
>
|
|
||||||
<view class="text-lg text-gray-700 font-semibold">
|
|
||||||
报告基础配置信息
|
|
||||||
</view>
|
|
||||||
<view class="mt-1 text-sm text-gray-600">
|
|
||||||
<view>
|
|
||||||
基础成本价:<text class="font-medium">
|
|
||||||
{{
|
|
||||||
productConfigData.cost_price
|
|
||||||
}}
|
|
||||||
</text>
|
|
||||||
元
|
|
||||||
</view>
|
|
||||||
<!-- <view>区间起始价:<text class="font-medium">{{ productConfigData.price_range_min }}</text> 元</view> -->
|
|
||||||
<view>
|
|
||||||
最高设定金额上限:<text class="font-medium">
|
|
||||||
{{
|
|
||||||
productConfigData.price_range_max
|
|
||||||
}}
|
|
||||||
</text>
|
|
||||||
元
|
|
||||||
</view>
|
|
||||||
<view>
|
|
||||||
最高设定比例上限:<text class="font-medium">
|
|
||||||
{{
|
|
||||||
priceRatioMax
|
|
||||||
}}
|
|
||||||
</text>
|
|
||||||
%
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 分隔线 -->
|
|
||||||
<view class="section-divider my-6">
|
|
||||||
成本策略配置
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 加价金额 -->
|
|
||||||
<view class="custom-field" :class="{ 'field-error': increaseError, 'field-active': activeField === 'price_increase_amount' }">
|
|
||||||
<text class="field-label">
|
|
||||||
🚀 加价金额
|
|
||||||
</text>
|
|
||||||
<view class="field-input-wrap">
|
|
||||||
<wd-input
|
|
||||||
v-model.number="configData.price_increase_amount"
|
|
||||||
type="number"
|
|
||||||
placeholder="0"
|
|
||||||
class="field-wd-input"
|
|
||||||
no-border
|
|
||||||
clearable
|
|
||||||
@focus="onFieldFocus('price_increase_amount')"
|
|
||||||
@blur="
|
|
||||||
() => {
|
|
||||||
onFieldBlur('price_increase_amount')
|
|
||||||
validateDecimal('price_increase_amount')
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<text class="field-unit">
|
|
||||||
元
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="mt-1 text-xs text-gray-400">
|
|
||||||
提示:最大加价金额为{{ priceIncreaseAmountMax }}元<br>
|
|
||||||
说明:加价金额是在基础成本价上增加的额外费用,决定下级报告的最低定价,您将获得所有输入的金额利润。
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 分隔线 -->
|
|
||||||
<view class="section-divider my-6">
|
|
||||||
定价策略配置
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 定价区间最低 -->
|
|
||||||
<view class="custom-field" :class="{ 'field-error': rangeError, 'field-active': activeField === 'price_range_from' }">
|
|
||||||
<text class="field-label">
|
|
||||||
💰 最低金额
|
|
||||||
</text>
|
|
||||||
<view class="field-input-wrap">
|
|
||||||
<wd-input
|
|
||||||
v-model.number="configData.price_range_from"
|
|
||||||
type="number"
|
|
||||||
placeholder="0"
|
|
||||||
class="field-wd-input"
|
|
||||||
no-border
|
|
||||||
clearable
|
|
||||||
@focus="onFieldFocus('price_range_from')"
|
|
||||||
@blur="
|
|
||||||
() => {
|
|
||||||
onFieldBlur('price_range_from')
|
|
||||||
validateDecimal('price_range_from')
|
|
||||||
validateRange()
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<text class="field-unit">
|
|
||||||
元
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="mt-1 text-xs text-gray-400">
|
|
||||||
提示:最低金额不能低于(基础最低
|
|
||||||
{{ productConfigData?.price_range_min || 0 }}元 +
|
|
||||||
加价金额)<br>
|
|
||||||
说明:设定的最低金额为定价区间的起始值,若下级设定的报告金额在区间内,则区间内部分将按比例获得收益。
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 定价区间最高 -->
|
|
||||||
<view class="custom-field" :class="{ 'field-error': rangeError, 'field-active': activeField === 'price_range_to' }">
|
|
||||||
<text class="field-label">
|
|
||||||
💰 最高金额
|
|
||||||
</text>
|
|
||||||
<view class="field-input-wrap">
|
|
||||||
<wd-input
|
|
||||||
v-model.number="configData.price_range_to"
|
|
||||||
type="number"
|
|
||||||
placeholder="0"
|
|
||||||
class="field-wd-input"
|
|
||||||
no-border
|
|
||||||
clearable
|
|
||||||
@focus="onFieldFocus('price_range_to')"
|
|
||||||
@blur="
|
|
||||||
() => {
|
|
||||||
onFieldBlur('price_range_to')
|
|
||||||
validateDecimal('price_range_to')
|
|
||||||
validateRange()
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<text class="field-unit">
|
|
||||||
元
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="mt-1 text-xs text-gray-400">
|
|
||||||
提示:最高金额不能超过上限({{
|
|
||||||
productConfigData?.price_range_max || 0
|
|
||||||
}}元)和大于最低金额({{ priceIncreaseMax }}元)<br>
|
|
||||||
说明:设定的最高金额为定价区间的结束值,若下级设定的报告金额在区间内,则区间内部分将按比例获得收益。
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 收取比例 -->
|
|
||||||
<view class="custom-field" :class="{ 'field-error': ratioError, 'field-active': activeField === 'price_ratio' }">
|
|
||||||
<text class="field-label">
|
|
||||||
📈 收取比例
|
|
||||||
</text>
|
|
||||||
<view class="field-input-wrap">
|
|
||||||
<wd-input
|
|
||||||
v-model.number="configData.price_ratio"
|
|
||||||
type="number"
|
|
||||||
placeholder="0"
|
|
||||||
class="field-wd-input"
|
|
||||||
no-border
|
|
||||||
clearable
|
|
||||||
@focus="onFieldFocus('price_ratio')"
|
|
||||||
@blur="
|
|
||||||
() => {
|
|
||||||
onFieldBlur('price_ratio')
|
|
||||||
validateRatio()
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<text class="field-unit">
|
|
||||||
%
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="mt-1 text-xs text-gray-400">
|
|
||||||
提示:最大收取比例为{{ priceRatioMax }}%<br>
|
|
||||||
说明:收取比例表示对定价区间内(即报告金额超过最低金额,小于最高金额的部分)的金额,按此比例进行利润分成。
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 保存按钮 -->
|
|
||||||
<wd-button
|
|
||||||
type="primary" block
|
|
||||||
class="h-12 rounded-xl from-blue-500 to-blue-600 bg-gradient-to-r text-white shadow-lg hover:from-blue-600 hover:to-blue-700"
|
|
||||||
@click="handleSubmit"
|
|
||||||
>
|
|
||||||
保存当前报告配置
|
|
||||||
</wd-button>
|
|
||||||
</view>
|
|
||||||
<!-- 未选择提示 -->
|
|
||||||
<view v-else class="py-12 text-center">
|
|
||||||
<text class="mb-4 block text-4xl text-gray-400">
|
|
||||||
⚠️
|
|
||||||
</text>
|
|
||||||
<text class="text-gray-500">
|
|
||||||
请先选择需要配置的报告类型
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.selector {
|
.card {
|
||||||
|
border-radius: 24rpx;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
|
||||||
|
padding: 32rpx;
|
||||||
|
margin-bottom: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-y-6 {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-y-6>view {
|
||||||
|
margin-bottom: 48rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-y-6>view:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.wd-cell__title) {
|
||||||
|
line-height: 34px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.wd-cell__left) {
|
||||||
|
min-width: 120px !important;
|
||||||
|
max-width: 120px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vip-input-wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
border-radius: 16rpx;
|
||||||
cursor: pointer;
|
padding: 0 24rpx;
|
||||||
}
|
background: #fafafa;
|
||||||
|
|
||||||
.selector-label {
|
|
||||||
color: #2563eb;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selector-value {
|
|
||||||
color: #4b5563;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-title {
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.report-list {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.report-item {
|
|
||||||
padding: 10px 12px;
|
|
||||||
border: 1px solid #e5e7eb;
|
|
||||||
border-radius: 8px;
|
|
||||||
text-align: center;
|
|
||||||
color: #374151;
|
|
||||||
}
|
|
||||||
|
|
||||||
.report-item.active {
|
|
||||||
border-color: #2563eb;
|
|
||||||
color: #2563eb;
|
|
||||||
background: #eff6ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-divider {
|
|
||||||
text-align: center;
|
|
||||||
color: #9ca3af;
|
|
||||||
font-size: 12px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-divider::before,
|
|
||||||
.section-divider::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
width: 30%;
|
|
||||||
height: 1px;
|
|
||||||
background: #e5e7eb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-divider::before {
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-divider::after {
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-field {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
color: #4b5563;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-input-wrap {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background: #f3f4f6;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
border: 1px solid #e5e7eb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.field-wd-input .wd-input__inner) {
|
.vip-input-wrap:focus-within {
|
||||||
flex: 1;
|
border-color: #93c5fd;
|
||||||
background: transparent !important;
|
background: #fafafa;
|
||||||
text-align: left !important;
|
box-shadow: 0 0 0 6rpx rgba(59, 130, 246, 0.32);
|
||||||
}
|
}
|
||||||
|
|
||||||
.field-unit {
|
.vip-input-row {
|
||||||
margin-left: 8px;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vip-input-unit {
|
||||||
|
margin-left: 12rpx;
|
||||||
color: #3b82f6;
|
color: #3b82f6;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
::deep(.field-wd-input.wd-input),
|
:deep(.vip-wd-input.wd-input),
|
||||||
::deep(.field-wd-input .wd-input__body),
|
:deep(.vip-wd-input.wd-input:after),
|
||||||
::deep(.field-wd-input .wd-input__prefix),
|
:deep(.vip-wd-input .wd-input),
|
||||||
::deep(.field-wd-input .wd-input__suffix),
|
:deep(.vip-wd-input .wd-input__body),
|
||||||
::deep(.field-wd-input .wd-input__value),
|
:deep(.vip-wd-input .wd-input__inner),
|
||||||
::deep(.field-wd-input .wd-input__clear) {
|
:deep(.vip-wd-input .wd-input__value),
|
||||||
|
:deep(.vip-wd-input .wd-input__clear) {
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
}
|
border: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
.field-active .field-input-wrap {
|
|
||||||
border-color: #93c5fd;
|
|
||||||
background: #eff6ff;
|
|
||||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-error .field-input-wrap {
|
|
||||||
border-color: #fca5a5;
|
|
||||||
background: #fef2f2;
|
|
||||||
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -134,11 +134,9 @@ function statusClass(state) {
|
|||||||
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
|
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
|
||||||
加载中...
|
加载中...
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="!reportList.length" class="py-4 text-center text-sm text-gray-400">
|
<EmptyState v-else-if="!reportList.length" text="暂无查询记录" />
|
||||||
暂无记录
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<wd-loadmore :state="loadMoreState" @reload="fetchData" />
|
<wd-loadmore v-if="reportList.length > 0" :state="loadMoreState" @reload="fetchData" />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -45,16 +45,8 @@ function getAgentLevelLabel(value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取收益列表
|
// 获取收益列表
|
||||||
function mergeUniqueById(oldList, newList) {
|
function appendList(oldList, newList) {
|
||||||
const map = new Map()
|
return oldList.concat(newList)
|
||||||
const resolveKey = (item, index) => String(item?.id ?? item?.order_id ?? `${item?.create_time || ''}_${item?.type || ''}_${index}`)
|
|
||||||
oldList.forEach((item, index) => {
|
|
||||||
map.set(resolveKey(item, index), item)
|
|
||||||
})
|
|
||||||
newList.forEach((item, index) => {
|
|
||||||
map.set(resolveKey(item, oldList.length + index), item)
|
|
||||||
})
|
|
||||||
return Array.from(map.values())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchRewardDetails(reset = false) {
|
async function fetchRewardDetails(reset = false) {
|
||||||
@@ -177,7 +169,7 @@ async function fetchRewardDetails(reset = false) {
|
|||||||
total.value = data.value.data.total || 0
|
total.value = data.value.data.total || 0
|
||||||
// 处理列表数据
|
// 处理列表数据
|
||||||
const list = data.value.data.list || []
|
const list = data.value.data.list || []
|
||||||
rewardDetails.value = reset ? list : mergeUniqueById(rewardDetails.value, list)
|
rewardDetails.value = reset ? list : appendList(rewardDetails.value, list)
|
||||||
const isLastPage = list.length < pageSize || rewardDetails.value.length >= total.value
|
const isLastPage = list.length < pageSize || rewardDetails.value.length >= total.value
|
||||||
hasMore.value = !isLastPage
|
hasMore.value = !isLastPage
|
||||||
loadMoreState.value = isLastPage ? 'finished' : 'loading'
|
loadMoreState.value = isLastPage ? 'finished' : 'loading'
|
||||||
@@ -334,12 +326,8 @@ function formatNumber(num) {
|
|||||||
贡献统计
|
贡献统计
|
||||||
</view>
|
</view>
|
||||||
<view class="grid grid-cols-2 gap-3">
|
<view class="grid grid-cols-2 gap-3">
|
||||||
<view
|
<view v-for="item in statistics" :key="item.type" class="flex items-center rounded-lg p-2"
|
||||||
v-for="item in statistics"
|
:class="getRewardTypeClass(item.type).split(' ')[0]">
|
||||||
:key="item.type"
|
|
||||||
class="flex items-center rounded-lg p-2"
|
|
||||||
:class="getRewardTypeClass(item.type).split(' ')[0]"
|
|
||||||
>
|
|
||||||
<image :src="getRewardTypeIcon(item.type)" class="mr-2 h-5 w-5 flex-shrink-0" />
|
<image :src="getRewardTypeIcon(item.type)" class="mr-2 h-5 w-5 flex-shrink-0" />
|
||||||
<view class="flex-1">
|
<view class="flex-1">
|
||||||
<view class="text-sm font-medium" :class="getRewardTypeClass(item.type).split(' ')[1]">
|
<view class="text-sm font-medium" :class="getRewardTypeClass(item.type).split(' ')[1]">
|
||||||
@@ -359,20 +347,18 @@ function formatNumber(num) {
|
|||||||
</view>
|
</view>
|
||||||
<view class="mb-4 rounded-xl bg-white p-4 shadow-sm">
|
<view class="mb-4 rounded-xl bg-white p-4 shadow-sm">
|
||||||
<!-- 贡献记录列表 -->
|
<!-- 贡献记录列表 -->
|
||||||
<view class="text-base text-gray-800 font-medium">
|
<view class="text-base text-gray-800 font-medium mb-3">
|
||||||
贡献记录
|
贡献记录
|
||||||
</view>
|
</view>
|
||||||
<view class="detail-scroll p-4">
|
<view class="detail-scroll">
|
||||||
<view v-if="rewardDetails.length === 0" class="py-8 text-center text-gray-500">
|
<EmptyState v-if="!loading && rewardDetails.length === 0" text="暂无贡献记录" />
|
||||||
暂无贡献记录
|
<view v-for="(item, index) in rewardDetails" v-else :key="index" class="reward-item">
|
||||||
</view>
|
|
||||||
<view v-for="item in rewardDetails" v-else :key="item.id" class="reward-item">
|
|
||||||
<view class="mb-3 border-b border-gray-200 pb-3">
|
<view class="mb-3 border-b border-gray-200 pb-3">
|
||||||
<view class="flex items-center justify-between">
|
<view class="flex items-center justify-between">
|
||||||
<view class="flex items-center space-x-3">
|
<view class="flex items-center space-x-3">
|
||||||
<image :src="getRewardTypeIcon(item.type)" class="h-5 w-5 flex-shrink-0" />
|
<image :src="getRewardTypeIcon(item.type)" class="h-4 w-4 flex-shrink-0" />
|
||||||
<view>
|
<view>
|
||||||
<view class="text-gray-800 font-medium">
|
<view class="text-gray-800 font-sm">
|
||||||
{{ getRewardTypeDescription(item.type) }}
|
{{ getRewardTypeDescription(item.type) }}
|
||||||
</view>
|
</view>
|
||||||
<view class="text-xs text-gray-500">
|
<view class="text-xs text-gray-500">
|
||||||
@@ -392,7 +378,7 @@ function formatNumber(num) {
|
|||||||
加载中...
|
加载中...
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<wd-loadmore :state="loadMoreState" @reload="fetchRewardDetails" />
|
<wd-loadmore v-if="rewardDetails.length > 0" :state="loadMoreState" @reload="fetchRewardDetails" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ onReachBottom(() => {
|
|||||||
<template>
|
<template>
|
||||||
<view class="subordinate-list">
|
<view class="subordinate-list">
|
||||||
<!-- 顶部统计卡片 -->
|
<!-- 顶部统计卡片 -->
|
||||||
<view class="p-4 pb-0">
|
<view v-if="subordinates.length > 0" class="p-4 pb-0">
|
||||||
<view class="rounded-xl bg-white p-4 shadow-sm">
|
<view class="rounded-xl bg-white p-4 shadow-sm">
|
||||||
<view class="flex items-center justify-center">
|
<view class="flex items-center justify-center">
|
||||||
<view class="text-center">
|
<view class="text-center">
|
||||||
@@ -212,10 +212,8 @@ onReachBottom(() => {
|
|||||||
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
|
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
|
||||||
加载中...
|
加载中...
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="!subordinates.length" class="py-4 text-center text-sm text-gray-400">
|
<EmptyState v-else-if="!subordinates.length" text="暂无我的下级" />
|
||||||
暂无下级代理
|
<wd-loadmore v-if="subordinates.length > 0" :state="loadMoreState" @reload="fetchSubordinates" />
|
||||||
</view>
|
|
||||||
<wd-loadmore :state="loadMoreState" @reload="fetchSubordinates" />
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -198,11 +198,9 @@ onReachBottom(() => {
|
|||||||
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
|
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
|
||||||
加载中...
|
加载中...
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="!data.list.length" class="py-10 text-center text-sm text-gray-400">
|
<EmptyState v-else-if="!data.list.length" text="暂无提现记录" />
|
||||||
暂无提现记录
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="pagination-wrap">
|
<view v-if="data.list.length" class="pagination-wrap">
|
||||||
<wd-loadmore :state="loadMoreState" @reload="getData" />
|
<wd-loadmore :state="loadMoreState" @reload="getData" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
Reference in New Issue
Block a user