index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. <template>
  2. <div class="edit" :class="[isH5 ? 'edit-h5' : '']">
  3. <header class="edit-header">
  4. <i v-if="isH5" class="icon icon-back" @click="cancel"></i>
  5. <h1 class="edit-header-title">{{ $t("TUIProfile.资料设置") }}</h1>
  6. </header>
  7. <ul class="edit-list">
  8. <li class="edit-list-item space-top">
  9. <main class="edit-list-item-content" @click="setProfile('avatar')">
  10. <label>{{ $t("TUIProfile.头像") }}</label>
  11. <span v-if="isH5">
  12. <img :src="profile.avatar ? profile.avatar : 'https://oss.dayaedu.com/news-info/07/1690787574969.png'" onerror="this.src='https://oss.dayaedu.com/news-info/07/1690787574969.png'" />
  13. </span>
  14. <ul class="avatar-list" v-else>
  15. <li class="avatar-list-item" v-for="(item, index) in avatarList" :key="index" @click="chooseAvatar(item)">
  16. <img :class="[profile.avatar === item.avatar && 'selected']" :src="item.avatar" />
  17. </li>
  18. </ul>
  19. </main>
  20. <i v-if="isH5" class="icon icon-right"></i>
  21. </li>
  22. <li class="edit-list-item space-top">
  23. <main class="edit-list-item-content" @click="setProfile('nick')">
  24. <label>{{ $t("TUIProfile.昵称") }}</label>
  25. <span v-if="isH5">{{ profile.nick }}</span>
  26. <input v-else type="text" v-model="profile.nick" />
  27. </main>
  28. <i v-if="isH5" class="icon icon-right"></i>
  29. </li>
  30. <li class="edit-list-item">
  31. <main class="edit-list-item-content">
  32. <label>{{ $t("TUIProfile.账号") }}</label>
  33. <span>{{ profile.userID }}</span>
  34. </main>
  35. </li>
  36. <li class="edit-list-item space-top">
  37. <main class="edit-list-item-content" @click="setProfile('selfSignature')">
  38. <label>{{ $t("TUIProfile.个性签名") }}</label>
  39. <span v-if="isH5">{{ profile.selfSignature }}</span>
  40. <input v-else type="text" v-model="profile.selfSignature" />
  41. </main>
  42. <i v-if="isH5" class="icon icon-right"></i>
  43. </li>
  44. <li class="edit-list-item">
  45. <main class="edit-list-item-content" @click="setProfile('gender')">
  46. <label>{{ $t("TUIProfile.性别") }}</label>
  47. <span v-if="isH5">{{ profile.gender ? $t(`TUIProfile.${genderLabel[profile.gender]}`) : "" }}</span>
  48. <ul v-else class="gender-list">
  49. <li class="gender-list-item" v-for="(item, index) in type" :key="index" @click="showChooseGender(item)">
  50. <i class="gender" :class="[profile.gender === item.type && 'gender-selected']"></i>
  51. <p class="name">{{ $t(`TUIProfile.${item.label}`) }}</p>
  52. </li>
  53. </ul>
  54. </main>
  55. <i v-if="isH5" class="icon icon-right"></i>
  56. </li>
  57. <li class="edit-list-item">
  58. <main class="edit-list-item-content" @click="setProfile('birthday')">
  59. <label>{{ $t("TUIProfile.出生年月") }}</label>
  60. <span v-if="isH5">{{ profile.birthday }}</span>
  61. <Datepicker v-else :placeholder="$t(`TUIProfile.请选择出生日期`)" :enableTimePicker="false" :format="format" :previewFormat="format" :modelValue="birthday" @update:modelValue="showBirthday" />
  62. </main>
  63. <i v-if="isH5" class="icon icon-right"></i>
  64. </li>
  65. </ul>
  66. <footer class="edit-footer" v-if="!isH5">
  67. <button class="btn-default" @click="cancel">{{ $t("TUIProfile.取消") }}</button>
  68. <button class="btn-submit" @click="submit">{{ $t("TUIProfile.保存") }}</button>
  69. </footer>
  70. <div class="mask" v-if="setName && isH5" @click.self="closeMask">
  71. <div class="mask-main">
  72. <header class="edit-h5-header">
  73. <h1>{{ $t(`TUIProfile.${editConfig.title}`) }}</h1>
  74. <span class="close" @click="closeMask">{{ $t(`关闭`) }}</span>
  75. </header>
  76. <main class="edit-h5-main">
  77. <ul class="list" v-if="editConfig.type === 'select'">
  78. <li class="list-item" v-for="(item, index) in editConfig.list" :key="index" @click="choose(item)">
  79. <img v-if="item?.avatar" :class="[editConfig.value === item.avatar && 'selected']" :src="item.avatar" />
  80. <span v-else :class="[editConfig.value === item.type && 'selected']">{{ $t(`TUIProfile.${item.label}`) }}</span>
  81. </li>
  82. </ul>
  83. <div class="input" v-else>
  84. <textarea v-if="editConfig.type === 'textarea'" :placeholder="editConfig.placeholder" v-model="editConfig.value"></textarea>
  85. <Datepicker class="datePicker" :placeholder="$t(`TUIProfile.请选择出生日期`)" v-else-if="editConfig.type === 'date'" :enableTimePicker="false" :format="format" :previewFormat="format" :modelValue="birthday" @update:modelValue="showBirthday" />
  86. <input v-else :type="editConfig.type" :placeholder="$t(`TUIProfile.${editConfig.placeholder}`)" v-model="editConfig.value" />
  87. </div>
  88. <sub v-if="editConfig.subText">{{ $t(`TUIProfile.${editConfig.subText}`) }}</sub>
  89. </main>
  90. <footer class="edit-h5-footer">
  91. <button class="btn btn-submit" :disabled="!editConfig.value" @click="submit">{{ $t(`确定`) }}</button>
  92. </footer>
  93. </div>
  94. </div>
  95. </div>
  96. </template>
  97. <script lang="ts">
  98. import { computed, defineComponent, reactive, toRefs, watchEffect } from "vue";
  99. import Datepicker from "@vuepic/vue-datepicker";
  100. import "@vuepic/vue-datepicker/dist/main.css";
  101. const TUIProfileEdit: any = defineComponent({
  102. props: {
  103. userInfo: {
  104. type: Object,
  105. default: () => ({}),
  106. },
  107. isH5: {
  108. type: Boolean,
  109. default: () => false,
  110. },
  111. },
  112. components: { Datepicker },
  113. setup(props: any, ctx: any) {
  114. const TUIServer: any = TUIProfileEdit?.TUIServer;
  115. const data = reactive({
  116. profile: {},
  117. isEdit: false,
  118. avatarList: [
  119. {
  120. name: "avatar_01",
  121. avatar: " https://im.sdk.qcloud.com/download/tuikit-resource/avatar/avatar_1.png",
  122. },
  123. {
  124. name: "avatar_02",
  125. avatar: " https://im.sdk.qcloud.com/download/tuikit-resource/avatar/avatar_2.png",
  126. },
  127. {
  128. name: "avatar_03",
  129. avatar: " https://im.sdk.qcloud.com/download/tuikit-resource/avatar/avatar_3.png",
  130. },
  131. {
  132. name: "avatar_04",
  133. avatar: " https://im.sdk.qcloud.com/download/tuikit-resource/avatar/avatar_4.png",
  134. },
  135. {
  136. name: "avatar_05",
  137. avatar: " https://im.sdk.qcloud.com/download/tuikit-resource/avatar/avatar_5.png",
  138. },
  139. {
  140. name: "avatar_06",
  141. avatar: " https://im.sdk.qcloud.com/download/tuikit-resource/avatar/avatar_6.png",
  142. },
  143. ],
  144. type: [
  145. {
  146. label: "男",
  147. type: TUIServer.TUICore.TIM.TYPES.GENDER_MALE,
  148. },
  149. {
  150. label: "女",
  151. type: TUIServer.TUICore.TIM.TYPES.GENDER_FEMALE,
  152. },
  153. ],
  154. genderLabel: {
  155. [TUIServer.TUICore.TIM.TYPES.GENDER_MALE]: "男",
  156. [TUIServer.TUICore.TIM.TYPES.GENDER_FEMALE]: "女",
  157. [TUIServer.TUICore.TIM.TYPES.GENDER_UNKNOWN]: "不显示",
  158. },
  159. setName: "",
  160. editConfig: {
  161. title: "",
  162. list: [],
  163. type: "", // select、text、textarea、date
  164. subText: "",
  165. placeholder: "",
  166. value: "",
  167. },
  168. });
  169. const format = (date: any) => {
  170. const day = date.getDate() > 9 ? date.getDate() : `0${date.getDate()}`;
  171. const month = date.getMonth() > 8 ? date.getMonth() + 1 : `0${date.getMonth() + 1}`;
  172. const year = date.getFullYear();
  173. return `${year}${month}${day}`;
  174. };
  175. watchEffect(() => {
  176. data.profile = JSON.parse(JSON.stringify(props.userInfo));
  177. });
  178. const birthday = computed(() => {
  179. let value = (data.profile as any).birthday;
  180. if (data.setName === "birthday" && props.isH5) {
  181. value = data.editConfig.value;
  182. }
  183. return handleBirthdayFamate(value);
  184. });
  185. const handleBirthdayFamate = (value: any) => {
  186. const birthday: any = `${value}`;
  187. if (birthday.length === 8) {
  188. const y = birthday.slice(0, 4);
  189. const m = birthday.slice(4, 6);
  190. const d = birthday.slice(-2);
  191. return `${y}-${m}-${d}`;
  192. }
  193. return "";
  194. };
  195. const showChooseGender = (options: any) => {
  196. (data.profile as any).gender = options.type;
  197. };
  198. const chooseAvatar = (item: any) => {
  199. (data.profile as any).avatar = item.avatar;
  200. };
  201. const showBirthday = (e: any) => {
  202. if (!props.isH5) {
  203. (data.profile as any).birthday = e ? Number(format(e)) : 0;
  204. } else {
  205. (data.editConfig.value as unknown) = e ? Number(format(e)) : 0;
  206. }
  207. };
  208. const submit = () => {
  209. if (props.isH5) {
  210. (data.profile as any)[data.setName] = data.editConfig.value;
  211. closeMask();
  212. }
  213. ctx.emit("submit", data.profile);
  214. };
  215. const cancel = () => {
  216. ctx.emit("cancel", data.profile);
  217. };
  218. const setProfile = (name: string) => {
  219. data.editConfig.value = `${(data.profile as any)[name]}`;
  220. data.setName = name;
  221. switch (name) {
  222. case "avatar":
  223. data.editConfig.title = "选择头像";
  224. (data.editConfig.list as unknown) = data.avatarList;
  225. data.editConfig.type = "select";
  226. break;
  227. case "nick":
  228. data.editConfig.title = "设置昵称";
  229. data.editConfig.subText = "仅限中文、字母、数字和下划线,2-20个字";
  230. data.editConfig.placeholder = "请输入昵称";
  231. data.editConfig.type = "text";
  232. break;
  233. case "gender":
  234. data.editConfig.title = "性别选择";
  235. (data.editConfig.list as unknown) = data.type;
  236. data.editConfig.type = "select";
  237. break;
  238. case "selfSignature":
  239. data.editConfig.title = "个性签名";
  240. data.editConfig.type = "textarea";
  241. data.editConfig.placeholder = "请输入内容";
  242. break;
  243. case "birthday":
  244. data.editConfig.title = "出生年月";
  245. data.editConfig.type = "date";
  246. data.editConfig.placeholder = "请选择出生日期";
  247. break;
  248. default:
  249. break;
  250. }
  251. };
  252. const choose = (item: any) => {
  253. data.editConfig.value = item?.avatar || item?.type;
  254. };
  255. const closeMask = () => {
  256. data.setName = "";
  257. data.editConfig = {
  258. title: "",
  259. list: [],
  260. type: "",
  261. subText: "",
  262. placeholder: "",
  263. value: "",
  264. };
  265. };
  266. return {
  267. ...toRefs(data),
  268. showChooseGender,
  269. chooseAvatar,
  270. showBirthday,
  271. birthday,
  272. submit,
  273. cancel,
  274. setProfile,
  275. choose,
  276. closeMask,
  277. format,
  278. };
  279. },
  280. });
  281. export default TUIProfileEdit;
  282. </script>
  283. <style lang="scss" scoped src="./style/index.scss"></style>