更新:游客模式、我的湖分、我的证书
This commit is contained in:
34
App.vue
34
App.vue
@@ -1,10 +1,33 @@
|
||||
<script>
|
||||
// #ifdef APP-PLUS
|
||||
import update from "@/uni_modules/uni-upgrade-center-app/utils/check-update";
|
||||
|
||||
// #endif
|
||||
import { useUserStore } from '@/stores/user'
|
||||
export default {
|
||||
onLaunch: function() {
|
||||
const userStore = useUserStore()
|
||||
console.log('App Launch')
|
||||
// 保存原生 switchTab 方法
|
||||
const originalSwitchTab = uni.switchTab;
|
||||
uni.switchTab = (options) => {
|
||||
if (options.url.includes('/pages/book/index') && !userStore.token) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请先登录后访问该页面',
|
||||
confirmText: '去登录',
|
||||
success: (res) => {
|
||||
console.log(res, 'res');
|
||||
if (res.confirm) uni.navigateTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
});
|
||||
return; // 拦截跳转
|
||||
}
|
||||
// 已登录/非拦截页 → 执行原生跳转
|
||||
originalSwitchTab.call(uni, options);
|
||||
}
|
||||
// 检测自动更新
|
||||
// #ifdef APP-PLUS
|
||||
update();
|
||||
@@ -15,15 +38,18 @@
|
||||
},
|
||||
onHide: function() {
|
||||
console.log('App Hide')
|
||||
},
|
||||
onTabItemTap: function() {
|
||||
console.log('点击了');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/style/tailwind.css";
|
||||
@import "@/style/ui.scss";
|
||||
@import "@/style/tailwind.css";
|
||||
@import "@/style/ui.scss";
|
||||
|
||||
.container {
|
||||
.container {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -7,8 +7,8 @@ export const ENV = process.env.NODE_ENV || 'development';
|
||||
*/
|
||||
const BASE_URL_MAP = {
|
||||
development: {
|
||||
// MAIN: 'http://192.168.110.100:9300/pb/', // 张川川
|
||||
MAIN: 'https://global.nuttyreading.com/', // 线上
|
||||
MAIN: 'http://192.168.110.100:9300/pb/', // 张川川
|
||||
//MAIN: 'https://global.nuttyreading.com/', // 线上
|
||||
// PAYMENT: 'https://dev-pay.example.com', // 暂时用不到
|
||||
// CDN: 'https://cdn-dev.example.com', // 暂时用不到
|
||||
},
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
import { mainClient } from '@/api/clients/main'
|
||||
import type { IApiResponse } from '@/api/types'
|
||||
import type { IAgreement } from '@/types/user'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
|
||||
|
||||
export const commonApi = {
|
||||
/**
|
||||
@@ -36,8 +39,9 @@ export const commonApi = {
|
||||
* @returns 消息列表
|
||||
*/
|
||||
getMessageList(isBook: number, isMedical: number, isSociology: number) {
|
||||
const userStore = useUserStore()
|
||||
return mainClient.request<IMessageListResponse>({
|
||||
url: 'common/message/listByPage',
|
||||
url: userStore.token ? 'common/message/listByPage' : '/visitor/listByPage',
|
||||
method: 'POST',
|
||||
data: { isBook, isMedical, isSociology }
|
||||
})
|
||||
|
||||
@@ -14,6 +14,9 @@ import type {
|
||||
} from '@/types/course'
|
||||
import type { ISearchRequest, ISearchResponse } from '@/types/search'
|
||||
import type { ICommentListResponse, IAddCommentResponse, IComment } from '@/types/comment'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
|
||||
|
||||
const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN })
|
||||
|
||||
@@ -57,8 +60,9 @@ export const courseApi = {
|
||||
page: number,
|
||||
limit: number
|
||||
}) {
|
||||
const userStore = useUserStore()
|
||||
return client.request<IMarketCourseListResponse>({
|
||||
url: 'medical/home/getMarketCourseList',
|
||||
url: userStore.token ? 'medical/home/getMarketCourseList' : 'visitor/getMarketCourseList',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
|
||||
@@ -7,6 +7,8 @@ import type {
|
||||
IMarketCourseListResponse,
|
||||
ICourseMedicalLabelsResponse
|
||||
} from '@/types/course'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
|
||||
const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN })
|
||||
|
||||
@@ -20,8 +22,9 @@ export const courseSubjectClassificationApi = {
|
||||
* @returns 分类数据
|
||||
*/
|
||||
getCourseMedicalTree() {
|
||||
const userStore = useUserStore()
|
||||
return client.request<ICourseCategoryResponse>({
|
||||
url: 'medical/home/getCourseMedicalTree',
|
||||
url: userStore.token ? 'medical/home/getCourseMedicalTree' : '/visitor/getCourseMedicalTree',
|
||||
method: 'POST',
|
||||
data: {}
|
||||
})
|
||||
|
||||
@@ -314,3 +314,31 @@ export async function migrateUserData(data: { tel: string, code: string }) {
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的湖分
|
||||
* @return
|
||||
*/
|
||||
export async function getUserContributionData() {
|
||||
const res = await mainClient.request<IApiResponse>({
|
||||
url: 'common/userContribution/getUserContribution',
|
||||
method: 'POST'
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* 湖分列表
|
||||
* @param current 当前页码
|
||||
* @param limit 每页数量
|
||||
* @param type 湖分类型
|
||||
* @return
|
||||
*/
|
||||
export async function getUserContributionByTypeList(current : number, limit : number, type : string,) {
|
||||
const res = await mainClient.request<IApiResponse>({
|
||||
url: 'common/userContribution/getUserContributionByType',
|
||||
method: 'POST',
|
||||
data: { current, limit, type, }
|
||||
})
|
||||
return res
|
||||
}
|
||||
@@ -227,7 +227,11 @@
|
||||
"instruction2": "After data migration is complete, the chinese account data will be cleared, and all purchased Tianyi Coins, points, courses, E-book, VIP, certificate, and User Contribution will be transferred to the current account",
|
||||
"instruction3": "The migration process may take a few minutes, please be patient.",
|
||||
"instruction4": "If you encounter any issues, please contact customer service for assistance.",
|
||||
"closeWindow": "Close the payment pop-up window"
|
||||
"closeWindow": "Close the payment pop-up window",
|
||||
"certificate": "My certificate",
|
||||
"iHufen": "My lake",
|
||||
"hufenRecord": "Lake division record",
|
||||
"hufen": "Hufen"
|
||||
},
|
||||
"book": {
|
||||
"title": "My Books",
|
||||
|
||||
@@ -228,7 +228,11 @@
|
||||
"instruction2": "数据迁移完成后,旧账号数据将被清空,已购买的天医币、积分、课程、电子书、VIP、证书、湖分将转移到当前账号。",
|
||||
"instruction3": "迁移过程可能需要几分钟时间,请耐心等待。",
|
||||
"instruction4": "如遇到问题,请联系客服获取帮助。",
|
||||
"closeWindow": "关闭支付弹窗"
|
||||
"closeWindow": "关闭支付弹窗",
|
||||
"certificate": "我的证书",
|
||||
"iHufen": "我的湖分",
|
||||
"hufenRecord": "湖分记录",
|
||||
"hufen": "湖分"
|
||||
},
|
||||
"book": {
|
||||
"title": "我的书单",
|
||||
|
||||
23
pages.json
23
pages.json
@@ -67,6 +67,24 @@
|
||||
"navigationBarTitleText": "%user.feedback%",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},{
|
||||
"path": "pages/user/certificate/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "%user.certificate%",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},{
|
||||
"path": "pages/user/hufen/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "%user.hufen%",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},{
|
||||
"path": "pages/user/hufen/forDetails",
|
||||
"style": {
|
||||
"navigationBarTitleText": "%user.hufen%",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/user/recharge/index",
|
||||
"style": {
|
||||
@@ -219,6 +237,11 @@
|
||||
"animationDuration": 200
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"path": "pages/visitor/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tabBar": {
|
||||
|
||||
@@ -211,7 +211,9 @@ import { commonApi } from '@/api/modules/common'
|
||||
import { getNotchHeight } from '@/utils/system'
|
||||
// import { onPageJump } from '@/utils'
|
||||
import type { IMedicalTag, ICourse, INews } from '@/types/course'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const { t } = useI18n()
|
||||
|
||||
// 系统信息
|
||||
@@ -239,6 +241,8 @@ const selectedFirstLevel = ref<number>('医学') // 当前选中的一级分类
|
||||
* 学科点击处理
|
||||
*/
|
||||
const handleFirstLevelClick = (item: string) => {
|
||||
getPrompt()
|
||||
if(!userStore.token) return
|
||||
selectedFirstLevel.value = item
|
||||
switch (item) {
|
||||
case '医学':
|
||||
@@ -251,6 +255,7 @@ const handleFirstLevelClick = (item: string) => {
|
||||
getSociologyCateList()
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 医学
|
||||
@@ -326,6 +331,8 @@ const getSociologyCateList = async () => {
|
||||
* 终极分类点击处理
|
||||
*/
|
||||
const curseClickJump = (item: IMedicalTag) => {
|
||||
getPrompt()
|
||||
if(!userStore.token) return
|
||||
uni.navigateTo({
|
||||
url: `/pages/course/list/category?id=${item.id}&title=${item.title}&pid=${item.pid}&subject=${selectedFirstLevel.value}`
|
||||
})
|
||||
@@ -335,6 +342,8 @@ const curseClickJump = (item: IMedicalTag) => {
|
||||
* 页面跳转统一处理
|
||||
*/
|
||||
const onPageJump = (url: string, id?: number, title?: string) => {
|
||||
getPrompt()
|
||||
if(!userStore.token) return
|
||||
let targetUrl = url
|
||||
if (id !== undefined) {
|
||||
targetUrl += `?id=${id}`
|
||||
@@ -381,9 +390,12 @@ const getNewsList = async () => {
|
||||
* 新闻点击处理
|
||||
*/
|
||||
const newsClick = (item: INews) => {
|
||||
getPrompt()
|
||||
if(!userStore.token) return
|
||||
uni.navigateTo({
|
||||
url: `/pages/news/details?newsId=${item.id}&url=${item.url}&type=${item.type}`
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 精彩试听
|
||||
@@ -406,11 +418,32 @@ const getTryListenList = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录提示语
|
||||
*/
|
||||
const getPrompt = () => {
|
||||
if(!userStore.token) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请先登录后访问该页面',
|
||||
confirmText: '去登录',
|
||||
success: (res) => {
|
||||
console.log(res, 'res');
|
||||
if (res.confirm) uni.navigateTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一请求所有数据
|
||||
*/
|
||||
const requestAll = async () => {
|
||||
if(userStore.token){
|
||||
getLearnCourse()
|
||||
}
|
||||
getMedicalTags()
|
||||
getTryListenList()
|
||||
getNewsList()
|
||||
@@ -420,17 +453,24 @@ const requestAll = async () => {
|
||||
* 页面挂载
|
||||
*/
|
||||
onMounted(() => {
|
||||
if(!userStore.token) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
// 重置分类索引
|
||||
currentIndex.value = 0
|
||||
|
||||
// 请求所有数据
|
||||
requestAll()
|
||||
console.log('进来了2');
|
||||
})
|
||||
|
||||
/**
|
||||
* 页面显示
|
||||
*/
|
||||
onShow(() => {
|
||||
console.log('进来了1');
|
||||
// 检查是否有固定的分类选择状态
|
||||
const fixed = uni.getStorageSync('fixed')
|
||||
if (fixed && currentItem.value) {
|
||||
|
||||
@@ -115,11 +115,11 @@
|
||||
</view>
|
||||
|
||||
<!-- 游客体验 -->
|
||||
<!-- <view class="youke-l">
|
||||
<view @click="onPageJump('/pages/visitor/visitor')">
|
||||
<view class="youke-l">
|
||||
<view @click="onPageJump('/pages/course/index')">
|
||||
{{ $t('login.noLogin') }}
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 用户协议弹窗 -->
|
||||
@@ -399,7 +399,7 @@ const yszc = () => {
|
||||
* 页面跳转
|
||||
*/
|
||||
const onPageJump = (url: string) => {
|
||||
uni.navigateTo({
|
||||
uni.switchTab({
|
||||
url: url,
|
||||
})
|
||||
}
|
||||
|
||||
134
pages/user/certificate/index.vue
Normal file
134
pages/user/certificate/index.vue
Normal file
@@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<view class="certificate-page">
|
||||
<nav-bar :title="$t('user.certificate')"></nav-bar>
|
||||
<view v-if="certificateList.length > 0">
|
||||
<view style="margin: 10rpx;" >【共{{certificateList.length}}个证书】</view>
|
||||
<view class="certificate-list" v-for="(item,index) in certificateList" :key="index">
|
||||
<view class="certificate-list-row">
|
||||
<h3>证书编号:{{item.bh}}</h3>
|
||||
<text style="font-size: 26rpx; color: #999;">获得时间:{{item.time}}</text>
|
||||
</view>
|
||||
<view class="certificate-certificate">
|
||||
<view class="img" v-for="(i,index) in item.certificateUrl" :key="index">
|
||||
<image @click="preveImg(i.url)" :src="i.url" mode="heightFix"></image>
|
||||
</view>
|
||||
<view class="certificate-detailed" @click="detailed(item)">详细信息</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else><wd-divider>您还未获得证书</wd-divider></view>
|
||||
</view>
|
||||
<wd-popup v-model="detailedState" position="bottom" :closeable="true">
|
||||
<view class="detailed">
|
||||
<view class="detailed-text">
|
||||
证书详情
|
||||
</view>
|
||||
<view class="detailed-row">证书类型:<text class="text">{{detailedData.a}}</text></view>
|
||||
<view class="detailed-row">获得时间:<text class="text">{{detailedData.time}}</text></view>
|
||||
<view class="detailed-row">获得途径:<text class="text">{{detailedData.b}}</text></view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
const detailedState = ref(false)
|
||||
const detailedData = ref({})
|
||||
|
||||
// 模拟的 certificateList 数据
|
||||
const certificateList = ref([
|
||||
{ a: 'ZH', b: '吴门', bh: 1, time: '2025-6-20', certificateUrl: "https://ehh-private-01.oss-cn-beijing.aliyuncs.com/certificate/ca2140c3-d212-4d4e-9203-ddc161d50470.jpg,https://ehh-private-01.oss-cn-beijing.aliyuncs.com/certificate/18a7ea22-b75a-4ef6-9109-f448f45e424f.jpg" },
|
||||
{ bh: 2, time: '2025-6-22', certificateUrl: "https://ehh-private-01.oss-cn-beijing.aliyuncs.com/certificate/ca2140c3-d212-4d4e-9203-ddc161d50470.jpg,https://ehh-private-01.oss-cn-beijing.aliyuncs.com/certificate/18a7ea22-b75a-4ef6-9109-f448f45e424f.jpg" }
|
||||
]);
|
||||
|
||||
// 重新获取数据
|
||||
certificateList.value = certificateList.value.map(item => {
|
||||
return { ...item, certificateUrl: item.certificateUrl.split(',').map(url => ({ url })) };
|
||||
});
|
||||
|
||||
/**
|
||||
* 查看证书详情信息
|
||||
*/
|
||||
const detailed = (item) => {
|
||||
detailedState.value = true
|
||||
detailedData.value = item
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看照片
|
||||
*/
|
||||
const preveImg = (url : any) => {
|
||||
uni.previewImage({
|
||||
urls: [url],
|
||||
current: 0
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.certificate-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f7faf9;
|
||||
}
|
||||
|
||||
.certificate-list {
|
||||
background: #fff;
|
||||
border-radius: 15rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
margin: 20rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.certificate-list-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.certificate-certificate {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-top: 20rpx;
|
||||
|
||||
.img {
|
||||
width: 36%;
|
||||
overflow: hidden;
|
||||
height: 300rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.certificate-detailed {
|
||||
color: #55aaff;
|
||||
border: #55aaff 1px solid;
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.detailed {
|
||||
padding: 20rpx;
|
||||
|
||||
.detailed-text {
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.detailed-row {
|
||||
color: #999;
|
||||
margin: 20rpx 0;
|
||||
font-size: 26rpx;
|
||||
|
||||
.text {
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
113
pages/user/hufen/forDetails.vue
Normal file
113
pages/user/hufen/forDetails.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<z-paging ref="paging" v-model="bookList" auto-show-back-to-top class="my-book-page" @query="hufenList"
|
||||
:default-page-size="10">
|
||||
<template #top>
|
||||
<!-- 自定义导航栏 -->
|
||||
<nav-bar :title="$t('user.hufenRecord')"></nav-bar>
|
||||
</template>
|
||||
<view class="recharge-record" v-if="(bookList && bookList.length > 0)">
|
||||
<view class="go-gecharge">{{hufenData.nameValue}} {{$t('user.hufenRecord')}}</view>
|
||||
<view class="recharge-record-block" v-for="(item, index) in bookList" :key="index">
|
||||
<view class="recharge-record-block-row">{{item.createTime}}<text class="text">{{item.score}}</text>
|
||||
</view>
|
||||
<view class="time">{{item.detail}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { getUserContributionByTypeList } from '@/api/modules/user'
|
||||
import { copyToClipboard } from '@/utils/index'
|
||||
|
||||
const { t } = useI18n()
|
||||
const paging = ref<any>()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// 数据状态
|
||||
const bookList = ref([])
|
||||
const loading = ref(false)
|
||||
const firstLoad = ref(true)
|
||||
const hufenData = ref('')
|
||||
|
||||
// 湖分记录
|
||||
async function hufenList(pageNo : number, pageSize : number) {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getUserContributionByTypeList(pageNo, pageSize, hufenData.value.type)
|
||||
console.log(res, 'res');
|
||||
paging.value.complete(res.list.records)
|
||||
} catch (error) {
|
||||
paging.value.complete(false)
|
||||
console.error('Failed to load book list:', error)
|
||||
} finally {
|
||||
firstLoad.value = false
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
onLoad((options) => {
|
||||
hufenData.value = options
|
||||
console.log(hufenData);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.my-book-page {
|
||||
background: #f7faf9;
|
||||
min-height: 100vh;
|
||||
|
||||
.recharge-record {
|
||||
background: #fff;
|
||||
border-radius: 15rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
// padding: 20rpx;
|
||||
margin: 20rpx;
|
||||
|
||||
.go-gecharge {
|
||||
text-align: center;
|
||||
background: linear-gradient(to right, #007bff, #17a2b8);
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
padding: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
padding-left: 20rpx;
|
||||
margin-bottom: 30rpx;
|
||||
color: #007bff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.recharge-record-block {
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
padding: 20rpx;
|
||||
|
||||
.time {
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 20rpx;
|
||||
color: #343434
|
||||
}
|
||||
|
||||
.recharge-record-block-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
// font-weight: 700;
|
||||
color: #909090;
|
||||
|
||||
.text {
|
||||
color: #007bff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
69
pages/user/hufen/index.vue
Normal file
69
pages/user/hufen/index.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<view class="recharge-page">
|
||||
<nav-bar :title="$t('user.iHufen')"></nav-bar>
|
||||
<view class="menu-section" v-if="hufenList.list.length > 0">
|
||||
<wd-cell-group border class="menu-list">
|
||||
<wd-cell v-for="item in hufenList.list" :key="item.type" :title="item.dict_value" is-link
|
||||
@click="handleMenuClick(item)">
|
||||
<text class="menu-list-hufen">{{item.score}}</text><text class="menu-list-hufen-text">{{$t('user.hufen')}}</text>
|
||||
</wd-cell>
|
||||
</wd-cell-group>
|
||||
</view>
|
||||
<view v-else><wd-divider>您还未获得湖分</wd-divider></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { getUserContributionData } from '@/api/modules/user'
|
||||
|
||||
const { t } = useI18n()
|
||||
const hufenList = ref([])
|
||||
|
||||
/**
|
||||
* 获取用户湖分
|
||||
*/
|
||||
const getHufen = async () => {
|
||||
hufenList.value = await getUserContributionData()
|
||||
console.log(hufenList.value.list)
|
||||
}
|
||||
|
||||
const handleMenuClick = (item) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/user/hufen/forDetails?type=${item.type}&nameValue=${item.dict_value}`
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getHufen()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.recharge-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f7faf9;
|
||||
}
|
||||
|
||||
.menu-section {
|
||||
padding: 20rpx 20rpx;
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
background: #fff;
|
||||
border-radius: 15rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
|
||||
.menu-list-hufen {
|
||||
font-size: 36rpx;
|
||||
color: #007bff;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
|
||||
.menu-list-hufen-text {
|
||||
color: #007bff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="user-page" :style="{ paddingTop: getNotchHeight() + 30 + 'px' }">
|
||||
<view class="user-page" :style="{ paddingTop: getNotchHeight() + 30 + 'px' }" v-if="userStore.token">
|
||||
<!-- 设置图标 -->
|
||||
<view class="settings-icon" :style="{ top: getNotchHeight() + 30 + 'px' }" @click="goSettings">
|
||||
<wd-icon name="setting1" size="24px" color="#666" />
|
||||
@@ -23,18 +23,23 @@
|
||||
<view class="vip-card-title">{{ $t('user.vip') }}</view>
|
||||
<view class="vip-card-content">
|
||||
<view class="vip-item-list">
|
||||
<view v-if="vipInfo?.length > 0" v-for="vip in vipInfo">{{ vipTypeDict[vip.type] }}({{ parseTime(vip.endTime, '{y}-{m}-{d}') }} 截止)</view>
|
||||
<view v-if="vipInfo?.length > 0" v-for="vip in vipInfo">
|
||||
{{ vipTypeDict[vip.type] }}({{ parseTime(vip.endTime, '{y}-{m}-{d}') }} 截止)</view>
|
||||
<view v-else>办理课程VIP,畅享更多权益</view>
|
||||
</view>
|
||||
<wd-button v-if="vipInfo?.length > 0" plain type="primary" size="small" @click="goCourseVipSub">{{ $t('vip.renewal') }}</wd-button>
|
||||
<wd-button v-else plain type="primary" size="small" @click="goCourseVipSub">{{ $t('vip.openVip') }}</wd-button>
|
||||
<wd-button v-if="vipInfo?.length > 0" plain type="primary" size="small"
|
||||
@click="goCourseVipSub">{{ $t('vip.renewal') }}</wd-button>
|
||||
<wd-button v-else plain type="primary" size="small"
|
||||
@click="goCourseVipSub">{{ $t('vip.openVip') }}</wd-button>
|
||||
</view>
|
||||
<view class="vip-card-content">
|
||||
<view class="vip-item-list">
|
||||
<view v-if="vipInfoEbook?.length > 0" v-for="vip in vipInfoEbook">电子书VIP{{ vipTypeDict[vip.type] }}({{ parseTime(vip.endTime, '{y}-{m}-{d}') }} 截止)</view>
|
||||
<view v-if="vipInfoEbook?.length > 0" v-for="vip in vipInfoEbook">
|
||||
电子书VIP{{ vipTypeDict[vip.type] }}({{ parseTime(vip.endTime, '{y}-{m}-{d}') }} 截止)</view>
|
||||
<view v-else>办理电子书VIP,畅享更多权益</view>
|
||||
</view>
|
||||
<wd-button v-if="!vipInfoEbook?.length" plain type="primary" size="small" @click="goSubscribe">{{ $t('vip.openVip') }}</wd-button>
|
||||
<wd-button v-if="!vipInfoEbook?.length" plain type="primary" size="small"
|
||||
@click="goSubscribe">{{ $t('vip.openVip') }}</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -65,22 +70,28 @@
|
||||
<!-- 功能菜单列表 -->
|
||||
<view class="menu-section">
|
||||
<wd-cell-group border class="menu-list">
|
||||
<wd-cell v-for="item in menuItems" :key="item.id" :title="item.name" :label="item.desc" is-link @click="handleMenuClick(item)" />
|
||||
<wd-cell v-for="item in menuItems" :key="item.id" :title="item.name" :label="item.desc" is-link
|
||||
@click="handleMenuClick(item)">
|
||||
<text v-if="item.hufenState" class="menu-list-hufen">{{hufenData.total ?? 0}}<text
|
||||
style="margin-left: 6rpx;">湖分</text></text>
|
||||
</wd-cell>
|
||||
</wd-cell-group>
|
||||
</view>
|
||||
</view>
|
||||
<visitor v-else></visitor>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { useSysStore } from '@/stores/sys'
|
||||
import { getUserInfo, getVipInfo } from '@/api/modules/user'
|
||||
import { getUserInfo, getVipInfo, getUserContributionData } from '@/api/modules/user'
|
||||
import type { IVipInfo } from '@/types/user'
|
||||
import { getNotchHeight } from '@/utils/system'
|
||||
import { parseTime } from '@/utils/index'
|
||||
import { t } from '@/utils/i18n'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import visitor from '@/pages/visitor/index.vue';
|
||||
|
||||
const userStore = useUserStore()
|
||||
const sysStore = useSysStore()
|
||||
@@ -140,7 +151,22 @@
|
||||
// desc: t('user.migrateSubtitle'),
|
||||
// type: 'pageJump'
|
||||
// }
|
||||
// {
|
||||
// id: 7,
|
||||
// name: t('user.certificate'),
|
||||
// url: '/pages/user/certificate/index',
|
||||
// type: 'pageJump'
|
||||
// },
|
||||
{
|
||||
id: 8,
|
||||
name: t('user.iHufen'),
|
||||
url: '/pages/user/hufen/index',
|
||||
type: 'pageJump',
|
||||
hufenState: true
|
||||
},
|
||||
])
|
||||
// 湖分
|
||||
const hufenData = ref('')
|
||||
|
||||
/**
|
||||
* 获取平台信息
|
||||
@@ -161,6 +187,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户湖分
|
||||
*/
|
||||
const getHufen = async () => {
|
||||
hufenData.value = await getUserContributionData()
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到设置页面
|
||||
*/
|
||||
@@ -243,11 +276,20 @@
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
console.log(userInfo, 'userInfo');
|
||||
if (userStore.token) {
|
||||
getData()
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
console.log(userInfo, 'userInfo');
|
||||
if (userStore.token) {
|
||||
getPlatform()
|
||||
getHufen()
|
||||
}
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -394,6 +436,16 @@
|
||||
border-radius: 15rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
|
||||
.menu-list-hufen {
|
||||
font-size: 36rpx;
|
||||
color: #007bff;
|
||||
|
||||
text {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.chong_btn {
|
||||
|
||||
138
pages/visitor/index.vue
Normal file
138
pages/visitor/index.vue
Normal file
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<view class="visitor">
|
||||
<view class="visitor-block">
|
||||
<view style="display: flex;">
|
||||
<image class="visitor_img" src="/static/logo.png" mode="aspectFil">
|
||||
</image>
|
||||
<text class="visitor-text" @click="gologin">立即登录</text>
|
||||
</view>
|
||||
<wd-cell-group border class="visitor-list">
|
||||
<wd-cell v-for="item in menuItems" :title="item.name" is-link @click="handleMenuClick(item)">
|
||||
</wd-cell>
|
||||
</wd-cell-group>
|
||||
</view>
|
||||
</view>
|
||||
<wd-action-sheet v-model="isShareSheetOpen" title="选择分享渠道" :panels="panels" @select="handleShare" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const menuItems = ref([
|
||||
{
|
||||
name: '分享APP'
|
||||
},
|
||||
{
|
||||
name: '关于我们',
|
||||
}
|
||||
])
|
||||
|
||||
const isShareSheetOpen = ref(false)
|
||||
|
||||
const panels = ref([
|
||||
{
|
||||
iconUrl: '/static/contact-person.png',
|
||||
title: '微信消息'
|
||||
},
|
||||
{
|
||||
iconUrl: '/static/moments.png',
|
||||
title: '朋友圈'
|
||||
}
|
||||
])
|
||||
|
||||
// 打开分享菜单
|
||||
const openShareSheet = () => {
|
||||
isShareSheetOpen.value = true
|
||||
}
|
||||
|
||||
// 选择分享渠道后执行分享逻辑
|
||||
const handleShare = (action) => {
|
||||
console.log(action, 'action');
|
||||
isShareSheetOpen.value = false // 关闭菜单
|
||||
if (action.index == 0) {
|
||||
// 分享到好友
|
||||
uni.share({
|
||||
provider: "weixin",
|
||||
scene: "WXSceneSession",
|
||||
type: 0,
|
||||
href: '',
|
||||
title: "吴门医述",
|
||||
summary: "我正在使用吴门医述提升自己,赶紧跟我一起来体验吧!",
|
||||
imageUrl: "static/icon/home_icon_logo.png",
|
||||
success: function (res) {
|
||||
console.log("success:" + JSON.stringify(res));
|
||||
},
|
||||
fail: function (err) {
|
||||
console.log("fail:" + JSON.stringify(err));
|
||||
},
|
||||
});
|
||||
} else if (action.index == 1) {
|
||||
// 分享到朋友圈
|
||||
uni.share({
|
||||
provider: "weixin",
|
||||
scene: "WXSceneTimeline",
|
||||
type: 0,
|
||||
href: '',
|
||||
title: "吴门医述",
|
||||
summary: "我正在使用吴门医述提升自己,赶紧跟我一起来体验吧!",
|
||||
imageUrl: "static/icon/home_icon_logo.png",
|
||||
success: function (res) {
|
||||
console.log("success:" + JSON.stringify(res));
|
||||
},
|
||||
fail: function (err) {
|
||||
console.log("fail:" + JSON.stringify(err));
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const handleMenuClick = (item : { name : string }) => {
|
||||
if (item.name === '关于我们') {
|
||||
uni.navigateTo({
|
||||
url: '/pages/user/about/index'
|
||||
})
|
||||
} else {
|
||||
isShareSheetOpen.value = true
|
||||
}
|
||||
}
|
||||
const gologin = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/login/login'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.visitor {
|
||||
background: #f4f7ff;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.visitor-block {
|
||||
padding: 40rpx 20rpx;
|
||||
|
||||
.visitor_img {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 60px;
|
||||
}
|
||||
|
||||
.visitor-text {
|
||||
margin-top: 30rpx;
|
||||
margin-left: 20rpx;
|
||||
font-weight: bold;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.visitor-list {
|
||||
background: #fff;
|
||||
border-radius: 15rpx;
|
||||
overflow: hidden;
|
||||
margin-top: 40rpx;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
</style>
|
||||
BIN
static/contact-person.png
Normal file
BIN
static/contact-person.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/moments.png
Normal file
BIN
static/moments.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Reference in New Issue
Block a user