edit.uvue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <template>
  2. <cl-page>
  3. <view class="p-3">
  4. <view class="flex flex-col justify-center items-center py-10 mb-3">
  5. <view class="relative overflow-visible">
  6. <!-- #ifdef MP-WEIXIN -->
  7. <button
  8. class="absolute top-0 left-0 w-full h-full opacity-0 z-10"
  9. open-type="chooseAvatar"
  10. @chooseavatar="uploadAvatar"
  11. ></button>
  12. <!-- #endif -->
  13. <cl-avatar
  14. :src="userInfo?.avatarUrl"
  15. :size="80"
  16. :pt="{ className: '!rounded-3xl', icon: { size: 32 } }"
  17. @tap="uploadAvatar"
  18. >
  19. </cl-avatar>
  20. <view
  21. class="flex flex-col justify-center items-center absolute bottom-0 right-[-3px] bg-black rounded-full p-1 border border-solid border-white"
  22. >
  23. <cl-icon name="edit-line" color="white" :size="10"></cl-icon>
  24. </view>
  25. </view>
  26. </view>
  27. <cl-list :pt="{ className: 'mb-3' }">
  28. <cl-list-item
  29. :label="t('我的昵称')"
  30. hoverable
  31. arrow
  32. justify="start"
  33. @tap="router.to('/pages/user/edit-name')"
  34. >
  35. <cl-text>{{ userInfo?.nickName }}</cl-text>
  36. </cl-list-item>
  37. <cl-list-item label="手机号" hoverable justify="start">
  38. <cl-text>{{ userInfo?.phone }}</cl-text>
  39. </cl-list-item>
  40. </cl-list>
  41. <cl-list :pt="{ className: 'mb-3' }">
  42. <cl-list-item
  43. :label="t('简介')"
  44. hoverable
  45. arrow
  46. justify="start"
  47. @tap="router.to('/pages/user/edit-description')"
  48. >
  49. <cl-text color="info" v-if="userInfo?.description == null">{{
  50. t("介绍一下自己")
  51. }}</cl-text>
  52. <cl-text ellipsis v-else>{{ userInfo?.description }}</cl-text>
  53. </cl-list-item>
  54. </cl-list>
  55. <cl-list :pt="{ className: 'mb-3' }">
  56. <cl-list-item
  57. :label="t('性别')"
  58. hoverable
  59. arrow
  60. justify="start"
  61. @tap="open('gender')"
  62. >
  63. <cl-text>{{ genderText }}</cl-text>
  64. <cl-text color="info" v-if="genderText == ''">{{ t("编辑性别") }}</cl-text>
  65. </cl-list-item>
  66. <cl-list-item
  67. :label="t('生日')"
  68. hoverable
  69. arrow
  70. justify="start"
  71. @tap="open('birthday')"
  72. >
  73. <cl-text>{{ userInfo?.birthday }}</cl-text>
  74. <cl-text color="info" v-if="userInfo?.birthday == null">{{
  75. t("选择生日")
  76. }}</cl-text>
  77. </cl-list-item>
  78. <cl-list-item
  79. :label="t('地区')"
  80. hoverable
  81. arrow
  82. justify="start"
  83. @tap="open('region')"
  84. >
  85. <cl-text>{{ regionText }}</cl-text>
  86. <cl-text color="info" v-if="regionText == ''">{{
  87. t("选择所在的地区")
  88. }}</cl-text>
  89. </cl-list-item>
  90. </cl-list>
  91. <cl-select
  92. :title="t('选择性别')"
  93. :model-value="userInfo?.gender"
  94. :ref="refs.set('gender')"
  95. :options="genderOptions"
  96. :show-trigger="false"
  97. @change="onGenderChange"
  98. ></cl-select>
  99. <cl-select-date
  100. :title="t('选择生日')"
  101. :model-value="userInfo?.birthday"
  102. :ref="refs.set('birthday')"
  103. type="date"
  104. :end="today"
  105. :show-trigger="false"
  106. @change="onBirthdayChange"
  107. ></cl-select-date>
  108. <cl-cascader
  109. :title="t('选择所在的地区')"
  110. :ref="refs.set('region')"
  111. :options="regionOptions"
  112. :show-trigger="false"
  113. @change="onRegionChange"
  114. ></cl-cascader>
  115. </view>
  116. </cl-page>
  117. </template>
  118. <script setup lang="ts">
  119. import { dayUts, router, upload, useRefs, useStore, type Response, userInfo, t } from "@/.cool";
  120. import { useCascader, useUi, type ClSelectOption } from "@/uni_modules/cool-ui";
  121. import { computed, ref } from "vue";
  122. import pca from "@/.cool/data/pca.json";
  123. const { user } = useStore();
  124. const ui = useUi();
  125. const refs = useRefs();
  126. // 今天
  127. const today = dayUts().format("YYYY-MM-DD");
  128. // 性别选项
  129. const genderOptions = ref<ClSelectOption[]>([
  130. {
  131. label: t("保密"),
  132. value: 0
  133. },
  134. {
  135. label: t("男"),
  136. value: 1
  137. },
  138. {
  139. label: t("女"),
  140. value: 2
  141. }
  142. ]);
  143. // 性别文本
  144. const genderText = computed(() => {
  145. return [t("保密"), t("男"), t("女")][userInfo.value?.gender!];
  146. });
  147. // 性别改变
  148. function onGenderChange(val: number) {
  149. user.update({
  150. gender: val
  151. });
  152. ui.showToast({
  153. message: t("性别设置成功")
  154. });
  155. }
  156. // 生日改变
  157. function onBirthdayChange(val: string) {
  158. user.update({
  159. birthday: val
  160. });
  161. ui.showToast({
  162. message: t("生日设置成功")
  163. });
  164. }
  165. // 地区选项
  166. const regionOptions = useCascader(pca);
  167. // 地区文本
  168. const regionText = computed(() => {
  169. return [userInfo.value?.province, userInfo.value?.city, userInfo.value?.district]
  170. .filter((e) => e != null)
  171. .join(" - ");
  172. });
  173. // 地区改变
  174. function onRegionChange(arr: string[]) {
  175. user.update({
  176. province: arr[0],
  177. city: arr[1],
  178. district: arr[2]
  179. });
  180. ui.showToast({
  181. message: t("地区设置成功")
  182. });
  183. }
  184. // 打开弹窗
  185. function open(name: string) {
  186. refs.open(name);
  187. }
  188. // 上传头像
  189. function uploadAvatar(e: UniEvent) {
  190. function next(path: string) {
  191. upload(path)
  192. .then((url) => {
  193. ui.showToast({
  194. message: t("头像上传成功")
  195. });
  196. user.update({
  197. avatarUrl: url
  198. });
  199. })
  200. .catch((err) => {
  201. ui.showToast({
  202. message: (err as Response).message!
  203. });
  204. });
  205. }
  206. // #ifdef MP-WEIXIN
  207. next(e.detail.avatarUrl);
  208. // #endif
  209. // #ifndef MP-WEIXIN
  210. uni.chooseImage({
  211. count: 1,
  212. success(res) {
  213. next(res.tempFiles[0].path);
  214. }
  215. });
  216. // #endif
  217. }
  218. </script>