You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

399 lines
8.6 KiB

  1. <template>
  2. <el-dialog
  3. title="纸张管理"
  4. :visible.sync="dialogVisible"
  5. :close-on-click-modal="false"
  6. width="900px"
  7. top="5vh"
  8. custom-class="paper-management-dialog"
  9. :append-to-body="true"
  10. @close="handleDialogClose"
  11. >
  12. <div class="paper-management-content">
  13. <!-- 纸张表单区域 -->
  14. <div class="form-section">
  15. <PaperForm
  16. :paper-data="currentPaper"
  17. :is-edit-mode="isEditMode"
  18. :existing-papers="paperList"
  19. @save="handleSave"
  20. @cancel="handleCancel"
  21. />
  22. </div>
  23. <!-- 纸张列表区域 -->
  24. <div class="list-section">
  25. <PaperList
  26. :papers="paperList"
  27. :loading="listLoading"
  28. :table-height="300"
  29. @edit="handleEdit"
  30. @delete="handleDelete"
  31. @refresh="loadPaperList"
  32. @toggle-status="handleToggleStatus"
  33. />
  34. </div>
  35. </div>
  36. <!-- 对话框底部 -->
  37. <div slot="footer" class="dialog-footer">
  38. <div class="footer-info">
  39. <span class="paper-count">
  40. {{ paperList.length }} 个纸张规格
  41. ({{ activePaperCount }} 个启用)
  42. </span>
  43. </div>
  44. <div class="footer-actions">
  45. <el-button @click="handleClose">关闭</el-button>
  46. </div>
  47. </div>
  48. </el-dialog>
  49. </template>
  50. <script>
  51. import PaperForm from './PaperForm.vue'
  52. import PaperList from './PaperList.vue'
  53. import { getPaperList } from '@/api/labelSetting/paperManagement.js'
  54. import dynamicPaperConfig from '@/utils/paperConfigDynamic.js'
  55. export default {
  56. name: 'PaperManagementDialog',
  57. components: {
  58. PaperForm,
  59. PaperList
  60. },
  61. props: {
  62. visible: {
  63. type: Boolean,
  64. default: false
  65. }
  66. },
  67. emits: ['update:visible', 'paper-updated'],
  68. data() {
  69. return {
  70. paperList: [],
  71. currentPaper: null,
  72. isEditMode: false,
  73. listLoading: false,
  74. dialogVisible: false
  75. }
  76. },
  77. computed: {
  78. // 启用的纸张数量
  79. activePaperCount() {
  80. return this.paperList.filter(paper => paper.isActive).length
  81. }
  82. },
  83. watch: {
  84. visible: {
  85. handler(newVal) {
  86. this.dialogVisible = newVal
  87. if (newVal) {
  88. this.initDialog()
  89. }
  90. },
  91. immediate: true
  92. },
  93. dialogVisible(newVal) {
  94. // 当对话框关闭时,通知父组件
  95. this.$emit('update:visible', newVal)
  96. }
  97. },
  98. beforeDestroy() {
  99. // 确保组件销毁前清理状态
  100. this.paperList = []
  101. this.currentPaper = null
  102. this.isEditMode = false
  103. this.listLoading = false
  104. },
  105. methods: {
  106. // 初始化对话框
  107. async initDialog() {
  108. await this.loadPaperList()
  109. this.resetForm()
  110. },
  111. // 重置对话框状态
  112. resetDialog() {
  113. this.resetForm()
  114. this.paperList = []
  115. },
  116. // 加载纸张列表
  117. async loadPaperList() {
  118. try {
  119. this.listLoading = true
  120. const { data } = await getPaperList({
  121. site: this.$store.state.user.site
  122. })
  123. if (data.code === 200) {
  124. this.paperList = data.data || []
  125. // 更新动态纸张配置缓存
  126. this.paperList.forEach(paper => {
  127. dynamicPaperConfig.addPaperToCache(paper)
  128. })
  129. console.log('纸张列表加载成功:', this.paperList.length)
  130. } else {
  131. this.$message.error(data.msg || '加载纸张列表失败')
  132. this.paperList = []
  133. }
  134. } catch (error) {
  135. console.error('加载纸张列表失败:', error)
  136. this.$message.error('加载纸张列表失败,请重试')
  137. this.paperList = []
  138. } finally {
  139. this.listLoading = false
  140. }
  141. },
  142. // 保存纸张
  143. handleSave(savedPaper) {
  144. if (this.isEditMode) {
  145. // 更新模式:更新列表中的纸张
  146. const index = this.paperList.findIndex(p => p.id === savedPaper.id)
  147. if (index >= 0) {
  148. this.$set(this.paperList, index, savedPaper)
  149. }
  150. // 更新缓存
  151. dynamicPaperConfig.addPaperToCache(savedPaper)
  152. // 重置为新增模式
  153. this.resetForm()
  154. } else {
  155. // 新增模式:添加到列表
  156. this.paperList.unshift(savedPaper)
  157. // 更新缓存
  158. dynamicPaperConfig.addPaperToCache(savedPaper)
  159. }
  160. // 通知父组件纸张数据已更新
  161. this.$emit('paper-updated', {
  162. action: this.isEditMode ? 'update' : 'create',
  163. paper: savedPaper
  164. })
  165. },
  166. // 取消操作
  167. handleCancel() {
  168. this.resetForm()
  169. },
  170. // 编辑纸张
  171. handleEdit(paper) {
  172. this.currentPaper = { ...paper }
  173. this.isEditMode = true
  174. // 滚动到表单区域
  175. this.$nextTick(() => {
  176. const formSection = this.$el.querySelector('.form-section')
  177. if (formSection) {
  178. formSection.scrollIntoView({ behavior: 'smooth', block: 'start' })
  179. }
  180. })
  181. },
  182. // 删除纸张
  183. handleDelete(deletedPaper) {
  184. // 从列表中移除
  185. this.paperList = this.paperList.filter(p => p.id !== deletedPaper.id)
  186. // 从缓存中移除
  187. dynamicPaperConfig.removePaperFromCache(deletedPaper.id)
  188. // 如果删除的是当前编辑的纸张,重置表单
  189. if (this.isEditMode && this.currentPaper && this.currentPaper.id === deletedPaper.id) {
  190. this.resetForm()
  191. }
  192. // 通知父组件
  193. this.$emit('paper-updated', {
  194. action: 'delete',
  195. paper: deletedPaper
  196. })
  197. },
  198. // 切换纸张状态
  199. handleToggleStatus(updatedPaper) {
  200. // 更新列表中的纸张状态
  201. const index = this.paperList.findIndex(p => p.id === updatedPaper.id)
  202. if (index >= 0) {
  203. this.$set(this.paperList, index, updatedPaper)
  204. }
  205. // 更新缓存
  206. dynamicPaperConfig.addPaperToCache(updatedPaper)
  207. // 通知父组件
  208. this.$emit('paper-updated', {
  209. action: 'toggle-status',
  210. paper: updatedPaper
  211. })
  212. },
  213. // 重置表单
  214. resetForm() {
  215. this.currentPaper = null
  216. this.isEditMode = false
  217. },
  218. // 关闭对话框
  219. handleClose() {
  220. this.dialogVisible = false
  221. },
  222. // 对话框关闭事件处理
  223. handleDialogClose() {
  224. // 延迟清理状态,避免销毁时机冲突
  225. this.$nextTick(() => {
  226. this.resetDialog()
  227. })
  228. }
  229. }
  230. }
  231. </script>
  232. <style scoped>
  233. .paper-management-dialog {
  234. border-radius: 8px !important;
  235. }
  236. .paper-management-content {
  237. max-height: 70vh;
  238. overflow-y: auto;
  239. }
  240. .form-section {
  241. margin-bottom: 0;
  242. }
  243. .list-section {
  244. margin-top: 5px;
  245. }
  246. .dialog-footer {
  247. display: flex;
  248. justify-content: space-between;
  249. align-items: center;
  250. padding: 12px 0 0 0;
  251. border-top: 1px solid #e4e7ed;
  252. margin-top: 16px;
  253. }
  254. .footer-info {
  255. flex: 1;
  256. }
  257. .paper-count {
  258. font-size: 13px;
  259. color: #606266;
  260. }
  261. .footer-actions {
  262. display: flex;
  263. gap: 8px;
  264. }
  265. /* Element UI 分隔线样式 */
  266. .paper-management-content .el-divider {
  267. margin: 16px 0;
  268. }
  269. .paper-management-content .el-divider__text {
  270. background-color: #fff;
  271. color: #909399;
  272. font-size: 12px;
  273. }
  274. .paper-management-content .el-divider__text i {
  275. font-size: 14px;
  276. }
  277. /* 滚动条样式 */
  278. .paper-management-content::-webkit-scrollbar {
  279. width: 6px;
  280. }
  281. .paper-management-content::-webkit-scrollbar-track {
  282. background: #f1f1f1;
  283. border-radius: 3px;
  284. }
  285. .paper-management-content::-webkit-scrollbar-thumb {
  286. background: #c1c1c1;
  287. border-radius: 3px;
  288. }
  289. .paper-management-content::-webkit-scrollbar-thumb:hover {
  290. background: #a8a8a8;
  291. }
  292. /* 响应式调整 */
  293. @media (max-width: 1200px) {
  294. .paper-management-dialog {
  295. width: 95% !important;
  296. margin: 0 auto !important;
  297. }
  298. }
  299. @media (max-width: 768px) {
  300. .paper-management-dialog {
  301. width: 98% !important;
  302. top: 2vh !important;
  303. }
  304. .paper-management-content {
  305. max-height: 80vh;
  306. }
  307. .dialog-footer {
  308. flex-direction: column;
  309. gap: 12px;
  310. align-items: stretch;
  311. }
  312. .footer-info {
  313. text-align: center;
  314. }
  315. .footer-actions {
  316. justify-content: center;
  317. }
  318. }
  319. </style>
  320. <!-- 全局样式 -->
  321. <style>
  322. .paper-management-dialog {
  323. border-radius: 8px !important;
  324. box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12) !important;
  325. }
  326. .paper-management-dialog .el-dialog__header {
  327. padding: 16px 20px 12px !important;
  328. border-bottom: 1px solid #e4e7ed !important;
  329. background: #fafafa !important;
  330. }
  331. .paper-management-dialog .el-dialog__title {
  332. font-size: 16px !important;
  333. font-weight: 600 !important;
  334. color: #303133 !important;
  335. }
  336. .paper-management-dialog .el-dialog__body {
  337. padding: 20px !important;
  338. background: #fff !important;
  339. }
  340. .paper-management-dialog .el-dialog__footer {
  341. padding: 12px 20px 16px !important;
  342. border-top: 1px solid #e4e7ed !important;
  343. background: #fafafa !important;
  344. }
  345. </style>