16 Commits

Author SHA1 Message Date
a04d40a6d0 修复:电子书VIP套餐页“白块”问题 2025-12-19 14:38:17 +08:00
11dfd01b39 Merge branch 'main' of https://git.nuttyreading.com/zm/taimed-international-app 2025-12-19 13:59:34 +08:00
ce12470688 优化:数据迁移功能优化 2025-12-19 13:59:30 +08:00
62adfa1d4f Merge branch 'main' of https://git.nuttyreading.com/zm/taimed-international-app 2025-12-19 08:57:37 +08:00
778c6372e7 修复:后台充值和积分,app不显示订单号和跳转详情 2025-12-19 08:57:17 +08:00
54815f871f 修复:解决控制台报错 2025-12-18 16:01:09 +08:00
cf9ef2e6dd Merge branch 'main' of https://git.nuttyreading.com/zm/taimed-international-app 2025-12-18 15:57:54 +08:00
2b0e339bc9 修复:完善数据迁移;修改logo及课程首页接口文件覆盖问题; 2025-12-18 15:57:50 +08:00
4df53c611b 修改:后台操作,充值、积分功能。手机端进行限制 2025-12-18 15:30:23 +08:00
56772970e2 修复:优化访客模式 2025-12-18 14:03:01 +08:00
9e04533bdc 更新:更新打包版本 2025-12-18 09:20:51 +08:00
77fedbe877 修复:ios审核上传照片问题 2025-12-17 18:26:21 +08:00
6c2811646a 修复:修改logo图 2025-12-15 15:47:16 +08:00
9e00409e5e 修复:不同系统支付,显示支付方式不同 2025-12-15 11:18:22 +08:00
1457a24cea 修复:更新ios支付接口 2025-12-15 10:41:41 +08:00
34d6cfdf9e 更新:访客模式可以查看图书首页 2025-12-12 14:33:47 +08:00
26 changed files with 176 additions and 210 deletions

22
App.vue
View File

@@ -3,31 +3,9 @@
import update from "@/uni_modules/uni-upgrade-center-app/utils/check-update"; import update from "@/uni_modules/uni-upgrade-center-app/utils/check-update";
// #endif // #endif
import { useUserStore } from '@/stores/user'
export default { export default {
onLaunch: function() { onLaunch: function() {
const userStore = useUserStore()
console.log('App Launch') console.log('App Launch')
// 保存原生 switchTab 方法
const originalSwitchTab = uni.switchTab;
uni.switchTab = (options) => {
if (options.url.includes('/pages/book/index') && !uni.getStorageSync('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 // #ifdef APP-PLUS
update(); update();

View File

@@ -7,8 +7,8 @@ export const ENV = process.env.NODE_ENV || 'development';
*/ */
const BASE_URL_MAP = { const BASE_URL_MAP = {
development: { development: {
// MAIN: 'http://192.168.110.100:9300/pb/', // 张川川 MAIN: 'http://192.168.110.100:9300/pb/', // 张川川
MAIN: 'https://global.nuttyreading.com/', // 线上 // MAIN: 'https://global.nuttyreading.com/', // 线上
// PAYMENT: 'https://dev-pay.example.com', // 暂时用不到 // PAYMENT: 'https://dev-pay.example.com', // 暂时用不到
// CDN: 'https://cdn-dev.example.com', // 暂时用不到 // CDN: 'https://cdn-dev.example.com', // 暂时用不到
}, },

View File

@@ -42,7 +42,7 @@ export const bookHomeApi = {
*/ */
getRecommendBooks() { getRecommendBooks() {
return skeletonClient.request<IRecommendBooksResponse>({ return skeletonClient.request<IRecommendBooksResponse>({
url: 'bookAbroad/home/getRecommendBooks', url: uni.getStorageSync('token') ? 'bookAbroad/home/getRecommendBooks' : 'visitor/bookAbroad/getRecommendBooks',
method: 'POST', method: 'POST',
data: {} data: {}
}) })
@@ -54,7 +54,7 @@ export const bookHomeApi = {
*/ */
getBookLabelList(type: number) { getBookLabelList(type: number) {
return skeletonClient.request<ILabelListResponse>({ return skeletonClient.request<ILabelListResponse>({
url: 'bookAbroad/home/getBookAbroadLableList', url: uni.getStorageSync('token') ? 'bookAbroad/home/getBookAbroadLableList' : 'visitor/bookAbroad//getBookAbroadLableList',
method: 'POST', method: 'POST',
data: { type } data: { type }
}) })
@@ -66,7 +66,7 @@ export const bookHomeApi = {
*/ */
getSubLabelList(pid: number) { getSubLabelList(pid: number) {
return skeletonClient.request<ILabelListResponse>({ return skeletonClient.request<ILabelListResponse>({
url: 'bookAbroad/home/getBookAbroadLableListByPid', url: uni.getStorageSync('token') ? 'bookAbroad/home/getBookAbroadLableListByPid' : 'visitor/bookAbroad//getBookAbroadLableListByPid',
method: 'POST', method: 'POST',
data: { pid } data: { pid }
}) })
@@ -78,7 +78,7 @@ export const bookHomeApi = {
*/ */
getBooksByLabel(lableId: number) { getBooksByLabel(lableId: number) {
return skeletonClient.request<IBookListResponse>({ return skeletonClient.request<IBookListResponse>({
url: 'bookAbroad/home/getAbroadBookListByLable', url: uni.getStorageSync('token') ? 'bookAbroad/home/getAbroadBookListByLable' : 'visitor/bookAbroad/getAbroadBookListByLable',
method: 'POST', method: 'POST',
data: { lableId } data: { lableId }
}) })

View File

@@ -2,7 +2,6 @@
import { mainClient, skeletonClient } from '@/api/clients' import { mainClient, skeletonClient } from '@/api/clients'
import type { IApiResponse } from '@/api/types' import type { IApiResponse } from '@/api/types'
import type { IAgreement } from '@/types/user' import type { IAgreement } from '@/types/user'
import { useUserStore } from '@/stores/user'
export const commonApi = { export const commonApi = {
/** /**
@@ -37,9 +36,8 @@ export const commonApi = {
* @returns 消息列表 * @returns 消息列表
*/ */
getMessageList(isBook: number, isMedical: number, isSociology: number) { getMessageList(isBook: number, isMedical: number, isSociology: number) {
const userStore = useUserStore()
return skeletonClient.request<IApiResponse>({ return skeletonClient.request<IApiResponse>({
url: userStore.token ? 'common/message/listByPage' : '/visitor/listByPage', url: uni.getStorageSync('token') ? 'common/message/listByPage' : '/visitor/listByPage',
method: 'POST', method: 'POST',
data: { isBook, isMedical, isSociology } data: { isBook, isMedical, isSociology }
}) })

View File

@@ -13,7 +13,6 @@ import type {
} from '@/types/course' } from '@/types/course'
import type { ISearchRequest, ISearchResponse } from '@/types/search' import type { ISearchRequest, ISearchResponse } from '@/types/search'
import type { ICommentListResponse, IAddCommentResponse, IComment } from '@/types/comment' import type { ICommentListResponse, IAddCommentResponse, IComment } from '@/types/comment'
import { useUserStore } from '@/stores/user'
/** /**
* 课程相关API * 课程相关API
@@ -55,9 +54,8 @@ export const courseApi = {
page: number, page: number,
limit: number limit: number
}) { }) {
const userStore = useUserStore()
return skeletonClient.request<IMarketCourseListResponse>({ return skeletonClient.request<IMarketCourseListResponse>({
url: userStore.token ? 'medical/home/getMarketCourseList' : 'visitor/getMarketCourseList', url: uni.getStorageSync('token') ? 'medical/home/getMarketCourseList' : 'visitor/getMarketCourseList',
method: 'POST', method: 'POST',
data data
}) })

View File

@@ -1,17 +1,9 @@
// api/modules/course.ts // api/modules/course.ts
import { createRequestClient } from '../request' import { mainClient, skeletonClient } from '@/api/clients'
import { SERVICE_MAP } from '../config'
import type { import type {
ICourseCategoryResponse, ICourseCategoryResponse,
IUserLateCourseListResponse,
IMarketCourseListResponse, IMarketCourseListResponse,
ICourseMedicalLabelsResponse
} from '@/types/course' } from '@/types/course'
import { useUserStore } from '@/stores/user'
import { skeletonClient } from '../clients'
const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN })
/** /**
* 课程分类及分类下课程相关API * 课程分类及分类下课程相关API
@@ -23,9 +15,8 @@ export const courseSubjectClassificationApi = {
* @returns 分类数据 * @returns 分类数据
*/ */
getCourseMedicalTree() { getCourseMedicalTree() {
const userStore = useUserStore() return skeletonClient.request<ICourseCategoryResponse>({
return client.request<ICourseCategoryResponse>({ url: uni.getStorageSync('token') ? 'medical/home/getCourseMedicalTree' : '/visitor/getCourseMedicalTree',
url: userStore.token ? 'medical/home/getCourseMedicalTree' : '/visitor/getCourseMedicalTree',
method: 'POST', method: 'POST',
data: {} data: {}
}) })
@@ -63,7 +54,7 @@ export const courseSubjectClassificationApi = {
* @returns 分类数据 * @returns 分类数据
*/ */
getCourseMedicalLabels(id: number) { getCourseMedicalLabels(id: number) {
return client.request<ICourseCategoryResponse>({ return mainClient.request<ICourseCategoryResponse>({
url: 'medical/home/getMedicalLabels', url: 'medical/home/getMedicalLabels',
method: 'POST', method: 'POST',
data: { id } data: { id }
@@ -76,7 +67,7 @@ export const courseSubjectClassificationApi = {
* @returns 分类数据 * @returns 分类数据
*/ */
getCourseMedicalChildLabels(id: number) { getCourseMedicalChildLabels(id: number) {
return client.request<ICourseCategoryResponse>({ return mainClient.request<ICourseCategoryResponse>({
url: 'medical/home/getChildCourseMedicalTree', url: 'medical/home/getChildCourseMedicalTree',
method: 'POST', method: 'POST',
data: { id } data: { id }
@@ -94,7 +85,7 @@ export const courseSubjectClassificationApi = {
page: number, // 页码 page: number, // 页码
limit: number // 每页数量 limit: number // 每页数量
}) { }) {
return client.request<IMarketCourseListResponse>({ return mainClient.request<IMarketCourseListResponse>({
url: 'medical/home/getMedicalCourseList', url: 'medical/home/getMedicalCourseList',
method: 'POST', method: 'POST',
data data
@@ -107,7 +98,7 @@ export const courseSubjectClassificationApi = {
* @returns 分类数据 * @returns 分类数据
*/ */
getCourseSoulChildLabels(id: number) { getCourseSoulChildLabels(id: number) {
return client.request<ICourseCategoryResponse>({ return mainClient.request<ICourseCategoryResponse>({
url: 'psyche/home/getChildCoursePsycheTree', url: 'psyche/home/getChildCoursePsycheTree',
method: 'POST', method: 'POST',
data: { id } data: { id }
@@ -125,7 +116,7 @@ export const courseSubjectClassificationApi = {
page: number, // 页码 page: number, // 页码
limit: number // 每页数量 limit: number // 每页数量
}) { }) {
return client.request<IMarketCourseListResponse>({ return mainClient.request<IMarketCourseListResponse>({
url: 'psyche/home/getPsycheCourseList', url: 'psyche/home/getPsycheCourseList',
method: 'POST', method: 'POST',
data data
@@ -143,7 +134,7 @@ export const courseSubjectClassificationApi = {
page: number, // 页码 page: number, // 页码
limit: number // 每页数量 limit: number // 每页数量
}) { }) {
return client.request<IMarketCourseListResponse>({ return mainClient.request<IMarketCourseListResponse>({
url: 'sociology/course/getSociologyCourseList', url: 'sociology/course/getSociologyCourseList',
method: 'POST', method: 'POST',
data data

View File

@@ -324,7 +324,7 @@ export async function migrateUserData(data: { tel: string, code: string, type: s
* } * }
*/ */
export async function getUserMigrateInfo() { export async function getUserMigrateInfo() {
const res = await mainClient.request<IApiResponse>({ const res = await skeletonClient.request<IApiResponse>({
url: 'common/user/getMigrationList', url: 'common/user/getMigrationList',
method: 'POST', method: 'POST',
}) })
@@ -336,7 +336,7 @@ export async function getUserMigrateInfo() {
* @return * @return
*/ */
export async function getUserContributionData() { export async function getUserContributionData() {
const res = await mainClient.request<IApiResponse>({ const res = await skeletonClient.request<IApiResponse>({
url: 'common/userContribution/getUserContribution', url: 'common/userContribution/getUserContribution',
method: 'POST' method: 'POST'
}) })
@@ -370,7 +370,7 @@ export async function getUserContributionByTypeList(current : number, limit : nu
*/ */
export async function getIosPayment(transactionId : string, productId : string, orderId : string, receiptData : string, customerOid : string) { export async function getIosPayment(transactionId : string, productId : string, orderId : string, receiptData : string, customerOid : string) {
const res = await mainClient.request<IApiResponse>({ const res = await mainClient.request<IApiResponse>({
url: 'Ipa/veri/', url: 'Ipa/veri',
method: 'POST', method: 'POST',
data: { transactionId, productId, orderId, receiptData, customerOid} data: { transactionId, productId, orderId, receiptData, customerOid}
}) })

View File

@@ -145,7 +145,7 @@
"updateFailed": "Update Failed", "updateFailed": "Update Failed",
"paymentMethod": "Payment Method", "paymentMethod": "Payment Method",
"googlePay": "Google Pay", "googlePay": "Google Pay",
"applePay": "Apple Pay", "applePay": "In-App Purchase",
"agreeText": "I have agreed", "agreeText": "I have agreed",
"agreement": "Recharge Agreement", "agreement": "Recharge Agreement",
"agreeFirst": "Please agree to the recharge agreement first", "agreeFirst": "Please agree to the recharge agreement first",
@@ -223,8 +223,8 @@
"migrateCodePlaceholder": "The code obtained from chinese account", "migrateCodePlaceholder": "The code obtained from chinese account",
"migrateWarning": "Migration is irreversible, please proceed with caution!", "migrateWarning": "Migration is irreversible, please proceed with caution!",
"migrateInstructions": "Migration Instructions", "migrateInstructions": "Migration Instructions",
"instruction1": "Please obtain the migration code from your chinese account, get it by going to 【我的】-【数据迁移】-【获取迁移验证码】.", "instruction1": "Please obtain the migration code from your chinese account, get it by going to 【我的】-【数据迁移】-【查看账号和迁移验证码】.",
"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", "instruction2": "After data migration is complete, the chinese account data will be cleared, and all purchased Tianyi Coins, points, courses, VIP and User Hufen will be transferred to the current account",
"instruction3": "The migration process may take a few minutes, please be patient.", "instruction3": "The migration process may take a few minutes, please be patient.",
"instruction4": "If you encounter any issues, please contact customer service for assistance.", "instruction4": "If you encounter any issues, please contact customer service for assistance.",
"alreadyMigrated": "You have already migrated:", "alreadyMigrated": "You have already migrated:",
@@ -234,7 +234,9 @@
"certificate": "My certificate", "certificate": "My certificate",
"iHufen": "My lake", "iHufen": "My lake",
"hufenRecord": "Lake division record", "hufenRecord": "Lake division record",
"hufen": "Hufen" "hufen": "Hufen",
"backEnd" : "Back-end recharge",
"cannotView" : "The recharge in the background cannot be viewed"
}, },
"book": { "book": {
"title": "My Books", "title": "My Books",

View File

@@ -146,7 +146,7 @@
"updateFailed": "更新失败", "updateFailed": "更新失败",
"paymentMethod": "支付方式", "paymentMethod": "支付方式",
"googlePay": "Google Pay", "googlePay": "Google Pay",
"applePay": "Apple Pay", "applePay": "IAP 支付",
"agreeText": "我已同意", "agreeText": "我已同意",
"agreement": "充值协议", "agreement": "充值协议",
"agreeFirst": "请先同意充值协议", "agreeFirst": "请先同意充值协议",
@@ -224,8 +224,8 @@
"migrateCodePlaceholder": "国内版账号获取的迁移验证码", "migrateCodePlaceholder": "国内版账号获取的迁移验证码",
"migrateWarning": "迁移后不可恢复,请谨慎操作!", "migrateWarning": "迁移后不可恢复,请谨慎操作!",
"migrateInstructions": "迁移说明", "migrateInstructions": "迁移说明",
"instruction1": "请在吴门医述、心灵空间、众妙之门、疯子读书任意APP中获取迁移验证码获取方式【我的】-【数据迁移】-【获取迁移验证码】。", "instruction1": "请在吴门医述APP中获取迁移验证码获取方式【我的】-【数据迁移】-【查看账号和迁移验证码】。",
"instruction2": "数据迁移完成后,旧账号数据将被清空,已购买的天医币、积分、课程、电子书、VIP、证书、湖分将转移到当前账号。", "instruction2": "数据迁移完成后,旧账号数据将被清空,已购买的天医币、积分、课程、VIP、湖分将转移到当前账号。",
"instruction3": "迁移过程可能需要几分钟时间,请耐心等待。", "instruction3": "迁移过程可能需要几分钟时间,请耐心等待。",
"instruction4": "如遇到问题,请联系客服获取帮助。", "instruction4": "如遇到问题,请联系客服获取帮助。",
"alreadyMigrated": "您已迁移过:", "alreadyMigrated": "您已迁移过:",
@@ -235,7 +235,9 @@
"certificate": "我的证书", "certificate": "我的证书",
"iHufen": "我的湖分", "iHufen": "我的湖分",
"hufenRecord": "湖分记录", "hufenRecord": "湖分记录",
"hufen": "湖分" "hufen": "湖分",
"backEnd" : "后台充值",
"cannotView" : "后台充值无法查看"
}, },
"book": { "book": {
"title": "我的书单", "title": "我的书单",

View File

@@ -2,8 +2,8 @@
"name" : "吴门国际", "name" : "吴门国际",
"appid" : "__UNI__1250B39", "appid" : "__UNI__1250B39",
"description" : "吴门国际", "description" : "吴门国际",
"versionName" : "1.0.9", "versionName" : "1.1.1",
"versionCode" : 109, "versionCode" : 111,
"transformPx" : false, "transformPx" : false,
/* 5+App */ /* 5+App */
"app-plus" : { "app-plus" : {
@@ -113,7 +113,7 @@
"platforms" : "Android", "platforms" : "Android",
"url" : "https://ext.dcloud.net.cn/plugin?id=12608", "url" : "https://ext.dcloud.net.cn/plugin?id=12608",
"android_package_name" : "com.amazinglimited", "android_package_name" : "com.amazinglimited",
"ios_bundle_id" : "", "ios_bundle_id" : "com.amazinglimited",
"isCloud" : true, "isCloud" : true,
"bought" : 1, "bought" : 1,
"pid" : "12608", "pid" : "12608",

View File

@@ -12,7 +12,7 @@
/> />
<view class="icon-hua"> <view class="icon-hua">
<image <image
src="../../static/home_icon.png" src="../../static/book/home_icon.png"
mode="aspectFit" mode="aspectFit"
class="icon-hua-img" class="icon-hua-img"
/> />
@@ -35,16 +35,16 @@
<view class="mine-1"> <view class="mine-1">
<text class="mine-title">{{ $t('bookHome.block1') }}</text> <text class="mine-title">{{ $t('bookHome.block1') }}</text>
<view <view
v-if="data.page.records.length > 0" v-if="data?.page?.records.length > 0"
class="mine-more" class="mine-more"
@click="handleMoreClick" @click="handleMoreClick"
> >
{{ $t('bookHome.more') }} {{ $t('bookHome.more') }}
<image src="@/static/icon/icon_right.png" /> <image src="@/static/icon/icon_right.png" />
</view> </view>
<view v-if="data.page.records.length > 0" class="mine-1-list"> <view v-if="data?.page?.records.length > 0" class="mine-1-list">
<view <view
v-for="(item, index) in data.page.records" v-for="(item, index) in data?.page?.records"
:key="index" :key="index"
class="mine-item" class="mine-item"
@click="handleMyBookClick(item.id)" @click="handleMyBookClick(item.id)"
@@ -284,7 +284,7 @@ const vipInfo = computed(() => userStore.userInfo?.userEbookVip?.[0] || null)
/** /**
* 获取我的书单 * 获取我的书单
*/ */
const getMyBooks = () => bookHomeApi.getMyBooks(1, 10) const getMyBooks = () => uni.getStorageSync('token') ? bookHomeApi.getMyBooks(1, 10) : []
/** /**
* 获取推荐图书 * 获取推荐图书
@@ -364,6 +364,8 @@ const handleMyBookClick = (bookId: number) => {
* 处理图书点击 * 处理图书点击
*/ */
const handleBookClick = (bookId: number) => { const handleBookClick = (bookId: number) => {
getPrompt()
if(!uni.getStorageSync('token')) return
uni.navigateTo({ uni.navigateTo({
url: `/pages/book/detail?id=${bookId}` url: `/pages/book/detail?id=${bookId}`
}) })
@@ -382,6 +384,8 @@ const handleMoreClick = () => {
* 处理活动标签点击 * 处理活动标签点击
*/ */
const handleActivityLabelClick = async (labelId: number, index: number) => { const handleActivityLabelClick = async (labelId: number, index: number) => {
getPrompt()
if(!uni.getStorageSync('token')) return
currentActivityIndex.value = index currentActivityIndex.value = index
activityBooksSkeleton.value.reload() activityBooksSkeleton.value.reload()
} }
@@ -404,6 +408,25 @@ const handleCategoryLevel2Click = async (labelId: number, index: number) => {
categoryBooksSkeleton.value.reload() categoryBooksSkeleton.value.reload()
} }
/**
* 登录提示语
*/
const getPrompt = () => {
if(!uni.getStorageSync('token')) {
uni.showModal({
title: '提示',
content: '请先登录后访问该页面',
confirmText: '去登录',
success: (res) => {
console.log(res , 'res');
if (res.confirm) uni.navigateTo({
url: '/pages/login/login'
});
}
});
}
}
/** /**
* 页面显示 * 页面显示
*/ */

View File

@@ -326,7 +326,7 @@ const handleFirstLevelClick = (item: string) => {
if(!uni.getStorageSync('token')) return if(!uni.getStorageSync('token')) return
selectedFirstLevel.value = item selectedFirstLevel.value = item
if (item === '医学') { if (item === '医学') {
medicineMenuSkeletonRef.value.reload() medicineMenuSkeletonRef.value?.reload()
} else { } else {
menuSkeletonRef.value?.reload() menuSkeletonRef.value?.reload()
} }
@@ -457,17 +457,16 @@ const requestAll = async () => {
* 页面挂载 * 页面挂载
*/ */
onMounted(() => { onMounted(() => {
if(!userStore.token) { // 重置分类索引
currentIndex.value = 0
if(!uni.getStorageSync('state') && !uni.getStorageSync('token')) {
uni.navigateTo({ uni.navigateTo({
url: '/pages/login/login' url: '/pages/login/login'
}); });
} }
// 重置分类索引 if(uni.getStorageSync('state')) uni.removeStorageSync('state')
currentIndex.value = 0
// 请求所有数据 // 请求所有数据
requestAll() requestAll()
console.log('进来了2');
}) })
/** /**
@@ -485,7 +484,7 @@ onShow(() => {
// 刷新数据 // 刷新数据
// requestAll() // requestAll()
if(userStore.token){ if(uni.getStorageSync('token')){
getLearnCourse() getLearnCourse()
} }
}) })
@@ -692,7 +691,7 @@ $border-color: #eeeeee;
width: 60rpx; width: 60rpx;
height: 60rpx; height: 60rpx;
background-size: 100% 100%; background-size: 100% 100%;
background-image: url("@/static/soul/cate_bg.png"); background-image: url("@/static/icon/cate_bg.png");
border-radius: 4rpx; border-radius: 4rpx;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -753,7 +752,7 @@ $border-color: #eeeeee;
width: 65rpx; width: 65rpx;
height: 78rpx; height: 78rpx;
background-size: 100% 100%; background-size: 100% 100%;
background-image: url("@/static/soul/cate_bg.png"); background-image: url("@/static/icon/cate_bg.png");
border-radius: 4rpx; border-radius: 4rpx;
display: flex; display: flex;
align-items: center; align-items: center;

View File

@@ -401,6 +401,7 @@ const yszc = () => {
* 页面跳转 * 页面跳转
*/ */
const onPageSwitch = (url: string) => { const onPageSwitch = (url: string) => {
uni.setStorageSync('state', 'true');
uni.switchTab({ uni.switchTab({
url: url, url: url,
}) })
@@ -446,7 +447,6 @@ const getOS = () =>{
const oprateOs = uni.getSystemInfoSync().platform const oprateOs = uni.getSystemInfoSync().platform
console.log(oprateOs, 'oprateOs'); console.log(oprateOs, 'oprateOs');
isAndorid.value = oprateOs === "android" ? true : false isAndorid.value = oprateOs === "android" ? true : false
console.log(isAndorid.value);
} }
onMounted(() => { onMounted(() => {

View File

@@ -7,7 +7,7 @@
<!-- 应用信息 --> <!-- 应用信息 -->
<view class="app-info"> <view class="app-info">
<image <image
src="/static/icon/home_icon_logo.jpg" src="/static/logo.png"
mode="aspectFit" mode="aspectFit"
class="app-logo" class="app-logo"
/> />
@@ -52,11 +52,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { useI18n } from 'vue-i18n' import { t } from '@/utils/i18n'
import { makePhoneCall } from '@/utils/index' import { makePhoneCall } from '@/utils/index'
const { t } = useI18n()
// 导航栏高度 // 导航栏高度
const statusBarHeight = ref(0) const statusBarHeight = ref(0)
const navbarHeight = ref('44px') const navbarHeight = ref('44px')

View File

@@ -1,5 +1,5 @@
<template> <template>
<view class="user-page" :style="{ paddingTop: getNotchHeight() + 30 + 'px' }" v-if="userStore.token && uni.getStorageSync('token')"> <view class="user-page" :style="{ paddingTop: getNotchHeight() + 30 + 'px' }" v-if="tokenState">
<!-- 设置图标 --> <!-- 设置图标 -->
<view class="settings-icon" :style="{ top: getNotchHeight() + 30 + 'px' }" @click="goSettings"> <view class="settings-icon" :style="{ top: getNotchHeight() + 30 + 'px' }" @click="goSettings">
<wd-icon name="setting1" size="24px" color="#666" /> <wd-icon name="setting1" size="24px" color="#666" />
@@ -124,6 +124,13 @@
url: '/pages/user/myBook/index', url: '/pages/user/myBook/index',
type: 'pageJump' type: 'pageJump'
}, },
{
id: 8,
name: t('user.iHufen'),
url: '/pages/user/hufen/index',
type: 'pageJump',
hufenState: true
},
{ {
id: 3, id: 3,
name: t('user.profile'), name: t('user.profile'),
@@ -142,29 +149,23 @@
url: '/pages/user/feedback/index', url: '/pages/user/feedback/index',
type: 'pageJump' type: 'pageJump'
}, },
// { {
// id: 6, id: 6,
// name: t('user.dataMigrate'), name: t('user.dataMigrate'),
// url: '/pages/user/migrate/index', url: '/pages/user/migrate/index',
// desc: t('user.migrateSubtitle'), desc: t('user.migrateSubtitle'),
// type: 'pageJump' type: 'pageJump'
// } },
// { // {
// id: 7, // id: 7,
// name: t('user.certificate'), // name: t('user.certificate'),
// url: '/pages/user/certificate/index', // url: '/pages/user/certificate/index',
// type: 'pageJump' // type: 'pageJump'
// }, // },
{
id: 8,
name: t('user.iHufen'),
url: '/pages/user/hufen/index',
type: 'pageJump',
hufenState: true
},
]) ])
// 湖分 // 湖分
const hufenData = ref() const hufenData = ref()
const tokenState = ref(false)
/** /**
* 获取平台信息 * 获取平台信息
@@ -190,7 +191,6 @@
*/ */
const getHufen = async () => { const getHufen = async () => {
hufenData.value = await getUserContributionData() hufenData.value = await getUserContributionData()
hufenData.value = await getUserContributionData()
} }
/** /**
@@ -273,10 +273,12 @@
url: '/pages/user/points/index' url: '/pages/user/points/index'
}) })
} }
onShow(() => { onShow(() => {
if (uni.getStorageSync('token')) { if (uni.getStorageSync('token')) {
tokenState.value = true
getData() getData()
getHufen()
} }
}) })

View File

@@ -96,7 +96,7 @@ const formData = ref({
const getMigrateInfo = async () => { const getMigrateInfo = async () => {
const res = await getUserMigrateInfo() const res = await getUserMigrateInfo()
migrateInfo.value.alreadyMigration = res.alreadyMigration migrateInfo.value.alreadyMigration = res.alreadyMigration
// migrateInfo.value.notMigration = res.notMigration migrateInfo.value.notMigration = res.notMigration
} }
onMounted(() => { onMounted(() => {
getMigrateInfo() getMigrateInfo()
@@ -151,6 +151,9 @@ const submitMigrate = async () => {
// 清空表单 // 清空表单
formData.value.tel = '' formData.value.tel = ''
formData.value.code = '' formData.value.code = ''
// 刷新用户迁移信息
getMigrateInfo()
} }
</script> </script>

View File

@@ -12,11 +12,11 @@
</view> </view>
<view class="title">{{$t('order.pointsRecord')}}</view> <view class="title">{{$t('order.pointsRecord')}}</view>
<view class="recharge-record-block" v-for="(item, index) in bookList" :key="index" @click="toDetails(item)"> <view class="recharge-record-block" v-for="(item, index) in bookList" :key="index" @click="toDetails(item)">
<view class="recharge-record-block-row">{{item.remark.slice(0, (item.remark.indexOf(',')))}}<text <view class="recharge-record-block-row">{{item.relationId ? item.remark.slice(0, (item.remark.indexOf(','))) : $t('user.backEnd')}}<text
:class="item.actType === 1 ? 'text1' : 'text2'">{{item.actType === 1 ? '' : '+'}}{{item.changeAmount}}</text> :class="item.changeAmount < 0 ? 'text1' : 'text2'">{{item.changeAmount < 0 ? '' : '+'}}{{item.changeAmount}}</text>
</view> </view>
<view class="time">{{item.createTime}}</view> <view class="time">{{item.createTime}}</view>
<view style="font-size: 24rpx;">{{item.remark.slice((item.remark.indexOf(','))+1)}}<wd-icon name="file-copy" <view style="font-size: 24rpx;" v-if="item.relationId">{{item.remark.slice((item.remark.indexOf(','))+1)}}<wd-icon name="file-copy"
size="14px" color="#65A1FA" style="margin-left: 10rpx;" @click="copyToClipboard()"></wd-icon></view> size="14px" color="#65A1FA" style="margin-left: 10rpx;" @click="copyToClipboard()"></wd-icon></view>
</view> </view>
</view> </view>
@@ -69,10 +69,14 @@
* 跳转订单详情 * 跳转订单详情
*/ */
const toDetails = (order: IOrder) => { const toDetails = (order: IOrder) => {
console.log(order.relationId, "order"); if (order.relationId) {
uni.navigateTo({ uni.navigateTo({
url: '/pages/user/order/details?orderId=' + order.relationId url: '/pages/user/order/details?orderId=' + order.relationId
}) })
} else {
uni.showToast({ title: t('user.cannotView'), icon: 'none' });
}
} }
</script> </script>

View File

@@ -3,7 +3,7 @@
<!-- 自定义导航栏 --> <!-- 自定义导航栏 -->
<nav-bar :title="$t('order.recharge')"></nav-bar> <nav-bar :title="$t('order.recharge')"></nav-bar>
<!-- 活动充值金额 --> <!-- 活动充值金额 -->
<view class="block" v-if="eventAmountList.length > 0"> <view class="block" v-if="eventAmountList?.length > 0">
<!-- <view class="text">{{$t('order.rechargeAmount')}}</view> --> <!-- <view class="text">{{$t('order.rechargeAmount')}}</view> -->
<view class="text">活动充值金额</view> <view class="text">活动充值金额</view>
<view class="recharge"> <view class="recharge">
@@ -39,13 +39,11 @@
<view class="cha_fangsh"> <view class="cha_fangsh">
<view class="cf_title">{{$t('user.paymentMethod')}}</view> <view class="cf_title">{{$t('user.paymentMethod')}}</view>
<view class="cf_radio"> <view class="cf_radio">
<radio-group v-for="item in iosPaylist"> <radio-group>
<view> <view>
<view :class="payType == item.id ? 'Tab_xf cf_xuanx' : 'cf_xuanx'"> <view class="cf_xuanx">
<!-- <image class="pay_item_img" :src="item.imgUrl" mode="aspectFil"> <text>{{ isAndroid ? $t('user.googlePay') : $t('user.applePay')}}</text>
</image> --> <radio checked="true;" @click="choseType(item.id)"></radio>
<text>{{ item.title }}</text>
<radio :checked="payType === item.id" @click="choseType(item.id)"></radio>
</view> </view>
</view> </view>
</radio-group> </radio-group>
@@ -88,14 +86,6 @@
const userStore = useUserStore() const userStore = useUserStore()
const { t } = useI18n() const { t } = useI18n()
const message = useMessage() const message = useMessage()
const payType = ref('1')
const iosPaylist = ref([
{
title: "Google Pay",
id: '1',
// imgUrl: "/static/icon/currency.png"
}
])
// 充值列表 // 充值列表
const rechargeList = ref([]) const rechargeList = ref([])
// 金额列表单独每项 // 金额列表单独每项
@@ -135,7 +125,7 @@
const eventAmountList = ref([]) const eventAmountList = ref([])
//正常金额数据 //正常金额数据
const standardAmountList = ref([]) const standardAmountList = ref([])
// 声明ios实例
const iapChannel = ref(null) const iapChannel = ref(null)
/** /**
@@ -148,7 +138,7 @@
console.log('运行Android上') console.log('运行Android上')
} else { } else {
isAndroid.value = false; isAndroid.value = false;
qudao.value = 'Google' qudao.value = 'IOS'
console.log('运行iOS上') console.log('运行iOS上')
} }
getData() getData()
@@ -251,16 +241,16 @@
} }
}); });
} }
/** /**
* 查询后台配置的商品信息 * 查询后台配置的商品信息
*/ */
const getProductInfo = () => { const getProductInfo = () => {
const id = String(aloneItem.value.priceTypeId) const id = String(aloneItem.value.priceTypeId)
iapChannel.value.requestProduct([id], (res: any) => { iapChannel.value.requestProduct([id], (res : any) => {
console.log(res, '查询苹果后台配置的商品id'); console.log(res, '查询苹果后台配置的商品id');
topay(id) topay(id)
}, (err: any) => { }, (err : any) => {
uni.showToast({ title: '未获取到产品信息,请联系管理员', icon: 'none' }); uni.showToast({ title: '未获取到产品信息,请联系管理员', icon: 'none' });
console.error('失败', err); console.error('失败', err);
}); });
@@ -269,7 +259,7 @@
/** /**
* 准备支付-调出支付窗口 * 准备支付-调出支付窗口
*/ */
const topay = (id: string) => { const topay = (id : string) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
uni.hideLoading() uni.hideLoading()
uni.requestPayment({ uni.requestPayment({
@@ -288,16 +278,13 @@
fail: (err) => { fail: (err) => {
console.log('支付错误', err); console.log('支付错误', err);
restoreComplateRequest() restoreComplateRequest()
uni.showToast({ uni.showToast({ title: t('user.closeWindow'), icon: 'error' })
title: '关闭支付弹窗',
icon: 'none'
})
reject(err); reject(err);
} }
}); });
}) })
} }
/** /**
* 调用后台支付-ios * 调用后台支付-ios
*/ */
@@ -307,14 +294,17 @@
const obj = await getIosPayment(res.transactionIdentifier, res.payment.productid, res.payment.username, res.transactionReceipt, userStore.userInfo.id) const obj = await getIosPayment(res.transactionIdentifier, res.payment.productid, res.payment.username, res.transactionReceipt, userStore.userInfo.id)
console.log(obj, '校验订单') console.log(obj, '校验订单')
finishTransaction(res) finishTransaction(res)
uni.switchTab({
url: '/pages/user/index'
})
} catch (error) { } catch (error) {
console.error('校验订单失败:', error) console.error('校验订单失败:', error)
// 也需要释放订单,防止再次提交支付窗口拉不起来 // 也需要释放订单,防止失败再次提交支付窗口拉不起来
finishTransaction(res) finishTransaction(res)
} }
} }
/** /**
* 检查是否存在未关闭的订单 * 检查是否存在未关闭的订单
*/ */
@@ -322,9 +312,9 @@
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
iapChannel.value.restoreCompletedTransactions({ iapChannel.value.restoreCompletedTransactions({
manualFinishTransaction: true, manualFinishTransaction: true,
}, (res: unknown) => { }, (res : unknown) => {
console.log(res, '成功-restoreCompletedTransactions'); console.log(res, '成功-restoreCompletedTransactions');
res.map((item: any) => { res.map((item : any) => {
finishTransaction(item) finishTransaction(item)
}) })
resolve(res); resolve(res);
@@ -334,7 +324,7 @@
}) })
}); });
} }
/** /**
* 关闭订单 * 关闭订单
*/ */
@@ -493,13 +483,6 @@
} }
} }
/**
* 切换支付方式
*/
const choseType = () => {
// payType.value = val;
}
onMounted(() => { onMounted(() => {
getDevName(); getDevName();
getActivityDescriptionData() getActivityDescriptionData()

View File

@@ -16,10 +16,10 @@
<view class="title">{{$t('order.rechargeConsumptionList')}}</view> <view class="title">{{$t('order.rechargeConsumptionList')}}</view>
<view class="recharge-record-block" v-for="(item, index) in bookList" :key="index" @click="toDetails(item)"> <view class="recharge-record-block" v-for="(item, index) in bookList" :key="index" @click="toDetails(item)">
<view class="recharge-record-block-row">{{item.orderType}}<text <view class="recharge-record-block-row">{{item.orderType}}<text
:class="item.orderType !== '充值' ? 'text1' : 'text2'">{{item.orderType !== '充值' ? '' : '+'}}{{item.changeAmount}}</text> :class="item.changeAmount < 0 ? 'text1' : 'text2'">{{item.changeAmount < 0 ? '' : '+'}}{{item.changeAmount}}</text>
</view> </view>
<view class="recharge-record-block-row_">{{item.productName}}</view> <view class="recharge-record-block-row_">{{item.productName}}</view>
<view class="recharge-record-block-row_">{{$t('user.orderSn')}}{{item.payNo}}<wd-icon name="file-copy" <view class="recharge-record-block-row_" v-if="item.relationId">{{$t('user.orderSn')}}{{item.payNo}}<wd-icon name="file-copy"
size="14px" color="#65A1FA" style="margin-left: 10rpx;" @click="copyToClipboard()"></wd-icon> size="14px" color="#65A1FA" style="margin-left: 10rpx;" @click="copyToClipboard()"></wd-icon>
</view> </view>
<view class="time">{{item.createTime}}</view> <view class="time">{{item.createTime}}</view>
@@ -75,10 +75,14 @@
* 跳转订单详情 * 跳转订单详情
*/ */
const toDetails = (order: IOrder) => { const toDetails = (order: IOrder) => {
console.log(order.relationId, "order"); if (order.relationId) {
uni.navigateTo({ uni.navigateTo({
url: '/pages/user/order/details?orderId=' + order.relationId url: '/pages/user/order/details?orderId=' + order.relationId
}) })
} else {
uni.showToast({ title: t('user.cannotView'), icon: 'none' });
}
} }
</script> </script>

View File

@@ -4,7 +4,7 @@
<nav-bar :title="$t('vip.bookVip')" /> <nav-bar :title="$t('vip.bookVip')" />
<!-- VIP介绍卡片 --> <!-- VIP介绍卡片 -->
<view class="vip-intro-card"> <view class="vip-intro-card mt-2!">
<view class="vip-intro-header"> <view class="vip-intro-header">
<text class="vip-intro-title">📚 读书VIP特权</text> <text class="vip-intro-title">📚 读书VIP特权</text>
<!-- <text class="vip-intro-subtitle">畅享海量电子图书</text> --> <!-- <text class="vip-intro-subtitle">畅享海量电子图书</text> -->
@@ -58,14 +58,15 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue' import { ref } from 'vue'
import { onShow } from '@dcloudio/uni-app' import { onShow } from '@dcloudio/uni-app'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { vipApi } from '@/api/modules/vip' import { vipApi } from '@/api/modules/vip'
import type { IVipBook } from '@/types/vip'
const userStore = useUserStore() const userStore = useUserStore()
const vipList = ref([]) const vipList = ref<IVipBook[]>([])
const getVipList = async () => { const getVipList = async () => {
const res = await vipApi.getBookVipList() const res = await vipApi.getBookVipList()
// 模拟推荐标识,实际项目中应该从后端获取 // 模拟推荐标识,实际项目中应该从后端获取
@@ -100,7 +101,10 @@ onShow(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.page-wrapper { .page-wrapper {
padding: 20rpx; padding: 20rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); // background-image: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
background-color: #6E63C4;
background-size: cover;
background-position: center;
min-height: 100vh; min-height: 100vh;
} }

View File

@@ -19,9 +19,9 @@
import { ref } from 'vue' import { ref } from 'vue'
const menuItems = ref([ const menuItems = ref([
{ // {
name: '分享APP' // name: '分享APP'
}, // },
{ {
name: '关于我们', name: '关于我们',
} }
@@ -58,7 +58,7 @@
href: 'https://a.app.qq.com/o/simple.jsp?pkgname=com.cn.medicine', href: 'https://a.app.qq.com/o/simple.jsp?pkgname=com.cn.medicine',
title: "吴门医述", title: "吴门医述",
summary: "我正在使用吴门医述提升自己,赶紧跟我一起来体验吧!", summary: "我正在使用吴门医述提升自己,赶紧跟我一起来体验吧!",
imageUrl: "static/icon/home_icon_logo.png", imageUrl: "static/logo.png",
success: function (res) { success: function (res) {
console.log("success:" + JSON.stringify(res)); console.log("success:" + JSON.stringify(res));
}, },
@@ -75,7 +75,7 @@
href: 'https://a.app.qq.com/o/simple.jsp?pkgname=com.cn.medicine', href: 'https://a.app.qq.com/o/simple.jsp?pkgname=com.cn.medicine',
title: "吴门医述", title: "吴门医述",
summary: "我正在使用吴门医述提升自己,赶紧跟我一起来体验吧!", summary: "我正在使用吴门医述提升自己,赶紧跟我一起来体验吧!",
imageUrl: "static/icon/home_icon_logo.png", imageUrl: "static/logo.png",
success: function (res) { success: function (res) {
console.log("success:" + JSON.stringify(res)); console.log("success:" + JSON.stringify(res));
}, },

View File

Before

Width:  |  Height:  |  Size: 261 KiB

After

Width:  |  Height:  |  Size: 261 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -8,8 +8,6 @@
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace; "Courier New", monospace;
--color-red-500: oklch(63.7% 0.237 25.331); --color-red-500: oklch(63.7% 0.237 25.331);
--color-gray-300: oklch(87.2% 0.01 258.338);
--color-gray-500: oklch(55.1% 0.027 264.364);
--color-white: #fff; --color-white: #fff;
--spacing: 0.25rem; --spacing: 0.25rem;
--text-xs: 0.75rem; --text-xs: 0.75rem;
@@ -220,15 +218,6 @@
.mt-2\! { .mt-2\! {
margin-top: calc(var(--spacing) * 2) !important; margin-top: calc(var(--spacing) * 2) !important;
} }
.mt-2\.5\! {
margin-top: calc(var(--spacing) * 2.5) !important;
}
.mt-3 {
margin-top: calc(var(--spacing) * 3);
}
.mt-3\! {
margin-top: calc(var(--spacing) * 3) !important;
}
.mt-5 { .mt-5 {
margin-top: calc(var(--spacing) * 5); margin-top: calc(var(--spacing) * 5);
} }
@@ -244,21 +233,6 @@
.mt-\[20rpx\]\! { .mt-\[20rpx\]\! {
margin-top: 20rpx !important; margin-top: 20rpx !important;
} }
.mr-\[20rpx\] {
margin-right: 20rpx;
}
.mr-\[20rpx\]\! {
margin-right: 20rpx !important;
}
.mb-1 {
margin-bottom: calc(var(--spacing) * 1);
}
.mb-1\! {
margin-bottom: calc(var(--spacing) * 1) !important;
}
.mb-1\.5\! {
margin-bottom: calc(var(--spacing) * 1.5) !important;
}
.mb-2 { .mb-2 {
margin-bottom: calc(var(--spacing) * 2); margin-bottom: calc(var(--spacing) * 2);
} }
@@ -283,12 +257,6 @@
.ml-2\.5\! { .ml-2\.5\! {
margin-left: calc(var(--spacing) * 2.5) !important; margin-left: calc(var(--spacing) * 2.5) !important;
} }
.ml-\[20rpx\] {
margin-left: 20rpx;
}
.ml-\[20rpx\]\! {
margin-left: 20rpx !important;
}
.block { .block {
display: block; display: block;
} }
@@ -344,12 +312,6 @@
border-style: var(--tw-border-style); border-style: var(--tw-border-style);
border-width: 1px; border-width: 1px;
} }
.bg-gray-300 {
background-color: var(--color-gray-300);
}
.bg-gray-500 {
background-color: var(--color-gray-500);
}
.bg-white { .bg-white {
background-color: var(--color-white); background-color: var(--color-white);
} }
@@ -359,12 +321,6 @@
.p-0\! { .p-0\! {
padding: calc(var(--spacing) * 0) !important; padding: calc(var(--spacing) * 0) !important;
} }
.p-2 {
padding: calc(var(--spacing) * 2);
}
.p-2\.5 {
padding: calc(var(--spacing) * 2.5);
}
.p-3 { .p-3 {
padding: calc(var(--spacing) * 3); padding: calc(var(--spacing) * 3);
} }
@@ -374,9 +330,6 @@
.p-\[20rpx\] { .p-\[20rpx\] {
padding: 20rpx; padding: 20rpx;
} }
.p-\[20rpx\]\! {
padding: 20rpx !important;
}
.p-\[30rpx\] { .p-\[30rpx\] {
padding: 30rpx; padding: 30rpx;
} }

12
types/vip.d.ts vendored
View File

@@ -24,4 +24,16 @@ export interface IVipItemProduct {
fee: number | null, // 课程价格 fee: number | null, // 课程价格
lastFee?: number | null, // 未使用字段 lastFee?: number | null, // 未使用字段
[key: string]: any [key: string]: any
}
/**
* 电子书VIP套餐
*/
export interface IVipBook {
id: number
type: number
title: string
money: number // vip金额
days: number // vip天数
[key: string]: any
} }

View File

@@ -232,6 +232,18 @@ export function useUpload(): UseUploadReturn {
extension extension
}: ChooseFileOption): Promise<ChooseFile[]> { }: ChooseFileOption): Promise<ChooseFile[]> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if(uni.getSystemInfoSync().platform === 'ios') {
uni.chooseImage({
count: multiple ? maxCount : 1,
mediaType: ['image'],
sizeType,
sourceType,
extension,
success: (res) => resolve(formatImage(res)),
fail: reject
})
return
}
switch (accept) { switch (accept) {
case 'image': case 'image':
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN