create-group.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <template>
  2. <!-- 创建群聊 -->
  3. <div class="w-full h-[100vh] bg-[#F7F8FA] box-border pt-66">
  4. <ChatHeader title="创建群聊" />
  5. <van-cell-group style="margin-bottom: 12px" inset>
  6. <van-field
  7. v-model="formData.groupName"
  8. rows="1"
  9. autosize
  10. :rules="[{ required: true, message: '请输入群名称' }]"
  11. type="textarea"
  12. placeholder="请输入群名称"
  13. label-align="top"
  14. maxlength="30"
  15. show-word-limit
  16. >
  17. <template #label>
  18. <span class="text-xl text-black-3">
  19. 群名称
  20. <span class="text-[#EE0C0C] m-0 p-0">*</span>
  21. </span>
  22. </template>
  23. </van-field>
  24. </van-cell-group>
  25. <van-cell-group style="margin-bottom: 12px" inset>
  26. <van-field
  27. v-model="formData.description"
  28. rows="3"
  29. autosize
  30. type="textarea"
  31. :rules="[{ required: true, message: '请输入群介绍' }]"
  32. placeholder="简单说说你想在群内讨论的话题、以及希望哪些人加入群聊"
  33. label-align="top"
  34. maxlength="200"
  35. show-word-limit
  36. >
  37. <template #label>
  38. <span class="text-xl text-black-3">
  39. 群介绍
  40. <span class="text-[#EE0C0C] m-0 p-0">*</span>
  41. </span>
  42. </template>
  43. </van-field>
  44. </van-cell-group>
  45. <van-cell-group style="margin-bottom: 12px" inset>
  46. <!-- value="未选择" -->
  47. <van-cell @click="show = true" center is-link :value="groupTypeName">
  48. <template #title>
  49. <span class="text-xl text-black-3">群类型</span>
  50. </template>
  51. <template #label>
  52. <span class="text-base text-black/[0.4]">同城生活,聊天交友等</span>
  53. </template>
  54. </van-cell>
  55. </van-cell-group>
  56. <van-cell-group style="margin-bottom: 12px" inset>
  57. <van-cell center>
  58. <template #title>
  59. <span class="text-xl text-black-3">个人主页展示</span>
  60. </template>
  61. <template #label>
  62. <span class="text-base text-black/[0.4]">开启后,在群聊广场和个人主页</span>
  63. </template>
  64. <template #right-icon>
  65. <van-switch v-model="checked" active-color="#FF9300" inactive-color="#dcdee0" />
  66. </template>
  67. </van-cell>
  68. </van-cell-group>
  69. <!-- 弹窗 -->
  70. <van-dialog width="90%" v-model:show="show" show-cancel-button>
  71. <template #title>
  72. <div class="w-full flex justify-between items-center px-16 py-11 border-b-[1px]">
  73. <h1>群类型</h1>
  74. <div class="w-32 h-32 -mt-3 shrink-0" @click="show = false">
  75. <img
  76. @click="visible = false"
  77. class="w-full h-full object-cover"
  78. src="~/assets/img/note-create/close.svg"
  79. alt=""
  80. />
  81. </div>
  82. </div>
  83. </template>
  84. <!-- <div class="w-full px-16 py-20" >
  85. <van-row :gutter="[12, 16]">
  86. <template v-for="(subItem, subIndex) in groupTypeList" :key="subIndex">
  87. <van-col @click="handleTypeClick(subItem)" span="12" class="h-40 mb-16">
  88. <div
  89. :class="` relative ${showIndex == subItem.id ? ' border-[#FF9300] border-2 shadow-[0_4px_4px_0px_rgba(0,0,0,0.1)]' : ''} h-40 pl-22 flex justify-start items-center shrink-0 text-xl text-black-6 font-semibold bg-[#F7F8FA] rounded-md`"
  90. >
  91. <div class="w-24 h-24 border shrink-0 mr-6">
  92. <img class="w-full h-full object-cover" :src="city" alt="" />
  93. </div>
  94. {{ subItem.typeName }}
  95. <div
  96. v-if="showIndex == subItem.id"
  97. class="absolute rounded-t-md square1 -top-2 left-0 z-1"
  98. ></div>
  99. <div v-if="showIndex == subItem.id" class="w-14 h-14 absolute top-2 left-2 z-2">
  100. <img
  101. class="w-full h-full object-cover"
  102. alt=""
  103. src="~/assets/img/chat/check.svg"
  104. />
  105. </div>
  106. </div>
  107. </van-col>
  108. <div
  109. v-if="showIndex == subItem.id"
  110. class="w-full relative flex justify-start box-border flex-wrap pl-21 mb-18 pt-14 bg-[#F7F7F7] rounded-md"
  111. >
  112. <div
  113. :class="`w-32 h-8 absolute -top-[8px] ${subIndex % 2 != 0 ? 'right-[23px]' : 'left-[23px]'} `"
  114. >
  115. <img class="w-full h-full" src="~/assets/img/chat/polygon.svg" alt="" />
  116. </div>
  117. <template v-for="(el, index2) in subItem.children" :key="`ss${index2}`">
  118. <div
  119. @click="childrenHandleTypeClick(el)"
  120. :class="`${childrenIndex == el.id ? 'text-[#FF9300] border-[#FF9300] border-[2px] bg-[#FF9300]/[0.08]' : 'bg-white border text-black-6'} py-5 mr-8 mb-12 rounded-[4px] text-sm box-border px-12`"
  121. >
  122. {{ el.typeName }}
  123. </div>
  124. </template>
  125. </div>
  126. </template>
  127. </van-row>
  128. </div> -->
  129. <div class="w-full px-16 py-20 card-list">
  130. <template v-for="(subItem, subIndex) in groupTypeList" :key="subItem?.id">
  131. <div
  132. :class="` h-40 mb-4 relative ${showIndex == subItem.id ? ' border-[#FF9300] border-2 shadow-[0_4px_4px_0px_rgba(0,0,0,0.1)]' : ''} pl-22 flex justify-start items-center shrink-0 text-xl text-black-6 font-semibold bg-[#F7F8FA] rounded-md`"
  133. @click="handleTypeClick(subItem)"
  134. >
  135. <div class="w-24 h-24 border shrink-0 mr-6">
  136. <img
  137. class="w-full h-full object-cover"
  138. :src="item?.typeIcon ? item?.typeIcon : city"
  139. alt=""
  140. />
  141. </div>
  142. <span class="line-clamp-1">
  143. {{ subItem.typeName }}
  144. </span>
  145. <div
  146. v-if="showIndex == subItem.id"
  147. class="absolute rounded-t-md square1 -top-2 -left-2 z-1"
  148. ></div>
  149. <div v-if="showIndex == subItem.id" class="w-14 h-14 absolute top-0 left-0 z-2">
  150. <img class="w-full h-full object-cover" alt="" src="~/assets/img/chat/check.svg" />
  151. </div>
  152. </div>
  153. <div
  154. v-if="showIndex == subItem.id && subItem?.children.length > 0"
  155. class="item__child mb-4 w-full relative flex justify-start box-border flex-wrap pl-21 pt-14 bg-[#F7F7F7] rounded-md"
  156. >
  157. <div
  158. :class="`w-32 h-8 absolute -top-[8px] ${subIndex % 2 != 0 ? 'right-[23px]' : 'left-[23px]'} `"
  159. >
  160. <img class="w-full h-full" src="~/assets/img/chat/polygon.svg" alt="" />
  161. </div>
  162. <template v-for="el in subItem.children" :key="el?.id">
  163. <div
  164. @click="childrenHandleTypeClick(el)"
  165. :class="`${childrenIndex == el.id ? 'text-[#FF9300] border-[#FF9300] border-[2px] bg-[#FF9300]/[0.08]' : 'bg-white border text-black-6'} py-5 mr-8 mb-12 rounded-[4px] text-sm box-border px-12`"
  166. >
  167. {{ el.typeName }}
  168. </div>
  169. </template>
  170. </div>
  171. </template>
  172. </div>
  173. <template #footer>
  174. <div class="w-full px-40 pb-30">
  175. <van-button
  176. style="font-size: 16px"
  177. type="primary"
  178. color="#FF9300"
  179. round
  180. block
  181. @click="show = false"
  182. >
  183. 确认
  184. </van-button>
  185. </div>
  186. </template>
  187. </van-dialog>
  188. <div class="w-full h-72 px-16 pb-24 fixed bottom-0 left-0 box-border">
  189. <van-button
  190. style="font-size: 16px"
  191. type="primary"
  192. native-type="submit"
  193. color="#FF9300"
  194. round
  195. block
  196. @click="handleCreateGroup"
  197. :loading="isSubmiting"
  198. >
  199. 立即创建
  200. </van-button>
  201. </div>
  202. </div>
  203. </template>
  204. <script setup>
  205. import city from '~/assets/img/chat/city-one.svg'
  206. const userInfoStore = useUserInfoStore()
  207. const { userInfo } = storeToRefs(userInfoStore)
  208. const TYPE_TEXT = '未选择'
  209. const groupTypeList = ref([])
  210. const subTypeList = ref([])
  211. definePageMeta({
  212. layout: false
  213. })
  214. const formData = reactive({
  215. createType: '1',
  216. groupName: '',
  217. creatUserId: computed(() => userInfo.value.userId),
  218. description: '',
  219. belongTypeId: ''
  220. })
  221. // 是否群类型的弹窗打开
  222. const show = ref(false)
  223. const showIndex = ref(null)
  224. const groupTypeName = ref(TYPE_TEXT)
  225. const childrenIndex = ref(null)
  226. // 是否个人主页展示
  227. const checked = ref(true)
  228. // 获取群类型
  229. async function getTreeType() {
  230. try {
  231. const { data } = await request('/website/tourGroupType/treeType')
  232. if (Array.isArray(data) && data.length) {
  233. groupTypeList.value = data
  234. } else {
  235. groupTypeList.value = []
  236. }
  237. } finally {
  238. }
  239. }
  240. //
  241. const handleTypeClick = (item) => {
  242. if (showIndex.value == item?.id) {
  243. showIndex.value = null
  244. subTypeList.value = []
  245. } else {
  246. showIndex.value = item.id
  247. subTypeList.value = item.children
  248. }
  249. }
  250. //
  251. const childrenHandleTypeClick = (item) => {
  252. if (childrenIndex.value == item?.id) {
  253. formData.belongTypeId = ''
  254. childrenIndex.value = null
  255. groupTypeName.value = TYPE_TEXT
  256. } else {
  257. formData.belongTypeId = item.id
  258. childrenIndex.value = item.id
  259. groupTypeName.value = item.typeName
  260. }
  261. }
  262. const isSubmiting = ref(false)
  263. // 创建群聊
  264. async function handleCreateGroup() {
  265. try {
  266. isSubmiting.value = true
  267. if (!formData.groupName) {
  268. showToast('请输入群名称')
  269. return
  270. }
  271. if (!formData.description) {
  272. showToast('请输入群描述')
  273. return
  274. }
  275. checked ? (formData.isPublic = 1) : (formData.isPublic = 0)
  276. const { data } = await request('/website/tourGroup/createGroup', {
  277. method: 'post',
  278. body: {
  279. ...formData
  280. }
  281. })
  282. if (data) {
  283. showSuccessToast('群聊创建成功')
  284. // navigateTo({
  285. // path: '/profile/my-news',
  286. // replace: true
  287. // })
  288. navigateTo({
  289. path: '/chat/group',
  290. query: {
  291. groupId: data
  292. },
  293. replace: true
  294. })
  295. }
  296. } finally {
  297. isSubmiting.value = false
  298. }
  299. }
  300. onMounted(() => {
  301. getTreeType()
  302. })
  303. useSeoMeta({
  304. title: '我的消息'
  305. })
  306. </script>
  307. <style lang="scss" scoped>
  308. ::v-deep .van-dialog__header {
  309. padding-top: 0;
  310. }
  311. .card-list {
  312. display: grid;
  313. grid-template-columns: repeat(2, 1fr);
  314. grid-auto-flow: dense; /* 确保项目会填充所有的网格单元 */
  315. grid-gap: 12px;
  316. .item__child {
  317. grid-column: span 2;
  318. }
  319. .square1 {
  320. width: 0;
  321. height: 0;
  322. border-bottom: 28px solid transparent; /* 创建三角形 */
  323. border-left: 28px solid #ff9300; /* 三角形的颜色 */
  324. }
  325. }
  326. </style>