userInfo.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <template>
  2. <view class="app">
  3. <view class="cell">
  4. <text class="tit fill">头像</text>
  5. <view class="avatar-wrap" @click="chooseImage">
  6. <image class="avatar" :src="tempAvatar || userInfo.avatar || '/static/icon/default-avatar.png'" mode="aspectFill"></image>
  7. <!-- 进度遮盖 -->
  8. <view class="progress center"
  9. :class="{
  10. 'no-transtion': uploadProgress === 0,
  11. show: uploadProgress != 100
  12. }"
  13. :style="{
  14. width: uploadProgress + '%',
  15. height: uploadProgress + '%',
  16. }"></view>
  17. </view>
  18. </view>
  19. <view class="cell b-b">
  20. <text class="tit fill">昵称</text>
  21. <input class="input" v-model="userInfo.nickname" type="text" maxlength="8" placeholder="请输入昵称" placeholder-class="placeholder">
  22. </view>
  23. <u-cell-group>
  24. <u-cell title="昵称" :value="userInfo.nickname" isLink @click="nicknameClick()"></u-cell>
  25. </u-cell-group>
  26. <u-modal :show="nicknameOpen" title="修改昵称" showCancelButton @confirm="nicknameSubmit" @cancel="nicknameCancel">
  27. <view class="slot-content">
  28. <u--form labelPosition="left" :model="nicknameForm" :rules="nicknameRules" ref="nicknameForm" errorType="toast">
  29. <u-form-item prop="nickname">
  30. <u--input v-model="nicknameForm.nickname" placeholder="请输入昵称" border="none"></u--input>
  31. </u-form-item>
  32. </u--form>
  33. </view>
  34. </u-modal>
  35. </view>
  36. </template>
  37. <script>
  38. export default {
  39. data() {
  40. return {
  41. uploadProgress: 100, //头像上传进度
  42. tempAvatar: '',
  43. userInfo: {},
  44. nicknameOpen: false,
  45. nicknameForm: {
  46. nickname: ''
  47. },
  48. nicknameRules: {
  49. nickname: [{
  50. required: true,
  51. message: '请输入昵称'
  52. }]
  53. }
  54. }
  55. },
  56. computed: {
  57. curUserInfo(){
  58. return this.$store.state.userInfo
  59. }
  60. },
  61. watch: {
  62. curUserInfo(curUserInfo){
  63. const {avatar, nickname, gender} = curUserInfo;
  64. this.userInfo = {avatar, nickname, gender,};
  65. }
  66. },
  67. onLoad() {
  68. const {avatar, nickname, gender, anonymous} = this.curUserInfo;
  69. this.userInfo = {avatar, nickname, gender};
  70. },
  71. methods: {
  72. nicknameClick() {
  73. this.nicknameOpen = true;
  74. this.nicknameForm.nickname = this.userInfo.nickname;
  75. },
  76. nicknameCancel() {
  77. this.nicknameOpen = false;
  78. },
  79. nicknameSubmit() {
  80. this.$refs.nicknameForm.validate().then(() => {
  81. this.loading = true;
  82. // 执行登陆
  83. const { mobile, code, password} = this.form;
  84. const loginPromise = this.loginType == 'password' ? login(mobile, password) :
  85. smsLogin(mobile, code);
  86. loginPromise.then(data => {
  87. // 登陆成功
  88. this.loginSuccessCallBack(data);
  89. }).catch(errors => {
  90. }).finally(() => {
  91. this.loading = false;
  92. })
  93. }).catch(errors => {
  94. });
  95. },
  96. // 提交修改
  97. async confirm() {
  98. // 校验信息是否变化
  99. const {uploadProgress, userInfo, curUserInfo} = this;
  100. let isUpdate = false;
  101. for (let key in userInfo) {
  102. if(userInfo[key] !== curUserInfo[key]){
  103. isUpdate = true;
  104. break;
  105. }
  106. }
  107. if (isUpdate === false) {
  108. this.$util.msg('信息未修改');
  109. this.$refs.confirmBtn.stop();
  110. return;
  111. }
  112. if (!userInfo.avatar) {
  113. this.$util.msg('请上传头像');
  114. this.$refs.confirmBtn.stop();
  115. return;
  116. }
  117. if (uploadProgress !== 100) {
  118. this.$util.msg('请等待头像上传完毕');
  119. this.$refs.confirmBtn.stop();
  120. return;
  121. }
  122. if (!userInfo.nickname) {
  123. this.$util.msg('请输入您的昵称');
  124. this.$refs.confirmBtn.stop();
  125. return;
  126. }
  127. const res = await this.$request('user', 'update', userInfo);
  128. this.$refs.confirmBtn.stop();
  129. this.$util.msg(res.msg);
  130. if(res.status === 1){
  131. this.$store.dispatch('getUserInfo'); //刷新用户信息
  132. setTimeout(()=>{
  133. uni.navigateBack();
  134. }, 1000)
  135. }
  136. },
  137. // 选择头像
  138. chooseImage(){
  139. uni.chooseImage({
  140. count: 1,
  141. success: res=> {
  142. uni.navigateTo({
  143. url: `./cutImage/cut?src=${res.tempFilePaths[0]}`
  144. });
  145. }
  146. });
  147. },
  148. // 裁剪回调
  149. async setAvatar(filePath){
  150. this.tempAvatar = filePath;
  151. this.uploadProgress = 0;
  152. const result = await uniCloud.uploadFile({
  153. filePath: filePath,
  154. cloudPath: + new Date() + ('000000' + Math.floor(Math.random() * 999999)).slice(-6) + '.jpg',
  155. onUploadProgress: e=> {
  156. this.uploadProgress = Math.round(
  157. (e.loaded * 100) / e.total
  158. );
  159. }
  160. });
  161. if(!result.fileID){
  162. this.$util.msg('头像上传失败');
  163. return;
  164. }
  165. if(typeof uniCloud.getTempFileURL === 'undefined'){
  166. this.userInfo.avatar = result.fileID;
  167. }else{
  168. const tempFiles = await uniCloud.getTempFileURL({
  169. fileList: [result.fileID]
  170. })
  171. const tempFile = tempFiles.fileList[0];
  172. if(tempFile.download_url || tempFile.fileID){
  173. this.userInfo.avatar = tempFile.download_url || tempFile.fileID;
  174. }else{
  175. this.$util.msg('头像上传失败');
  176. }
  177. }
  178. }
  179. }
  180. }
  181. </script>
  182. <style scoped lang="scss">
  183. .app{
  184. padding-top: 16rpx;
  185. }
  186. .cell{
  187. display: flex;
  188. align-items: center;
  189. min-height: 110rpx;
  190. padding: 0 40rpx;
  191. &:first-child{
  192. margin-bottom: 10rpx;
  193. }
  194. &:after{
  195. left: 40rpx;
  196. right: 40rpx;
  197. border-color: #d8d8d8;
  198. }
  199. .tit{
  200. font-size: 30rpx;
  201. color: #333;
  202. }
  203. .avatar-wrap{
  204. width: 120rpx;
  205. height: 120rpx;
  206. position: relative;
  207. border-radius: 100rpx;
  208. overflow: hidden;
  209. .avatar{
  210. width: 100%;
  211. height: 100%;
  212. border-radius: 100rpx;
  213. }
  214. .progress{
  215. position: absolute;
  216. left: 50%;
  217. top: 50%;
  218. transform: translate(-50%, -50%);
  219. width: 100rpx;
  220. height: 100rpx;
  221. box-shadow: rgba(0,0,0,.6) 0px 0px 0px 2005px;
  222. border-radius: 100rpx;
  223. transition: .5s;
  224. opacity: 0;
  225. &.no-transtion{
  226. transition: 0s;
  227. }
  228. &.show{
  229. opacity: 1;
  230. }
  231. }
  232. }
  233. .input{
  234. flex: 1;
  235. text-align: right;
  236. font-size: 28rpx;
  237. color: #333;
  238. }
  239. switch{
  240. margin: 0;
  241. transform: scale(0.8) translateX(10rpx);
  242. transform-origin: center right;
  243. }
  244. .tip{
  245. margin-left: 20rpx;
  246. font-size: 28rpx;
  247. color: #999;
  248. }
  249. .checkbox{
  250. padding: 12rpx 0 12rpx 40rpx;
  251. font-size: 28rpx;
  252. color: #333;
  253. .mix-icon{
  254. margin-right: 12rpx;
  255. font-size: 36rpx;
  256. color: #ccc;
  257. }
  258. .icon-xuanzhong{
  259. color: $base-color;
  260. }
  261. }
  262. }
  263. </style>