浏览代码

merge 2024

wangguoyu 2 月之前
父节点
当前提交
23b5838a91

+ 12 - 0
api/pdf.js

@@ -0,0 +1,12 @@
+import request from '@/utils/request'
+export function getPDFUrl(data = {}) {
+    return request({
+        'url': '/app/user/my/tiku/pdf',
+        headers: {
+            isToken: true
+        },
+        method: 'post',
+        data,
+        timeout: 20000
+    })
+}

+ 55 - 0
components/dialog/nichengDialog.vue

@@ -0,0 +1,55 @@
+<!-- 小弹窗 一行文字 -->
+<template>
+	<uni-popup ref="tipSmallPopup" :animation="false" :is-mask-click="false"
+	 mask-background-color="rgba(255, 255, 255, 0.6);">
+	 <view class="ezy-tip-dialog tip-small-dialog duihuan-dialog">
+		<view class="tip-content-box">
+			<view class="tip-title">{{title}}</view>
+				<input class="duihuan-input" type="text" focus v-model="nichengValue" placeholder="请输入昵称" />
+				<view class="tip-btn-box">
+					<view class="not-confirm-btn" @click="handleClose"></view>
+					<view class="confirm-btn" @click="confirmBtn"></view>
+				</view>
+		</view>
+	 </view>
+	</uni-popup>
+</template>
+
+<script setup>
+	import { ref } from 'vue';
+	const props = defineProps({
+	  title: {
+	    type: String,
+	    default: '提示'
+	  },
+	  content: {
+	    type: String,
+		require: true,
+	    default: ''
+	  },
+	});
+	const tipSmallPopup = ref(null); // 索引
+	const nichengValue = ref(''); // 索引
+	const $emit = defineEmits(['confirm-btn'])
+	// 打开弹窗
+	function handleShow() {
+		tipSmallPopup.value.open();
+	}
+	// 取消
+	function handleClose() {
+		nichengValue.value = ''
+		tipSmallPopup.value.close();
+	}
+	// 确认
+	function confirmBtn(){
+		$emit('confirm-btn',nichengValue.value);
+		tipSmallPopup.value.close();
+		nichengValue.value = ''
+	}
+	defineExpose({
+			handleShow
+		})
+</script>
+
+<style>
+</style>

+ 52 - 0
pages/my/banbenConfirmDialog.vue

@@ -0,0 +1,52 @@
+<!-- 生成题库弹窗 -->
+<template>
+ <uni-popup ref="tipBigPopup" :animation="false" :is-mask-click="false"
+  mask-background-color="rgba(255, 255, 255, 0.6);">
+  <view class="sxtk-sc-dialog">
+  <view class="tip-content-box">
+   <view class="tip-title">{{title}}</view>
+   <view class="tip-content" v-if="content">{{content}}</view>
+   <view class="tip-btn-box">
+    <view class="confirm-btn" @click="confirmBtn">生成</view>
+    <view class="not-confirm-btn" @click="handleClose">取消</view>
+   </view>
+  </view>
+  </view>
+ </uni-popup>
+</template>
+
+<script setup>
+ import { ref } from 'vue';
+ const props = defineProps({
+   title: {
+     type: String,
+     default: '温馨提示'
+   },
+   content: {
+     type: String,
+     default: ''
+   },
+ });
+ const tipBigPopup = ref(null); // 索引
+ const $emit = defineEmits(['confirm-btn'])
+ // 打开弹窗
+ function handleShow() {
+  tipBigPopup.value.open();
+ }
+ // 取消
+ function handleClose() {
+  tipBigPopup.value.close();
+ }
+ // 确认
+ function confirmBtn(){
+  $emit('confirm-btn');
+  tipBigPopup.value.close();
+ }
+ defineExpose({
+   handleShow,
+   handleClose
+  })
+</script>
+
+<style>
+</style>

+ 175 - 0
pages/my/headImg.vue

@@ -0,0 +1,175 @@
+<template>
+	<view class="ezy-ghtx-page">
+		<view class="icon-title-navBar-box">
+			<view @click="handleBack" class="nav-bar-icon"></view>
+			<text class="nav-bar-title">更换头像</text>
+		</view>
+		<img class="ghtx-img" :src="userImg" alt="">
+
+		<view @click="chooseImage" class="xc-btn">相册</view>
+		<view @click="handleBack" class="qx-btn">取消</view>
+	</view>
+</template>
+
+<script setup>
+	import agreeContentDialog from '@/pages/login/agreeContentDialog.vue';
+	import {
+		toast,
+		getUserIdentity
+	} from "@/utils/common";
+	import cacheManager from '@/utils/cacheManager.js';
+	import {
+		getFilePolicy,
+		updataHead,myInfo
+	} from '@/api/my.js'
+	import {
+		onLoad
+	} from '@dcloudio/uni-app';
+	import axios from 'axios';
+	import {
+		reactive,
+		ref
+	} from "vue";
+	import {
+		onShow
+	} from '@dcloudio/uni-app';
+
+	let userImg = ref(null);
+	let currentPlatform = ref(null);
+	const tempPath = ref('')
+	const checkAlbumPermission = async () => {
+		const status = await uni.getSetting()
+		if (!status.authSetting['scope.album']) {
+			await uni.authorize({
+				scope: 'scope.album'
+			})
+		}
+	}
+	const chooseImage = async () => {
+		try {
+			await checkAlbumPermission()
+			uni.chooseImage({
+				count: 1,
+				sizeType: ['compressed'],
+				sourceType: ['album'], // 仅限相册选择‌:ml-citation{ref="1" data="citationList"}
+				success: (res) => {
+
+					uploadFile(res.tempFilePaths[0])
+				},
+				fail: (err) => {
+					console.error('选择失败:', err)
+				}
+			})
+		} catch (err) {
+			uni.showModal({
+				title: '权限申请失败',
+				content: '请前往设置开启相册权限'
+			})
+		}
+	}
+	function updateIcon(data){
+		updataHead({icon:data}).then(res=>{
+			if(res.code ==0){
+			uni.showToast({
+				title: '上传成功',
+				icon: 'success'
+			});	
+			}else{
+				uni.showToast({
+					title: '上传失败',
+				});
+			}
+		})
+	}
+	function uploadFile(filePath) {
+		const suffix = filePath.split('.').pop();
+		let req = {
+			prefix: 'resource/',
+			suffix: suffix
+		}
+		getFilePolicy(req).then(res => {
+			if (res.code === 0) {
+				const policyData = res.data;
+				console.log('policyData', policyData);
+				uni.uploadFile({
+					url: policyData.uploadUrl,
+					filePath: filePath,
+					name: 'file',
+					formData: {
+						key: policyData.key,
+						policy: policyData.policy,
+						OSSAccessKeyId: policyData.accessid,
+						signature: policyData.signature,
+						success_action_status: '200'
+					},
+					header: {
+						'Content-Type': 'multipart/form-data'
+					},
+					success(uploadRes) {
+						console.log('uploadRes', uploadRes);
+						if (uploadRes.statusCode === 200) {
+							userImg.value = `${policyData.downloadUrl}/${policyData.key}`;					
+							updateIcon(userImg.value)
+						} else {
+							uni.showToast({
+								title: '阿里云上传错误,请重试!',
+							});
+							return false
+						}
+					},
+					fail(err) {
+						console.log('err', err);
+					}
+				});
+
+
+			}
+		})
+
+	}
+
+
+
+	function handleBack() {
+		uni.redirectTo({
+			url: '/pages/my/yingyongshezhi'
+		})
+	}
+
+	function openXiangce2() {
+
+	}
+
+
+	function openXiangce() {
+
+	}
+
+	function isIOSorAndroid() {
+		const systemInfo = uni.getSystemInfoSync();
+
+		console.log('systemInfo', systemInfo);
+
+		if (systemInfo.platform == 'ios') {
+			return currentPlatform.value = 'ios'
+		} else {
+			return currentPlatform.value = 'android'
+		}
+	}
+	function getMyInfo() {
+			myInfo({}).then(res => {
+				if (res.code == 0) {
+					userImg.value = res.data.icon;
+				} else {
+					toast('获取头像失败')
+					return false
+				}
+	
+			})
+		}
+			
+	onLoad((options) => {
+		isIOSorAndroid();
+		getMyInfo();
+	})
+</script>

+ 146 - 0
pages/my/sxtkPage.vue

@@ -0,0 +1,146 @@
+<template>
+	<view class="ezy-sxtk-page">
+		<view class="icon-title-navBar-box">
+			<view @click="handleBack" class="nav-bar-icon"></view>
+			<text class="nav-bar-title">数学题库</text>
+		</view>
+		<view class="ezy-tab-border sxtk-tab-border">
+			<view class="tab-img"></view>
+			<view class="sxtk-tab-box">
+				<view v-for="(item,index) in jiaocaiData" :key="index"  class="tab-item"
+				 @click="selectNianji(item,index)" :class="{'active': currentNianjiName == item.nianji}">
+					<view class="tab-nianji-item">{{item.nianji}}</view>
+				</view>
+			</view>
+			<view class="sxtk-line"></view>
+			<view class="sxtk-banben-body">
+				<view v-for="(item,index) in currentBanbenList" :key="index" class="banben-item"
+				:class="{'active': banbenName == item}" @click="selectBanben(item,index)">
+					<view class="banben-text-item">{{item}}</view>
+				</view>
+			</view>
+			<view class="sxtk-line"></view>
+			<button class="sxtk-confirm-btn" @click="handleConfirm"></button>
+		</view>
+		<banbenConfirmDialog ref="jiaocaiRef" @confirm-btn="jcConfirm" :content="jcContent"></banbenConfirmDialog>
+		<CustomTabBar ></CustomTabBar>
+	</view>
+</template>
+
+<script setup>
+	import {
+		onLoad
+	} from '@dcloudio/uni-app';
+		import CustomTabBar from '@/components/custom-tabbar/custom-tabbar.vue';
+	import {
+		selectTiku
+	} from '@/api/my.js'
+	import {
+		toast,
+		getUserIdentity
+	} from "@/utils/common";
+	import * as httpApi from "@/api/pdf.js"
+	import {
+		ref
+	} from "vue";
+	import banbenConfirmDialog from './banbenConfirmDialog.vue';
+	let jiaocaiData = ref(null)
+	let currentBanbenList = ref([])
+
+	let currentNianjiName = ref('L1')
+	let currentBanbenIndex = ref(null)
+	const banbenName = ref(null)
+	const jiaocaiRef = ref(null);
+	const jcContent = ref(null);
+
+	function selectNianji(item, index) {
+		currentNianjiName.value = item.nianji
+
+		currentBanbenList.value = item.banbenList
+		banbenName.value = ''
+
+	}
+
+	function jcConfirm() {
+		httpApi.getPDFUrl({
+		  banben:banbenName.value,
+		  nianji:currentNianjiName.value,
+		}).then(res1 => {
+			uni.downloadFile({
+			  url: res1.data,
+			  success: function (res) {
+			    var filePath = res.tempFilePath;
+			    uni.openDocument({
+			      filePath: filePath,
+			      showMenu: true,
+			      success: function (res) {
+			        console.log('打开文档成功');
+					jiaocaiRef.value.handleClose();
+			      }
+			    });
+			  }
+			});
+		})
+	
+		/* uni.navigateTo({
+			url: '/pages/pdfPage/pdfPage?banben=' + banbenName.value + '&nianji=' + currentNianjiName.value
+		}); */
+	}
+
+	function selectBanben(item, index) {
+
+		console.log('item', item);
+		if (!currentNianjiName.value) {
+			toast("请选择年级")
+			return false
+		}
+
+		banbenName.value = item
+
+	}
+
+	function handleBack() {
+		uni.redirectTo({
+			url: '/pages/my/index'
+		});
+	}
+
+	function handleConfirm() {
+		// 确认逻辑
+		if (banbenName.value && currentNianjiName.value) {
+			jcContent.value = "用户你好,鹅状元将为您随机生成《" + banbenName.value + "》100道试题."
+			console.log('jcContent.value', jcContent.value);
+			jiaocaiRef.value.handleShow();
+		} else {
+			toast("请选择年级和对应的教学版本")
+			return false
+		}
+	}
+
+	function getInfo() {
+		selectTiku({}).then(res => {
+			// jiaocaiData.value = [{
+			// 		"nianji": "L1",
+			// 		"banbenList": ["人教版"]
+			// 	},
+			// 	{
+			// 		"nianji": "L2",
+			// 		"banbenList": ["人教版222", "人教版222333"]
+			// 	}
+			// ]
+			jiaocaiData.value = res.data
+			// 默认显示第一个年级的版本列表
+			if (jiaocaiData.value && jiaocaiData.value.length > 0) {
+				currentBanbenList.value = jiaocaiData.value[0].banbenList
+			}
+		})
+	}
+
+	onLoad((options) => {
+		if (options.banben && options.nianji) {
+			currentNianjiName.value = options.nianji
+			banbenName.value = options.banben
+		}
+		getInfo()
+	})
+</script>

+ 394 - 0
pages/my/xuexiJilu.vue

@@ -0,0 +1,394 @@
+<template>
+	<view class="ezy-xxjl-page">
+		<view class="icon-title-navBar-box">
+			<view @click="handleBack" class="nav-bar-icon"></view>
+			<text class="nav-bar-title">学习记录</text>
+		</view>
+		<view class="ezy-tab-border">
+			<uni-segmented-control :current="data.current" :values="data.items" active-color="#3A7FE9"
+				@clickItem="onChangeTab" class="ezy-tab-box" />
+			<view class="xxjl-content-box">
+				<view v-if="data.current === 0">
+					<scroll-view scroll-y="true" refresher-enabled="true" :refresher-triggered="data.shuxue.loading"
+						:refresher-threshold="50" refresher-background="transparent" @refresherrefresh="onRefresh"
+						class="xxjl-scroll-view">
+						<!--数学-->
+						<uni-list>
+							<uni-list-item v-for="item in data.shuxue.list" class="xxjl-item-box">
+								<template v-slot:body>
+									<view @click="goDao(item)">
+										<view class="item-date-row">
+											<view class="data-item">
+												<icon class="data-icon"></icon>
+												<text>{{ item.createTime }}</text>
+											</view>
+											<!-- 这里加点击事件 wgy看这里 -->
+											<view class="data-item del-item">
+												<icon @click.stop="deleteJilu(item)" class="del-icon"></icon>
+											</view>
+										</view>
+										<view class="item-zhang-row">
+											<icon class="zhang-icon"></icon>
+											<view>{{ item.levelName }}</view>
+										</view>
+										<view class="item-jie-row">
+											<text>{{ item.zhangName }}</text>
+										</view>
+										<view class="item-jie-row">
+											<text>{{ item.jieName }}</text>
+										</view>
+									</view>
+
+								</template>
+							</uni-list-item>
+							<uni-load-more :status="data.shuxue.state" @click="getMore(0)"
+								:contentText="data.shuxue.contentText"></uni-load-more>
+						</uni-list>
+					</scroll-view>
+				</view>
+				<view v-if="data.current === 1">
+					<scroll-view scroll-y="true" refresher-enabled="true" :refresher-triggered="data.yingyu.loading"
+						:refresher-threshold="50" refresher-background="transparent" @refresherrefresh="onRefresh"
+						class="xxjl-scroll-view">
+						<!--英语-->
+						<uni-list>
+							<uni-list-item v-for="item in data.yingyu.list" class="xxjl-item-box">
+								<template v-slot:body>
+									<view>
+										<view class="item-date-row">
+											<view class="data-item">
+												<icon class="data-icon"></icon>
+												<text>{{ item.createTime }}</text>
+											</view>
+											<!-- 这里加点击事件 wgy看这里 -->
+											<view class="data-item del-item">
+												<icon @click.stop="deleteJilu(item)" class="del-icon"></icon>
+											</view>
+										</view>
+										<view class="item-zhang-row">
+											<icon class="zhang-icon"></icon>
+											<view>{{ item.levelName }}</view>
+										</view>
+										<view class="item-jie-row">
+											<text>{{ item.zhangName }}</text>
+										</view>
+										<view class="item-jie-row">
+											<text>{{ item.jieName }}</text>
+										</view>
+									</view>
+								</template>
+							</uni-list-item>
+							<uni-load-more :status="data.yingyu.state" @click="getMore(1)"
+								:contentText="data.yingyu.contentText"></uni-load-more>
+						</uni-list>
+					</scroll-view>
+				</view>
+			</view>
+		</view>
+		<tip-small-dialog ref="deleteJiluDialogRef" @confirm-btn="deleteJiluBtn"
+			:content="deleteJiluContent"></tip-small-dialog>
+		<CustomTabBar></CustomTabBar>
+	</view>
+</template>
+
+<script setup>
+	import {
+		reactive,
+		ref
+	} from "vue";
+	import {
+		xuexiJilu,
+		xuexiJiluDelete
+	} from "@/api/my.js";
+	import {
+		onLoad
+	} from "@dcloudio/uni-app";
+	import cuoti from "@/components/chengji/chengji.vue";
+	import tipSmallDialog from '@/components/dialog/tipSmallDialog.vue';
+	import {
+		getWrongInfo
+	} from "@/api/wrong";
+	import {
+		toast,
+		getUserIdentity
+	} from "@/utils/common";
+	import CustomTabBar from '@/components/custom-tabbar/custom-tabbar.vue';
+	import cacheManager from "@/utils/cacheManager.js"
+	const zhangId = ref(null);
+	const nianji = ref(null);
+	const subjectId = ref(null);
+	const deleteJiluDialogRef = ref(null);
+	const deleteJiluContent = '你确定要执行这个操作吗?';
+	const wrongRef = ref(null);
+	const deleteId = ref('');
+
+	const data = reactive({
+		items: ['数学', '英语'],
+		current: 0,
+		shuxue: {
+			page: 0,
+			list: [],
+			loading: false,
+			state: 'more',
+			contentText: {
+				contentdown: '查看更多',
+				contentrefresh: '加载中',
+				contentnomore: '没有更多'
+			}
+
+		},
+		yingyu: {
+			page: 0,
+			list: [],
+			loading: false,
+			state: 'more',
+			contentText: {
+				contentdown: '查看更多',
+				contentrefresh: '加载中',
+				contentnomore: '没有更多'
+			}
+		},
+		wrongList: [],
+	})
+	subjectId.value = data.current + 1;
+
+
+	function goDao(data) {
+		const auth = cacheManager.get('auth');
+		cacheManager.updateObject('auth', {
+			levelId: data.levelId,
+			zhangId: data.zhangId,
+		})
+		cacheManager.remove('zhangInfo')
+		uni.redirectTo({
+			url: `/pages/study/index`
+		})
+
+	}
+
+	function deleteJilu(item) {
+		deleteId.value = item.id
+		deleteJiluDialogRef.value.handleShow();
+	}
+
+	function deleteJiluBtn(id) {
+		let req = {
+			id: deleteId.value
+		}
+		xuexiJiluDelete(req).then(res => {
+			if (res.code == 0) {
+				if (data.current === 0) {
+					data.shuxue.list = [];
+					data.shuxue.page = 0;
+				} else {
+					data.yingyu.list = [];
+					data.yingyu.page = 0;
+				}
+				// 重新加载数据
+				refreshData(data.current);
+			} else {
+				toast('失败,请稍后重试')
+			}
+		}).catch(err => {
+			toast('失败,请稍后重试')
+		})
+	}
+
+	function handleBack() {
+		uni.redirectTo({
+			url: '/pages/my/index'
+		})
+		uni.$emit('back-outpage')
+	}
+
+	function handleBackFromCuoti() {
+		wrongRef.value.closePopup();
+		uni.$emit('back-outpage')
+	}
+
+	function onChangeTab(e) {
+		if (data.current !== e.currentIndex) {
+			data.current = e.currentIndex;
+			subjectId.value = data.current + 1;
+			if (data.current == 0) {
+				data.shuxue.page = 0
+			} else if (data.current == 1) {
+				data.yingyu.page = 0
+			}
+			refreshData(data.current);
+		}
+	}
+
+	function refreshData(code) {
+		const opt = {
+			page: 1,
+			size: 10, // 固定查询10条
+			subjectId: data.current + 1 // 前台索引加1为学科cardId
+		}
+
+		if (code == 0) {
+			data.shuxue.list = [];
+			// 数学
+			data.shuxue.state = 'loading';
+			data.shuxue.page++;
+			opt.page = data.shuxue.page;
+		} else if (code == 1) {
+			data.yingyu.list = [];
+			// 英语
+			data.yingyu.state = 'loading';
+			data.yingyu.page++;
+			opt.page = data.yingyu.page;
+		}
+		xuexiJilu(opt).then(res => {
+			if (code == 0) {
+				data.shuxue.list = data.shuxue.list.concat(res.data.data);
+				data.shuxue.loading = false;
+			} else if (code == 1) {
+				data.yingyu.list = data.yingyu.list.concat(res.data.data);
+				data.yingyu.loading = false;
+			}
+			if (code == 0) {
+				if (res.data.total > data.shuxue.list.length) {
+					// 数学
+					data.shuxue.state = 'more';
+					data.shuxue.loading = false;
+				} else {
+					// 数学
+					data.shuxue.state = 'no-more';
+					data.shuxue.loading = false;
+
+				}
+			} else if (code == 1) {
+				if (res.data.total > data.yingyu.list.length) {
+					// 英语
+					data.yingyu.state = 'more';
+					data.yingyu.loading = false;
+				} else {
+					// 英语
+					data.yingyu.state = 'no-more';
+					data.yingyu.loading = false;
+				}
+			}
+		}).catch(err => {
+			if (code == 0) {
+				// 数学
+				data.shuxue.state = 'more';
+				data.shuxue.loading = false;
+			} else if (code == 1) {
+				// 英语
+				data.yingyu.state = 'more';
+				data.yingyu.loading = false;
+			}
+		})
+	}
+
+	function getMore(code) {
+		console.log('12312312312');
+		const opt = {
+			page: 1,
+			size: 10, // 固定查询10条
+			subjectId: data.current + 1 // 前台索引加1为学科cardId
+		}
+
+		if (code == 0) {
+
+			if (data.shuxue.state == 'no-more') return;
+			// 数学
+			data.shuxue.state = 'loading';
+			data.shuxue.page++;
+			opt.page = data.shuxue.page;
+		} else if (code == 1) {
+			// 英语
+			if (data.yingyu.state == 'no-more') return;
+			data.yingyu.state = 'loading';
+			data.yingyu.page++;
+			opt.page = data.yingyu.page;
+		}
+		xuexiJilu(opt).then(res => {
+			if (code == 0) {
+				data.shuxue.list = data.shuxue.list.concat(res.data.data);
+				data.shuxue.loading = false;
+			} else if (code == 1) {
+				data.yingyu.list = data.yingyu.list.concat(res.data.data);
+				data.yingyu.loading = false;
+			}
+			if (code == 0) {
+				if (res.data.total > data.shuxue.list.length) {
+					// 数学
+					data.shuxue.state = 'more';
+					data.shuxue.state_text = '加载更多';
+					data.shuxue.loading = false;
+				} else {
+					// 数学
+					data.shuxue.state = 'no-more';
+					data.shuxue.state_text = '没有更多啦';
+
+					data.shuxue.loading = false;
+				}
+			} else if (code == 1) {
+				if (res.data.total > data.yingyu.list.length) {
+					// 英语
+					data.yingyu.state = 'more';
+					data.yingyu.state_text = '加载更多';
+					data.yingyu.loading = false;
+				} else {
+					// 英语
+					data.yingyu.state = 'no-more';
+					data.yingyu.state_text = '没有更多啦';
+
+					data.yingyu.loading = false;
+				}
+			}
+		}).catch(err => {
+			if (code == 0) {
+				// 数学
+				data.shuxue.state = 'more';
+				data.shuxue.state_text = '加载更多';
+				data.shuxue.loading = false;
+			} else if (code == 1) {
+				// 英语
+				data.yingyu.state = 'more';
+				data.yingyu.state_text = '加载更多';
+				data.yingyu.loading = false;
+			}
+		})
+	}
+
+	// function formatListToUse(list) {
+	// 	list.forEach((item, index) => {
+	// 		item.mta_show = false;
+	// 		if (item.type == 3) {
+	// 			item.result = JSON.parse(item.result);
+	// 			item.placeholders = item.result.map((item, cindex) => `[bank${cindex+1}]`)
+	// 			item.reply = item.reply ? JSON.parse(item.reply) : item.result.map(() => '');
+	// 		}
+
+	//      if (item.type == 4) {
+	//        // 特殊题型英语题
+	//        const audioList = item.audios ? item.audios.split(',') : [];
+	//        item.placeholders = audioList.map((item, cindex) => `[yingyu${cindex+1}]`)
+	//        item.audioList = audioList;
+	//      }
+	// 	})
+	// }
+	function onRefresh() {
+		if (data.current == 0) {
+			data.shuxue.page = 0;
+			data.shuxue.list = [];
+			data.shuxue.loading = true;
+		} else if (data.current == 1) {
+			data.yingyu.page = 0;
+			data.yingyu.list = [];
+			data.yingyu.loading = true;
+		}
+		refreshData(data.current);
+	}
+
+	onLoad(() => {
+		getMore(data.current);
+	})
+</script>
+
+<style>
+
+</style>

+ 270 - 0
pages/my/xuexishichang.vue

@@ -0,0 +1,270 @@
+<template>
+	<view class="ezy-cuoti-page">
+		<view class="icon-title-navBar-box">
+			<view @click="handleBack" class="nav-bar-icon"></view>
+			<text class="nav-bar-title">关于我们</text>
+		</view>
+		<text>学习时长</text>
+		<CustomTabBar></CustomTabBar>
+	</view>
+</template>
+
+<script setup>
+	import {
+		reactive,
+		ref
+	} from "vue";
+	import {
+		getWrongData
+	} from "@/api/wrong";
+	import {
+		onLoad
+	} from "@dcloudio/uni-app";
+	import cuoti from "@/components/chengji/chengji.vue";
+	import {
+		getWrongInfo
+	} from "@/api/wrong";
+	import CustomTabBar from '@/components/custom-tabbar/custom-tabbar.vue';
+
+	const zhangId = ref(null);
+	const nianji = ref(null);
+	const subjectId = ref(null);
+
+	const wrongRef = ref(null);
+
+	const data = reactive({
+		items: ['数学', '英语'],
+		current: 0,
+		shuxue: {
+			page: 0,
+			list: [],
+			loading: false,
+			state: 'more',
+			contentText: {
+				contentdown: '查看更多',
+				contentrefresh: '加载中',
+				contentnomore: '没有更多'
+			}
+
+		},
+		yingyu: {
+			page: 0,
+			list: [],
+			loading: false,
+			state: 'more',
+			contentText: {
+				contentdown: '查看更多',
+				contentrefresh: '加载中',
+				contentnomore: '没有更多'
+			}
+		},
+		wrongList: [],
+	})
+	subjectId.value = data.current+1;
+	function handleBack() {
+		uni.redirectTo({
+			url: '/pages/my/index'
+		})
+	}
+
+	function handleBackFromCuoti() {
+		wrongRef.value.closePopup();
+		uni.$emit('back-outpage')
+	}
+
+	function onChangeTab(e) {
+		if (data.current !== e.currentIndex) {
+			data.current = e.currentIndex;
+			subjectId.value = data.current+1;
+			if (data.current == 0) {
+				data.shuxue.page = 0
+			} else if (data.current == 1) {
+				data.yingyu.page = 0
+			}
+			refreshData(data.current);
+		}
+	}
+
+	function refreshData(code) {
+		const opt = {
+			page: 1,
+			size: 10, // 固定查询10条
+			subjectId: data.current + 1 // 前台索引加1为学科cardId
+		}
+
+		if (code == 0) {
+			data.shuxue.list = [];
+			// 数学
+			data.shuxue.state = 'loading';
+			data.shuxue.page++;
+			opt.page = data.shuxue.page;
+		} else if (code == 1) {
+			data.yingyu.list = [];
+			// 英语
+			data.yingyu.state = 'loading';
+			data.yingyu.page++;
+			opt.page = data.yingyu.page;
+		}
+		getWrongData(opt).then(res => {
+			if (code == 0) {
+				data.shuxue.list = data.shuxue.list.concat(res.data.data);
+				data.shuxue.loading = false;
+			} else if (code == 1) {
+				data.yingyu.list = data.yingyu.list.concat(res.data.data);
+				data.yingyu.loading = false;
+			}
+			if (code == 0) {
+				if (res.data.total > data.shuxue.list.length) {
+					// 数学
+					data.shuxue.state = 'more';
+					data.shuxue.loading = false;
+				} else {
+					// 数学
+					data.shuxue.state = 'no-more';
+					data.shuxue.loading = false;
+				
+				}
+			} else if (code == 1) {
+				if (res.data.total > data.yingyu.list.length) {
+					// 英语
+					data.yingyu.state = 'more';
+					data.yingyu.loading = false;
+				} else {
+					// 英语
+					data.yingyu.state = 'no-more';
+					data.yingyu.loading = false;
+				}
+			}
+		}).catch(err => {
+			if (code == 0) {
+				// 数学
+				data.shuxue.state = 'more';
+				data.shuxue.loading = false;
+			} else if (code == 1) {
+				// 英语
+				data.yingyu.state = 'more';
+				data.yingyu.loading = false;
+			}
+		})
+	}
+
+	function getMore(code) {
+		const opt = {
+			page: 1,
+			size: 10, // 固定查询10条
+			subjectId: data.current + 1 // 前台索引加1为学科cardId
+		}
+
+		if (code == 0) {
+			if (data.shuxue.state == 'no-more') return;
+			// 数学
+			data.shuxue.state = 'loading';
+			data.shuxue.page++;
+			opt.page = data.shuxue.page;
+		} else if (code == 1) {
+			// 英语
+			if (data.yingyu.state == 'no-more') return;
+			data.yingyu.state = 'loading';
+			data.yingyu.page++;
+			opt.page = data.yingyu.page;
+		}
+		getWrongData(opt).then(res => {
+			if (code == 0) {
+				data.shuxue.list = data.shuxue.list.concat(res.data.data);
+				data.shuxue.loading = false;
+			} else if (code == 1) {
+				data.yingyu.list = data.yingyu.list.concat(res.data.data);
+				data.yingyu.loading = false;
+			}
+			if (code == 0) {
+				if (res.data.total > data.shuxue.list.length) {
+					// 数学
+					data.shuxue.state = 'more';
+					data.shuxue.state_text = '加载更多';
+					data.shuxue.loading = false;
+				} else {
+					// 数学
+					data.shuxue.state = 'no-more';
+					data.shuxue.state_text = '没有更多啦';
+				
+					data.shuxue.loading = false;
+				}
+			} else if (code == 1) {
+				if (res.data.total > data.yingyu.list.length) {
+					// 英语
+					data.yingyu.state = 'more';
+					data.yingyu.state_text = '加载更多';
+					data.yingyu.loading = false;
+				} else {
+					// 英语
+					data.yingyu.state = 'no-more';
+					data.yingyu.state_text = '没有更多啦';
+			
+					data.yingyu.loading = false;
+				}
+			}
+		}).catch(err => {
+			if (code == 0) {
+				// 数学
+				data.shuxue.state = 'more';
+				data.shuxue.state_text = '加载更多';
+				data.shuxue.loading = false;
+			} else if (code == 1) {
+				// 英语
+				data.yingyu.state = 'more';
+				data.yingyu.state_text = '加载更多';
+				data.yingyu.loading = false;
+			}
+		})
+	}
+
+	function formatListToUse(list) {
+		list.forEach((item, index) => {
+			item.mta_show = false;
+			if (item.type == 3) {
+				item.result = JSON.parse(item.result);
+				item.placeholders = item.result.map((item, cindex) => `[bank${cindex+1}]`)
+				item.reply = item.reply ? JSON.parse(item.reply) : item.result.map(() => '');
+			}
+
+      if (item.type == 4) {
+        // 特殊题型英语题
+        const audioList = item.audios ? item.audios.split(',') : [];
+        item.placeholders = audioList.map((item, cindex) => `[yingyu${cindex+1}]`)
+        item.audioList = audioList;
+      }
+		})
+	}
+
+	function getCuotiData(item) {
+		getWrongInfo({
+			subjectId: data.current + 1,
+			cdate: item.cdate
+		}).then(res => {
+			formatListToUse(res.data)
+			data.wrongList = res.data;
+			wrongRef.value.showPopup();
+		})
+	}
+
+	function onRefresh() {
+		if (data.current == 0) {
+			data.shuxue.page = 0;
+			data.shuxue.list = [];
+			data.shuxue.loading = true;
+		} else if (data.current == 1) {
+			data.yingyu.page = 0;
+			data.yingyu.list = [];
+			data.yingyu.loading = true;
+		}
+		refreshData(data.current);
+	}
+
+	onLoad(() => {
+		getMore(data.current);
+	})
+</script>
+
+<style>
+
+</style>

+ 390 - 0
pages/my/yingyongshezhi.vue

@@ -0,0 +1,390 @@
+<template>
+	<view class="ezy-yysz-page">
+		<view class="icon-title-navBar-box">
+			<view @click="handleBack" class="nav-bar-icon"></view>
+			<text class="nav-bar-title">应用设置</text>
+		</view>
+		<view class="ezy-tab-border">
+			<view class="yysz-row-box">
+				<view class="yysz-item img-item" @click="headClick">
+					<text>头像</text>
+					<icon class="yysz-img-box"
+						:style="{backgroundImage: 'url(' + myInfoData.icon + ')'}"></icon>
+				</view>
+				<view class="yysz-item" @click="nichengClick">
+					<text>昵称</text>
+					<text>{{myInfoData.nickName}}</text>
+				</view>
+			</view>	
+			<view class="yysz-row-box">
+				<view class="yysz-item" @click="telClick">
+					<text>手机号码</text>
+					<text>{{myInfoData.userName}}</text>
+				</view>
+			</view>
+			<view class="yysz-row-box">	
+				<view class="yysz-item" @click="aboutClick">
+					<text>关于我们</text>
+				</view>
+				<view v-if="loginFlag" class="yysz-item" @click="yinsizhengce">
+					<text>隐私政策</text>
+				</view>
+				<view class="yysz-item" @click="kefudianhua">
+					<text>客服与投诉</text>
+					<text>4001750778</text>
+				</view>
+				<!--<view v-if="loginFlag" class="yysz-item" @click="yonghuzhuxiao">
+					<icon class="list-icon zhuxiao-icon"></icon>
+					<text>用户注销</text>
+				</view>
+				 <view class="yysz-item" @click="exitLogin">
+					<icon class="list-icon login-out-icon"></icon>
+					<text>退出登录</text>
+				</view> -->
+		</view>
+		</view>
+		<CustomTabBar :levelId="levelId" :currentTabNumber="3" :typeId="typeId" :subjectId="subjectId"
+			:tipFlag="tipFlag">
+		</CustomTabBar>
+		<tip-small-dialog ref="exitDialogRef" @confirm-btn="exitBtn" :content="tipContent"></tip-small-dialog>
+		<tip-small-dialog ref="zhuxiaoDialogRef" @confirm-btn="zhuxiaoBtn" :content="zhuxiaoContent"></tip-small-dialog>
+		<duihuanmaDialog ref="duihuanmaDialogRef" @confirm-btn="duihuanmaBtn" title="兑换"></duihuanmaDialog>
+		<tel-dialog @telClose="telClose" @bindBtn="bindBtn" v-if="telDialogFlag"></tel-dialog>
+		<agree-content-dialog ref="agreeContentDialogRef" :agreeType="agreeType"></agree-content-dialog>
+		<tip-small-dialog ref="kefuDialogRef" :title="kefuTitle" @confirm-btn="kefuBtn" :content="kefuContent"
+			class="kefu-dialog"></tip-small-dialog>
+		<nichengDialog ref="nichengDialogRef" @confirm-btn="nichengBtn" title="修改昵称"></nichengDialog>
+	</view>
+</template>
+
+<script setup>
+	import agreeContentDialog from '@/pages/login/agreeContentDialog.vue';
+	import {
+		toast,
+		getUserIdentity
+	} from "@/utils/common";
+	import cacheManager from '@/utils/cacheManager.js';
+	import {
+		logout
+	} from '@/api/login.js'
+	import {
+		myInfo,
+		zhuxiao,
+		duihuanmaCode,
+		nichengUpdate,
+		myCardList,
+		commonCardList,
+		getFilePolicy,
+		updataHead
+	} from '@/api/my.js'
+	import CustomTabBar from '@/components/custom-tabbar/custom-tabbar.vue';
+	import {
+		onLoad
+	} from '@dcloudio/uni-app';
+	import {
+		reactive,
+		ref
+	} from "vue";
+	import tipSmallDialog from '@/components/dialog/tipSmallDialog.vue';
+	import duihuanmaDialog from '@/components/dialog/duihuanmaDialog.vue';
+	import nichengDialog from '@/components/dialog/nichengDialog.vue';
+	import tipMiddleDialog from '@/components/dialog/tipMiddleDialog.vue';
+	import tipBigDialog from '@/components/dialog/tipBigDialog.vue';
+	import telDialog from './telDialog.vue'
+	import {
+		onShow
+	} from '@dcloudio/uni-app';
+	const agreeType = ref(null);
+	const agreeContentDialogRef = ref(null);
+
+	const tipContent = '你确定要执行这个操作吗?';
+	const zhuxiaoContent = '你确定要执行这个操作吗?';
+	let loginFlag = ref(false);
+	let telDialogFlag = ref(false);
+	let myInfoData = reactive({
+		userImg: '',
+		userName: '',
+		credit: '',
+		vipFlag: '',
+		nickName: '',
+		icon: '',
+	});
+	let routerOpt = ref(false);
+	let appleCode = ref(null);
+	let currentPlatform = ref(null);
+	const exitDialogRef = ref(null);
+	const zhuxiaoDialogRef = ref(null);
+	const nichengDialogRef = ref(null);
+
+	const kefuDialogRef = ref(null);
+	const kefuTitle = '提示';
+	const kefuContent = '客服电话:4001750778';
+	const exitLogin = () => {
+		exitDialogRef.value.handleShow();
+	}
+
+	function handleBack() {
+		uni.redirectTo({
+			url: '/pages/my/index'
+		})
+	}
+
+	function headClick() {
+		chooseImage()
+	}
+
+	const checkAlbumPermission = async () => {
+		const status = await uni.getSetting()
+		if (!status.authSetting['scope.album']) {
+			await uni.authorize({
+				scope: 'scope.album'
+			})
+		}
+	}
+	const chooseImage = async () => {
+		try {
+		//	await checkAlbumPermission()
+			uni.chooseImage({
+				count: 1,
+				sizeType: ['compressed'],
+				sourceType: ['album'], // 仅限相册选择‌:ml-citation{ref="1" data="citationList"}
+				success: (res) => {
+
+					uploadFile(res.tempFilePaths[0])
+				},
+				fail: (err) => {
+					console.error('选择失败:', err)
+				}
+			})
+		} catch (err) {
+			uni.showModal({
+				title: '权限申请失败',
+				content: '请前往设置开启相册权限'
+			})
+		}
+	}
+
+	function updateIcon(data) {
+		updataHead({
+			icon: data
+		}).then(res => {
+			if (res.code == 0) {
+				uni.showToast({
+					title: '上传成功',
+					icon: 'success'
+				});
+			} else {
+				uni.showToast({
+					title: '上传失败',
+				});
+			}
+		})
+	}
+
+	function uploadFile(filePath) {
+		const suffix = filePath.split('.').pop();
+		let req = {
+			prefix: 'resource/',
+			suffix: suffix
+		}
+		getFilePolicy(req).then(res => {
+			if (res.code === 0) {
+				const policyData = res.data;
+				console.log('policyData', policyData);
+				uni.uploadFile({
+					url: policyData.uploadUrl,
+					filePath: filePath,
+					name: 'file',
+					formData: {
+						key: policyData.key,
+						policy: policyData.policy,
+						OSSAccessKeyId: policyData.accessid,
+						signature: policyData.signature,
+						success_action_status: '200'
+					},
+					header: {
+						'Content-Type': 'multipart/form-data'
+					},
+					success(uploadRes) {
+						console.log('uploadRes', uploadRes);
+						if (uploadRes.statusCode === 200) {
+							myInfoData.icon = `${policyData.downloadUrl}/${policyData.key}`;
+							updateIcon(myInfoData.icon)
+						} else {
+							uni.showToast({
+								title: '阿里云上传错误,请重试!',
+							});
+							return false
+						}
+					},
+					fail(err) {
+						console.log('err', err);
+					}
+				});
+
+
+			}
+		})
+
+	}
+
+	function nichengClick() {
+		nichengDialogRef.value.handleShow();
+	}
+	// 退出按钮
+	const exitBtn = () => {
+		if (loginFlag.value) {
+			logout().then(res => {
+				toast('退出登录成功')
+				cacheManager.clearAll();
+				uni.reLaunch({
+					url: '/pages/login/index'
+				});
+			}).catch(err => {
+				toast('退出登录失败,请稍后重试')
+			})
+		} else {
+			uni.reLaunch({
+				url: '/pages/login/index'
+			});
+		}
+
+	}
+	const zhuxiaoBtn = () => {
+		let req = {
+
+		}
+		zhuxiao().then(res => {
+			cacheManager.clearAll();
+			toast('用户注销成功')
+			uni.redirectTo({
+				url: '/pages/login/index'
+			});
+		}).catch(err => {
+			toast('失败,请稍后重试')
+		})
+	}
+
+	function yonghuzhuxiao() {
+		zhuxiaoDialogRef.value.handleShow();
+	}
+
+	function nichengBtn(data) {
+		console.log('data', data);
+		let req = {
+			nickName: data
+		}
+		nichengUpdate(req).then(res => {
+			if (res.code == 0) {
+				toast('修改成功')
+				myInfoData.nickName = data
+			} else {
+				toast('修改失败请重试或联系管理员')
+				return false
+			}
+		}).catch(err => {
+
+		})
+	}
+
+	function yinsizhengce() {
+		agreeType.value = 'ystk'
+		agreeContentDialogRef.value.handleShow();
+	}
+
+	function kefudianhua() {
+		kefuDialogRef.value.handleShow();
+	}
+
+	function kefuBtn() {
+		kefuDialogRef.value.handleClose();
+	}
+	// 手机号码
+	function telClick() {
+		if (loginFlag.value) {
+			telDialogFlag.value = true;
+		} else {
+			youkeDialogRef.value.handleShow();
+		}
+
+	}
+	// 手机号码绑定
+	function bindBtn() {
+		telDialogFlag.value = false;
+		myGetAuth()
+	}
+	// 关闭手机号码弹窗
+	function telClose() {
+		telDialogFlag.value = false;
+	}
+	// 关于我们
+	function aboutClick() {
+		if (loginFlag.value) {
+			uni.redirectTo({
+				url: '/pages/my/aboutPage'
+			});
+		} else {
+			uni.redirectTo({
+				url: `/pages/my/aboutPage?levelId=${routerOpt.levelId}&typeId=${routerOpt.typeId}&subjectId=${routerOpt.subjectId}&tipFlag=${routerOpt.tipFlag}`
+			});
+		}
+	}
+	// 获取用户数据
+	function getMyInfo() {
+		myInfo({}).then(res => {
+			myInfoData.userName = res.data.userName;
+			myInfoData.credit = res.data.credit;
+			myInfoData.nickName = res.data.nickName;
+
+			if (res.data.nickName) {
+				myInfoData.nickName = res.data.nickName;
+			} else {
+				myInfoData.nickName = '鹅状元';
+			}
+			if (res.data.icon) {
+				myInfoData.icon = res.data.icon;
+			} else {
+				getUserImg(res.data.growthType)
+			}
+
+		})
+	}
+
+	function getUserImg(data) {
+		switch (data) {
+			case 0:
+				myInfoData.icon = 'static/images/my/head-img0.png'
+				break;
+			case 1:
+				myInfoData.icon = 'static/images/my/head-img1.png'
+				break;
+			case 2:
+				myInfoData.icon = 'static/images/my/head-img2.png'
+				break;
+			case 3:
+				myInfoData.icon = 'static/images/my/head-img3.png'
+				break;
+			default:
+				myInfoData.icon = 'static/images/my/head-unlogin-img.png'
+				break;
+
+		}
+	}
+
+	function isIOSorAndroid() {
+		const systemInfo = uni.getSystemInfoSync();
+
+		console.log('systemInfo', systemInfo);
+
+		if (systemInfo.platform == 'ios') {
+			return currentPlatform.value = 'ios'
+		} else {
+			return currentPlatform.value = 'android'
+		}
+	}
+	onLoad((options) => {
+		isIOSorAndroid()
+		loginFlag.value = true;
+		getMyInfo();
+	})
+</script>

二进制
static/images/common/cancel-btn.png


二进制
static/images/common/confirm-btn.png


二进制
static/images/my/sz-icon1.png


二进制
static/images/my/sz-icon2.png


二进制
static/images/my/tk-dialog-bj.png


二进制
static/images/my/tk-dialog-qx.png


二进制
static/images/my/tk-dialog-sc.png


二进制
static/images/my/tk-list-item-a.png


二进制
static/images/my/tk-list-item.png


二进制
static/images/my/tk-qxzjc.png


二进制
static/images/my/tk-tab-item.png