index.vue 8.1 KB

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