profile.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. <template>
  2. <div :class="['TUI-profile', !isPC && 'TUI-profile-h5']">
  3. <div
  4. v-if="displayType !== 'setting'"
  5. :class="['TUI-profile-basic', !isPC && 'TUI-profile-h5-basic']"
  6. >
  7. <img
  8. :class="['TUI-profile-basic-avatar', !isPC && 'TUI-profile-h5-basic-avatar']"
  9. :src="
  10. userProfile.avatar ||
  11. 'https://bucket.sxdirectpurchase.com/wx/static/img/ImAvatar.png'
  12. "
  13. />
  14. <div :class="['TUI-profile-basic-info', !isPC && 'TUI-profile-h5-basic-info']">
  15. <div
  16. :class="[
  17. 'TUI-profile-basic-info-nick',
  18. !isPC && 'TUI-profile-h5-basic-info-nick',
  19. ]"
  20. >
  21. {{ userProfile.nick || "-" }}
  22. </div>
  23. <div
  24. :class="['TUI-profile-basic-info-id', !isPC && 'TUI-profile-h5-basic-info-id']"
  25. >
  26. <label
  27. :class="[
  28. 'TUI-profile-basic-info-id-label',
  29. !isPC && 'TUI-profile-h5-basic-info-id-label',
  30. ]"
  31. >{{ "用户ID" }}:</label
  32. >
  33. <div
  34. :class="[
  35. 'TUI-profile-basic-info-id-value',
  36. !isPC && 'TUI-profile-h5-basic-info-id-value',
  37. ]"
  38. >
  39. {{ userProfile.userID }}
  40. </div>
  41. </div>
  42. </div>
  43. </div>
  44. <div
  45. v-if="displayType !== 'profile' && (!isPC || showSetting)"
  46. ref="settingDomRef"
  47. :class="['TUI-profile-setting', !isPC && 'TUI-profile-h5-setting']"
  48. >
  49. <div
  50. v-for="(item, key) in settingList"
  51. :key="key"
  52. :class="[
  53. 'TUI-profile-setting-item',
  54. !isPC && 'TUI-profile-h5-setting-item',
  55. item.value === 'exit' && 'TUI-profile-h5-setting-item-exit',
  56. ]"
  57. >
  58. <div
  59. :class="[
  60. 'TUI-profile-setting-item-label',
  61. !isPC && 'TUI-profile-h5-setting-item-label',
  62. ]"
  63. @click="handleSettingListItemOnClick(item)"
  64. >
  65. <div :class="['label-left']">
  66. <div :class="['label-title']">
  67. {{ item.label }}
  68. </div>
  69. <div
  70. v-if="item.children && !isPC && item.childrenShowType === 'switch'"
  71. :class="['label-desc']"
  72. >
  73. {{ item.value }}
  74. </div>
  75. </div>
  76. <div :class="['label-right']">
  77. <div
  78. v-if="
  79. !isPC &&
  80. item.children &&
  81. item.selectedChild &&
  82. item.childrenShowType === 'bottomPopup'
  83. "
  84. :class="[
  85. 'TUI-profile-setting-item-label-value',
  86. !isPC && 'TUI-profile-h5-setting-item-label-value',
  87. ]"
  88. >
  89. {{ generateLabel(item) }}
  90. </div>
  91. <Icon
  92. v-if="item.children"
  93. :file="rightArrowIcon"
  94. width="14px"
  95. height="14px"
  96. style="width: 14px; height: 14px; display: flex"
  97. />
  98. </div>
  99. </div>
  100. <!-- 移动端 children显示,分多个类型 -->
  101. <BottomPopup
  102. v-if="item.children && !isPC && item.childrenShowType === 'bottomPopup'"
  103. :show="item.showChildren"
  104. @onClose="bottomPopupOnClose(item)"
  105. >
  106. <div
  107. v-for="child in item.children"
  108. :class="[
  109. 'TUI-profile-setting-item-bottom-popup',
  110. !isPC && 'TUI-profile-h5-setting-item-bottom-popup',
  111. ]"
  112. @click="handleSettingListItemOnClick(child)"
  113. >
  114. {{ child.label }}
  115. </div>
  116. </BottomPopup>
  117. </div>
  118. </div>
  119. </div>
  120. </template>
  121. <script lang="ts" setup>
  122. import TUIChatEngine, {
  123. TUIUserService,
  124. TUIStore,
  125. StoreName,
  126. TUIChatService,
  127. } from "@tencentcloud/chat-uikit-engine";
  128. import { TUILogin } from "@tencentcloud/tui-core";
  129. import { TUIGlobal } from "@tencentcloud/universal-api";
  130. import { ref, defineProps, onMounted } from "../../TUIKit/adapter-vue";
  131. import { isPC } from "../../TUIKit/utils/env";
  132. import { Toast, TOAST_TYPE } from "../../TUIKit/components/common/Toast/index";
  133. import BottomPopup from "../../TUIKit/components/common/BottomPopup/index.vue";
  134. import Icon from "../../TUIKit/components/common/Icon.vue";
  135. import rightArrowIcon from "../../TUIKit/assets/icon/right-icon.svg";
  136. import { IUserProfile } from "../../TUIKit/interface";
  137. import { onHide } from "@dcloudio/uni-app";
  138. import { translator } from "../../TUIKit/components/TUIChat/utils/translation";
  139. import { removeTokenStorage } from "../../utils/token";
  140. const props = defineProps({
  141. displayType: {
  142. type: String,
  143. default: "all", // "profile"/"setting"/"all"
  144. },
  145. showSetting: {
  146. type: Boolean,
  147. default: false,
  148. },
  149. });
  150. const settingDomRef = ref();
  151. const userProfile = ref<IUserProfile>({});
  152. const settingList = ref<{
  153. [propsName: string]: {
  154. value: string;
  155. label: string;
  156. onClick?: any;
  157. // children相关
  158. selectedChild?: string;
  159. childrenShowType?: string; // "bottomPopup"/"switch"
  160. showChildren?: boolean;
  161. children?: {
  162. [propsName: string]: {
  163. value: string;
  164. label: string;
  165. onClick?: any;
  166. };
  167. };
  168. };
  169. }>({
  170. editProfile: {
  171. value: "editProfile",
  172. label: "编辑资料(暂未开放)",
  173. onClick: (item: any) => {
  174. console.warn("编辑资料功能努力开发中,敬请期待");
  175. },
  176. },
  177. allowType: {
  178. value: "allowType",
  179. label: "加我为好友时",
  180. selectedChild: "",
  181. childrenShowType: "bottomPopup",
  182. showChildren: false,
  183. onClick: (item: any) => {
  184. if (!isPC) {
  185. item.showChildren = true;
  186. }
  187. },
  188. children: {
  189. [TUIChatEngine.TYPES.ALLOW_TYPE_ALLOW_ANY]: {
  190. value: TUIChatEngine.TYPES.ALLOW_TYPE_ALLOW_ANY,
  191. label: "同意任何用户加好友",
  192. onClick: (item: any) => {
  193. updateMyProfile({ allowType: item.value });
  194. },
  195. },
  196. [TUIChatEngine.TYPES.ALLOW_TYPE_NEED_CONFIRM]: {
  197. value: TUIChatEngine.TYPES.ALLOW_TYPE_NEED_CONFIRM,
  198. label: "需要验证",
  199. onClick: (item: any) => {
  200. updateMyProfile({ allowType: item.value });
  201. },
  202. },
  203. [TUIChatEngine.TYPES.ALLOW_TYPE_DENY_ANY]: {
  204. value: TUIChatEngine.TYPES.ALLOW_TYPE_DENY_ANY,
  205. label: "拒绝任何人加好友",
  206. onClick: (item: any) => {
  207. updateMyProfile({ allowType: item.value });
  208. },
  209. },
  210. },
  211. },
  212. displayMessageReadReceipt: {
  213. value: "displayMessageReadReceipt",
  214. label: "消息阅读状态",
  215. selectedChild: "userLevelReadReceiptOpen",
  216. childrenShowType: "bottomPopup",
  217. showChildren: false,
  218. onClick(item: any) {
  219. if (!isPC) {
  220. item.showChildren = true;
  221. }
  222. },
  223. children: {
  224. userLevelReadReceiptOpen: {
  225. value: "userLevelReadReceiptOpen",
  226. label: "开启",
  227. onClick() {
  228. switchEnabelUserLevelReadRecript(true);
  229. },
  230. },
  231. userLevelReadReceiptClose: {
  232. value: "userLevelReadReceiptClose",
  233. label: "关闭",
  234. onClick() {
  235. switchEnabelUserLevelReadRecript(false);
  236. },
  237. },
  238. },
  239. },
  240. displayOnlineStatus: {
  241. value: "displayOnlineStatus",
  242. label: "显示在线状态",
  243. selectedChild: "userLevelOnlineStatusOpen",
  244. childrenShowType: "bottomPopup",
  245. showChildren: false,
  246. onClick(item: any) {
  247. if (!isPC) {
  248. item.showChildren = true;
  249. }
  250. },
  251. children: {
  252. userLevelOnlineStatusOpen: {
  253. value: "userLevelOnlineStatusOpen",
  254. label: "开启",
  255. onClick() {
  256. switchUserLevelOnlineStatus(true);
  257. },
  258. },
  259. userLevelOnlineStatusClose: {
  260. value: "userLevelOnlineStatusClose",
  261. label: "关闭",
  262. onClick() {
  263. switchUserLevelOnlineStatus(false);
  264. },
  265. },
  266. },
  267. },
  268. translateLanguage: {
  269. value: "translateLanguage",
  270. label: "翻译语言",
  271. selectedChild: "zh",
  272. childrenShowType: "bottomPopup",
  273. showChildren: false,
  274. onClick(item: any) {
  275. if (!isPC) {
  276. item.showChildren = true;
  277. }
  278. },
  279. children: {
  280. zh: {
  281. value: "zh",
  282. label: "中文",
  283. onClick() {
  284. switchTranslationTargetLanguage("zh");
  285. },
  286. },
  287. en: {
  288. value: "en",
  289. label: "English",
  290. onClick() {
  291. switchTranslationTargetLanguage("en");
  292. },
  293. },
  294. jp: {
  295. value: "jp",
  296. label: "日本語",
  297. onClick() {
  298. switchTranslationTargetLanguage("jp");
  299. },
  300. },
  301. kr: {
  302. value: "kr",
  303. label: "한국인",
  304. onClick() {
  305. switchTranslationTargetLanguage("kr");
  306. },
  307. },
  308. },
  309. },
  310. exit: {
  311. value: "exit",
  312. label: "退出登录",
  313. onClick: (item: any) => {
  314. TUILogin.logout().then(() => {
  315. uni.removeStorage({
  316. key: "userInfo",
  317. });
  318. removeTokenStorage();
  319. TUIGlobal?.reLaunch({
  320. url: "/pages/views/login",
  321. });
  322. });
  323. },
  324. },
  325. });
  326. const handleSettingListItemOnClick = (item: any) => {
  327. if (item?.onClick && typeof item?.onClick === "function") {
  328. item.onClick(item);
  329. }
  330. };
  331. const bottomPopupOnClose = (item: any) => {
  332. item.showChildren = false;
  333. };
  334. const generateLabel = (item: any) => {
  335. return item?.children[item?.selectedChild]?.label;
  336. };
  337. const updateMyProfile = (props: object) => {
  338. TUIUserService.updateMyProfile(props)
  339. .then((res: any) => {
  340. Toast({
  341. message: "更新用户资料成功",
  342. type: TOAST_TYPE.SUCCESS,
  343. duration: 0,
  344. });
  345. if ("allowType" in props) {
  346. settingList.value["allowType"].showChildren = false;
  347. }
  348. })
  349. .catch((err: any) => {
  350. console.warn("更新用户资料失败", err);
  351. Toast({
  352. message: "更新用户资料失败",
  353. type: TOAST_TYPE.ERROR,
  354. duration: 0,
  355. });
  356. });
  357. };
  358. TUIStore.watch(StoreName.USER, {
  359. userProfile: (userProfileData: IUserProfile) => {
  360. userProfile.value = userProfileData;
  361. if (userProfile?.value?.allowType) {
  362. settingList.value.allowType.selectedChild = userProfile?.value?.allowType;
  363. }
  364. },
  365. displayMessageReadReceipt(isDisplay: boolean) {
  366. settingList.value.displayMessageReadReceipt.selectedChild = isDisplay
  367. ? "userLevelReadReceiptOpen"
  368. : "userLevelReadReceiptClose";
  369. },
  370. displayOnlineStatus(isOnlineStatusDisplay: boolean) {
  371. settingList.value.displayOnlineStatus.selectedChild = isOnlineStatusDisplay
  372. ? "userLevelOnlineStatusOpen"
  373. : "userLevelOnlineStatusClose";
  374. },
  375. });
  376. // 规避TUIStore.watch userProfile 登录后暂时不能及时触发更新
  377. onMounted(() => {
  378. // 查询自己的资料
  379. TUIUserService.getUserProfile().then((res: any) => {
  380. userProfile.value = res.data;
  381. });
  382. });
  383. // tabbar 切换其他tab,关闭profile已经打开的设置弹窗
  384. onHide(() => {
  385. for (const settingItemKey in settingList.value) {
  386. if (settingList?.value[settingItemKey]?.hasOwnProperty("showChildren")) {
  387. settingList.value[settingItemKey].showChildren = false;
  388. }
  389. }
  390. });
  391. function switchEnabelUserLevelReadRecript(status: boolean) {
  392. TUIStore.update(StoreName.USER, "displayMessageReadReceipt", status);
  393. settingList.value["displayMessageReadReceipt"].showChildren = false;
  394. }
  395. function switchUserLevelOnlineStatus(status: boolean) {
  396. TUIUserService.switchUserStatus({ displayOnlineStatus: status });
  397. settingList.value["displayOnlineStatus"].showChildren = false;
  398. }
  399. function switchTranslationTargetLanguage(lang: string) {
  400. translator.clear();
  401. TUIChatService.setTranslationLanguage(lang);
  402. settingList.value.translateLanguage.selectedChild = lang;
  403. settingList.value.translateLanguage.showChildren = false;
  404. }
  405. </script>
  406. <style lang="scss" scoped src="../../styles/profile/index.scss"></style>