setting.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. <!-- 用户信息 -->
  2. <template>
  3. <s-layout title="用户信息" class="set-userinfo-wrap">
  4. <uni-forms
  5. :model="state.model"
  6. :rules="state.rules"
  7. labelPosition="left"
  8. border
  9. class="form-box"
  10. >
  11. <view class="bg-white">
  12. <uni-list :border="false" class="">
  13. <uni-list-chat
  14. clickable
  15. :avatar-circle="true"
  16. :title="state.model?.nickname"
  17. :avatar="state.model?.avatar"
  18. note="个性签名"
  19. @tap="sheep.$router.go('/pages/user/info')"
  20. >
  21. <view class="chat-custom-right">
  22. <text
  23. class="_icon-forward"
  24. style="color: #bbbbbb; font-size: 32rpx"
  25. ></text>
  26. </view>
  27. </uni-list-chat>
  28. <uni-list-item
  29. clickable
  30. @tap="sheep.$router.go('/pages/user/address/list')"
  31. title="实体收货地址管理"
  32. showArrow
  33. :border="false"
  34. />
  35. <uni-list-item
  36. clickable
  37. @tap="sheep.$router.go('/pages/user/dummyAddress/list')"
  38. title="虚拟收货地址管理"
  39. showArrow
  40. :border="false"
  41. />
  42. <uni-list-item
  43. title="支付宝账号"
  44. showArrow
  45. clickable
  46. :border="false"
  47. @tap="onChangeAlipayAccount">
  48. <template v-slot:body>
  49. <p style="width: 100%"
  50. >支付宝账号&nbsp;&nbsp;{{alipayAccount?alipayAccount:'未绑定'}}
  51. </p>
  52. </template>
  53. </uni-list-item>
  54. <uni-list-item
  55. title="银行卡"
  56. showArrow
  57. clickable
  58. :border="false"
  59. @tap="onChangeBankAccount">
  60. <template v-slot:body>
  61. <p style="width: 100%"
  62. >银行卡&nbsp;&nbsp;{{bankAccount?bankAccount:'未绑定'}}
  63. </p>
  64. </template>
  65. </uni-list-item>
  66. <!-- <uni-list-item
  67. clickable
  68. @tap="sheep.$router.go('/pages/user/invoice/list')"
  69. title="发票抬头管理"
  70. showArrow
  71. :border="false"
  72. /> -->
  73. <uni-list-item
  74. :clickable="!userInfo.mobile"
  75. @tap="sheep.$router.go('/pages/user/address/list')"
  76. title="实名认证"
  77. showArrow
  78. :border="false"
  79. >
  80. <template v-slot:body>
  81. <p style="width: 100%"
  82. >实名认证&nbsp;&nbsp; 未认证
  83. </p>
  84. </template>
  85. </uni-list-item>
  86. <uni-list-item
  87. v-if="userWallet.isPtSystemUser"
  88. :clickable="true"
  89. @tap="goBackEnd('pt')"
  90. title="进入平台"
  91. showArrow
  92. :border="false"
  93. >
  94. <template v-slot:body>
  95. <p style="width: 100%"
  96. >进入平台
  97. </p>
  98. </template>
  99. </uni-list-item>
  100. <uni-list-item
  101. v-if="userWallet.isShSystemUser"
  102. :clickable="true"
  103. @tap="goBackEnd('sh')"
  104. title="进入商家后台"
  105. showArrow
  106. :border="false"
  107. >
  108. <template v-slot:body>
  109. <p style="width: 100%"
  110. >进入商家后台
  111. </p>
  112. </template>
  113. </uni-list-item>
  114. <uni-list-item
  115. title="我的二维码"
  116. clickable
  117. @tap="sheep.$router.go('/pages/user/qrcode-share')"
  118. :border="false"
  119. >
  120. <template v-slot:body>
  121. <p style="width: 100%; display: flex; align-items: center">
  122. 我的二维码&nbsp;&nbsp;&nbsp;&nbsp;
  123. <su-image
  124. class="content-img"
  125. style="border: 1px solid #f4f4f4"
  126. :current="0"
  127. :src="state.model?.avatar"
  128. :height="100"
  129. :width="100"
  130. :radius="0"
  131. mode="scaleToFill"
  132. />
  133. </p>
  134. </template>
  135. </uni-list-item>
  136. </uni-list>
  137. </view>
  138. </uni-forms>
  139. <!-- 当前社交平台的绑定关系,只处理 wechat 微信场景 -->
  140. <view v-if="sheep.$platform.name !== 'H5'">
  141. <view class="title-box ss-p-l-30">第三方账号绑定</view>
  142. <view class="account-list ss-flex ss-row-between">
  143. <view v-if="'WechatOfficialAccount' === sheep.$platform.name" class="ss-flex ss-col-center">
  144. <image class="list-img" :src="sheep.$url.static('/static/images/WechatOfficialAccount.png')" />
  145. <text class="list-name">微信公众号</text>
  146. </view>
  147. <view v-if="'WechatMiniProgram' === sheep.$platform.name" class="ss-flex ss-col-center">
  148. <image class="list-img" :src="sheep.$url.static('/static/images/WechatMiniProgram.png')" />
  149. <text class="list-name">微信小程序</text>
  150. </view>
  151. <view v-if="'App' === sheep.$platform.name" class="ss-flex ss-col-center">
  152. <image class="list-img" :src="sheep.$url.static('/static/images/wechat.png')" />
  153. <text class="list-name">微信开放平台</text>
  154. </view>
  155. <view class="ss-flex ss-col-center">
  156. <view class="info ss-flex ss-col-center" v-if="state.thirdInfo">
  157. <image class="avatar ss-m-r-20" :src="sheep.$url.cdn(state.thirdInfo.avatar)" />
  158. <text class="name">{{ state.thirdInfo.nickname }}</text>
  159. </view>
  160. <view class="bind-box ss-m-l-20">
  161. <button v-if="state.thirdInfo.openid" class="ss-reset-button relieve-btn"
  162. @tap="unBindThirdOauth">
  163. 解绑
  164. </button>
  165. <button v-else class="ss-reset-button bind-btn" @tap="bindThirdOauth">绑定</button>
  166. </view>
  167. </view>
  168. </view>
  169. </view>
  170. <su-fixed bottom placeholder>
  171. <view class="ss-p-x-20 ss-p-b-40">
  172. <button class="loginout-btn ss-reset-button" @tap="onLogout" v-if="isLogin">
  173. 退出登录
  174. </button>
  175. </view>
  176. </su-fixed>
  177. <!-- <su-fixed bottom placeholder bg="none">
  178. <view class="footer-box ss-p-20">
  179. <button class="ss-rest-button logout-btn ui-Shadow-Main" @tap="onSubmit">保存</button>
  180. </view>
  181. </su-fixed> -->
  182. </s-layout>
  183. </template>
  184. <script setup>
  185. import { computed, reactive, onBeforeMount } from 'vue';
  186. import sheep from '@/sheep';
  187. import { clone } from 'lodash';
  188. const isLogin = computed(() => sheep.$store('user').isLogin);
  189. import { showAuthModal, showShareModal } from '@/sheep/hooks/useModal';
  190. import FileApi from '@/sheep/api/infra/file';
  191. import UserApi from '@/sheep/api/member/user';
  192. import AuthUtil from '@/sheep/api/member/auth';
  193. import {
  194. onLoad
  195. } from '@dcloudio/uni-app';
  196. const userInfo = computed(() => sheep.$store('user').userInfo);
  197. const userWallet = computed(() => sheep.$store('user').userWallet);
  198. const alipayAccount = computed(() => {
  199. let account = userInfo.value.alipayAccount;
  200. if (!account) {
  201. return false;
  202. }
  203. // 手机号脱敏
  204. if (/^\d{11}$/.test(account)) { // 检查是否是11位数字的手机号
  205. return `${account.substring(0, 3)}****${account.substring(7)}`;
  206. } else if (/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(account)) {
  207. const atIndex = account.indexOf('@');
  208. // 邮箱用户名长度小于等于3位时,不脱敏
  209. if (atIndex <= 3) {
  210. return account;
  211. }
  212. const username = account.substring(0, Math.ceil(atIndex / 2)); // 取邮箱用户名的一半
  213. const domain = account.substring(atIndex); // 邮箱域名部分
  214. return `${username}***${domain}`;
  215. }
  216. })
  217. const bankAccount = computed(() => {
  218. let account = userInfo.value.bankAccount;
  219. if (!account) {
  220. return false;
  221. }
  222. if (account.length === 8) {
  223. return account.substring(0, 2) + '********' + account.substr(-2);
  224. } else {
  225. return account.substring(0, 4) + '******' + account.substr(-4);
  226. }
  227. })
  228. // 修改支付宝账号
  229. const onChangeAlipayAccount = () => {
  230. showAuthModal('alipayAccount');
  231. };
  232. // 修改银行卡号
  233. const onChangeBankAccount = () => {
  234. showAuthModal('bankAccount');
  235. };
  236. const state = reactive({
  237. model: {}, // 个人信息
  238. rules: {},
  239. thirdInfo: {}, // 社交用户的信息
  240. });
  241. const placeholderStyle = 'color:#BBBBBB;font-size:28rpx;line-height:normal';
  242. // 绑定第三方账号
  243. async function bindThirdOauth() {
  244. let result = await sheep.$platform.useProvider('wechat').bind();
  245. if (result) {
  246. await getUserInfo();
  247. }
  248. }
  249. // 解绑第三方账号
  250. function unBindThirdOauth() {
  251. uni.showModal({
  252. title: '解绑提醒',
  253. content: '解绑后您将无法通过微信登录此账号',
  254. cancelText: '再想想',
  255. confirmText: '确定',
  256. success: async function(res) {
  257. if (!res.confirm) {
  258. return;
  259. }
  260. const result = await sheep.$platform.useProvider('wechat').unbind(state.thirdInfo.openid);
  261. if (result) {
  262. await getUserInfo();
  263. }
  264. },
  265. });
  266. }
  267. // 保存信息
  268. async function onSubmit() {
  269. const { code } = await UserApi.updateUser({
  270. avatar: state.model.avatar,
  271. nickname: state.model.nickname,
  272. sex: state.model.sex,
  273. });
  274. if (code === 0) {
  275. await getUserInfo();
  276. }
  277. }
  278. // 获得用户信息
  279. const getUserInfo = async () => {
  280. // 个人信息
  281. const userInfo = await sheep.$store('user').getInfo();
  282. state.model = clone(userInfo);
  283. // 获得社交用户的信息
  284. if (sheep.$platform.name !== 'H5') {
  285. const result = await sheep.$platform.useProvider('wechat').getInfo();
  286. state.thirdInfo = result || {};
  287. }
  288. };
  289. // 退出账号
  290. function onLogout() {
  291. uni.showModal({
  292. title: '提示',
  293. content: '确认退出账号?',
  294. success: async function(res) {
  295. if (!res.confirm) {
  296. return;
  297. }
  298. const {
  299. code
  300. } = await AuthUtil.logout();
  301. if (code !== 0) {
  302. return;
  303. }
  304. sheep.$store('user').logout();
  305. uni.removeStorageSync('linkId');
  306. sheep.$router.go('/pages/index/user');
  307. },
  308. });
  309. }
  310. // 跳到平台到商户
  311. async function goBackEnd(type){
  312. const {
  313. code,
  314. data
  315. } = await AuthUtil.getConsumerRedirectUrl();
  316. if(code === 0){
  317. window.location.href = data;
  318. }
  319. }
  320. onBeforeMount(() => {
  321. getUserInfo();
  322. });
  323. onLoad(()=>{
  324. uni.$on('alipayAccountChangeComplete', getUserInfo);
  325. uni.$on('bankAccountChangeComplete', getUserInfo);
  326. })
  327. </script>
  328. <style lang="scss" scoped>
  329. .loginout-btn {
  330. background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
  331. color:#fff;
  332. width: 100%;
  333. height: 80rpx;
  334. border-radius: 40rpx;
  335. font-size: 30rpx;
  336. }
  337. :deep() {
  338. .uni-file-picker {
  339. border-radius: 50%;
  340. }
  341. .uni-list-chat__content-extra {
  342. display: flex;
  343. justify-content: center;
  344. }
  345. .uni-file-picker__container {
  346. margin: -14rpx -12rpx;
  347. }
  348. .file-picker__progress {
  349. height: 0 !important;
  350. }
  351. .uni-list-item__content-title {
  352. font-size: 32rpx !important;
  353. color: #333333 !important;
  354. line-height: normal !important;
  355. }
  356. .uni-icons {
  357. font-size: 40rpx !important;
  358. }
  359. .is-disabled {
  360. color: #333333;
  361. }
  362. }
  363. :deep(.disabled) {
  364. opacity: 1;
  365. }
  366. .uni-list-item {
  367. min-height: 100rpx;
  368. }
  369. .gender-name {
  370. font-size: 28rpx;
  371. font-weight: 500;
  372. line-height: normal;
  373. color: #333333;
  374. }
  375. .title-box {
  376. font-size: 28rpx;
  377. font-weight: 500;
  378. color: #666666;
  379. line-height: 60rpx;
  380. }
  381. .logout-btn {
  382. width: 710rpx;
  383. height: 80rpx;
  384. background: linear-gradient(90deg, #132b85, #193bb6);
  385. border-radius: 40rpx;
  386. font-size: 30rpx;
  387. font-weight: 500;
  388. color: $white;
  389. }
  390. .radio-dark {
  391. filter: grayscale(100%);
  392. filter: gray;
  393. opacity: 0.4;
  394. }
  395. .content-img {
  396. border-radius: 50%;
  397. }
  398. .header-box-content {
  399. position: relative;
  400. width: 160rpx;
  401. height: 160rpx;
  402. overflow: hidden;
  403. border-radius: 50%;
  404. }
  405. .avatar-action {
  406. position: absolute;
  407. left: 50%;
  408. transform: translateX(-50%);
  409. bottom: 0;
  410. z-index: 1;
  411. width: 160rpx;
  412. height: 46rpx;
  413. background: rgba(#000000, 0.3);
  414. .avatar-action-btn {
  415. width: 160rpx;
  416. height: 46rpx;
  417. font-weight: 500;
  418. font-size: 24rpx;
  419. color: #ffffff;
  420. }
  421. }
  422. // 绑定项
  423. .account-list {
  424. background-color: $white;
  425. height: 100rpx;
  426. padding: 0 20rpx;
  427. .list-img {
  428. width: 40rpx;
  429. height: 40rpx;
  430. margin-right: 10rpx;
  431. }
  432. .list-name {
  433. font-size: 28rpx;
  434. color: #333333;
  435. }
  436. .info {
  437. .avatar {
  438. width: 38rpx;
  439. height: 38rpx;
  440. border-radius: 50%;
  441. overflow: hidden;
  442. }
  443. .name {
  444. font-size: 28rpx;
  445. font-weight: 400;
  446. color: $dark-9;
  447. }
  448. }
  449. .bind-box {
  450. width: 100rpx;
  451. height: 50rpx;
  452. line-height: normal;
  453. display: flex;
  454. justify-content: center;
  455. align-items: center;
  456. font-size: 24rpx;
  457. .bind-btn {
  458. width: 100%;
  459. height: 100%;
  460. border-radius: 25rpx;
  461. background: #f4f4f4;
  462. color: #999999;
  463. }
  464. .relieve-btn {
  465. width: 100%;
  466. height: 100%;
  467. border-radius: 25rpx;
  468. background: var(--ui-BG-Main-opacity-1);
  469. color: var(--ui-BG-Main);
  470. }
  471. }
  472. }
  473. .list-border {
  474. font-size: 28rpx;
  475. font-weight: 400;
  476. color: #333333;
  477. border-bottom: 2rpx solid #eeeeee;
  478. }
  479. image {
  480. width: 100%;
  481. height: 100%;
  482. }
  483. </style>