TemplatePreviewEdit.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <template>
  2. <el-tabs
  3. v-model="currentTab"
  4. class="template-tabs"
  5. type="card"
  6. @tab-change="handleTabChange"
  7. >
  8. <el-tab-pane label="预览" name="preview">
  9. <div v-if="url" class="template-preview">
  10. <div class="file-preview">
  11. <FilePreview :file-url="url"></FilePreview>
  12. </div>
  13. </div>
  14. <div v-else class="template-preview-empty">
  15. <p>请先上传模板文件</p>
  16. </div>
  17. </el-tab-pane>
  18. <el-tab-pane v-if="isShowEdit" label="编辑" name="edit">
  19. <div class="template-edit">
  20. <div class="file-edit-section">
  21. <div v-if="url" class="reupload-section">文件编辑</div>
  22. <div v-else class="template-edit-empty">
  23. <p>请先上传模板文件</p>
  24. </div>
  25. </div>
  26. </div>
  27. </el-tab-pane>
  28. </el-tabs>
  29. </template>
  30. <script>
  31. import FilePreview from './FilePreview.vue'
  32. export default {
  33. name: 'TemplatePreviewEdit',
  34. components: { FilePreview },
  35. props: {
  36. activeTab: {
  37. type: String,
  38. default: 'preview',
  39. },
  40. fileUrl: {
  41. type: String,
  42. default: '',
  43. },
  44. isShowBtn: {
  45. type: Boolean,
  46. default: false,
  47. },
  48. isShowEdit: {
  49. type: Boolean,
  50. default: true,
  51. },
  52. },
  53. data() {
  54. return {
  55. currentTab: this.activeTab, // 创建本地数据属性
  56. }
  57. },
  58. computed: {
  59. // 计算属性
  60. url() {
  61. return this.fileUrl
  62. },
  63. },
  64. watch: {
  65. // 监听 prop 变化,更新本地状态
  66. activeTab(newVal) {
  67. this.currentTab = newVal
  68. },
  69. },
  70. methods: {
  71. // 处理标签页切换事件
  72. handleTabChange(tabName) {
  73. this.currentTab = tabName
  74. this.$emit('tab-change', tabName) // 通知父组件
  75. },
  76. onReupload() {
  77. this.$emit('reupload')
  78. },
  79. onInsertTag(tag) {
  80. this.$emit('insert-tag', tag)
  81. },
  82. onExtractTableData() {
  83. this.$emit('extract-table-data')
  84. },
  85. onGenerateTemplateFromTable() {
  86. this.$emit('generate-template-from-table')
  87. },
  88. },
  89. }
  90. </script>
  91. <style scoped>
  92. .template-tabs {
  93. height: 100%;
  94. }
  95. .template-tabs ::v-deep .el-tabs__nav {
  96. display: flex;
  97. width: 100%;
  98. }
  99. .template-tabs ::v-deep .el-tabs__item {
  100. flex: 1;
  101. text-align: center;
  102. width: 50%;
  103. }
  104. .template-tabs {
  105. margin-bottom: 20px;
  106. }
  107. .template-preview {
  108. min-height: 300px;
  109. border: 1px solid #e4e7ed;
  110. border-radius: 4px;
  111. background-color: #fafafa;
  112. overflow: hidden;
  113. }
  114. .template-preview-empty,
  115. .template-edit-empty {
  116. min-height: 300px;
  117. display: flex;
  118. align-items: center;
  119. justify-content: center;
  120. border: 1px dashed #dcdfe6;
  121. border-radius: 4px;
  122. color: #909399;
  123. background-color: #fafafa;
  124. }
  125. .file-preview {
  126. height: 100%;
  127. display: flex;
  128. flex-direction: column;
  129. }
  130. .file-info {
  131. padding: 15px;
  132. background-color: #ecf5ff;
  133. border-bottom: 1px solid #dcdfe6;
  134. display: flex;
  135. align-items: center;
  136. gap: 10px;
  137. }
  138. .file-type-badge {
  139. background-color: #409eff;
  140. color: white;
  141. padding: 2px 8px;
  142. border-radius: 10px;
  143. font-size: 12px;
  144. }
  145. .pdf-preview-placeholder,
  146. .word-preview-placeholder,
  147. .table-preview-placeholder {
  148. flex: 1;
  149. display: flex;
  150. flex-direction: column;
  151. align-items: center;
  152. justify-content: center;
  153. color: #909399;
  154. padding: 20px;
  155. text-align: center;
  156. overflow-y: auto;
  157. }
  158. .table-preview-sample {
  159. width: 100%;
  160. margin-top: 20px;
  161. text-align: left;
  162. }
  163. .table-preview-sample h5 {
  164. margin: 0 0 10px 0;
  165. font-size: 14px;
  166. color: #606266;
  167. }
  168. .template-edit {
  169. min-height: 300px;
  170. }
  171. .file-edit-section {
  172. height: 100%;
  173. display: flex;
  174. flex-direction: column;
  175. gap: 15px;
  176. padding: 10px;
  177. border: 1px solid #e4e7ed;
  178. border-radius: 4px;
  179. background-color: #fafafa;
  180. }
  181. .tag-insert-section,
  182. .edit-instructions,
  183. .table-specific-actions {
  184. background-color: #fff;
  185. padding: 15px;
  186. border-radius: 4px;
  187. border: 1px solid #e4e7ed;
  188. }
  189. .tags-list {
  190. display: flex;
  191. flex-wrap: wrap;
  192. gap: 10px;
  193. margin-top: 10px;
  194. }
  195. .insertable-tag {
  196. cursor: pointer;
  197. user-select: none;
  198. }
  199. .insertable-tag:hover {
  200. color: #409eff;
  201. border-color: #409eff;
  202. }
  203. .edit-instructions ul {
  204. margin: 10px 0 0 20px;
  205. padding: 0;
  206. }
  207. .edit-instructions li {
  208. margin-bottom: 5px;
  209. color: #606266;
  210. }
  211. .reupload-section {
  212. display: flex;
  213. gap: 10px;
  214. align-items: center;
  215. padding: 10px;
  216. background-color: #fff;
  217. border-radius: 4px;
  218. border: 1px solid #e4e7ed;
  219. }
  220. .button-bar {
  221. text-align: center;
  222. margin-top: 20px;
  223. }
  224. </style>