Authored by Rickie

完善

1 import { request } from '../utils/request.js'; 1 import { request } from '../utils/request.js';
2 2
3 -export const getDeviceList = () => {  
4 - return request({  
5 - url: '/device/list',  
6 - method: 'GET',  
7 - });  
8 -};  
9 -  
10 // 登录 3 // 登录
11 export const loginApi = (data) => { 4 export const loginApi = (data) => {
12 return request({ 5 return request({
@@ -59,4 +52,22 @@ export const signUpApi = (data) => { @@ -59,4 +52,22 @@ export const signUpApi = (data) => {
59 method: 'POST', 52 method: 'POST',
60 data, 53 data,
61 }); 54 });
  55 +};
  56 +
  57 +// 获取用户信息
  58 +export const userInfoApi = (data) => {
  59 + return request({
  60 + url: '/api/get-info',
  61 + method: 'GET',
  62 + data,
  63 + });
  64 +};
  65 +
  66 +// 获取我的报名列表
  67 +export const userSignUpListApi = (data) => {
  68 + return request({
  69 + url: '/api/course/get-my-signup',
  70 + method: 'GET',
  71 + data,
  72 + });
62 }; 73 };
@@ -10,7 +10,8 @@ @@ -10,7 +10,8 @@
10 { 10 {
11 "path": "pages/my/my", 11 "path": "pages/my/my",
12 "style": { 12 "style": {
13 - "navigationBarTitleText": "我的" 13 + "navigationBarTitleText": "",
  14 + "navigationStyle": "custom"
14 } 15 }
15 }, 16 },
16 { 17 {
@@ -90,16 +90,24 @@ @@ -90,16 +90,24 @@
90 90
91 const submit = async () => { 91 const submit = async () => {
92 try { 92 try {
93 - await formRef.value.validate() 93 + await formRef.value.validate()
  94 +
  95 + uni.showLoading({
  96 + title: "提交中",
  97 + mask: true
  98 + })
94 99
95 const res = await addStudentsApi(state.studentInfo) 100 const res = await addStudentsApi(state.studentInfo)
  101 + uni.hideLoading()
96 uni.showToast({ 102 uni.showToast({
97 icon: 'success', 103 icon: 'success',
98 title: '添加成功' 104 title: '添加成功'
99 }) 105 })
100 formRef.value.resetFields() 106 formRef.value.resetFields()
101 uni.navigateBack() 107 uni.navigateBack()
102 - } catch {} 108 + } finally {
  109 + uni.hideLoading()
  110 + }
103 } 111 }
104 </script> 112 </script>
105 113
@@ -122,12 +122,15 @@ @@ -122,12 +122,15 @@
122 122
123 const getCourseList = async () => { 123 const getCourseList = async () => {
124 try { 124 try {
  125 + uni.showLoading({ title: "加载中" })
125 const { data } = await courseListApi({ 126 const { data } = await courseListApi({
126 grade: state.grade === "全部年级" ? "" : state.grade, 127 grade: state.grade === "全部年级" ? "" : state.grade,
127 subject: state.accounts === "全部科目" ? "" : state.accounts 128 subject: state.accounts === "全部科目" ? "" : state.accounts
128 }) 129 })
129 state.courses = data.courses 130 state.courses = data.courses
130 - } catch {} 131 + } finally {
  132 + uni.hideLoading()
  133 + }
131 } 134 }
132 135
133 const showGradesPop = () => { 136 const showGradesPop = () => {
@@ -62,18 +62,26 @@ @@ -62,18 +62,26 @@
62 62
63 const loginHandler = async () => { 63 const loginHandler = async () => {
64 try { 64 try {
65 - await formRef.value.validate() 65 + await formRef.value.validate()
  66 +
  67 + uni.showLoading({
  68 + title: "登录中",
  69 + mask: true
  70 + })
66 71
67 const { 72 const {
68 token 73 token
69 - } = await loginApi(state.userInfo) 74 + } = await loginApi(state.userInfo)
  75 + uni.hideLoading()
70 uni.showToast({ 76 uni.showToast({
71 icon: 'success', 77 icon: 'success',
72 title: '登录成功' 78 title: '登录成功'
73 }) 79 })
74 uni.setStorageSync('token', token) 80 uni.setStorageSync('token', token)
75 uni.navigateBack() 81 uni.navigateBack()
76 - } catch {} 82 + } finally {
  83 + uni.hideLoading()
  84 + }
77 } 85 }
78 </script> 86 </script>
79 87
1 -<template>  
2 - <view class="container">  
3 - <!-- 自定义标题栏 -->  
4 - <uv-navbar leftIcon="" placeholder bgColor="/static/topBg.png">  
5 - <template v-slot:center>  
6 - <view class="uv-nav-slot">  
7 - <image src="/static/my/myTitle.png" mode="heightFix" style="height: 44rpx;"></image> 1 +<template>
  2 + <view class="container">
  3 +  <uv-navbar leftIcon="" placeholder bgColor="rgba(255, 255, 255, 0)" />
  4 +
  5 + <view class="content-box">
  6 + <view class="header">
  7 + <view class="avatar">
  8 + <image v-if="state.userInfo?.avatar" :src="state.userInfo.avatar" style="width: 100%;height: 100%;"></image>
8 </view> 9 </view>
9 - </template>  
10 - </uv-navbar>  
11 -  
12 - <view class="content-box">  
13 - <div class="content-padding">  
14 - <!-- 用户信息 -->  
15 - <view class="user-info">  
16 - <view class="center-avatar">  
17 - <view class="center-inner">  
18 - <image src="/static/my/avatar.png" style="width: 100%;height: 100%;"></image>  
19 - </view> 10 + <view class="fm-box">
  11 + <view style="font-size: 36rpx;">
  12 + {{ state.userInfo?.nickName || "未知" }}
20 </view> 13 </view>
21 - <view class="loginTo-btn">  
22 - 登录/注册 14 + <view class="">
  15 + {{ state.userInfo?.phonenumber ? state.userInfo?.phonenumber.slice(0, 8) + '****' : "" }}
23 </view> 16 </view>
24 </view> 17 </view>
25 -  
26 - <view class="nav-list">  
27 - <view class="nav-item">  
28 - <view style="display: flex;align-items: center;">  
29 - <uv-icon name="/static/my/student.png" :size="22"></uv-icon>  
30 - <view style="margin-left: 26rpx;color: #6a6a6a;">绑定学生</view> 18 + </view>
  19 +
  20 + <view style="background-color: #fff;padding: 20rpx 30rpx;margin-top: 60rpx;border-radius: 20rpx;font-size: 28rpx;">
  21 + <view style="display: flex;justify-content: space-between;">
  22 + <view class="">
  23 + 我的孩子
  24 + </view>
  25 + <view style="display: flex;justify-content: space-between;align-items: center;color: #7175f0;">
  26 + 添加<uv-icon name="arrow-right" color="#7175f0" size="14"></uv-icon>
  27 + </view>
  28 + </view>
  29 + <view style="display: grid;grid-template-columns: repeat(2, 1fr);gap: 20rpx;margin-top: 30rpx;">
  30 + <view v-for="item in state.students" style="display: flex;border: 2rpx solid #e4e9ff;padding: 10rpx;border-radius: 20rpx;">
  31 + <view style="flex-shrink: 0;width: 90rpx;height: 90rpx;border-radius: 50%;background-color: #bdceff;">
  32 + <image v-if="item.avatar" :src="item.avatar" style="width: 100%;height: 100%;"></image>
  33 + </view>
  34 + <view style="flex: 1;display: flex;flex-direction: column;justify-content: space-between;margin-left: 20rpx;">
  35 + <view class="">
  36 + {{ item.name || "未知" }}
  37 + </view>
  38 + <view style="font-size: 28rpx;">
  39 + {{ item.grade || "-" }}
  40 + </view>
31 </view> 41 </view>
32 - <uv-icon name="arrow-right" :size="16"></uv-icon>  
33 </view> 42 </view>
34 - <view class="nav-item">  
35 - <view style="display: flex;align-items: center;">  
36 - <uv-icon name="/static/my/print.png" :size="24"></uv-icon>  
37 - <view style="margin-left: 26rpx;color: #6a6a6a;">打印记录</view> 43 + </view>
  44 + </view>
  45 +
  46 + <view style="background-color: #fff;padding: 20rpx 30rpx;border-radius: 20rpx;font-size: 28rpx;margin-top: 40rpx;">
  47 + <view style="margin-bottom: 30rpx;">
  48 + 我的报名
  49 + </view>
  50 + <template v-if="state.signupList.length">
  51 + <view v-for="item in state.signupList" style="display: flex;justify-content: space-between;border-radius: 20rpx;border: 2rpx solid #bdceff;padding: 10rpx;">
  52 + <view style="background-color: #b8cfff;border-radius: 16rpx;flex-shrink: 0;width: 100rpx;height: 100rpx;">
  53 + <image v-if="item.avatar" :src="item.avatar" style="width: 100%;height: 100%;"></image>
  54 + </view>
  55 + <view style="flex: 1;display: flex;flex-direction: column;justify-content: space-between;margin-left: 20rpx;">
  56 + <view class="">
  57 + 华地校区-四年级-数学-A+班
  58 + </view>
  59 + <view class="">
  60 + 10-01至10-31 19:00-21:00
  61 + </view>
38 </view> 62 </view>
39 - <uv-icon name="arrow-right" :size="16"></uv-icon>  
40 </view> 63 </view>
  64 + </template>
  65 + <view v-else style="text-align: center;color: #666;padding: 30rpx 0;">
  66 + 暂无报名数据
41 </view> 67 </view>
42 - </div>  
43 - </view>  
44 - </view>  
45 -</template>  
46 -  
47 -<script setup>  
48 -  
49 -</script>  
50 -  
51 -<style lang="scss" scoped>  
52 - .container {  
53 - background-color: #f7f8fa;  
54 - height: 100vh;  
55 - overflow-y: auto;  
56 - display: flex;  
57 - flex-direction: column; 68 + </view>
  69 + </view>
  70 + </view>
  71 +</template>
  72 +
  73 +<script setup>
  74 + import {
  75 + reactive,
  76 + onMounted
  77 + } from 'vue';
  78 + import { userInfoApi, myStudentsApi, userSignUpListApi } from "@/api/index.js"
  79 +
  80 + const state = reactive({
  81 + userInfo: {},
  82 + signupList: [],
  83 + students: []
  84 + })
  85 +
  86 + onMounted(() => {
  87 + getUserInfo()
  88 + getMyStudents()
  89 + getuserSignUpList()
  90 + })
  91 +
  92 + const getUserInfo = async () => {
  93 + const { data } = await userInfoApi()
  94 + state.userInfo = data.user
58 } 95 }
59 -  
60 - .content-box {  
61 - flex: 1;  
62 - overflow-y: auto;  
63 - background-image: url('~@/static/bottomBg.png');  
64 - background-repeat: no-repeat;  
65 - background-size: 100% auto; 96 +
  97 + const getMyStudents = async () => {
  98 + const { data } = await myStudentsApi()
  99 + state.students = data.students
66 } 100 }
67 101
68 - .content-padding {  
69 - padding: 0 28rpx; 102 + const getuserSignUpList = async () => {
  103 + const { data } = await userSignUpListApi()
  104 + console.log(data)
  105 + state.signupList = data.signupList
  106 + }
  107 +</script>
  108 +
  109 +<style lang="scss" scoped>
  110 + .container {
  111 + background: linear-gradient(135deg, #d4d6fe 10%, #f6f7fb 90%);
  112 + background-color: red;
  113 + height: calc(100vh - var(--tab-bar-height));
  114 + display: flex;
  115 + flex-direction: column;
  116 + }
  117 +
  118 + .content-box {
  119 + flex: 1;
  120 + overflow-y: auto;
  121 + padding: 0 30rpx;
  122 + display: flex;
  123 + flex-direction: column;
70 } 124 }
71 -  
72 - .user-info {  
73 - width: 100%;  
74 - height: 440rpx;  
75 - background-image: url('~@/static/my/information.png');  
76 - background-repeat: no-repeat;  
77 - background-size: 100% auto;  
78 - background-position: bottom;  
79 - background-color: transparent;  
80 - position: relative;  
81 -  
82 - .center-avatar {  
83 - position: absolute;  
84 - top: 20rpx;  
85 - left: 50%;  
86 - transform: translateX(-50%);  
87 - width: 34%;  
88 - aspect-ratio: 1/1;  
89 - background-color: #fff;  
90 - border-radius: 50%;  
91 -  
92 - .center-inner {  
93 - width: 100%;  
94 - height: 100%;  
95 - border-radius: 50%;  
96 - overflow: hidden;  
97 - }  
98 - }  
99 -  
100 - .loginTo-btn {  
101 - position: absolute;  
102 - left: 50%;  
103 - bottom: 60rpx;  
104 - transform: translateX(-50%);  
105 - color: #fff;  
106 - font-size: 44rpx;  
107 - } 125 +
  126 + .header {
  127 + display: flex;
  128 + justify-content: space-between;
  129 + padding: 0 20rpx;
108 } 130 }
109 -  
110 - .nav-list {  
111 - background-color: #fff;  
112 - border-radius: 12rpx;  
113 - box-shadow: 0 0 20rpx #eee;  
114 - padding: 10rpx 20rpx;  
115 - box-sizing: border-box;  
116 - margin-top: 40rpx;  
117 -  
118 - .nav-item {  
119 - display: flex;  
120 - justify-content: space-between;  
121 - border-bottom: 2rpx dashed #d8d8d8;  
122 - padding: 30rpx 0;  
123 -  
124 - &:last-child {  
125 - border: none;  
126 - }  
127 - } 131 +
  132 + .avatar {
  133 + flex-shrink: 0;
  134 + width: 120rpx;
  135 + height: 120rpx;
  136 + border-radius: 50%;
  137 + background-color: #c1cdff;
128 } 138 }
  139 +
  140 + .fm-box {
  141 + margin-left: 30rpx;
  142 + flex: 1;
  143 + display: flex;
  144 + flex-direction: column;
  145 + justify-content: space-between;
  146 + padding: 6rpx 0;
  147 + }
129 </style> 148 </style>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 20
21 <view class="student-box" style="margin-top: 30rpx;display: block;"> 21 <view class="student-box" style="margin-top: 30rpx;display: block;">
22 <view class="title" style="margin-bottom: 30rpx;"> 22 <view class="title" style="margin-bottom: 30rpx;">
23 - 选择 23 + 选择
24 </view> 24 </view>
25 <view style="display: grid;grid-template-columns: repeat(3, 1fr);gap: 20rpx;"> 25 <view style="display: grid;grid-template-columns: repeat(3, 1fr);gap: 20rpx;">
26 <view v-for="item in state.selectData.schoolArr" @click="select1(item)" 26 <view v-for="item in state.selectData.schoolArr" @click="select1(item)"
@@ -166,7 +166,7 @@ @@ -166,7 +166,7 @@
166 }) 166 })
167 if (!state.schoolName) return uni.showToast({ 167 if (!state.schoolName) return uni.showToast({
168 icon: 'error', 168 icon: 'error',
169 - title: '请选择区' 169 + title: '请选择区'
170 }) 170 })
171 if (!state.className) return uni.showToast({ 171 if (!state.className) return uni.showToast({
172 icon: 'error', 172 icon: 'error',
@@ -180,6 +180,7 @@ @@ -180,6 +180,7 @@
180 icon: 'error', 180 icon: 'error',
181 title: '请选择时段' 181 title: '请选择时段'
182 }) 182 })
  183 + uni.showLoading({ title: "提交中", mask: true })
183 await signUpApi({ 184 await signUpApi({
184 studentWorkNo: state.students[state.activeIndex]?.workNo, 185 studentWorkNo: state.students[state.activeIndex]?.workNo,
185 courseId: state.courseId, 186 courseId: state.courseId,
@@ -194,7 +195,9 @@ @@ -194,7 +195,9 @@
194 title: '报名成功' 195 title: '报名成功'
195 }) 196 })
196 resetSelect() 197 resetSelect()
197 - } catch {} 198 + } finally {
  199 + uni.hideLoading();
  200 + }
198 } 201 }
199 202
200 const resetSelect = () => { 203 const resetSelect = () => {
@@ -256,18 +259,23 @@ @@ -256,18 +259,23 @@
256 259
257 const getSelectCourseData = async () => { 260 const getSelectCourseData = async () => {
258 if (state.courseId === null) return 261 if (state.courseId === null) return
259 -  
260 - const {  
261 - data  
262 - } = await getSelectApi({  
263 - courseId: state.courseId,  
264 - schoolName: state.schoolName,  
265 - className: state.className,  
266 - teacherName: state.teacherName,  
267 - courseDate: state.courseDate,  
268 - courseTime: state.courseTime  
269 - })  
270 - state.selectData = data 262 +
  263 + try {
  264 + uni.showLoading({ title: "加载中", mask: true })
  265 + const {
  266 + data
  267 + } = await getSelectApi({
  268 + courseId: state.courseId,
  269 + schoolName: state.schoolName,
  270 + className: state.className,
  271 + teacherName: state.teacherName,
  272 + courseDate: state.courseDate,
  273 + courseTime: state.courseTime
  274 + })
  275 + state.selectData = data
  276 + } finally {
  277 + uni.hideLoading()
  278 + }
271 } 279 }
272 280
273 const getMyStudents = async () => { 281 const getMyStudents = async () => {