wx.uvue 4.4 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" :pt="{ className: '!text-sm' }">
  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-[95rpx]"
  15. >
  16. <cl-text>{{ t("头像") }}</cl-text>
  17. <view class="relative">
  18. <cl-avatar :size="60" :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-[95rpx]"
  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
  46. size="large"
  47. text
  48. border
  49. type="light"
  50. :pt="{
  51. className: 'flex-1 !rounded-xl h-[80rpx]'
  52. }"
  53. @tap="editClose"
  54. >{{ t("取消") }}</cl-button
  55. >
  56. <cl-button
  57. size="large"
  58. :pt="{
  59. className: 'flex-1 !rounded-xl h-[80rpx]'
  60. }"
  61. :loading="editLoading"
  62. @tap="editSave"
  63. >{{ t("确认") }}</cl-button
  64. >
  65. </view>
  66. </view>
  67. </cl-popup>
  68. </template>
  69. <script setup lang="ts">
  70. import { parse, router, service, upload, useStore, useWx, type Response, type Token } from "@/cool";
  71. import { t } from "@/locale";
  72. import { useUi } from "@/uni_modules/cool-ui";
  73. import { reactive, ref } from "vue";
  74. const emit = defineEmits(["success"]);
  75. const { user } = useStore();
  76. const ui = useUi();
  77. const wx = useWx();
  78. // 是否显示编辑
  79. const editVisible = ref(false);
  80. // 是否保存中
  81. const editLoading = ref(false);
  82. // 编辑表单
  83. type EditForm = {
  84. avatarUrl: string;
  85. nickName: string;
  86. };
  87. const editForm = reactive<EditForm>({
  88. avatarUrl: "",
  89. nickName: ""
  90. });
  91. // 编辑打开
  92. function editOpen() {
  93. editVisible.value = true;
  94. }
  95. // 编辑关闭
  96. function editClose() {
  97. editVisible.value = false;
  98. }
  99. // 编辑保存
  100. async function editSave() {
  101. // 校验头像是否已上传
  102. if (editForm.avatarUrl == "") {
  103. ui.showToast({
  104. message: t("请上传头像")
  105. });
  106. return;
  107. }
  108. // 校验昵称是否已填写
  109. if (editForm.nickName == "") {
  110. ui.showToast({
  111. message: t("请输入昵称")
  112. });
  113. return;
  114. }
  115. // 设置保存状态为加载中
  116. editLoading.value = true;
  117. // 上传头像并更新用户信息
  118. await upload(editForm.avatarUrl)
  119. .then((url) => {
  120. // 上传成功后,更新用户昵称和头像
  121. user.update({
  122. nickName: editForm.nickName,
  123. avatarUrl: url
  124. });
  125. // 关闭弹窗
  126. editClose();
  127. // 跳转首页
  128. router.nextLogin();
  129. })
  130. .catch((err) => {
  131. // 上传失败,提示错误信息
  132. ui.showToast({
  133. message: (err as Response).message!
  134. });
  135. });
  136. // 恢复保存状态
  137. editLoading.value = false;
  138. }
  139. // 编辑选择头像
  140. function onEditChooseAvatar(e: UniEvent) {
  141. // #ifdef MP-WEIXIN
  142. editForm.avatarUrl = e.detail.avatarUrl;
  143. // #endif
  144. }
  145. // 编辑关闭
  146. function onEditClose() {
  147. editVisible.value = false;
  148. }
  149. // 微信小程序登录
  150. async function miniLogin() {
  151. // #ifdef MP
  152. ui.showLoading(t("登录中"));
  153. await wx.miniLogin().then(async (data) => {
  154. await service.user.login
  155. .mini(data)
  156. .then(async (res) => {
  157. // 设置token
  158. user.setToken(parse<Token>(res)!);
  159. // 获取用户信息
  160. await user.get();
  161. // 是否首次注册,根据业务情况调整判断逻辑
  162. if (user.info.nickName == "微信用户") {
  163. // 打开编辑弹窗
  164. editOpen();
  165. } else {
  166. // 跳转首页
  167. router.nextLogin();
  168. }
  169. })
  170. .catch((err) => {
  171. ui.showToast({
  172. message: (err as Response).message!
  173. });
  174. });
  175. });
  176. ui.hideLoading();
  177. // #endif
  178. }
  179. // 微信APP登录
  180. function appLogin() {}
  181. // 微信登录
  182. async function login() {
  183. // #ifdef MP
  184. miniLogin();
  185. // #endif
  186. // #ifdef APP
  187. appLogin();
  188. // #endif
  189. }
  190. defineExpose({
  191. login,
  192. editOpen,
  193. editClose
  194. });
  195. </script>