PreviewDialog.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <template>
  2. <cus-dialog
  3. :visible="previewVisible"
  4. @on-close="previewVisible = false"
  5. ref="widgetPreview"
  6. form
  7. :title="$t('fm.actions.preview')"
  8. fullscreen
  9. class="fm-generate-preview-container"
  10. >
  11. <el-radio-group v-model="platform" size="mini" class="platform-controller">
  12. <el-radio-button label="pc"><i class="fm-iconfont icon-pc"/></el-radio-button>
  13. <el-radio-button label="pad"><i class="fm-iconfont icon-pad"/></el-radio-button>
  14. <el-radio-button label="mobile"><i class="fm-iconfont icon-mobile"/></el-radio-button>
  15. </el-radio-group>
  16. <div class="fm-generate-preview" :class="`${platform}`" v-loading="exportLoading || printLoading">
  17. <el-scrollbar style="height: 100%;">
  18. <generate-form preview :print-read="printRead" :platform="platform" :edit="formEdit" insite="true" v-if="previewVisible && showForm && (previewForm.config.ui == 'element' || !previewForm.config.ui)" :data="previewForm" :value="widgetModels" :remote="remoteFuncs" ref="generateForm">
  19. <template v-slot:blank="scope">
  20. Width<el-input v-model="scope.model.blank.width" style="width: 100px"></el-input>
  21. Height:<el-input v-model="scope.model.blank.height" style="width: 100px"></el-input>
  22. </template>
  23. </generate-form>
  24. <antd-generate-form preview :print-read="printRead" :platform="platform" :edit="formEdit" insite="true" v-if="previewVisible && showForm && previewForm.config.ui == 'antd'" :data="previewForm" :value="widgetModels" :remote="remoteFuncs" ref="generateAntForm">
  25. <template v-slot:blank="scope">
  26. <a-input
  27. v-decorator="[
  28. 'blank',
  29. {
  30. initialValue: scope.model.blank
  31. }
  32. ]"
  33. style="width: 100px"></a-input>
  34. </template>
  35. </antd-generate-form>
  36. </el-scrollbar>
  37. <div v-show="platform === 'mobile' && showQrcode" style=" position: absolute; top: 80px; left: 50%; margin-left: 220px;">
  38. <el-card shadow="never" :body-style="{
  39. padding: '15px'
  40. }">
  41. <div style="line-height: 20px; margin-bottom: 10px; ">{{$t('fm.description.qrcodePreview')}}</div>
  42. <div id="fmpreviewqrcode"></div>
  43. </el-card>
  44. </div>
  45. </div>
  46. <template slot="action">
  47. <el-button type="primary" @click="handleTest">{{$t('fm.actions.getData')}}</el-button>
  48. <el-button @click="handleReset">{{$t('fm.actions.reset')}}</el-button>
  49. <el-button @click="formEdit = false" v-if="formEdit" :disabled="printRead">{{$t('fm.actions.disabledEdit')}}</el-button>
  50. <el-button @click="formEdit = true" v-else :disabled="printRead">{{$t('fm.actions.enabledEdit')}}</el-button>
  51. <el-button @click="printRead = true" v-if="!printRead">{{$t('fm.actions.printReadMode')}}</el-button>
  52. <el-button @click="printRead = false" v-if="printRead">{{$t('fm.actions.editMode')}}</el-button>
  53. <el-button @click="handlePrint" :loading="printLoading">{{$t('fm.actions.print')}}</el-button>
  54. <el-button size="large" @click="handleExportPDF" :loading="exportLoading">{{$t('fm.actions.exportPDF')}}</el-button>
  55. <el-button @click="previewVisible = false" type="info" plain>{{$t('fm.actions.close')}}</el-button>
  56. </template>
  57. <PreviewPdf ref="pdfPreview"></PreviewPdf>
  58. </cus-dialog>
  59. </template>
  60. <script>
  61. import CusDialog from './CusDialog'
  62. import GenerateForm from './GenerateForm'
  63. import AntdGenerateForm from './AntdvGenerator/GenerateForm'
  64. import { consoleError } from '../util/index'
  65. import { Message } from 'element-ui'
  66. import PreviewPdf from './PreviewPdf.vue'
  67. export default {
  68. components: {
  69. CusDialog,
  70. GenerateForm,
  71. AntdGenerateForm,
  72. PreviewPdf
  73. },
  74. props: {
  75. },
  76. data () {
  77. return {
  78. previewVisible: false,
  79. showForm: false,
  80. formEdit: true,
  81. previewForm: {},
  82. widgetModels: {},
  83. remoteFuncs: {
  84. func_test (resolve) {
  85. setTimeout(() => {
  86. const options = [
  87. {id: '1', name: '1111'},
  88. {id: '2', name: '2222'},
  89. {id: '3', name: '3333'}
  90. ]
  91. resolve(options)
  92. }, 50)
  93. },
  94. funcGetToken (resolve) {
  95. request.get('https://tools-server.making.link/api/uptoken').then(res => {
  96. resolve(res.uptoken)
  97. })
  98. },
  99. upload_callback (response, file, fileList) {
  100. console.log('callback', response, file, fileList)
  101. },
  102. },
  103. platform: 'pc',
  104. printRead: false,
  105. showQrcode: false,
  106. exportLoading: false,
  107. printLoading: false
  108. }
  109. },
  110. methods: {
  111. generateQrcode (url) {
  112. if (!window.QRCode) {
  113. consoleError('QRCode is not defined')
  114. return false
  115. }
  116. setTimeout(() => {
  117. this.showQrcode = true
  118. var qrcode = new QRCode(document.getElementById("fmpreviewqrcode"), {
  119. width : 120,
  120. height : 120
  121. });
  122. qrcode.makeCode(url)
  123. }, 500)
  124. },
  125. preview (data, platform) {
  126. this.previewForm = data
  127. this.formEdit = this.previewVisible = true
  128. this.printRead = false
  129. this.showQrcode = false
  130. this.platform = platform
  131. this.$nextTick(() => {
  132. window.document.getElementsByClassName('fm-generate-preview-container')?.[0].removeAttribute('tabindex')
  133. this.showForm = true
  134. })
  135. },
  136. handleTest () {
  137. const $form = this.previewForm.config.ui == 'element' || !this.previewForm.config.ui ?
  138. this.$refs.generateForm : this.$refs.generateAntForm
  139. $form.getData().then(data => {
  140. this.$emit('get-data-success', data)
  141. this.$refs.widgetPreview.end()
  142. }).catch(e => {
  143. Message.error(e)
  144. this.$refs.widgetPreview.end()
  145. })
  146. },
  147. handleReset () {
  148. const $form = this.previewForm.config.ui == 'element' || !this.previewForm.config.ui ?
  149. this.$refs.generateForm : this.$refs.generateAntForm
  150. $form.reset()
  151. },
  152. handleExportWord () {
  153. var rules = "",
  154. ss = document.styleSheets;
  155. for (var i = 0; i < ss.length; ++i) {
  156. for (var x = 0; x < ss[i].cssRules.length; ++x) {
  157. rules += ss[i].cssRules[x].cssText;
  158. }
  159. }
  160. var header = `<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'>
  161. <head><meta charset='utf-8'><title>Export HTML to Word Document with JavaScript</title>
  162. <style>${rules}</style>
  163. </head><body>`;
  164. var footer = "</body></html>";
  165. var html = header+document.getElementById('export-id').innerHTML+footer;
  166. var blob = new Blob(['\ufeff', html], {
  167. type: 'application/msword'
  168. });
  169. // Specify link url
  170. var url = 'data:application/vnd.ms-word;charset=utf-8,' + encodeURIComponent(html);
  171. // Specify file name
  172. let filename = filename?filename+'.doc':'document.doc';
  173. // Create download link element
  174. var downloadLink = document.createElement("a");
  175. document.body.appendChild(downloadLink);
  176. if(navigator.msSaveOrOpenBlob ){
  177. navigator.msSaveOrOpenBlob(blob, filename);
  178. }else{
  179. // Create a link to the file
  180. downloadLink.href = url;
  181. // Setting the file name
  182. downloadLink.download = filename;
  183. //triggering the function
  184. downloadLink.click();
  185. }
  186. document.body.removeChild(downloadLink);
  187. },
  188. handlePrint () {
  189. const tempPrint = this.printRead
  190. this.printLoading = true
  191. setTimeout(() => {
  192. this.printRead = true
  193. this.$nextTick(() => {
  194. const $form = this.previewForm.config.ui == 'element' || !this.previewForm.config.ui ?
  195. this.$refs.generateForm : this.$refs.generateAntForm
  196. $form.print().then().finally(() => {
  197. this.printLoading = false
  198. this.printRead = tempPrint
  199. })
  200. })
  201. }, 100)
  202. },
  203. handleExportPDF () {
  204. const tempPrint = this.printRead
  205. this.exportLoading = true
  206. setTimeout(() => {
  207. this.printRead = true
  208. this.$nextTick(() => {
  209. const $form = this.previewForm.config.ui == 'element' || !this.previewForm.config.ui ?
  210. this.$refs.generateForm : this.$refs.generateAntForm
  211. $form.exportPDF().then(data => {
  212. this.$refs.pdfPreview.open(data)
  213. }).finally(() => {
  214. this.exportLoading = false
  215. this.printRead = tempPrint
  216. })
  217. })
  218. }, 100)
  219. }
  220. }
  221. }
  222. </script>
  223. <style lang="scss">
  224. .fm-generate-preview-container{
  225. .platform-controller{
  226. position: absolute;
  227. // width: 120px;
  228. top: 50px;
  229. z-index: 5000;
  230. left: 20px;
  231. // margin-left: -60px;
  232. }
  233. .fm-generate-preview{
  234. margin-top: 15px !important;
  235. }
  236. }
  237. @media print{
  238. .fm-design-container{
  239. display: none;
  240. }
  241. .fm-generate-preview-container{
  242. position: relative;
  243. .el-dialog{
  244. display: block;
  245. }
  246. .el-dialog__header{
  247. display: none;
  248. }
  249. .el-dialog__footer{
  250. display: none;
  251. }
  252. .el-dialog__body{
  253. padding: 0;
  254. display: block;
  255. .fm-generate-preview{
  256. box-shadow: none;
  257. border: 0;
  258. }
  259. }
  260. .platform-controller{
  261. display: none;
  262. }
  263. }
  264. }
  265. </style>