index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <template>
  2. <view class="container">
  3. <!-- <tn-nav-bar :isBack="false" backgroundColor="#fff" :bottomShadow="false">数字人</tn-nav-bar> -->
  4. <!-- <view class="pos">
  5. </view> -->
  6. <view class="context">
  7. <view class="createPro" @click="handleCreatePro">
  8. <view class="centerAdd">
  9. <view class="addIcon">
  10. <!-- <image src="/static/images/buy.png" mode=""></image> -->
  11. <text class="iconfont icon-chuangjian" style="color: white;"></text>
  12. </view>
  13. <view class="addTxt">
  14. 创建项目
  15. </view>
  16. </view>
  17. </view>
  18. <view class="draft" v-if="draftList.length!=0">
  19. <view class="draftLabel">
  20. 草稿
  21. </view>
  22. <view class="draftList">
  23. <view class="itemBox" v-for="(item,index) in draftList" @click="toCreateDetail(item)">
  24. <view class="top"
  25. style="display: flex;justify-content: center;align-items: center;aspect-ratio: 4/3;">
  26. <text class="iconfont icon-caogao" style="color: white;font-size: 46rpx;"></text>
  27. </view>
  28. <view class="bottom">
  29. <view class="left">
  30. {{item.name}}
  31. </view>
  32. <view class="delIcon" @click.stop="delDraft(item,index)">
  33. <!-- <image src="/static/images/head.jpg" mode=""></image> -->
  34. <text class="iconfont icon-shanchu" style="font-size: 32rpx;"></text>
  35. </view>
  36. </view>
  37. </view>
  38. </view>
  39. </view>
  40. <view class="draft">
  41. <view class="draftLabel">
  42. 数字人作品
  43. </view>
  44. <view class="draftList">
  45. <view class="itemBox" v-for="(item,index) in workList" @click="goWorkDetail(item)">
  46. <view class="top" :style="{minHeight:isPc?'rpx':'470rpx'}">
  47. <image :src="item.cover" mode="aspectFit" v-if="item.state">
  48. </image>
  49. <view class="tipBox" v-else>
  50. <!-- <view class="preloader_1" :style="{left:isPc?'':'40%'}">
  51. <view></view>
  52. <view></view>
  53. <view></view>
  54. <view></view>
  55. <view></view>
  56. </view> -->
  57. <view class="preloader_1" style="">
  58. <view></view>
  59. <view></view>
  60. <view></view>
  61. <view></view>
  62. <view></view>
  63. </view>
  64. <!-- <view class="progress">
  65. <u-line-progress :percentage="'percentage'+item.id" :showText="true"
  66. activeColor="#9b59b6" height="12"></u-line-progress>
  67. </view> -->
  68. <view class="tip" style="color:#26b3a0">
  69. 生成中...
  70. </view>
  71. </view>
  72. </view>
  73. <view class="bottom">
  74. <view class="left">
  75. {{item.name}}
  76. </view>
  77. <!-- <view class="left">
  78. {{item.state==1?"已生成":'生成中'}}
  79. </view> -->
  80. <view class="delIcon" @click.stop="handleShowMoreMenu(item,index)">
  81. <!-- <image src="/static/images/head.jpg" mode=""></image> -->
  82. <text class="iconfont icon-gengduo-shuxiang" style="font-size: 32rpx;"></text>
  83. </view>
  84. </view>
  85. </view>
  86. </view>
  87. </view>
  88. <u-popup :show="show" @close="close" @open="open" mode="center">
  89. <view
  90. style="background: rgba(0, 0, 0, 0);width: 300rpx;height: 300rpx;display: flex;align-items: center;flex-direction: column;justify-content: center;color:#26b3a0;">
  91. <l-circularProgress :isBgShow="true" :lineWidth="10" boxWidth="100" boxHeight="100"
  92. progressColor="#26b3a0" fontColor="#26b3a0" gradualColor="#26b3a0"
  93. :percent="progress"></l-circularProgress>
  94. <view class="">
  95. 视频下载中...
  96. </view>
  97. </view>
  98. </u-popup>
  99. <u-picker :defaultIndex='[0]' :closeOnClickOverlay="true" :showIcon="true" :show="showMoreMenu"
  100. :columns="columns" title="更多" confirmColor="" @cancel="showMoreMenu=false" @confirm="handleConfirm"
  101. @close="handleClosePicker"></u-picker>
  102. <wike-tabbar :onTabbar="true" :isShowAnimate="true"></wike-tabbar>
  103. </view>
  104. </view>
  105. </template>
  106. <script>
  107. import {
  108. workList,
  109. delWork,
  110. draftList
  111. } from '@/api/robot/index.js'
  112. import {
  113. downLoad3
  114. } from '@/utils/download3.js'
  115. export default {
  116. data() {
  117. return {
  118. show: false,
  119. showMoreMenu: false,
  120. columns: [
  121. ['删除', '下载视频', '复制链接']
  122. ],
  123. draftList: [],
  124. workList: [],
  125. delItem: {},
  126. delIndex: -1,
  127. is_wx: false,
  128. isPc: false,
  129. timer: null,
  130. // percentage: 0,
  131. reqTimes: 0,
  132. progress: 0,
  133. isDowload: false
  134. };
  135. },
  136. computed: {
  137. },
  138. onReady() {
  139. },
  140. onUnload() {
  141. },
  142. onLoad(o) {
  143. },
  144. onShow() {
  145. let _this = this
  146. if (getApp().from == 'create') {
  147. _this.timer = setInterval(async () => {
  148. let res = await workList({})
  149. if (res.code == 0) {
  150. // _this.reqTimes += 1
  151. _this.workList = res.data
  152. // res.data.forEach((item, index) => {
  153. // console.log('每一个percentage', _this['percentage' + item.id]);
  154. // if (_this.reqTimes <= 5) {
  155. // _this['percentage' + item.id] += 10
  156. // } else {
  157. // _this['percentage' + item.id] += 1
  158. // }
  159. // if (item.state == 1) {
  160. // console.log('已完成的那一项', item);
  161. // _this['percentage' + item.id] = 100
  162. // }
  163. // })
  164. let allSuc = res.data.every((item, index) => {
  165. return item.state == 1
  166. })
  167. if (allSuc) {
  168. clearInterval(_this.timer)
  169. // _this.percentage = 100
  170. return
  171. }
  172. console.log('定时器--数字人作品列表返回值:', res);
  173. } else {
  174. uni.showToast({
  175. title: res.msg,
  176. icon: 'none'
  177. })
  178. }
  179. }, 10000)
  180. }
  181. getApp().from = ''
  182. const userAgent = navigator.userAgent.toLowerCase();
  183. if (/ipad|iphone|midp|rv:1.2.3.4|ucweb|android|windows ce|windows mobile/.test(userAgent)) {
  184. // 移动端
  185. console.log('移动端')
  186. this.isPc = false
  187. } else {
  188. // pc端
  189. this.isPc = true
  190. console.log('PC端')
  191. }
  192. // console.log('1213', download);
  193. this.getIndexData()
  194. this.is_wx = this.is_weixin()
  195. console.log('this.is_wx', this.is_wx);
  196. },
  197. onShareAppMessage: function(res) {
  198. },
  199. async onPullDownRefresh() {
  200. this.getIndexData()
  201. },
  202. methods: {
  203. open() {
  204. // console.log('open');
  205. },
  206. close() {
  207. this.show = false
  208. // console.log('close');
  209. },
  210. handleClosePicker() {
  211. this.showMoreMenu = false
  212. // this.columns = [
  213. // ['删除', '下载视频', '复制链接']
  214. // ]
  215. },
  216. toCreateDetail(item) {
  217. getApp().draftDetail = item
  218. uni.navigateTo({
  219. url: '/pages/robot/generate/index'
  220. })
  221. },
  222. async delDraft(item, index) {
  223. let res = await delWork({
  224. id: item.id
  225. })
  226. if (res.code == 0) {
  227. this.draftList.splice(index, 1)
  228. console.log('删除数字人草稿返回值:', res);
  229. uni.showToast({
  230. title: '数字人:' + item.name + '草稿删除成功!',
  231. icon: 'success'
  232. })
  233. } else {
  234. uni.showToast({
  235. title: res.msg,
  236. icon: 'none'
  237. })
  238. }
  239. },
  240. downLoad(url) {
  241. uni.downloadFile({
  242. url: url,
  243. header: {
  244. // 'Authorization':this.$utils.localData.getToken(),
  245. },
  246. success: (res) => {
  247. if (res.statusCode === 200) {
  248. console.log('res.tempFilePath', res.tempFilePath);
  249. return
  250. //res.tempFilePath; //此参数为本地的缓存地址
  251. var link = document.createElement('a');
  252. link.href = url; //url 为获取的本地缓存地址或者直接是url地址
  253. link.download = name + '.file'; //name为自定义的文件名称 .file为文件后缀名
  254. document.body.appendChild(link)
  255. link.click()
  256. //移除
  257. setTimeout(() => document.body.removeChild(link), 1000)
  258. }
  259. },
  260. fail: (e) => {
  261. uni.showToast({
  262. title: '数据处理错误,请刷新重试',
  263. icon: 'none',
  264. duration: 2000
  265. });
  266. }
  267. })
  268. },
  269. downLoad2(url) {
  270. var link = document.createElement('a');
  271. link.href = url; //url 为获取的本地缓存地址或者直接是url地址
  272. link.download = '数字人视频' + '.mp4'; //name为自定义的文件名称 .file为文件后缀名
  273. document.body.appendChild(link)
  274. link.click()
  275. //移除
  276. setTimeout(() => document.body.removeChild(link), 1000)
  277. },
  278. // 判断是否是微信浏览器
  279. is_weixin() {
  280. var ua = window.navigator.userAgent.toLowerCase();
  281. if (ua.match(/MicroMessenger/i) == 'micromessenger') {
  282. console.log('微信浏览器');
  283. return true;
  284. } else {
  285. console.log("不是微信浏览器");
  286. return false;
  287. }
  288. },
  289. async getIndexData() {
  290. let res = await workList({})
  291. if (res.code == 0) {
  292. uni.stopPullDownRefresh()
  293. this.workList = res.data
  294. // let parm = {}
  295. // res.data.forEach((item, index) => {
  296. // parm['percentage' + item.id] = 0
  297. // })
  298. // this.$data = Object.assign(this.$data, parm);
  299. // console.log('百分比批量赋值后:', this.$data);
  300. console.log('数字人作品列表返回值:', res);
  301. } else {
  302. uni.showToast({
  303. title: res.msg,
  304. icon: 'none'
  305. })
  306. }
  307. let res1 = await draftList({})
  308. if (res1.code == 0) {
  309. uni.stopPullDownRefresh()
  310. this.draftList = res1.data
  311. console.log('数字人草稿列表返回值:', res1);
  312. } else {
  313. uni.showToast({
  314. title: res1.msg,
  315. icon: 'none'
  316. })
  317. }
  318. },
  319. goWorkDetail(item) {
  320. if (item.state == 0) {
  321. uni.showToast({
  322. title: '数字人正在生成中,请稍后查看',
  323. icon: 'none'
  324. })
  325. return
  326. }
  327. getApp().url = item.url
  328. uni.navigateTo({
  329. url: '/pages/robot/workDetail/index'
  330. })
  331. },
  332. handleCreatePro() {
  333. uni.navigateTo({
  334. url: '/pages/robot/generate/index?type=create'
  335. })
  336. },
  337. handleShowMoreMenu(item, index) {
  338. this.delIndex = index
  339. this.delItem = item
  340. this.showMoreMenu = true
  341. },
  342. async handleConfirm(e) {
  343. this.showMoreMenu = false
  344. if (e.value[0] == '删除') {
  345. let res = await delWork({
  346. id: this.delItem.id
  347. })
  348. if (res.code == 0) {
  349. this.workList.splice(this.delIndex, 1)
  350. console.log('删除数字人返回值:', res);
  351. uni.showToast({
  352. title: '数字人:' + this.delItem.name + '删除成功!',
  353. icon: 'success'
  354. })
  355. } else {
  356. uni.showToast({
  357. title: res.msg,
  358. icon: 'none'
  359. })
  360. }
  361. } else if (e.value[0] == '复制链接') {
  362. uni.setClipboardData({
  363. data: this.delItem.url,
  364. success: function() {
  365. uni.showToast({
  366. title: '链接复制成功!',
  367. duration: 1500
  368. });
  369. }
  370. });
  371. } else if (e.value[0] == '下载视频') {
  372. const detectDeviceType = () => /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i
  373. .test(
  374. navigator.userAgent) ? false : true;
  375. if (this.is_wx) {
  376. // 微信内置浏览器
  377. // this.downLoad2(this.delItem.url)
  378. let _that = this
  379. uni.showModal({
  380. title: '温馨提示',
  381. content: '微信内置浏览器不支持视频文件下载,请复制视频链接至手机浏览器打开',
  382. confirmText: '复制',
  383. confirmColor: '#26B3A0',
  384. success: function(res) {
  385. if (res.confirm) {
  386. uni.setClipboardData({
  387. data: _that.delItem.url,
  388. success: function() {
  389. uni.showToast({
  390. title: "复制成功",
  391. icon: 'success',
  392. })
  393. }
  394. });
  395. } else if (res.cancel) {}
  396. }
  397. })
  398. return
  399. } else {
  400. if (detectDeviceType()) {
  401. let _this = this
  402. if (_this.isDowload) {
  403. uni.showToast({
  404. icon: 'none',
  405. title: '请等待上一个视频下载完成后,再下载',
  406. });
  407. }
  408. // PC端
  409. // this.delItem.url = 'http://www.liwantao.top/test.mp4'
  410. // downLoad3(this.delItem.url, '数字人' + this.delItem.name + '视频', 'video/mp4')
  411. const downloadTask = uni.downloadFile({
  412. url: _this.delItem.url, //文件链接
  413. success: (res) => {
  414. if (res.statusCode === 200) {
  415. var oA = document.createElement("a");
  416. oA.download = _this.delItem.name; // 设置下载的文件名,默认是'下载'
  417. oA.href = res.tempFilePath; //临时路径再保存到本地
  418. document.body.appendChild(oA);
  419. oA.click();
  420. oA.remove(); // 下载之后把创建的元素删除
  421. }
  422. },
  423. fail: (err) => {
  424. _this.show = false;
  425. _this.isDowload = false
  426. _this.progress = 0
  427. // console.log(_this.show, _this.isDowload, _this.progress, err);
  428. uni.showToast({
  429. icon: 'none',
  430. mask: true,
  431. title: '失败请重新下载',
  432. });
  433. },
  434. })
  435. downloadTask.onProgressUpdate((res) => {
  436. if (res.progress > 0) {
  437. _this.show = true;
  438. _this.isDowload = true
  439. }
  440. _this.progress = res.progress;
  441. if (res.progress == 100) {
  442. _this.show = false;
  443. _this.isDowload = false
  444. _this.progress = 0
  445. uni.showToast({
  446. icon: 'success',
  447. title: _this.delItem.name + ',下载成功!',
  448. });
  449. }
  450. })
  451. } else {
  452. // 其他移动端浏览器
  453. window.open(this.delItem.url)
  454. }
  455. }
  456. }
  457. }
  458. }
  459. };
  460. </script>
  461. <style lang="scss" scoped>
  462. @import './index.scss';
  463. </style>