wx.uvue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <template>
  2. <cl-popup
  3. v-model="editVisible"
  4. direction="center"
  5. :title="t('提示')"
  6. size="80%"
  7. @close="onEditClose"
  8. >
  9. <view class="p-4 pt-0">
  10. <cl-text color="info">
  11. {{ t("为提供更好的服务,我们邀请您填写昵称、头像等公开信息") }}
  12. </cl-text>
  13. <view
  14. class="flex flex-row justify-between items-center bg-surface-100 rounded-xl p-2 px-3 mt-3 h-[48px]"
  15. >
  16. <cl-text>{{ t("头像") }}</cl-text>
  17. <view class="relative">
  18. <cl-avatar :size="30" :src="editForm.avatarUrl"></cl-avatar>
  19. <button
  20. class="absolute top-0 right-0 h-10 w-10 z-10 opacity-0 p-0 m-0"
  21. open-type="chooseAvatar"
  22. @chooseavatar="onEditChooseAvatar"
  23. ></button>
  24. </view>
  25. </view>
  26. <view
  27. class="flex flex-row justify-between items-center bg-surface-100 rounded-xl p-2 px-3 mt-3 h-[48px]"
  28. >
  29. <cl-text>{{ t("昵称") }}</cl-text>
  30. <cl-input
  31. v-model="editForm.nickName"
  32. type="nickname"
  33. :border="false"
  34. :placeholder="t('点击输入昵称')"
  35. :maxlength="16"
  36. :pt="{
  37. className: '!bg-transparent !px-0 flex-1',
  38. inner: {
  39. className: 'text-right'
  40. }
  41. }"
  42. ></cl-input>
  43. </view>
  44. <view class="flex flex-row mt-4">
  45. <cl-button size="large" text border type="light" fluid @tap="editClose">{{
  46. t("取消")
  47. }}</cl-button>
  48. <cl-button size="large" fluid :loading="editLoading" @tap="editSave">{{
  49. t("确认")
  50. }}</cl-button>
  51. </view>
  52. </view>
  53. </cl-popup>
  54. </template>
  55. <script setup lang="ts">
  56. import {
  57. parse,
  58. request,
  59. router,
  60. upload,
  61. userInfo,
  62. useStore,
  63. useWx,
  64. type Response,
  65. type Token,
  66. t
  67. } from "@/.cool";
  68. import { useUi } from "@/uni_modules/cool-ui";
  69. import { reactive, ref } from "vue";
  70. const emit = defineEmits(["success"]);
  71. const { user } = useStore();
  72. const ui = useUi();
  73. const wx = useWx();
  74. // 是否显示编辑
  75. const editVisible = ref(false);
  76. // 是否保存中
  77. const editLoading = ref(false);
  78. // 编辑表单
  79. type EditForm = {
  80. avatarUrl: string;
  81. nickName: string;
  82. };
  83. const editForm = reactive<EditForm>({
  84. avatarUrl: "",
  85. nickName: ""
  86. });
  87. // 编辑打开
  88. function editOpen() {
  89. editVisible.value = true;
  90. }
  91. // 编辑关闭
  92. function editClose() {
  93. editVisible.value = false;
  94. }
  95. // 编辑保存
  96. async function editSave() {
  97. // 校验头像是否已上传
  98. if (editForm.avatarUrl == "") {
  99. ui.showToast({
  100. message: t("请上传头像")
  101. });
  102. return;
  103. }
  104. // 校验昵称是否已填写
  105. if (editForm.nickName == "") {
  106. ui.showToast({
  107. message: t("请输入昵称")
  108. });
  109. return;
  110. }
  111. // 设置保存状态为加载中
  112. editLoading.value = true;
  113. // 上传头像并更新用户信息
  114. await upload(editForm.avatarUrl)
  115. .then((url) => {
  116. // 上传成功后,更新用户昵称和头像
  117. user.update({
  118. nickName: editForm.nickName,
  119. avatarUrl: url
  120. });
  121. // 关闭弹窗
  122. editClose();
  123. // 跳转首页
  124. router.nextLogin();
  125. })
  126. .catch((err) => {
  127. // 上传失败,提示错误信息
  128. ui.showToast({
  129. message: (err as Response).message!
  130. });
  131. });
  132. // 恢复保存状态
  133. editLoading.value = false;
  134. }
  135. // 编辑选择头像
  136. function onEditChooseAvatar(e: UniEvent) {
  137. // #ifdef MP-WEIXIN
  138. editForm.avatarUrl = e.detail.avatarUrl;
  139. // #endif
  140. }
  141. // 编辑关闭
  142. function onEditClose() {
  143. editVisible.value = false;
  144. }
  145. // 微信小程序登录
  146. async function miniLogin() {
  147. // #ifdef MP
  148. ui.showLoading(t("登录中"));
  149. await wx.miniLogin().then(async (data) => {
  150. await request({
  151. url: "/app/user/login/mini",
  152. method: "POST",
  153. data
  154. })
  155. .then(async (res) => {
  156. // 设置token
  157. user.setToken(parse<Token>(res)!);
  158. // 获取用户信息
  159. await user.get();
  160. // 是否首次注册,根据业务情况调整判断逻辑
  161. if (userInfo.value?.nickName == "微信用户") {
  162. // 打开编辑弹窗
  163. editOpen();
  164. } else {
  165. // 跳转首页
  166. router.nextLogin();
  167. }
  168. })
  169. .catch((err) => {
  170. ui.showToast({
  171. message: (err as Response).message!
  172. });
  173. });
  174. });
  175. ui.hideLoading();
  176. // #endif
  177. }
  178. // 微信APP登录
  179. function appLogin() {
  180. // 开发中
  181. }
  182. // 微信登录
  183. async function login() {
  184. // #ifdef MP
  185. miniLogin();
  186. // #endif
  187. // #ifdef APP
  188. appLogin();
  189. // #endif
  190. }
  191. defineExpose({
  192. login,
  193. editOpen,
  194. editClose
  195. });
  196. </script>