detail.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <template>
  2. <view class="wrap">
  3. <div class="preview-conatiner">
  4. <view class="title">{{viewData.taskTitle}}</view>
  5. </div>
  6. <view class="content">
  7. <view class="result">
  8. <view class="title">
  9. <text>内容</text>
  10. <button @click="read" class="submit-bt read">朗读</button>
  11. </view>
  12. <view class="result-conatiner">
  13. <uni-forms ref="form" :modelValue="formData" :label-width="90">
  14. <uni-forms-item :label="item.text" v-for="(item,key) in viewData.taskContent" :key="key" required >
  15. <uni-data-checkbox v-model="item.checked" :localdata="range"></uni-data-checkbox>
  16. </uni-forms-item>
  17. <uni-forms-item>
  18. <button @click="submitForm" class="submit-bt">提交</button>
  19. </uni-forms-item>
  20. </uni-forms>
  21. </view>
  22. </view>
  23. </view>
  24. </view>
  25. </template>
  26. <script>
  27. import {updateMemory} from '@/api/user.js'
  28. export default{
  29. data(){
  30. return{
  31. readSrc:"",
  32. innerAudioContext:null,
  33. viewData:{
  34. taskTitle:"",
  35. taskContent:[]
  36. },
  37. range: [{
  38. "value": 0,
  39. "text": "正确"
  40. },
  41. {
  42. "value": 1,
  43. "text": "错误"
  44. }
  45. ],
  46. formData:{}
  47. }
  48. },
  49. onShow() {
  50. let info=uni.getStorageSync('index-detail-info')
  51. this.viewData=info
  52. let taskContentNew=[]
  53. let items=info.taskContent.split(/[\s\n]/).filter(item=>item!=="");
  54. items=items.map((item,index)=>{
  55. return {
  56. text: item,
  57. value: index,
  58. checked:0
  59. }
  60. })
  61. if(!this.isEmpty(info.taskContentNew)){
  62. taskContentNew=info.taskContentNew.split(/[\s\n]/).filter(item=>item!=="");
  63. taskContentNew=taskContentNew.map((item,index)=>{
  64. return {
  65. text: item,
  66. value: index,
  67. checked:1
  68. }
  69. })
  70. }
  71. this.viewData.taskContent=items.concat(taskContentNew)
  72. },
  73. created() {
  74. this.getTTStoken()
  75. },
  76. onUnload() {
  77. uni.removeStorageSync('index-detail-info')
  78. if(this.innerAudioContext){
  79. this.innerAudioContext.stop();
  80. this.innerAudioContext.destroy()
  81. this.innerAudioContext=null;
  82. }
  83. },
  84. methods:{
  85. submitForm(){
  86. let right=this.viewData.taskContent
  87. .filter(item=>item.checked==0)
  88. .map(item=>item.text)
  89. .join(" ")
  90. let error=this.viewData.taskContent
  91. .filter(item=>item.checked==1)
  92. .map(item=>item.text)
  93. .join(" ")
  94. updateMemory({
  95. "taskId": this.viewData.taskId,
  96. "accountId": this.viewData.accountId,
  97. "taskTitle": this.viewData.taskTitle,
  98. "taskContent": right,
  99. "expectedFinishDate": this.viewData.expectedFinishDate,
  100. "taskPhase": this.viewData.taskPhase,
  101. "taskContentNew": error
  102. }).then(()=>{
  103. uni.showToast({
  104. title:"提交成功!",
  105. icon:"none"
  106. })
  107. setTimeout(()=>{
  108. uni.switchTab({
  109. url:'/pages/index/index'
  110. })
  111. },1000)
  112. })
  113. },
  114. async read(){
  115. let taskContent=this.viewData.taskContent
  116. let time=3;
  117. if(this.innerAudioContext){
  118. this.innerAudioContext.stop();
  119. }else{
  120. this.innerAudioContext = uni.createInnerAudioContext();
  121. }
  122. for(let i=0;i<taskContent.length;i++){
  123. for(let j=0;j<time;j++){
  124. await this.playAudio(this.getreadSrc(taskContent[i].text))
  125. }
  126. }
  127. },
  128. getreadSrc(ttsText){
  129. let cuid="hyy-"+(new Date().getTime());
  130. let access_token=this.tts_token
  131. let spd=3
  132. let per=0;
  133. let readUrl=`https://tsn.baidu.com/text2audio?lan=zh&ctp=1&cuid=${cuid}&tok=${access_token}&vol=9&per=${per}&spd=${spd}&pit=5&aue=3&tex=${ttsText}`;
  134. return readUrl;
  135. },
  136. playAudio(src,sleep=3000){
  137. return new Promise((resolve, reject)=>{
  138. var innerAudioContext = this.innerAudioContext;
  139. innerAudioContext.autoplay = true;
  140. innerAudioContext.src = src;
  141. innerAudioContext.onPlay(() => {
  142. console.log('开始播放');
  143. });
  144. innerAudioContext.onError((res) => {
  145. uni.showToast({
  146. title:"播放异常!"
  147. })
  148. });
  149. innerAudioContext.onEnded(()=>{
  150. setTimeout(()=>{
  151. resolve()
  152. },sleep)
  153. })
  154. })
  155. },
  156. async getTTStoken() {
  157. let tts_token=uni.getStorageSync('tts-token')
  158. if(this.isEmpty(tts_token)||tts_token&&this.detectionToken(tts_token.time)){
  159. var [err, res] = await uni.request({
  160. url: "http://back.haiyaya.club:8083/hyy/GetAccessToken",
  161. });
  162. uni.setStorageSync('tts-token',{
  163. token:res.data.refresh_token,
  164. time:new Date().getTime()
  165. })
  166. tts_token=res.data.refresh_token
  167. }else{
  168. tts_token=tts_token.token
  169. }
  170. this.tts_token=tts_token;
  171. },
  172. detectionToken(token){
  173. let now=new Date().getTime();
  174. return now-token.time>5*60*60*24*1000
  175. },
  176. isEmpty(val){
  177. if(val!=="undefined"&&val!==undefined&&val!==""&&val!==null){
  178. return false
  179. }
  180. return true
  181. }
  182. }
  183. }
  184. </script>
  185. <style lang="scss" scoped>
  186. *{
  187. padding: 0;
  188. margin: 0;
  189. }
  190. .wrap{
  191. padding:20rpx;
  192. .title{
  193. height: 40rpx;
  194. font-size: 28rpx;
  195. font-family: PingFang SC;
  196. font-weight: bold;
  197. line-height: 40rpx;
  198. color: #333333;
  199. opacity: 1;
  200. padding:0 0 36rpx 20rpx;
  201. position: relative;
  202. &::after{
  203. width: 12rpx;
  204. height: 28rpx;
  205. background:#2A83EF;
  206. opacity: 1;
  207. border-radius: 6px;
  208. content: "";
  209. display: block;
  210. position: absolute;
  211. left: 0;
  212. top: 8rpx;
  213. }
  214. }
  215. .content{
  216. padding: 10rpx;
  217. margin-top: 24rpx;
  218. ::v-deep .uni-forms-item__content{
  219. display: flex;
  220. align-items: center;
  221. flex-wrap: wrap;
  222. }
  223. .title{
  224. display: flex;
  225. justify-content: space-between;
  226. align-items: center;
  227. }
  228. }
  229. .submit-bt{
  230. width: 400rpx;
  231. height: 72rpx;
  232. line-height: 72rpx;
  233. text-align: center;
  234. background:#3D90F4;
  235. border-radius: 36rpx;
  236. font-size: 32rpx;
  237. font-family: PingFang SC;
  238. font-weight: 400;
  239. color: #FFFFFF;
  240. z-index: 999;
  241. margin-top: 50rpx;
  242. &.read{
  243. width: 140rpx;
  244. height: 60rpx;
  245. line-height: 60rpx;
  246. margin-top: 20rpx;
  247. }
  248. }
  249. }
  250. </style>