图书馆小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
5.0 KiB

2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
  1. <template>
  2. <view class="user-info-page">
  3. <view class="user-info-section">
  4. <!-- 点击获取头像 -->
  5. <button open-type="chooseAvatar" @chooseavatar="onChooseAvatar" class="avatar-btn">
  6. <image v-if="avatarUrl" :src="avatarUrl" class="avatar-img"></image>
  7. <image v-else src="@/static/images/avatar.png" class="avatar-img"></image>
  8. <text class="tip-text">点击更换头像</text>
  9. </button>
  10. </view>
  11. <!-- 昵称 -->
  12. <view class="form-item">
  13. <text class="label">昵称</text>
  14. <input
  15. class="input"
  16. type="nickname"
  17. v-model="nickName"
  18. placeholder="请输入昵称"
  19. />
  20. <uni-icons type="right" size="18" color="#ccc"></uni-icons>
  21. </view>
  22. <!-- 保存按钮 -->
  23. <view class="save-box">
  24. <button class="save-btn" @click="saveUserInfo">保存修改</button>
  25. </view>
  26. </view>
  27. </template>
  28. <script>
  29. import config from '@/utils/config'
  30. import { FetchBindRead } from '@/api/user';
  31. // 缓存 key 与个人中心保持一致
  32. const USER_KEY = 'user-info';
  33. export default {
  34. data() {
  35. return {
  36. nickName: '',
  37. avatarUrl: ''
  38. };
  39. },
  40. onLoad() {
  41. // 页面加载时获取本地缓存的用户信息
  42. this.loadUserInfo();
  43. },
  44. methods: {
  45. // 加载缓存中的用户信息
  46. loadUserInfo() {
  47. const userInfo = uni.getStorageSync(USER_KEY) || {};
  48. this.nickName = userInfo.nickName || '';
  49. this.avatarUrl = userInfo.avatarUrl || '';
  50. },
  51. // 选择微信头像
  52. async onChooseAvatar(e) {
  53. const tempFilePath = e.detail.avatarUrl;
  54. uni.showLoading({ title: '上传中...' });
  55. try {
  56. // 1. 上传头像到服务器
  57. const uploadRes = await new Promise((resolve, reject) => {
  58. uni.uploadFile({
  59. url: config.baseUrl + '/api/fileRelevant/uploadWxAvatarImg',
  60. filePath: tempFilePath,
  61. name: 'file',
  62. success: resolve,
  63. fail: reject
  64. })
  65. });
  66. const resData = JSON.parse(uploadRes.data);
  67. const imgId = resData.data;
  68. if (!imgId) {
  69. uni.showToast({ title: '头像上传失败', icon: 'none' });
  70. return;
  71. }
  72. // 拼接头像地址
  73. const avatarUrl = config.baseUrl + '/api/fileRelevant/getImg?imgType=5&imgId=' + imgId;
  74. this.avatarUrl = avatarUrl;
  75. uni.showToast({ title: '头像选择成功,点击保存生效', icon: 'success' });
  76. } catch (err) {
  77. console.error('头像上传失败:', err);
  78. uni.showToast({ title: '头像更新失败', icon: 'none' });
  79. } finally {
  80. uni.hideLoading();
  81. }
  82. },
  83. // 保存用户信息(头像 + 昵称)
  84. async saveUserInfo() {
  85. // 校验昵称
  86. if (!this.nickName.trim()) {
  87. uni.showToast({ title: '请输入昵称', icon: 'none' });
  88. return;
  89. }
  90. uni.showLoading({ title: '保存中...' });
  91. try {
  92. const openId = uni.getStorageSync('wx_login_code') || '';
  93. const params = {
  94. avatar: this.avatarUrl,
  95. libcode: "1201",
  96. nickname: this.nickName,
  97. openid: openId
  98. };
  99. // 调用保存接口
  100. await FetchBindRead(params);
  101. // 更新缓存
  102. const userInfo = {
  103. nickName: this.nickName,
  104. avatarUrl: this.avatarUrl
  105. };
  106. uni.setStorageSync(USER_KEY, userInfo);
  107. uni.showToast({
  108. title: '保存成功',
  109. icon: 'success'
  110. });
  111. // 返回上一页
  112. setTimeout(() => {
  113. uni.navigateBack();
  114. }, 1500);
  115. } catch (error) {
  116. console.error('保存失败:', error);
  117. uni.showToast({
  118. title: '保存失败,请重试',
  119. icon: 'none'
  120. });
  121. } finally {
  122. uni.hideLoading();
  123. }
  124. }
  125. }
  126. };
  127. </script>
  128. <style lang="scss" scoped>
  129. .user-info-page {
  130. background-color: #f5f5f5;
  131. min-height: 100vh;
  132. padding: 20rpx;
  133. box-sizing: border-box;
  134. }
  135. /* 头像区域 */
  136. .user-info-section {
  137. background: #fff;
  138. padding: 40rpx 0;
  139. border-radius: 12rpx;
  140. margin-bottom: 20rpx;
  141. display: flex;
  142. flex-direction: column;
  143. align-items: center;
  144. }
  145. .avatar-btn {
  146. background: transparent;
  147. display: flex;
  148. flex-direction: column;
  149. align-items: center;
  150. &::after {
  151. border: none;
  152. }
  153. }
  154. .avatar-img {
  155. width: 120rpx;
  156. height: 120rpx;
  157. border-radius: 50%;
  158. object-fit: cover;
  159. margin-bottom: 10rpx;
  160. }
  161. .tip-text {
  162. font-size: 26rpx;
  163. color: #999;
  164. }
  165. /* 表单项 */
  166. .form-item {
  167. background-color: #fff;
  168. display: flex;
  169. justify-content: space-between;
  170. align-items: center;
  171. padding: 0 30rpx;
  172. height: 88rpx;
  173. border-radius: 12rpx;
  174. margin-bottom: 20rpx;
  175. }
  176. .label {
  177. font-size: 30rpx;
  178. color: #333;
  179. width: 120rpx;
  180. }
  181. .input {
  182. flex: 1;
  183. font-size: 30rpx;
  184. color: #333;
  185. text-align: right;
  186. }
  187. /* 保存按钮 */
  188. .save-box {
  189. margin-top: 60rpx;
  190. padding: 0 20rpx;
  191. }
  192. .save-btn {
  193. height: 88rpx;
  194. line-height: 88rpx;
  195. background-color: #007aff;
  196. color: #fff;
  197. border-radius: 44rpx;
  198. font-size: 32rpx;
  199. }
  200. </style>