manage-member.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. <template>
  2. <main
  3. v-if="!isUniFrameWork"
  4. class="member"
  5. >
  6. <ul class="list">
  7. <li
  8. v-for="(item, index) in memberList"
  9. :key="index"
  10. class="list-item"
  11. >
  12. <aside
  13. class="aside"
  14. @click="handleMemberProfileShow(item)"
  15. >
  16. <img
  17. class="avatar"
  18. :src="
  19. item.avatar ||
  20. 'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'
  21. "
  22. onerror="this.onerror=null;this.src='https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"
  23. >
  24. <span class="name">{{ item.nick || item.userID }}</span>
  25. <span>{{ handleRoleName(item) }}</span>
  26. </aside>
  27. <div @click="submit(item)">
  28. <Icon
  29. v-if="item.role !== 'Owner' && isShowDeleteBtn"
  30. :file="delIcon"
  31. :width="'16px'"
  32. :height="'16px'"
  33. />
  34. </div>
  35. </li>
  36. <li
  37. v-if="memberList.length < totalMember"
  38. class="list-item"
  39. @click="getMore"
  40. >
  41. {{ TUITranslateService.t(`TUIGroup.查看更多`) }}
  42. </li>
  43. </ul>
  44. </main>
  45. <div
  46. v-else
  47. class="edit-h5"
  48. >
  49. <main class="main">
  50. <header class="edit-h5-header">
  51. <aside class="left">
  52. <h1>{{ TUITranslateService.t(`TUIGroup.群成员`) }}</h1>
  53. </aside>
  54. <span
  55. class="close"
  56. @click="close('member')"
  57. >{{
  58. TUITranslateService.t(`关闭`)
  59. }}</span>
  60. </header>
  61. <div class="member">
  62. <ul class="list list-uniapp">
  63. <li
  64. v-for="(item, index) in memberList"
  65. :key="index"
  66. class="list-item"
  67. >
  68. <aside
  69. class="aside"
  70. @click="handleMemberProfileShow(item)"
  71. >
  72. <img
  73. class="avatar"
  74. :src="
  75. item.avatar ||
  76. 'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'
  77. "
  78. onerror="this.onerror=null;this.src='https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"
  79. >
  80. <span class="name">{{ item.nick || item.userID }}</span>
  81. <span>{{ handleRoleName(item) }}</span>
  82. </aside>
  83. <div @click="submit(item)">
  84. <Icon
  85. v-if="item.role !== 'Owner' && isShowDeleteBtn"
  86. :file="delIcon"
  87. :width="'16px'"
  88. :height="'16px'"
  89. />
  90. </div>
  91. </li>
  92. <li
  93. v-if="memberList.length < totalMember"
  94. class="list-item"
  95. @click="getMore"
  96. >
  97. {{ TUITranslateService.t(`TUIGroup.查看更多`) }}
  98. </li>
  99. </ul>
  100. </div>
  101. </main>
  102. </div>
  103. </template>
  104. <script lang="ts" setup>
  105. import TUIChatEngine, {
  106. TUITranslateService,
  107. } from '@tencentcloud/chat-uikit-engine';
  108. import { watchEffect, ref } from '../../../adapter-vue';
  109. import Icon from '../../common/Icon.vue';
  110. import delIcon from '../../../assets/icon/del-icon.svg';
  111. import { IGroupSelfInfo, IGroupMember } from '../../../interface';
  112. import { isUniFrameWork } from '../../../utils/env';
  113. const props = defineProps({
  114. list: {
  115. type: Array,
  116. default: () => [],
  117. },
  118. total: {
  119. type: Number,
  120. default: () => 0,
  121. },
  122. isShowDel: {
  123. type: Boolean,
  124. default: () => false,
  125. },
  126. self: {
  127. type: Object,
  128. default: () => ({}),
  129. },
  130. });
  131. const totalMember = ref(0);
  132. const memberList = ref<Array<IGroupMember>>([]);
  133. const isShowDeleteBtn = ref(false);
  134. const selfValue = ref<IGroupSelfInfo>({});
  135. watchEffect(() => {
  136. totalMember.value = props.total;
  137. isShowDeleteBtn.value = props.isShowDel;
  138. memberList.value = props.list as Array<IGroupMember>;
  139. selfValue.value = props.self;
  140. });
  141. const emits = defineEmits(['more', 'del', 'handleMemberProfileShow', 'close']);
  142. const handleRoleName = (item: any) => {
  143. let name = '';
  144. switch (item?.role) {
  145. case TUIChatEngine.TYPES.GRP_MBR_ROLE_ADMIN:
  146. name = TUITranslateService.t('TUIGroup.管理员');
  147. break;
  148. case TUIChatEngine.TYPES.GRP_MBR_ROLE_OWNER:
  149. name = TUITranslateService.t('TUIGroup.群主');
  150. break;
  151. }
  152. if (name) {
  153. name = `(${name})`;
  154. }
  155. if (item.userID === selfValue.value.userID) {
  156. name += ` (${TUITranslateService.t('TUIGroup.我')})`;
  157. }
  158. return name;
  159. };
  160. const getMore = () => {
  161. emits('more');
  162. };
  163. const submit = (item: any) => {
  164. emits('del', [item]);
  165. };
  166. const handleMemberProfileShow = (user: any) => {
  167. emits('handleMemberProfileShow', user);
  168. };
  169. const close = (tabName: string) => {
  170. emits('close', tabName);
  171. };
  172. </script>
  173. <style lang="scss" scoped>
  174. @import "../../../assets/styles/common";
  175. .member {
  176. flex: 1;
  177. background: #fff;
  178. .list {
  179. display: flex;
  180. flex-direction: column;
  181. background: #f4f5f9;
  182. padding-top: 22px;
  183. &-uniapp {
  184. background: none;
  185. }
  186. &-item {
  187. padding: 13px;
  188. display: flex;
  189. justify-content: space-between;
  190. align-items: center;
  191. background: #fff;
  192. font-size: 14px;
  193. overflow: hidden;
  194. cursor: pointer;
  195. &:hover {
  196. background: #f1f2f6;
  197. }
  198. .aside {
  199. display: flex;
  200. align-items: center;
  201. width: 100%;
  202. overflow: hidden;
  203. .name {
  204. margin-left: 8px;
  205. font-weight: 400;
  206. font-size: 14px;
  207. color: #000;
  208. flex: 1;
  209. overflow: hidden;
  210. white-space: nowrap;
  211. text-overflow: ellipsis;
  212. }
  213. }
  214. }
  215. }
  216. }
  217. .avatar {
  218. width: 36px;
  219. height: 36px;
  220. border-radius: 4px;
  221. }
  222. .edit-h5 {
  223. position: fixed;
  224. width: 100%;
  225. height: 100%;
  226. top: 0;
  227. left: 0;
  228. background: rgba(0, 0, 0, 0.5);
  229. display: flex;
  230. align-items: flex-end;
  231. z-index: 1;
  232. .main {
  233. background: #fff;
  234. flex: 1;
  235. padding: 18px;
  236. border-radius: 12px 12px 0 0;
  237. overflow: scroll;
  238. height: 50%;
  239. width: 80vw;
  240. }
  241. &-header {
  242. display: flex;
  243. align-items: center;
  244. justify-content: space-between;
  245. .close {
  246. font-family: PingFangSC-Regular;
  247. font-weight: 400;
  248. font-size: 18px;
  249. color: #3370ff;
  250. letter-spacing: 0;
  251. line-height: 27px;
  252. }
  253. }
  254. &-footer {
  255. display: flex;
  256. .btn {
  257. flex: 1;
  258. border: none;
  259. background: #147aff;
  260. border-radius: 5px;
  261. font-family: PingFangSC-Regular;
  262. font-weight: 400;
  263. font-size: 16px;
  264. color: #fff;
  265. letter-spacing: 0;
  266. line-height: 27px;
  267. padding: 8px 0;
  268. &:disabled {
  269. opacity: 0.3;
  270. }
  271. }
  272. }
  273. }
  274. </style>