converter.vue 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. <template>
  2. <div class="page-converter">
  3. <div class="date-tips flex content-center justify-center py-6px">
  4. <img src="http://cn-file.17pdf.com/website/common/ic_notice.svg" class="align-middle">
  5. <div class="text-container">
  6. <span class="text">
  7. 转档后的文件支持在云端保留24小时,<span v-if="userInfo?.subscriberType === 1">会员尊享5G容量,</span>请在24小时内下载文件至本地永久保存
  8. </span>
  9. <span v-if="userInfo?.subscriberType === 1" class="vip tip">
  10. <img src="http://cn-file.17pdf.com/website/common/ic_info.svg" alt="">
  11. <div class="tip-text">
  12. 若已有文件大小超出5G,将按转档时间计算(从最近一次转档往过去推算),即保留最近的5G容量文件,超出部分文件将不再保留
  13. </div>
  14. </span>
  15. </div>
  16. </div>
  17. <h1 class="text-48px text-opacity-100 font-500 text-[#3333] mt-48px mb-10px text-center">文件转换器</h1>
  18. <h2 class="text-20px text-center text-[#666] mt-20px font-normal">PDF文件格式转换器,一键转档,支持批量转换,精准快速。</h2>
  19. <div class="text-center mb-80px">
  20. <a
  21. class="mt-20px text-[#4D4D4D] text-16px font-600 inline-flex items-center leading-22px hover:text-$btn-color-primary hover:underline"
  22. href="https://www.compdf.com/pdf-conversion-sdk?utm_source=anroidapp&utm_medium=17pdfweb&utm_campaign=pdfsdk" target="_blank">由 ComPDFKit Conversion SDK 提供技术支持
  23. <svg class="ml-8px" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
  24. <path d="M6 12.9567L10.714 8.24261L6 3.52856" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
  25. </svg>
  26. </a>
  27. </div>
  28. <div class="transfer-container-wrap">
  29. <div class="index-converter w-[80%] h-700px relative top-0 left-[50%] -ml-[40%]">
  30. <div class="transfer-container absolute w-full h-auto my-0 -mx-15px bg-white pb-60px">
  31. <button type="button" class="close hidden" data-dismiss="modal" aria-label="Close">
  32. <span aria-hidden="true">×</span>
  33. </button>
  34. <div class="recharge py-0 px-[10%] h-48px mx-0 mt-24px mb-14px absolute right-0 -top-70px z-2">
  35. <span @click="handlSubmit($event, 'buy')" class="recharge-btn float-right bg-white border border-[#ff4f4f] boder-solid text-16px py-7px px-18px rounded-4px mt-4px cursor-pointer hover:bg-[#ff4f4f]">
  36. <a class="text-[#ff4f4f] no-underline leading-normal">充值</a>
  37. </span>
  38. <div class="need-volume float-right right-48px text-16px text-[#666] leading-48px mr-20px">
  39. 所需券:<span class="text-[#0dd299] text-16px" :class="{'text-red-500': requiredCoupon > userInfo?.points}">{{ requiredCoupon }}券</span> / 剩余券:<span class="text-[#0dd299] text-16px">{{ Object.keys(this.userInfo).length === 0 ? 0 : userInfo.points }}券</span>
  40. </div>
  41. </div>
  42. <div class="transfer-panel">
  43. <div>
  44. <form enctype="multipart/form-data">
  45. <input type="hidden" name="folder" value="converter/input"/>
  46. <!-- 转档框 -->
  47. <div class="file-input theme-explorer file-input-ajax-new h-380px mt-17px py-0 px-[10%]">
  48. <div class="file-preview rounded-5px w-[100%] h-[100%]">
  49. <div ref="drag" @drop="handleEvent" @dragleave="handleEvent" @dragenter="handleEvent" @dragover="handleEvent"
  50. class="file-drop-zone border border-dashed border-[#d1d1d1] rounded-4px h-[100%] text-center align-middle overflow-y-auto">
  51. <div v-show="fileList.length <= 0" class="file-drop-zone-title text-[#999] text-16px leading-[1.428571429] pt-222px cursor-default">
  52. <div></div>
  53. 点击从电脑上传文件或把文件拖到这里
  54. <p class="text-14px leading-[1.428571429]">(支持PDF to Word、PPT、Excel、TXT、JPG/PNG无限次数转换)</p>
  55. </div>
  56. <table id="table-fileinput" class="table table-hover w-[100%] max-w-[100%]">
  57. <thead v-show="fileList.length > 0">
  58. <tr class="h-40px bg-[#eee]">
  59. <th class="!w-[5.5%]"></th>
  60. <th class="!text-left w-[26.5%]">文档名</th>
  61. <th class="!w-[17%]">大小</th>
  62. <th class="!w-[13%]">所需券</th>
  63. <th class="!w-[9.5%]">转为</th>
  64. <th class="!w-[23%]">状态</th>
  65. <th class="!w-[4.5%]"></th>
  66. </tr>
  67. </thead>
  68. <tbody v-show="fileList.length > 0" class="file-preview-thumbnails cursor-default">
  69. <tr v-for="(item, index) in fileList" id="preview-1668340925733-0" :key="index" class="file-preview-frame explorer-frame kv-preview-thumb w-100px h-38px hover:bg-[#f5f5f5]" data-fileindex="0" data-template="pdf" title="test.pdf">
  70. <td class="file-details-cell">{{ index+1 }}</td>
  71. <td class="file-details-cell !text-left">
  72. <div class="explorer-caption max-w-260px truncate block text-[#777]" title="test.pdf">{{ item.name }}</div>
  73. </td>
  74. <td class="file-details-cell text-[#999]">{{ getfilesize(item.size) }}</td>
  75. <td class="file-details-cell points">{{ userInfo?.subscriberType === 1 ? 0 : item.price }}</td>
  76. <td class="file-details-cell select w-106px">
  77. <select v-show="item.status !== 6" v-model="item.output" class="transfer-select appearance-none text-center min-w-90px" @change="changeOutput(item, index)" :disabled =" !changeFileFlag">
  78. <option value="png" class="text-center">PNG</option>
  79. <option value="xlsx" class="text-center">XLSX</option>
  80. <option value="pptx" class="text-center">PPTX</option>
  81. <option value="docx" class="text-center">DOCX</option>
  82. <option value="txt" class="text-center">TXT</option>
  83. <option value="jpg" class="text-center">JPG</option>
  84. </select>
  85. <span v-show="item.status == 6">{{ item.output }}</span>
  86. </td>
  87. <td class="file-details-cell state text-14px text-[#878787]" v-html="fileStatus(item, index)"></td>
  88. <!-- <td v-else class="file-details-cell state text-14px text-red-500">转换失败<img src="/converter/menu_ic_pdfconvert.png" @click="rechangeFile" /></td> -->
  89. <td class="file-actions-cell w-50px p-0">
  90. <div class="file-actions text-center">
  91. <div class="file-footer-buttons" @click="deleteFile(index)" v-if="changeFileFlag">
  92. <button type="button" class="kv-file-remove btn btn-xs btn-default bg-inherit !border-none pr-7px py-1px pl-5px text-12px leading-normal rounded-3px" title="删除文件"><i class="pdf-removeicon"></i></button>
  93. </div>
  94. </div>
  95. </td>
  96. </tr>
  97. </tbody>
  98. </table>
  99. <div class="clearfix"></div>
  100. <div class="file-preview-status text-success text-center text-[#3c763d]"></div>
  101. </div>
  102. </div>
  103. <div class="kv-upload-progress hide">
  104. <div class="progress overflow-hidden h-20px mb-20px bg-[#f5f5f5] rounded-4px ring-inset-2 ring-[rgba(0,0,0/10%)]">
  105. <div class="progress-bar progress-bar-success progress-bar-striped active w-0 bg-[#5cb85c]" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
  106. 0%
  107. </div>
  108. </div>
  109. </div>
  110. <div class="input-group file-caption-main w-[100%] -top-450px relative table border-separate">
  111. <div v-show="changeFileFlag" class="input-group-btn relative text-0px whitespace-nowrap !flex">
  112. <div tabindex="500" class="btn btn-file" :class="{'btn-file-left' : fileList.length > 0}" v-if="changeFileFlag">
  113. <div class="add-file" :class="{'add-file-left':(fileList.length > 0)}">
  114. {{ fileList.length > 0 ? '添加文件' : '' }}
  115. </div>
  116. <input id="fileinput-explorer" ref="file" name="file" accept=".pdf" title="上传文件" type="file" multiple=""
  117. class="absolute top-0 right-0 p-0 m-0 min-w-[100%] h-[100%] w-90px text-right opacity-0 bg-none bg-repeat bg-scroll block outline-none border-0 cursor-pointer"
  118. @change="addFile($event)" @click="handlSubmit($event, '')"/>
  119. </div>
  120. <div v-show="fileList.length > 0 && changeFileFlag" class="inline-block ml-30px bg-white border border-[#ff4f4f] boder-solid text-16px py-7px px-18px rounded-4px mt-4px cursor-pointer text-[#ff4f4f] leading-normal hover:bg-[#ff4f4f] hover:text-white"
  121. @click="deleteAllFile">清空</div>
  122. </div>
  123. </div>
  124. </div>
  125. </form>
  126. </div>
  127. <div class="transfer-btn mt-30px h-64px text-center">
  128. <div class="cursor-not-allowed inline-block">
  129. <span :class="{'disabledBtn' : !checkbox || !changeFileFlag||fileList.length === 0 }" class="btn transfer-start-btn bg-[#ff524f] text-20px py-0 px-150px rounded-4px h-60px w-386px text-white hover:bg-[#f34545]"
  130. @click="handlSubmit($event, 'change')">
  131. <a class="text-white leading-60px">{{ !changeFileFlag ? '转换中...' : '开始转换' }}</a>
  132. <span v-show="!changeFileFlag" class="loading"></span>
  133. </span>
  134. </div>
  135. <span class="hide btn btn-down small w-240px h-60px bg-[#0dd299] rounded-4px text-20px ml-15px hover:bg-[#0fc993]"><a class="leading-60px text-white">下载全部</a></span>
  136. </div>
  137. </div>
  138. <div class="transfer-remember mt-23px text-center">
  139. <div class="checkbox checkbox-danger relative block mt-10px mb-10px">
  140. <label for="remember" class="text-12px font-normal text-[#999] min-h-20px pl-20px mb-0 inline-block max-w-[100%]">
  141. <input v-model="checkbox" type="checkbox" name="remember" class="remember_pass cursor-pointer" :disabled="!changeFileFlag" :class="{'cursor-not-allowed' : !changeFileFlag }" />确保上传的文档不涉及版权问题及违法内容
  142. </label>
  143. </div>
  144. </div>
  145. </div>
  146. <div class="modal verifi-modal top-[20%!important]" d="verifiPayModal" tabindex="-1" role="dialog" aria-labelledby="verifiPayModal">
  147. <div class="modal-dialog verifi-dialog w-480px h-426px my-50px" role="document">
  148. <div class="modal-content relative bg-white rounded-6px border border-solid border-[rgba(0,0,0,0.2)] outline-0 bg-clip-padding ring-[rgba(0,0,0/50%)] ring-offseet-3px ring-9px md:ring-offset-5 md:ring-15px">
  149. <div class="">
  150. <button id="verifi-close" type="button" class="close pompt_close py-5px px-10px outline-none" data-dismiss="modal" aria-label="Close">
  151. <span aria-hidden="true">×</span>
  152. </button>
  153. </div>
  154. <div class="verifi-content text-center pt-60px px-0 pb-35px">
  155. <img src="http://cn-file.17pdf.com/website/converter/pic_trans_diomands.png"/>
  156. <p>该功能为付费套餐专属</p>
  157. <p>订阅解锁更多特权</p>
  158. <a href="javascript:;" class="now_pricing" value="0"
  159. >立即订阅</a
  160. >
  161. </div>
  162. </div>
  163. </div>
  164. </div>
  165. </div>
  166. <div class="file_num w-[100%] h-120px text-center text-white leading-120px text-30px mb-76px">
  167. 17PDF Reader,当前已转换了<span class="text-32px"> 1,859,726 </span> 个文件
  168. </div>
  169. <div id="more_type" class="pdf_converter clear w-[80%] my-0 mx-auto">
  170. <div class="package_type">
  171. <h3 class="text-24px text-[#333] font-normal mx-0 mt-0 mb-49px h-30px leading-30px">会员专享格式</h3>
  172. <ul class="flex justify-center w-[100%] min-w-340px p-0 mt-0 mb-10">
  173. <li>
  174. <a href="/converter">
  175. <img src="/converter/ic_pdf_word.png" />
  176. <span>PDF To Word</span>
  177. </a>
  178. </li>
  179. <li>
  180. <a href="/converter">
  181. <img src="/converter/ic_pdf_ppt.png"/>
  182. <span>PDF to PowerPoint</span>
  183. </a>
  184. </li>
  185. <li>
  186. <a href="/converter">
  187. <img src="/converter/ic_pdf_execl.png"/>
  188. <span>PDF to EXCEL</span>
  189. </a>
  190. </li>
  191. <li>
  192. <a href="/converter">
  193. <img src="/converter/ic_pdf_txt.png" />
  194. <span>PDF to TXT</span>
  195. </a>
  196. </li>
  197. <li>
  198. <a href="/converter">
  199. <img src="/converter/ic_pdf_picture.png" />
  200. <span>PDF to JPG/PNG</span>
  201. </a>
  202. </li>
  203. </ul>
  204. </div>
  205. </div>
  206. <div class="about_converter w-[100%] bg-[#fafafa] py-60px px-[10%] mt-102px">
  207. <h3 class="name text-24px text-[#333] font-normal mx-0 mt-0 mb-49px h-30px leading-30px">关于转档</h3>
  208. <ul class="clear p-0">
  209. <li>
  210. <img src="http://cn-file.17pdf.com/website/converter/ic_way.png" />
  211. <div class="content">
  212. <h3>如何转档</h3>
  213. <p>
  214. 进入“文件转换器”区域。点击下方“添加文件”选择添加本地目标文件,然后在“转为”栏选择转换目标格式,最后点击“开始转换”即可。
  215. </p>
  216. </div>
  217. </li>
  218. <li>
  219. <img
  220. src="http://cn-file.17pdf.com/website/converter/ic_quality.png"
  221. />
  222. <div class="content">
  223. <h3>领先品质</h3>
  224. <p>
  225. 行业领先的转换品质,经过转换的文件版面清晰、保持格式的一致,支持一键转档,批量转换,精准快速的文件格式转换,稳定的转换品质,是您处理转格式转换的首选。
  226. </p>
  227. </div>
  228. </li>
  229. <li>
  230. <img src="http://cn-file.17pdf.com/website/converter/ic_safe.png" />
  231. <div class="content">
  232. <h3>文件安全</h3>
  233. <p>
  234. 我们尊重每位用户的隐私信息和文件安全。转档后的文件仅在云端保留24小时,让您免去后顾之忧。
  235. </p>
  236. </div>
  237. </li>
  238. <li>
  239. <img src="http://cn-file.17pdf.com/website/converter/ic_more.png" />
  240. <div class="content">
  241. <h3>多平台支持</h3>
  242. <p>
  243. 文件格式转换器可以在所有计算机(Mac、Windows及Linux)上使用,也可下载App
  244. 17PDF Reader在移动端使用,让您在手机上也能轻松转档文件。
  245. </p>
  246. </div>
  247. </li>
  248. </ul>
  249. </div>
  250. <div class="converter_question px-[10%] pt-76px pb-60px text-center">
  251. <h3 class="name text-24px text-[#333] font-normal m-0 h-30px leading-30px text-left">常见问题</h3>
  252. <table class="w-[100%] p-0 bg-transparent">
  253. <tbody>
  254. <tr>
  255. <td>
  256. <h3>1. 支持哪些格式转换?</h3>
  257. <p>
  258. <span></span>支持PDF to
  259. Word、PPT、Excel、TXT、JPG/PNG无限次数转换
  260. </p>
  261. </td>
  262. <td>
  263. <h3>2. 为什么图片格式的文件转档效果不好?</h3>
  264. <p>
  265. 如原文件为图片格式或者通过扫描文档保存为PDF文件的,转档后的文件可能无法选取文字进行高亮等编辑。
  266. </p>
  267. </td>
  268. </tr>
  269. <tr>
  270. <td>
  271. <h3>3. 文件转档后出现乱码?</h3>
  272. <p>
  273. 如果是原文件就有乱码问题,先处理好文件再提交转档;如果原文件正常而转档后目标文件乱码,请联系我们处理。
  274. </p>
  275. </td>
  276. </tr>
  277. </tbody>
  278. </table>
  279. <a class="more w-auto h-30px leading-30px text-[#666] inline-block text-center mx-auto mt-48px mb-0 link:no-underline hover:(!border-[#ff4f4f] text-[#ff4f4f])" href="/question#convert">更多问题请查看帮助</a>
  280. </div>
  281. <div class="download_code fixed right-14px bottom-50px bg-white w-134px py-12px px-0 rounded-6px text-center ">
  282. <span class="large text-16px inline-block w-[100%] my-6px mx-0">下载APP</span>
  283. <img src="http://cn-file.17pdf.com/website/download/android_code.png" class="w-110px border-0 align-middle inline-block" />
  284. <span class="inline-block w-[100%] text-14px my-6px mx-0">使用更便捷</span>
  285. </div>
  286. </div>
  287. <client-only>
  288. <el-dialog :visible.sync="visiable" :close-on-click-modal="true" :close-on-press-escape="false" width="480px" append-to-body center>
  289. <div class="changepwd-tittle">
  290. <p class="text-20px text-center text-$btn-color-primary">提示</p>
  291. </div>
  292. <div class="text-16px text-[#707070] text-center my-30px">
  293. 您还未登录或注册,请先
  294. <span class="text-$btn-color-primary cursor-pointer" @click="login">登录</span>
  295. <span class="text-$btn-color-primary cursor-pointer" @click="register">注册</span>
  296. </div>
  297. </el-dialog>
  298. </client-only>
  299. </div>
  300. </template>
  301. <script>
  302. import { client } from 'process'
  303. import { mapState } from 'vuex'
  304. export default {
  305. data() {
  306. return {
  307. fileList: [],
  308. uniqFileArr: [],
  309. checkbox: true,
  310. changeFileFlag: true,
  311. uploadNum: 0,
  312. getFileStatusTimer: null,
  313. changeSucesssNumTotal: 0,
  314. changeSucesssFileList: [],
  315. visiable: false
  316. };
  317. },
  318. middleware: "user",
  319. head() {
  320. return {
  321. title: "PDF转换器免费在线转档",
  322. meta: [
  323. {
  324. hid: "description",
  325. content: "17PDF Reader免费提供在线PDF格式转换文件转档服务,支持PDF转word,PDF转doc,PDF转PPT,PDF转png,PDF转html,PDF转epub,PDF转xls,psd转ai等。轻松拖曳,一键转档,批量转换,支持多种常用格式相互转档。先进的转换引擎,极速转换,精准度高达99.99%。",
  326. },
  327. {
  328. name: "keywords",
  329. content: "格式转换,文件转档,pdf convert,converter, word to pdf"
  330. }
  331. ]
  332. };
  333. },
  334. computed: {
  335. ...mapState([
  336. "userInfo"
  337. ]),
  338. // 所需券数
  339. requiredCoupon() {
  340. let total = 0;
  341. for (let i = 0; i < this.fileList.length; i++) {
  342. total += this.fileList[i].price;
  343. }
  344. for (const file of this.fileList) {
  345. if (file.status === 6) {
  346. total -= file.price;
  347. }
  348. }
  349. if (this.userInfo && this.userInfo.subscriberType === 1) {
  350. total = 0;
  351. }
  352. return total;
  353. }
  354. },
  355. mounted() {
  356. // console.log(this.userInfo)
  357. if (localStorage.getItem("file") !== null) {
  358. this.fileList = JSON.parse(localStorage.getItem("file"));
  359. this.changeSucesssFileList = JSON.parse(localStorage.getItem("file"));
  360. }
  361. },
  362. methods: {
  363. handlSubmit(event, type) {
  364. if (!this.$store.state.token) {
  365. event.preventDefault();
  366. this.visiable = true;
  367. return;
  368. }
  369. if (type === "buy") {
  370. this.handlerBuy("ticket");
  371. }
  372. else if (type === "change") {
  373. this.createFileMission();
  374. }
  375. // this.$store.commit('OPEN_LOGIN', true)
  376. // this.$store.commit('SET_INTERFACE', 'vip')
  377. },
  378. login() {
  379. this.visiable = false;
  380. this.$store.commit("OPEN_LOGIN", true);
  381. this.$store.commit("SET_INTERFACE", "login");
  382. },
  383. register() {
  384. this.visiable = false;
  385. this.$store.commit("OPEN_LOGIN", true);
  386. this.$store.commit("SET_INTERFACE", "register");
  387. },
  388. // 充值弹框
  389. handlerBuy(type) {
  390. this.$store.commit("OPEN_LOGIN", true);
  391. this.$store.commit("SET_INTERFACE", type);
  392. },
  393. //拖拽事件
  394. handleEvent(event) {
  395. // 阻止事件的默认行为
  396. event.preventDefault();
  397. if (event.type === 'drop') {
  398. // 文件进入并松开鼠标,文件边框恢复正常
  399. this.$refs.drag.style.background = '#fff'
  400. this.$refs.drag.style.border = "thin dashed #d1d1d1"
  401. //传递拖拽的文件
  402. this.addFile(event.dataTransfer.files)
  403. } else if (event.type === 'dragleave') {
  404. // 离开时
  405. this.$refs.drag.style.background = '#fff'
  406. this.$refs.drag.style.border = "thin dashed #d1d1d1"
  407. } else {
  408. // 进入时
  409. this.$refs.drag.style.background = '#f0f0f0'
  410. this.$refs.drag.style.border = "3px dashed #d1d1d1"
  411. }
  412. },
  413. // 添加文件
  414. async addFile(event) {
  415. let array = {}
  416. if(event.target){
  417. array = event.target.files
  418. }else{
  419. array = event
  420. }
  421. const defaultPrice = await this.getFilePrice("pdf", "docx");
  422. for (let i = 0; i < array.length; i++) {
  423. const fileObj = {
  424. name: array[i].name,
  425. size: array[i].size,
  426. price: defaultPrice,
  427. input: "pdf",
  428. output: "docx",
  429. status: 0
  430. };
  431. this.fileList.push(fileObj);
  432. this.uniqFileArr.push(array[i]);
  433. }
  434. // this.fileList,this.uniqFileArr数组去重
  435. let newArr= [];
  436. let arrId = [];
  437. for(var item of this.fileList){
  438. if(arrId.indexOf(item['name']) == -1){
  439. arrId.push(item['name']);
  440. newArr.push(item);
  441. }
  442. }
  443. this.fileList=newArr
  444. newArr=[]
  445. arrId=[]
  446. for(var item of this.uniqFileArr){
  447. if(arrId.indexOf(item['name']) == -1){
  448. arrId.push(item['name']);
  449. newArr.push(item);
  450. }
  451. }
  452. this.uniqFileArr=newArr
  453. if(event.target){
  454. event.target.value=''
  455. }
  456. },
  457. // 查询文件所需券数
  458. async getFilePrice(input, output) {
  459. let price = 0;
  460. await this.$axios.get(`/convertType/getConvertTypeList?input=${input}&output=${output}`).then((res) => {
  461. if (res.code === 200) {
  462. price = res.result[0].price;
  463. }
  464. });
  465. return price;
  466. },
  467. // 改变要转换的格式
  468. async changeOutput(item, index) {
  469. const price = await this.getFilePrice(item.input, item.output);
  470. this.$set(this.fileList[index], "price", price);
  471. this.$set(this.fileList[index], "output", item.output);
  472. },
  473. // 计算文件大小函数(保留两位小数),Size为字节大小
  474. getfilesize(size) {
  475. if (!size)
  476. return "";
  477. const num = 1024; // byte
  478. if (size < num) {
  479. return size + "B";
  480. }
  481. if (size < Math.pow(num, 2)) {
  482. return (size / num).toFixed(2) + "K";
  483. }
  484. if (size < Math.pow(num, 3)) {
  485. return (size / Math.pow(num, 2)).toFixed(2) + "M";
  486. }
  487. if (size < Math.pow(num, 4)) {
  488. return (size / Math.pow(num, 3)).toFixed(2) + "G";
  489. }
  490. else {
  491. return (size / Math.pow(num, 4)).toFixed(2) + "T";
  492. }
  493. },
  494. // 删除文件
  495. deleteFile(index) {
  496. this.fileList.splice(index, 1);
  497. this.uniqFileArr.splice(index - this.changeSucesssNumTotal, 1);
  498. this.changeSucesssFileList = [];
  499. localStorage.removeItem("file");
  500. this.fileList.forEach(item => {
  501. if (item.status === 6) {
  502. this.changeSucesssFileList.push(item);
  503. }
  504. });
  505. localStorage.setItem("file", JSON.stringify(this.changeSucesssFileList));
  506. },
  507. // 清空
  508. deleteAllFile() {
  509. this.fileList = [];
  510. this.uniqFileArr = [];
  511. this.changeFileStatus("all", 5);
  512. this.changeSucesssFileList = [];
  513. localStorage.removeItem("file");
  514. this.showFileBig = false
  515. },
  516. // 转档第一步,根据文件列表创建任务和插入文件信息
  517. createFileMission() {
  518. // if (this.fileList.length === 0) return
  519. const points = this.userInfo.points;
  520. if (this.requiredCoupon > points) {
  521. alert("券数不足,请充值");
  522. return;
  523. }
  524. const filterFileList = this.fileList.filter(function (item) {
  525. return item.status !== 6;
  526. });
  527. let fileArr = [];
  528. for (let i = 0; i < filterFileList.length; i++) {
  529. const file = {};
  530. file.sourceType = 0;
  531. file.size = filterFileList[i].size;
  532. file.input = "pdf";
  533. file.output = filterFileList[i].output;
  534. file.filename = filterFileList[i].name;
  535. fileArr[i] = file;
  536. }
  537. fileArr = JSON.stringify(fileArr);
  538. this.changeFileFlag = false;
  539. this.changeFileStatus("all", 1);
  540. const config = {
  541. method: "post",
  542. url: "/mission/create",
  543. headers: {
  544. "Accept": "*/*",
  545. "Content-Type": "application/json"
  546. },
  547. data: fileArr
  548. };
  549. this.$axios("/mission/create", config).then((res) => {
  550. if (res.code === 200) {
  551. const missionFiles = res.result.missionFilePoJos;
  552. // console.log(missionFiles)
  553. for (let i = 0; i < missionFiles.length; i++) {
  554. this.changeFileStatus(missionFiles[i].fileName, 1);
  555. this.uploadFile(this.uniqFileArr[i], missionFiles[i].id, res.result.id);
  556. }
  557. }
  558. else {
  559. this.changeFileFlag = true;
  560. this.changeFileStatus("all", 5);
  561. }
  562. });
  563. },
  564. // 修改文件状态
  565. changeFileStatus(fileName, status) {
  566. if (fileName === "all") {
  567. this.fileList.forEach(item => {
  568. if (item.status !== 6) {
  569. this.$set(item, "status", status);
  570. }
  571. });
  572. }
  573. else {
  574. this.fileList.forEach(item => {
  575. if (item.name === fileName) {
  576. this.$set(item, "status", status);
  577. }
  578. });
  579. }
  580. },
  581. // 文件状态: 0未转换,1上传中,2上传完成,3转换中,4转换成功,5转换失败,6已转档
  582. fileStatus(item, index) {
  583. switch (item.status) {
  584. case 0:
  585. this.$set(this.fileList[index], "status", 0);
  586. return "未转换";
  587. case 1:
  588. this.$set(this.fileList[index], "status", 1);
  589. return "上传中";
  590. case 2:
  591. this.$set(this.fileList[index], "status", 2);
  592. return "上传完成";
  593. case 3:
  594. this.$set(this.fileList[index], "status", 3);
  595. return "转换中";
  596. case 4:
  597. this.$set(this.fileList[index], "status", 4);
  598. return "<span style=\"color: orange\">转换成功</span>";
  599. case 5:
  600. this.$set(this.fileList[index], "status", 5);
  601. return "<span style=\"color: red\">转换失败</span>";
  602. case 6:
  603. this.$set(this.fileList[index], "status", 6);
  604. return `<a href="${item.path}" style="color: #0dd299">下载</a>`;
  605. }
  606. },
  607. // 转档第二步,上传文件
  608. uploadFile(file, id, missionId) {
  609. // console.log(file)
  610. this.uploadNum = 0;
  611. const formData = new FormData();
  612. formData.append("file", file);
  613. formData.append("missionFileId", id);
  614. const config = {
  615. headers: {
  616. "Content-Type": "multipart/form-data;boundary = " + new Date().getTime()
  617. }
  618. };
  619. this.$axios.post("/missionFile/upload", formData, config).then((res) => {
  620. // console.log('上传文件')
  621. if (res.code === 200) {
  622. this.changeFileStatus(file.name, 2);
  623. this.uploadNum++;
  624. if (this.uploadNum === this.uniqFileArr.length) {
  625. this.convertFile(file.name, missionId);
  626. }
  627. }
  628. else {
  629. this.changeFileFlag = true;
  630. this.changeFileStatus(file.name, 5);
  631. }
  632. });
  633. },
  634. // 转档第三步,开始转档
  635. convertFile(file, missionId) {
  636. const formData = new FormData();
  637. formData.append("missionId", missionId);
  638. const config = {
  639. headers: {
  640. "Content-Type": "multipart/form-data;boundary = " + new Date().getTime()
  641. }
  642. };
  643. this.$axios.post("/mission/convertFile", formData, config).then((res) => {
  644. // console.log('开始转档')
  645. if (res.code === 200) {
  646. this.changeFileStatus("all", 3);
  647. this.getFileStatusTimer = window.setInterval(() => {
  648. setTimeout(this.getFileStatus(formData, config), 0);
  649. }, 3000);
  650. }
  651. else {
  652. this.uploadNum = 0;
  653. this.changeFileStatus("all", 5);
  654. this.changeFileFlag = true;
  655. }
  656. });
  657. },
  658. // 转档最后一步,轮询文件状态和下载链接
  659. getFileStatus(formData, config) {
  660. this.$axios.post("/mission/queryFileStatus", formData, config).then((res) => {
  661. // console.log('获取文件状态')
  662. if (res.code === 200) {
  663. const getFileList = res.result[0].missionFilePoJos;
  664. // console.log(getFileList)
  665. let changeSucesssNum = 0;
  666. for (let i = 0; i < getFileList.length; i++) {
  667. if (getFileList[i].status === 2) {
  668. this.changeFileStatus(getFileList[i].fileName, 4);
  669. this.fileList.forEach(item => {
  670. if (item.name === getFileList[i].fileName) {
  671. this.changeFileStatus(getFileList[i].fileName, 6);
  672. this.$set(item, "path", getFileList[i].path);
  673. this.changeSucesssFileList.push(item);
  674. }
  675. });
  676. }
  677. else {
  678. this.changeFileStatus(getFileList[i].fileName, 5);
  679. }
  680. changeSucesssNum++;
  681. }
  682. if (changeSucesssNum === getFileList.length) {
  683. clearInterval(this.getFileStatusTimer);
  684. this.getFileStatusTimer = null;
  685. this.changeSucesssNumTotal += changeSucesssNum;
  686. let failedFileList = getFileList.filter((val) => val.status === 3);
  687. let failedFileNameArr = failedFileList.map(val => val.fileName);
  688. let result = [];
  689. for (let i = 0; i < failedFileNameArr.length; i++) {
  690. this.uniqFileArr.forEach(item => {
  691. if (item.name === failedFileNameArr[i]) {
  692. result.push(item);
  693. }
  694. });
  695. }
  696. this.uniqFileArr = result;
  697. }
  698. // console.log('changeSucesssFileList:', this.changeSucesssFileList)
  699. localStorage.setItem("file", JSON.stringify(this.changeSucesssFileList));
  700. }
  701. else {
  702. this.changeFileStatus("all", 5);
  703. }
  704. this.uploadNum = 0;
  705. this.changeFileFlag = true;
  706. });
  707. }
  708. },
  709. components: { client }
  710. }
  711. </script>
  712. <style lang="scss" scoped>
  713. ::v-deep body {
  714. min-width: 1200px !important;
  715. }
  716. .page-converter {
  717. .date-tips {
  718. background: linear-gradient(0deg, #fff2f6, #fff2f6),
  719. linear-gradient(90deg, snow 10.37%, rgba(255, 243, 243, 0) 91.75%),
  720. linear-gradient(90deg, #fff2f6 2.26%, rgba(255, 242, 246, 0.21) 101.41%);
  721. .text-container {
  722. display: flex;
  723. align-items: center;
  724. margin-left: 16px;
  725. img {
  726. margin-left: 8px;
  727. }
  728. }
  729. span {
  730. font-size: 14px;
  731. line-height: 24px;
  732. vertical-align: middle;
  733. }
  734. .text {
  735. display: inline-flex;
  736. align-items: center;
  737. }
  738. .tip {
  739. position: relative;
  740. font-size: 0;
  741. .tip-text {
  742. display: none;
  743. position: absolute;
  744. left: -3px;
  745. width: 258px;
  746. padding: 15px 14px 10px 10px;
  747. background: url('http://cn-file.17pdf.com/website/members/ic_tip.svg')
  748. left top no-repeat;
  749. background-size: auto 100%;
  750. font-size: 12px;
  751. line-height: 18px;
  752. color: #fff;
  753. border-radius: 4px;
  754. }
  755. &:hover .tip-text {
  756. display: block;
  757. }
  758. }
  759. }
  760. .transfer-container {
  761. .hide {
  762. display: none !important;
  763. }
  764. button {
  765. padding-right: 7px;
  766. }
  767. .close {
  768. float: right;
  769. font-size: 21px;
  770. font-weight: bold;
  771. line-height: 1;
  772. color: #000;
  773. text-shadow: 0 1px 0 #fff;
  774. opacity: 0.2;
  775. filter: alpha(opacity=20);
  776. }
  777. button.close {
  778. padding: 0;
  779. cursor: pointer;
  780. background: transparent;
  781. border: 0;
  782. -webkit-appearance: none;
  783. }
  784. button:focus {
  785. outline: none;
  786. }
  787. .close:hover,
  788. .close:focus {
  789. color: #000;
  790. text-decoration: none;
  791. cursor: pointer;
  792. opacity: 0.5;
  793. filter: alpha(opacity=50);
  794. }
  795. .recharge .recharge-btn:hover a {
  796. color: #fff;
  797. }
  798. .transfer-btn .loading {
  799. display: inline-block;
  800. border: 3px solid #fff;
  801. border-bottom: 3px solid #cccccc;
  802. height: 35px;
  803. width: 35px;
  804. border-radius: 50%;
  805. position: relative;
  806. top: 10px;
  807. left: 100px;
  808. -webkit-animation: loading 1s infinite linear;
  809. -moz-animation: loading 1s infinite linear;
  810. -o-animation: loading 1s infinite linear;
  811. animation: loading 1s infinite linear;
  812. }
  813. }
  814. .table>caption+thead>tr:first-child>th, .table>caption+thead>tr:first-child>td, .table>colgroup+thead>tr:first-child>th, .table>colgroup+thead>tr:first-child>td, .table>thead:first-child>tr:first-child>th, .table>thead:first-child>tr:first-child>td {
  815. border-top: 0;
  816. }
  817. .file-drop-zone .table thead tr th {
  818. color: #666666;
  819. text-align: center;
  820. }
  821. .table>thead>tr>th {
  822. vertical-align: bottom;
  823. border-bottom: 2px solid #ddd;
  824. }
  825. .table>thead>tr>th, .table>thead>tr>td, .table>tbody>tr>th, .table>tbody>tr>td, .table>tfoot>tr>th, .table>tfoot>tr>td {
  826. padding: 8px;
  827. line-height: 1.428571429;
  828. vertical-align: top;
  829. border-top: 1px solid #ddd;
  830. }
  831. .table th, .table td {
  832. vertical-align: middle;
  833. box-sizing: border-box;
  834. }
  835. th {
  836. text-align: left;
  837. }
  838. td, th {
  839. padding: 0;
  840. }
  841. .input-group-btn {
  842. position: relative;
  843. font-size: 0;
  844. white-space: nowrap;
  845. }
  846. .input-group-addon, .input-group-btn {
  847. white-space: nowrap;
  848. vertical-align: middle;
  849. }
  850. .input-group-addon, .input-group-btn, .input-group .form-control {
  851. display: table-cell;
  852. }
  853. .clearfix:before, .clearfix:after {
  854. content: " ";
  855. display: table;
  856. }
  857. .input-group-btn:last-child>.btn, .input-group-btn:last-child>.btn-group {
  858. z-index: 2;
  859. margin-left: -1px;
  860. }
  861. .input-group-btn:first-child>.btn, .input-group-btn:first-child>.btn-group {
  862. margin-right: -1px;
  863. }
  864. .input-group .form-control:last-child, .input-group-addon:last-child, .input-group-btn:last-child>.btn, .input-group-btn:last-child>.btn-group>.btn, .input-group-btn:last-child>.dropdown-toggle, .input-group-btn:first-child>.btn:not(:first-child), .input-group-btn:first-child>.btn-group:not(:first-child)>.btn {
  865. border-bottom-left-radius: 0;
  866. border-top-left-radius: 0;
  867. }
  868. .input-group .form-control:first-child, .input-group-addon:first-child, .input-group-btn:first-child>.btn, .input-group-btn:first-child>.btn-group>.btn, .input-group-btn:first-child>.dropdown-toggle, .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle), .input-group-btn:last-child>.btn-group:not(:last-child)>.btn {
  869. border-bottom-right-radius: 0;
  870. border-top-right-radius: 0;
  871. }
  872. .input-group-btn>.btn {
  873. position: relative;
  874. }
  875. .btn.disabled, .btn[disabled], fieldset[disabled] .btn {
  876. cursor: not-allowed;
  877. opacity: 0.65;
  878. filter: alpha(opacity=65);
  879. -webkit-box-shadow: none;
  880. box-shadow: none;
  881. }
  882. .btn-file {
  883. position: relative;
  884. overflow: hidden;
  885. margin: 0;
  886. top: 170px;
  887. left: 50%;
  888. margin-left: -45px !important;
  889. outline: none;
  890. cursor: pointer;
  891. }
  892. .btn {
  893. display: inline-block;
  894. margin-bottom: 0;
  895. font-weight: normal;
  896. text-align: center;
  897. vertical-align: middle;
  898. touch-action: manipulation;
  899. cursor: pointer;
  900. background-image: none;
  901. border: 1px solid transparent;
  902. white-space: nowrap;
  903. border-radius: 4px;
  904. -webkit-user-select: none;
  905. -moz-user-select: none;
  906. -ms-user-select: none;
  907. user-select: none;
  908. }
  909. .btn-file .add-file {
  910. background: url(http://cn-file.17pdf.com/website/fileinput/ic_file_add.png) no-repeat;
  911. width: 90px;
  912. height: 100px;
  913. }
  914. .btn-file .add-file-left {
  915. background: url(http://cn-file.17pdf.com/website/fileinput/ic_add.png) no-repeat;
  916. width: 120px;
  917. height: 30px;
  918. margin-top: 10px;
  919. margin-left: 10px;
  920. padding-left: 38px;
  921. font-size: 16px;
  922. line-height: 30px;
  923. color: #666666;
  924. }
  925. .btn-file-left {
  926. position: relative;
  927. top: 0px;
  928. left: 20px;
  929. }
  930. .transfer-container .transfer-remember .checkbox input[type="checkbox"] {
  931. top: 3px;
  932. }
  933. .radio input[type="radio"], .radio-inline input[type="radio"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] {
  934. position: absolute;
  935. margin-left: -20px;
  936. }
  937. input[type="radio"], input[type="checkbox"] {
  938. margin: 4px 0 0;
  939. line-height: normal;
  940. }
  941. .modal {
  942. display: none;
  943. overflow: hidden;
  944. position: fixed;
  945. top: 0;
  946. right: 0;
  947. bottom: 0;
  948. left: 0;
  949. z-index: 1050;
  950. -webkit-overflow-scrolling: touch;
  951. outline: 0;
  952. }
  953. .file-drop-zone .table tbody tr:hover td {
  954. background: #dfdfdf;
  955. }
  956. .file-drop-zone .table tbody tr td {
  957. border-top: 0px;
  958. }
  959. .theme-explorer .explorer-frame td {
  960. vertical-align: middle;
  961. text-align: center;
  962. }
  963. .file-drop-zone .table tbody tr:hover td .transfer-select {
  964. border-color: #ff4f4f;
  965. background: url(http://cn-file.17pdf.com/website/converter/ic_trans_xiala_hover.png) no-repeat 72px 6px;
  966. }
  967. .file-drop-zone .table tbody tr .transfer-select {
  968. width: 100%;
  969. height: 22px;
  970. border: 1px solid #dadada;
  971. padding: 0px;
  972. outline: none;
  973. font-size: 14px;
  974. color: #ff4f4f;
  975. line-height: 22px;
  976. // padding-left: 30px;
  977. border-radius: 2px;
  978. background: url(http://cn-file.17pdf.com/website/converter/ic_trans_xiala_nor.png) no-repeat 72px 6px;
  979. }
  980. .theme-explorer .file-actions-cell .file-actions .file-footer-buttons .pdf-removeicon:before {
  981. content: url(https://cn-file.17pdf.com/website/converter/ic_delet_red.png) !important;
  982. display: none;
  983. }
  984. .file-drop-zone .table tbody tr:hover td .file-actions .file-footer-buttons .pdf-removeicon:before {
  985. display: block;
  986. }
  987. .btn.disabledBtn {
  988. background-color: rgb(204, 204, 204);
  989. pointer-events: none;
  990. }
  991. .file_num {
  992. background: url(http://cn-file.17pdf.com/website/converter/pic_account_bg.png) repeat -10px 0px;
  993. }
  994. .clear {
  995. zoom: 1;
  996. }
  997. .clear:after {
  998. visibility: hidden;
  999. display: block;
  1000. font-size: 0;
  1001. content: " ";
  1002. clear: both;
  1003. height: 0;
  1004. }
  1005. .pdf_converter .package_type h3:before,
  1006. .about_converter .name:before,
  1007. .converter_question .name:before {
  1008. content: '';
  1009. display: inline-block;
  1010. width: 5px;
  1011. height: 22px;
  1012. background: #ff4f4f;
  1013. margin-right: 10px;
  1014. margin-top: 4px;
  1015. vertical-align: top;
  1016. }
  1017. .pdf_converter .package_type ul li {
  1018. width: 120px;
  1019. list-style: none;
  1020. text-align: center;
  1021. margin-right: 30px;
  1022. cursor: pointer;
  1023. a {
  1024. display: block;
  1025. font-size: 14px;
  1026. color: #333333;
  1027. img {
  1028. display: inline-block;
  1029. width: 80px;
  1030. height: 80px;
  1031. margin-bottom: 20px;
  1032. vertical-align: middle;
  1033. }
  1034. span {
  1035. display: block;
  1036. white-space: nowrap;
  1037. transition: all .5s;
  1038. }
  1039. }
  1040. }
  1041. .about_converter ul li {
  1042. width: 50%;
  1043. float: left;
  1044. list-style: none;
  1045. margin-bottom: 85px;
  1046. img {
  1047. width: 70px;
  1048. height: 70px;
  1049. float: left;
  1050. margin: 10px 36px 0px 0px;
  1051. }
  1052. .content {
  1053. width: 330px;
  1054. float: left;
  1055. h3 {
  1056. font-size: 20px;
  1057. color: #333333;
  1058. margin: 0px 0px 10px;
  1059. font-weight: normal;
  1060. }
  1061. p {
  1062. font-size: 16px;
  1063. color: #4c4c4c;
  1064. margin: 0px !important;
  1065. }
  1066. }
  1067. }
  1068. table {
  1069. border-collapse: collapse;
  1070. border-spacing: 0;
  1071. }
  1072. .converter_question table td {
  1073. width: 50%;
  1074. vertical-align: top;
  1075. h3 {
  1076. font-size: 18px;
  1077. color: #333333;
  1078. margin: 54px 0px 14px;
  1079. font-weight: normal;
  1080. text-align: left;
  1081. }
  1082. p {
  1083. width: 75%;
  1084. font-size: 16px;
  1085. color: #4c4c4c;
  1086. text-align: left;
  1087. span {
  1088. width: 8px;
  1089. height: 8px;
  1090. display: inline-block;
  1091. border-radius: 100%;
  1092. background: #333333;
  1093. margin-right: 12px;
  1094. margin-left: 4px;
  1095. }
  1096. }
  1097. }
  1098. .converter_question .more {
  1099. border-bottom: 1px solid #999999;
  1100. }
  1101. .download_code {
  1102. box-shadow: 0px 1px 5px rgb(0 0 0 / 12%);
  1103. }
  1104. .file-details-cell.state img {
  1105. display: inline-block;
  1106. cursor: pointer;
  1107. }
  1108. }
  1109. </style>