AI销管
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

1638 lignes
35 KiB

  1. <template>
  2. <view class="translation" @click="changeEditing(false)">
  3. <view style="width: 690rpx;height: 64rpx;margin: 0 auto;margin-top: 30rpx;background: #F2F2F2;border-radius: 32rpx;
  4. display: flex;align-items: center;" @tap="toKeywordsearch()">
  5. <image style="width: 28rpx;height: 28rpx;margin-left: 30rpx;" src="/static/images/search.png" mode="">
  6. </image>
  7. <text style="margin-left: 10rpx;color: #999999;font-size: 24rpx;">请输入关键字</text>
  8. </view>
  9. <view class="top">
  10. <view class="title">
  11. <view class="call_record_time">{{date}}</view>
  12. <view class="hash" @click="delTheFullText" v-if="CHECKAUTHORITY('ccal')">
  13. 删除案例
  14. </view>
  15. <view class="hash" @click="gotoChat" v-if="commentList.length">
  16. 查看全部评论
  17. </view>
  18. </view>
  19. <view class="call_record_time_one">接待时长 {{alltimeStr}}</view>
  20. <zaudio @checkPlaybackRate="checkPlaybackRate" theme="theme4"></zaudio>
  21. </view>
  22. <scroll-view :scroll-top="scrollTop" lower-threshold='100px' @scrolltolower="ltolower()" upper-threshold='40px'
  23. @scrolltoupper="rolltoupper()" :scroll-into-view="scrollId" scroll-y="true" class="text scroll-Y">
  24. <!-- 音频识别模块 -->
  25. <view>
  26. <!-- 聊天记录-->
  27. <view class="dialog-block" v-for="(dialog,i) in dialogList" :key="i">
  28. <view :id="'dialog'+i" class="fileName">录音文件</view>
  29. <view class="text" :id="'dialog'+csdFileindex+'text'+item.bg"
  30. :class="{active: Math.floor(item.bg/1000) < playNow && Math.floor(item.ed/1000) > playNow, isGreen: item.isShow == 0}"
  31. v-for="(item,index) in dialog.message" :key="index" :data-speaker="item.speaker">
  32. <view class="avatar">
  33. <image v-if="item.isShow == 0"
  34. src="https://static.quhouse.com/b11a7e1ccf914020b3ee23d3e4862637.png" mode="widthFix">
  35. </image>
  36. <text v-else :style="[borderColor(item.speaker)]">{{ item.speaker | toCapital }}</text>
  37. </view>
  38. <view class="content">
  39. <view v-html="item.onebest"></view>
  40. </view>
  41. </view>
  42. </view>
  43. <!-- 点赞 -->
  44. <view class="likeArea" :class="{'liked':isLiked}">
  45. <image
  46. :src="isLiked?'/static/images/recordingManagement/likeActive.png':'/static/images/recordingManagement/like_gray.png'"
  47. mode=""></image>
  48. </view>
  49. <view class="hash" id="hash">
  50. </view>
  51. </view>
  52. </scroll-view>
  53. <!-- 写评价 -->
  54. <view class="bottomArea">
  55. <image class="voice" @click.stop="changeVoiceShow" src="/static/images/recordingManagement/voice.png"
  56. mode=""></image>
  57. <view class="inputArea">
  58. <textarea :value="content" :focus="textareaFocus" type="text" @input="changeContent" :auto-height="true"
  59. class="editor" :class="{'active':editing}" @click.stop="changeEditing(true)" @confirm="sendComment">
  60. </textarea>
  61. <view class="placeholder" :class="{'editing':editing}" v-if="!content && !editing">写评价</view>
  62. <image class="edit" v-if="!editing && content == ''" src="/static/images/recordingManagement/edit.png"
  63. mode=""></image>
  64. </view>
  65. <image class="like" v-if="myId != createUser && !editing" @click="changeLike"
  66. src="/static/images/recordingManagement/like.png" mode=""></image>
  67. <image class="add" @click.stop="uploadImage" v-if="!editing && content == ''"
  68. src="/static/images/recordingManagement/add.png" mode=""></image>
  69. <view class="send" @click="sendComment" v-if="content!=''">
  70. 发送
  71. </view>
  72. </view>
  73. <!-- 评语列表 -->
  74. <u-popup v-model="watchAllCommit" mode="bottom">
  75. <scroll-view style="height: 70vh;" scroll-y>
  76. <view class="boxs">
  77. <view class="chat">
  78. <view class="total">
  79. 全部评论(共{{commentList.length}}条)
  80. </view>
  81. <view class="list">
  82. <view class="message" v-for="(item,index) in commentList" :key="index">
  83. <u-avatar class="avator" size="72"
  84. :src="item.commentPic ||'https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/jjycrm/my/headPicture.png'">
  85. </u-avatar>
  86. <view class="right">
  87. <view class="name">
  88. {{item.commentName||"未知昵称"}}
  89. </view>
  90. <view class="subtitle" v-if="item.commentAutoGraph">
  91. {{item.commentAutoGraph}}
  92. </view>
  93. <view class="answer" v-if="item.replyName">
  94. 回复@{{item.replyName}}
  95. </view>
  96. <view class="content" v-if="item.content">
  97. {{item.content}}
  98. </view>
  99. <view class="pic" v-if="item.picUrl">
  100. <image style="width: 100%;max-width: 240px;" :src="item.picUrl" mode="widthFix">
  101. </image>
  102. </view>
  103. <view class="bottom">
  104. <view class="time">
  105. {{item.createTime}}
  106. </view>
  107. <view class="button" v-if="myId != item.commentUser"
  108. @click.stop="answer(item.commentUser,item.id)">
  109. 回复
  110. </view>
  111. </view>
  112. </view>
  113. </view>
  114. </view>
  115. </view>
  116. <!-- 写评价 -->
  117. <view class="bottomArea">
  118. <image class="voice" @click.stop="changeVoiceShow"
  119. src="/static/images/recordingManagement/voice.png" mode=""></image>
  120. <view class="inputArea">
  121. <textarea :value="content" :focus="textareaFocus" type="text" @input="changeContent"
  122. :auto-height="true" class="editor" :class="{'active':editing}"
  123. @click.stop="changeEditing(true)" @confirm="sendComment">
  124. </textarea>
  125. <view class="placeholder" :class="{'editing':editing}" v-if="!content && !editing">写评价
  126. </view>
  127. <image class="edit" v-if="!editing && content == ''"
  128. src="/static/images/recordingManagement/edit.png" mode=""></image>
  129. </view>
  130. <image class="like" v-if="myId != createUser && !editing" @click="changeLike"
  131. src="/static/images/recordingManagement/like.png" mode=""></image>
  132. <image class="add" @click.stop="uploadImage" v-if="!editing && content == ''"
  133. src="/static/images/recordingManagement/add.png" mode=""></image>
  134. <view class="send" @click="sendComment" v-if="content!=''">
  135. 发送
  136. </view>
  137. </view>
  138. </view>
  139. </scroll-view>
  140. </u-popup>
  141. <!-- 回到顶部 -->
  142. <!-- <view class="backTop" @click.stop="gotoTop()">
  143. <image src="/static/images/backTop.png" mode=""></image>
  144. </view> -->
  145. <!-- 语音输入 -->
  146. <cover-view class="voiceContent" v-if="voiceShow" @click="changeVoiceShow">
  147. <cover-view class="box" @click.stop="" @touchstart="voiceStart" @touchend="voiceEnd">
  148. <cover-view class="center">
  149. <cover-image class="voice" src="/static/images/voice.png" mode="widthFix"></cover-image>
  150. <cover-view class="text">
  151. {{isRecording?'正在输入':'长按语音输入'}}
  152. </cover-view>
  153. </cover-view>
  154. </cover-view>
  155. </cover-view>
  156. </view>
  157. </template>
  158. <script>
  159. var app = getApp();
  160. var util = require("../../../utils/util.js");
  161. var config = require("../../../config");
  162. var plugin = requirePlugin("WechatSI")
  163. let manager = plugin.getRecordRecognitionManager();
  164. import zaudio from '@/components/uniapp-zaudio/zaudio';
  165. export default {
  166. components: {
  167. zaudio
  168. },
  169. data() {
  170. return {
  171. roleindex: 0,
  172. dialogList: [], // 录音对话转移列表
  173. luyinList: [], //录音文件列表
  174. newluyinList: [],
  175. id: "",
  176. customerId: '',
  177. message: "", //聊天记录表
  178. durationTimeStr: "",
  179. autoLoad: true,
  180. playNow: 0,
  181. scrollTop: 0,
  182. scrollId: "",
  183. editing: false,
  184. isLiked: null,
  185. createUser: null,
  186. commentList: [], //评论列表
  187. content: "",
  188. voiceShow: false,
  189. isRecording: false,
  190. answerUserId: null,
  191. answerId: null,
  192. textareaFocus: false,
  193. myId: uni.getStorageSync("weapp_session_userInfo_data").accountId,
  194. audioPlay: false, //当前的播放状态控制
  195. sliderValue: 0, //进度条最小值
  196. end: false,
  197. recordPath: "",
  198. csdFileindex: 0,
  199. date: "", //年月日
  200. alltimeStr: "00:00",
  201. num: 0, //上拉 转写文件下标
  202. Bnum: 0, //下拉 转写文件下标
  203. status: 0,
  204. itemobj: {},
  205. textindex: 0, //下拉 转写文件下标
  206. toptextindex: 0, //上拉 转写文件下标
  207. timer: null,
  208. watchAllCommit: false, // 查看全部评论
  209. ACTION: Symbol('zaudio'), // 唯一值区分每个页面的方法
  210. isPageHide: false, // 是否息屏
  211. duration: '',
  212. nowPlaying: 0, // 当前播放位置
  213. stepPosition: 0, // 需要跳转的播放位置
  214. };
  215. },
  216. onLoad(options) {
  217. this.status = options.status;
  218. this.customerId = options.customerId;
  219. this.itemobj = JSON.parse(options.itemobj);
  220. this.stateisshow = options.stateisshow;
  221. this.getdianzan()
  222. this.getCommentList();
  223. // 当进入页面时调一次接口添加浏览量
  224. this.getView()
  225. let that = this
  226. this.timer = setTimeout(function() {
  227. that.addHot()
  228. }, 30000)
  229. //注意: 不同的回调方法, 相同的业务函数方法名, 不会相互影响;
  230. this.$zaudio.on('stop', this.ACTION, () => {
  231. // console.log('我是强制暂停或关闭小程序音频浮窗触发的')
  232. })
  233. this.$zaudio.on('seek', this.ACTION, (time) => {
  234. this.sliderChangeComplate(this.TIMEEVENT(time))
  235. })
  236. this.$zaudio.on('playing', this.ACTION, (obj) => {
  237. this.duration = obj.duration
  238. this.nowPlaying = obj.current_value
  239. this.TimeUpdate(this.TIMEEVENT(obj.current))
  240. })
  241. uni.$on('THEFULLTEXT2', info => {
  242. this.getluyinList(info)
  243. })
  244. },
  245. onShow() {
  246. //实时渲染当前的播放状态
  247. this.$zaudio.syncRender()
  248. this.initRecord();
  249. if (this.stateisshow == 2) {
  250. var info = this.itemobj;
  251. }
  252. !this.isPageHide && this.getluyinList(info);
  253. },
  254. onHide() {
  255. this.isPageHide = true
  256. },
  257. onUnload() {
  258. uni.$off('THEFULLTEXT2')
  259. //卸载不需要的业务和获取播放状态的业务,提高页面性能
  260. this.$zaudio.off('seek', this.ACTION);
  261. this.$zaudio.off('stop', this.ACTION);
  262. this.$zaudio.off('playing', this.ACTION);
  263. },
  264. methods: {
  265. // 删除优秀案例
  266. delTheFullText() {
  267. uni.showModal({
  268. title: '提示',
  269. content: `确认删除该案例吗?`,
  270. showCancel: true,
  271. cancelText: '取消',
  272. confirmText: '确认删除',
  273. confirmColor: "#FA3534",
  274. success: res => {
  275. console.log(res)
  276. if (res.confirm) {
  277. this.delATD()
  278. }
  279. }
  280. })
  281. },
  282. // 优秀案例删除
  283. delATD() {
  284. this.$u.get('/addtodigest/delATD', { carId: this.customerId }).then(res => {
  285. console.log(res)
  286. // if ()
  287. uni.showToast({
  288. title: '操作成功',
  289. icon: 'none',
  290. duration: 2000
  291. });
  292. setTimeout(() => {
  293. uni.navigateBack()
  294. }, 2000)
  295. }).catch(e => {
  296. uni.showToast({
  297. title: e.data.message,
  298. icon: 'none',
  299. duration: 2000
  300. });
  301. })
  302. },
  303. borderColor(index) {
  304. let obj = {
  305. color: '',
  306. borderRadius: '',
  307. border: ''
  308. }
  309. switch (index) {
  310. case 1:
  311. obj.color = '#E6625B';
  312. obj.borderRadius = '8rpx';
  313. obj.border = '2rpx solid #E6625B';
  314. break;
  315. case 2:
  316. obj.color = '#FF981E';
  317. obj.borderRadius = '8rpx';
  318. obj.border = '2rpx solid #FF981E';
  319. break;
  320. case 3:
  321. obj.color = '#F6BD16';
  322. obj.borderRadius = '8rpx';
  323. obj.border = '2rpx solid #F6BD16';
  324. break;
  325. case 5:
  326. obj.color = '#4980C8';
  327. obj.borderRadius = '8rpx';
  328. obj.border = '2rpx solid #4980C8';
  329. break;
  330. case 6:
  331. obj.color = '#60CBEC';
  332. obj.borderRadius = '8rpx';
  333. obj.border = '2rpx solid #60CBEC';
  334. break;
  335. case 7:
  336. obj.color = '##FF981E';
  337. obj.borderRadius = '8rpx';
  338. obj.border = '2rpx solid #FF981E';
  339. break;
  340. case 8:
  341. obj.color = '#4F861E';
  342. obj.borderRadius = '8rpx';
  343. obj.border = '2rpx solid #4F861E';
  344. break;
  345. default:
  346. obj.color = '#9F61C8';
  347. obj.borderRadius = '8rpx';
  348. obj.border = '2rpx solid #9F61C8';
  349. break;
  350. }
  351. return obj
  352. },
  353. toKeywordsearch() {
  354. uni.navigateTo({
  355. url: '/pages/learning/Thefulltext/search?customerId=' + this.customerId + "&status=" + this
  356. .status + "&skpl=" + "2" + '&UpDateEvent=THEFULLTEXT2'
  357. })
  358. },
  359. getView() {
  360. this.$u.get('/addtodigest/addPageviews', {
  361. id: this.customerId
  362. })
  363. .then(res => {
  364. // console.log(res)
  365. })
  366. },
  367. addHot() {
  368. this.$u.post('/zkstudyrecord', {
  369. targetId: this.customerId
  370. })
  371. .then(res => {
  372. // console.log(res)
  373. })
  374. },
  375. TimeUpdate(currentTime) {
  376. this.playNow = Number(currentTime)
  377. if (this.dialogList.length == 0) {
  378. return
  379. } else {
  380. const message = this.dialogList[0].message;
  381. if (!message) return
  382. for (let i = 0; i < message.length; i++) {
  383. if ((Math.floor(message[i].bg / 1000) <= this.playNow && this.playNow < Math.floor(message[i].ed /
  384. 1000))) {
  385. this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg;
  386. break;
  387. }
  388. if (i < message.length - 1 && Math.floor(message[i].ed / 1000) < this.playNow && this.playNow <
  389. Math.floor(message[i + 1].bg / 1000)) {
  390. this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg;
  391. break;
  392. }
  393. }
  394. }
  395. this.$forceUpdate()
  396. },
  397. //下一页
  398. ltolower() {
  399. var lengthcz = this.newluyinList.length - 1;
  400. if (this.textindex >= lengthcz) {
  401. uni.showToast({
  402. title: '到底了',
  403. icon: 'none',
  404. duration: 2000
  405. });
  406. return
  407. } else {
  408. this.textindex = this.textindex + 1;
  409. this.newluyinList[this.textindex].message.forEach(item => {
  410. this.dialogList[0].message.push(item)
  411. })
  412. }
  413. },
  414. //上一页
  415. rolltoupper() {
  416. if (this.toptextindex == 0) {
  417. // uni.showToast({
  418. // title: '到头了',
  419. // duration: 2000
  420. // });
  421. return
  422. } else {
  423. if (this.dialogList[0] == undefined) {
  424. return
  425. } else {
  426. this.toptextindex = this.toptextindex - 1;
  427. let reverselist = this.newluyinList[this.toptextindex].message;
  428. let runlist = reverselist.reverse();
  429. runlist.forEach(item => {
  430. this.dialogList[0].message.unshift(item)
  431. })
  432. }
  433. }
  434. // console.log("上一页", this.toptextindex)
  435. },
  436. //获取点赞列表isLiked likegetLike
  437. getdianzan() {
  438. this.$u.get(config.service.likegetLike, {
  439. targetId: this.customerId
  440. }).then(data => {
  441. this.isLiked = data.like;
  442. }).catch(e => {
  443. uni.hideLoading();
  444. })
  445. },
  446. // 获取评论列表
  447. getCommentList() {
  448. const that = this;
  449. util.getRequestPromise(config.service.cmmentList + '?targetId=' + this.customerId, {}, false, "GET").then(
  450. data => {
  451. let tmp = data;
  452. tmp.reverse();
  453. that.commentList = tmp;
  454. });
  455. },
  456. // 获取录音记录列表
  457. getluyinList(info) {
  458. const parames = {
  459. pageNum: 1,
  460. pageSize: 100,
  461. query: {
  462. customerId: this.customerId
  463. }
  464. }
  465. this.$u.post("/corpus/findByPage", parames).then(res => {
  466. if (res && res.length) {
  467. let alltime = res[0].recordDuration;
  468. this.alltimeStr = this.getTime(alltime)
  469. if (info.bg != 0) {
  470. this.luyinList = res;
  471. this.recordPath = res[0].recordPath
  472. this.date = res[0].receptionTime;
  473. this.getCorpusAnalysis(info);
  474. this.stepPlay(Math.floor(info.bg / 1000))
  475. } else {
  476. this.luyinList = res;
  477. this.recordPath = res[0].recordPath
  478. this.date = res[0].receptionTime;
  479. this.getCorpusAnalysis(info);
  480. this.zyAudio()
  481. }
  482. }
  483. })
  484. },
  485. //搜索跳转
  486. adasdasdasd(e) {
  487. this.stepPlay(e)
  488. },
  489. // 获取转义后的对话结果
  490. getCorpusAnalysis(info) {
  491. this.dialogList = [];
  492. let obj = {
  493. corpusId: this.luyinList[this.csdFileindex].id,
  494. bg: info.bg,
  495. speaker: this.roleindex,
  496. }
  497. this.$u.get(config.service.getCorpusAnal, obj).then((data) => {
  498. let jsonInfo = JSON.parse(data.audioContent);
  499. //上拉标记点
  500. this.textindex = data.index;
  501. //下拉标记点
  502. this.toptextindex = data.index;
  503. jsonInfo.forEach(item => {
  504. item.message = JSON.parse(item.onebest)
  505. item.backindex = this.csdFileindex;
  506. if (info.onebest) {
  507. item.message.forEach(che => {
  508. if (che.onebest == info.onebest) {
  509. che.onebest =
  510. `<font style='color: red'>${che.onebest}</font>`;
  511. }
  512. })
  513. }
  514. })
  515. this.newluyinList = jsonInfo;
  516. this.dialogList.push(jsonInfo[this.textindex]);
  517. this.adasdasdasd(Math.floor(info.bg / 1000))
  518. })
  519. },
  520. getTime(time) {
  521. return util.formatSecond(time)
  522. },
  523. //音频前进回退
  524. sliderChangeComplate(currentTime) {
  525. let platetime = currentTime * 1000;
  526. this.dialogList = []
  527. this.$u.get(config.service.fastForward, {
  528. corpusId: this.luyinList[this.csdFileindex].id,
  529. bg: platetime
  530. }).then(data => {
  531. this.textindex = data.index;
  532. this.toptextindex = data.index;
  533. this.dialogList.push(this.newluyinList[data.index])
  534. if (this.$zaudio.paused) {
  535. this.$zaudio.operate()
  536. }
  537. })
  538. },
  539. formatTime(num) {
  540. //格式化时间格式
  541. num = num.toFixed(0);
  542. let second = num % 60;
  543. if (second < 10) second = '0' + second;
  544. let min = Math.floor(num / 60);
  545. if (min < 10) min = '0' + min;
  546. return min + ":" + second;
  547. },
  548. changeVoiceShow() {
  549. this.voiceShow = !this.voiceShow;
  550. },
  551. voiceStart() {
  552. manager.start({
  553. lang: "zh_CN"
  554. });
  555. },
  556. voiceEnd() {
  557. // uni.showToast();
  558. if (this.isRecording) {
  559. uni.showLoading({
  560. title: "识别中"
  561. })
  562. }
  563. this.voiceShow = false;
  564. this.isRecording = false;
  565. manager.stop();
  566. },
  567. // 语音初始化
  568. initRecord() {
  569. const that = this;
  570. manager.onStart = function(res) {
  571. that.isRecording = true;
  572. // this.voiceState = "onStart:" + res.msg + "正在录音"
  573. };
  574. //有新的识别内容返回,则会调用此事件
  575. manager.onRecognize = (res) => {
  576. // console.log('ing' + res.result);
  577. }
  578. // 识别结束事件
  579. manager.onStop = (res) => {
  580. uni.hideLoading();
  581. let newText = that.content + res.result;
  582. if (newText.length > 140) {
  583. newText = newText.substring(0, 140)
  584. }
  585. that.content = newText;
  586. that.textareaFocus = true;
  587. }
  588. // 识别错误事件
  589. manager.onError = (res) => {
  590. uni.hideLoading();
  591. }
  592. },
  593. changeContent(e) {
  594. this.content = e.detail.value;
  595. },
  596. answer(userId, tid) {
  597. this.answerId = tid;
  598. this.answerUserId = userId;
  599. this.editing = true;
  600. this.textareaFocus = true;
  601. },
  602. // 保存评论
  603. sendComment() {
  604. if (this.content == "") {
  605. uni.showToast({
  606. icon: "none",
  607. title: "请输入标题"
  608. })
  609. return;
  610. }
  611. let parames = {
  612. targetId: this.customerId,
  613. content: this.content,
  614. commentType: 1
  615. };
  616. if (this.answerUserId) {
  617. parames.replyCommentId = this.answerId;
  618. parames.replyUser = this.answerUserId;
  619. }
  620. const that = this;
  621. util.getRequestPromise(config.service.saveCmment, parames, false).then(data => {
  622. that.getCommentList();
  623. uni.showToast({
  624. title: "评论成功",
  625. icon: "none"
  626. })
  627. that.textareaFocus = false;
  628. that.content = "";
  629. });
  630. },
  631. uploadImage() {
  632. const that = this;
  633. var parames = {
  634. targetId: that.customerId,
  635. commentType: 1
  636. };
  637. if (this.answerUserId) {
  638. parames.replyCommentId = this.answerId;
  639. parames.replyUser = this.answerUserId;
  640. }
  641. uni.chooseImage({
  642. count: 1, //默认9
  643. sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  644. sourceType: ['album', 'camera'],
  645. success: function(res) {
  646. uni.showLoading({
  647. title: "上传中"
  648. })
  649. uni.uploadFile({
  650. url: config.service.saveCmmentUpload,
  651. filePath: res.tempFilePaths[0],
  652. name: 'file',
  653. header: {
  654. 'Authorization': 'Bearer ' + uni.getStorageSync(
  655. 'weapp_session_login_data').token
  656. },
  657. formData: parames,
  658. success: (uploadFileRes) => {
  659. that.getCommentList();
  660. uni.hideLoading();
  661. uni.showToast({
  662. icon: "none",
  663. title: "上传成功"
  664. })
  665. // console.log(uploadFileRes.data);
  666. }
  667. });
  668. }
  669. });
  670. },
  671. changeLike() {
  672. uni.showLoading({
  673. title: "请求中",
  674. mask: true
  675. })
  676. if (this.isLiked) {
  677. this.cancelLike();
  678. } else {
  679. this.saveLike();
  680. }
  681. },
  682. // 点赞
  683. saveLike() {
  684. const that = this;
  685. util.getRequestPromise(config.service.saveLike, {
  686. targetId: this.customerId
  687. }, false).then(data => {
  688. that.isLiked = true;
  689. uni.hideLoading();
  690. uni.showToast({
  691. icon: "none",
  692. title: "点赞成功"
  693. })
  694. });
  695. },
  696. // 取消点赞
  697. cancelLike() {
  698. const that = this;
  699. util.getRequestPromise(config.service.cancelLike, {
  700. targetId: this.customerId
  701. }, false).then(data => {
  702. that.isLiked = false;
  703. uni.hideLoading();
  704. uni.showToast({
  705. icon: "none",
  706. title: "取消点赞成功"
  707. })
  708. });
  709. },
  710. // 查看全部评论
  711. gotoChat() {
  712. this.watchAllCommit = true
  713. },
  714. gotoTop() {
  715. this.scrollId = null;
  716. this.$nextTick(() => {
  717. this.scrollId = "top";
  718. })
  719. },
  720. changeEditing(type) {
  721. this.editing = type;
  722. this.answerId = null;
  723. this.answerUserId = null;
  724. this.textareaFocus = false;
  725. },
  726. // 迅速切换音频源并切换回来
  727. checkPlaybackRate() {
  728. this.stepPosition = this.nowPlaying
  729. //
  730. let data = [{
  731. src: 'https://static.quhouse.com/record/prop/2022-12-13/1670905992910-00066.mp3',
  732. title: '录音音频',
  733. singer: '',
  734. coverImgUrl: ''
  735. }]
  736. this.$zaudio.setAudio(data)
  737. //渲染第一首音频
  738. this.$zaudio.setRender(0)
  739. if (!this.refresh) {
  740. setTimeout(() => {
  741. this.$zaudio.operate()
  742. }, 150)
  743. }
  744. setTimeout(() => {
  745. this.zyAudio()
  746. }, 500)
  747. },
  748. //录音实例
  749. zyAudio() {
  750. let data = [{
  751. src: this.recordPath,
  752. title: '录音音频',
  753. singer: '',
  754. coverImgUrl: ''
  755. }]
  756. this.$zaudio.setAudio(data)
  757. //渲染第一首音频
  758. this.$zaudio.setRender(0)
  759. if (this.stepPosition != 0) {
  760. setTimeout(() => {
  761. this.stepPlay(this.stepPosition)
  762. }, 1500)
  763. }
  764. },
  765. // 跳转指定位置播放
  766. stepPlay(t) {
  767. this.$zaudio.seek(t)
  768. if (this.$zaudio.paused) {
  769. this.$zaudio.operate()
  770. }
  771. }
  772. }
  773. };
  774. </script>
  775. <style lang="scss" scoped>
  776. .biaoqiantom {
  777. background-color: #008EF2;
  778. color: #FFFFFF;
  779. border: none;
  780. }
  781. .boxs {
  782. min-height: 100%;
  783. display: flex;
  784. flex-direction: column;
  785. .chat {
  786. flex-grow: 1;
  787. }
  788. .bottomArea {
  789. flex-shrink: 0;
  790. position: sticky;
  791. bottom: 0;
  792. }
  793. }
  794. // 表单
  795. .tian-view {
  796. width: 570rpx;
  797. background-color: #FFFFFF;
  798. border-bottom: 1px solid #ededee;
  799. display: flex;
  800. min-height: 96rpx;
  801. .tian-view-t1 {
  802. width: 20rpx;
  803. font-size: 34rpx;
  804. height: 34rpx;
  805. line-height: 110rpx;
  806. letter-spacing: 0px;
  807. color: red;
  808. }
  809. .tian-view-t2 {
  810. width: 30%;
  811. min-height: 96rpx;
  812. line-height: 96rpx;
  813. font-size: 34rpx;
  814. color: #333;
  815. }
  816. .tian-view-t3 {
  817. width: 61%;
  818. padding-top: 31rpx;
  819. padding-bottom: 31rpx;
  820. display: flex;
  821. .tian-input {
  822. width: 98%;
  823. font-size: 34rpx;
  824. border: none;
  825. }
  826. }
  827. }
  828. .zhezhoa {
  829. position: fixed;
  830. top: 0;
  831. left: 0;
  832. z-index: 999;
  833. width: 100%;
  834. height: 100vh;
  835. opacity: 0.5;
  836. background-color: #666666;
  837. }
  838. .bounced {
  839. width: 570rpx;
  840. background: #FFFFFF;
  841. z-index: 1000;
  842. border-radius: 10rpx;
  843. position: fixed;
  844. left: 50%;
  845. top: 50%;
  846. transform: translate(-50%, -50%);
  847. /* 50%为自身尺寸的一半 */
  848. .jiajinghuatit {
  849. width: 100%;
  850. height: 68rpx;
  851. font-size: 30rpx;
  852. text-align: center;
  853. line-height: 68rpx;
  854. }
  855. .jiajinghuaview {
  856. padding: 18rpx 18rpx 18rpx 18rpx;
  857. display: flex;
  858. flex-wrap: wrap;
  859. .jiajinghuaview1 {
  860. padding: 8rpx 8rpx 8rpx 8rpx;
  861. font-size: 26rpx;
  862. border-radius: 12rpx;
  863. border: 1px solid #979797;
  864. margin-left: 8rpx;
  865. }
  866. .jighuaview2 {
  867. padding: 8rpx 8rpx 8rpx 8rpx;
  868. font-size: 26rpx;
  869. border-radius: 12rpx;
  870. border: 1px solid #979797;
  871. margin-left: 8rpx;
  872. display: flex;
  873. .view1-text {
  874. text-align: center;
  875. // border-right: 1rpx solid red;
  876. }
  877. .view1-img {
  878. width: 50rpx;
  879. }
  880. }
  881. }
  882. .bounced3 {
  883. height: 100rpx;
  884. width: 100%;
  885. margin-top: 40rpx;
  886. border-top: 1px solid #dddddd;
  887. display: flex;
  888. }
  889. .bounced3-1 {
  890. width: 50%;
  891. height: 100%;
  892. text-align: center;
  893. line-height: 100rpx;
  894. border-right: 1px solid #dddddd;
  895. font-size: 36rpx;
  896. color: #999999;
  897. }
  898. .bounced3-2 {
  899. width: 50%;
  900. height: 100%;
  901. text-align: center;
  902. line-height: 100rpx;
  903. font-size: 36rpx;
  904. color: #108ee9;
  905. }
  906. }
  907. .tab-box {
  908. width: 100%;
  909. display: flex;
  910. justify-content: center;
  911. align-items: center;
  912. .yinpinshibie {
  913. width: 156rpx;
  914. height: 50rpx;
  915. font-size: 36rpx;
  916. font-weight: 400;
  917. color: #333333;
  918. text-align: center;
  919. line-height: 50rpx;
  920. letter-spacing: 2rpx;
  921. margin-right: 188rpx;
  922. &.active {
  923. position: relative;
  924. &::after {
  925. position: absolute;
  926. content: '';
  927. width: 119rpx;
  928. height: 8rpx;
  929. background: #008EF2;
  930. border-radius: 4rpx;
  931. top: 50rpx;
  932. right: 0;
  933. left: 0;
  934. margin: 0 auto;
  935. }
  936. }
  937. }
  938. .rate {
  939. width: 156rpx;
  940. height: 50rpx;
  941. font-size: 36rpx;
  942. font-weight: 400;
  943. color: #333333;
  944. line-height: 50rpx;
  945. letter-spacing: 2rpx;
  946. text-align: center;
  947. &.active {
  948. position: relative;
  949. &::after {
  950. position: absolute;
  951. content: '';
  952. width: 119rpx;
  953. height: 8rpx;
  954. background: #008EF2;
  955. border-radius: 4rpx;
  956. top: 50rpx;
  957. right: 0;
  958. left: 0;
  959. margin: 0 auto;
  960. }
  961. }
  962. }
  963. }
  964. .dialog-block {
  965. margin: 20rpx 0;
  966. border-bottom: 1px solid #ccc;
  967. .fileName {
  968. text-align: center;
  969. margin: 10rpx auto;
  970. width: 115rpx;
  971. height: 42rpx;
  972. line-height: 42rpx;
  973. background: #EFEFEF;
  974. border-radius: 4rpx;
  975. font-size: 20rpx;
  976. font-weight: 400;
  977. color: #333333;
  978. }
  979. }
  980. // 评分
  981. .rate-box {
  982. padding: 10rpx 20rpx;
  983. .date {
  984. width: 300rpx;
  985. height: 33rpx;
  986. font-size: 24rpx;
  987. font-weight: 400;
  988. color: #333333;
  989. line-height: 33rpx;
  990. letter-spacing: 1rpx;
  991. margin-bottom: 8rpx;
  992. }
  993. .title {
  994. width: 100%;
  995. height: 42rpx;
  996. font-size: 30rpx;
  997. font-weight: 500;
  998. color: #333333;
  999. line-height: 42rpx;
  1000. letter-spacing: 2rpx;
  1001. margin-bottom: 20rpx;
  1002. }
  1003. .level1 {
  1004. display: flex;
  1005. align-items: center;
  1006. .level-name {
  1007. width: 104rpx;
  1008. height: 33rpx;
  1009. font-size: 24rpx;
  1010. font-weight: 500;
  1011. color: #333333;
  1012. line-height: 33rpx;
  1013. letter-spacing: 1rpx;
  1014. margin-right: 10rpx;
  1015. }
  1016. .level-progress {
  1017. flex: 1;
  1018. border-radius: 11rpx;
  1019. height: 21rpx;
  1020. background-color: #BEE4FF;
  1021. position: relative;
  1022. .color {
  1023. width: 0;
  1024. position: absolute;
  1025. top: 0;
  1026. left: 0;
  1027. height: 21rpx;
  1028. border-radius: 11rpx 0 0 11rpx;
  1029. background-color: #008EF2;
  1030. }
  1031. }
  1032. .level-rate {
  1033. width: 65rpx;
  1034. height: 33rpx;
  1035. font-size: 24rpx;
  1036. font-weight: 500;
  1037. color: #333333;
  1038. line-height: 33rpx;
  1039. letter-spacing: 1rpx;
  1040. margin: 0 20rpx 0 15rpx;
  1041. }
  1042. .arrow {
  1043. width: 37rpx;
  1044. height: 21rpx;
  1045. padding: 5rpx 20rpx;
  1046. }
  1047. .rotatearrow {
  1048. transform: rotate(270deg);
  1049. }
  1050. }
  1051. .level1-subbox {
  1052. display: flex;
  1053. margin-top: 20rpx;
  1054. flex-wrap: wrap;
  1055. .sub-name {
  1056. width: 50%;
  1057. display: flex;
  1058. margin-bottom: 18rpx;
  1059. .subitem-name {
  1060. width: 104rpx;
  1061. height: 33rpx;
  1062. font-size: 24rpx;
  1063. font-weight: 400;
  1064. color: #999999;
  1065. line-height: 33rpx;
  1066. letter-spacing: 1rpx;
  1067. margin-right: 12rpx;
  1068. }
  1069. .checkimg {
  1070. width: 27rpx;
  1071. height: 27rpx;
  1072. }
  1073. }
  1074. }
  1075. }
  1076. .luyin {
  1077. height: 100rpx;
  1078. width: 100%;
  1079. }
  1080. .translation {
  1081. background: #FFFFFF;
  1082. display: flex;
  1083. flex-direction: column;
  1084. height: 100vh;
  1085. }
  1086. .translation .top {
  1087. margin-top: 20rpx;
  1088. padding: 0 30rpx;
  1089. background: #ffffff;
  1090. border-bottom: 1rpx solid #F2F2F2;
  1091. padding-bottom: 10rpx;
  1092. }
  1093. .translation .top .title {
  1094. padding: 0 30rpx;
  1095. display: flex;
  1096. align-items: center;
  1097. justify-content: space-between;
  1098. .hash {
  1099. color: rgba(21, 144, 233, 1);
  1100. font-size: 26rpx;
  1101. }
  1102. }
  1103. .call_record_time {
  1104. height: 42rpx;
  1105. line-height: 42rpx;
  1106. font-size: 30rpx;
  1107. font-family: PingFangSC-Medium, PingFang SC;
  1108. font-weight: 500;
  1109. color: #303030;
  1110. }
  1111. .call_record_time_one {
  1112. padding-left: 30rpx;
  1113. color: #70798d;
  1114. display: flex;
  1115. justify-content: space-between;
  1116. position: relative;
  1117. height: 40rpx;
  1118. font-size: 28rpx;
  1119. font-family: PingFangSC-Regular, PingFang SC;
  1120. font-weight: 400;
  1121. color: #303030;
  1122. line-height: 40rpx;
  1123. margin-top: 20rpx;
  1124. .diangweitupian {
  1125. width: 46rpx;
  1126. height: 46rpx;
  1127. position: absolute;
  1128. top: 0rpx;
  1129. right: 75rpx;
  1130. }
  1131. .file-change {
  1132. position: absolute;
  1133. top: 50rpx;
  1134. right: 0rpx;
  1135. width: 184rpx;
  1136. background: #FFFFFF;
  1137. box-shadow: 0rpx 0rpx 6rpx 2rpx rgba(230, 230, 230, 0.5);
  1138. border-radius: 4rpx;
  1139. z-index: 99;
  1140. height: auto;
  1141. max-height: 600rpx;
  1142. overflow: auto;
  1143. }
  1144. .file-item {
  1145. width: 184rpx;
  1146. height: 60rpx;
  1147. line-height: 60rpx;
  1148. text-align: center;
  1149. font-size: 30rpx;
  1150. font-weight: 400;
  1151. color: #333333;
  1152. border-bottom: 1rpx solid #E2E2E2;
  1153. }
  1154. .file-item:last-child {
  1155. border: 0
  1156. }
  1157. .fileactive {
  1158. color: #008EF2
  1159. }
  1160. }
  1161. .scroll-Y {
  1162. font-size: 36rpx;
  1163. color: #999999;
  1164. background: #FFFFFF;
  1165. margin-top: 30rpx;
  1166. flex: 1;
  1167. overflow-y: scroll;
  1168. width: 100%;
  1169. }
  1170. .scroll-Y .text {
  1171. margin: 30rpx;
  1172. line-height: 40rpx;
  1173. display: flex;
  1174. align-items: flex-start;
  1175. }
  1176. .scroll-Y .text[data-speaker="2"],
  1177. .scroll-Y .text[data-speaker="4"],
  1178. .scroll-Y .text[data-speaker="6"] {
  1179. flex-direction: row-reverse;
  1180. text-align: right;
  1181. .content {
  1182. margin-left: 0;
  1183. margin-right: 30rpx;
  1184. }
  1185. }
  1186. .scroll-Y .text .avatar {
  1187. text {
  1188. display: block;
  1189. width: 72rpx;
  1190. height: 72rpx;
  1191. line-height: 72rpx;
  1192. text-align: center;
  1193. background: #FFFFFF;
  1194. border-radius: 8rpx;
  1195. font-size: 30rpx;
  1196. font-family: PingFangSC-Medium, PingFang SC;
  1197. font-weight: 500;
  1198. box-sizing: border-box;
  1199. }
  1200. image {
  1201. width: 72rpx;
  1202. height: 72rpx;
  1203. }
  1204. }
  1205. .scroll-Y .text .content {
  1206. margin-left: 30rpx;
  1207. text-align: left;
  1208. padding: 10rpx;
  1209. background: #f8f8f8;
  1210. border-radius: 12rpx;
  1211. max-width: 442rpx;
  1212. color: #999999;
  1213. position: relative;
  1214. font-size: 30rpx;
  1215. font-family: PingFangSC-Regular, PingFang SC;
  1216. font-weight: 400;
  1217. color: #505050;
  1218. line-height: 40rpx;
  1219. }
  1220. .scroll-Y .text.active .content {
  1221. color: #2671E2 !important;
  1222. position: relative;
  1223. }
  1224. .likeArea {
  1225. width: 86rpx;
  1226. height: 84rpx;
  1227. margin: 20rpx auto 38rpx auto;
  1228. border-radius: 50%;
  1229. display: flex;
  1230. justify-content: center;
  1231. align-items: center;
  1232. border: 1rpx solid #C1C2C1;
  1233. &.liked {
  1234. border: 1rpx solid rgba(21, 144, 233, 1);
  1235. }
  1236. image {
  1237. width: 38rpx;
  1238. height: 39rpx;
  1239. }
  1240. }
  1241. .chat {
  1242. padding: 20rpx;
  1243. display: flex;
  1244. flex-direction: column;
  1245. border-top: 1rpx solid rgba(151, 151, 151, 0.4);
  1246. .total {
  1247. color: rgba(21, 144, 233, 1);
  1248. font-size: 24rpx;
  1249. }
  1250. .list {
  1251. display: flex;
  1252. flex-direction: column;
  1253. .message {
  1254. display: flex;
  1255. margin-top: 20rpx;
  1256. border-bottom: 1rpx solid rgba(151, 151, 151, 0.4);
  1257. padding-bottom: 20rpx;
  1258. &:last-child {
  1259. border-bottom: 0;
  1260. }
  1261. .avator {
  1262. margin-left: 120rpx;
  1263. }
  1264. &:first-child {
  1265. .avator {
  1266. margin-left: 0;
  1267. }
  1268. }
  1269. .right {
  1270. display: flex;
  1271. flex-direction: column;
  1272. margin-left: 20rpx;
  1273. flex: 1;
  1274. .name {
  1275. color: rgba(16, 16, 16, 1);
  1276. font-size: 30rpx;
  1277. }
  1278. .subtitle {
  1279. color: rgba(120, 120, 120, 1);
  1280. font-size: 24rpx;
  1281. margin-top: 16rpx;
  1282. }
  1283. .answer {
  1284. font-size: 24rpx;
  1285. color: #787878;
  1286. }
  1287. .content {
  1288. color: rgba(49, 48, 48, 1);
  1289. font-size: 30rpx;
  1290. margin-top: 20rpx;
  1291. position: relative;
  1292. }
  1293. .bottom {
  1294. margin-top: 16rpx;
  1295. display: flex;
  1296. justify-content: space-between;
  1297. .time {
  1298. color: rgba(185, 185, 185, 1);
  1299. font-size: 20rpx;
  1300. }
  1301. .button {
  1302. color: rgba(144, 144, 144, 1);
  1303. font-size: 30rpx;
  1304. width: 111rpx;
  1305. height: 44rpx;
  1306. border-radius: 22rpx;
  1307. border: 1rpx solid rgba(151, 151, 151, 1);
  1308. text-align: center;
  1309. }
  1310. }
  1311. }
  1312. }
  1313. }
  1314. }
  1315. .bottomArea {
  1316. min-height: 90rpx;
  1317. background: #F0F2F5;
  1318. width: 100vw;
  1319. display: flex;
  1320. align-items: center;
  1321. border-top: 1rpx solid rgba(151, 151, 151, 0.25);
  1322. .voice {
  1323. width: 44rpx;
  1324. height: 44rpx;
  1325. margin-left: 38rpx;
  1326. }
  1327. .inputArea {
  1328. margin-left: 38rpx;
  1329. margin-right: 38rpx;
  1330. flex: 1;
  1331. display: flex;
  1332. position: relative;
  1333. .edit {
  1334. width: 30rpx;
  1335. height: 28rpx;
  1336. position: absolute;
  1337. top: 31rpx;
  1338. left: 27rpx;
  1339. }
  1340. .editor {
  1341. background: rgba(0, 139, 245, 0.17);
  1342. border-radius: 29rpx;
  1343. flex: 1;
  1344. min-height: 58rpx;
  1345. width: unset;
  1346. padding: 0 32rpx;
  1347. font-size: 30rpx;
  1348. margin: 16rpx 0;
  1349. line-height: 29px;
  1350. }
  1351. .placeholder {
  1352. position: absolute;
  1353. left: 70rpx;
  1354. top: 26rpx;
  1355. color: #26A2FF;
  1356. &.editing {
  1357. left: 36rpx;
  1358. }
  1359. }
  1360. }
  1361. .download {
  1362. width: 41rpx;
  1363. height: 35rpx;
  1364. margin-right: 36rpx;
  1365. }
  1366. .like {
  1367. width: 38rpx;
  1368. height: 39rpx;
  1369. margin-right: 38rpx;
  1370. }
  1371. .add {
  1372. width: 50rpx;
  1373. height: 50rpx;
  1374. margin-right: 38rpx;
  1375. }
  1376. .send {
  1377. background: #1590e9;
  1378. color: white;
  1379. padding: 10rpx 20rpx;
  1380. margin: 5px;
  1381. border-radius: 8rpx;
  1382. }
  1383. }
  1384. .backTop {
  1385. width: 60rpx;
  1386. height: 60rpx;
  1387. background: rgba(211, 235, 253, 1);
  1388. box-shadow: 0rpx 0rpx 2rpx 4rpx rgba(38, 161, 255, 0.04);
  1389. border-radius: 50%;
  1390. position: fixed;
  1391. bottom: 200rpx;
  1392. right: 8rpx;
  1393. display: flex;
  1394. justify-content: center;
  1395. align-items: center;
  1396. image {
  1397. width: 26rpx;
  1398. height: 34rpx;
  1399. }
  1400. }
  1401. .voiceContent {
  1402. position: fixed;
  1403. top: 0;
  1404. bottom: 0;
  1405. left: 0;
  1406. right: 0;
  1407. width: 100vw;
  1408. height: 100vh;
  1409. display: flex;
  1410. justify-content: center;
  1411. align-items: center;
  1412. background: rgba(30, 30, 30, 0.4592);
  1413. z-index: 10001;
  1414. }
  1415. .box {
  1416. background: rgba(21, 144, 233, 0.299);
  1417. width: 524rpx;
  1418. height: 524rpx;
  1419. border-radius: 50%;
  1420. display: flex;
  1421. align-items: center;
  1422. justify-content: center;
  1423. .center {
  1424. width: 412rpx;
  1425. height: 412rpx;
  1426. background: #1590E9;
  1427. border-radius: 50%;
  1428. display: flex;
  1429. align-items: center;
  1430. justify-content: center;
  1431. flex-direction: column;
  1432. .voice {
  1433. width: 110rpx;
  1434. height: 133rpx;
  1435. }
  1436. .text {
  1437. color: #FFFFFF;
  1438. font-size: 36rpx;
  1439. margin-top: 24rpx;
  1440. }
  1441. }
  1442. }
  1443. .audio-container {
  1444. width: 100%;
  1445. display: flex;
  1446. justify-content: space-between;
  1447. align-items: center;
  1448. .audio-head {
  1449. width: 60rpx;
  1450. height: 60rpx;
  1451. flex-shrink: 0;
  1452. }
  1453. .audio-head .image {
  1454. width: 100%;
  1455. height: 100%;
  1456. }
  1457. .audio-slider {
  1458. width: 96%;
  1459. position: relative;
  1460. padding: 2px 0rpx 0px 20px;
  1461. display: flex;
  1462. justify-content: space-between;
  1463. align-items: center;
  1464. }
  1465. .audio-slider .slider {
  1466. width: 100%;
  1467. padding: 0px 15rpx;
  1468. box-sizing: border-box;
  1469. }
  1470. .audio-time {
  1471. width: 110rpx;
  1472. text-align: right;
  1473. font-size: 24rpx;
  1474. line-height: 28rpx;
  1475. color: #70798D;
  1476. display: flex;
  1477. justify-content: space-between;
  1478. }
  1479. .audio-play {
  1480. width: 40rpx;
  1481. height: 40rpx;
  1482. flex-shrink: 0;
  1483. }
  1484. .audio-play .image {
  1485. width: 100%;
  1486. height: 100%;
  1487. }
  1488. }
  1489. </style>