index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. <template>
  2. <view class="app-page">
  3. <button class="avatar-wrapper" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"
  4. style="border: none;background: transparent;margin: 0;padding: 72rpx 0;">
  5. <view class="h-view">
  6. <u--image v-if="form.headimg" width='144rpx' height='144rpx' radius="100%" shape='circle'
  7. customStyle="margin: 0" :src="form.headimg" :fade="true" duration="450" mode='heightFix'>
  8. </u--image>
  9. <view class="v1" v-else>
  10. <u--image width='144rpx' height='144rpx' radius="100%" shape='circle'
  11. :src="`${$getImgBaseUrl()}nologin.png`" :fade="true" duration="450" mode='heightFix'>
  12. </u--image>
  13. </view>
  14. </view>
  15. </button>
  16. <view class="card-box">
  17. <view class="display-flex-between" >
  18. <text class="left-title">昵称</text>
  19. <view class="h-view">
  20. <u-input v-model="form.nickname" placeholder="请输入" type="nickname" border="none" :auto-height="true"
  21. clearable inputAlign="right" />
  22. </view>
  23. </view>
  24. <u-divider ></u-divider>
  25. <view class="display-flex-between" >
  26. <text class="left-title">姓名</text>
  27. <view class="h-view">
  28. <u-input v-model="form.realname" placeholder="请输入" border="none" :auto-height="true" clearable
  29. inputAlign="right" />
  30. </view>
  31. </view>
  32. <u-divider ></u-divider>
  33. <view class="display-flex-between" @click="show2 = true">
  34. <text class="left-title">性别</text>
  35. <view class="h-view" >
  36. {{form.base_sex}} <view class="ml8"><u-icon name="arrow-right" bold color="#333333" size="14"></u-icon></view>
  37. </view>
  38. </view>
  39. <u-divider ></u-divider>
  40. <view class="display-flex-between" >
  41. <text class="left-title">所在地区</text>
  42. <view class="h-view">
  43. <picker mode="region" :value="form.region_area" @change="bindAreaChange">
  44. <view v-if="!form.region_province" class="color-9 display-flex-content-center">省市区县、乡镇等 <view class="ml8"><u-icon name="arrow-right" bold color="#333333" size="14"></u-icon></view></view>
  45. <view v-else class="color-23 display-flex-content-center">{{areaDisplay}} <view class="ml8"><u-icon name="arrow-right" bold color="#333333" size="14"></u-icon></view></view>
  46. </picker>
  47. </view>
  48. </view>
  49. <u-divider ></u-divider>
  50. <view class="display-flex-between" >
  51. <text class="left-title">手机号</text>
  52. <view class="h-view">
  53. <u-input v-model="form.phone" placeholder="请输入" type="number" border="none" :auto-height="true"
  54. clearable :maxlength="11" customStyle="margin:0 20rpx;text-align: right;" />
  55. <button class="btn-c" open-type="getRealtimePhoneNumber"
  56. @getrealtimephonenumber="getrealtimephonenumber" size="mini">获取手机号</button>
  57. </view>
  58. </view>
  59. </view>
  60. <view class="bottom-menu-box">
  61. <view class="agree-box">
  62. <view class="unchecked-tips" v-show="showUnchecked">请先阅读并同意协议</view>
  63. <u-checkbox-group @change="termsChange" v-model="termsChecked" style="margin-left: 30rpx;">
  64. <u-checkbox activeColor="#C29556" name="term" shape="circle" size="40rpx"></u-checkbox>
  65. </u-checkbox-group>
  66. <text class="item-text">
  67. 已阅读并同意
  68. <text class="text-primary fs14 fw600" @click="checkPrimary('2')">《隐私保护协议》</text>
  69. <text class="text-primary fs14 fw600" @click="checkPrimary('1')">《用户协议》</text>
  70. </text>
  71. </view>
  72. <view class="common-btn" @click="commit">提交</view>
  73. </view>
  74. <u-picker :show="show" keyName="label" confirmColor="#815BFF" :columns="[list]" @confirm="confirm"
  75. @cancel="show = false"></u-picker>
  76. <u-picker :show="show2" :columns="columns" ref="uPicker" @confirm="sexConfirm" @cancel="sexCancel" ></u-picker>
  77. </view>
  78. </template>
  79. <script>
  80. import {
  81. uploadBase64File,
  82. } from "@/common/api/common.js";
  83. import {
  84. updateUserInfo,
  85. userRegister,
  86. getUserInfo
  87. } from "@/common/api/user.js";
  88. import {
  89. getUserPhone
  90. } from "@/common/api/common.js";
  91. export default {
  92. data() {
  93. return {
  94. form: {
  95. region_province: '',
  96. region_city: '',
  97. region_area: '',
  98. nickname: undefined,
  99. realname: undefined,
  100. headimg: undefined,
  101. avatarUrl: undefined,
  102. phone: undefined,
  103. base_sex: undefined,
  104. },
  105. columns: [
  106. ['男', '女']
  107. ],
  108. showUnchecked: false,
  109. termsChecked: false,
  110. show: false,
  111. show2: false,
  112. isNeedUpLoad: false,
  113. userInfo: {},
  114. selectItem: {},
  115. }
  116. },
  117. computed: {
  118. areaDisplay() {
  119. const {
  120. region_province = '', region_city = '', region_area = ''
  121. } = this.form
  122. return region_province +' '+ region_city +' ' + region_area
  123. },
  124. },
  125. onLoad(options) {},
  126. onShow() {
  127. this.reUserInfo();
  128. this.getUserInfo();
  129. },
  130. methods: {
  131. getrealtimephonenumber(e) {
  132. console.log("getrealtimephonenumber=>", e)
  133. if (e.detail?.code) {
  134. this.getUserPhone(e.detail?.code)
  135. }
  136. },
  137. async getUserPhone(code) {
  138. const data = {
  139. code: code
  140. }
  141. await getUserPhone(data)
  142. .then(res => {
  143. if (res.data) {
  144. this.form.phone = res.data.purePhoneNumber
  145. }
  146. })
  147. .catch(() => {
  148. uni.hideLoading();
  149. });
  150. },
  151. bindAreaChange(data) {
  152. const {
  153. code,
  154. value
  155. } = data.detail
  156. this.form.region_province = value[0]
  157. this.form.region_city = value[1]
  158. this.form.region_area = value[2]
  159. // this.areaDisplay = value.join('.')
  160. console.log(8999, data, this.form)
  161. },
  162. // 回调参数为包含columnIndex、value、values
  163. sexConfirm(e) {
  164. const {
  165. value,
  166. } = e
  167. console.log(e)
  168. this.form.base_sex = value[0]
  169. this.show2 = false
  170. },
  171. sexCancel(e) {
  172. this.show2 = false
  173. },
  174. checkPrimary(name) {
  175. uni.navigateTo({
  176. url: '/pages/singlePage/index?name=' + name
  177. });
  178. },
  179. termsChange(value) {
  180. if (value.length) {
  181. this.showUnchecked = false;
  182. } else {
  183. this.showUnchecked = true;
  184. }
  185. },
  186. toAuthenticationList() {
  187. uni.navigateTo({
  188. url: '/subPages/authenticationList/index'
  189. })
  190. },
  191. commit() {
  192. if (this.isNeedUpLoad) {
  193. this.getImageInfo()
  194. return
  195. }
  196. if (!this.termsChecked.length) {
  197. this.showUnchecked = true;
  198. return;
  199. }
  200. if (!this.form.region_province) {
  201. uni.$u.toast('请选择所在地区')
  202. return
  203. }
  204. if (!this.form.phone) {
  205. uni.$u.toast('请输入手机号')
  206. return
  207. }
  208. if (this.form.phone.length!==11) {
  209. uni.$u.toast('请输入11位手机号')
  210. return
  211. }
  212. this.userRegister();
  213. },
  214. reUserInfo() {
  215. const userInfo = uni.getStorageSync('userInfo');
  216. if (userInfo && JSON.parse(userInfo).nickname != '' && JSON.parse(userInfo).headimg != '') {
  217. this.userInfo = JSON.parse(userInfo);
  218. const {
  219. headimg,
  220. nickname,
  221. base_sex,
  222. realname,
  223. region_area,
  224. region_city,
  225. region_province,
  226. phone
  227. } =
  228. this.userInfo
  229. this.avatarUrl = headimg
  230. this.form = Object.assign({}, this.form, {
  231. headimg,
  232. nickname,
  233. base_sex,
  234. realname,
  235. region_area,
  236. region_city,
  237. region_province,
  238. phone
  239. })
  240. }
  241. console.log("reUserInfo==>", this.form);
  242. },
  243. async getUserInfo() {
  244. const data = {}
  245. await getUserInfo(data)
  246. .then(res => {
  247. if (res.data) {
  248. uni.setStorageSync('token', res.data.token.token)
  249. uni.setStorageSync('userInfo', JSON.stringify(res.data))
  250. this.userInfo = res.data;
  251. console.log("getUserInfo==>", this.userInfo)
  252. }
  253. })
  254. .catch(() => {
  255. uni.hideLoading();
  256. });
  257. await this.reUserInfo();
  258. },
  259. onChooseAvatar(e) {
  260. const {
  261. avatarUrl
  262. } = e.detail
  263. console.log('成功授权', avatarUrl)
  264. this.form.headimg = avatarUrl
  265. this.isNeedUpLoad = true;
  266. },
  267. getImageInfo() {
  268. // 获取当前图片信息
  269. uni.getImageInfo({
  270. src: this.form.headimg,
  271. success: (image) => {
  272. // 做png/jpeg的类型判断————对不同类型的图像添加不同的转换头信息
  273. if (image.type == 'png' || image.type == 'jpeg') {
  274. // 对符合类型的图片转换为base64类型
  275. uni.getFileSystemManager().readFile({ // 【重点来啦】人家自提供的转码API
  276. filePath: image.path, // 所需转码图像路径
  277. encoding: "base64", // 转码类型
  278. success: (res) => {
  279. // 生成base64
  280. let imageBase64 = 'data:image/' + image.type + ';base64,' + res
  281. .data;
  282. console.log('转base64后:', imageBase64);
  283. this.uploadBase64File(imageBase64)
  284. }
  285. })
  286. } else { // 友好一点,不是以上类型做出提醒
  287. uni.showToast({
  288. title: '当前只支持png/jpeg格式',
  289. duration: 2500,
  290. icon: 'none'
  291. })
  292. }
  293. }
  294. });
  295. },
  296. uploadBase64File(imageBase64) {
  297. uploadBase64File({
  298. base64: imageBase64
  299. }, {
  300. 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
  301. })
  302. .then((res) => {
  303. console.log("uploadFile==>", res.data.url)
  304. this.avatarUrl = res.data.url
  305. this.form.headimg = res.data.url
  306. this.userRegister();
  307. })
  308. .catch(() => {
  309. uni.hideLoading();
  310. });
  311. },
  312. confirm(e) {
  313. this.selectItem = e.value[0];
  314. console.log(e.value[0].label);
  315. this.show = false;
  316. },
  317. userRegister() {
  318. this.isNeedUpLoad = false;
  319. const data = this.form;
  320. updateUserInfo(data)
  321. .then((res) => {
  322. console.log("updateUserInfo==>", res.data)
  323. if (res.data) {
  324. if (res.data.token) {
  325. uni.setStorageSync('token', res.data.token.token)
  326. }
  327. uni.setStorageSync('userInfo', JSON.stringify(res.data))
  328. uni.$u.toast('更新成功')
  329. setTimeout(() => {
  330. uni.navigateBack()
  331. }, 800);
  332. }
  333. });
  334. },
  335. }
  336. }
  337. </script>
  338. <style lang="scss" scoped>
  339. .app-page {
  340. width: 100%;
  341. display: flex;
  342. align-items: center;
  343. flex-direction: column;
  344. }
  345. .card-box {
  346. width: 650rpx;
  347. background: #FFFFFF;
  348. border-radius: 20rpx 20rpx 20rpx 20rpx;
  349. margin: 0 auto 20rpx auto;
  350. padding: 30rpx;
  351. }
  352. .h-view {
  353. flex: 1;
  354. display: flex;
  355. flex-direction: row;
  356. justify-content: flex-end;
  357. align-items: center;
  358. }
  359. .left-title {
  360. font-size: 28rpx;
  361. }
  362. button::after {
  363. border: none;
  364. }
  365. .avatar-wrapper button::before {
  366. padding: 0;
  367. margin: 0;
  368. border-radius: 20rpx;
  369. background: transparent;
  370. border: none;
  371. line-height: 1;
  372. }
  373. .avatar-wrapper button::after {
  374. padding: 0;
  375. margin: 0;
  376. border-radius: 20rpx;
  377. background: transparent;
  378. border: none;
  379. line-height: 1;
  380. }
  381. .agree-box {
  382. display: flex;
  383. color: $gray-1;
  384. position: relative;
  385. align-items: center;
  386. margin: 0 auto;
  387. .unchecked-tips {
  388. position: absolute;
  389. height: 50rpx;
  390. color: #fff;
  391. background-color: rgba($color: #27282a, $alpha: 1);
  392. top: -60rpx;
  393. left: 0;
  394. border-radius: 8rpx;
  395. line-height: 50rpx;
  396. font-size: 24rpx;
  397. padding: 0 16rpx;
  398. &::after {
  399. display: "block";
  400. content: "";
  401. position: absolute;
  402. width: 20rpx;
  403. height: 20rpx;
  404. // background: rgba($color: #27282a, $alpha: 1);
  405. bottom: -6rpx;
  406. left: 10rpx;
  407. transform: rotate(45deg);
  408. border-radius: 4rpx;
  409. }
  410. }
  411. .u-checkbox {
  412. flex-shrink: 0;
  413. align-items: flex-start;
  414. margin-top: 6rpx;
  415. }
  416. .item-text {
  417. font-size: 24rpx;
  418. }
  419. }
  420. .bottom-view {
  421. margin-bottom: var(--window-bottom);
  422. padding-bottom: calc(260rpx);
  423. }
  424. .bottom-menu-box {
  425. height: calc(260rpx);
  426. display: flex;
  427. flex-direction: column;
  428. justify-content: center;
  429. align-items: flex-start;
  430. position: fixed;
  431. z-index: 9;
  432. background: white;
  433. bottom: var(--window-bottom);
  434. left: 0;
  435. right: 0;
  436. width: 100vw;
  437. .primary-btn {
  438. width: 713rpx;
  439. margin-top: 50rpx;
  440. height: 78rpx;
  441. line-height: 78rpx;
  442. background: #815BFF;
  443. border-radius: 40rpx;
  444. font-size: 32rpx;
  445. font-family: PingFang SC-Medium, PingFang SC;
  446. font-weight: 500;
  447. color: #FFFFFF;
  448. }
  449. .common-btn {
  450. // width: 713rpx;
  451. width: calc(100% - 80rpx);
  452. box-sizing: border-box;
  453. margin: 0 auto;
  454. margin-top: 50rpx;
  455. background: linear-gradient( 315deg, #CA9359 0%, #E2B98E 100%);
  456. border-radius: 292rpx 292rpx 292rpx 292rpx;
  457. border:0;
  458. }
  459. button::after {
  460. height: 78rpx;
  461. line-height: 78rpx;
  462. }
  463. .primary-btn:active {
  464. opacity: 0.7;
  465. }
  466. }
  467. .btn-c{
  468. width: 180rpx;
  469. height: 56rpx;
  470. border-radius: 8rpx 8rpx 8rpx 8rpx;
  471. border: 2rpx solid #C29556;
  472. padding: 0 10px;
  473. }
  474. </style>