set.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. <template>
  2. <view class="page">
  3. <!-- 顶部自定义导航 -->
  4. <!-- <tn-nav-bar fixed alpha customBack>
  5. <view slot="back" class='tn-custom-nav-bar__back' @click="goBack">
  6. <text class='icon tn-icon-left-arrow'></text>
  7. </view>
  8. </tn-nav-bar> -->
  9. <!-- :style="{paddingTop: vuex_custom_bar_height + 'px'}" -->
  10. <view class="">
  11. <view class="tn-flex tn-flex-row-between tn-strip-bottom-min tn-padding">
  12. <view class="justify-content-item">
  13. <view class="tn-text-bold tn-text-lg">
  14. 用户头像
  15. </view>
  16. <view class="tn-color-gray tn-padding-top-xs">
  17. 有趣的头像,百里挑一
  18. </view>
  19. </view>
  20. <button class="avatar-wrapper" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
  21. <view class="justify-content-item tn-text-lg tn-color-grey">
  22. <view class="logo-pic tn-shadow">
  23. <view class="logo-image">
  24. <view class="tn-shadow-blur" style="width: 80rpx;height: 80rpx;background-size: cover;"
  25. :style="{backgroundImage:'url('+user.avatar+')'}">
  26. </view>
  27. </view>
  28. </view>
  29. </view>
  30. </button>
  31. </view>
  32. <view class="tn-flex tn-flex-row-between tn-strip-bottom-min tn-padding" @click="showModalNickname">
  33. <view class="justify-content-item">
  34. <view class="tn-text-bold tn-text-lg">
  35. 用户昵称
  36. </view>
  37. <view class="tn-color-gray tn-padding-top-xs">
  38. {{nickname}}
  39. </view>
  40. </view>
  41. <view class="justify-content-item tn-text-lg tn-color-grey">
  42. <view class="tn-icon-right tn-padding-top"></view>
  43. </view>
  44. </view>
  45. <view class="tn-flex tn-flex-row-between tn-strip-bottom tn-padding" @click="showModalMobile" v-show="bindMobile > 0">
  46. <view class="justify-content-item">
  47. <view class="tn-text-bold tn-text-lg">
  48. 绑定手机号
  49. </view>
  50. <view class="tn-color-gray tn-padding-top-xs">
  51. {{mobile}}
  52. </view>
  53. </view>
  54. <view class="justify-content-item tn-text-lg tn-color-grey">
  55. <view class="tn-icon-right tn-padding-top"></view>
  56. </view>
  57. </view>
  58. <!-- <view class="tn-flex tn-flex-row-between tn-strip-bottom-min tn-padding" @click="showModalRealName">
  59. <view class="justify-content-item">
  60. <view class="tn-text-bold tn-text-lg">
  61. 姓名
  62. </view>
  63. <view class="tn-color-gray tn-padding-top-xs">
  64. 未填写
  65. </view>
  66. </view>
  67. <view class="justify-content-item tn-text-lg tn-color-grey">
  68. <view class="tn-icon-right tn-padding-top"></view>
  69. </view>
  70. </view> -->
  71. <picker @change="bindGenderChange" :value="indexGender" :range="arrayGender">
  72. <view class="tn-flex tn-flex-row-between tn-strip-bottom-min tn-padding">
  73. <view class="justify-content-item">
  74. <view class="tn-text-bold tn-text-lg">
  75. 性别
  76. </view>
  77. <view class="tn-color-gray tn-padding-top-xs">
  78. <view class="tn-color-gray">{{arrayGender[indexGender]}}</view>
  79. </view>
  80. </view>
  81. <view class="justify-content-item tn-text-lg tn-color-grey">
  82. <view class="tn-icon-right tn-padding-top"></view>
  83. </view>
  84. </view>
  85. </picker>
  86. <picker @change="bindDateChange" mode="date" :value="birthday" :start="startDate" :end="endDate">
  87. <view class="tn-flex tn-flex-row-between tn-strip-bottom-min tn-padding">
  88. <view class="justify-content-item">
  89. <view class="tn-text-bold tn-text-lg">
  90. 生日
  91. </view>
  92. <view class="tn-color-gray tn-padding-top-xs">
  93. {{birthday}}
  94. </view>
  95. </view>
  96. <view class="justify-content-item tn-text-lg tn-color-grey">
  97. <view class="tn-icon-right tn-padding-top"></view>
  98. </view>
  99. </view>
  100. </picker>
  101. <!-- <picker @change="bindPickerChange1" :value="index1" :range="array1">
  102. <view class="tn-flex tn-flex-row-between tn-strip-bottom-min tn-padding">
  103. <view class="justify-content-item">
  104. <view class="tn-text-bold tn-text-lg">
  105. 职业
  106. </view>
  107. <view class="tn-color-gray tn-padding-top-xs">
  108. {{array1[index1]}}
  109. </view>
  110. </view>
  111. <view class="justify-content-item tn-text-lg tn-color-grey">
  112. <view class="tn-icon-right tn-padding-top"></view>
  113. </view>
  114. </view>
  115. </picker> -->
  116. <tn-modal v-model="showNickname" :custom="true" :showCloseBtn="true">
  117. <view class="custom-modal-content">
  118. <view class="">
  119. <view class="tn-text-lg tn-text-bold tn-color-purplered tn-text-center tn-padding">修改昵称</view>
  120. <view class="tn-bg-gray--light"
  121. style="border-radius: 10rpx;padding: 20rpx 30rpx;margin: 50rpx 0 60rpx 0;">
  122. <input type="nickname" v-model="nickname" placeholder-style="color:#AAAAAA" maxlength="20"
  123. placeholder="请输入昵称" />
  124. </view>
  125. </view>
  126. <view class="tn-flex-1 justify-content-item tn-margin-sm tn-text-center">
  127. <tn-button shape="round" backgroundColor="#5677fc" padding="40rpx 0" width="60%" shadow fontBold @click="showNickname = false">
  128. <text class="tn-color-white">确定</text>
  129. </tn-button>
  130. </view>
  131. </view>
  132. </tn-modal>
  133. <tn-modal v-model="showMobile" :custom="true" :showCloseBtn="true">
  134. <view class="custom-modal-content">
  135. <view class="">
  136. <view class="tn-text-lg tn-text-bold tn-color-purplered tn-text-center tn-padding">变更手机号码</view>
  137. <view class="tn-bg-gray--light"
  138. style="border-radius: 10rpx;padding: 20rpx 30rpx;margin: 50rpx 0 60rpx 0;">
  139. <input placeholder="请填写手机号码" name="input" placeholder-style="color:#AAAAAA" v-model="mobile"
  140. maxlength="11"></input>
  141. </view>
  142. </view>
  143. <view class="tn-flex-1 justify-content-item tn-margin-sm tn-text-center">
  144. <tn-button shape="round" backgroundColor="#5677fc" padding="40rpx 0" width="60%" shadow fontBold @click="showMobile = false">
  145. <text class="tn-color-white">确定</text>
  146. </tn-button>
  147. </view>
  148. </view>
  149. </tn-modal>
  150. <!-- <tn-modal v-model="showMobile" :custom="true" :showCloseBtn="true">
  151. <view class="custom-modal-content">
  152. <view class="">
  153. <view class="tn-text-lg tn-text-bold tn-color-purplered tn-text-center tn-padding">变更手机号码</view>
  154. <view class="tn-bg-gray--light tn-color-gray"
  155. style="border-radius: 10rpx;padding: 20rpx 30rpx;margin: 50rpx 0 60rpx 0;">
  156. {{mobile || '尚未设置'}}
  157. </view>
  158. </view>
  159. <view class="tn-flex-1 justify-content-item tn-margin-sm tn-text-center">
  160. <tn-button shape="round" backgroundColor="#5677fc" padding="40rpx 0" width="60%" shadow fontBold
  161. open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">
  162. <text class="tn-color-white">获取手机号</text>
  163. </tn-button>
  164. </view>
  165. </view>
  166. </tn-modal> -->
  167. <!-- <tn-modal v-model="showRealName" :custom="true" :showCloseBtn="true">
  168. <view class="custom-modal-content">
  169. <view class="">
  170. <view class="tn-text-lg tn-text-bold tn-color-purplered tn-text-center tn-padding">请输入真实姓名
  171. </view>
  172. <view class="tn-bg-gray--light"
  173. style="border-radius: 10rpx;padding: 20rpx 30rpx;margin: 50rpx 0 60rpx 0;">
  174. <input placeholder="请填写姓名" name="input" placeholder-style="color:#AAAAAA"
  175. maxlength="20"></input>
  176. </view>
  177. </view>
  178. <view class="tn-flex-1 justify-content-item tn-margin-sm tn-text-center">
  179. <tn-button shape="round" backgroundColor="#5677fc" padding="40rpx 0" width="60%" shadow fontBold
  180. open-type="getMobileNumber">
  181. <text class="tn-color-white">保 存</text>
  182. </tn-button>
  183. </view>
  184. </view>
  185. </tn-modal> -->
  186. </view>
  187. <!-- 悬浮按钮-->
  188. <view class="tn-flex tn-footerfixed">
  189. <view class="tn-flex-1 justify-content-item tn-margin-sm tn-text-center" @click="save">
  190. <tn-button shape="round" backgroundColor="#5677fc" padding="40rpx 0" width="60%" shadow
  191. fontBold>
  192. <!-- <text class="tn-icon-light tn-padding-right-xs tn-color-black"></text> -->
  193. <text class="tn-color-white">保存</text>
  194. <!-- <text class="tn-icon-light tn-padding-left-xs tn-color-black"></text> -->
  195. </tn-button>
  196. </view>
  197. </view>
  198. <login ref="login" v-on:login_success="ajax"></login>
  199. <kz-wx-privacy-check></kz-wx-privacy-check>
  200. </view>
  201. </template>
  202. <script>
  203. import userApi from "@/common/api/user.js"
  204. export default {
  205. data() {
  206. return {
  207. showNickname: false,
  208. showMobile: false,
  209. showRealName: false,
  210. user: null,
  211. nickname: '',
  212. mobile: '',
  213. indexGender: 0,
  214. arrayGender: ['女', '男'],
  215. birthday: '',
  216. tempAvatarUrl: '',
  217. bindMobile: 1,// 0=不绑定,1=可选绑定,2=强制绑定
  218. }
  219. },
  220. computed: {
  221. startDate() {
  222. return this.getDate('start');
  223. },
  224. endDate() {
  225. return this.getDate('end');
  226. }
  227. },
  228. onLoad() {
  229. this.ajax()
  230. let system = uni.getStorageSync('system')
  231. this.system = system
  232. if (system && system.bind_mobile) {
  233. this.bindMobile = system.bind_mobile
  234. }
  235. },
  236. onShow() {
  237. uni.$on('login_success', (data) => {
  238. console.log('login_success', data)
  239. this.setUser(data.user)
  240. })
  241. },
  242. onHide() {
  243. uni.$off('login_success')
  244. },
  245. methods: {
  246. ajax() {
  247. console.log('ajax')
  248. userApi.getUserInfo(this).then(res => {
  249. this.setUser(res.data)
  250. })
  251. },
  252. setUser(user) {
  253. this.user = user
  254. uni.setStorageSync('user', this.user)
  255. this.nickname = this.user.nickname
  256. this.mobile = this.user.mobile
  257. this.indexGender = this.user.gender
  258. this.birthday = this.user.birthday || '2000-01-01'
  259. },
  260. // 弹出昵称模态框
  261. showModalNickname(event) {
  262. this.showNickname = true
  263. },
  264. // 弹出手机模态框
  265. showModalMobile(event) {
  266. this.showMobile = true
  267. },
  268. // 弹出真实姓名模态框
  269. showModalRealName(event) {
  270. this.showRealName = true
  271. },
  272. // 选择头像
  273. onChooseAvatar(e) {
  274. console.log("e: ", e);
  275. this.tempAvatarUrl = e.detail.avatarUrl
  276. this.user.avatar = this.tempAvatarUrl
  277. },
  278. // 选择性别
  279. bindGenderChange: function(e) {
  280. console.log('gender', e)
  281. this.indexGender = e.detail.value
  282. },
  283. bindPickerChange1: function(e) {
  284. this.index1 = e.detail.value
  285. },
  286. bindDateChange: function(e) {
  287. this.birthday = e.detail.value
  288. },
  289. getDate(type) {
  290. const date = new Date();
  291. let year = date.getFullYear();
  292. let month = date.getMonth() + 1;
  293. let day = date.getDate();
  294. if (type === 'start') {
  295. year = year - 60;
  296. } else if (type === 'end') {
  297. year = year + 2;
  298. }
  299. month = month > 9 ? month : '0' + month;
  300. day = day > 9 ? day : '0' + day;
  301. return `${year}-${month}-${day}`;
  302. },
  303. // 获取微信手机号
  304. getPhoneNumber(e) {
  305. console.log('getPhoneNumber e', e)
  306. if (!e.iv || !e.encryptedData) {
  307. this.utils.toast('用户取消授权')
  308. return
  309. }
  310. const data = {
  311. iv: e.iv,
  312. encryptedData: e.encryptedData,
  313. }
  314. // 后端处理后返回解密的手机号码
  315. userApi.getWechatPhone(this, data).then(res => {
  316. console.log('getWechatPhone res', res)
  317. if (res.code == 1) {
  318. this.mobile = res.data.phoneNumber
  319. } else {
  320. this.utils.alert(res.msg)
  321. }
  322. })
  323. },
  324. // 保存设置
  325. async save() {
  326. if (this.bindMobile == 2 && !this.mobile) {
  327. this.utils.alert('请设置手机号码')
  328. return
  329. }
  330. let newAvatar = ''
  331. let uploadResult = ''
  332. // 上传头像
  333. if (this.tempAvatarUrl) {
  334. await this.utils.uploadFile(this, this.tempAvatarUrl).then(res => {
  335. if (res.code == 1) {
  336. newAvatar = res.data.fullurl
  337. uploadResult = ''
  338. } else {
  339. uploadResult = res.msg
  340. }
  341. })
  342. }
  343. console.log('uploadResult', uploadResult)
  344. console.log('newAvatar', newAvatar)
  345. if (uploadResult) {
  346. this.utils.alert(uploadResult)
  347. return
  348. }
  349. let data = {
  350. nickname: this.nickname,
  351. mobile: this.mobile,
  352. gender: this.indexGender,
  353. birthday: this.birthday
  354. }
  355. if (newAvatar) {
  356. data['avatar'] = newAvatar
  357. }
  358. console.log('save user data', data)
  359. await userApi.save(this, data).then(res => {
  360. console.log('user save res', res)
  361. if (res.code == 1) {
  362. uni.setStorageSync('user', this.user)
  363. this.utils.alert('保存成功')
  364. } else {
  365. this.utils.alert(res.msg)
  366. }
  367. })
  368. }
  369. }
  370. }
  371. </script>
  372. <style lang="scss">
  373. page {
  374. background-color: #fff !important;
  375. }
  376. /* 胶囊*/
  377. .tn-custom-nav-bar__back {
  378. width: 60%;
  379. height: 100%;
  380. position: relative;
  381. display: flex;
  382. justify-content: space-evenly;
  383. align-items: center;
  384. box-sizing: border-box;
  385. background-color: rgba(0, 0, 0, 0.15);
  386. border-radius: 1000rpx;
  387. border: 1rpx solid rgba(255, 255, 255, 0.5);
  388. color: #FFFFFF;
  389. font-size: 18px;
  390. .icon {
  391. display: block;
  392. flex: 1;
  393. margin: auto;
  394. text-align: center;
  395. }
  396. }
  397. /* 间隔线 start*/
  398. .tn-strip-bottom-min {
  399. width: 100%;
  400. border-bottom: 1rpx solid #F8F9FB;
  401. }
  402. .tn-strip-bottom {
  403. width: 100%;
  404. border-bottom: 20rpx solid rgba(241, 241, 241, 0.8);
  405. }
  406. /* 间隔线 end*/
  407. /* 用户头像 start */
  408. .logo-image {
  409. width: 80rpx;
  410. height: 80rpx;
  411. position: relative;
  412. }
  413. .logo-pic {
  414. background-size: cover;
  415. background-repeat: no-repeat;
  416. // background-attachment:fixed;
  417. background-position: top;
  418. border: 2rpx solid rgba(255, 255, 255, 0.05);
  419. box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.15);
  420. border-radius: 50%;
  421. overflow: hidden;
  422. // background-color: #FFFFFF;
  423. }
  424. .avatar-wrapper {
  425. background: none;
  426. }
  427. /* 底部悬浮按钮 start*/
  428. .tn-tabbar-height {
  429. min-height: 100rpx;
  430. height: calc(120rpx + env(safe-area-inset-bottom) / 2);
  431. }
  432. .tn-footerfixed {
  433. position: fixed;
  434. width: 100%;
  435. bottom: calc(30rpx + env(safe-area-inset-bottom));
  436. z-index: 1024;
  437. box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0);
  438. }
  439. /* 底部悬浮按钮 end*/
  440. </style>