index.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <template>
  2. <Dialog
  3. :show="true"
  4. :isH5="!isPC"
  5. :isHeaderShow="false"
  6. :isFooterShow="false"
  7. :background="false"
  8. @update:show="closeCreated"
  9. >
  10. <div
  11. class="group"
  12. :class="[!isPC ? 'group-h5' : '']"
  13. >
  14. <div class="group-box">
  15. <header class="group-box-header">
  16. <Icon
  17. :file="isPC ? closeIcon : backIcon"
  18. class="icon-close"
  19. size="16px"
  20. @onClick="closeCreated"
  21. />
  22. <h1 class="group-box-header-title">
  23. {{ headerTitle }}
  24. </h1>
  25. </header>
  26. <ul
  27. v-if="!groupInfo.isEdit"
  28. class="group-list"
  29. >
  30. <li class="group-list-item">
  31. <label class="group-list-item-label">{{ TUITranslateService.t('TUIGroup.群头像') }}</label>
  32. <Avatar :url="groupInfo.profile.avatar" />
  33. </li>
  34. <ul>
  35. <li
  36. v-for="(item, index) in createInfo"
  37. :key="index"
  38. class="group-list-item"
  39. >
  40. <label class="group-list-item-label">{{ item.name }}</label>
  41. <input
  42. v-if="isPC"
  43. v-model="groupInfo.profile[item.key]"
  44. type="text"
  45. :placeholder="item.placeholder"
  46. >
  47. <span
  48. v-else
  49. class="group-h5-list-item-content"
  50. @click="edit(item.key)"
  51. >
  52. <p class="content">{{ groupInfo.profile[item.key] }}</p>
  53. <Icon :file="rightIcon" />
  54. </span>
  55. </li>
  56. <li class="group-list-introduction">
  57. <div class="group-list-item">
  58. <label class="group-list-item-label">{{ TUITranslateService.t('TUIGroup.群类型') }}</label>
  59. <GroupIntroduction
  60. v-if="isPC"
  61. :groupType="groupInfo.profile.type"
  62. @selectType="selected"
  63. />
  64. <span
  65. v-else
  66. class="group-h5-list-item-content"
  67. @click="edit('type')"
  68. >
  69. <p class="content">{{ groupTypeDetail.label }}</p>
  70. <Icon :file="rightIcon" />
  71. </span>
  72. </div>
  73. <article
  74. v-if="!isPC"
  75. class="group-h5-list-item-introduction"
  76. >
  77. <label class="introduction-name">{{ groupTypeDetail.label }}:</label>
  78. <span class="introduction-detail">{{ groupTypeDetail.detail }}</span>
  79. <a
  80. :href="documentLink.product.url"
  81. target="view_window"
  82. >
  83. {{ TUITranslateService.t(`TUIGroup.${groupTypeDetail.src}`) }}
  84. </a>
  85. </article>
  86. </li>
  87. </ul>
  88. </ul>
  89. <!-- Edit Group Name -->
  90. <div
  91. v-else
  92. class="group-list group-list-edit"
  93. >
  94. <input
  95. v-if="groupInfo.groupConfig.type === 'input'"
  96. v-model="groupInfo.groupConfig.value"
  97. class="group-name-input"
  98. type="text"
  99. :placeholder="TUITranslateService.t(`TUIGroup.${groupInfo.groupConfig.placeholder}`)"
  100. >
  101. <GroupIntroduction
  102. v-else
  103. class="group-introduction-list"
  104. :groupType="groupInfo.groupConfig.value"
  105. @selectType="selected"
  106. />
  107. </div>
  108. <footer class="group-profile-footer">
  109. <button
  110. v-if="isPC && !groupInfo.isEdit"
  111. class="btn-default"
  112. @click="closeCreated"
  113. >
  114. {{ TUITranslateService.t('TUIGroup.取消') }}
  115. </button>
  116. <button
  117. class="btn-submit"
  118. :disabled="submitDisabledStatus"
  119. @click="submit"
  120. >
  121. {{ TUITranslateService.t('TUIGroup.确认') }}
  122. </button>
  123. </footer>
  124. </div>
  125. </div>
  126. </Dialog>
  127. </template>
  128. <script lang="ts" setup>
  129. import TUIChatEngine, {
  130. TUITranslateService,
  131. TUIGroupService,
  132. TUIStore,
  133. StoreName,
  134. } from '@tencentcloud/chat-uikit-engine';
  135. import { computed, reactive, watchEffect } from '../../../adapter-vue';
  136. import documentLink from '../../../utils/documentLink';
  137. import { isPC } from '../../../utils/env';
  138. import Icon from '../../common/Icon.vue';
  139. import backIcon from '../../../assets/icon/back.svg';
  140. import closeIcon from '../../../assets/icon/icon-close.svg';
  141. import rightIcon from '../../../assets/icon/right-icon.svg';
  142. import GroupIntroduction from './group-introduction/index.vue';
  143. import { groupIntroConfig, findGroupIntroConfig } from './group-introduction/config';
  144. import Dialog from '../../common/Dialog/index.vue';
  145. import { Toast, TOAST_TYPE } from '../../common/Toast/index';
  146. import Avatar from '../../common/Avatar/index.vue';
  147. import Server from '../server';
  148. import { IUserProfile } from '../../../interface';
  149. const TUIGroupServer = Server.getInstance();
  150. const TUIConstants = TUIGroupServer.constants;
  151. const groupInfo = reactive<any>({
  152. profile: {
  153. groupID: '',
  154. name: '',
  155. type: groupIntroConfig[0].type,
  156. avatar: groupIntroConfig[0].icon,
  157. introduction: '',
  158. notification: '',
  159. // joinOption: '',
  160. memberList: [],
  161. isSupportTopic: false,
  162. },
  163. groupConfig: {
  164. title: '',
  165. value: '',
  166. key: '',
  167. type: '',
  168. placeholder: '',
  169. },
  170. isEdit: false,
  171. });
  172. watchEffect(() => {
  173. const params = TUIGroupServer.getOnCallParams(TUIConstants.TUIGroup.SERVICE.METHOD.CREATE_GROUP);
  174. groupInfo.profile.memberList = params.memberList;
  175. groupInfo.groupConfig.title = params.title;
  176. });
  177. const groupTypeDetail = computed(() => {
  178. return findGroupIntroConfig(groupInfo.profile.type);
  179. });
  180. const headerTitle = computed(() => {
  181. let name = '添加群聊';
  182. if (groupInfo.isEdit) {
  183. name = groupInfo.groupConfig.title;
  184. }
  185. return TUITranslateService.t(`TUIGroup.${name}`);
  186. });
  187. const createInfo = computed(() => {
  188. const groupNameInput = {
  189. name: TUITranslateService.t('TUIGroup.群名称'),
  190. key: 'name',
  191. placeholder: TUITranslateService.t('TUIGroup.请输入群名称'),
  192. };
  193. const groupIDInput = {
  194. name: `${TUITranslateService.t('TUIGroup.群ID')}(${TUITranslateService.t('TUIGroup.选填')})`,
  195. key: 'groupID',
  196. placeholder: TUITranslateService.t('TUIGroup.请输入群ID'),
  197. };
  198. return groupInfo.profile.type === TUIChatEngine.TYPES.GRP_COMMUNITY
  199. ? [groupNameInput]
  200. : [groupNameInput, groupIDInput];
  201. });
  202. const submitDisabledStatus = computed(() => {
  203. return groupInfo.profile.name === '' && !groupInfo.isEdit;
  204. });
  205. const selected = (type: any) => {
  206. if (groupInfo.profile.type !== type) {
  207. groupInfo.profile.type = type;
  208. groupInfo.profile.avatar = findGroupIntroConfig(type).icon;
  209. if (groupInfo.isEdit) {
  210. groupInfo.groupConfig.value = type;
  211. }
  212. }
  213. };
  214. const createGroup = async (options: any) => {
  215. try {
  216. options.memberList = options.memberList.map((item: IUserProfile) => {
  217. return { userID: item.userID };
  218. });
  219. if (options.type === TUIChatEngine.TYPES.GRP_COMMUNITY) {
  220. delete options.groupID;
  221. }
  222. const res = await TUIGroupService.createGroup(options);
  223. const { type } = res.data.group;
  224. if (type === TUIChatEngine.TYPES.GRP_AVCHATROOM) {
  225. await TUIGroupService.joinGroup({
  226. groupID: res.data.group.groupID,
  227. applyMessage: '',
  228. });
  229. }
  230. handleCompleteCreate(res.data.group);
  231. Toast({
  232. message: TUITranslateService.t('TUIGroup.群组创建成功'),
  233. type: TOAST_TYPE.SUCCESS,
  234. });
  235. } catch (err: any) {
  236. Toast({
  237. message: err.message,
  238. type: TOAST_TYPE.ERROR,
  239. });
  240. }
  241. };
  242. const submit = () => {
  243. const { profile } = groupInfo;
  244. if (groupInfo.isEdit) {
  245. groupInfo.profile[groupInfo.groupConfig.key] = groupInfo.groupConfig.value;
  246. return groupInfo.isEdit = !groupInfo.isEdit;
  247. } else {
  248. createGroup(profile);
  249. }
  250. };
  251. const closeCreated = () => {
  252. if (groupInfo.isEdit) {
  253. return groupInfo.isEdit = !groupInfo.isEdit;
  254. }
  255. handleCompleteCreate(null);
  256. };
  257. const edit = (label: string) => {
  258. groupInfo.isEdit = !groupInfo.isEdit;
  259. groupInfo.groupConfig.key = label;
  260. groupInfo.groupConfig.value = (groupInfo.profile as any)[label];
  261. switch (label) {
  262. case 'name':
  263. groupInfo.groupConfig.title = '设置群名称';
  264. groupInfo.groupConfig.placeholder = '请输入群名称';
  265. groupInfo.groupConfig.type = 'input';
  266. break;
  267. case 'groupID':
  268. groupInfo.groupConfig.title = '设置群ID';
  269. groupInfo.groupConfig.placeholder = '请输入群ID';
  270. groupInfo.groupConfig.type = 'input';
  271. break;
  272. case 'type':
  273. groupInfo.groupConfig.title = '选择群类型';
  274. groupInfo.groupConfig.type = 'select';
  275. break;
  276. }
  277. };
  278. const handleCompleteCreate = (group: any) => {
  279. TUIStore.update(StoreName.GRP, 'isShowCreateComponent', false);
  280. const callback = TUIGroupServer.getOnCallCallback(TUIConstants.TUIGroup.SERVICE.METHOD.CREATE_GROUP);
  281. callback && callback(group);
  282. };
  283. </script>
  284. <style lang="scss" scoped src="./style/index.scss"></style>