index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. <!--onlyoffice 编辑器-->
  2. <template>
  3. <div style="height:100%;width:100%" v-loading="loading">
  4. <div class="menu_btn">
  5. <el-button size="small" type="primary" @click="saveNewFile">保存新文件</el-button>
  6. </div>
  7. <div id='vabOnlyOffice' v-if="show"></div>
  8. <addNewFile ref="addNewFile"></addNewFile>
  9. </div>
  10. </template>
  11. <script>
  12. import addNewFile from './addNewFile.vue'
  13. import mixins from './index.js'
  14. export default {
  15. name: 'VabOnlyOffice',
  16. components:{
  17. addNewFile
  18. },
  19. mixins:[mixins],
  20. props: {
  21. option: {
  22. type: Object,
  23. default: () => {
  24. return {}
  25. },
  26. },
  27. },
  28. data() {
  29. return {
  30. doctype: '',
  31. docEditor: null,
  32. loading:false,
  33. show:true,
  34. currentVersion:{},
  35. historyData:[]
  36. }
  37. },
  38. beforeDestroy() {
  39. if (this.docEditor !== null) {
  40. this.docEditor.destroyEditor();
  41. this.docEditor = null;
  42. }
  43. },
  44. watch: {
  45. // option: {
  46. // handler: function(n) {
  47. // this.setEditor(n)
  48. // this.doctype = this.getFileType(n.fileType)
  49. // },
  50. // deep: true,
  51. // },
  52. },
  53. mounted() {
  54. if (this.option.url) {
  55. this.setEditor(this.option)
  56. }
  57. },
  58. methods: {
  59. async insetText(){
  60. console.log(this.docEditor,this.docEditor.connector())
  61. return
  62. // document.execCommand('insertText', true, '插入的文本')
  63. // return
  64. // this.docEditor.blurFocus('要复制的文本内容')
  65. // this.setClipboardText('要复制的文本内容').then(() => {
  66. // console.log('复制成功');
  67. // document.execCommand('paste');
  68. // console.log(document.execCommand('paste'))
  69. // }).catch(err => {
  70. // console.error('复制失败', err);
  71. // })
  72. // await navigator.clipboard.writeText('插入的文本')
  73. // var dom = Api.createParagraph();
  74. // dom.addText('插入的文本')
  75. var connector = this.docEditor.createConnector()
  76. console.log(connector)
  77. connector.callCommand(function(){
  78. var dom = Api.createParagraph();
  79. dom.addText('插入的文本')
  80. },function(){
  81. console.log('123')
  82. })
  83. console.log(window.AscEmbed.initWorker)
  84. window.Asc.plugin.callCommand(function() {
  85. var oWorksheet = Api.createParagraph();
  86. oWorksheet.addText('插入的文本')
  87. }, true);
  88. },
  89. setClipboardText(text) {
  90. return new Promise((resolve, reject) => {
  91. const clipboard = navigator.clipboard;
  92. if (clipboard && clipboard.writeText) {
  93. clipboard.writeText(text)
  94. .then(() => resolve())
  95. .catch(error => reject(error));
  96. } else {
  97. const textArea = document.createElement('textarea');
  98. textArea.value = text;
  99. // 防止元素显示在屏幕上
  100. textArea.style.position = 'fixed';
  101. textArea.style.top = '0';
  102. textArea.style.left = '0';
  103. textArea.style.width = '2em';
  104. textArea.style.height = '2em';
  105. textArea.style.padding = '0';
  106. textArea.style.border = 'none';
  107. textArea.style.outline = 'none';
  108. textArea.style.boxShadow = 'none';
  109. textArea.style.background = 'transparent';
  110. document.body.appendChild(textArea);
  111. textArea.select();
  112. try {
  113. const successful = document.execCommand('copy');
  114. successful ? resolve() : reject();
  115. } catch (err) {
  116. reject(err);
  117. }
  118. document.body.removeChild(textArea);
  119. }
  120. });
  121. },
  122. async setEditor(option) {
  123. if (this.docEditor !== null) {
  124. this.docEditor.destroyEditor();
  125. this.docEditor = null;
  126. }
  127. var params = {
  128. guid:this.option.id,
  129. }
  130. await this.$api.getCurrentVersionData(params).then(response=>{
  131. if(response.code == 200){
  132. if(response.data && response.data.fileType){
  133. var obj = response.data
  134. this.option.fileType=obj.fileType,
  135. this.option.key=obj.key,
  136. this.option.version = obj.version
  137. this.option.url=this.$c.url+ (this.$c.env=='production'?'/api':'')+'/fileManager/downloadFile?fileId=' +obj.url
  138. }
  139. }
  140. })
  141. this.doctype = this.getFileType(option.fileType)
  142. var user={
  143. id:option.user.id,
  144. name:option.user.name
  145. }
  146. let config = {
  147. document: {
  148. //后缀
  149. fileType: option.fileType,
  150. key: option.key ||'',
  151. title: option.title,
  152. permissions: {
  153. edit: option.isEdit,//是否可以编辑: 只能查看,传false
  154. print: option.isPrint,
  155. download: true,
  156. fillForms: true,//是否可以填写表格,如果将mode参数设置为edit,则填写表单仅对文档编辑器可用。 默认值与edit或review参数的值一致。
  157. review: true, //跟踪变化
  158. comment:true,//是否可以注释文档
  159. copy:true,
  160. chat: true,
  161. },
  162. url: option.url,
  163. },
  164. documentType: this.doctype,
  165. editorConfig: {
  166. // callbackUrl: 'http://192.168.2.24:8803/Test/TestQuery',//"编辑word后保存时回调的地址,这个api需要自己写了,将编辑后的文件通过这个api保存到自己想要的位置
  167. callbackUrl: `http://192.168.2.103:5000/onlyOffice/callback?guid=${option.id}&created=${option.created}&user=${JSON.stringify(user)}&previousVersion=${option.version}`,//"编辑word后保存时回调的地址,这个api需要自己写了,将编辑后的文件通过这个api保存到自己想要的位置
  168. lang: option.lang,//语言设置
  169. //定制
  170. customization: {
  171. comments:true,
  172. about:false,
  173. autosave: false,//是否自动保存
  174. forcesave:true,
  175. help: false,
  176. // "hideRightMenu": false,//定义在第一次加载时是显示还是隐藏右侧菜单。 默认值为false
  177. //是否显示插件
  178. plugins: false,
  179. // "about": true,
  180. // "feedback": false
  181. // customer:{
  182. // logo:'https://www.xsip.cn/api/fileManager/downloadFile?fileId=9ba11d7c72d24387a8cb2f484c23e0a5',
  183. // address:'',
  184. // info:'',
  185. // logoDark:'https://www.xsip.cn/api/fileManager/downloadFile?fileId=9ba11d7c72d24387a8cb2f484c23e0a5',
  186. // mail:'',
  187. // name:'',
  188. // www:'',
  189. // },
  190. logo: {
  191. // image: "https://www.xsip.cn/api/fileManager/downloadFile?fileId=9ba11d7c72d24387a8cb2f484c23e0a5",
  192. // imageDark: "https://www.xsip.cn/api/fileManager/downloadFile?fileId=9ba11d7c72d24387a8cb2f484c23e0a5",
  193. // url: "",
  194. visible: false,
  195. },
  196. },
  197. user:user,
  198. mode:option.model?option.model:'edit',
  199. // "canCoAuthoring": true
  200. },
  201. events:{
  202. onRequestHistory:this.onRequestHistory,//获取历史记录
  203. onRequestHistoryData:this.onRequestHistoryData,//获取历史文件
  204. onRequestRestore:this.onRequestRestore,//恢复
  205. onRequestHistoryClose:this.onRequestHistoryClose,//关闭历史
  206. },
  207. width: '100%',
  208. height: '100%',
  209. token:option.token||'',
  210. // frameEditorId: "vabOnlyOffice",
  211. // parentOrigin: window.location.origin,
  212. // type: "desktop"
  213. }
  214. if(!config.token){
  215. //获取token并赋值
  216. var data = {
  217. jsons:JSON.stringify(config)
  218. }
  219. this.loading = true
  220. await this.$api.GetJWT(data).then(response=>{
  221. if(response.code == 200){
  222. config.token = response.data
  223. this.option.token = response.data
  224. this.loading = false
  225. }
  226. }).catch(error=>{
  227. this.loading = false
  228. })
  229. // config.token = this.getJWT(config)
  230. }
  231. // eslint-disable-next-line no-undef,no-unused-vars
  232. this.docEditor = new DocsAPI.DocEditor('vabOnlyOffice', config)
  233. },
  234. async onRequestHistory(event){
  235. var params = {
  236. guid:this.option.id
  237. }
  238. var that = this
  239. await this.$api.queryFileVersion(params).then(response=>{
  240. if(response.code == 200){
  241. that.currentVersion = response.data.currentVersion
  242. that.historyData = response.data.history
  243. }
  244. })
  245. if(this.historyData.length == 0 || !this.currentVersion){
  246. that.docEditor.refreshHistory({
  247. currentVersion:'',
  248. history:[]
  249. })
  250. return
  251. }
  252. var currentVersion = this.currentVersion.currentVersion
  253. this.option.version = currentVersion
  254. var history = []
  255. for(var i = 0;i<that.historyData.length;i++){
  256. var item = that.historyData[i]
  257. history.push(
  258. {
  259. serverVersion:item.serverVersion,
  260. // changes:item.changes,
  261. created:item.created,
  262. user:item.user,
  263. version:item.version,
  264. key:item.key,
  265. }
  266. )
  267. }
  268. history.reverse()
  269. this.docEditor.refreshHistory(
  270. {
  271. currentVersion:currentVersion,
  272. history:history
  273. }
  274. )
  275. return
  276. },
  277. async onRequestHistoryData(event){
  278. const version = event.data
  279. var obj = this.historyData.find(item=>{
  280. return item.version == version
  281. })
  282. if(obj){
  283. var obj1 = null
  284. if(obj.previousVersion){
  285. obj1 = this.historyData.find(item=>{
  286. return item.version == obj.previousVersion
  287. })
  288. }
  289. var obj2 = {
  290. fileType:obj.fileType,
  291. key:obj.key,
  292. url:this.$c.url+ (this.$c.env=='production'?'/api':'')+'/fileManager/downloadFile?fileId=' +obj.url,
  293. version:obj.version,
  294. // previous:obj1?{
  295. // fileType:obj1.fileType,
  296. // key:obj1.key,
  297. // url:this.$c.url+ (this.$c.env=='production'?'/api':'')+'/fileManager/downloadFile?fileId=' +obj1.url,
  298. // }:null,
  299. // changesUrl:obj.changesUrl?(this.$c.url+ (this.$c.env=='production'?'/api':'')+'/fileManager/downloadFile?fileId=' +obj.changesUrl):""
  300. }
  301. var params = {
  302. jsons:JSON.stringify(obj2)
  303. }
  304. this.loading = true
  305. await this.$api.GetJWT(params).then(response=>{
  306. if(response.code == 200){
  307. obj2.token = response.data
  308. this.option.token = response.data
  309. this.loading = false
  310. }
  311. }).catch(error=>{
  312. this.loading = false
  313. })
  314. this.docEditor.setHistoryData(obj2)
  315. }
  316. },
  317. //恢复
  318. onRequestRestore(event){
  319. const version = event.data.version
  320. var params = {
  321. userId:this.option.user.id,
  322. userName:this.option.user.name,
  323. restoreVersion:version,
  324. previousVersion:this.option.version,
  325. guid:this.option.id
  326. }
  327. this.$api.restoreVersion(params).then(response=>{
  328. if(response.code == 200){
  329. this.setEditor(this.option)
  330. }
  331. })
  332. },
  333. onRequestHistoryClose(event){
  334. this.setEditor(this.option)
  335. },
  336. getFileType(fileType) {
  337. let docType = ''
  338. let fileTypesDoc = [
  339. 'doc', 'docm', 'docx', 'dot', 'dotm', 'dotx', 'epub', 'fodt', 'htm', 'html', 'mht', 'odt', 'ott', 'pdf', 'rtf', 'txt', 'djvu', 'xps',
  340. ]
  341. let fileTypesCsv = [
  342. 'csv', 'fods', 'ods', 'ots', 'xls', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx',
  343. ]
  344. let fileTypesPPt = [
  345. 'fodp', 'odp', 'otp', 'pot', 'potm', 'potx', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx',
  346. ]
  347. if (fileTypesDoc.includes(fileType)) {
  348. docType = 'text'
  349. }
  350. if (fileTypesCsv.includes(fileType)) {
  351. docType = 'spreadsheet'
  352. }
  353. if (fileTypesPPt.includes(fileType)) {
  354. docType = 'presentation'
  355. }
  356. return docType
  357. },
  358. },
  359. }
  360. </script>
  361. <style>
  362. .extra #header-logo i{
  363. background-image: url('../../assets/logo.png') !important;
  364. }
  365. </style>
  366. <style lang="scss" scoped>
  367. .menu_btn{
  368. height: 45px;
  369. padding: 0 20px;
  370. display: flex;
  371. align-items: center;
  372. flex-direction: row-reverse;
  373. }
  374. </style>