liveDetail.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. <template>
  2. <view class="container">
  3. <trtc-room ref="trtc-component" :config="rtcConfig"> </trtc-room>
  4. <view class="top_box" :style="{ top: btn_top, left: btn_left}">
  5. <image class="top_box_img" :src="head_img" mode="aspectFill"></image>
  6. <view class="top_box_text">
  7. <view class="left_box"><text class="text_box_top">{{title}}</text><text class="text_box_bottom" >{{user_name}}</text></view>
  8. <view class="tx_btn" @click="subTap()"><text class="iconfont tixingn">{{tixing_str}}</text></view>
  9. </view>
  10. </view>
  11. <view class="popup-open" @click="showGoods()">
  12. <view class="iconfont iconzhibo-shangpin"></view>
  13. </view>
  14. <uni-popup ref="popup" type="bottom">
  15. <view class="popup-box">
  16. <view class="popup-close" @click="closeGoods()">收起</view>
  17. <scroll-view scroll-y="true" class="good-box">
  18. <view class="goods-row" v-for="(item, index) in goodsList" :key="index" @click="goToGoodDetails(item)">
  19. <image class="goods-img" :src="item.imgPath" mode="aspectFill"></image>
  20. <view class="goods-info">
  21. <view class="goods-name">{{item.productName}}</view>
  22. <view class="goods-sales">{{item.sellCount}}人付款</view>
  23. <view class="goods-number">
  24. <text class="goods-icon">¥</text>
  25. <text class="goods-spec">{{item.bizPrice}}</text>
  26. <text class="price">原价:{{item.originalPrice}}</text>
  27. </view>
  28. </view>
  29. <view class="more-button">
  30. <view class="iconfont icongengduo"></view>
  31. </view>
  32. </view>
  33. </scroll-view>
  34. </view>
  35. </uni-popup>
  36. <u-top-tips ref="uTips"></u-top-tips>
  37. <view class="talk_box" :style="{ left: btn_left}">
  38. <view class="line_box" v-for="(item, index) in text_list" :key="index">
  39. <view class="talk_box_timp" >
  40. <image :src="item.description"></image>
  41. <text>{{item.extension}}:{{item.data}}</text>
  42. </view>
  43. </view>
  44. </view>
  45. <view class="talk_input" :style="{ left: btn_left}">
  46. <view class="talk_box_timp" style="width: 60%;height: 80rpx;padding: 10rpx;">
  47. <input placeholder="说点什么..." placeholder-style="color:#fff" :value="send_value" type='text' confirm-type="send" @confirm="sendsms_fun" @input="getVal"/>
  48. </view>
  49. </view>
  50. </view>
  51. </template>
  52. <script>
  53. const NET = require('@/utils/request')
  54. const API = require('@/config/api')
  55. import {
  56. genTestUserSig,
  57. setData
  58. } from "@/pagesGood/debug/GenerateTestUserSig";
  59. import trtcRoom from "@/pagesGood/trtc-room/trtc-room";
  60. export default {
  61. components: {
  62. trtcRoom
  63. },
  64. data() {
  65. return {
  66. text_list:[
  67. //{description:'https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJc8RKCs43SAHMkh1bxVR3WTCr0MRkPCQkhlPrhA6Zhib1l5BouSIW0g6su8ia1cNVKhC2IZmM5humA/132',extension:'1111',data:'323123'}
  68. ],
  69. first_gx:true,
  70. send_value:'',
  71. videoType: '',
  72. roomID: '',
  73. userID: '',
  74. goodsList: [],
  75. rtcConfig: {
  76. sdkAppID: '',
  77. // 必要参数 开通实时音视频服务创建应用后分配的 sdkAppID
  78. userID: '',
  79. // 必要参数 用户 ID 可以由您的帐号系统指定
  80. userSig: '',
  81. // 必要参数 身份签名,相当于登录密码的作用
  82. template: '' // 必要参数 组件模版,支持的值 1v1 grid custom ,注意:不支持动态修改, iOS 不支持 pusher 动态渲染
  83. },
  84. showTipToast: false,
  85. options: {},
  86. btn_left:0,
  87. btn_top:0,
  88. title:"888",
  89. user_name:'0',
  90. head_img:"../static/images/loginLogo.png",
  91. liveId: '',
  92. tixing_str:'直播提醒'
  93. }
  94. },
  95. onLoad(options) {
  96. this.videoType = options.videoType
  97. this.roomID = options.roomId
  98. this.userID = "1323565280579813376"
  99. this.liveId = options.liveId
  100. NET.request(API.isSubscribed + options.liveId, {}, 'GET').then(res => {
  101. if(res.data==false){
  102. this.tixing_str="直播提醒"
  103. }else{
  104. this.tixing_str="取消提醒"
  105. }
  106. //this.goodsList = res.data
  107. }).catch(res => {
  108. })
  109. },
  110. onReady() {
  111. var that=this;
  112. // NET.request(API.getLiveGoodsDetail + options.liveId, {}, 'GET').then(res => {
  113. // this.goodsList = res.data
  114. // }).catch(res => {
  115. // this.$refs.uTips.show({
  116. // title: '获取商品列表失败',
  117. // type: 'warning',
  118. // })
  119. // })
  120. let menuButtonObject = wx.getMenuButtonBoundingClientRect();
  121. wx.getSystemInfo({
  122. success: res => {
  123. this.setData({
  124. btn_left: res.windowWidth - menuButtonObject.right+'px',
  125. btn_top:menuButtonObject.top+menuButtonObject.height+14+'rpx',
  126. head_img:uni.getStorageSync("liveImgUrl"),
  127. title:uni.getStorageSync("liveName"),
  128. })
  129. },
  130. })
  131. wx.setKeepScreenOn({
  132. keepScreenOn: true
  133. }); // 获取 rtcroom 实例
  134. this.trtcComponent = this.$refs['trtc-component']; // 监听TRTC Room 关键事件
  135. this.bindTRTCRoomEvent(); // 将String 类型的 true false 转换成 boolean
  136. this.options.localAudio = false; //开启麦克风
  137. this.options.localVideo = false; //开启视频
  138. this.enterRoom({
  139. roomID: Number(this.roomID),
  140. userID: uni.getStorageSync("userData").userId,
  141. template: "grid",
  142. });
  143. },
  144. methods: {
  145. getVal(e) {
  146. let {
  147. value
  148. } = e.detail
  149. this.send_value = value;
  150. },
  151. subTap: function() {
  152. let that = this;
  153. if(that.tixing_str=="取消提醒"){
  154. var post_data={liveId:that.liveId,mid:uni.getStorageSync("userData").userId}
  155. post_data.isDelete=0;
  156. NET.request(API.subscribeLive, post_data, 'POST').then(res => {
  157. if(that.tixing_str=="取消提醒"){
  158. that.tixing_str="直播提醒"
  159. }else{
  160. that.tixing_str="取消提醒"
  161. }
  162. //this.goodsList = res.data
  163. }).catch(res => {
  164. })
  165. }else{
  166. wx.requestSubscribeMessage({
  167. tmplIds: ['y0X1cZfbEMg7HdTGN_bW8v7TKeI3M0CHSVTY1zStIXM'],
  168. success(res) {
  169. if(res.y0X1cZfbEMg7HdTGN_bW8v7TKeI3M0CHSVTY1zStIXM=="accept"){
  170. var post_data={liveId:that.liveId,mid:uni.getStorageSync("userData").userId}
  171. if(that.tixing_str=="直播提醒"){
  172. post_data.isDelete=1;
  173. }else{
  174. post_data.isDelete=0;
  175. }
  176. NET.request(API.subscribeLive, post_data, 'POST').then(res => {
  177. if(that.tixing_str=="取消提醒"){
  178. that.tixing_str="直播提醒"
  179. }else{
  180. that.tixing_str="取消提醒"
  181. }
  182. //this.goodsList = res.data
  183. }).catch(res => {
  184. })
  185. }else{
  186. console.log('444', res);
  187. }
  188. //console.log('1111', res);
  189. },
  190. fail(res) {
  191. console.log('2222', res);
  192. }
  193. })
  194. }
  195. },
  196. // 打开弹窗
  197. showGoods() {
  198. this.$refs.popup.open()
  199. NET.request(API.getLiveGoodsDetail + this.liveId, {}, 'GET').then(res => {
  200. this.goodsList = res.data
  201. }).catch(res => {
  202. this.$refs.uTips.show({
  203. title: '获取商品列表失败',
  204. type: 'warning',
  205. })
  206. })
  207. },
  208. // 关闭弹窗
  209. closeGoods() {
  210. this.$refs.popup.close()
  211. },
  212. sendsms_fun:function(){
  213. /*this.trtcComponent.sendGroupTextMessage({
  214. roomID: Number(this.data.roomID), // 房间 ID
  215. message: this.data.title,
  216. })*/
  217. if(Number(wx.getStorageSync('jy_time'))>(new Date()).valueOf()){
  218. wx.showToast({
  219. title: "禁言中,不能发言",
  220. icon: 'none'
  221. })
  222. return false;
  223. }
  224. this.trtcComponent.sendGroupCustomMessage({
  225. roomID: Number(this.roomID), // 房间 ID
  226. payload: {
  227. data: this.send_value,
  228. description: uni.getStorageSync("userData").headImage,
  229. extension: uni.getStorageSync("userData").userName
  230. }
  231. })
  232. var that=this;
  233. console.log("new_log",uni.getStorageSync("userData"))
  234. var temp={
  235. data: this.send_value,
  236. description: uni.getStorageSync("userData").headImage,
  237. extension: uni.getStorageSync("userData").userName
  238. };
  239. var data=that.text_list;
  240. if(data.length==5){
  241. data.shift();
  242. }
  243. data.push(temp);
  244. this.setData({
  245. text_list:data,
  246. });
  247. this.setData({
  248. send_value:'',
  249. });
  250. },
  251. goToGoodDetails(item) {
  252. uni.navigateTo({
  253. url: '/pagesGood/goodDetails?goodId=' + item.productId
  254. });
  255. },
  256. setData,
  257. enterRoom: function(params) {
  258. params.template = params.template || '1v1';
  259. params.roomID = params.roomID || 2333;
  260. params.userID = params.userID || new Date().getTime().toString(16);
  261. console.log('* room enterRoom', params);
  262. const Signature = genTestUserSig(params.userID);
  263. params.sdkAppID = Signature.sdkAppID;
  264. params.userSig = Signature.userSig;
  265. this.template = params.template;
  266. this.rtcConfig = {
  267. sdkAppID: params.sdkAppID,
  268. // 您的实时音视频服务创建应用后分配的 sdkAppID
  269. userID: params.userID,
  270. userSig: params.userSig,
  271. template: params.template,
  272. // 1v1 grid custom
  273. debugMode: false,
  274. // 非必要参数,打开组件的调试模式,开发调试时建议设置为 true
  275. // cloudenv: params.cloudenv, // 非必要参数
  276. frontCamera: "front",
  277. enableEarMonitor: false,
  278. enableAutoFocus: true,
  279. localMirror: 'auto',
  280. enableAgc: true,
  281. enableAns: true,
  282. enableMic:false,
  283. enableCamera:false,
  284. encsmall: false ? 1 : 0,
  285. videoWidth: 1280,
  286. videoHeight: 720,
  287. scene: "live",
  288. maxBitrate: 2000,
  289. minBitrate: 1500,
  290. beautyLevel: 9, // 默认开启美颜
  291. enableIM: true, // 用于组件内渲染
  292. showIMPanel: false,
  293. exitIMThrottle: false,
  294. messageContent: '',
  295. messageList: [], // 仅保留10条消息
  296. maxMessageListLength: 10,
  297. messageListScrollTop: 0
  298. };
  299. this.setData({
  300. rtcConfig: this.rtcConfig
  301. }, () => {
  302. // roomID 取值范围 1 ~ 4294967295
  303. this.trtcComponent.enterRoom({
  304. roomID: params.roomID
  305. }).then(() => {
  306. if (this.template === 'custom') {
  307. // 设置推流端视窗的坐标和尺寸
  308. this.trtcComponent.setViewRect({
  309. userID: params.userID,
  310. xAxis: '480rpx',
  311. yAxis: '160rpx',
  312. width: '240rpx',
  313. height: '320rpx'
  314. });
  315. }
  316. }).catch(res => {
  317. console.error('* room joinRoom 进房失败:', res);
  318. });
  319. });
  320. },
  321. setNum:function(){
  322. var that=this;
  323. let promise = that.trtcComponent.tim.getGroupProfile({ groupID: this.roomID+"" });
  324. promise.then(function(imResponse) {
  325. that.setData({
  326. user_name:(Number(imResponse.data.group.memberCount)-1)
  327. })
  328. console.log(imResponse.data.group);
  329. }).catch(function(imError) {
  330. console.warn('getGroupProfile error:', imError); // 获取群详细资料失败的相关信息
  331. });
  332. },
  333. bindTRTCRoomEvent: function() {
  334. const TRTC_EVENT = this.trtcComponent.EVENT;
  335. this.timestamp = []; // 初始化事件订阅
  336. this.trtcComponent.on(TRTC_EVENT.LOCAL_JOIN, event => {
  337. let user_list=this.trtcComponent.getRemoteUserList();
  338. /*this.setData({
  339. user_name:user_list.length
  340. })*/
  341. console.log('* room LOCAL_JOIN', event); // 进房成功,触发该事件后可以对本地视频和音频进行设置
  342. if (this.options.localVideo === true || this.options.template === '1v1') {
  343. //this.trtcComponent.publishLocalVideo();
  344. }
  345. if (this.options.localAudio === true || this.options.template === '1v1') {
  346. //this.trtcComponent.publishLocalAudio();
  347. }
  348. });
  349. this.trtcComponent.on(TRTC_EVENT.LOCAL_LEAVE, event => {
  350. console.log('* room LOCAL_LEAVE', event);
  351. });
  352. this.trtcComponent.on(TRTC_EVENT.ERROR, event => {
  353. console.log('* room ERROR', event);
  354. }); // 远端用户进房
  355. this.trtcComponent.on(TRTC_EVENT.REMOTE_USER_JOIN, event => {
  356. let user_list=this.trtcComponent.getRemoteUserList();
  357. /*this.setData({
  358. user_name:user_list.length
  359. })*/
  360. console.log('* room REMOTE_USER_JOIN --- room.vue', event, this.trtcComponent.getRemoteUserList(), this.template);
  361. this.timestamp.push(new Date()); // 1v1视频通话时限制人数为两人的简易逻辑,建议通过后端实现房间人数管理
  362. // 2人以上同时进行通话请选择网格布局
  363. if (this.template === '1v1' && this.timestamp.length > 1) {
  364. const interval = this.timestamp[1] - this.timestamp[0];
  365. if (interval < 1000) {
  366. // 房间里已经有两个人
  367. this.setData({
  368. showTipToast: true
  369. }, () => {
  370. setTimeout(() => {
  371. this.setData({
  372. showTipToast: false
  373. });
  374. wx.navigateBack({
  375. delta: 1
  376. });
  377. }, 4000);
  378. });
  379. }
  380. }
  381. }); // 远端用户退出
  382. this.trtcComponent.on(TRTC_EVENT.REMOTE_USER_LEAVE, event => {
  383. //if (event.data.userID == this.userID) {
  384. console.log("直播用户退出");
  385. this.$refs.uTips.show({
  386. title: '直播用户退出',
  387. type: 'success',
  388. })
  389. setTimeout(() => {
  390. uni.navigateBack()
  391. }, 3000)
  392. //}
  393. let user_list=this.trtcComponent.getRemoteUserList();
  394. /*this.setData({
  395. user_name:user_list.length
  396. })*/
  397. }); // 远端用户推送视频
  398. this.trtcComponent.on(TRTC_EVENT.REMOTE_VIDEO_ADD, event => {
  399. console.log('* room REMOTE_VIDEO_ADD', event, this.trtcComponent.getRemoteUserList()); // 订阅视频
  400. const userList = this.trtcComponent.getRemoteUserList();
  401. const data = event.data;
  402. if (this.template === '1v1' && (!this.remoteUser || this.remoteUser === data.userID)) {
  403. // 1v1 只订阅第一个远端流
  404. this.remoteUser = data.userID;
  405. this.trtcComponent.subscribeRemoteVideo({
  406. userID: data.userID,
  407. streamType: data.streamType
  408. });
  409. } else if (this.template === 'grid') {
  410. this.trtcComponent.subscribeRemoteVideo({
  411. userID: data.userID,
  412. streamType: data.streamType
  413. });
  414. }
  415. if (this.template === 'custom' && data.userID && data.streamType) {
  416. let index = userList.findIndex(item => {
  417. return item.userID === data.userID;
  418. });
  419. index++;
  420. const y = 320 * index + 160; // 设置远端视图坐标和尺寸
  421. this.trtcComponent.setViewRect({
  422. userID: data.userID,
  423. streamType: data.streamType,
  424. xAxis: '480rpx',
  425. yAxis: y + 'rpx',
  426. width: '240rpx',
  427. height: '320rpx'
  428. });
  429. }
  430. }); // 远端用户取消推送视频
  431. this.trtcComponent.on(TRTC_EVENT.REMOTE_VIDEO_REMOVE, event => {
  432. console.log('* room REMOTE_VIDEO_REMOVE', event, this.trtcComponent.getRemoteUserList());
  433. }); // 远端用户推送音频
  434. this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_ADD, event => {
  435. console.log('* room REMOTE_AUDIO_ADD', event, this.trtcComponent.getRemoteUserList()); // 订阅音频
  436. const data = event.data;
  437. if (this.template === '1v1' && (!this.remoteUser || this.remoteUser === data.userID)) {
  438. this.remoteUser = data.userID;
  439. this.trtcComponent.subscribeRemoteAudio({
  440. userID: data.userID
  441. });
  442. } else if (this.template === 'grid' || this.template === 'custom') {
  443. this.trtcComponent.subscribeRemoteAudio({
  444. userID: data.userID
  445. });
  446. } // 如果不订阅就不会自动播放音频
  447. // this.trtcComponent.subscribeRemoteAudio({ userID: data.userID })
  448. }); // 远端用户取消推送音频
  449. this.trtcComponent.on(TRTC_EVENT.REMOTE_AUDIO_REMOVE, event => {
  450. console.log('* room REMOTE_AUDIO_REMOVE', event, this.trtcComponent.getRemoteUserList());
  451. });
  452. this.trtcComponent.on(TRTC_EVENT.IM_READY, event => {
  453. console.log('* room IM_READY', event)
  454. var that=this;
  455. setTimeout(function(){
  456. if(that.first_gx){
  457. that.first_gx=false;
  458. that.setNum();
  459. }
  460. },1000)
  461. })
  462. this.trtcComponent.on(TRTC_EVENT.IM_MESSAGE_RECEIVED, event => {
  463. var that=this;
  464. if(event.data.data==undefined){
  465. return false;
  466. }
  467. if(event.data.data[0]==undefined){
  468. return false;
  469. }
  470. if(event.data.data[0].type=="TIMCustomElem"){
  471. if(event.data.data[0].payload.description==0||event.data.data[0].payload.description==1||event.data.data[0].payload.description==2||event.data.data[0].payload.description==3){
  472. var user_id=wx.getStorageSync('uid');
  473. if(event.data.data[0].payload.data==user_id){
  474. var jy_time=0;
  475. if(event.data.data[0].payload.description==0){
  476. jy_time=(new Date()).valueOf()+5*60*1000;
  477. }
  478. if(event.data.data[0].payload.description==1){
  479. jy_time=(new Date()).valueOf()+10*60*1000;
  480. }
  481. if(event.data.data[0].payload.description==2){
  482. jy_time=(new Date()).valueOf()+30*60*1000;
  483. }
  484. if(event.data.data[0].payload.description==3){
  485. jy_time=(new Date()).valueOf()+60*60*1000;
  486. }
  487. wx.setStorageSync('jy_time', jy_time)
  488. }
  489. wx.showToast({
  490. title: event.data.data[0].payload.extension,
  491. icon: 'none'
  492. })
  493. }else{
  494. var temp=event.data.data[0].payload;
  495. if(temp.data=="genxin"){
  496. setTimeout(function(){
  497. that.setNum();
  498. },3000)
  499. return false;
  500. }
  501. var data=that.text_list;
  502. if(data.length==5){
  503. data.shift();
  504. }
  505. data.push(temp);
  506. this.setData({
  507. text_list:data,
  508. });
  509. }
  510. }
  511. })
  512. }
  513. },
  514. }
  515. </script>
  516. <style lang="less" scoped>
  517. page {
  518. width: 100%;
  519. height: 100%;
  520. }
  521. .container {
  522. width: 100%;
  523. height: 100;
  524. float: left;
  525. position: relative;
  526. .popup-open {
  527. width: 50px;
  528. height: 50px;
  529. position: fixed;
  530. bottom: 15px;
  531. right: 15px;
  532. background: #52A63A;
  533. border-radius: 50%;
  534. text-align: center;
  535. line-height: 50px;
  536. z-index: 100;
  537. .iconzhibo-shangpin {
  538. color: #FFFFFF;
  539. font-size: 34px;
  540. }
  541. }
  542. .popup-box {
  543. width: 100%;
  544. height: 265px;
  545. float: left;
  546. background-color: #FFFFFF;
  547. border-radius: 15px 15px 0px 0px;
  548. box-sizing: border-box;
  549. padding: 16px 0 0 0;
  550. position: relative;
  551. .popup-close {
  552. width: 100%;
  553. height: 26px;
  554. float: left;
  555. box-sizing: border-box;
  556. padding: 10px 15px 0 15px;
  557. font-size: 15px;
  558. font-family: PingFang SC;
  559. color: #52A63A;
  560. line-height: 16px;
  561. }
  562. .good-box {
  563. width: 100%;
  564. height: calc(100% - 26px);
  565. box-sizing: border-box;
  566. padding: 0 0 10px 0;
  567. overflow: auto;
  568. position: relative;
  569. .goods-row:first-child {
  570. margin-top: 12px;
  571. }
  572. .goods-row {
  573. width: calc(100% - 30px);
  574. height: 104px;
  575. float: left;
  576. background: #FFFFFF;
  577. box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.1);
  578. border-radius: 5px;
  579. overflow: hidden;
  580. margin: 0 15px 10px 15px;
  581. position: relative;
  582. .goods-img {
  583. width: 104px;
  584. height: 104px;
  585. object-fit: cover;
  586. float: left;
  587. margin-right: 15px;
  588. }
  589. .goods-info {
  590. width: calc(100% - 120px);
  591. float: left;
  592. padding-top: 10px;
  593. .goods-name {
  594. width: 100%;
  595. height: 30px;
  596. float: left;
  597. font-size: 15px;
  598. font-family: PingFang SC;
  599. color: #333333;
  600. line-height: 15px;
  601. overflow: hidden;
  602. text-overflow: ellipsis;
  603. display: -webkit-box;
  604. -webkit-line-clamp: 2;
  605. -webkit-box-orient: vertical;
  606. word-wrap: break-word;
  607. }
  608. .goods-sales {
  609. width: 100%;
  610. float: left;
  611. font-size: 12px;
  612. font-family: PingFang SC;
  613. color: #666666;
  614. line-height: 15px;
  615. margin: 4px 0 8px 0;
  616. }
  617. .goods-number {
  618. width: 100%;
  619. height: 24px;
  620. float: left;
  621. white-space: nowrap;
  622. font-family: PingFang SC;
  623. color: #52A63A;
  624. line-height: 24px;
  625. .goods-icon {
  626. font-size: 14px;
  627. }
  628. .goods-spec {
  629. font-size: 24px;
  630. }
  631. .price {
  632. font-size: 12px;
  633. text-decoration: line-through;
  634. color: #A67954;
  635. margin-left: 6px;
  636. }
  637. }
  638. }
  639. .more-button {
  640. width: 24px;
  641. height: 24px;
  642. position: absolute;
  643. right: 16px;
  644. bottom: 16px;
  645. .iconfont {
  646. font-size: 36px;
  647. color: #999999;
  648. }
  649. }
  650. }
  651. }
  652. }
  653. .top_box{
  654. width: auto;
  655. height: 86rpx;
  656. position: absolute;
  657. z-index: 100;
  658. background: rgba(0, 0, 0, 0.4);
  659. -webkit-border-radius: 100px;
  660. border-radius: 100px;
  661. top: 182rpx;
  662. left: 30rpx;
  663. padding-right: 10rpx;
  664. }
  665. .top_box_img{
  666. width: 86rpx;
  667. height: 86rpx;
  668. border-radius: 100rpx;
  669. float: left;
  670. }
  671. .top_box_text{
  672. float: left;
  673. color: #fff;
  674. margin-left: 30rpx;
  675. padding-top: 2rpx;
  676. }
  677. .text_box_top{
  678. font-size: 28rpx;
  679. display: block;
  680. height: 30rpx;
  681. margin-top: 6rpx;
  682. }
  683. .text_box_bottom{
  684. font-size: 22rpx;
  685. margin-top: 10rpx;
  686. }
  687. .tx_btn{
  688. background: #4fa237;
  689. display: inline-block;
  690. height: 70rpx;
  691. margin-top: 5rpx;
  692. border-radius: 60rpx;
  693. line-height: 70rpx;
  694. padding: 0 30rpx;
  695. margin-left: 30rpx;
  696. }
  697. .tx_btn image{
  698. width: 60rpx;
  699. height: 60rpx;
  700. margin-top: 5rpx;
  701. margin-right: 20rpx;
  702. }
  703. .tixingn{
  704. font-size: 34rpx;
  705. display: flex;
  706. }
  707. .tixingn:before {
  708. font-size: 60rpx;
  709. }
  710. .talk_box{
  711. z-index: 10;
  712. position: absolute;
  713. bottom: 170rpx;
  714. left: 0rpx;
  715. }
  716. .line_box{
  717. width:100%
  718. }
  719. .talk_box_timp{
  720. display: inline-block;
  721. border-radius: 60rpx;
  722. background: rgba(0, 0, 0, 0.4);
  723. margin-bottom: 10rpx;
  724. }
  725. .talk_box_timp image{
  726. width: 56rpx;
  727. height: 56rpx;
  728. border-radius: 60rpx;
  729. float: left;
  730. }
  731. .talk_box_timp text{
  732. float: left;
  733. color: #fff;
  734. padding-top: 6rpx;
  735. padding-right: 50rpx;
  736. font-size: 28rpx;
  737. margin-left: 20rpx;
  738. line-height: 45rpx;
  739. }
  740. .talk_input{
  741. z-index: 10;
  742. position: absolute;
  743. bottom: 38rpx;
  744. left: 0rpx;
  745. width:100%
  746. }
  747. .talk_box_timp input{
  748. float: left;
  749. color: #fff;
  750. padding-top: 6rpx;
  751. padding-right: 50rpx;
  752. font-size: 30rpx;
  753. margin-left: 20rpx;
  754. line-height: 45rpx;
  755. line-height: 34rpx;
  756. }
  757. .left_box{
  758. display: inline-block;
  759. }
  760. }
  761. </style>