feat: 对接完接口

This commit is contained in:
anonymous
2025-01-02 11:05:26 +08:00
parent 6d62cc0567
commit bcd940efe3
48 changed files with 1711 additions and 360 deletions
+3 -1
View File
@@ -96,6 +96,8 @@
"onWatcherCleanup": true,
"useId": true,
"useModel": true,
"useTemplateRef": true
"useTemplateRef": true,
"useCaptcha": true,
"useListPageRequest": true
}
}
Vendored
+3 -3
View File
@@ -7,9 +7,9 @@ VITE_WX_APPID = 'wxa2abb91f64032a2b'
# h5部署网站的base,配置到 manifest.config.ts 里的 h5.router.base
VITE_APP_PUBLIC_BASE=/
VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'
VITE_UPLOAD_BASEURL = 'https://ukw0y1.laf.run/upload'
VITE_SERVER_BASEURL = 'http://api.divine913.com'
VITE_UPLOAD_BASEURL = 'http://api.divine913.com/api/v1/UploadFile'
# h5是否需要配置代理
VITE_APP_PROXY=false
VITE_APP_PROXY=true
VITE_APP_PROXY_PREFIX = '/api'
+1
View File
@@ -103,6 +103,7 @@
"@dcloudio/uni-mp-xhs": "3.0.0-4020920240930001",
"@dcloudio/uni-quickapp-webview": "3.0.0-4020920240930001",
"dayjs": "1.11.10",
"nprogress": "^0.2.0",
"pinia": "2.0.36",
"pinia-plugin-persistedstate": "3.2.1",
"qs": "6.5.3",
+8
View File
@@ -62,6 +62,9 @@ importers:
dayjs:
specifier: 1.11.10
version: 1.11.10
nprogress:
specifier: ^0.2.0
version: 0.2.0
pinia:
specifier: 2.0.36
version: 2.0.36(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2))
@@ -4224,6 +4227,9 @@ packages:
resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
nprogress@0.2.0:
resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==}
nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
@@ -10958,6 +10964,8 @@ snapshots:
dependencies:
path-key: 4.0.0
nprogress@0.2.0: {}
nth-check@2.1.1:
dependencies:
boolbase: 1.0.0
+6 -4
View File
@@ -11,6 +11,8 @@ onLaunch((options) => {
// redirect: options.path,
// },
})
} else {
userStore.loadUserInfo()
}
})
@@ -100,15 +102,15 @@ uni-modal {
}
.uni-modal__title {
@apply p-16 text-left text-16 font-600;
@apply p-15 text-left text-16 font-600;
}
.uni-modal__bd {
@apply mb-16 px-16 pt-0 text-left text-14 font-medium text-#666;
@apply px-15 pt-0 text-left text-14 font-medium text-#666;
}
.uni-modal__btn {
@apply px-16 py-8 flex-none rounded-full shadow-none text-14;
@apply px-15 py-6 flex-none rounded-full shadow-none text-14;
&::after {
content: none;
@@ -120,7 +122,7 @@ uni-modal {
}
.uni-modal__ft {
@apply justify-end p-16 leading-normal;
@apply justify-end px-15 pb-10 leading-normal;
&::after {
content: none;
+11
View File
@@ -0,0 +1,11 @@
export const useCaptcha = () => {
const codeUrl = ref('')
const refreshCode = () => {
const baseUrl = import.meta.env.VITE_SERVER_BASEURL
codeUrl.value = baseUrl + '/api/v1/getCaptcha?t=' + Date.now()
}
onMounted(() => {
refreshCode()
})
return { codeUrl, refreshCode }
}
+105
View File
@@ -0,0 +1,105 @@
import { onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
import { computed, onMounted, ref } from 'vue'
interface PaginationRequest {
pageIndex?: number
pageSize?: number
[key: string]: any
}
function useListPageRequest(
request: (params: PaginationRequest) => Promise<any>,
options: {
autoBind?: boolean
autoRequest?: boolean
} = {},
) {
const { autoBind = true, autoRequest = true } = options
const list = ref<any[]>([])
// 加载中
const loading = ref(false)
// 加载更多中
const moreLoading = ref(false)
// 全部数据加载完成
const totalPage = ref(0)
const finished = computed(() => totalPage.value <= pagingParams.value.pageIndex)
const pagingParams = ref<PaginationRequest>({
pageIndex: 1,
pageSize: 10,
})
const getPagingParams = computed(() => {
return {
...pagingParams.value,
}
})
let customParams: PaginationRequest = {}
const statusLoading = computed(() => {
if (moreLoading.value || loading.value) {
return 'loading'
}
if (finished.value) {
return 'noMore'
}
return 'more'
})
const loadData = async () => {
const { data } = await request({
...getPagingParams.value,
...customParams,
})
totalPage.value = data.count ? Math.ceil(data.count / pagingParams.value.pageSize!) : 0
list.value.push(...data.list)
}
const onReload = async (params?: AnyObject) => {
loading.value = true
pagingParams.value.pageIndex = 1
if (params) {
customParams = params
}
try {
await loadData()
} finally {
loading.value = false
}
}
const onMore = async () => {
if (finished.value) {
return
}
pagingParams.value.pageIndex = pagingParams.value.pageIndex! + 1
moreLoading.value = true
try {
await loadData()
} finally {
moreLoading.value = false
}
}
if (autoRequest) {
onMounted(onReload)
}
if (autoBind) {
onPullDownRefresh(async () => {
await onReload()
uni.stopPullDownRefresh()
})
onReachBottom(onMore)
}
return {
list,
loading,
moreLoading,
finished,
statusLoading,
totalPage,
onReload,
onMore,
}
}
export { useListPageRequest }
+1 -1
View File
@@ -17,7 +17,7 @@ type IUseRequestOptions<T> = {
*/
export default function useRequest<T>(
func: () => Promise<IResData<T>>,
options: IUseRequestOptions<T> = { immediate: false },
options: IUseRequestOptions<T> = { immediate: true },
) {
const loading = ref(false)
const error = ref(false)
+2 -2
View File
@@ -51,9 +51,9 @@ const httpInterceptor = {
}
// 3. 添加 token 请求头标识
const userStore = useUserStore()
const { token } = userStore.userInfo as unknown as IUserInfo
const token = userStore.token
if (token) {
options.header.Authorization = `Bearer ${token}`
options.header.Authorization = token
}
},
}
+15 -5
View File
@@ -4,6 +4,7 @@
* 可以设置路由白名单,或者黑名单,看业务需要选哪一个
* 我这里应为大部分都可以随便进入,所以使用黑名单
*/
import { getUserInfoAPI } from '@/service'
import { useUserStore } from '@/store'
import {
getNotNeedLoginPages as _getNotNeedLoginPages,
@@ -11,6 +12,10 @@ import {
} from '@/utils'
import type { Router } from 'vue-router'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
NProgress.configure({ showSpinner: true, parent: '#app' })
export const loginRoute = '/pages/login/index'
export const isLogged = () => {
@@ -68,7 +73,6 @@ export const getNotNeedLoginPages = () => {
export const checkLoginUrl = (url: string) => {
const path = url.split('?')[0]
const isNotNeedLogin = getNotNeedLoginPages().includes(path.replace(/^pages/, '/pages'))
console.log(path)
return isNotNeedLogin
}
@@ -89,15 +93,21 @@ export const checkNotFound = (url: string) => {
}
export const routerBeforeEachConfig = (router: Router) => {
router.beforeEach((to, from, next) => {
router.beforeEach(async (to, from, next) => {
NProgress.start()
if (checkWithRedirectLogin(to.path)) {
return next({
path: loginRoute,
// query: {
// redirect: to.fullPath,
// },
})
}
const userStore = useUserStore()
if (!userStore.userInfo && userStore.isLogged) {
await userStore.loadUserInfo()
}
return next()
})
router.afterEach(() => {
NProgress.done()
})
}
+23 -13
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '我的资产',
@@ -14,41 +14,51 @@
class="mt-15 mx-15 text-white btn-gradient p-15 rounded-10 shadow-[0_5px_30px_rgba(55,230,236,0.4)]"
>
<view class="text-14">总投资金</view>
<view class="text-35 mt-10 font-bold">10000.00</view>
<view class="text-35 mt-10 font-bold">{{ userStore.userInfo?.member_investment }}</view>
<view class="flex mt-15">
<view class="flex-1">
<view class="text-12 font-light">我的分红</view>
<view class="text-16 font-bold mt-5">10000.00</view>
<view class="text-16 font-bold mt-5">{{ userStore.userInfo?.member_dividend }}</view>
</view>
<view class="flex-1">
<view class="text-12 font-light">数字人民币</view>
<view class="text-16 font-bold mt-5">10000.00</view>
<view class="text-16 font-bold mt-5">{{ userStore.userInfo?.member_dividend }}</view>
</view>
<view class="flex-1">
<view class="text-12 font-light">认购点</view>
<view class="text-16 font-bold mt-5">10000.00</view>
<view class="text-16 font-bold mt-5">{{ userStore.userInfo?.member_point }}</view>
</view>
</view>
</view>
<view class="text-16 mx-15 mb-15 font-bold text-#333 mt-30">资产记录</view>
<view
class="flex px-15 py-8 border-b items-center border-#E5E5E5 border-b-solid"
v-for="item in 10"
:key="item"
v-for="item in list"
:key="item.id"
>
<image src="/static/images/page-sub/invite-icon.png" class="w-32 h-32 self-center" />
<view class="flex flex-col flex-1 ml-15">
<view class="text-14 text-#333">邀请好友奖励</view>
<view class="text-14 text-#333">{{ item.title }}</view>
<view class="text-12 mt-10 text-#999">奖励</view>
<view class="text-12 mt-10 text-#999">2024-12-27 10:00:00</view>
<view class="text-12 mt-10 text-#999">{{ item.create_time }}</view>
</view>
<view class="flex flex-col items-end">
<view class="text-14 font-bold text-#FF5F5F">+1000 RMB</view>
<view class="text-14 font-bold text-#FF5F5F">+2000 RMB</view>
<view class="text-14 font-bold text-#FF5F5F">+30 </view>
<view class="text-14 mt-10 py-4 px-10 bg-#71C78A1A text-#71C78A">已到账</view>
<view class="text-14 font-bold text-#FF5F5F">{{ item.money }}</view>
<!-- <view class="text-14 font-bold text-#FF5F5F">+2000 RMB</view> -->
<!-- <view class="text-14 font-bold text-#FF5F5F">+30 </view> -->
<view class="text-14 mt-10 py-4 px-10 bg-#71C78A1A text-#71C78A" v-if="item.status === 1">
已到账
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { getBalanceRecordsAPI } from '@/service'
import { useUserStore } from '@/store'
const userStore = useUserStore()
const { list } = useListPageRequest(getBalanceRecordsAPI)
</script>
+10 -5
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '公司简介',
@@ -6,17 +6,22 @@
}
</route>
<script setup lang="ts">
import { getCompanyInfoAPI } from '@/service'
const { data: companyInfo } = useRequest(() => getCompanyInfoAPI())
</script>
<template>
<view class="pt-15 pb-50 min-h-screen">
<view class="text-center text-16 font-bold">中巴军团</view>
<view class="text-center text-16 font-bold">{{ companyInfo.title }}</view>
<image
class="w-345 h-170 rounded-10 mt-15 mx-auto block"
src="@/static/images/page-sub/introduction.png"
:src="companyInfo.cover_image"
mode="aspectFill"
/>
<view class="text-gray-500 mx-16 text-14 mt-15">
中巴军团集团有限公司由具有160年历史的上海纺织集团和具有70年外贸历史的原东方国际集团联合重组而成是一家拥有先进制造业与现代服务业以时尚产业健康产业和供应链服务为核心主业以科技实业产业地产金融投资为支撑构建一体两翼三支撑总体格局的大型综合性企业集团名列中国企业500强第275位上海企业100强第25位
集团拥有总资产627亿元员工5.8万人海外员工占70%2023年快报营业收入780亿元进出口56.64亿美元出口41.34亿美元进口15.3亿美元集团在海外拥有96家业务机构分布在五大洲27个国家和地区所属企业389家上市公司4家东方创业申达股份龙头股份香港联泰控股
{{ companyInfo.description }}
</view>
</view>
</template>
+33 -16
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '投资记录',
@@ -6,24 +6,41 @@
},
}
</route>
<script lang="ts" setup>
import { getBuyFundOrderListAPI } from '@/service'
import { useListPageRequest } from '@/hooks/useListPageRequest'
import { formatTime } from '@/utils'
const { list: fundList } = useListPageRequest(getBuyFundOrderListAPI)
</script>
<template>
<view class="min-h-screen pb-100">
<view
class="flex px-15 py-8 border-b border-#E5E5E5 border-b-solid"
v-for="item in 10"
:key="item"
>
<image src="/static/images/page-sub/money-icon.png" class="w-32 h-32 self-center" />
<view class="flex flex-col flex-1 justify-between ml-15">
<view class="text-14 text-#333">5G通信</view>
<view class="text-12 text-#999">投资</view>
<view class="text-12 text-#999">2024-12-27 10:00:00</view>
</view>
<template v-if="fundList.length > 0">
<view
class="flex px-15 py-8 border-b border-#E5E5E5 border-b-solid"
v-for="item in fundList"
:key="item.id"
>
<image src="/static/images/page-sub/money-icon.png" class="w-32 h-32 self-center" />
<view class="flex flex-col flex-1 justify-between ml-15">
<view class="text-14 text-#333">{{ item.fund_name }}</view>
<view class="text-12 text-#999">投资</view>
<view class="text-12 text-#999">{{ formatTime(item.create_time * 1000) }}</view>
</view>
<view class="flex flex-col items-end">
<view class="text-16 text-#FF5F5F">+1000 RMB</view>
<view class="text-14 mt-18 py-4 px-10 bg-#71C78A1A text-#71C78A">投资成功</view>
<view class="flex flex-col items-end">
<view class="text-16 text-#FF5F5F">+{{ item.buy_price }} RMB</view>
<view
class="text-14 mt-18 py-4 px-10 bg-#71C78A1A text-#71C78A"
v-if="item.order_status === 1"
>
投资成功
</view>
</view>
</view>
</view>
</template>
<template v-else>
<wd-status-tip image="content" tip="暂无内容" />
</template>
</view>
</template>
+1 -1
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationStyle: 'custom',
+3 -3
View File
@@ -1,7 +1,7 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '投资成功',
navigationBarTitleText: '充值成功',
navigationBarBackgroundColor: '#fff',
},
}
@@ -9,7 +9,7 @@
<template>
<view class="min-h-screen flex flex-col items-center justify-center">
<image mode="aspectFit" src="/static/images/page-sub/invest-success.png" class="w-150 h-150" />
<view class="text-17 text-#333">恭喜您投资成功</view>
<view class="text-17 text-#333">恭喜您充值成功</view>
<!-- 返回 -->
<view class="mt-15">
<view @click="onBack" class="btn-gradient text-14 text-white rounded-full px-30 py-10">
+8 -4
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '邀请好友',
@@ -8,9 +8,13 @@
</route>
<script setup lang="ts">
import { useUserStore } from '@/store'
import VueQrcode from '@chenfengyuan/vue-qrcode'
const qrcodeValue = '/pages/register/index?invite=888888'
const userStore = useUserStore()
const qrcodeValue =
location.origin + '/#/pages/register/index?invite=' + userStore.userInfo?.invitation_code
const onCopy = (code: string) => {
uni.setClipboardData({
@@ -27,11 +31,11 @@ const onCopy = (code: string) => {
>
<view>
邀请码
<text class="font-bold">9999999</text>
<text class="font-bold">{{ userStore.userInfo.invitation_code }}</text>
</view>
<view
class="btn-gradient text-white rounded-full px-15 py-4 text-12 ml-10"
@click="onCopy('99999')"
@click="onCopy(userStore.userInfo.invitation_code)"
>
复制
</view>
+28
View File
@@ -0,0 +1,28 @@
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '新闻详情',
navigationBarBackgroundColor: '#fff',
},
}
</route>
<script setup lang="ts">
import { getNewsDetailAPI } from '@/service'
const newsDetail = ref<any>({})
onLoad(async (options) => {
const { data } = await getNewsDetailAPI({ news_id: options.id })
newsDetail.value = data
})
</script>
<template>
<view class="min-h-screen pb-100 pt-30 px-15">
<view class="text-20 text-black font-bold">{{ newsDetail.title }}</view>
<view class="flex justify-between py-10">
<view class="text-14 text-gray-500">{{ newsDetail.auther }}</view>
<view class="text-14 text-gray-500">{{ newsDetail.create_time }}</view>
</view>
<image class="w-full mt-15" mode="widthFix" :src="newsDetail.cover_image" />
<view class="text-14 text-gray-600 mt-15">{{ newsDetail.description }}</view>
</view>
</template>
+1 -1
View File
@@ -3,7 +3,7 @@ import NavBar from '@/components/NavBar.vue'
import VueQrcode from '@chenfengyuan/vue-qrcode'
</script>
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '官方社群',
+127
View File
@@ -0,0 +1,127 @@
<template>
<view class="min-h-screen pt-50 pb-100">
<view
class="w-345 mx-auto rounded-10 btn-gradient px-30 pb-20 relative shadow-[0_5px_30px_rgba(55,230,236,0.4)]"
>
<view class="relative -top-30px">
<view class="relative w-70">
<Avatar class="w-70 h-70 box-border" />
<view
class="text-center left-1/2 whitespace-nowrap -translate-x-1/2 py-2 px-10 absolute -bottom-6 bg-[linear-gradient(180deg,#FFD54B,#FFB99A)] rounded-full text-10 left-0 text-#fff"
>
黄金会员
</view>
</view>
<view class="text-16 mt-15 text-#fff">132***0101</view>
</view>
<view class="absolute -bottom-10 right-30 text-90 leading-80 font-bold text-#ffffff20">
VIP
</view>
</view>
<view class="mt-30 w-345 mx-auto grid grid-cols-3 gap-10">
<view
class="bg-#fff py-40 rounded-10 text-center border border-#E5E5E5 border-solid"
v-for="(item, index) of vipList"
:key="item.id"
:class="{
'!bg-[linear-gradient(90deg,#3B81F320,#37E6EC20)]': currentVipIndex === index,
'!border-#3B81F3': currentVipIndex === index,
}"
@click="currentVipIndex = index"
>
<view class="text-14">{{ item.vip_name }}</view>
<view class="mt-10 text-20 font-bold">{{ item.buy_price }}</view>
</view>
</view>
<view class="text-center mt-30 mt-30 pt-30 border-t-8 border-#f7f7f7 border-t-solid">
<view class="text-18 font-500 text-#333">会员专属权益</view>
<view class="text-14 text-#666 mt-10">每日获得高收益分红</view>
</view>
<view class="mt-30 w-345 mx-auto grid grid-cols-3 gap-10">
<view class="bg-#fff py-20 rounded-10 text-center border border-#E5E5E5 border-solid">
<image
class="w-50 h-50"
src="@/static/images/page-sub/purchase-member/icon-1.png"
mode="scaleToFill"
/>
<view class="mt-10 text-12 text-#999">每日可以获取</view>
<view class="text-14 font-bold text-#FF5F5F">
{{ Number(vipList[currentVipIndex].award_investment) }}投资金
</view>
</view>
<view class="border border-#E5E5E5 border-solid py-20 rounded-10 text-center">
<image
class="w-50 h-50"
src="@/static/images/page-sub/purchase-member/icon-2.png"
mode="scaleToFill"
/>
<view class="mt-10 text-12 text-#999">数字人民币</view>
<view class="text-14 font-bold text-#FF5F5F">
{{ Number(vipList[currentVipIndex].award_currency) }}
</view>
</view>
<view class="bg-#fff py-20 rounded-10 text-center border border-#E5E5E5 border-solid">
<image
class="w-50 h-50"
src="@/static/images/page-sub/purchase-member/icon-3.png"
mode="scaleToFill"
/>
<view class="mt-10 text-12 text-#999">AI智能</view>
<view class="text-14 font-bold text-#FF5F5F">
{{ vipList[currentVipIndex].dividend_multiple }}
</view>
</view>
</view>
<view
class="bg-white fixed bottom-0 left-0 right-0 px-15 py-10 shadow-[0_0_10px_rgba(10,68,245,0.1)]"
>
<view class="flex items-center pb-safe">
<view
class="btn-gradient flex-1 text-center text-white rounded-full text-14 px-30 py-10"
@click="onSubmit"
>
立即购买
</view>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import Avatar from '@/components/Avatar.vue'
import { buyVIPAPI, getVipListAPI } from '@/service'
import { useUserStore } from '@/store'
import { mergeStep, showModal } from '@/utils'
const vipList = ref<any[]>([])
const currentVipIndex = ref(0)
onLoad(() => {
getVipListAPI().then((res) => {
vipList.value = res.data.list
})
})
const userStore = useUserStore()
const onSubmit = mergeStep(async () => {
console.log(vipList.value[currentVipIndex.value])
await showModal('确认购买吗?')
await buyVIPAPI({
fund_id: vipList.value[currentVipIndex.value].id,
})
await showModal('购买成功')
await userStore.loadUserInfo()
})
</script>
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '购买会员',
navigationBarBackgroundColor: '#fff',
},
}
</route>
+77 -54
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '实名认证',
@@ -9,80 +9,103 @@
<template>
<view class="withdrawal-type-edit-page pb-100 min-h-screen">
<view class="p-15 m-15 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10">
<view class="flex items-center py-15 text-14">
<image src="@/static/images/page-sub/realname/realname-type.png" class="w-20 h-20" />
<view class="ml-8">证件类型</view>
<view class="flex-1 text-right text-14">身份</view>
<template v-if="Number(userStore.userInfo?.member_certification) === 0">
<view class="p-15 m-15 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10">
<view class="flex items-center py-15 text-14">
<image src="@/static/images/page-sub/realname/realname-type.png" class="w-20 h-20" />
<view class="ml-8">件类型</view>
<view class="flex-1 text-right text-14">身份证</view>
</view>
<view class="flex items-center py-15 text-14">
<image src="@/static/images/page-sub/realname/realname-name.png" class="w-20 h-20" />
<view class="ml-8">真实姓名</view>
<input
class="flex-1 text-right text-14"
placeholder-class=" text-#889BC6 text-right"
type="text"
placeholder="请输入真实姓名"
v-model="form.credentials_name"
/>
</view>
<view class="flex items-center py-15 text-14">
<image src="@/static/images/page-sub/realname/realname-number.png" class="w-20 h-20" />
<view class="ml-8">身份证号</view>
<input
class="flex-1 text-right text-14"
placeholder-class=" text-#889BC6 text-right"
type="text"
placeholder="请输入身份证号"
v-model="form.credentials_number"
/>
</view>
</view>
<view class="flex items-center py-15 text-14">
<image src="@/static/images/page-sub/realname/realname-name.png" class="w-20 h-20" />
<view class="ml-8">真实姓名</view>
<input
class="flex-1 text-right text-14"
placeholder-class=" text-#889BC6 text-right"
type="text"
placeholder="请输入真实姓名"
v-model="form.name"
/>
<view class="fixed bottom-0 left-0 right-0 pb-safe">
<button class="btn-gradient text-white rounded-full m-15 text-16" @click="onSubmit">
提交
</button>
</view>
<view class="flex items-center py-15 text-14">
<image src="@/static/images/page-sub/realname/realname-number.png" class="w-20 h-20" />
<view class="ml-8">身份证号</view>
<input
class="flex-1 text-right text-14"
placeholder-class=" text-#889BC6 text-right"
type="text"
placeholder="请输入身份证号"
v-model="form.idCard"
/>
</view>
</view>
<view class="fixed bottom-0 left-0 right-0 pb-safe">
<button class="btn-gradient text-white rounded-full m-15 text-16" @click="onAddType">
提交
</button>
</view>
<view class="flex flex-col items-center" v-if="false">
</template>
<template v-else-if="Number(userStore.userInfo?.member_certification) === 2">
<image
src="@/static/images/page-sub/realname/realname-success.png"
class="w-150 h-150 block"
mode="aspectFit"
/>
<view class="text-center mt-15 text-14 text-#999">恭喜您实名认证成功</view>
<button class="btn-gradient px-30 text-white rounded-full m-15 text-16" @click="onBack">
返回
</button>
<image
src="@/static/images/page-sub/realname/realname-fail.png"
class="w-150 h-150 block"
src="@/static/images/page-sub/realname/realname-checking.png"
class="w-150 mx-auto h-150 block"
mode="aspectFit"
/>
<view class="text-center mt-15 text-14 text-#999">您的实名认证正在审核中请耐心等待</view>
<button class="btn-gradient px-30 text-white rounded-full m-15 text-16" @click="onBack">
返回
</button>
<image
src="@/static/images/page-sub/realname/realname-checking.png"
class="w-150 h-150 block"
mode="aspectFit"
/>
<view class="text-center mt-15 text-14 text-#999">您的实名认证审核未通过请重新提交</view>
<button class="btn-gradient px-30 text-white rounded-full m-15 text-16">重新提交</button>
</view>
</template>
<template v-else-if="Number(userStore.userInfo?.member_certification) === 1">
<view class="flex flex-col items-center" v-if="false">
<image
src="@/static/images/page-sub/realname/realname-success.png"
class="w-150 h-150 block"
mode="aspectFit"
/>
<view class="text-center mt-15 text-14 text-#999">恭喜您实名认证成功</view>
<button class="btn-gradient px-30 text-white rounded-full m-15 text-16" @click="onBack">
返回
</button>
<!--
<image
src="@/static/images/page-sub/realname/realname-checking.png"
class="w-150 h-150 block"
mode="aspectFit"
/>
<view class="text-center mt-15 text-14 text-#999">您的实名认证审核未通过请重新提交</view>
<button class="btn-gradient px-30 text-white rounded-full m-15 text-16">重新提交</button> -->
</view>
</template>
</view>
</template>
<script setup lang="ts">
import { createAuthUser } from '@/service'
import { useUserStore } from '@/store'
import { showModal } from '@/utils'
import { ref } from 'vue'
const userStore = useUserStore()
const notSubmit = ref(true)
const form = ref({
type: '',
credentials_name: '',
credentials_number: '',
})
const onBack = () => {
uni.navigateBack()
}
const onSubmit = async () => {
if (!form.value.credentials_name || !form.value.credentials_number) {
await showModal('请填写完整信息')
return
}
await createAuthUser(form.value)
notSubmit.value = false
}
</script>
<style lang="scss" scoped>
.withdrawal-type-edit-page {
+86
View File
@@ -0,0 +1,86 @@
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '充值记录',
navigationBarBackgroundColor: '#fff',
},
}
</route>
<template>
<view class="min-h-screen pb-100">
<template v-if="list.length">
<view
class="flex px-15 py-8 border-b border-#E5E5E5 border-b-solid"
v-for="item in list"
:key="item.id"
>
<image
v-if="getCurrentWallet(item.wall_id).wallet_crad_type === 1"
src="/static/images/invest/unionpay-icon.png"
class="w-32 h-32 self-center"
/>
<image
v-if="getCurrentWallet(item.wall_id).wallet_crad_type === 2"
src="/static/images/invest/alipay-icon.png"
class="w-32 h-32 self-center"
/>
<image
v-if="getCurrentWallet(item.wall_id).wallet_crad_type === 3"
src="/static/images/invest/wechat-icon.png"
class="w-32 h-32 self-center"
/>
<view class="flex flex-col flex-1 justify-between ml-15">
<view class="text-14 text-#333">{{ getCurrentWallet(item.wall_id).wallet_name }}</view>
<view class="text-12 text-#999">充值</view>
<view class="text-12 text-#999">{{ item.create_time }}</view>
</view>
<view class="flex flex-col items-end">
<view class="text-16 text-#FF5F5F">+{{ item.change_money }} RMB</view>
<view
class="text-14 mt-18 py-4 px-10 bg-gray-400 text-white"
v-if="item.change_status === 0"
>
充值中
</view>
<view
class="text-14 mt-18 py-4 px-10 bg-#71C78A1A text-#71C78A"
v-else-if="item.change_status === 1"
>
充值成功
</view>
<view
class="text-14 mt-18 py-4 px-10 bg-#FF5F5F text-white"
v-else-if="item.change_status === 2"
>
充值失败
</view>
</view>
</view>
</template>
<template v-else>
<wd-status-tip image="content" tip="暂无数据" />
</template>
</view>
</template>
<script setup lang="ts">
import { getRechargeRecordAPI, getSystemRechargeAccountAPI } from '@/service'
const { list } = useListPageRequest(getRechargeRecordAPI)
const walletList = ref<any[]>([])
onMounted(async () => {
const {
data: { list },
} = await getSystemRechargeAccountAPI({
wallet_type: 1,
})
walletList.value = list
})
const getCurrentWallet = (id: string) => {
return walletList.value.find((item) => item.id === id)
}
</script>
+223
View File
@@ -0,0 +1,223 @@
<route lang="json5">
{
style: {
navigationStyle: 'custom',
navigationBarTitleText: '充值',
},
}
</route>
<template>
<view class="recharge-page min-h-screen pb-100">
<NavBar>
<template #right>
<image @click="onRecharge" src="/static/images/page-sub/recharge.png" class="w-24 h-24" />
</template>
</NavBar>
<view class="p-15">
<view class="mt-15">
<view class="text-14 text-#333">充值金额</view>
<view class="text-14 mt-15 text-#333 p-16 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10">
<input
v-model="form.change_money"
type="number"
placeholder="请输入充值金额"
class="text-14 text-#333"
/>
</view>
</view>
<view class="mt-15">
<view class="text-14 text-#333">充值方式</view>
<view class="text-14 mt-15 text-#333 p-16 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10">
<wd-select-picker
type="radio"
custom-class="!p-0"
custom-value-class="text-14 text-#889BC6"
class="flex-1"
placeholder="请选择充值方式"
v-model="walletType"
:columns="columns"
></wd-select-picker>
<!-- 用卡片展示收款银行信息 -->
<view class="mt-15">
<!-- 银行卡信息 -->
<view class="mt-15" v-if="walletType === 1">
<view class="mt-15 flex items-center justify-between">
<view class="text-14 text-#333">银行名称</view>
<view class="text-14 text-#889BC6">{{ currentWallet.wallet_name }}</view>
</view>
<view class="mt-15 flex items-center justify-between">
<view class="text-14 text-#333">银行账号</view>
<view class="text-14 text-#889BC6">{{ currentWallet.wallet_account }}</view>
</view>
<view class="mt-15 flex items-center justify-between">
<view class="text-14 text-#333">银行户名</view>
<view class="text-14 text-#889BC6">{{ currentWallet.wallet_username }}</view>
</view>
</view>
<!-- 支付宝信息 -->
<view class="mt-15" v-if="walletType === 2">
<view class="mt-15 flex items-center justify-between">
<view class="text-14 text-#333">支付宝账号</view>
<view class="text-14 text-#889BC6">{{ currentWallet.wallet_account }}</view>
</view>
<view class="mt-15 flex items-center justify-between">
<view class="text-14 text-#333">支付宝户名</view>
<view class="text-14 text-#889BC6">{{ currentWallet.wallet_username }}</view>
</view>
</view>
<!-- 微信信息 -->
<view class="mt-15" v-if="walletType === 3">
<view class="mt-15 flex items-center justify-between">
<view class="text-14 text-#333">微信账号</view>
<view class="text-14 text-#889BC6">{{ currentWallet.wallet_account }}</view>
</view>
<view class="mt-15 flex items-center justify-between">
<view class="text-14 text-#333">微信户名</view>
<view class="text-14 text-#889BC6">{{ currentWallet.wallet_username }}</view>
</view>
</view>
</view>
</view>
</view>
<view class="mt-15">
<view class="text-14 text-#333">充值账号</view>
<view class="text-14 mt-15 text-#333 p-16 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10">
<input
v-model="form.bank_account"
type="number"
placeholder="请输入充值账号"
class="text-14 text-#333"
/>
</view>
</view>
<view class="mt-15">
<view class="text-14 text-#333">付款截图</view>
<view class="text-14 mt-15 text-#333 p-16 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10">
<view @click="handleUpload" class="text-14 text-gradient">上传截图</view>
<image
mode="aspectFill"
@click="handlePreview"
class="w-100 h-100 mt-15 rounded-10"
:src="form.change_image"
/>
</view>
</view>
</view>
<view class="fixed bottom-0 left-0 right-0 px-15 pb-safe">
<view
class="btn-gradient mb-15 text-center text-white rounded-full text-16 px-30 py-10"
@click="onSubmit"
>
提交
</view>
</view>
</view>
</template>
<script setup lang="ts">
import NavBar from '@/components/NavBar.vue'
import { getSystemRechargeAccountAPI, rechargeAPI } from '@/service'
import { mergeStep, showModal } from '@/utils'
const walletType = ref(1)
const columns = [
{
label: '银行卡',
value: 1,
},
{
label: '支付宝',
value: 2,
},
{
label: '微信',
value: 3,
},
]
const form = ref({
change_money: '',
bank_account: '',
change_image: '',
wall_id: '',
})
const currentWallet = ref<any>(null)
watch(
() => columns[walletType.value - 1]?.value,
async (walletCradType) => {
const {
data: { list },
} = await getSystemRechargeAccountAPI({
wallet_type: 1,
wallet_crad_type: walletCradType,
})
currentWallet.value = list[0]
form.value.wall_id = list[0].id
},
{ immediate: true },
)
const { data, run } = useUpload<any>()
const handleUpload = () => {
run()
}
watch(data, async (newVal) => {
const path = JSON.parse(newVal)?.data?.path
form.value.change_image = path
})
const onRecharge = () => {
uni.navigateTo({
url: '/pages-sub/recharge-detail/index',
})
}
const onSubmit = mergeStep(async () => {
if (!form.value.change_image) {
uni.showToast({
title: '请上传付款截图',
icon: 'none',
})
return
}
if (!form.value.bank_account) {
uni.showToast({
title: '请输入充值账号',
icon: 'none',
})
return
}
if (!form.value.change_money) {
uni.showToast({
title: '请输入充值金额',
icon: 'none',
})
return
}
await rechargeAPI(form.value)
await showModal('充值成功')
uni.redirectTo({
url: '/pages-sub/invest-result/index',
})
})
const handlePreview = () => {
uni.previewImage({
urls: [form.value.change_image],
})
}
</script>
<style lang="scss" scoped>
.recharge-page {
--wot-input-placeholder-color: #889bc6;
--wot-cell-wrapper-padding: 0;
--wot-cell-padding: 0;
}
</style>
+36 -8
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '我的邀请',
@@ -23,7 +23,7 @@
/>
<view class="flex flex-col">
<view class="text-14 text-gradient">看看人数</view>
<view class="text-35 font-bold text-gradient mt-10 leading-35">1234</view>
<view class="text-35 font-bold text-gradient mt-10 leading-35">{{ totalCount }}</view>
</view>
</view>
<image
@@ -45,17 +45,21 @@
<view class="text-14 text-center">{{ item.title }}</view>
</view>
</view>
<view class="mt-25 bg-white rounded-10 w-345 mx-auto">
<view class="flex p-15 items-center" v-for="item in 10" :key="item">
<Avatar class="w-40 h-40" />
<view class="mt-25 bg-white rounded-10 w-345 mx-auto" v-if="list.length > 0">
<view class="flex p-15 items-center" v-for="item in list" :key="item.id">
<Avatar class="w-40 h-40" :src="item.member_portrait" />
<view class="flex-1 flex flex-col ml-15">
<view class="text-14 text-#333">用户名</view>
<view class="text-12 mt-10 text-#999">1234567890</view>
<view class="text-12 mt-10 text-#999">2024-12-27 12:00:00</view>
<view class="text-14 text-#333">{{ item.nickname }}</view>
<view class="text-12 mt-10 text-#999">{{ item.member_username }}</view>
<view class="text-12 mt-10 text-#999">{{ item.create_time }}</view>
</view>
<view class="bg-#71C78A80 text-white text-12 rounded-10 px-10 py-5">邀请成功</view>
</view>
</view>
<view class="mt-25 bg-white rounded-10 w-345 mx-auto p-15" v-else>
<wd-status-tip image="content" tip="暂无内容" />
</view>
<wd-action-sheet v-model="showRule" title="邀请奖励规则">
<view class="text-16 text-#333 p-15">
<view class="mb-10">1.每邀请一人可以获得1万投资金2000数字人民币 1点认购点</view>
@@ -71,6 +75,7 @@
<script setup lang="ts">
import Avatar from '@/components/Avatar.vue'
import NavBar from '@/components/NavBar.vue'
import { getMyTeamAPI } from '@/service'
import Level1 from '@/static/images/page-sub/team/level-1.png'
import Level2 from '@/static/images/page-sub/team/level-2.png'
import Level3 from '@/static/images/page-sub/team/level-3.png'
@@ -89,28 +94,51 @@ const levelList = ref([
{
title: '一级用户',
icon: Level1,
level: 1,
},
{
title: '二级用户',
icon: Level2,
level: 2,
},
{
title: '三级用户',
icon: Level3,
level: 3,
},
{
title: '四级用户',
icon: Level4,
level: 4,
},
{
title: '五级用户',
icon: Level5,
level: 5,
},
{
title: '六级用户',
icon: Level6,
level: 6,
},
])
const totalCount = ref(0)
const { list, onReload } = useListPageRequest((...rest) => {
return getMyTeamAPI(...rest).then((res) => {
totalCount.value = (res.data as any).total_count
return res
})
})
watch(
() => unref(levelList)[currentLevelIndex.value].level,
(level) => {
onReload({
level,
})
},
)
</script>
<style lang="scss" scoped>
+45 -16
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '提现记录',
@@ -8,22 +8,51 @@
</route>
<template>
<view class="min-h-screen pb-100">
<view
class="flex px-15 py-8 border-b border-#E5E5E5 border-b-solid"
v-for="item in 10"
:key="item"
>
<image src="/static/images/invest/unionpay-icon.png" class="w-32 h-32 self-center" />
<view class="flex flex-col flex-1 justify-between ml-15">
<view class="text-14 text-#333">银行卡</view>
<view class="text-12 text-#999">提现</view>
<view class="text-12 text-#999">2024-12-27 10:00:00</view>
</view>
<template v-if="list.length">
<view
class="flex px-15 py-8 border-b border-#E5E5E5 border-b-solid"
v-for="item in list"
:key="item.id"
>
<image
v-if="item.cash_type === 1"
src="/static/images/invest/unionpay-icon.png"
class="w-32 h-32 self-center"
/>
<image
v-if="item.cash_type === 2"
src="/static/images/invest/alipay-icon.png"
class="w-32 h-32 self-center"
/>
<image
v-if="item.cash_type === 3"
src="/static/images/invest/wechat-icon.png"
class="w-32 h-32 self-center"
/>
<view class="flex flex-col flex-1 justify-between ml-15">
<view class="text-14 text-#333">{{ typeName(item.cash_type) }}</view>
<view class="text-12 text-#999">提现</view>
<view class="text-12 text-#999">{{ item.create_time }}</view>
</view>
<view class="flex flex-col items-end">
<view class="text-16 text-#FF5F5F">-1000 RMB</view>
<view class="text-14 mt-18 py-4 px-10 bg-#71C78A1A text-#71C78A">提现成功</view>
<view class="flex flex-col items-end">
<view class="text-16 text-#FF5F5F">-{{ item.cash_money }} RMB</view>
<view class="text-14 mt-18 py-4 px-10 bg-#71C78A1A text-#71C78A">{{ item.message }}</view>
</view>
</view>
</view>
</template>
<template v-else>
<wd-status-tip image="content" tip="暂无内容" />
</template>
</view>
</template>
<script setup lang="ts">
import { getWithdrawalRecordAPI } from '@/service'
const { list } = useListPageRequest(getWithdrawalRecordAPI)
const typeName = (item) => {
return ['银行卡', '支付宝', '微信'][Number(item.card_type) - 1]
}
</script>
+56 -23
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '编辑收款方式',
@@ -18,42 +18,42 @@
custom-value-class="text-14 text-#889BC6 text-right"
class="flex-1"
placeholder="请选择收款类型"
v-model="form.type"
v-model="form.card_type"
:columns="columns"
@change="handleChange"
></wd-select-picker>
</view>
<view class="flex items-center py-15 text-14">
<view class="flex items-center py-15 text-14" v-if="form.card_type === 1">
<view>开户行</view>
<input
class="flex-1 text-right text-14"
placeholder-class=" text-#889BC6 text-right"
type="text"
placeholder="请输入开户行"
v-model="form.bank"
v-model="form.bank_name"
/>
</view>
<view class="flex items-center py-15 text-14">
<view>持卡人姓名</view>
<view>{{ typeName }}账号</view>
<input
class="flex-1 text-right text-14"
placeholder-class=" text-#889BC6 text-right"
type="text"
placeholder="请输入持卡人姓名"
v-model="form.name"
:placeholder="`请输入${typeName}账号`"
v-model="form.card_account"
/>
</view>
<view class="flex items-center py-15 text-14">
<view>银行账号</view>
<view>{{ form.card_type === 1 ? '持卡人' : '' }}姓名</view>
<input
class="flex-1 text-right text-14"
placeholder-class=" text-#889BC6 text-right"
type="text"
placeholder="请输入银行账号"
v-model="form.account"
:placeholder="`请输入${form.card_type === 1 ? '持卡人' : ''}姓名`"
v-model="form.card_name"
/>
</view>
<view class="flex items-center py-15 text-14">
<!-- <view class="flex items-center py-15 text-14">
<view>备注</view>
<input
class="flex-1 text-right text-14"
@@ -62,7 +62,7 @@
placeholder="请输入备注"
v-model="form.remark"
/>
</view>
</view> -->
</view>
<view class="fixed bottom-0 left-0 right-0 pb-safe">
<button class="btn-gradient text-white rounded-full m-15 text-16" @click="onAddType">
@@ -73,29 +73,62 @@
</template>
<script setup lang="ts">
import { bindBankCardAPI } from '@/service'
import { mergeStep, showModal } from '@/utils'
import { ref } from 'vue'
const form = ref({
type: '',
card_type: 1,
bank_name: '',
bank_address: '',
card_name: '',
card_account: '',
})
const columns = [
{
label: '银行卡',
value: 1,
},
{
label: '支付宝',
value: '1',
value: 2,
},
{
label: '微信',
value: '2',
},
{
label: '银行卡',
value: '3',
value: 3,
},
]
const handleChange = (value: string) => {
console.log(value)
}
const typeName = computed(() => {
return ['银行卡', '支付宝', '微信'][Number(form.value.card_type) - 1]
})
const onAddType = mergeStep(async () => {
if (form.value.card_type === 1) {
if (!form.value.bank_name) {
return uni.showToast({
title: '请输入开户行',
icon: 'none',
})
}
}
if (!form.value.card_account) {
return uni.showToast({
title: '请输入账号',
icon: 'none',
})
}
if (!form.value.card_name) {
return uni.showToast({
title: '请输入姓名',
icon: 'none',
})
}
await bindBankCardAPI(form.value)
await showModal('添加成功')
uni.navigateBack()
})
</script>
<style lang="scss" scoped>
.withdrawal-type-edit-page {
+40 -13
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '收款方式',
@@ -9,19 +9,43 @@
<template>
<view class="withdrawal-type-page min-h-screen pb-100">
<view
class="flex items-center justify-between py-15 text-14 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10 m-15 p-15"
v-for="item in 10"
:key="item"
@click="onSelectType(item)"
>
<image class="w-45 h-45" src="@/static/images/invest/alipay-icon.png" mode="aspectFit" />
<view class="flex-1 ml-15">
<view class="text-16 font-bold">支付宝</view>
<view class="mt-10 text-14 text-#889BC6">132****113</view>
<template v-if="list.length > 0">
<view
class="flex items-center justify-between py-15 text-14 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10 m-15 p-15"
v-for="item in list"
:key="item.id"
@click="onSelectType(item)"
>
<image
v-if="Number(item.card_type) === 1"
class="w-45 h-45"
src="@/static/images/invest/unionpay-icon.png"
mode="aspectFit"
/>
<image
v-if="Number(item.card_type) === 2"
class="w-45 h-45"
src="@/static/images/invest/alipay-icon.png"
mode="aspectFit"
/>
<image
v-if="Number(item.card_type) === 3"
class="w-45 h-45"
src="@/static/images/invest/wechat-icon.png"
mode="aspectFit"
/>
<view class="flex-1 ml-15">
<view class="text-16 font-bold">
{{ ['银行卡', '支付宝', '微信'][Number(item.card_type) - 1] }}
</view>
<view class="mt-10 text-14 text-#889BC6">{{ item.card_account }}</view>
</view>
<wd-icon name="arrow-right" size="14px"></wd-icon>
</view>
<wd-icon name="arrow-right" size="14px"></wd-icon>
</view>
</template>
<template v-else>
<wd-status-tip image="content" tip="暂无内容" />
</template>
<view class="fixed bottom-0 left-0 right-0 pb-safe">
<button class="text-16 btn-gradient text-white rounded-full m-15" @click="onAddType">
添加收款方式
@@ -31,6 +55,7 @@
</template>
<script setup lang="ts">
import { getBankCardListAPI } from '@/service'
import { onLoad } from '@dcloudio/uni-app'
let isSelect = false
@@ -56,4 +81,6 @@ const onAddType = () => {
url: '/pages-sub/withdrawal-type/edit',
})
}
const { list } = useListPageRequest(getBankCardListAPI)
</script>
+74 -8
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationStyle: 'custom',
@@ -23,10 +23,22 @@
<view
class="flex items-center text-14 mt-15 text-#333 p-16 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10"
>
<input type="number" placeholder="请输入提现金额" class="text-14 text-#333 flex-1" />
<view class="text-12 text-#04A9F9">全部</view>
<input
v-model="form.cash_money"
type="number"
placeholder="请输入提现金额"
class="text-14 text-#333 flex-1"
/>
<view
class="text-12 text-#04A9F9"
@click="form.cash_money = Number(userStore.userInfo.member_balance ?? 0)"
>
全部
</view>
</view>
<view class="text-12 text-#889BC6 mt-15">
当前余额{{ userStore.userInfo.member_balance }}
</view>
<view class="text-12 text-#889BC6 mt-15">当前余额10012.12</view>
</view>
<view class="mt-50">
@@ -35,7 +47,9 @@
class="flex items-center text-14 mt-15 text-#333 p-16 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10"
@click="onSelectPayType"
>
<view class="flex-1">请选择收款方式</view>
<view class="flex-1">
{{ typeName ? `${typeName}${currentBank?.card_account}` : '请选择收款方式' }}
</view>
<wd-icon name="arrow-right" size="16px"></wd-icon>
</view>
</view>
@@ -43,7 +57,12 @@
<view class="mt-50">
<view class="text-14 text-#333">交易密码</view>
<view class="text-14 mt-15 text-#333 p-16 shadow-[0_0_10px_rgba(10,68,245,0.1)] rounded-10">
<input type="password" placeholder="请输入交易密码" class="text-14 text-#333" />
<input
type="password"
v-model="form.pay_password"
placeholder="请输入交易密码"
class="text-14 text-#333"
/>
</view>
</view>
</view>
@@ -65,6 +84,25 @@
<script setup lang="ts">
import NavBar from '@/components/NavBar.vue'
import { applyWithdrawalAPI } from '@/service'
import { useUserStore } from '@/store'
import { showModal } from '@/utils'
import { ref } from 'vue'
const userStore = useUserStore()
const form = ref({
cash_money: 0,
cash_remark: '',
bank_id: '',
pay_password: '',
})
const typeName = computed(() => {
return ['银行卡', '支付宝', '微信'][Number(unref(currentBank)?.card_type) - 1]
})
const currentBank = ref<any>(null)
const onWithdrawalDetail = () => {
uni.navigateTo({
@@ -74,14 +112,42 @@ const onWithdrawalDetail = () => {
const onSelectPayType = () => {
uni.$once('withdrawal-type', (data: any) => {
console.log(data)
form.value.bank_id = data.id
currentBank.value = data
})
uni.navigateTo({
url: '/pages-sub/withdrawal-type/index?type=select',
})
}
const onSubmit = () => {
const onSubmit = async () => {
if (!form.value.bank_id) {
return uni.showToast({
title: '请选择收款方式',
icon: 'none',
})
}
if (!form.value.bank_id) {
return uni.showToast({
title: '请选择收款方式',
icon: 'none',
})
}
if (!form.value.pay_password) {
return uni.showToast({
title: '请输入交易密码',
icon: 'none',
})
}
if (!form.value.cash_money) {
return uni.showToast({
title: '请输入提现金额',
icon: 'none',
})
}
await applyWithdrawalAPI(form.value)
await showModal('申请成功')
uni.redirectTo({
url: '/pages-sub/invest-result/index',
})
+33 -1
View File
@@ -156,7 +156,7 @@
"path": "invest-result/index",
"type": "page",
"style": {
"navigationBarTitleText": "投资成功",
"navigationBarTitleText": "充值成功",
"navigationBarBackgroundColor": "#fff"
}
},
@@ -168,6 +168,14 @@
"navigationBarBackgroundColor": "#fff"
}
},
{
"path": "news-detail/index",
"type": "page",
"style": {
"navigationBarTitleText": "新闻详情",
"navigationBarBackgroundColor": "#fff"
}
},
{
"path": "official-community/index",
"type": "page",
@@ -177,6 +185,14 @@
"navigationStyle": "custom"
}
},
{
"path": "purchase-member/index",
"type": "page",
"style": {
"navigationBarTitleText": "购买会员",
"navigationBarBackgroundColor": "#fff"
}
},
{
"path": "realname/index",
"type": "page",
@@ -185,6 +201,22 @@
"navigationBarBackgroundColor": "#fff"
}
},
{
"path": "recharge/index",
"type": "page",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "充值"
}
},
{
"path": "recharge-detail/index",
"type": "page",
"style": {
"navigationBarTitleText": "充值记录",
"navigationBarBackgroundColor": "#fff"
}
},
{
"path": "team/index",
"type": "page",
+99 -27
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '忘记密码',
@@ -15,46 +15,46 @@
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/phone.png" mode="aspectFit" />
<input
v-model="form.member_username"
type="text"
placeholder-class="text-#889BC6"
class="text-right flex-1 text-14"
placeholder="请输入手机号"
placeholder="请输入用户名"
/>
</view>
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/message.png" mode="aspectFit" />
<input
type="text"
placeholder-class="text-#889BC6"
class="text-right flex-1 text-14"
placeholder="请输入短信验证码"
/>
<view
class="py-6 rounded-full ml-15 px-15 text-12 text-white btn-gradient text-14 text-#889BC6"
@click="handleGetCode"
>
获取验证码
</view>
</view>
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/password.png" mode="aspectFit" />
<input
v-model="form.old_password"
placeholder-class="text-#889BC6"
type="password"
class="text-right flex-1 text-14"
placeholder="请输入登录密码"
placeholder="请输入登录密码"
/>
</view>
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/password.png" mode="aspectFit" />
<input
v-model="form.member_password"
placeholder-class="text-#889BC6"
type="password"
class="text-right flex-1 text-14"
placeholder="请再次新登录密码"
/>
</view>
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/password.png" mode="aspectFit" />
<input
v-model="form.confirm_member_password"
placeholder-class="text-#889BC6"
type="password"
class="text-right flex-1 text-14"
placeholder="请再次输入登录密码"
placeholder="请再次输入登录密码"
/>
</view>
<view class="flex items-center py-15">
<!-- <view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/password.png" mode="aspectFit" />
<input
placeholder-class="text-#889BC6"
@@ -71,11 +71,22 @@
class="text-right flex-1 text-14"
placeholder="请再次输入支付密码"
/>
</view> -->
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/message.png" mode="aspectFit" />
<input
v-model="form.verify_code"
type="text"
placeholder-class="text-#889BC6"
class="text-right flex-1 text-14"
placeholder="请输入图形验证码"
/>
<image :src="codeUrl" class="ml-10 w-80 h-30" @click="handleGetCode" />
</view>
</view>
<view
class="mt-50 text-center py-12 rounded-full mx-15 text-15 text-white btn-gradient"
@click="handleRegister"
@click="handleUpdatePassword"
>
确认
</view>
@@ -85,23 +96,84 @@
<script lang="ts" setup>
import NavBar from '@/components/NavBar.vue'
import { isLogged } from '@/interceptors/route'
import { isLogged, loginRoute } from '@/interceptors/route'
import { getCodeAPI, updateUserAPI } from '@/service'
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
const form = ref({
member_username: '',
member_password: '',
confirm_member_password: '',
verify_code: '',
old_password: '',
})
let redirect = '/'
onLoad((options) => {
redirect = options.redirect ?? '/'
})
const handleRegister = () => {
userStore.setUserInfo({
token: '123456',
const { codeUrl, refreshCode: handleGetCode } = useCaptcha()
onLoad(async () => {
if (isLogged()) {
uni.reLaunch({
url: redirect,
})
}
})
const handleUpdatePassword = async () => {
if (!form.value.member_username) {
uni.showToast({
title: '请输入用户名',
icon: 'none',
})
return
}
if (!form.value.old_password) {
uni.showToast({
title: '请输入旧登录密码',
icon: 'none',
})
return
}
if (!form.value.member_password) {
uni.showToast({
title: '请输入新登录密码',
icon: 'none',
})
return
}
if (form.value.member_password !== form.value.confirm_member_password) {
uni.showToast({
title: '两次输入的密码不一致',
icon: 'none',
})
return
}
if (!form.value.verify_code) {
uni.showToast({
title: '请输入图形验证码',
icon: 'none',
})
return
}
// userStore.setUserInfo({
// token: '123456',
// })
await updateUserAPI(form.value)
uni.showToast({
title: '修改密码成功',
icon: 'none',
})
uni.reLaunch({
url: redirect,
uni.redirectTo({
url: loginRoute,
})
// uni.reLaunch({
// url: redirect,
// })
}
onLoad(() => {
if (isLogged()) {
+30 -11
View File
@@ -1,5 +1,5 @@
<!-- 使用 type="home" 属性设置首页其他页面不需要设置默认为page推荐使用json5更强大且允许注释 -->
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationStyle: 'custom',
@@ -10,23 +10,23 @@
<template>
<view class="house-page">
<NavBar />
<view class="p-15">
<view class="text-16 pl-15">黄埔区</view>
<view class="p-15" v-for="cityItem in cityList" :key="cityItem.id">
<view class="text-16 pl-15">{{ cityItem.region }}</view>
<view class="mt-15 bg-white p-15 rounded-10 grid grid-cols-2 gap-15">
<view v-for="item in 10" :key="item">
<image class="w-150 h-170" src="@/static/images/house/1.png" mode="aspectFill" />
<view class="flex items-center justify-between py-10 px-10">
<view v-for="houseItem in cityItem.house_list" :key="houseItem.id">
<image class="w-150 h-170" :src="houseItem.house_image" mode="aspectFill" />
<view class="flex items-center justify-between py-10">
<view
class="text-14 bg-[linear-gradient(to_right,#3B81F3,#37E6EC)] text-transparent"
style="background-clip: text"
>
70
{{ houseItem.size }}
</view>
<view class="text-12 text-#999">认购点3</view>
<view class="text-12 text-#999">认购点{{ houseItem.buy_price }}</view>
</view>
<view
class="text-12 text-center bg-[linear-gradient(to_right,#3B81F3,#37E6EC)] text-white py-8 rounded-full"
@click="handleClick(item)"
@click="handleClick(houseItem)"
>
领取
</view>
@@ -38,14 +38,33 @@
<script lang="ts" setup>
import NavBar from '@/components/NavBar.vue'
import { buyHouseAPI, getHouseListAPI } from '@/service'
import { useUserStore } from '@/store'
import { showModal } from '@/utils'
defineOptions({
name: 'Home',
})
const handleClick = (item: number) => {
alert('领取成功')
const userStore = useUserStore()
const handleClick = async (item: any) => {
await showModal('确认领取?')
await buyHouseAPI({
house_id: item.id,
})
await userStore.loadUserInfo()
uni.showToast({
title: '领取成功',
icon: 'none',
})
}
const cityList = ref<any[]>([])
onMounted(async () => {
const res = await getHouseListAPI()
cityList.value = res.data.list
})
</script>
<style>
+55 -18
View File
@@ -10,11 +10,16 @@
<template>
<view class="home-page">
<NavBar />
<image
class="mx-auto block w-345 h-170 mt-15 rounded-10 overflow-hidden"
src="@/static/images/home/main-bg.png"
mode="aspectFill"
/>
<wd-swiper
v-if="bannerList.length"
class="w-345 bg-#ffffff30 mx-auto mt-15 rounded-10 overflow-hidden"
height="min(45.333vw, 272px)"
value-key="swipe_image"
:list="bannerList"
autoplay
@click="handleClick"
></wd-swiper>
<view class="flex bg-white py-15 rounded-10 m-15">
<view class="flex-1 flex flex-col items-center" @click="handleIntroduction">
<image class="w-30 h-30" src="@/static/images/home/nav-1.png" mode="aspectFill" />
@@ -30,20 +35,29 @@
</view>
</view>
<view class="bg-white py-15 px-15 rounded-10 m-15">
<view class="bg-white py-15 px-15 rounded-10 m-15" v-if="newsList.length">
<view class="text-14 text-#333">热点新闻</view>
<view class="mt-15">
<image class="w-323 h-160" src="@/static/images/home/news-1.png" mode="aspectFill" />
<view class="text-14 text-#000 mt-8">
#人海战术#签约!中央广播电视总台与农业农村部达成战略合作
</view>
</view>
<view class="flex mt-15" v-for="item in 10" :key="item">
<image class="w-85 h-85" src="@/static/images/home/news-2.png" mode="aspectFill" />
<view class="ml-15 flex-1 flex flex-col justify-between">
<view text-14>#人海战术#签约!中央广播电视总台与农业农村部达成战略合作</view>
<view class="text-12 text-#999">证券时报网</view>
</view>
<view
class="flex mt-15"
v-for="(item, index) in newsList"
:key="item"
@click="handleNewsDetail(item)"
>
<template v-if="index === 0">
<view>
<image class="w-323 h-160" :src="item.cover_image" mode="aspectFill" />
<view class="text-14 text-#000 mt-8">
{{ item.title }}
</view>
</view>
</template>
<template v-else>
<image class="w-85 h-85" :src="item.cover_image" mode="aspectFill" />
<view class="ml-10 flex-1 flex flex-col justify-between">
<view text-14>{{ item.title }}</view>
<view class="text-12 text-#999">{{ item.auther }}</view>
</view>
</template>
</view>
</view>
</view>
@@ -51,6 +65,8 @@
<script lang="ts" setup>
import NavBar from '@/components/NavBar.vue'
import { useListPageRequest } from '@/hooks/useListPageRequest'
import { getBannerListAPI, getNewsListAPI } from '@/service'
defineOptions({
name: 'Home',
@@ -73,6 +89,27 @@ const handleOfficialCommunity = () => {
url: '/pages-sub/official-community/index',
})
}
const handleClick = (item) => {
console.log(item)
}
const bannerList = ref<any[]>([])
const { list: newsList } = useListPageRequest(getNewsListAPI)
const handleNewsDetail = (item) => {
uni.navigateTo({
url: `/pages-sub/news-detail/index?id=${item.id}`,
})
}
onLoad(async () => {
getBannerListAPI().then((res) => {
bannerList.value = res.data.map((item) => ({
...item,
type: 'image',
}))
})
})
</script>
<style>
+32 -16
View File
@@ -1,5 +1,5 @@
<!-- 使用 type="home" 属性设置首页其他页面不需要设置默认为page推荐使用json5更强大且允许注释 -->
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationStyle: 'custom',
@@ -18,36 +18,40 @@
class="flex shadow-[0_1px_4px_rgba(255,255,255,0.8)] mt-100 pt-12 pb-8 flex-col mx-15 rounded-10 items-center bg-[linear-gradient(180deg,rgba(212,232,255,1),rgba(229,239,249,0.8))]"
>
<view class="text-15 text-#486CCF">我的投资金</view>
<view class="text-30 text-#333 font-bold">1000000</view>
<view class="text-30 text-#333 font-bold">{{ userStore.userInfo.member_investment }}</view>
</view>
<view class="mt-60">
<view
v-for="item in 10"
:key="item"
v-for="item in fundList"
:key="item.id"
class="invest-item relative flex flex-col items-center pt-15"
>
<view class="text-15 text-#3F88F6">5G通讯</view>
<view class="text-15 text-#3F88F6">{{ item.fund_name }}</view>
<view class="flex w-full mt-15">
<view class="flex-1 text-center">
<view class="text-22 text-#333 font-bold">1000.00</view>
<view class="text-22 text-#333 font-bold">{{ item.buy_price }}</view>
<view class="text-12 mt-4 text-#3B81F3">投资金额</view>
</view>
<view class="flex-1 text-center">
<view class="text-22 text-#FF3B30 font-bold">1000.00</view>
<view class="text-22 text-#FF3B30 font-bold">{{ item.day_income }}</view>
<view class="text-12 mt-4 text-#3B81F3">每日分红</view>
</view>
</view>
<view
class="text-center px-50 absolute bottom-0 left-0 text-12 text-#fff rounded-full py-8 bg-[linear-gradient(45deg,rgba(59,129,243,1),rgba(55,230,236,1))]"
class="text-center px-50 absolute bottom-0 left-0 text-12 text-#fff rounded-full py-8 bg-[linear-gradient(80deg,rgba(59,129,243,1),rgba(55,230,236,1))]"
@click="onInvest(item)"
>
立即投资
</view>
<view
class="text-center px-16 absolute bottom-13 right-33 text-12 text-#fff rounded-br-10 rounded-tl-10 py-4 bg-[linear-gradient(45deg,rgba(59,129,243,1),rgba(55,230,236,1))]"
class="text-center px-16 absolute bottom-13 right-33 text-12 text-#fff rounded-br-10 rounded-tl-10 py-4 bg-[linear-gradient(80deg,rgba(59,129,243,1),rgba(55,230,236,1))]"
:class="{
'!bg-[linear-gradient(80deg,#E2AF74,#FFCC40)]': item.is_ai,
'!text-#9B6F33': item.is_ai,
}"
>
新手体验
{{ item.is_ai ? '会员产品' : '新手体验' }}
</view>
</view>
</view>
@@ -60,10 +64,16 @@ import NavBar from '@/components/NavBar.vue'
import AlipayIcon from '@/static/images/invest/alipay-icon.png'
import WechatIcon from '@/static/images/invest/wechat-icon.png'
import UnionpayIcon from '@/static/images/invest/unionpay-icon.png'
import { buyFundAPI, getFundListAPI } from '@/service'
import { useUserStore } from '@/store'
import { mergeStep, showModal } from '@/utils'
defineOptions({
name: 'Home',
})
const userStore = useUserStore()
const showPayType = ref(false)
const panels = ref([
{
@@ -91,12 +101,18 @@ const onSelectPayType = ({ item, index }: any) => {
alert(item.title)
}
const onInvest = (item: any) => {
// uni.navigateTo({
// url: '/pages-sub/invest-immediately/index',
// })
showPayType.value = true
}
const onInvest = mergeStep(async (item: any) => {
await showModal('确认投资?')
await buyFundAPI({
fund_id: item.id,
})
await userStore.loadUserInfo()
uni.showToast({
title: '投资成功',
icon: 'none',
})
})
const { list: fundList } = useListPageRequest(getFundListAPI)
</script>
<style>
+24 -10
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '登录',
@@ -22,26 +22,28 @@
<image class="w-24 h-24" src="@/static/images/login/phone.png" mode="aspectFit" />
<input
type="text"
v-model="formData.member_username"
placeholder-class="text-#889BC6"
class="text-right flex-1 text-14"
placeholder="请输入手机号"
placeholder="请输入用户名"
/>
</view>
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/password.png" mode="aspectFit" />
<input
placeholder-class="text-#889BC6"
type="text"
type="password"
v-model="formData.member_password"
class="text-right flex-1 text-14"
placeholder="请输入登录密码"
/>
</view>
</view>
<view class="ml-auto mr-0 w-fit text-#04A9F9 text-14 p-15" @click="handleEditPassword">
<!-- <view class="ml-auto mr-0 w-fit text-#04A9F9 text-14 p-15" @click="handleEditPassword">
忘记密码
</view>
</view> -->
<view
class="mt-30 text-center py-12 rounded-full mx-15 text-15 text-white bg-[linear-gradient(45deg,rgba(59,129,243,0.5),rgba(55,230,236,0.51))]"
class="mt-30 text-center py-12 rounded-full mx-15 text-15 text-white btn-gradient"
@click="handleLogin"
>
登录
@@ -58,19 +60,31 @@
<script lang="ts" setup>
import NavBar from '@/components/NavBar.vue'
import { isLogged } from '@/interceptors/route'
import { loginAPI } from '@/service'
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
const formData = ref({
member_username: '',
member_password: '',
})
let redirect = '/'
onLoad((options) => {
redirect = options.redirect ?? '/'
})
const handleLogin = () => {
userStore.setUserInfo({
token: '123456',
})
const handleLogin = async () => {
if (!formData.value.member_username || !formData.value.member_password) {
return uni.showToast({
title: '请输入用户名和密码',
icon: 'none',
})
}
const {
data: { token },
} = await loginAPI(formData.value)
userStore.setToken(token)
uni.reLaunch({
url: redirect,
})
+1 -1
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
layout: 'demo',
style: {
+52 -16
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationStyle: 'custom',
@@ -11,17 +11,21 @@
<view class="my-page">
<NavBar />
<view class="flex flex-col items-center justify-center mt-30">
<Avatar class="w-80 h-80 mx-auto" />
<view class="text-16 mt-10">默认用户</view>
<view class="text-12 mt-8">手机号199****654</view>
<Avatar
class="w-80 h-80 mx-auto"
:src="userStore.userInfo?.member_portrait"
@click="uploadAvatar"
/>
<view class="text-16 mt-10">{{ userStore.userInfo?.member_username }}</view>
<!-- <view class="text-12 mt-8">账号{{ userStore.userInfo?.member_username }}</view> -->
</view>
<view class="flex justify-center text-center mt-15">
<view class="">
<view class="text-30 font-bold">1002</view>
<view class="text-30 font-bold">{{ userStore.userInfo?.member_dividend }}</view>
<view class="text-14 mt-10 text-#3B81F3">我的分红</view>
</view>
<view class="ml-30">
<view class="text-30 font-bold">1231.23</view>
<view class="text-30 font-bold">{{ userStore.userInfo?.member_currency }}</view>
<view class="text-14 mt-10 text-#3B81F3">数字人民币</view>
</view>
</view>
@@ -38,15 +42,26 @@
提现
</view>
</view>
<view
<!-- <view
class="ml-10 flex py-30 justify-center items-center rounded-tl-10 rounded-br-10 flex-1 bg-[linear-gradient(180deg,#D9EBFF,#9EDAFF)] border-1 border-#5FAEFF80 border-solid"
@click="handleWithdrawalDetail"
@click="handleWithdrawalRecord"
>
<image class="w-40 h-40" src="@/static/images/my/top-up.png" mode="aspectFit" />
<view
class="text-white text-14 px-15 py-5 ml-15 rounded-full bg-[linear-gradient(45deg,#3B81F3_0%,#37E6EC_100%)]"
>
提现明细
提现记录
</view>
</view> -->
<view
class="ml-10 flex py-30 justify-center items-center rounded-tl-10 rounded-br-10 flex-1 bg-[linear-gradient(180deg,#D9EBFF,#9EDAFF)] border-1 border-#5FAEFF80 border-solid"
@click="handleRecharge"
>
<image class="w-40 h-40" src="@/static/images/my/top-up.png" mode="aspectFit" />
<view
class="text-white text-14 px-15 py-5 ml-15 rounded-full bg-[linear-gradient(45deg,#3B81F3_0%,#37E6EC_100%)]"
>
充值
</view>
</view>
</view>
@@ -55,7 +70,7 @@
class="w-330 h-123 mx-auto mt-15 block"
src="@/static/images/my/recommend.png"
mode="aspectFill"
@click="handleInvite"
@click="handlePurchaseMember"
/>
<view class="mt-15 grid grid-cols-2 gap-10 p-15">
@@ -103,19 +118,21 @@
import Avatar from '@/components/Avatar.vue'
import NavBar from '@/components/NavBar.vue'
import { loginRoute } from '@/interceptors/route'
import { logoutAPI, updateUserAPI } from '@/service'
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
const handleLogout = () => {
userStore.clearUserInfo()
const handleLogout = async () => {
logoutAPI()
userStore.logout()
uni.reLaunch({
url: loginRoute,
})
}
const handleWithdrawalDetail = () => {
const handleRecharge = () => {
uni.navigateTo({
url: '/pages-sub/withdrawal-detail/index',
url: '/pages-sub/recharge/index',
})
}
@@ -149,11 +166,30 @@ const handleBankCard = () => {
})
}
const handleInvite = () => {
const handlePurchaseMember = () => {
uni.navigateTo({
url: '/pages-sub/invite/index',
url: '/pages-sub/purchase-member/index',
})
}
const handleWithdrawalRecord = () => {
uni.navigateTo({
url: '/pages-sub/withdrawal-detail/index',
})
}
const { data, run } = useUpload<any>()
const uploadAvatar = () => {
run()
}
watch(data, async (newVal) => {
const path = JSON.parse(newVal)?.data?.path
await updateUserAPI({
member_portrait: path,
})
userStore.loadUserInfo()
})
</script>
<style lang="scss" scoped>
+93 -23
View File
@@ -1,4 +1,4 @@
<route lang="json5">
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '注册',
@@ -15,30 +15,17 @@
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/phone.png" mode="aspectFit" />
<input
v-model="form.member_username"
type="text"
placeholder-class="text-#889BC6"
class="text-right flex-1 text-14"
placeholder="请输入手机号"
placeholder="请输入用户名"
/>
</view>
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/message.png" mode="aspectFit" />
<input
type="text"
placeholder-class="text-#889BC6"
class="text-right flex-1 text-14"
placeholder="请输入短信验证码"
/>
<view
class="py-6 rounded-full ml-15 px-15 text-12 text-white btn-gradient text-14 text-#889BC6"
@click="handleGetCode"
>
获取验证码
</view>
</view>
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/password.png" mode="aspectFit" />
<input
v-model="form.member_password"
placeholder-class="text-#889BC6"
type="password"
class="text-right flex-1 text-14"
@@ -48,6 +35,7 @@
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/password.png" mode="aspectFit" />
<input
v-model="form.confirm_member_password"
placeholder-class="text-#889BC6"
type="password"
class="text-right flex-1 text-14"
@@ -57,6 +45,7 @@
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/password.png" mode="aspectFit" />
<input
v-model="form.pay_password"
placeholder-class="text-#889BC6"
type="password"
class="text-right flex-1 text-14"
@@ -66,6 +55,7 @@
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/password.png" mode="aspectFit" />
<input
v-model="form.confirm_pay_password"
placeholder-class="text-#889BC6"
type="password"
class="text-right flex-1 text-14"
@@ -75,12 +65,24 @@
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/invite.png" mode="aspectFit" />
<input
v-model="form.invitation_code"
placeholder-class="text-#889BC6"
type="password"
type="text"
class="text-right flex-1 text-14"
placeholder="请输入邀请码"
/>
</view>
<view class="flex items-center py-15">
<image class="w-24 h-24" src="@/static/images/login/message.png" mode="aspectFit" />
<input
v-model="form.verify_code"
type="text"
placeholder-class="text-#889BC6"
class="text-right flex-1 text-14"
placeholder="请输入图形验证码"
/>
<image :src="codeUrl" class="ml-10 w-80 h-30" @click="handleGetCode" />
</view>
</view>
<view
class="mt-50 text-center py-12 rounded-full mx-15 text-15 text-white btn-gradient"
@@ -95,29 +97,97 @@
<script lang="ts" setup>
import NavBar from '@/components/NavBar.vue'
import { isLogged } from '@/interceptors/route'
import { registerAPI } from '@/service'
import { useUserStore } from '@/store/user'
import { mergeStep } from '@/utils'
const userStore = useUserStore()
const form = ref({
member_username: '',
// member_nickname: '',
member_password: '',
confirm_member_password: '',
verify_code: '',
invitation_code: '',
pay_password: '',
confirm_pay_password: '',
})
let redirect = '/'
onLoad((options) => {
redirect = options.redirect ?? '/'
form.value.invitation_code = options.invitation_code ?? ''
})
const handleRegister = () => {
userStore.setUserInfo({
token: '123456',
const handleRegister = mergeStep(async () => {
if (!form.value.member_username) {
uni.showToast({
title: '请输入用户名',
icon: 'none',
})
return
}
if (!form.value.verify_code) {
uni.showToast({
title: '请输入图形验证码',
icon: 'none',
})
return
}
if (!form.value.member_password) {
uni.showToast({
title: '请输入登录密码',
icon: 'none',
})
return
}
if (form.value.member_password !== form.value.confirm_member_password) {
uni.showToast({
title: '两次输入的密码不一致',
icon: 'none',
})
return
}
if (!form.value.pay_password) {
uni.showToast({
title: '请输入支付密码',
icon: 'none',
})
return
}
if (form.value.pay_password !== form.value.confirm_pay_password) {
uni.showToast({
title: '两次输入的支付密码不一致',
icon: 'none',
})
return
}
// if (!form.value.invitation_code) {
// uni.showToast({
// title: '请输入邀请码',
// icon: 'none',
// })
// return
// }
const {
data: { token },
} = await registerAPI(form.value).catch(() => {
handleGetCode()
throw new Error('注册失败')
})
userStore.setToken(token)
uni.reLaunch({
url: redirect,
})
}
onLoad(() => {
})
const { codeUrl, refreshCode: handleGetCode } = useCaptcha()
onLoad(async (options) => {
if (isLogged()) {
uni.reLaunch({
url: redirect,
})
}
form.value.invitation_code = options.invite ?? ''
})
</script>
+134
View File
@@ -0,0 +1,134 @@
import { http } from '@/utils/http'
/** 账号登录 */
export const loginAPI = (data) => {
return http.post<{ token: string }>('/api/v1/LoginUser', data)
}
/** 修改密码 */
export const updateUserAPI = (data) => {
return http.post('/api/v1/UpgradeUser', data)
}
/** 注册账号 */
export const registerAPI = (data) => {
return http.post<{ token: string }>('/api/v1/RegisterUser', data)
}
/** 用户信息 */
export const getUserInfoAPI = () => {
return http.post<IUserInfo>('/api/v1/getUserInfo')
}
/** 退出登录 */
export const logoutAPI = () => {
return http.post('/api/v1/Logiout')
}
/** 实名认证 */
export const createAuthUser = (data) => {
return http.post('/api/v1/CreateAuthUser', data)
}
/** 轮播列表 */
export const getBannerListAPI = () => {
return http.post<any[]>('/api/v1/getSwipeList')
}
/** 新闻列表 */
export const getNewsListAPI = (data) => {
return http.post<any[]>('/api/v1/getNewsList', data)
}
/** 新闻详情 */
export const getNewsDetailAPI = (data) => {
return http.post<any>('/api/v1/getNewsDetail', data, data)
}
/** 公司简介 */
export const getCompanyInfoAPI = () => {
return http.post<any>('/api/v1/getCompanyProfile')
}
/** 基金列表 */
export const getFundListAPI = () => {
return http.post<any[]>('/api/v1/getFundList')
}
/** 购买基金 */
export const buyFundAPI = (data) => {
return http.post('/api/v1/buyFundOrder', data)
}
/** 购买基金订单列表 */
export const getBuyFundOrderListAPI = (data) => {
return http.post<any[]>('/api/v1/getFundOrderList', data)
}
/** 房屋列表 */
export const getHouseListAPI = () => {
return http.post<{ list: any[] }>('/api/v1/getHouseList')
}
/** 购买房屋 */
export const buyHouseAPI = (data) => {
return http.post('/api/v1/buyHouseOrder', data)
}
/** VIP列表 */
export const getVipListAPI = () => {
return http.post<{ list: any[] }>('/api/v1/getVipList')
}
/** 购买VIP */
export const buyVIPAPI = (data) => {
return http.post('/api/v1/buyFundOrder', data)
}
/** 我的团队 */
export const getMyTeamAPI = (data) => {
return http.post<{ list: any[] }>('/api/v1/getMyTeam', data)
}
/** 绑定收款卡号 */
export const bindBankCardAPI = (data) => {
return http.post('/api/v1/CreateCardUser', data)
}
/** 删除收款卡号 */
export const deleteBankCardAPI = (data) => {
return http.post('/api/v1/CannelUserCard', data)
}
/** 获取银行卡列表 */
export const getBankCardListAPI = (data) => {
return http.post<{ list: any[] }>('/api/v1/getCardList', data)
}
/** 申请提现 */
export const applyWithdrawalAPI = (data) => {
return http.post('/api/v1/CreateWithdrawal', data)
}
/** 提现记录 */
export const getWithdrawalRecordAPI = (data) => {
return http.post<{ list: any[] }>('/api/v1/WithdrawalOrder', data)
}
/** 余额明细 */
export const getBalanceRecordsAPI = (data) => {
return http.post<{ list: any[] }>('/api/v1/getBalanceRecords', data)
}
/** 系统充收款账号列表 */
export const getSystemRechargeAccountAPI = (data) => {
return http.post<{ list: any[] }>('/api/v1/getWalletList', data)
}
/** 充值 */
export const rechargeAPI = (data) => {
return http.post('/api/v1/CreateRechangeOrder', data)
}
/** 充值记录 */
export const getRechargeRecordAPI = (data) => {
return http.post<{ list: any[] }>('/api/v1/getRechangeOrder', data)
}
-15
View File
@@ -1,15 +0,0 @@
import { http } from '@/utils/http'
export interface IFooItem {
id: string
name: string
}
/** GET 请求 */
export const getFooAPI = (name: string) => {
return http.get<IFooItem>('/foo', { name })
}
/** POST 请求 */
export const postFooAPI = (name: string) => {
return http.post<IFooItem>('/foo', { name }, { name })
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

+27 -7
View File
@@ -1,28 +1,48 @@
import { getUserInfoAPI } from '@/service'
import { mergeStep } from '@/utils'
import { defineStore } from 'pinia'
import { ref } from 'vue'
const initState = { nickname: '', avatar: '' }
export const useUserStore = defineStore(
'user',
() => {
const userInfo = ref<IUserInfo>({ ...initState })
const userInfo = ref<IUserInfo | null>(null)
const token = ref('')
const loadUserInfo = mergeStep(async () => {
const res = await getUserInfoAPI()
userInfo.value = res.data
})
const setUserInfo = (val: IUserInfo) => {
userInfo.value = val
}
const clearUserInfo = () => {
userInfo.value = { ...initState }
const setToken = (val: string) => {
token.value = val
}
const isLogged = computed(() => !!userInfo.value.token)
const clearUserInfo = () => {
userInfo.value = null
}
const clearToken = () => {
token.value = ''
}
const logout = () => {
clearUserInfo()
clearToken()
}
const isLogged = computed(() => !!token.value)
return {
userInfo,
loadUserInfo,
setUserInfo,
clearUserInfo,
isLogged,
setToken,
token,
logout,
}
},
{
+4
View File
@@ -75,9 +75,11 @@ declare global {
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCaptcha: typeof import('../hooks/useCaptcha')['useCaptcha']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useId: typeof import('vue')['useId']
const useListPageRequest: typeof import('../hooks/useListPageRequest')['useListPageRequest']
const useModel: typeof import('vue')['useModel']
const useNavbarWeixin: (typeof import('../hooks/useNavbarWeixin'))['default']
const useRequest: typeof import('../hooks/useRequest')['default']
@@ -171,9 +173,11 @@ declare module 'vue' {
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly unref: UnwrapRef<typeof import('vue')['unref']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useCaptcha: UnwrapRef<typeof import('../hooks/useCaptcha')['useCaptcha']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useId: UnwrapRef<typeof import('vue')['useId']>
readonly useListPageRequest: UnwrapRef<typeof import('../hooks/useListPageRequest')['useListPageRequest']>
readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
readonly useRequest: UnwrapRef<typeof import('../hooks/useRequest')['default']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
+4
View File
@@ -18,8 +18,12 @@ interface NavigateToOptions {
"/pages-sub/invest-immediately/index" |
"/pages-sub/invest-result/index" |
"/pages-sub/invite/index" |
"/pages-sub/news-detail/index" |
"/pages-sub/official-community/index" |
"/pages-sub/purchase-member/index" |
"/pages-sub/realname/index" |
"/pages-sub/recharge/index" |
"/pages-sub/recharge-detail/index" |
"/pages-sub/team/index" |
"/pages-sub/withdrawal/index" |
"/pages-sub/withdrawal-detail/index" |
+25 -6
View File
@@ -2,7 +2,7 @@
type IResData<T> = {
code: number
msg: string
message: string
data: T
}
@@ -16,11 +16,30 @@ type IUniUploadFileOptions = {
}
type IUserInfo = {
nickname?: string
avatar?: string
/** 微信的 openid,非微信没有这个字段 */
openid?: string
token?: string
/** 用户ID */
member_id: string
/** 用户名 */
member_username: string
/** 余额 */
member_balance: string
/** 数字人民币 */
member_currency: string
/** 分红 */
member_dividend: string
/** 认购点 */
member_point: string
/** 投资金 */
member_investment: string
/** 头像地址 */
member_portrait: string
/** 用户昵称 */
member_nickname: string
/** 余额状态 1开启 0冻结 */
balance_status: string
/** 是否实名认证 1是 0否 2审核中 */
member_certification: number
/** 邀请码 */
invitation_code: string
}
enum TestEnum {
+39 -7
View File
@@ -1,4 +1,6 @@
import { CustomRequestOptions } from '@/interceptors/request'
import { loginRoute } from '@/interceptors/route'
import { useUserStore } from '@/store'
export const http = <T>(options: CustomRequestOptions) => {
// 1. 返回 Promise 对象
@@ -10,11 +12,40 @@ export const http = <T>(options: CustomRequestOptions) => {
responseType: 'json',
// #endif
// 响应成功
success(res) {
async success(res) {
// 状态码 2xx,参考 axios 的设计
if (res.statusCode >= 200 && res.statusCode < 300) {
// 2.1 提取核心数据 res.data
resolve(res.data as IResData<T>)
if (res.header['content-type'].includes('application/json')) {
// 2.1 提取核心数据 res.data
const data = res.data as IResData<T>
if (data.code === 200) {
resolve(data as IResData<T>)
} else if (data.code === 401) {
const userStore = useUserStore()
userStore.logout()
!options.hideErrorToast &&
(await uni.showModal({
title: '提示',
content: data.message || '请求错误',
showCancel: false,
}))
uni.reLaunch({
url: loginRoute,
})
reject(res)
} else {
!options.hideErrorToast &&
(await uni.showModal({
title: '提示',
content: data.message || '请求错误',
showCancel: false,
}))
reject(res)
}
} else {
resolve(res.data as any)
}
} else if (res.statusCode === 401) {
// 401错误 -> 清理用户信息,跳转到登录页
// userStore.clearUserInfo()
@@ -23,10 +54,11 @@ export const http = <T>(options: CustomRequestOptions) => {
} else {
// 其他错误 -> 根据后端错误信息轻提示
!options.hideErrorToast &&
uni.showToast({
icon: 'none',
title: (res.data as IResData<T>).msg || '请求错误',
})
(await uni.showModal({
title: '提示',
content: (res.data as IResData<T>).message || '请求错误',
showCancel: false,
}))
reject(res)
}
},
+32 -20
View File
@@ -1,5 +1,6 @@
import { pages, subPackages, tabBar } from '@/pages.json'
import { isMp } from './platform'
import dayjs from 'dayjs'
export const getLastPage = () => {
// getCurrentPages() 至少有1个元素,所以不再额外判断
@@ -128,26 +129,7 @@ export const notNeedLoginPages: string[] = getAllPages('notNeedLogin').map((page
*/
export const getEnvBaseUrl = () => {
// 请求基准地址
let baseUrl = import.meta.env.VITE_SERVER_BASEURL
// 小程序端环境区分
if (isMp) {
const {
miniProgram: { envVersion },
} = uni.getAccountInfoSync()
switch (envVersion) {
case 'develop':
baseUrl = 'https://ukw0y1.laf.run'
break
case 'trial':
baseUrl = 'https://ukw0y1.laf.run'
break
case 'release':
baseUrl = 'https://ukw0y1.laf.run'
break
}
}
const baseUrl = import.meta.env.VITE_SERVER_BASEURL
return baseUrl
}
@@ -158,6 +140,9 @@ export const getEnvBaseUrl = () => {
export const getEnvBaseUploadUrl = () => {
// 请求基准地址
let baseUploadUrl = import.meta.env.VITE_UPLOAD_BASEURL
if (JSON.parse(__VITE_APP_PROXY__)) {
baseUploadUrl = `${import.meta.env.VITE_APP_PROXY_PREFIX}/${baseUploadUrl.split(import.meta.env.VITE_APP_PROXY_PREFIX + '/')[1]}`
}
// 小程序端环境区分
if (isMp) {
@@ -207,3 +192,30 @@ export function mergeStep(wrapped: (...rest: any[]) => Promise<any>) {
return _mergeStepRequestInstance
}
}
// Promise 版modal
export const showModal = (
content: string,
{ showCancel, title, ...options }: UniApp.ShowModalOptions = {},
) => {
return new Promise((resolve, reject) =>
uni.showModal({
showCancel: showCancel === true,
title: title || '提示',
...options,
content,
success(e) {
if (e.confirm) {
return resolve(e)
}
reject(e)
},
fail: reject,
}),
)
}
/** 格式化时间 */
export const formatTime = (time: string | number) => {
return dayjs(time).format('YYYY-MM-DD HH:mm:ss')
}
+1 -1
View File
@@ -141,7 +141,7 @@ export default ({ command, mode }) => {
[VITE_APP_PROXY_PREFIX]: {
target: VITE_SERVER_BASEURL,
changeOrigin: true,
rewrite: (path) => path.replace(new RegExp(`^${VITE_APP_PROXY_PREFIX}`), ''),
rewrite: (path) => path.replace(new RegExp(`^${VITE_APP_PROXY_PREFIX}`), 'api'),
},
}
: undefined,