AIModal.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <script>
  2. export default {
  3. name: 'AIModal',
  4. props: {
  5. url: {
  6. type: String,
  7. default: '',
  8. },
  9. immediate: {
  10. type: Boolean,
  11. default: false,
  12. },
  13. id: String,
  14. title: String,
  15. },
  16. computed: {
  17. realUrl() {
  18. if (this.url.startsWith(`http`)) return this.url;
  19. const url = this.url.startsWith('/') ? this.url.slice(1) : this.url;
  20. return location.href.includes(`index.html`)
  21. ? location.href.replace(location.search, '').replace(location.hash, '').split('index.html')[0] + url
  22. : location.origin + '/' + url;
  23. },
  24. realSrc() {
  25. if (!this.sessionId) this.sessionId = Date.now() + Array.from({length: 16}, () => Math.floor(Math.random() * 16).toString(16)).join('');
  26. const [url, search] = this.realUrl.split('?');
  27. const params = new URLSearchParams(search);
  28. if (!params.has('session_id')) params.append('session_id', this.sessionId);
  29. if (!this.hideTitle) params.delete('hide_title');
  30. else if (!params.has('hide_title')) params.append('hide_title', true);
  31. return `${url}?${params.toString()}`;
  32. },
  33. },
  34. data() {
  35. return {
  36. modalLoaded: false,
  37. modalProps: {
  38. show: false,
  39. type: 'modal',
  40. remember: true,
  41. position: {
  42. top: 0,
  43. left: 0,
  44. },
  45. padding: false,
  46. showMinimize: true,
  47. resize: true,
  48. mask: false, lockView: false, lockScroll: false,
  49. showClose: true, escClosable: true,
  50. loading: true,
  51. title: ' ',
  52. width: Math.min(430, window.innerWidth * 0.6),
  53. height: Math.min(932, window.innerHeight * 0.8),
  54. },
  55. sessionId: '',
  56. hideTitle: true,
  57. };
  58. },
  59. methods: {
  60. handle() {
  61. if (this.modalProps.show && this.$refs.modal.isMinimized) this.$refs.modal.revert();
  62. else {
  63. if (!this.sessionId) this.modalProps.loading = true;
  64. this.modalProps.show = true;
  65. setTimeout(() => { try { this.$refs.kiosk.contentDocument.querySelector('#message-input').focus(); } catch (e) {} }, 1000);
  66. }
  67. },
  68. load() {
  69. const iframe = this.$refs.kiosk;
  70. this.modalProps.loading = false;
  71. this.modalProps.title = iframe.contentDocument.title;
  72. try { this.$refs.kiosk.contentDocument.querySelector('#message-input').focus(); } catch (e) {}
  73. },
  74. onClose({type, $event}) {
  75. if (!$event) $event = {};
  76. if (type === 'close' && !$event.shiftKey) this.sessionId = '';
  77. },
  78. },
  79. mounted() {
  80. this.modalProps.showClose = !this.immediate;
  81. if (this.immediate) {
  82. this.handle();
  83. setTimeout(() => {
  84. this.$refs.modal.minimize();
  85. this.modalLoaded = true;
  86. }, 2000);
  87. } else this.modalLoaded = true;
  88. },
  89. };
  90. </script>
  91. <template>
  92. <div>
  93. <slot :handle="handle" :title="modalProps.title" :open="modalProps.show">
  94. <div v-if="!modalProps.show" @click="handle()">{{ title || modalProps.title }}</div>
  95. </slot>
  96. <vxe-modal :class="{initialize: immediate && !modalLoaded}" ref="modal" v-bind="modalProps"
  97. v-model="modalProps.show" :id="id" :esc-closable="modalProps.escClosable" @close="onClose">
  98. <iframe ref="kiosk" :src="realSrc" style="display: block;width: 100%;height: 100%;border: 0;"
  99. @load="load"></iframe>
  100. </vxe-modal>
  101. </div>
  102. </template>
  103. <style scoped lang="scss">
  104. .vxe-modal--wrapper.initialize {
  105. display: none;
  106. }
  107. </style>