manage.vue 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017
  1. <template>
  2. <div>
  3. <i class="icon icon-chat-setting" @click="toggleShow"></i>
  4. <div class="manage" :class="[isH5 ? 'manage-h5' : '']" v-if="show" ref="dialog">
  5. <header :class="['manage-header', currentTab === 'onlyMute' ? 'currentModel' : '']">
  6. <i class="icon icon-back" v-if="isH5 && !currentTab" @click="toggleShow"></i>
  7. <aside class="manage-header-left">
  8. <i class="icon icon-back" v-if="currentTab" @click="() =>{
  9. currentModel = 'not_mute'
  10. setTab('')
  11. }"></i>
  12. <main v-if="currentTab !== 'onlyMute'">
  13. <h1>{{ $t(`TUIChat.manage.${TabName}`) }}</h1>
  14. </main>
  15. <n-tabs
  16. v-else
  17. justify-content="center"
  18. style="margin-left: -14Px;flex: 1; --n-tab-padding: 6px 0; --n-tab-gap: 34px; --n-tab-text-color: #000; --n-tab-text-color-hover: #0f0f0f; --n-tab-text-color-active: #000; --n-tab-font-weight-active: 600; --n-bar-color: #198cfe"
  19. :bar-width="20"
  20. :value="currentModel"
  21. @update:value="
  22. (val: any) => {
  23. currentModel = val;
  24. mutePage = 1
  25. muteSearch = ''
  26. getUserList()
  27. }
  28. "
  29. >
  30. <n-tab-pane name="not_mute" tab="未禁言"></n-tab-pane>
  31. <n-tab-pane name="mute" tab="已禁言"></n-tab-pane>
  32. </n-tabs>
  33. </aside>
  34. <span v-if="currentTab !== 'onlyMute'">
  35. <i v-if="!isH5" class="icon icon-close" @click="toggleShow"></i>
  36. </span>
  37. </header>
  38. <main :class="['main']" style="background-color: #f4f5f9; height: 100%" v-if="!currentTab">
  39. <ManageName class="space-top" :isAuth="isAuth" :isH5="isH5" :data="conversation.groupProfile" @update="updateProfile" style="background-color: #fff" />
  40. <div class="userInfo space-top" style="background-color: #fff">
  41. <header class="userInfo-header" @click="setTab('member')">
  42. <label>{{ $t(`TUIChat.manage.群成员`) }}</label>
  43. <p>
  44. <span> {{ groupDetail.memberNum || 0 }}{{ $t(`TUIChat.manage.人`) }} </span>
  45. <i class="icon icon-right"></i>
  46. </p>
  47. </header>
  48. <ol>
  49. <!-- @click="handleMemberProfileShow(item)" -->
  50. <dl v-for="(item, index) in userInfo?.list?.slice(0, showUserNum)" :key="index">
  51. <dt>
  52. <img class="avatar" :src="item?.avatar || 'https://oss.dayaedu.com/news-info/07/1690787574969.png'" onerror="this.src='https://oss.dayaedu.com/news-info/07/1690787574969.png'" />
  53. </dt>
  54. <dd>{{ item?.nickname || item?.userID }}</dd>
  55. </dl>
  56. <!-- v-if="isShowAddMember" -->
  57. <dl v-if="currentUserDetail.groupRoleType === 'Owner'">
  58. <dt class="avatar" @click="toggleMask('add')">+</dt>
  59. </dl>
  60. <!-- <dl v-if="conversation.groupProfile.selfInfo.role === 'Owner'">
  61. <dt class="avatar" @click="toggleMask('remove')">-</dt>
  62. </dl> -->
  63. </ol>
  64. </div>
  65. <ul class="content space-top" @click="editLableName = ''" style="background-color: #fff">
  66. <li @click.stop="setTab('notification')">
  67. <aside>
  68. <label>{{ $t(`TUIChat.manage.群公告`) }}</label>
  69. <article>{{ conversation.groupProfile.notification }}</article>
  70. </aside>
  71. <i class="icon icon-right end"></i>
  72. </li>
  73. <!-- <li v-if="isAdmin && isSetMuteTime" @click.stop="setTab('admin')">
  74. <label>{{ $t(`TUIChat.manage.群管理`) }}</label>
  75. <i class="icon icon-right"></i>
  76. </li>
  77. <li>
  78. <label>{{ $t(`TUIChat.manage.群ID`) }}</label>
  79. <div class="groupID">
  80. <span>{{ conversation.groupProfile.groupID }}</span>
  81. <i
  82. class="icon icon-msg-copy"
  83. @click="handleGroupIDCopy"
  84. :title="$t('TUIChat.复制')"
  85. ></i>
  86. </div>
  87. </li>
  88. <li>
  89. <label>{{ $t(`TUIChat.manage.群头像`) }}</label>
  90. <img
  91. class="avatar"
  92. :src="
  93. conversation?.groupProfile?.avatar ||
  94. 'https://oss.dayaedu.com/news-info/07/1690775328089.png'
  95. "
  96. onerror="this.src='https://oss.dayaedu.com/news-info/07/1690775328089.png'"
  97. />
  98. </li>
  99. <li>
  100. <label>{{ $t(`TUIChat.manage.群类型`) }}</label>
  101. <span>
  102. {{
  103. $t(`TUIChat.manage.${typeName[conversation.groupProfile.type]}`)
  104. }}
  105. </span>
  106. </li>
  107. <li>
  108. <label>{{ $t(`TUIChat.manage.加群方式`) }}</label>
  109. <span>
  110. {{
  111. $t(
  112. `TUIChat.manage.${
  113. typeName[conversation.groupProfile.joinOption]
  114. }`
  115. )
  116. }}
  117. </span>
  118. </li> -->
  119. </ul>
  120. <div v-if="currentUserDetail.groupRoleType === 'Owner' || currentUserDetail.groupRoleType === 'Admin'" class="admin-content space-top" style="background-color: #fff; padding-top: 12px;border-top: 1Px solid #f4f5f9;">
  121. <aside>
  122. <label>学生禁言</label>
  123. </aside>
  124. <Slider :open="groupDetail.configJson.mute" @change="setAllMuteTime" />
  125. </div>
  126. <div v-if="currentUserDetail.groupRoleType === 'Owner' || currentUserDetail.groupRoleType === 'Admin'" class="admin-content space-top" style="background-color: #fff; padding-top: 12px;border-top: 1Px solid #f4f5f9;" @click.stop="() => {
  127. userInfo.muteList = []
  128. setTab('onlyMute')
  129. }">
  130. <aside>
  131. <label>禁言名单</label>
  132. </aside>
  133. <i class="icon icon-right end"></i>
  134. </div>
  135. <div v-if="currentUserDetail.groupRoleType === 'Owner' && userInfo?.list.length > 1" class="admin-content space-top" style="background-color: #fff;padding-top: 12px; border-top: 1Px solid #f4f5f9;" @click.stop="toggleMask('changeOwner')">
  136. <aside>
  137. <label>移交群主</label>
  138. </aside>
  139. <i class="icon icon-right end"></i>
  140. </div>
  141. <ul class="footer space-top" style="overflow: hidden; background-color: #f4f5f9;">
  142. <!-- <li v-if="currentUserDetail.groupRoleType === 'Owner' && userInfo?.list.length > 1" @click.stop="toggleMask('changeOwner')">移交群主</li> -->
  143. <li v-if="currentUserDetail.groupRoleType === 'Owner'" @click.stop="dismiss(conversation.groupProfile)">解散群聊</li>
  144. <li v-else @click.stop="quit(conversation.groupProfile)">退出群组</li>
  145. </ul>
  146. </main>
  147. <ManageMember v-else-if="currentTab === 'member'" :self="conversation.groupProfile.selfInfo" :list="userInfo.list" :total="~~conversation.groupProfile.memberCount" @more="getMember('more')" @del="submit" @handleMemberProfileShow="handleMemberProfileShow" />
  148. <!-- :isShowDel="conversation.groupProfile.selfInfo.role === 'Owner'" -->
  149. <MemeberProfile v-else-if="currentTab === 'profile'" :userInfo="currentMember" />
  150. <ManageNotification v-else-if="currentTab === 'notification'" :isAuth="isAuth" :data="conversation.groupProfile" @update="updateProfile" />
  151. <main class="admin" v-else-if="currentTab === 'admin'">
  152. <div class="admin-list" v-if="isAdmin">
  153. <label>{{ $t(`TUIChat.manage.群管理员`) }}</label>
  154. <ol>
  155. <dl v-for="(item, index) in member.admin" :key="index">
  156. <dt>
  157. <img class="avatar" :src="item?.avatar || 'https://oss.dayaedu.com/news-info/07/1690787574969.png'" onerror="this.src='https://oss.dayaedu.com/news-info/07/1690787574969.png'" />
  158. </dt>
  159. <dd>{{ item?.nick || item?.userID }}</dd>
  160. </dl>
  161. <dl>
  162. <dt class="avatar" @click="toggleMask('addAdmin')">+</dt>
  163. </dl>
  164. <dl>
  165. <dt class="avatar" v-if="member.admin.length > 0" @click="toggleMask('removeAdmin')">-</dt>
  166. </dl>
  167. </ol>
  168. </div>
  169. <div class="admin-content space-top" v-if="isSetMuteTime">
  170. <aside>
  171. <label>{{ $t(`TUIChat.manage.学生禁言`) }}</label>
  172. <p>
  173. {{ $t(`TUIChat.manage.学生禁言开启后,只允许群主和管理员发言。`) }}
  174. </p>
  175. </aside>
  176. <Slider :open="conversation.groupProfile.muteAllMembers" @change="setAllMuteTime" />
  177. </div>
  178. <div class="admin-list last" v-if="isSetMuteTime">
  179. <label>{{ $t(`TUIChat.manage.单独禁言人员`) }}</label>
  180. <ol>
  181. <dl v-for="(item, index) in member.muteMember" :key="index">
  182. <dt>
  183. <img class="avatar" :src="item?.avatar || 'https://oss.dayaedu.com/news-info/07/1690787574969.png'" onerror="this.src='https://oss.dayaedu.com/news-info/07/1690787574969.png'" />
  184. </dt>
  185. <dd>{{ item?.nick || item?.userID }}</dd>
  186. </dl>
  187. <dl>
  188. <dt class="avatar" @click="toggleMask('addMute')">+</dt>
  189. </dl>
  190. <dl>
  191. <dt class="avatar" v-if="member.muteMember.length > 0" @click="toggleMask('removeMute')">-</dt>
  192. </dl>
  193. </ol>
  194. </div>
  195. </main>
  196. <ManageMute v-else-if="currentTab === 'onlyMute'" :currentModel="currentModel"
  197. :total="muteTotal"
  198. :self="conversation.groupProfile.selfInfo" :list="userInfo.muteList"
  199. :conversation="conversation"
  200. :muteLoading="muteLoading"
  201. @more="getUserList('more')"
  202. @del="submit"
  203. @back="() => {
  204. setTab('');
  205. currentModel = 'not_mute'
  206. }"
  207. @search="(keyword) => {
  208. mutePage = 1
  209. muteSearch = keyword
  210. userInfo.muteList = []
  211. getUserList()
  212. }"
  213. @handleMemberProfileShow="handleMemberProfileShow" />
  214. <MaskTUI :show="mask" @update:show="(e) => (mask = e)">
  215. <Transfer :title="$t(`TUIChat.manage.${transferTitle}`)" :list="transferList" :isSearch="isSearch" :isRadio="isRadio" :selectedList="selectedList" @submit="submit" @cancel="cancel" @search="handleSearchMember" :isH5="isH5" />
  216. </MaskTUI>
  217. <DialogTUI :title="$t(`TUIChat.manage.删除成员`)" :show="delDialogShow" :isH5="isH5" :center="true" :isHeaderShow="!isH5" @submit="handleManage(userList, 'remove')" @update:show="(e) => (delDialogShow = e)">
  218. <p v-if="userList.length === 1" class="delDialog-title">
  219. {{ $t(`TUIChat.manage.确定从群聊中删除该成员?`) }}
  220. </p>
  221. <p v-if="userList.length > 1" class="delDialog-title">
  222. {{ $t(`TUIChat.manage.确定从群聊中删除所选成员?`) }}
  223. </p>
  224. </DialogTUI>
  225. <DialogTUI title="退出群聊" :show="quitDialogShow" :isH5="isH5" :center="true" :isHeaderShow="!isH5" @submit="handleManage([], 'quit')" @update:show="(e) => (quitDialogShow = e)">
  226. <p class="delDialog-title">是否退出群聊?</p>
  227. </DialogTUI>
  228. <DialogTUI title="解散群聊" :show="dimmisDialogShow" :isH5="isH5" :center="true" :isHeaderShow="!isH5" @submit="handleManage([], 'dismiss')" @update:show="(e) => (dimmisDialogShow = e)">
  229. <p class="delDialog-title">是否解散群聊?</p>
  230. </DialogTUI>
  231. </div>
  232. </div>
  233. </template>
  234. <script lang="ts">
  235. import TUIMessage from "../../../components/messageTUI/index";
  236. import { defineComponent, watchEffect, reactive, toRefs, computed, watch, ref, onMounted } from "vue";
  237. import { onClickOutside } from "@vueuse/core";
  238. import MaskTUI from "../../../components/maskTUI/mask.vue";
  239. import Transfer from "../../../components/transferTUI/index.vue";
  240. import Slider from "../../../components/sliderTUI/index.vue";
  241. import ManageName from "./manage-name.vue";
  242. import ManageNotification from "./manage-notification.vue";
  243. import ManageMember from "./manage-member.vue";
  244. import MemeberProfile from "./member-profile.vue";
  245. import ManageMute from './manage-mute.vue'
  246. import DialogTUI from "../../../components/dialogTUi/index.vue";
  247. import { imGroupChangeGroupOwner, imGroupDetail, imGroupDismiss, imGroupMemberPage, imGroupMemberSaveImAll, imGroupMemberUserDetail, imGroupMuteAll, imGroupQuit, imUserFriendPage } from "../../../../api";
  248. import Vuex from "vuex";
  249. import { handleErrorPrompts } from "../../utils";
  250. import useClipboard from "vue-clipboard3";
  251. import { eventGlobal } from "@/helpers";
  252. const manage = defineComponent({
  253. components: {
  254. MaskTUI,
  255. Transfer,
  256. Slider,
  257. ManageName,
  258. ManageNotification,
  259. ManageMember,
  260. MemeberProfile,
  261. ManageMute,
  262. DialogTUI,
  263. },
  264. props: {
  265. userInfo: {
  266. type: Object,
  267. default: () => ({
  268. isGroup: false,
  269. list: [],
  270. }),
  271. },
  272. conversation: {
  273. type: Object,
  274. default: () => ({}),
  275. },
  276. show: {
  277. type: Boolean,
  278. default: () => false,
  279. },
  280. isH5: {
  281. type: Boolean,
  282. default: () => false,
  283. },
  284. },
  285. setup(props: any, ctx: any) {
  286. const types: any = manage.TUIServer.TUICore.TIM.TYPES;
  287. const { GroupServer } = manage;
  288. const { t } = manage.TUIServer.TUICore.config.i18n.useI18n();
  289. const data: any = reactive({
  290. conversation: {},
  291. userInfo: {
  292. isGroup: false,
  293. list: [],
  294. muteList: []
  295. },
  296. isShowMuteTimeInput: false,
  297. editLableName: "",
  298. mask: false,
  299. currentTab: "",
  300. transferType: "",
  301. isSearch: false,
  302. isRadio: false,
  303. transferList: [],
  304. selectedList: [],
  305. isMuteTime: false,
  306. show: false,
  307. typeName: {
  308. [types.GRP_WORK]: "好友工作群",
  309. [types.GRP_PUBLIC]: "陌生人社交群",
  310. [types.GRP_MEETING]: "临时会议群",
  311. [types.GRP_AVCHATROOM]: "直播群",
  312. [types.JOIN_OPTIONS_FREE_ACCESS]: "自由加入",
  313. [types.JOIN_OPTIONS_NEED_PERMISSION]: "需要验证",
  314. [types.JOIN_OPTIONS_DISABLE_APPLY]: "禁止加群",
  315. },
  316. delDialogShow: false,
  317. quitDialogShow: false,
  318. dimmisDialogShow: false,
  319. userList: [],
  320. transferTitle: "",
  321. member: {
  322. admin: [],
  323. member: [],
  324. muteMember: [],
  325. },
  326. currentMember: {},
  327. classGroupDetail: {}, // 群详情
  328. page: 1, // 当前默认查询第一页数据
  329. currentUserDetail: {} as any, // 用户信息
  330. mutePage: 1,
  331. muteSearch: '',
  332. muteLoading: false,
  333. muteTotal: 0,
  334. groupDetail: {} as any,
  335. currentModel: 'not_mute'
  336. });
  337. const dialog: any = ref();
  338. watchEffect(() => {
  339. data.conversation = props.conversation;
  340. data.userInfo = props.userInfo;
  341. data.show = props.show;
  342. });
  343. const VuexStore = ((window as any)?.TUIKitTUICore?.isOfficial && (Vuex as any)?.useStore()) || {};
  344. const TabName = computed(() => {
  345. let name = "";
  346. switch (data.currentTab) {
  347. case "notification":
  348. name = "群公告";
  349. break;
  350. case "member":
  351. name = "群成员";
  352. break;
  353. case "profile":
  354. name = "群成员";
  355. break;
  356. default:
  357. name = "群管理";
  358. break;
  359. }
  360. return name;
  361. });
  362. watch(
  363. () => data.userInfo.list,
  364. (newValue: any, oldValue: any) => {
  365. data.member = {
  366. admin: [],
  367. member: [],
  368. muteMember: [],
  369. };
  370. // TIM.TYPES.GRP_MBR_ROLE_ADMIN(群管理员),
  371. // TIM.TYPES.GRP_MBR_ROLE_MEMBER(群普通成员),
  372. // TIM.TYPES.GRP_MBR_ROLE_CUSTOM(自定义群成员角色,仅社群支持)
  373. newValue.map((item: any) => {
  374. switch (item?.groupRoleType) {
  375. case "Admin":
  376. data.member.admin.push(item);
  377. break;
  378. case "Member":
  379. data.member.member.push(item);
  380. break;
  381. default:
  382. break;
  383. }
  384. return item;
  385. });
  386. const time: number = new Date().getTime();
  387. data.member.muteMember = newValue.filter((item: any) => item?.muteUntil * 1000 - time > 0);
  388. },
  389. { deep: true }
  390. );
  391. const isDismissGroupAuth = computed(() => {
  392. const { conversation } = data;
  393. const userRole = conversation?.groupProfile?.selfInfo.role;
  394. const groupType = conversation?.groupProfile?.type;
  395. const isOwner = userRole === types.GRP_MBR_ROLE_OWNER;
  396. const isWork = groupType === types.GRP_WORK;
  397. return isOwner && !isWork;
  398. });
  399. const isShowAddMember = computed(() => {
  400. const { conversation } = data;
  401. const groupType = conversation?.groupProfile?.type;
  402. const isWork = groupType === types.GRP_WORK;
  403. if (isWork) {
  404. return true;
  405. }
  406. return false;
  407. });
  408. const showUserNum = computed(() => {
  409. let num = 3;
  410. if (!isShowAddMember.value) {
  411. num += 1;
  412. }
  413. if ((data.conversation as any).groupProfile.selfInfo.role !== "Owner") {
  414. num += 1;
  415. }
  416. return num;
  417. });
  418. const isAuth = computed(() => {
  419. const { conversation } = data;
  420. const userRole = conversation?.groupProfile?.selfInfo.role;
  421. const isOwner = userRole === types.GRP_MBR_ROLE_OWNER;
  422. const isAdmin = userRole === types.GRP_MBR_ROLE_ADMIN;
  423. return isOwner || isAdmin;
  424. });
  425. const isAdmin = computed(() => {
  426. const { conversation } = data;
  427. const groupType = conversation?.groupProfile?.type;
  428. const userRole = conversation?.groupProfile?.selfInfo.role;
  429. const isOwner = userRole === types.GRP_MBR_ROLE_OWNER;
  430. const isWork = groupType === types.GRP_WORK;
  431. const isAVChatRoom = groupType === types.GRP_AVCHATROOM;
  432. if (!isWork && !isAVChatRoom && isOwner) {
  433. return true;
  434. }
  435. return false;
  436. });
  437. const isSetMuteTime = computed(() => {
  438. const { conversation } = data;
  439. const groupType = conversation?.groupProfile?.type;
  440. const isWork = groupType === types.GRP_WORK;
  441. if (isWork || !isAuth.value) {
  442. return false;
  443. }
  444. return true;
  445. });
  446. const getMember = async (type?: string) => {
  447. try {
  448. const { conversation } = data;
  449. // console.log(conversation, "getMember -------");
  450. const options: any = {
  451. groupId: conversation?.groupProfile?.groupID,
  452. rows: 100,
  453. page: type && type === "more" ? data.page + 1 : data.page,
  454. // offset: type && type === "more" ? data.userInfo.list.length : 0,
  455. };
  456. await imGroupMemberPage(options).then((res: any) => {
  457. const rows = res.data.rows || [];
  458. rows.forEach((row: any) => {
  459. row.nick = row.nickname;
  460. });
  461. if (type && type === "more") {
  462. data.userInfo.list = [...data.userInfo.list, ...rows];
  463. } else {
  464. data.userInfo.list = rows;
  465. }
  466. });
  467. // GroupServer.getGroupMemberList(options)
  468. } catch {
  469. //
  470. }
  471. };
  472. // 禁言
  473. const getUserList = async (type?: string) => {
  474. data.muteLoading = true;
  475. try {
  476. const { conversation } = data;
  477. const options: any = {
  478. groupId: conversation?.groupProfile?.groupID,
  479. rows: 100,
  480. groupMute: data.currentModel === 'not_mute' ? false : true,
  481. groupRoleTypes: ['Member'],
  482. page: type && type === "more" ? data.mutePage + 1 : data.mutePage,
  483. keyword: data.muteSearch
  484. };
  485. await imGroupMemberPage(options).then((res: any) => {
  486. const rows = res.data.rows || [];
  487. rows.forEach((row: any) => {
  488. row.nick = row.nickname;
  489. });
  490. if (type && type === "more") {
  491. data.userInfo.muteList = [...data.userInfo.list, ...rows];
  492. } else {
  493. data.userInfo.muteList = rows;
  494. }
  495. data.muteTotal = res.data.total || 0;
  496. });
  497. } catch {
  498. //
  499. }
  500. data.muteLoading = false;
  501. };
  502. const addMember = async (userIDList: any) => {
  503. const { conversation } = data;
  504. // const options: any = {
  505. // groupID: conversation.groupProfile.groupID,
  506. // userIDList,
  507. // };
  508. // await GroupServer.addGroupMember(options);
  509. const params: any = [];
  510. userIDList.forEach((id: any) => {
  511. params.push({
  512. groupId: conversation.groupProfile.groupID,
  513. imUserId: id,
  514. });
  515. });
  516. // console.log(params, userIDList, "userIDList");
  517. // return;
  518. try {
  519. await imGroupMemberSaveImAll(params);
  520. getGroupDetail();
  521. getMember();
  522. } catch {
  523. //
  524. }
  525. };
  526. const deleteMember = (user: any) => {
  527. const { conversation } = data;
  528. const options: any = {
  529. groupID: conversation.groupProfile.groupID,
  530. userIDList: [user.userID],
  531. };
  532. GroupServer.deleteGroupMember(options);
  533. };
  534. const changeOwner = async (userID: any) => {
  535. // const options: any = {
  536. // groupID: data.conversation.groupProfile.groupID,
  537. // newOwnerID: userID,
  538. // };
  539. // const imResponse = await GroupServer.changeGroupOwner(options);
  540. // data.conversation.groupProfile = imResponse.data.group;
  541. console.log(data.conversation.groupProfile, userID);
  542. // 腾讯IM切换人之后
  543. await imGroupChangeGroupOwner({
  544. oldOwner: data.conversation.groupProfile.ownerID,
  545. groupId: data.conversation.groupProfile.groupID,
  546. newOwner: userID,
  547. });
  548. toggleShow();
  549. data.conversation.groupProfile = {};
  550. TUIMessage({
  551. message: "转交成功",
  552. isH5: false,
  553. type: "success",
  554. });
  555. };
  556. const quit = async (group: any) => {
  557. data.quitDialogShow = true;
  558. };
  559. const dismiss = async (group: any) => {
  560. data.dimmisDialogShow = true;
  561. // console.log(manage.TUIServer.deleteConversation, "manage.TUIServer");
  562. // manage.TUIServer.deleteConversation(data.conversation.conversationID);
  563. // manage.TUIServer.store.conversation = {};
  564. // toggleShow();
  565. // await GroupServer.dismissGroup(group.groupID);
  566. // manage.TUIServer.store.conversation = {};
  567. // (window as any)?.TUIKitTUICore?.isOfficial && VuexStore?.commit && VuexStore?.commit("handleTask", 5);
  568. };
  569. const handleAdmin = async (user: any) => {
  570. const { conversation } = data;
  571. let role = "";
  572. switch (user.role) {
  573. case types.GRP_MBR_ROLE_ADMIN:
  574. role = types.GRP_MBR_ROLE_MEMBER;
  575. break;
  576. case types.GRP_MBR_ROLE_MEMBER:
  577. role = types.GRP_MBR_ROLE_ADMIN;
  578. break;
  579. }
  580. const options: any = {
  581. groupID: conversation.groupProfile.groupID,
  582. userID: user.userID,
  583. role,
  584. };
  585. await GroupServer.setGroupMemberRole(options);
  586. getMember();
  587. };
  588. const setMemberMuteTime = async (userID: string, type?: string) => {
  589. const { conversation } = data;
  590. const options: any = {
  591. groupID: conversation.groupProfile.groupID,
  592. userID,
  593. muteTime: type === "add" ? 60 * 60 * 24 * 30 : 0,
  594. };
  595. await GroupServer.setGroupMemberMuteTime(options);
  596. if (type === "add") {
  597. (window as any)?.TUIKitTUICore?.isOfficial && VuexStore?.commit && VuexStore?.commit("handleTask", 4);
  598. }
  599. getMember();
  600. };
  601. const kickedOut = async (userIDList: any) => {
  602. const { conversation } = data;
  603. const options: any = {
  604. groupID: conversation.groupProfile.groupID,
  605. userIDList,
  606. reason: "",
  607. };
  608. await GroupServer.deleteGroupMember(options);
  609. getMember();
  610. };
  611. const edit = (labelName: string) => {
  612. data.editLableName = labelName;
  613. };
  614. const updateProfile = async (params: any) => {
  615. const { key, value } = params;
  616. const options: any = {
  617. groupID: data.conversation.groupProfile.groupID,
  618. [key]: value,
  619. };
  620. const res = await GroupServer.updateGroupProfile(options);
  621. const { conversation } = manage.TUIServer.store;
  622. conversation.groupProfile = res.data.group;
  623. manage.TUIServer.store.conversation = {};
  624. manage.TUIServer.store.conversation = conversation;
  625. data.editLableName = "";
  626. };
  627. const setTab = (tabName: string) => {
  628. if(tabName === 'onlyMute') {
  629. getUserList()
  630. }
  631. data.currentTab = tabName;
  632. data.editLableName = "";
  633. if (data.currentTab === "member") {
  634. data.transferType = "remove";
  635. }
  636. if (!data.currentTab) {
  637. data.transferType = "";
  638. }
  639. };
  640. const handleSearchMember = async (value: string) => {
  641. let imResponse: any = {};
  642. let imMemberResponse: any = {};
  643. const options: any = {
  644. groupID: data.conversation.groupProfile.groupID,
  645. userIDList: [value],
  646. };
  647. switch (data.transferType) {
  648. case "add":
  649. try {
  650. imMemberResponse = await GroupServer.getGroupMemberProfile(options);
  651. data.transferList = data.transferList.filter((item: any) => item.userID !== imResponse.data[0]?.userID);
  652. data.transferList = [...data.transferList, ...imResponse.data];
  653. if (imMemberResponse?.data?.memberList.length > 0) {
  654. data.transferList = data.transferList.map((item: any) => {
  655. if (item.userID === imMemberResponse?.data?.memberList[0].userID) {
  656. item.isDisabled = true;
  657. }
  658. return item;
  659. });
  660. }
  661. } catch (error) {
  662. const message = t("TUIChat.manage.该用户不存在");
  663. handleErrorPrompts(message, props);
  664. }
  665. break;
  666. case "remove":
  667. try {
  668. imResponse = await GroupServer.getGroupMemberProfile(options);
  669. if (imResponse.data.memberList.length === 0) {
  670. const message = t("TUIChat.manage.该用户不在群组内");
  671. return handleErrorPrompts(message, props);
  672. }
  673. data.transferList = data.transferList.filter(
  674. (item: any) =>
  675. // eslint-disable-next-line no-unsafe-optional-chaining
  676. item.userID !== imResponse?.data?.memberList[0]?.userID
  677. );
  678. data.transferList = [
  679. ...data.transferList,
  680. // eslint-disable-next-line no-unsafe-optional-chaining
  681. ...imResponse?.data?.memberList,
  682. ];
  683. } catch (error) {
  684. const message = t("TUIChat.manage.该用户不存在");
  685. handleErrorPrompts(message, props);
  686. }
  687. break;
  688. default:
  689. break;
  690. }
  691. };
  692. const submit = (userList: any) => {
  693. console.log(userList, data.transferType, " data.transferType");
  694. if(userList.length <= 0) return
  695. if (data.transferType === "remove") {
  696. data.userList = userList;
  697. data.delDialogShow = !data.delDialogShow;
  698. } else {
  699. handleManage(userList, data.transferType);
  700. }
  701. data.mask = false;
  702. };
  703. const friendList = async () => {
  704. const list = await imUserFriendPage({ page: 1, rows: 999 });
  705. console.log(list, "lits");
  706. const fristList = list.data.rows || [];
  707. fristList.forEach((item: any) => {
  708. item.nick = item.friendNickname;
  709. });
  710. return fristList.filter((item: any) => !data.userInfo.list.some((infoItem: any) => infoItem.imUserId === item.imUserId));
  711. };
  712. const cancel = () => {
  713. toggleMask();
  714. };
  715. const toggleMask = async (type?: string) => {
  716. data.selectedList = [];
  717. switch (type) {
  718. case "add":
  719. data.isRadio = false;
  720. data.transferList = await friendList();
  721. data.transferTitle = "添加成员";
  722. break;
  723. case "remove":
  724. data.isRadio = false;
  725. data.transferList = data.userInfo.list.filter(
  726. (item: any) =>
  727. // eslint-disable-next-line no-unsafe-optional-chaining
  728. item.userID !== data.conversation?.groupProfile?.selfInfo.userID
  729. );
  730. data.transferTitle = "删除成员";
  731. break;
  732. case "addAdmin":
  733. data.isRadio = true;
  734. data.transferList = data.member.member;
  735. data.transferTitle = "新增管理员";
  736. break;
  737. case "removeAdmin":
  738. data.isRadio = true;
  739. data.transferList = data.member.admin;
  740. data.transferTitle = "移除管理员";
  741. break;
  742. case "changeOwner":
  743. data.isRadio = true;
  744. data.transferList = [...data.member.admin, ...data.member.member].filter(item => item.roleType !== "STUDENT");
  745. data.transferTitle = "转让群组";
  746. console.log(data.transferList, "data.transferList");
  747. break;
  748. case "addMute":
  749. data.isRadio = true;
  750. data.transferList = data.member.member;
  751. if (data.conversation.groupProfile.selfInfo.role === "Owner") {
  752. data.transferList = [...data.member.admin, ...data.member.member];
  753. }
  754. data.transferTitle = "新增禁言用户";
  755. break;
  756. case "removeMute":
  757. data.isRadio = true;
  758. data.transferList = data.member.muteMember;
  759. data.transferTitle = "移除禁言用户";
  760. break;
  761. default:
  762. break;
  763. }
  764. data.transferType = type;
  765. data.mask = !data.mask;
  766. };
  767. onClickOutside(dialog, () => {
  768. data.show = false;
  769. });
  770. const toggleShow = () => {
  771. if (!GroupServer) {
  772. const message = t("TUIChat.manage.请先注册 TUIGroup 模块");
  773. return handleErrorPrompts(message, props);
  774. }
  775. data.show = !data.show;
  776. if (!data.show) {
  777. data.currentTab = "";
  778. }
  779. if (data.show) {
  780. getMember();
  781. }
  782. };
  783. // 禁言
  784. const setAllMuteTime = async (value: boolean) => {
  785. // updateProfile({ key: "muteAllMembers", value });
  786. // (window as any)?.TUIKitTUICore?.isOfficial && VuexStore?.commit && VuexStore?.commit("handleTask", 4);
  787. try {
  788. await imGroupMuteAll({
  789. groupId: data.conversation.groupProfile.groupID,
  790. muteAll: value,
  791. });
  792. getGroupDetail();
  793. } catch {
  794. //
  795. }
  796. };
  797. const handleManage = (userList: any, type: any) => {
  798. const userIDList: any = [];
  799. userList.map((item: any) => {
  800. userIDList.push(item.imUserId);
  801. return item;
  802. });
  803. switch (type) {
  804. case "add":
  805. addMember(userIDList);
  806. break;
  807. case "remove":
  808. kickedOut(userIDList);
  809. break;
  810. case "addAdmin":
  811. handleAdmin(userList[0]);
  812. break;
  813. case "removeAdmin":
  814. handleAdmin(userList[0]);
  815. break;
  816. case "changeOwner":
  817. changeOwner(userIDList[0]);
  818. break;
  819. case "addMute":
  820. setMemberMuteTime(userIDList[0], "add");
  821. break;
  822. case "removeMute":
  823. setMemberMuteTime(userIDList[0], "remove");
  824. break;
  825. case "quit":
  826. // 退出群聊
  827. imGroupQuit({
  828. id: data.conversation.groupProfile.groupID,
  829. }).then(() => {
  830. eventGlobal.emit("removeGroup", data.conversation.groupProfile.groupID);
  831. manage.TUIServer.deleteConversation(data.conversation.conversationID);
  832. manage.TUIServer.store.conversation = {};
  833. toggleShow();
  834. });
  835. break;
  836. case "dismiss":
  837. // 解散群
  838. imGroupDismiss({
  839. id: data.conversation.groupProfile.groupID,
  840. })
  841. .then(() => {
  842. eventGlobal.emit("removeGroup", data.conversation.groupProfile.groupID);
  843. manage.TUIServer.deleteConversation(data.conversation.conversationID);
  844. manage.TUIServer.store.conversation = {};
  845. toggleShow();
  846. })
  847. .catch((err: any) => {
  848. TUIMessage({
  849. message: err.message,
  850. isH5: false,
  851. type: "error",
  852. });
  853. });
  854. break;
  855. default:
  856. break;
  857. }
  858. };
  859. const handleGroupIDCopy = async () => {
  860. try {
  861. const { toClipboard } = useClipboard();
  862. await toClipboard(data?.conversation?.groupProfile?.groupID);
  863. } catch (error) {
  864. handleErrorPrompts(error, data.env);
  865. }
  866. };
  867. const handleMemberProfileShow = (user: any) => {
  868. data.currentMember = user;
  869. setTab("profile");
  870. };
  871. const getGroupMemberUserDetail = async () => {
  872. try {
  873. const res = await imGroupMemberUserDetail({
  874. groupId: data?.conversation?.groupProfile?.groupID,
  875. imUserId: data?.conversation?.groupProfile?.selfInfo.userID,
  876. });
  877. data.currentUserDetail = res.data;
  878. } catch {
  879. //
  880. }
  881. };
  882. /** 获取群详情 */
  883. const getGroupDetail = async () => {
  884. try {
  885. const res = await imGroupDetail({ id: data?.conversation?.groupProfile?.groupID });
  886. const tdata = res.data;
  887. tdata.configJson = tdata.configJson ? JSON.parse(tdata.configJson) : {};
  888. data.groupDetail = tdata;
  889. } catch {
  890. //
  891. }
  892. };
  893. watch(
  894. () => data.show,
  895. () => {
  896. if (data.show) {
  897. try {
  898. getGroupDetail();
  899. getGroupMemberUserDetail();
  900. } catch {
  901. //
  902. }
  903. }
  904. }
  905. );
  906. onMounted(() => {
  907. try {
  908. getGroupDetail();
  909. getGroupMemberUserDetail();
  910. console.log(data?.conversation, "data?.conversation?");
  911. // console.log(data.userInfo.list, "data.userInfo.list");
  912. } catch {
  913. //
  914. }
  915. });
  916. return {
  917. ...toRefs(data),
  918. isDismissGroupAuth,
  919. isShowAddMember,
  920. isSetMuteTime,
  921. isAdmin,
  922. isAuth,
  923. addMember,
  924. deleteMember,
  925. changeOwner,
  926. quit,
  927. dismiss,
  928. handleAdmin,
  929. setMemberMuteTime,
  930. kickedOut,
  931. edit,
  932. updateProfile,
  933. setTab,
  934. TabName,
  935. getMember,
  936. getUserList,
  937. handleSearchMember,
  938. submit,
  939. cancel,
  940. toggleMask,
  941. toggleShow,
  942. setAllMuteTime,
  943. handleManage,
  944. showUserNum,
  945. dialog,
  946. handleGroupIDCopy,
  947. handleMemberProfileShow,
  948. };
  949. },
  950. });
  951. export default manage;
  952. </script>
  953. <style lang="scss" scoped src="./style/index.scss"></style>