index.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <template>
  2. <headerBar title="编辑模板" />
  3. <marketingEdit
  4. v-model:data="data"
  5. v-model:index="index"
  6. :goods_text="defaultGoodsText"
  7. :goods_images="goodsImages"
  8. @save="save"
  9. />
  10. <el-dialog
  11. v-model="showNameDialog"
  12. title="输入模板名称"
  13. :close-on-click-modal="false"
  14. :close-on-press-escape="false"
  15. width="400px"
  16. >
  17. <el-input
  18. v-model="templateName"
  19. placeholder="请输入模板名称"
  20. maxlength="50"
  21. show-word-limit
  22. />
  23. <template #footer>
  24. <el-button @click="showNameDialog = false">取消</el-button>
  25. <el-button type="primary" @click="confirmName">确定</el-button>
  26. </template>
  27. </el-dialog>
  28. </template>
  29. <script setup lang="ts">
  30. import { computed, ref } from 'vue';
  31. import { useRoute, useRouter } from 'vue-router';
  32. import { ElMessage } from 'element-plus';
  33. import headerBar from "@/components/header-bar/index.vue";
  34. import marketingEdit from '@/views/components/marketingEdit/index.vue'
  35. import useClientStore from '@/stores/modules/client'
  36. import { saveCustomerTemplate } from '@/apis/other'
  37. const route = useRoute();
  38. const router = useRouter();
  39. const clientStore = useClientStore();
  40. const isEdit = !!route.params.id;
  41. const data = ref([])
  42. const index = ref(0)
  43. const templateName = ref('')
  44. const showNameDialog = ref(false) // 由"保存"触发,而不是进入页面就弹
  45. const pendingPayload = ref<any | null>(null)
  46. // 编辑模式:从sessionStorage中还原模板数据和名称
  47. if (isEdit) {
  48. const templateDataStr = sessionStorage.getItem('editTpl_template_data')
  49. if (templateDataStr) {
  50. try {
  51. const templateData = JSON.parse(templateDataStr)
  52. // 还原画布 JSON
  53. if (templateData.customer_template_json && Array.isArray(templateData.customer_template_json)) {
  54. data.value = templateData.customer_template_json
  55. }
  56. // 名称直接取 template_name,取不到则为空
  57. templateName.value = (templateData.template_name || '') as string
  58. // 清理sessionStorage,避免数据残留
  59. sessionStorage.removeItem('editTpl_template_data')
  60. } catch (e) {
  61. console.error('解析 editTpl_template_data 失败:', e)
  62. }
  63. }
  64. }
  65. // 默认商品文案
  66. const defaultGoodsText = [
  67. {
  68. key: '设计理念',
  69. value: '经典凹出兼具动感同时带来轻盈\n步调轻软,松弛自在蔓延\n立体质感让朝气肆意绽放'
  70. },
  71. {
  72. key: '标题',
  73. value: '休闲运动'
  74. },
  75. {
  76. key: '帮面',
  77. value: '网布+合成革'
  78. },
  79. {
  80. key: '鞋底',
  81. value: '橡胶底'
  82. },
  83. {
  84. key: '颜色',
  85. value: '黑色'
  86. }
  87. ]
  88. // 从sessionStorage中解析 goods_images,如果没有就使用默认示例
  89. const defaultGoodsImages = []
  90. const goodsImages = computed(() => {
  91. // 新增模式:从sessionStorage获取数据
  92. const templateDataStr = sessionStorage.getItem('addTpl_template_data')
  93. if (templateDataStr) {
  94. try {
  95. const templateData = JSON.parse(templateDataStr)
  96. if (templateData.customer_template_images && Array.isArray(templateData.customer_template_images)) {
  97. // 清理sessionStorage,避免数据残留
  98. sessionStorage.removeItem('addTpl_template_data')
  99. return templateData.customer_template_images
  100. }
  101. } catch (e) {
  102. console.error('解析 addTpl_template_data 失败:', e)
  103. }
  104. }
  105. // 编辑模式或其他情况返回默认值
  106. return defaultGoodsImages
  107. })
  108. // 新增模式:从sessionStorage中获取template_image_order
  109. const templateImageOrder = computed(() => {
  110. const templateDataStr = sessionStorage.getItem('addTpl_template_data')
  111. if (templateDataStr) {
  112. try {
  113. const templateData = JSON.parse(templateDataStr)
  114. return templateData.template_image_order || ''
  115. } catch (e) {
  116. console.error('解析 addTpl_template_data 失败:', e)
  117. }
  118. }
  119. return ''
  120. })
  121. const doSave = async (payload: any) => {
  122. try {
  123. // 组装请求参数
  124. const requestData: any = {
  125. customer_template_json: payload, // 所有画布的 JSON
  126. }
  127. // 编辑时必填 id
  128. if (isEdit) {
  129. requestData.id = route.params.id
  130. requestData.template_name = templateName.value?.trim() || ''
  131. // 编辑时使用原来的模板名称(不传 template_name,让后端保持原值)
  132. } else {
  133. // 新增时必填模板名称
  134. requestData.template_name = templateName.value?.trim() || ''
  135. }
  136. // 封面图:取第一张画布的 preview
  137. if (payload && payload.length > 0 && payload[0].preview) {
  138. requestData.template_cover_image = payload[0].preview
  139. }
  140. requestData.customer_template_images = goodsImages.value
  141. requestData.template_image_order = templateImageOrder.value || undefined
  142. // 直接从 goodsText 中获取所有商品文字的 key
  143. requestData.template_excel_headers = defaultGoodsText
  144. await saveCustomerTemplate(requestData)
  145. ElMessage.success(isEdit ? '模板保存成功' : '模板创建成功')
  146. router.back()
  147. } catch (error: any) {
  148. console.error('保存模板失败:', error)
  149. }
  150. }
  151. const confirmName = () => {
  152. if (!templateName.value || !templateName.value.trim()) {
  153. // 简单校验,保持弹窗打开
  154. return
  155. }
  156. showNameDialog.value = false
  157. if (!isEdit && pendingPayload.value) {
  158. doSave(pendingPayload.value)
  159. pendingPayload.value = null
  160. }
  161. }
  162. const save = (payload: any) => {
  163. if (isEdit) {
  164. // 编辑模式直接保存,不弹名称框
  165. doSave(payload)
  166. return
  167. }
  168. // 新增模式下,第一次点击“保存”且没填名称时,先弹输入名称框
  169. if (!templateName.value || !templateName.value.trim()) {
  170. pendingPayload.value = payload
  171. showNameDialog.value = true
  172. return
  173. }
  174. doSave(payload)
  175. }
  176. </script>
  177. <style lang="scss" scoped>
  178. </style>