index.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <template>
  2. <div>
  3. <div
  4. class="tui-conversation"
  5. @click="handleClickConv"
  6. @touchstart="handleTouchStart"
  7. @touchend="handleTouchEnd"
  8. >
  9. <div class="header">
  10. <div class="item" @click="group">
  11. <img
  12. src="https://directpurchase-oss-dev.oss-cn-chengdu.aliyuncs.com/wx/static/img/jhq.png"
  13. style="width: 60px; height: 60px"
  14. />
  15. <span class="title">资源聚合群</span>
  16. </div>
  17. <div class="item" @click="book">
  18. <img
  19. src="https://directpurchase-oss-dev.oss-cn-chengdu.aliyuncs.com/wx/static/img/txl.png"
  20. style="width: 60px; height: 60px"
  21. />
  22. <span class="title">通讯录</span>
  23. </div>
  24. <div class="item" @click="interactive">
  25. <div class="count" v-if="hdxsCount > 0">{{ hdxsCount }}</div>
  26. <img
  27. src="https://directpurchase-oss-dev.oss-cn-chengdu.aliyuncs.com/wx/static/img/hdxx.png"
  28. style="width: 60px; height: 60px"
  29. />
  30. <span class="title">互动消息</span>
  31. </div>
  32. <div class="item" @click="serviceNotice">
  33. <div class="count" v-if="fwCount > 0">{{ fwCount }}</div>
  34. <img
  35. src="https://directpurchase-oss-dev.oss-cn-chengdu.aliyuncs.com/wx/static/img/fwtz.png"
  36. style="width: 60px; height: 60px"
  37. />
  38. <span class="title">服务通知</span>
  39. </div>
  40. </div>
  41. <!--
  42. <TUISearch searchType="global" />
  43. <ConversationHeader v-if="isShowConversationHeader" ref="headerRef" />
  44. <ConversationNetwork /> -->
  45. <ConversationList
  46. ref="conversationListDomRef"
  47. class="tui-conversation-list"
  48. @handleSwitchConversation="handleSwitchConversation"
  49. @getPassingRef="getPassingRef"
  50. />
  51. </div>
  52. <div></div>
  53. </div>
  54. </template>
  55. <script lang="ts" setup>
  56. import { TUIStore, StoreName, TUIChatService } from "@tencentcloud/chat-uikit-engine";
  57. import { TUIGlobal } from "@tencentcloud/universal-api";
  58. import { ref, onMounted } from "../../adapter-vue";
  59. // import TUISearch from "../TUISearch/index.vue";
  60. import ConversationList from "./conversation-list/index.vue";
  61. import * as msgApi from "@/api/message/index";
  62. // import ConversationHeader from "./conversation-header/index.vue";
  63. import ConversationNetwork from "./conversation-network/index.vue";
  64. import { onHide, onShow, onLoad } from "@dcloudio/uni-app";
  65. // #ifdef MP-WEIXIN
  66. // uniapp packaged mini-programs are integrated by default, and the default initialization entry file is imported here
  67. // TUIChatKit init needs to be encapsulated because uni vue2 will report an error when compiling H5 directly through conditional compilation
  68. import "./entry.ts";
  69. // #endif
  70. const centerDialogVisibl = ref(false);
  71. const emits = defineEmits(["handleSwitchConversation"]);
  72. const totalUnreadCount = ref(0);
  73. const headerRef = ref<typeof ConversationHeader>();
  74. const conversationListDomRef = ref<typeof ConversationList>();
  75. const touchX = ref<number>(0);
  76. const touchY = ref<number>(0);
  77. const isShowConversationHeader = ref<boolean>(true);
  78. onLoad((option) => {
  79. initCount();
  80. initCountServer();
  81. });
  82. const hdxsCount = ref("");
  83. const fwCount = ref("");
  84. async function initCount() {
  85. let res = await msgApi.default.nuRead(1);
  86. hdxsCount.value = res.data;
  87. }
  88. async function initCountServer() {
  89. let res = await msgApi.default.nuRead(3);
  90. fwCount.value = res.data;
  91. }
  92. TUIStore.watch(StoreName.CONV, {
  93. totalUnreadCount: (count: number) => {
  94. totalUnreadCount.value = count;
  95. },
  96. });
  97. TUIStore.watch(StoreName.CUSTOM, {
  98. isShowConversationHeader: (showStatus: boolean) => {
  99. isShowConversationHeader.value = showStatus !== false;
  100. },
  101. });
  102. const interactive = () => {
  103. TUIGlobal?.navigateTo({
  104. url: "/pages/message/interactive",
  105. });
  106. };
  107. const serviceNotice = () => {
  108. TUIGlobal?.navigateTo({
  109. url: "/pages/message/serviceNotice",
  110. });
  111. };
  112. const group = () => {
  113. TUIGlobal?.navigateTo({
  114. url: "/pages/group/index",
  115. });
  116. };
  117. const book = () => {
  118. TUIGlobal?.navigateTo({
  119. url: "/TUIKit/components/TUIContact/index",
  120. });
  121. };
  122. function getQueryString(name) {
  123. var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  124. var r = window.location.search.substr(1).match(reg);
  125. if (r != null) {
  126. return unescape(r[2]);
  127. }
  128. return null;
  129. }
  130. const spuInfo = ref();
  131. const handleSwitchConversation = async (conversationID: string) => {
  132. let spuId = getQueryString("spuId");
  133. let share = getQueryString("share");
  134. if (spuId && share === "1") {
  135. let res = await msgApi.default.getSupplyDetails({ spuId: spuId });
  136. console.log(res);
  137. spuInfo.value = res.data;
  138. uni.showModal({
  139. title: "提示",
  140. content: `是否确认分享给该好友`,
  141. success: function (res) {
  142. if (res.confirm) {
  143. console.log("用户点击确定");
  144. let promise = TUIChatService.sendCustomMessage({
  145. payload: {
  146. data: JSON.stringify({
  147. saleType: spuInfo.value.saleType,
  148. id: spuInfo.value.id,
  149. // 订单类消息标识字段
  150. businessID: "order",
  151. // 订单标题
  152. title: spuInfo.value.title,
  153. // 订单描述
  154. description: spuInfo.value.spuDesc,
  155. // 订单价格
  156. price: spuInfo.value.lowestPrice,
  157. // 订单 url
  158. link: "https://buy.cloud.tencent.com/avc?ver=ultimate",
  159. // 订单封面图
  160. imageUrl: spuInfo.value.pic,
  161. unit: spuInfo.value.unit,
  162. }),
  163. description: "",
  164. extension: "",
  165. },
  166. });
  167. console.log("promise", promise);
  168. TUIGlobal?.navigateTo({
  169. url: "/TUIKit/components/TUIChat/index",
  170. });
  171. emits("handleSwitchConversation", conversationID);
  172. } else if (res.cancel) {
  173. console.log("用户点击取消");
  174. }
  175. },
  176. });
  177. } else {
  178. TUIGlobal?.navigateTo({
  179. url: "/TUIKit/components/TUIChat/index",
  180. });
  181. emits("handleSwitchConversation", conversationID);
  182. }
  183. };
  184. const closeChildren = () => {
  185. headerRef?.value?.closeChildren();
  186. conversationListDomRef?.value?.closeChildren();
  187. };
  188. const handleClickConv = () => {
  189. closeChildren();
  190. };
  191. onHide(closeChildren);
  192. const handleTouchStart = (e: any) => {
  193. touchX.value = e.changedTouches[0].clientX;
  194. touchY.value = e.changedTouches[0].clientY;
  195. };
  196. const handleTouchEnd = (e: any) => {
  197. const x = e.changedTouches[0].clientX;
  198. const y = e.changedTouches[0].clientY;
  199. let turn = "";
  200. if (x - touchX.value > 50 && Math.abs(y - touchY.value) < 50) {
  201. // Swipe right
  202. turn = "right";
  203. } else if (x - touchX.value < -50 && Math.abs(y - touchY.value) < 50) {
  204. // Swipe left
  205. turn = "left";
  206. }
  207. if (y - touchY.value > 50 && Math.abs(x - touchX.value) < 50) {
  208. // Swipe down
  209. turn = "down";
  210. } else if (y - touchY.value < -50 && Math.abs(x - touchX.value) < 50) {
  211. // Swipe up
  212. turn = "up";
  213. }
  214. // Operate according to the direction
  215. if (turn === "down" || turn === "up") {
  216. closeChildren();
  217. }
  218. };
  219. const getPassingRef = (ref) => {
  220. ref.value = conversationListDomRef.value;
  221. };
  222. </script>
  223. <style lang="less" scoped>
  224. .title {
  225. font-family: PingFangSC, PingFang SC;
  226. font-weight: 500;
  227. font-size: 24rpx;
  228. color: #333333;
  229. margin-top: 10rpx;
  230. }
  231. .count {
  232. position: absolute;
  233. right: 0px;
  234. top: -4px;
  235. width: 18px;
  236. height: 18px;
  237. background: red;
  238. text-align: center;
  239. color: white;
  240. border-radius: 50%;
  241. display: flex;
  242. flex-direction: row;
  243. justify-content: center;
  244. align-items: center;
  245. font-size: 10px;
  246. }
  247. </style>
  248. <style lang="scss" scoped src="./style/index.scss"></style>