UniApp金融理财产品项目简单介绍
一、项目目录架构设计
├── common # 公共资源
│ ├── api # 接口封装
│ ├── config # 项目配置
│ ├── filters # 过滤器
│ ├── mixins # 混入
│ └── utils # 工具类
├── components # 公共组件
│ ├── risk-indicator.vue # 风险等级指示器
│ ├── product-card.vue # 产品卡片
│ └── secure-keyboard.vue # 安全键盘
├── pages # 页面目录
│ ├── index # 首页
│ ├── product # 产品模块
│ │ ├── list.vue # 产品列表
│ │ └── detail.vue # 产品详情
│ ├── risk # 风险评估
│ │ ├── questionnaire.vue # 问卷页
│ │ └── result.vue # 结果页
│ ├── transaction # 交易模块
│ │ ├── purchase.vue # 购买页
│ │ └── redeem.vue # 赎回页
│ └── user # 用户模块
│ ├── login.vue # 登录页
│ └── assets.vue # 资产页
├── static # 静态资源
├── store # Vuex状态管理
├── uni.scss # 全局样式
└── manifest.json # 应用配置
二、核心模块实现详解
1. 产品展示模块
业务流程图:
产品列表 → 筛选排序 → 进入详情 → 查看说明书 → 购买/预约
关键实现代码:
// pages/product/list.vue
export default {
data() {
return {
filterParams: {
riskLevel: '',
yieldType: 1, // 1-固定收益 2-浮动收益
termRange: [0, 365]
},
productList: []
}
},
methods: {
async loadProducts() {
const res = await this.$api.get('/products', {
params: this.filterParams
})
this.productList = res.data.map(item => ({
...item,
status: this.getProductStatus(item)
}))
},
getProductStatus(product) {
// 产品状态判断逻辑
const now = Date.now()
if (now < product.startTime) return 'coming'
if (product.remaining <= 0) return 'soldout'
return 'selling'
}
}
}
优化点:
- 实现分页加载和虚拟滚动
- 产品卡片使用骨架屏优化体验
- 收益率数字动画效果
2. 风险评估模块
问卷数据结构:
// store/modules/risk.js
const state = {
questions: [
{
id: 'Q1',
text: '您的年龄范围是?',
options: [
{ text: '30岁以下', score: 5 },
{ text: '30-50岁', score: 3 },
{ text: '50岁以上', score: 1 }
]
},
// 更多问题...
],
currentAnswers: {}
}
风险评估计算:
// 计算风险等级(R1-R5)
function calculateRiskLevel(answers) {
const total = Object.values(answers).reduce((a, b) => a + b, 0)
const levels = [
{ min: 0, max: 20, level: 'R1' },
{ min: 21, max: 40, level: 'R2' },
// ...其他等级
]
return levels.find(l => total >= l.min && total <= l.max).level
}
业务流程:
开始评估 → 逐题作答 → 提交问卷 → 显示结果 → 同步服务器 → 限制产品购买范围
3. 购买交易模块
购买流程安全验证:
// pages/transaction/purchase.vue
async submitOrder() {
// 1. 风险等级验证
if (this.product.riskLevel > this.userRiskLevel) {
return this.$showModal({
title: '风险不匹配',
content: '该产品超出您的风险承受能力'
})
}
// 2. 交易密码验证
if (!await this.verifyTradePassword()) {
return this.$toast('密码错误')
}
// 3. 创建订单
const orderRes = await this.$api.post('/orders', {
productId: this.product.id,
amount: this.amount,
clientIp: this.$getClientIP()
})
// 4. 调用支付
uni.requestPayment({
provider: 'wxpay',
orderInfo: orderRes.paymentParams,
success: () => {
this.$trackEvent('purchase_success')
}
})
}
大额交易处理:
// 金额>5万的特殊验证
async verifyLargeAmount() {
await Promise.all([
this.verifySMSCode(),
this.verifyFaceRecognition()
])
this.$api.post('/audit/large-transaction', {
orderId: this.orderId,
verifyRecords: this.verifyRecords
})
}
4. 赎回模块实现
赎回业务规则:
- T+1到账机制
- 快速赎回额度控制(单日≤1万)
- 持有期限判断(是否收取赎回费)
关键代码:
// pages/transaction/redeem.vue
async submitRedeem() {
// 检查是否在开放期
if (!this.product.isInRedeemPeriod) {
return this.$toast('当前不在可赎回时段')
}
// 快速赎回额度检查
if (this.isFastRedeem && this.amount > 10000) {
return this.$toast('快速赎回单日限额1万元')
}
const res = await this.$api.post('/redeem', {
productId: this.productId,
share: this.share,
isFast: this.isFastRedeem
})
this.$showToast({
title: '赎回申请成功',
duration: 1500
})
}
5. 用户登录模块
多因素认证流程:
// pages/user/login.vue
async handleLogin() {
// 1. 获取微信code
const [loginRes, settings] = await Promise.all([
uni.login({ provider: 'weixin' }),
uni.getSystemInfo()
])
// 2. 调用认证接口
const authRes = await this.$api.post('/auth/login', {
code: loginRes.code,
deviceId: settings.deviceId,
platform: settings.platform
})
// 3. 生物识别验证
if (authRes.needBioAuth) {
await this.verifyBiometric()
}
// 4. 存储token
uni.setStorageSync('authToken', authRes.token)
}
安全键盘实现:
<!-- components/secure-keyboard.vue -->
<template>
<view class="keyboard-wrapper">
<view class="keys">
<block v-for="i in 9" :key="i">
<view @touchstart="handleKey(i)"
@touchend="clearActive">
{{i}}
</view>
</block>
</view>
<view class="shuffle" @click="shuffleKeys">
<uni-icons type="refresh" size="20"/>
</view>
</view>
</template>
<script>
export default {
methods: {
shuffleKeys() {
// 每次点击打乱键盘布局
this.keyOrder = [...Array(9).keys()].sort(() => Math.random() - 0.5)
}
}
}
</script>
三、安全防护体系
1. 数据传输安全
// common/api/request.js
const encryptData = (data) => {
const timestamp = Date.now()
const nonce = Math.random().toString(36).slice(2, 10)
return {
encrypted: AES.encrypt(JSON.stringify(data)),
signature: sha256(`${timestamp}${nonce}${secretKey}`),
timestamp,
nonce
}
}
2. 敏感操作防护
- 交易密码输入防截屏
- 关键接口请求频率限制
- 异地登录检测机制
3. 数据存储安全
// 使用uni-app安全存储API
uni.setStorage({
key: 'userInfo',
data: encrypt(userInfo),
encrypt: true
})
四、性能优化策略
1. 首屏加载(预加载)优化
// manifest.json
{
"preloadRule": {
"pages/index": {
"network": "all",
"packages": ["__APP__"]
}
}
}
-
预加载机制原理
-
preloadRule
配置允许在页面加载前预先获取关键资源 - 对
pages/index
配置network: "all"
表示预加载所有网络资源 -
packages: ["__APP__"]
指定预加载主包资源
-
-
优化效果对比
优化方式 传统加载 使用preloadRule 首屏渲染时间 1.5-2s 0.8-1.2s 白屏概率 较高 降低60%以上 资源加载顺序 串行 并行预加载
二、具体优化实现方案
-
资源配置策略
javascriptCopy Code // manifest.json 完整配置示例 { "preloadRule": { "pages/index": { "network": "all", // 预加载所有网络请求 "packages": ["__APP__"], // 主包资源 "pages": ["pages/detail"] // 预加载关联页面:ml-citation{ref="5" data="citationList"} } }, "optimization": { "preloadPages": true // 启用页面预加载:ml-citation{ref="7" data="citationList"} } }
2. 资源加载优化
- 产品图片使用WebP格式
- 金融数据表格使用虚拟滚动
- 非核心模块动态导入
3. 数据缓存策略
// 产品数据缓存示例
async getProductList() {
const cacheKey = 'productList_' + this.filterHash
const cached = uni.getStorageSync(cacheKey)
if (cached && Date.now() - cached.time < 300000) {
return cached.data
}
const freshData = await this.fetchProducts()
uni.setStorageSync(cacheKey, {
time: Date.now(),
data: freshData
})
return freshData
}
五、多端适配方案
1. 样式适配策略
// uni.scss
.product-card {
padding: 20rpx;
@include respond-to('h5') {
padding: 15px;
}
@include respond-to('ios') {
border-radius: 10px;
}
}
2. 功能差异处理
// 支付功能多端适配
function getPaymentProvider() {
// #ifdef MP-WEIXIN
return 'wxpay'
// #endif
// #ifdef APP-PLUS
return 'applepay'
// #endif
}
3. 组件条件编译
<!-- 安全键盘组件 -->
<!-- #ifdef APP-PLUS -->
<fingerprint-verify @success="onVerifySuccess"/>
<!-- #endif -->
六、监控与统计
1. 埋点示例
// 交易流程埋点
this.$trackEvent('purchase_start', {
productId: this.productId,
amount: this.amount
})
this.$trackEvent('purchase_success', {
orderId: res.orderId,
paymentMethod: 'wechat'
})
2. 异常监控
// 全局错误捕获
uni.onError((err) => {
this.$api.post('/monitor/js-error', {
msg: err.message,
stack: err.stack,
page: getCurrentPages().pop().route
})
})
建议开发时特别注意:
- 所有金额计算必须使用Decimal.js处理
- 关键业务流程需添加水印和操作留痕
- 定期进行安全渗透测试
- 理财数据展示需标注"历史业绩不代表未来表现"