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";
// #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') && !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
update();

View File

@@ -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', // 暂时用不到
},

View File

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

View File

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

View File

@@ -13,7 +13,6 @@ 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'
/**
* 课程相关API
@@ -55,9 +54,8 @@ export const courseApi = {
page: number,
limit: number
}) {
const userStore = useUserStore()
return skeletonClient.request<IMarketCourseListResponse>({
url: userStore.token ? 'medical/home/getMarketCourseList' : 'visitor/getMarketCourseList',
url: uni.getStorageSync('token') ? 'medical/home/getMarketCourseList' : 'visitor/getMarketCourseList',
method: 'POST',
data
})

View File

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

View File

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

View File

@@ -145,7 +145,7 @@
"updateFailed": "Update Failed",
"paymentMethod": "Payment Method",
"googlePay": "Google Pay",
"applePay": "Apple Pay",
"applePay": "In-App Purchase",
"agreeText": "I have agreed",
"agreement": "Recharge Agreement",
"agreeFirst": "Please agree to the recharge agreement first",
@@ -223,8 +223,8 @@
"migrateCodePlaceholder": "The code obtained from chinese account",
"migrateWarning": "Migration is irreversible, please proceed with caution!",
"migrateInstructions": "Migration Instructions",
"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",
"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, VIP and User Hufen 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.",
"alreadyMigrated": "You have already migrated:",
@@ -234,7 +234,9 @@
"certificate": "My certificate",
"iHufen": "My lake",
"hufenRecord": "Lake division record",
"hufen": "Hufen"
"hufen": "Hufen",
"backEnd" : "Back-end recharge",
"cannotView" : "The recharge in the background cannot be viewed"
},
"book": {
"title": "My Books",

View File

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

View File

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

View File

@@ -12,7 +12,7 @@
/>
<view class="icon-hua">
<image
src="../../static/home_icon.png"
src="../../static/book/home_icon.png"
mode="aspectFit"
class="icon-hua-img"
/>
@@ -35,16 +35,16 @@
<view class="mine-1">
<text class="mine-title">{{ $t('bookHome.block1') }}</text>
<view
v-if="data.page.records.length > 0"
v-if="data?.page?.records.length > 0"
class="mine-more"
@click="handleMoreClick"
>
{{ $t('bookHome.more') }}
<image src="@/static/icon/icon_right.png" />
</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
v-for="(item, index) in data.page.records"
v-for="(item, index) in data?.page?.records"
:key="index"
class="mine-item"
@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) => {
getPrompt()
if(!uni.getStorageSync('token')) return
uni.navigateTo({
url: `/pages/book/detail?id=${bookId}`
})
@@ -382,6 +384,8 @@ const handleMoreClick = () => {
* 处理活动标签点击
*/
const handleActivityLabelClick = async (labelId: number, index: number) => {
getPrompt()
if(!uni.getStorageSync('token')) return
currentActivityIndex.value = index
activityBooksSkeleton.value.reload()
}
@@ -404,6 +408,25 @@ const handleCategoryLevel2Click = async (labelId: number, index: number) => {
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
selectedFirstLevel.value = item
if (item === '医学') {
medicineMenuSkeletonRef.value.reload()
medicineMenuSkeletonRef.value?.reload()
} else {
menuSkeletonRef.value?.reload()
}
@@ -457,17 +457,16 @@ const requestAll = async () => {
* 页面挂载
*/
onMounted(() => {
if(!userStore.token) {
// 重置分类索引
currentIndex.value = 0
if(!uni.getStorageSync('state') && !uni.getStorageSync('token')) {
uni.navigateTo({
url: '/pages/login/login'
});
}
// 重置分类索引
currentIndex.value = 0
if(uni.getStorageSync('state')) uni.removeStorageSync('state')
// 请求所有数据
requestAll()
console.log('进来了2');
})
/**
@@ -485,7 +484,7 @@ onShow(() => {
// 刷新数据
// requestAll()
if(userStore.token){
if(uni.getStorageSync('token')){
getLearnCourse()
}
})
@@ -692,7 +691,7 @@ $border-color: #eeeeee;
width: 60rpx;
height: 60rpx;
background-size: 100% 100%;
background-image: url("@/static/soul/cate_bg.png");
background-image: url("@/static/icon/cate_bg.png");
border-radius: 4rpx;
display: flex;
align-items: center;
@@ -753,7 +752,7 @@ $border-color: #eeeeee;
width: 65rpx;
height: 78rpx;
background-size: 100% 100%;
background-image: url("@/static/soul/cate_bg.png");
background-image: url("@/static/icon/cate_bg.png");
border-radius: 4rpx;
display: flex;
align-items: center;

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
<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">
<wd-icon name="setting1" size="24px" color="#666" />
@@ -124,6 +124,13 @@
url: '/pages/user/myBook/index',
type: 'pageJump'
},
{
id: 8,
name: t('user.iHufen'),
url: '/pages/user/hufen/index',
type: 'pageJump',
hufenState: true
},
{
id: 3,
name: t('user.profile'),
@@ -142,29 +149,23 @@
url: '/pages/user/feedback/index',
type: 'pageJump'
},
// {
// id: 6,
// name: t('user.dataMigrate'),
// url: '/pages/user/migrate/index',
// desc: t('user.migrateSubtitle'),
// type: 'pageJump'
// }
{
id: 6,
name: t('user.dataMigrate'),
url: '/pages/user/migrate/index',
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()
const tokenState = ref(false)
/**
* 获取平台信息
@@ -190,7 +191,6 @@
*/
const getHufen = async () => {
hufenData.value = await getUserContributionData()
hufenData.value = await getUserContributionData()
}
/**
@@ -276,7 +276,9 @@
onShow(() => {
if (uni.getStorageSync('token')) {
tokenState.value = true
getData()
getHufen()
}
})

View File

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

View File

@@ -12,11 +12,11 @@
</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-row">{{item.remark.slice(0, (item.remark.indexOf(',')))}}<text
:class="item.actType === 1 ? 'text1' : 'text2'">{{item.actType === 1 ? '' : '+'}}{{item.changeAmount}}</text>
<view class="recharge-record-block-row">{{item.relationId ? item.remark.slice(0, (item.remark.indexOf(','))) : $t('user.backEnd')}}<text
:class="item.changeAmount < 0 ? 'text1' : 'text2'">{{item.changeAmount < 0 ? '' : '+'}}{{item.changeAmount}}</text>
</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>
</view>
</view>
@@ -69,10 +69,14 @@
* 跳转订单详情
*/
const toDetails = (order: IOrder) => {
console.log(order.relationId, "order");
if (order.relationId) {
uni.navigateTo({
url: '/pages/user/order/details?orderId=' + order.relationId
})
} else {
uni.showToast({ title: t('user.cannotView'), icon: 'none' });
}
}
</script>

View File

@@ -3,7 +3,7 @@
<!-- 自定义导航栏 -->
<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">活动充值金额</view>
<view class="recharge">
@@ -39,13 +39,11 @@
<view class="cha_fangsh">
<view class="cf_title">{{$t('user.paymentMethod')}}</view>
<view class="cf_radio">
<radio-group v-for="item in iosPaylist">
<radio-group>
<view>
<view :class="payType == item.id ? 'Tab_xf cf_xuanx' : 'cf_xuanx'">
<!-- <image class="pay_item_img" :src="item.imgUrl" mode="aspectFil">
</image> -->
<text>{{ item.title }}</text>
<radio :checked="payType === item.id" @click="choseType(item.id)"></radio>
<view class="cf_xuanx">
<text>{{ isAndroid ? $t('user.googlePay') : $t('user.applePay')}}</text>
<radio checked="true;" @click="choseType(item.id)"></radio>
</view>
</view>
</radio-group>
@@ -88,14 +86,6 @@
const userStore = useUserStore()
const { t } = useI18n()
const message = useMessage()
const payType = ref('1')
const iosPaylist = ref([
{
title: "Google Pay",
id: '1',
// imgUrl: "/static/icon/currency.png"
}
])
// 充值列表
const rechargeList = ref([])
// 金额列表单独每项
@@ -135,7 +125,7 @@
const eventAmountList = ref([])
//正常金额数据
const standardAmountList = ref([])
// 声明ios实例
const iapChannel = ref(null)
/**
@@ -148,7 +138,7 @@
console.log('运行Android上')
} else {
isAndroid.value = false;
qudao.value = 'Google'
qudao.value = 'IOS'
console.log('运行iOS上')
}
getData()
@@ -288,10 +278,7 @@
fail: (err) => {
console.log('支付错误', err);
restoreComplateRequest()
uni.showToast({
title: '关闭支付弹窗',
icon: 'none'
})
uni.showToast({ title: t('user.closeWindow'), icon: 'error' })
reject(err);
}
});
@@ -307,9 +294,12 @@
const obj = await getIosPayment(res.transactionIdentifier, res.payment.productid, res.payment.username, res.transactionReceipt, userStore.userInfo.id)
console.log(obj, '校验订单')
finishTransaction(res)
uni.switchTab({
url: '/pages/user/index'
})
} catch (error) {
console.error('校验订单失败:', error)
// 也需要释放订单,防止再次提交支付窗口拉不起来
// 也需要释放订单,防止失败再次提交支付窗口拉不起来
finishTransaction(res)
}
@@ -493,13 +483,6 @@
}
}
/**
* 切换支付方式
*/
const choseType = () => {
// payType.value = val;
}
onMounted(() => {
getDevName();
getActivityDescriptionData()

View File

@@ -16,10 +16,10 @@
<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-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 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>
</view>
<view class="time">{{item.createTime}}</view>
@@ -75,10 +75,14 @@
* 跳转订单详情
*/
const toDetails = (order: IOrder) => {
console.log(order.relationId, "order");
if (order.relationId) {
uni.navigateTo({
url: '/pages/user/order/details?orderId=' + order.relationId
})
} else {
uni.showToast({ title: t('user.cannotView'), icon: 'none' });
}
}
</script>

View File

@@ -4,7 +4,7 @@
<nav-bar :title="$t('vip.bookVip')" />
<!-- VIP介绍卡片 -->
<view class="vip-intro-card">
<view class="vip-intro-card mt-2!">
<view class="vip-intro-header">
<text class="vip-intro-title">📚 读书VIP特权</text>
<!-- <text class="vip-intro-subtitle">畅享海量电子图书</text> -->
@@ -58,14 +58,15 @@
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { useUserStore } from '@/stores/user'
import { vipApi } from '@/api/modules/vip'
import type { IVipBook } from '@/types/vip'
const userStore = useUserStore()
const vipList = ref([])
const vipList = ref<IVipBook[]>([])
const getVipList = async () => {
const res = await vipApi.getBookVipList()
// 模拟推荐标识,实际项目中应该从后端获取
@@ -100,7 +101,10 @@ onShow(() => {
<style lang="scss" scoped>
.page-wrapper {
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;
}

View File

@@ -19,9 +19,9 @@
import { ref } from 'vue'
const menuItems = ref([
{
name: '分享APP'
},
// {
// name: '分享APP'
// },
{
name: '关于我们',
}
@@ -58,7 +58,7 @@
href: 'https://a.app.qq.com/o/simple.jsp?pkgname=com.cn.medicine',
title: "吴门医述",
summary: "我正在使用吴门医述提升自己,赶紧跟我一起来体验吧!",
imageUrl: "static/icon/home_icon_logo.png",
imageUrl: "static/logo.png",
success: function (res) {
console.log("success:" + JSON.stringify(res));
},
@@ -75,7 +75,7 @@
href: 'https://a.app.qq.com/o/simple.jsp?pkgname=com.cn.medicine',
title: "吴门医述",
summary: "我正在使用吴门医述提升自己,赶紧跟我一起来体验吧!",
imageUrl: "static/icon/home_icon_logo.png",
imageUrl: "static/logo.png",
success: function (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",
"Courier New", monospace;
--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;
--spacing: 0.25rem;
--text-xs: 0.75rem;
@@ -220,15 +218,6 @@
.mt-2\! {
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 {
margin-top: calc(var(--spacing) * 5);
}
@@ -244,21 +233,6 @@
.mt-\[20rpx\]\! {
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 {
margin-bottom: calc(var(--spacing) * 2);
}
@@ -283,12 +257,6 @@
.ml-2\.5\! {
margin-left: calc(var(--spacing) * 2.5) !important;
}
.ml-\[20rpx\] {
margin-left: 20rpx;
}
.ml-\[20rpx\]\! {
margin-left: 20rpx !important;
}
.block {
display: block;
}
@@ -344,12 +312,6 @@
border-style: var(--tw-border-style);
border-width: 1px;
}
.bg-gray-300 {
background-color: var(--color-gray-300);
}
.bg-gray-500 {
background-color: var(--color-gray-500);
}
.bg-white {
background-color: var(--color-white);
}
@@ -359,12 +321,6 @@
.p-0\! {
padding: calc(var(--spacing) * 0) !important;
}
.p-2 {
padding: calc(var(--spacing) * 2);
}
.p-2\.5 {
padding: calc(var(--spacing) * 2.5);
}
.p-3 {
padding: calc(var(--spacing) * 3);
}
@@ -374,9 +330,6 @@
.p-\[20rpx\] {
padding: 20rpx;
}
.p-\[20rpx\]\! {
padding: 20rpx !important;
}
.p-\[30rpx\] {
padding: 30rpx;
}

12
types/vip.d.ts vendored
View File

@@ -25,3 +25,15 @@ export interface IVipItemProduct {
lastFee?: number | null, // 未使用字段
[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
}: ChooseFileOption): Promise<ChooseFile[]> {
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) {
case 'image':
// #ifdef MP-WEIXIN