This commit is contained in:
2026-04-23 11:49:28 +08:00
parent 1e82051ca5
commit 59471a655c
9 changed files with 112 additions and 437 deletions

View File

@@ -162,12 +162,13 @@ export function getLatestVersion() {
/** /**
* 注销账号 * 注销账号(需传入短信验证码)
*/ */
export function cancelAccount() { export function cancelAccount(code) {
return request({ return request({
url: '/user/cancelOut', url: '/user/cancelOut',
method: 'POST' method: 'POST',
data: { code }
}) })
} }

View File

@@ -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} * @param {Object} params 查询参数 {product_id}

View File

@@ -12,7 +12,6 @@ declare global {
const aesEncrypt: typeof import('./utils/crypto.js')['aesEncrypt'] const aesEncrypt: typeof import('./utils/crypto.js')['aesEncrypt']
const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
const autoUpdateCheck: typeof import('./utils/autoUpdateCheck.js')['default']
const buildPromotionH5Url: typeof import('./utils/promotionH5Url.js')['buildPromotionH5Url'] const buildPromotionH5Url: typeof import('./utils/promotionH5Url.js')['buildPromotionH5Url']
const chatCrypto: typeof import('./utils/chatCrypto.js')['default'] const chatCrypto: typeof import('./utils/chatCrypto.js')['default']
const chatEncrypt: typeof import('./utils/chatEncrypt.js')['default'] const chatEncrypt: typeof import('./utils/chatEncrypt.js')['default']
@@ -228,7 +227,6 @@ declare global {
const useFullscreen: typeof import('@vueuse/core')['useFullscreen'] const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
const useGamepad: typeof import('@vueuse/core')['useGamepad'] const useGamepad: typeof import('@vueuse/core')['useGamepad']
const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
const useHotUpdate: typeof import('./composables/useHotUpdate.js')['useHotUpdate']
const useId: typeof import('vue')['useId'] const useId: typeof import('vue')['useId']
const useIdle: typeof import('@vueuse/core')['useIdle'] const useIdle: typeof import('@vueuse/core')['useIdle']
const useImage: typeof import('@vueuse/core')['useImage'] const useImage: typeof import('@vueuse/core')['useImage']
@@ -359,7 +357,6 @@ declare module 'vue' {
readonly aesEncrypt: UnwrapRef<typeof import('./utils/crypto.js')['aesEncrypt']> readonly aesEncrypt: UnwrapRef<typeof import('./utils/crypto.js')['aesEncrypt']>
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']> 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 buildPromotionH5Url: UnwrapRef<typeof import('./utils/promotionH5Url.js')['buildPromotionH5Url']>
readonly chatCrypto: UnwrapRef<typeof import('./utils/chatCrypto.js')['default']> readonly chatCrypto: UnwrapRef<typeof import('./utils/chatCrypto.js')['default']>
readonly chatEncrypt: UnwrapRef<typeof import('./utils/chatEncrypt.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 useFullscreen: UnwrapRef<typeof import('@vueuse/core')['useFullscreen']>
readonly useGamepad: UnwrapRef<typeof import('@vueuse/core')['useGamepad']> readonly useGamepad: UnwrapRef<typeof import('@vueuse/core')['useGamepad']>
readonly useGeolocation: UnwrapRef<typeof import('@vueuse/core')['useGeolocation']> 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 useId: UnwrapRef<typeof import('vue')['useId']>
readonly useIdle: UnwrapRef<typeof import('@vueuse/core')['useIdle']> readonly useIdle: UnwrapRef<typeof import('@vueuse/core')['useIdle']>
readonly useImage: UnwrapRef<typeof import('@vueuse/core')['useImage']> readonly useImage: UnwrapRef<typeof import('@vueuse/core')['useImage']>

View File

@@ -11,8 +11,8 @@
<div class="border-b border-gray-200"> <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="number" label="¥" label-width="28px" size="large"
:placeholder="`${productConfig.price_range_min} - ${productConfig.price_range_max}`" :placeholder="priceRangePlaceholder" @blur="onBlurPrice"
@blur="onBlurPrice" custom-class="wd-input" /> custom-class="wd-input" />
</div> </div>
<div class="flex items-center justify-between mt-2"> <div class="flex items-center justify-between mt-2">
<div>推广收益为<span class="text-orange-500"> {{ promotionRevenue }} </span></div> <div>推广收益为<span class="text-orange-500"> {{ promotionRevenue }} </span></div>
@@ -26,8 +26,8 @@
<div>我的成本 = 提价成本 + 底价成本</div> <div>我的成本 = 提价成本 + 底价成本</div>
<div class="mt-1">提价成本超过平台标准定价部分平台会收取部分成本价</div> <div class="mt-1">提价成本超过平台标准定价部分平台会收取部分成本价</div>
<div class="">设定范围<span class="text-orange-500">{{ <div class="">设定范围<span class="text-orange-500">{{
productConfig.price_range_min }}</span> - <span class="text-orange-500">{{ productConfig?.price_range_min ?? '--' }}</span> - <span class="text-orange-500">{{
productConfig.price_range_max }}</span></div> productConfig?.price_range_max ?? '--' }}</span></div>
</div> </div>
<div class="px-4 pb-4"> <div class="px-4 pb-4">
<wd-button class="w-full" round type="primary" size="large" @click="onConfirm">确认</wd-button> <wd-button class="w-full" round type="primary" size="large" @click="onConfirm">确认</wd-button>
@@ -60,6 +60,13 @@ watch(show, () => {
price.value = defaultPrice.value 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(() => { const costPrice = computed(() => {
if (!productConfig.value) return 0.00 if (!productConfig.value) return 0.00
// 平台定价成本 // 平台定价成本
@@ -88,6 +95,9 @@ const promotionRevenue = computed(() => {
// 价格校验与修正逻辑 // 价格校验与修正逻辑
const validatePrice = (currentPrice) => { const validatePrice = (currentPrice) => {
if (!productConfig.value) {
return { newPrice: Number(defaultPrice.value || 0), message: '当前产品配置不可用,请重新选择报告类型' }
}
const min = productConfig.value.price_range_min; const min = productConfig.value.price_range_min;
const max = productConfig.value.price_range_max; const max = productConfig.value.price_range_max;
let newPrice = Number(currentPrice); let newPrice = Number(currentPrice);
@@ -108,7 +118,7 @@ const validatePrice = (currentPrice) => {
newPrice = parseFloat(safeTruncate(newPrice)); newPrice = parseFloat(safeTruncate(newPrice));
message = '价格已自动格式化为两位小数'; message = '价格已自动格式化为两位小数';
} }
} catch {} } catch { }
// 范围校验(基于可能格式化后的值) // 范围校验(基于可能格式化后的值)
if (newPrice < min) { if (newPrice < min) {
@@ -159,17 +169,22 @@ const onBlurPrice = () => {
display: flex !important; display: flex !important;
align-items: center !important; align-items: center !important;
justify-content: center !important; justify-content: center !important;
:deep(.wd-input__label-inner) { :deep(.wd-input__label-inner) {
font-size: 24px !important; /* 增大label字体 */ font-size: 24px !important;
/* 增大label字体 */
} }
:deep(.wd-input__inner) { :deep(.wd-input__inner) {
font-size: 24px !important; /* 增大输入框内字体 */ font-size: 24px !important;
/* 增大输入框内字体 */
} }
:deep(.wd-input) { :deep(.wd-input) {
height: auto !important; /* 确保高度自适应 */ height: auto !important;
padding: 8px 0 !important; /* 增加垂直内边距 */ /* 确保高度自适应 */
padding: 8px 0 !important;
/* 增加垂直内边距 */
} }
} }
</style> </style>

View File

@@ -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 返回1v1 < 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
}
}

View File

@@ -23,12 +23,11 @@ function handleClickLeft() {
</script> </script>
<template> <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"> <view class="box-border min-h-screen">
<slot /> <slot />
</view> </view>
</template> </template>
<style scoped> <style scoped></style>
</style>

View File

@@ -369,7 +369,7 @@
<script setup> <script setup>
import { ref, onMounted, reactive, computed } from 'vue' import { ref, onMounted, reactive, computed } from 'vue'
import { useToast } from 'wot-design-uni' import { useToast } from 'wot-design-uni'
import { activateAgentMembership } from '@/apis/agent' import { activateAgentMembership, getAgentMembershipInfo } from '@/apis/agent'
import { formatExpiryTime } from '@/utils/format' import { formatExpiryTime } from '@/utils/format'
import { getCompanyName } from '@/utils/runtimeEnv.js' 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` 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价格配置 // VIP价格配置
const vipConfig = reactive({ const vipConfig = reactive({
price: 399, // VIP价格 price: 399, // VIP价格
@@ -630,6 +636,8 @@ const revenueData = computed(() => {
onMounted(async () => { onMounted(async () => {
// 从本地缓存获取代理信息 // 从本地缓存获取代理信息
loadAgentInfo() loadAgentInfo()
// 从后端加载会员配置(价格和收益参数)
await loadMembershipInfo()
}) })
// 从本地缓存加载代理信息 // 从本地缓存加载代理信息
@@ -650,20 +658,52 @@ const loadAgentInfo = () => {
const selectedType = ref('vip') // 默认选择VIP const selectedType = ref('vip') // 默认选择VIP
const showPayment = ref(false) 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({ const payData = ref({
product_name: `${selectedType.value.toUpperCase()}代理`, product_name: `${selectedType.value.toUpperCase()}代理`,
sell_price: vipConfig.price, sell_price: toFiniteNumber(vipConfig.price),
}) })
const payID = ref('') 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) { function selectType(type) {
selectedType.value = type selectedType.value = type
// 更新payData中的价格和产品名称 // 更新payData中的价格和产品名称
payData.value = { payData.value = buildPayData(type)
product_name: `${type === 'vip' ? 'VIP' : 'SVIP'}代理`,
sell_price: type === 'vip' ? vipConfig.price : vipConfig.svipPrice,
}
} }
// 申请VIP或SVIP // 申请VIP或SVIP
@@ -681,6 +721,11 @@ async function applyVip() {
} }
try { try {
if (toFiniteNumber(payData.value.sell_price) <= 0) {
toast.error('会员价格加载中,请稍后重试')
return
}
const res = await activateAgentMembership({ const res = await activateAgentMembership({
type: selectedType.value.toUpperCase(), type: selectedType.value.toUpperCase(),
}) })

View File

@@ -39,7 +39,7 @@
<!-- 定价 --> <!-- 定价 -->
<wd-input label="客户查询价" label-width="100px" v-model="formData.clientPrice" placeholder="请输入价格" readonly <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: '请输入客户查询价' }]" /> :rules="[{ required: true, message: '请输入客户查询价' }]" />
</wd-cell-group> </wd-cell-group>
@@ -156,7 +156,7 @@ const generatePromotionCode = async () => {
try { try {
const res = await generatePromotionLink({ const res = await generatePromotionLink({
product: formData.value.productType, product: formData.value.productType,
price: formData.value.clientPrice price: String(formData.value.clientPrice)
}) })
if (res.code === 200) { if (res.code === 200) {
@@ -201,7 +201,8 @@ const selectProductType = (reportTypeValue) => {
return return
} }
pickerProductConfig.value = matchedConfig pickerProductConfig.value = matchedConfig
formData.value.clientPrice = Number(matchedConfig.p_pricing_standard) // 与 App / H5 一致:默认客户查询价取成本价
formData.value.clientPrice = matchedConfig.cost_price
} }
// 获取产品配置 // 获取产品配置
@@ -242,10 +243,23 @@ const onPriceChange = (price) => {
formData.value.clientPrice = price formData.value.clientPrice = price
} }
const openPricePicker = () => {
if (!pickerProductConfig.value) {
uni.showToast({
title: '请选择有效报告类型',
icon: 'none'
})
return
}
showPricePicker.value = true
}
// 类型选择确认 // 类型选择确认
const onConfirmType = (e) => { const onConfirmType = (e) => {
const selectedValue = e?.value?.[0] ?? e?.value ?? e?.selectedOptions?.[0]?.value const rawValue = e?.value ?? e?.selectedItems?.[0]?.value ?? e?.selectedOptions?.[0]?.value
if (selectedValue !== undefined && selectedValue !== null && selectedValue !== '') const selectedValue = Array.isArray(rawValue) ? rawValue[0] : rawValue
if (selectedValue === undefined || selectedValue === null || selectedValue === '')
return
selectProductType(selectedValue) selectProductType(selectedValue)
} }

View File

@@ -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