shareLive.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <template>
  2. <view>
  3. <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption"
  4. :up="upOption">
  5. <view class="live-list">
  6. <view v-for="(item,index) in dataList" :key="index" class="item">
  7. <view class="bottom-box">
  8. <view class="left">
  9. <image class="img" v-if="item.liveImgUrl" :src="item.liveImgUrl"></image>
  10. <text class="ml30 label">{{item.liveName}}</text>
  11. </view>
  12. <view class="btn-box">
  13. <view class="btn pay" @click.stop="showDetail(item)">
  14. 分享直播间
  15. </view>
  16. <u-popup :show="show" @close="close">
  17. <view class="pop">
  18. <!-- 确保这里正确绑定方法 -->
  19. <view class="item" @click="generateAndCopyLink(currentItem)">
  20. <image class="w72 h72 mr20" src="/static/share_link.png"></image>
  21. <text>复制链接</text>
  22. </view>
  23. <view class="item">
  24. <button open-type="share" class="button"
  25. :data-item="JSON.stringify(currentItem)" @click="setShareItem(currentItem)">
  26. <image class="w72 h72 mr20" :src="imgPath+'/userapp/images/weixin1.png'">
  27. </image>
  28. <text>分享直播间</text>
  29. </button>
  30. </view>
  31. <view class="cancel" @click="close">取消</view>
  32. </view>
  33. </u-popup>
  34. </view>
  35. </view>
  36. </view>
  37. </view>
  38. </mescroll-body>
  39. </view>
  40. </template>
  41. <script>
  42. import {
  43. getGotoWxAppLiveLink,
  44. liveShareList
  45. } from '@/api/living.js'
  46. import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
  47. export default {
  48. mixins: [MescrollMixin],
  49. data() {
  50. return {
  51. show: false,
  52. userinfo: {},
  53. currentShareItem: null,
  54. currentItem: null, // 添加当前项存储
  55. // searchKey: "",
  56. mescroll: null,
  57. // 上拉加载的配置
  58. upOption: {
  59. onScroll: true,
  60. use: true, // 是否启用上拉加载; 默认true
  61. page: {
  62. num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
  63. size: 10 // 每页数据的数量,默认10
  64. },
  65. noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
  66. empty: {
  67. icon: '/static/images/no_data.png',
  68. tip: '暂无数据'
  69. }
  70. },
  71. item: null,
  72. companyId: null,
  73. companyUserId: null,
  74. // 列表数据
  75. dataList: [],
  76. };
  77. },
  78. onLoad(options) {
  79. console.log("分享直播间options", options)
  80. var that = this;
  81. // uni.$on('refreshOrder', () => {
  82. that.mescroll.resetUpScroll()
  83. // })
  84. this.companyId = options.companyId;
  85. this.companyUserId = options.companyUserId;
  86. this.userinfo = uni.getStorageSync("userInfo")
  87. },
  88. computed: {
  89. appid() {
  90. return this.$store.state.appid
  91. },
  92. imgPath() {
  93. return this.$store.state.imgpath
  94. }
  95. },
  96. onShareAppMessage() {
  97. const item = this.currentShareItem || {};
  98. console.log("item.liveId", item.liveId)
  99. console.log("this.companyUserId", this.companyUserId)
  100. return {
  101. title: '邀请你来观看直播:' + item.liveName,
  102. path: `/pages_course/living?companyId=${this.companyId}&companyUserId=${this.companyUserId}&liveId=${item.liveId}`,
  103. // imageUrl: this.products.image,
  104. imageUrl: '/static/logo.png',
  105. success(res) {
  106. console.log("分享成功", res);
  107. },
  108. fail(err) {
  109. console.error("分享失败", err);
  110. }
  111. };
  112. },
  113. methods: {
  114. async generateAndCopyLink(item) {
  115. console.log("复制链接被点击>>>", item);
  116. if (!item) {
  117. uni.showToast({
  118. title: '请先选择直播项目',
  119. icon: 'none'
  120. });
  121. return;
  122. }
  123. try {
  124. // 等待获取短链接
  125. const shareLink = await this.getGotoWxAppLiveLink(item);
  126. console.log("获取到的分享链接:", shareLink);
  127. if (!shareLink) {
  128. uni.showToast({
  129. title: '暂无链接',
  130. icon: 'none'
  131. });
  132. return;
  133. }
  134. // 复制到剪贴板
  135. await this.copyToClipboard(shareLink);
  136. this.close()
  137. } catch (error) {
  138. console.error('获取短链接失败:', error);
  139. uni.showToast({
  140. title: '暂无链接',
  141. icon: 'none'
  142. });
  143. }
  144. },
  145. getGotoWxAppLiveLink(item) {
  146. return new Promise((resolve, reject) => {
  147. if (!this.companyId) {
  148. reject(new Error('companyId 不存在'));
  149. return;
  150. }
  151. if (!item || !item.liveId) {
  152. reject(new Error('直播项目信息不完整'));
  153. return;
  154. }
  155. const data = {
  156. appid: this.appid,
  157. linkStr: `/pages_course/living?companyId=${this.companyId}&companyUserId=${this.companyUserId}&liveId=${item.liveId}`
  158. }
  159. console.log("请求短链接参数:", data);
  160. getGotoWxAppLiveLink(data).then(res => {
  161. console.log("短链接口返回:", res);
  162. if (res.code == 200) {
  163. // 正确使用 resolve 返回数据
  164. resolve(res.data || res.result || res.url || res);
  165. } else {
  166. uni.showToast({
  167. icon: 'none',
  168. title: "获取链接失败",
  169. });
  170. reject(new Error('请求失败: ' + (res.message || res.msg || '未知错误')));
  171. }
  172. }).catch(err => {
  173. console.error("获取链接异常:", err);
  174. reject(err);
  175. });
  176. });
  177. },
  178. // 复制到剪贴板
  179. copyToClipboard(text) {
  180. return new Promise((resolve, reject) => {
  181. if (!text) {
  182. uni.showToast({
  183. title: '暂无链接',
  184. icon: 'none'
  185. });
  186. reject(new Error('链接为空'));
  187. return;
  188. }
  189. uni.setClipboardData({
  190. data: text,
  191. success: () => {
  192. uni.showToast({
  193. title: '链接已复制',
  194. icon: 'success'
  195. });
  196. resolve();
  197. },
  198. fail: (err) => {
  199. uni.showToast({
  200. title: '复制失败',
  201. icon: 'none'
  202. });
  203. reject(err);
  204. }
  205. });
  206. });
  207. },
  208. close() {
  209. this.show = false
  210. this.currentItem = null; // 关闭时清空当前项
  211. },
  212. // 记录当前要分享的item
  213. setShareItem(item) {
  214. console.log("setShareItem接收到的参数:", item);
  215. // 如果item是字符串,需要解析;如果是对象,直接使用
  216. if (typeof item === 'string') {
  217. try {
  218. this.currentShareItem = JSON.parse(item);
  219. } catch (error) {
  220. console.error("JSON解析失败:", error);
  221. this.currentShareItem = null;
  222. }
  223. } else if (typeof item === 'object' && item !== null) {
  224. // 如果已经是对象,直接赋值
  225. this.currentShareItem = item;
  226. } else {
  227. console.error("setShareItem接收到无效的参数:", item);
  228. this.currentShareItem = null;
  229. }
  230. console.log("设置后的currentShareItem:", this.currentShareItem);
  231. },
  232. // goSearch(e) {
  233. // this.searchKey = e.detail.value;
  234. // this.mescroll.resetUpScroll()
  235. // },
  236. mescrollInit(mescroll) {
  237. this.mescroll = mescroll;
  238. },
  239. /*下拉刷新的回调 */
  240. downCallback(mescroll) {
  241. mescroll.resetUpScroll()
  242. },
  243. upCallback(page) {
  244. //联网加载数据
  245. var that = this;
  246. if (!this.companyId) return;
  247. var data = {
  248. pageNum: page.num,
  249. pageSize: page.size,
  250. };
  251. liveShareList( data).then(res => {
  252. if (res.code == 200) {
  253. //设置列表数据
  254. if (page.num == 1) {
  255. that.dataList = res.rows;
  256. } else {
  257. that.dataList = that.dataList.concat(res.rows);
  258. }
  259. that.mescroll.endBySize(res.rows.length, res.total);
  260. } else {
  261. uni.showToast({
  262. icon: 'none',
  263. title: "请求失败",
  264. });
  265. that.dataList = null;
  266. that.mescroll.endErr();
  267. }
  268. });
  269. },
  270. showDetail(item) {
  271. console.log(item)
  272. this.currentItem = item; // 存储当前点击的item
  273. this.show = !this.show
  274. },
  275. }
  276. }
  277. </script>
  278. <style lang="scss">
  279. .search-cont {
  280. padding: 16rpx 30rpx;
  281. background-color: #FFFFFF;
  282. .inner {
  283. box-sizing: border-box;
  284. width: 100%;
  285. height: 72rpx;
  286. background: #F7F7F7;
  287. border-radius: 36rpx;
  288. display: flex;
  289. align-items: center;
  290. padding: 0 30rpx;
  291. .icon-search {
  292. width: 28rpx;
  293. height: 28rpx;
  294. margin-right: 20rpx;
  295. }
  296. input {
  297. height: 60rpx;
  298. line-height: 60rpx;
  299. flex: 1;
  300. }
  301. }
  302. }
  303. .live-list {
  304. padding: 20rpx;
  305. .item {
  306. background: #FFFFFF;
  307. border-radius: 16rpx;
  308. padding: 20rpx 30rpx;
  309. margin-bottom: 20rpx;
  310. .bottom-box {
  311. display: flex;
  312. align-items: center;
  313. justify-content: space-between;
  314. .left {
  315. display: flex;
  316. align-items: center;
  317. .img {
  318. width: 140rpx;
  319. height: 140rpx;
  320. }
  321. .label {
  322. max-width: 300rpx;
  323. font-size: 28rpx;
  324. font-weight: 500;
  325. color: #999999;
  326. line-height: 1;
  327. }
  328. .price-box {
  329. display: flex;
  330. align-items: flex-end;
  331. .unit {
  332. font-size: 24rpx;
  333. font-family: PingFang SC;
  334. font-weight: 500;
  335. color: #FF6633;
  336. line-height: 1.2;
  337. margin-right: 4rpx;
  338. }
  339. .num {
  340. font-size: 32rpx;
  341. font-family: PingFang SC;
  342. font-weight: bold;
  343. color: #FF6633;
  344. line-height: 1;
  345. }
  346. }
  347. }
  348. .btn-box {
  349. box-sizing: border-box;
  350. display: flex;
  351. align-items: center;
  352. .btn {
  353. font-size: 28rpx;
  354. color: #F7F7F7;
  355. padding: 12rpx 20rpx;
  356. background-color: #2BC7B9;
  357. font-weight: 500;
  358. border-radius: 15rpx;
  359. }
  360. button {
  361. background-color: transparent !important;
  362. width: 100% !important;
  363. display: flex;
  364. justify-content: flex-start;
  365. padding: 0;
  366. font-size: 30rpx;
  367. }
  368. button:after {
  369. border: none !important;
  370. border-radius: 10px;
  371. box-sizing: border-box;
  372. }
  373. .pop {
  374. display: flex;
  375. flex-direction: column;
  376. background-color: #f1f1f1;
  377. padding: 40rpx 30rpx;
  378. .item {
  379. display: flex;
  380. align-items: center;
  381. padding: 20rpx;
  382. font-size: 30rpx;
  383. }
  384. .cancel {
  385. width: 100%;
  386. height: 100rpx;
  387. line-height: 100rpx;
  388. text-align: center;
  389. background-color: #FFFFFF;
  390. border-radius: 50rpx;
  391. font-weight: 500;
  392. font-size: 34rpx;
  393. }
  394. }
  395. }
  396. }
  397. }
  398. }
  399. </style>