f
This commit is contained in:
@@ -162,12 +162,13 @@ export function getLatestVersion() {
|
||||
|
||||
|
||||
/**
|
||||
* 注销账号
|
||||
* 注销账号(需传入短信验证码)
|
||||
*/
|
||||
export function cancelAccount() {
|
||||
export function cancelAccount(code) {
|
||||
return request({
|
||||
url: '/user/cancelOut',
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
data: { code }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,16 @@ export const activateAgentMembership = (data) => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代理会员配置(VIP/SVIP价格等)
|
||||
*/
|
||||
export const getAgentMembershipInfo = () => {
|
||||
return request({
|
||||
url: '/agent/membership/info',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代理会员用户配置
|
||||
* @param {Object} params 查询参数 {product_id}
|
||||
|
||||
4
src/auto-imports.d.ts
vendored
4
src/auto-imports.d.ts
vendored
@@ -12,7 +12,6 @@ declare global {
|
||||
const aesEncrypt: typeof import('./utils/crypto.js')['aesEncrypt']
|
||||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
||||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
|
||||
const autoUpdateCheck: typeof import('./utils/autoUpdateCheck.js')['default']
|
||||
const buildPromotionH5Url: typeof import('./utils/promotionH5Url.js')['buildPromotionH5Url']
|
||||
const chatCrypto: typeof import('./utils/chatCrypto.js')['default']
|
||||
const chatEncrypt: typeof import('./utils/chatEncrypt.js')['default']
|
||||
@@ -228,7 +227,6 @@ declare global {
|
||||
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
|
||||
const useGamepad: typeof import('@vueuse/core')['useGamepad']
|
||||
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
|
||||
const useHotUpdate: typeof import('./composables/useHotUpdate.js')['useHotUpdate']
|
||||
const useId: typeof import('vue')['useId']
|
||||
const useIdle: typeof import('@vueuse/core')['useIdle']
|
||||
const useImage: typeof import('@vueuse/core')['useImage']
|
||||
@@ -359,7 +357,6 @@ declare module 'vue' {
|
||||
readonly aesEncrypt: UnwrapRef<typeof import('./utils/crypto.js')['aesEncrypt']>
|
||||
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
|
||||
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
|
||||
readonly autoUpdateCheck: UnwrapRef<typeof import('./utils/autoUpdateCheck.js')['default']>
|
||||
readonly buildPromotionH5Url: UnwrapRef<typeof import('./utils/promotionH5Url.js')['buildPromotionH5Url']>
|
||||
readonly chatCrypto: UnwrapRef<typeof import('./utils/chatCrypto.js')['default']>
|
||||
readonly chatEncrypt: UnwrapRef<typeof import('./utils/chatEncrypt.js')['default']>
|
||||
@@ -574,7 +571,6 @@ declare module 'vue' {
|
||||
readonly useFullscreen: UnwrapRef<typeof import('@vueuse/core')['useFullscreen']>
|
||||
readonly useGamepad: UnwrapRef<typeof import('@vueuse/core')['useGamepad']>
|
||||
readonly useGeolocation: UnwrapRef<typeof import('@vueuse/core')['useGeolocation']>
|
||||
readonly useHotUpdate: UnwrapRef<typeof import('./composables/useHotUpdate.js')['useHotUpdate']>
|
||||
readonly useId: UnwrapRef<typeof import('vue')['useId']>
|
||||
readonly useIdle: UnwrapRef<typeof import('@vueuse/core')['useIdle']>
|
||||
readonly useImage: UnwrapRef<typeof import('@vueuse/core')['useImage']>
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
<div class="border-b border-gray-200">
|
||||
<wd-input v-model="price" type="number" label="¥" label-width="28px" size="large"
|
||||
:placeholder="`${productConfig.price_range_min} - ${productConfig.price_range_max}`"
|
||||
@blur="onBlurPrice" custom-class="wd-input" />
|
||||
:placeholder="priceRangePlaceholder" @blur="onBlurPrice"
|
||||
custom-class="wd-input" />
|
||||
</div>
|
||||
<div class="flex items-center justify-between mt-2">
|
||||
<div>推广收益为<span class="text-orange-500"> {{ promotionRevenue }} </span>元</div>
|
||||
@@ -26,8 +26,8 @@
|
||||
<div>我的成本 = 提价成本 + 底价成本</div>
|
||||
<div class="mt-1">提价成本:超过平台标准定价部分,平台会收取部分成本价</div>
|
||||
<div class="">设定范围:<span class="text-orange-500">{{
|
||||
productConfig.price_range_min }}</span>元 - <span class="text-orange-500">{{
|
||||
productConfig.price_range_max }}</span>元</div>
|
||||
productConfig?.price_range_min ?? '--' }}</span>元 - <span class="text-orange-500">{{
|
||||
productConfig?.price_range_max ?? '--' }}</span>元</div>
|
||||
</div>
|
||||
<div class="px-4 pb-4">
|
||||
<wd-button class="w-full" round type="primary" size="large" @click="onConfirm">确认</wd-button>
|
||||
@@ -60,6 +60,13 @@ watch(show, () => {
|
||||
price.value = defaultPrice.value
|
||||
})
|
||||
|
||||
const priceRangePlaceholder = computed(() => {
|
||||
const min = productConfig.value?.price_range_min
|
||||
const max = productConfig.value?.price_range_max
|
||||
if (min === undefined || max === undefined) return '请输入价格'
|
||||
return `${min} - ${max}`
|
||||
})
|
||||
|
||||
const costPrice = computed(() => {
|
||||
if (!productConfig.value) return 0.00
|
||||
// 平台定价成本
|
||||
@@ -88,6 +95,9 @@ const promotionRevenue = computed(() => {
|
||||
|
||||
// 价格校验与修正逻辑
|
||||
const validatePrice = (currentPrice) => {
|
||||
if (!productConfig.value) {
|
||||
return { newPrice: Number(defaultPrice.value || 0), message: '当前产品配置不可用,请重新选择报告类型' }
|
||||
}
|
||||
const min = productConfig.value.price_range_min;
|
||||
const max = productConfig.value.price_range_max;
|
||||
let newPrice = Number(currentPrice);
|
||||
@@ -108,7 +118,7 @@ const validatePrice = (currentPrice) => {
|
||||
newPrice = parseFloat(safeTruncate(newPrice));
|
||||
message = '价格已自动格式化为两位小数';
|
||||
}
|
||||
} catch {}
|
||||
} catch { }
|
||||
|
||||
// 范围校验(基于可能格式化后的值)
|
||||
if (newPrice < min) {
|
||||
@@ -159,17 +169,22 @@ const onBlurPrice = () => {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
|
||||
:deep(.wd-input__label-inner) {
|
||||
font-size: 24px !important; /* 增大label字体 */
|
||||
font-size: 24px !important;
|
||||
/* 增大label字体 */
|
||||
}
|
||||
|
||||
:deep(.wd-input__inner) {
|
||||
font-size: 24px !important; /* 增大输入框内字体 */
|
||||
font-size: 24px !important;
|
||||
/* 增大输入框内字体 */
|
||||
}
|
||||
|
||||
:deep(.wd-input) {
|
||||
height: auto !important; /* 确保高度自适应 */
|
||||
padding: 8px 0 !important; /* 增加垂直内边距 */
|
||||
height: auto !important;
|
||||
/* 确保高度自适应 */
|
||||
padding: 8px 0 !important;
|
||||
/* 增加垂直内边距 */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
import { ref } from 'vue'
|
||||
import { getApiBaseUrl } from '@/utils/runtimeEnv.js'
|
||||
|
||||
/**
|
||||
* WGT热更新处理
|
||||
* 静默下载更新,无需重启应用
|
||||
*/
|
||||
export function useHotUpdate() {
|
||||
const updating = ref(false)
|
||||
const hasNewVersion = ref(false)
|
||||
const currentVersion = ref('')
|
||||
const latestVersion = ref('')
|
||||
const downloadProgress = ref(0)
|
||||
const serverWgtUrl = ref('') // 保存服务器更新包地址
|
||||
|
||||
// 测试模式相关状态
|
||||
const isTestMode = ref(false)
|
||||
const mockWgtUrl = 'https://example.com/mock-update.wgt' // 模拟更新包地址
|
||||
|
||||
// 获取当前应用版本
|
||||
const getCurrentVersion = () => {
|
||||
return new Promise((resolve) => {
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.getProperty(plus.runtime.appid, function(inf) {
|
||||
const wgtVer = inf.version
|
||||
currentVersion.value = wgtVer
|
||||
resolve(wgtVer)
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
const defaultVersion = '1.0.0' // 非APP环境下的默认值
|
||||
currentVersion.value = defaultVersion
|
||||
resolve(defaultVersion)
|
||||
// #endif
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 只检查版本,不自动更新
|
||||
* 适用于手动触发的更新检查
|
||||
*/
|
||||
const checkVersionOnly = async () => {
|
||||
try {
|
||||
// 测试模式直接返回有新版本
|
||||
if (isTestMode.value) {
|
||||
await getCurrentVersion()
|
||||
latestVersion.value = incrementVersion(currentVersion.value)
|
||||
serverWgtUrl.value = mockWgtUrl
|
||||
hasNewVersion.value = true
|
||||
return true
|
||||
}
|
||||
|
||||
// 获取当前版本
|
||||
await getCurrentVersion()
|
||||
|
||||
// 替换为使用回调函数的方式
|
||||
return new Promise((resolve) => {
|
||||
uni.request({
|
||||
url: `${getApiBaseUrl()}/app/version`,
|
||||
method: 'GET',
|
||||
success: (res) => {
|
||||
if (!res || res.statusCode !== 200 || !res.data || res.data.code !== 200 || !res.data.data) {
|
||||
resolve(false)
|
||||
return
|
||||
}
|
||||
|
||||
const serverInfo = res.data.data
|
||||
latestVersion.value = serverInfo.version
|
||||
|
||||
// 保存服务器wgt地址,以便后续手动更新使用
|
||||
if (serverInfo.wgtUrl) {
|
||||
serverWgtUrl.value = serverInfo.wgtUrl
|
||||
}
|
||||
|
||||
// 比较版本号,检查是否有新版本
|
||||
hasNewVersion.value = compareVersion(serverInfo.version, currentVersion.value) > 0
|
||||
|
||||
resolve(hasNewVersion.value)
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('检查版本失败', error)
|
||||
resolve(false)
|
||||
}
|
||||
})
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('检查版本失败', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动增加版本号,用于测试
|
||||
*/
|
||||
const incrementVersion = (version) => {
|
||||
const parts = version.split('.')
|
||||
const lastPart = parseInt(parts[parts.length - 1]) + 1
|
||||
parts[parts.length - 1] = lastPart.toString()
|
||||
return parts.join('.')
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用或禁用测试模式
|
||||
*/
|
||||
const toggleTestMode = (enabled = true) => {
|
||||
isTestMode.value = enabled
|
||||
console.log('测试模式已' + (enabled ? '启用' : '禁用'))
|
||||
return isTestMode.value
|
||||
}
|
||||
|
||||
// 检查更新并自动静默更新(App.vue使用)
|
||||
const checkUpdate = async () => {
|
||||
try {
|
||||
// 如果是测试模式,不进行实际的静默更新
|
||||
if (isTestMode.value) {
|
||||
await getCurrentVersion()
|
||||
latestVersion.value = incrementVersion(currentVersion.value)
|
||||
hasNewVersion.value = true
|
||||
return
|
||||
}
|
||||
|
||||
// 获取当前版本
|
||||
await getCurrentVersion()
|
||||
|
||||
// 替换为使用回调函数的方式
|
||||
uni.request({
|
||||
url: `${getApiBaseUrl()}/app/version`,
|
||||
method: 'GET',
|
||||
success: (res) => {
|
||||
if (!res || res.statusCode !== 200 || !res.data || res.data.code !== 200 || !res.data.data) return
|
||||
console.log('update version res', res)
|
||||
const serverInfo = res.data.data
|
||||
latestVersion.value = serverInfo.version
|
||||
|
||||
// 比较版本号,检查是否有新版本
|
||||
if (compareVersion(serverInfo.version, currentVersion.value) > 0) {
|
||||
hasNewVersion.value = true
|
||||
// 如果有wgt下载地址,执行静默更新
|
||||
if (serverInfo.wgtUrl) {
|
||||
serverWgtUrl.value = serverInfo.wgtUrl
|
||||
silentUpdate(serverInfo.wgtUrl)
|
||||
}
|
||||
} else {
|
||||
hasNewVersion.value = false
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('检查更新失败', error)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('检查更新失败', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 比较版本号 (v1 > v2 返回1,v1 < v2 返回-1,相等返回0)
|
||||
const compareVersion = (v1, v2) => {
|
||||
const v1Parts = v1.split('.').map(Number)
|
||||
const v2Parts = v2.split('.').map(Number)
|
||||
|
||||
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
|
||||
const v1Part = v1Parts[i] || 0
|
||||
const v2Part = v2Parts[i] || 0
|
||||
|
||||
if (v1Part > v2Part) return 1
|
||||
if (v1Part < v2Part) return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// 静默下载并安装更新
|
||||
const silentUpdate = (wgtUrl) => {
|
||||
if (updating.value) return Promise.reject('更新已在进行中')
|
||||
|
||||
updating.value = true
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// #ifdef APP-PLUS
|
||||
const dtask = plus.downloader.createDownload(wgtUrl, {
|
||||
filename: '_doc/update/'
|
||||
}, (download, status) => {
|
||||
if (status === 200) {
|
||||
installing(download.filename)
|
||||
.then(() => {
|
||||
updating.value = false
|
||||
resolve()
|
||||
})
|
||||
.catch(err => {
|
||||
updating.value = false
|
||||
reject(err)
|
||||
})
|
||||
} else {
|
||||
updating.value = false
|
||||
reject('下载更新包失败')
|
||||
}
|
||||
})
|
||||
|
||||
dtask.start()
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
updating.value = false
|
||||
resolve() // 非APP环境下直接返回成功
|
||||
// #endif
|
||||
})
|
||||
}
|
||||
|
||||
// 安装wgt包
|
||||
const installing = (filePath) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.install(filePath, {
|
||||
force: false // 不重启应用
|
||||
}, () => {
|
||||
console.log('安装wgt成功')
|
||||
resolve()
|
||||
// 删除下载的安装包
|
||||
plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
|
||||
entry.remove()
|
||||
})
|
||||
}, (error) => {
|
||||
console.error('安装wgt失败', error)
|
||||
reject(error)
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
resolve() // 非APP环境下直接返回成功
|
||||
// #endif
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动更新,提供进度回调
|
||||
* @param {string} wgtUrl 更新包下载地址
|
||||
* @returns {Promise} 返回更新结果Promise
|
||||
*/
|
||||
const manualUpdate = (wgtUrl) => {
|
||||
if (updating.value) return Promise.reject('更新已在进行中')
|
||||
|
||||
updating.value = true
|
||||
downloadProgress.value = 0
|
||||
|
||||
// 如果是测试模式,模拟下载进度而不实际下载
|
||||
if (isTestMode.value) {
|
||||
return new Promise((resolve) => {
|
||||
let progress = 0
|
||||
const interval = setInterval(() => {
|
||||
progress += 5
|
||||
downloadProgress.value = progress
|
||||
|
||||
if (progress >= 100) {
|
||||
clearInterval(interval)
|
||||
setTimeout(() => {
|
||||
updating.value = false
|
||||
resolve()
|
||||
}, 500)
|
||||
}
|
||||
}, 200)
|
||||
})
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// #ifdef APP-PLUS
|
||||
const dtask = plus.downloader.createDownload(wgtUrl, {
|
||||
filename: '_doc/update/'
|
||||
}, (download, status) => {
|
||||
if (status === 200) {
|
||||
installing(download.filename)
|
||||
.then(() => {
|
||||
updating.value = false
|
||||
resolve()
|
||||
})
|
||||
.catch(err => {
|
||||
updating.value = false
|
||||
reject(err)
|
||||
})
|
||||
} else {
|
||||
updating.value = false
|
||||
reject('下载更新包失败')
|
||||
}
|
||||
})
|
||||
|
||||
// 监听下载进度
|
||||
dtask.addEventListener('statechanged', (task, status) => {
|
||||
switch (task.state) {
|
||||
case 1: // 开始
|
||||
console.log('开始下载更新...')
|
||||
break
|
||||
case 2: // 已连接到服务器
|
||||
console.log('已连接到服务器...')
|
||||
break
|
||||
case 3: // 下载中
|
||||
const totalSize = task.totalSize
|
||||
const downloadedSize = task.downloadedSize
|
||||
const progress = Math.round(downloadedSize / totalSize * 100) || 0
|
||||
downloadProgress.value = progress
|
||||
console.log(`下载进度: ${progress}%`)
|
||||
break
|
||||
case 4: // 下载完成
|
||||
console.log('下载完成')
|
||||
downloadProgress.value = 100
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
dtask.start()
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
// 模拟下载进度
|
||||
let progress = 0
|
||||
const timer = setInterval(() => {
|
||||
progress += 5
|
||||
downloadProgress.value = progress
|
||||
if (progress >= 100) {
|
||||
clearInterval(timer)
|
||||
updating.value = false
|
||||
resolve()
|
||||
}
|
||||
}, 200)
|
||||
// #endif
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
updating,
|
||||
hasNewVersion,
|
||||
currentVersion,
|
||||
latestVersion,
|
||||
downloadProgress,
|
||||
serverWgtUrl,
|
||||
isTestMode,
|
||||
checkUpdate,
|
||||
checkVersionOnly,
|
||||
manualUpdate,
|
||||
toggleTestMode
|
||||
}
|
||||
}
|
||||
@@ -23,12 +23,11 @@ function handleClickLeft() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<wd-navbar :title="title" left-text="返回" placeholder left-arrow safe-area-inset-top fixed @click-left="handleClickLeft" />
|
||||
<wd-navbar :title="title" left-text="返回" placeholder left-arrow safe-area-inset-top fixed
|
||||
@click-left="handleClickLeft" />
|
||||
<view class="box-border min-h-screen">
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -369,7 +369,7 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, reactive, computed } from 'vue'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
import { activateAgentMembership } from '@/apis/agent'
|
||||
import { activateAgentMembership, getAgentMembershipInfo } from '@/apis/agent'
|
||||
import { formatExpiryTime } from '@/utils/format'
|
||||
import { getCompanyName } from '@/utils/runtimeEnv.js'
|
||||
|
||||
@@ -451,6 +451,12 @@ const buttonClass = computed(() => {
|
||||
return `${baseClass} bg-gradient-to-r from-amber-500 to-amber-600 active:from-amber-600 active:to-amber-700 text-white`
|
||||
})
|
||||
|
||||
function toFiniteNumber(value, fallback = 0) {
|
||||
if (value === null || value === undefined || value === '') return fallback
|
||||
const n = typeof value === 'number' ? value : Number(value)
|
||||
return Number.isFinite(n) ? n : fallback
|
||||
}
|
||||
|
||||
// VIP价格配置
|
||||
const vipConfig = reactive({
|
||||
price: 399, // VIP价格
|
||||
@@ -630,6 +636,8 @@ const revenueData = computed(() => {
|
||||
onMounted(async () => {
|
||||
// 从本地缓存获取代理信息
|
||||
loadAgentInfo()
|
||||
// 从后端加载会员配置(价格和收益参数)
|
||||
await loadMembershipInfo()
|
||||
})
|
||||
|
||||
// 从本地缓存加载代理信息
|
||||
@@ -650,20 +658,52 @@ const loadAgentInfo = () => {
|
||||
|
||||
const selectedType = ref('vip') // 默认选择VIP
|
||||
const showPayment = ref(false)
|
||||
function buildPayData(type) {
|
||||
return {
|
||||
product_name: `${type === 'vip' ? 'VIP' : 'SVIP'}代理`,
|
||||
sell_price: type === 'vip' ? toFiniteNumber(vipConfig.price) : toFiniteNumber(vipConfig.svipPrice),
|
||||
}
|
||||
}
|
||||
const payData = ref({
|
||||
product_name: `${selectedType.value.toUpperCase()}代理`,
|
||||
sell_price: vipConfig.price,
|
||||
sell_price: toFiniteNumber(vipConfig.price),
|
||||
})
|
||||
const payID = ref('')
|
||||
|
||||
async function loadMembershipInfo() {
|
||||
try {
|
||||
const res = await getAgentMembershipInfo()
|
||||
if (res.code !== 200 || !res.data) return
|
||||
|
||||
const configData = res.data
|
||||
if (configData.vip_config) {
|
||||
const vipData = configData.vip_config
|
||||
vipConfig.price = toFiniteNumber(vipData.price, vipConfig.price)
|
||||
vipConfig.vipCommission = toFiniteNumber(vipData.report_commission, vipConfig.vipCommission)
|
||||
vipConfig.vipFloatingRate = toFiniteNumber(vipData.price_ratio, vipConfig.vipFloatingRate / 100) * 100
|
||||
vipConfig.vipConversionBonus = toFiniteNumber(vipData.lower_convert_vip_reward, vipConfig.vipConversionBonus)
|
||||
vipConfig.vipWithdrawalLimit = toFiniteNumber(vipData.exemption_amount, vipConfig.vipWithdrawalLimit)
|
||||
}
|
||||
|
||||
if (configData.svip_config) {
|
||||
const svipData = configData.svip_config
|
||||
vipConfig.svipPrice = toFiniteNumber(svipData.price, vipConfig.svipPrice)
|
||||
vipConfig.svipCommission = toFiniteNumber(svipData.report_commission, vipConfig.svipCommission)
|
||||
vipConfig.svipFloatingRate = toFiniteNumber(svipData.price_ratio, vipConfig.svipFloatingRate / 100) * 100
|
||||
vipConfig.withdrawRatio = toFiniteNumber(svipData.lower_withdraw_reward_ratio, vipConfig.withdrawRatio / 100) * 100
|
||||
vipConfig.svipConversionBonus = toFiniteNumber(svipData.lower_convert_svip_reward, vipConfig.svipConversionBonus)
|
||||
vipConfig.svipWithdrawalLimit = toFiniteNumber(svipData.exemption_amount, vipConfig.svipWithdrawalLimit)
|
||||
}
|
||||
|
||||
payData.value = buildPayData(selectedType.value)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// 选择代理类型
|
||||
function selectType(type) {
|
||||
selectedType.value = type
|
||||
// 更新payData中的价格和产品名称
|
||||
payData.value = {
|
||||
product_name: `${type === 'vip' ? 'VIP' : 'SVIP'}代理`,
|
||||
sell_price: type === 'vip' ? vipConfig.price : vipConfig.svipPrice,
|
||||
}
|
||||
payData.value = buildPayData(type)
|
||||
}
|
||||
|
||||
// 申请VIP或SVIP
|
||||
@@ -681,6 +721,11 @@ async function applyVip() {
|
||||
}
|
||||
|
||||
try {
|
||||
if (toFiniteNumber(payData.value.sell_price) <= 0) {
|
||||
toast.error('会员价格加载中,请稍后重试')
|
||||
return
|
||||
}
|
||||
|
||||
const res = await activateAgentMembership({
|
||||
type: selectedType.value.toUpperCase(),
|
||||
})
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
<!-- 定价 -->
|
||||
<wd-input label="客户查询价" label-width="100px" v-model="formData.clientPrice" placeholder="请输入价格" readonly
|
||||
clickable @click="showPricePicker = true" prop="clientPrice" suffix-icon="arrow-right"
|
||||
clickable @click="openPricePicker" prop="clientPrice" suffix-icon="arrow-right"
|
||||
:rules="[{ required: true, message: '请输入客户查询价' }]" />
|
||||
</wd-cell-group>
|
||||
|
||||
@@ -156,7 +156,7 @@ const generatePromotionCode = async () => {
|
||||
try {
|
||||
const res = await generatePromotionLink({
|
||||
product: formData.value.productType,
|
||||
price: formData.value.clientPrice
|
||||
price: String(formData.value.clientPrice)
|
||||
})
|
||||
|
||||
if (res.code === 200) {
|
||||
@@ -201,7 +201,8 @@ const selectProductType = (reportTypeValue) => {
|
||||
return
|
||||
}
|
||||
pickerProductConfig.value = matchedConfig
|
||||
formData.value.clientPrice = Number(matchedConfig.p_pricing_standard)
|
||||
// 与 App / H5 一致:默认客户查询价取成本价
|
||||
formData.value.clientPrice = matchedConfig.cost_price
|
||||
}
|
||||
|
||||
// 获取产品配置
|
||||
@@ -242,11 +243,24 @@ const onPriceChange = (price) => {
|
||||
formData.value.clientPrice = price
|
||||
}
|
||||
|
||||
const openPricePicker = () => {
|
||||
if (!pickerProductConfig.value) {
|
||||
uni.showToast({
|
||||
title: '请选择有效报告类型',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
showPricePicker.value = true
|
||||
}
|
||||
|
||||
// 类型选择确认
|
||||
const onConfirmType = (e) => {
|
||||
const selectedValue = e?.value?.[0] ?? e?.value ?? e?.selectedOptions?.[0]?.value
|
||||
if (selectedValue !== undefined && selectedValue !== null && selectedValue !== '')
|
||||
selectProductType(selectedValue)
|
||||
const rawValue = e?.value ?? e?.selectedItems?.[0]?.value ?? e?.selectedOptions?.[0]?.value
|
||||
const selectedValue = Array.isArray(rawValue) ? rawValue[0] : rawValue
|
||||
if (selectedValue === undefined || selectedValue === null || selectedValue === '')
|
||||
return
|
||||
selectProductType(selectedValue)
|
||||
}
|
||||
|
||||
// 显示公众号二维码
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import { useHotUpdate } from '@/composables/useHotUpdate'
|
||||
|
||||
/**
|
||||
* 自动更新检查工具
|
||||
* 用于在应用运行期间定期检查更新
|
||||
*/
|
||||
class AutoUpdateChecker {
|
||||
constructor() {
|
||||
this.checkInterval = 4 * 60 * 60 * 1000 // 默认4小时检查一次更新
|
||||
this.timer = null
|
||||
this.hotUpdate = useHotUpdate()
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动定时检查
|
||||
* @param {Number} interval 可选,检查间隔时间(毫秒)
|
||||
*/
|
||||
startAutoCheck(interval) {
|
||||
// 先清除可能存在的定时器
|
||||
this.stopAutoCheck()
|
||||
|
||||
// 设置检查间隔时间
|
||||
if (interval && typeof interval === 'number') {
|
||||
this.checkInterval = interval
|
||||
}
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
// 启动定时器
|
||||
this.timer = setInterval(() => {
|
||||
this.hotUpdate.checkUpdate()
|
||||
}, this.checkInterval)
|
||||
// #endif
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止定时检查
|
||||
*/
|
||||
stopAutoCheck() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即执行一次检查
|
||||
*/
|
||||
checkNow() {
|
||||
// #ifdef APP-PLUS
|
||||
this.hotUpdate.checkUpdate()
|
||||
// #endif
|
||||
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
// 创建单例
|
||||
const autoUpdateChecker = new AutoUpdateChecker()
|
||||
|
||||
export default autoUpdateChecker
|
||||
Reference in New Issue
Block a user