AI销管
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

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