index.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. <template>
  2. <view
  3. class="header-user"
  4. v-if="userDetails.id"
  5. @click.stop="handleOperation({ type: 'userDetails', needToken: true })"
  6. >
  7. <view class="user-photo">
  8. <image
  9. :src="userDetails.headPhoto || $defaultAvatar"
  10. mode="aspectFill"
  11. ></image>
  12. </view>
  13. <view class="user-info">
  14. <view class="user-name">{{ userDetails.nickname || "" }}</view>
  15. <view class="user-phone">{{ userDetails.mobile || "" }}</view>
  16. </view>
  17. <text class="iconfont icon-right1">&#xe671;</text>
  18. </view>
  19. <uv-gap height="12" bgColor="#F7F7F7"></uv-gap>
  20. <view class="body-operation">
  21. <view
  22. v-for="item in operationList"
  23. class="operation-item"
  24. :key="item.type"
  25. @click.stop="handleOperation(item)"
  26. >
  27. <text class="operation-item-label">{{ item.label }}</text>
  28. <text class="iconfont icon-right1">&#xe671;</text>
  29. </view>
  30. <view
  31. class="operation-item"
  32. key="versionUpdate"
  33. @click.stop="handleOperation({ type: 'versionUpdate' })"
  34. v-if="!weiXinShow"
  35. >
  36. <text class="operation-item-label">检测更新</text>
  37. <view>
  38. <text class="color-green" v-if="!appInfo.appUpdate && appInfo.version">
  39. V{{ appInfo.version }}</text
  40. >
  41. <text v-if="appInfo.appUpdate" style="color: #08be5d">有新版本</text>
  42. <text class="iconfont icon-right1">&#xe671;</text>
  43. </view>
  44. </view>
  45. </view>
  46. <!-- <uv-gap height="12" bgColor="#F7F7F7" v-if="!weiXinShow"></uv-gap>
  47. <view class="body-operation" v-if="!weiXinShow">
  48. <view class="bind-label">第三方绑定</view>
  49. <view
  50. class="operation-item bind-item"
  51. v-for="item in bindList"
  52. :key="item.type"
  53. @click="handleOperation(item)"
  54. >
  55. <text class="operation-item-label">{{ item.label }}</text>
  56. <view>
  57. <text class="color-green" v-if="item.bindShow" style="color: #808080;">已绑定</text>
  58. <text class="color-green" v-else>绑定验证</text>
  59. <text class="iconfont icon-right1">&#xe671;</text>
  60. </view>
  61. </view>
  62. </view> -->
  63. <view class="sign">
  64. <button class="u-btn-two" @click="logOut(1)">退出登录</button>
  65. </view>
  66. <!-- #ifdef APP-PLUS -->
  67. <!-- 版本更新 -->
  68. <VersionUpdate
  69. ref="versionUpdateRef"
  70. :open="false"
  71. @setAppInfo="setAppInfo"
  72. />
  73. <!-- #endif -->
  74. </template>
  75. <script setup>
  76. import { ref } from "vue";
  77. import { onLoad, onReachBottom, onPullDownRefresh } from "@dcloudio/uni-app";
  78. import { userLogout_Api, userBinding_Api, userInfo } from "@/api/login.js";
  79. import { thirdBindingInfo_Api } from "@/api/userInfo.js";
  80. import utils from "@/util/index.js";
  81. const versionUpdateRef = ref(null);
  82. const weiXinShow = ref(false);
  83. const userDetails = ref({});
  84. const appInfo = ref({}); // app信息
  85. const operationList = [
  86. {
  87. label: "更换手机号",
  88. needToken: true,
  89. type: "updatePhone",
  90. },
  91. {
  92. label: "设置支付密码",
  93. needToken: true,
  94. type: "setPayPassword",
  95. },
  96. {
  97. label: "关于我们",
  98. needToken: false,
  99. type: "aboutUs",
  100. },
  101. {
  102. label: "注销账户",
  103. needToken: true,
  104. type: "logOut",
  105. },
  106. ];
  107. const bindList = ref([
  108. {
  109. label: "微信",
  110. needToken: true,
  111. type: "wxBind",
  112. bindShow: false,
  113. },
  114. {
  115. label: "支付宝",
  116. needToken: true,
  117. type: "zfbBind",
  118. bindShow: false,
  119. },
  120. ]);
  121. const setAppInfo = (data) => {
  122. appInfo.value = data;
  123. };
  124. const handleOperation = (item) => {
  125. if (item.needToken && utils.isLoginTo(true)) return;
  126. switch (item.type) {
  127. case "updatePhone":
  128. uni.navigateTo({
  129. url: "/pages/set/updatePhone",
  130. });
  131. break;
  132. case "setPayPassword":
  133. uni.navigateTo({
  134. url: "/pages/set/payPassword",
  135. });
  136. break;
  137. case "aboutUs":
  138. uni.navigateTo({
  139. url: "/pages/protocol/index?code=about_us",
  140. });
  141. break;
  142. case "logOut":
  143. logOut(0);
  144. break;
  145. case "versionUpdate":
  146. if (appInfo.value.appUpdate) {
  147. versionUpdateRef.value.open();
  148. } else {
  149. uni.$uv.toast("当前版本为最新版本");
  150. }
  151. break;
  152. case "wxBind":
  153. WXBind();
  154. break;
  155. case "zfbBind":
  156. alipayBind();
  157. break;
  158. case "userDetails":
  159. uni.navigateTo({
  160. url: "/pages/set/edit",
  161. });
  162. break;
  163. default:
  164. break;
  165. }
  166. };
  167. // 退出登录
  168. const logOut = (type = 0) => {
  169. uni.showModal({
  170. title: type ? "你确定要退出吗?" : "你确定要注销账户吗?",
  171. success: function (res) {
  172. if (res.confirm) {
  173. uni.showLoading({
  174. title: type ? "正在退出..." : "注销中...",
  175. mask: true,
  176. });
  177. userLogout_Api()
  178. .then((res) => {
  179. uni.hideLoading();
  180. if (res.code == 200) {
  181. uni.clearStorageSync();
  182. uni.$uv.toast(type ? "退出成功" : "注销成功");
  183. // #ifdef MP-WEIXIN
  184. uni.redirectTo({
  185. url: "/pages/login/wxLogin",
  186. });
  187. // #endif
  188. // #ifndef MP-WEIXIN
  189. // 在此处编写仅在 App 端执行的代码
  190. uni.redirectTo({
  191. url: "/pages/login/otherLogin",
  192. });
  193. // #endif
  194. }
  195. })
  196. .catch((err) => {
  197. // uni.hideLoading();
  198. });
  199. } else if (res.cancel) {
  200. console.log("用户点击取消");
  201. }
  202. },
  203. });
  204. };
  205. // 绑定用户信息
  206. const setUserBinding = (data) => {
  207. userBinding_Api(data).then((res) => {
  208. if (res.code == 200) {
  209. uni.showToast({
  210. title: "绑定成功!",
  211. icon: "success",
  212. duration: 1500,
  213. });
  214. getThirdBindingInfo();
  215. }
  216. });
  217. };
  218. // 微信绑定
  219. const WXBind = () => {
  220. uni.login({
  221. provider: "weixin",
  222. onlyAuthorize: true, // 微信登录仅请求授权认证
  223. success: (event) => {
  224. const { code } = event;
  225. // console.log(event)
  226. //客户端成功获取授权临时票据(code),向业务服务器发起登录请求。
  227. let param = {
  228. thirdType: 0,
  229. code: code,
  230. };
  231. setUserBinding(param);
  232. },
  233. fail: (err) => {
  234. console.log(err);
  235. // 登录授权失败
  236. // err.code是错误码
  237. uni.$uv.toast("当前环境不支持微信操作!");
  238. },
  239. });
  240. };
  241. // 支付宝绑定
  242. const alipayBind = () => {
  243. const AlipayAuth = uni.requireNativePlugin("DHQ-AlipayAuth");
  244. AlipayAuth.login(
  245. {
  246. appId: "2021006116626014", //你在支付宝平台申请的App ID
  247. scheme: "xctUrlSchemes", // 需要传到支付宝SDK的scheme,注意需要在manifest.json-->App其他常用配置-->UrlSchemes中配置Android和iOS的
  248. scope: "auth_user", //默认为auth_user
  249. init: "init", //默认传入init
  250. },
  251. (res) => {
  252. // console.log("res===>", res);
  253. //客户端成功获取授权临时票据(code),向业务服务器发起登录请求。
  254. let code = res.auth_code;
  255. if (code) {
  256. let param = {
  257. code: code,
  258. thirdType: 1,
  259. };
  260. setUserBinding(param);
  261. }
  262. },
  263. (e) => {
  264. console.log(e);
  265. uni.$uv.toast("当前环境不支持支付宝操作!");
  266. }
  267. );
  268. };
  269. // 获取用户信息
  270. const getuserDetails = () => {
  271. userInfo().then((res) => {
  272. if (res && res.code == 200) {
  273. userDetails.value = res.data || {};
  274. uni.setStorageSync("personal", res.data || {});
  275. }
  276. });
  277. };
  278. // 获取第三方绑定信息
  279. const getThirdBindingInfo = () => {
  280. thirdBindingInfo_Api().then((res) => {
  281. if (res && res.code == 200) {
  282. // bindList.value = res.data || [];
  283. bindList.value[0].bindShow = res.data.bindingWechat ? true : false;
  284. bindList.value[1].bindShow = res.data.bindingAlipay ? true : false;
  285. }
  286. });
  287. };
  288. onLoad(() => {
  289. // #ifdef MP-WEIXIN
  290. weiXinShow.value = true;
  291. // #endif
  292. getuserDetails();
  293. // #ifndef MP-WEIXIN
  294. console.log("不是小程序");
  295. getThirdBindingInfo()
  296. // #endif
  297. });
  298. </script>
  299. <style lang="scss" scoped>
  300. .header-user {
  301. display: flex;
  302. align-items: center;
  303. padding: 40rpx 30rpx;
  304. font-size: 28rpx;
  305. font-family: PingFang SC, PingFang SC-Regular;
  306. font-weight: normal;
  307. color: #666666;
  308. .user-photo {
  309. flex-shrink: 0;
  310. image {
  311. width: 100rpx;
  312. height: 100rpx;
  313. margin-right: 25rpx;
  314. border-radius: 50%;
  315. }
  316. }
  317. .user-info {
  318. flex: 1;
  319. width: 0;
  320. margin-right: 20rpx;
  321. .user-name {
  322. margin-bottom: 5rpx;
  323. font-size: 32rpx;
  324. font-family: PingFang SC, PingFang SC-Bold;
  325. font-weight: bold;
  326. color: #1a1a1a;
  327. overflow: hidden;
  328. text-overflow: ellipsis;
  329. white-space: nowrap;
  330. }
  331. }
  332. .icon-right1 {
  333. margin-left: auto;
  334. }
  335. }
  336. .body-operation {
  337. padding: 0 30rpx;
  338. font-size: 28rpx;
  339. font-family: PingFang SC, PingFang SC-Regular;
  340. font-weight: normal;
  341. color: #1a1a1a;
  342. .operation-item {
  343. display: flex;
  344. align-items: center;
  345. justify-content: space-between;
  346. padding: 30rpx 0;
  347. border-bottom: 1rpx solid #f0f0f0;
  348. &:last-child {
  349. border: none;
  350. }
  351. .icon-right1 {
  352. margin-left: auto;
  353. color: #666666;
  354. }
  355. }
  356. .bind-label {
  357. padding-top: 30rpx;
  358. font-size: 32rpx;
  359. font-family: PingFang SC, PingFang SC-Bold;
  360. font-weight: bold;
  361. color: #1a1a1a;
  362. }
  363. .operation-item.bind-item {
  364. border-bottom: 1rpx solid #f0f0f0;
  365. }
  366. }
  367. .sign {
  368. padding: 100rpx 30rpx;
  369. box-sizing: border-box;
  370. .u-btn-two {
  371. height: 90rpx;
  372. line-height: 90rpx;
  373. }
  374. }
  375. .color-green {
  376. color: #0090ff;
  377. font-size: 28rpx;
  378. }
  379. </style>