|
|
@@ -138,7 +138,7 @@
|
|
|
:class="{
|
|
|
active: item === form.logo_path
|
|
|
}"
|
|
|
- @click.native="form.logo_path = item"
|
|
|
+ @click.native="selectLogo(item)"
|
|
|
></upload>
|
|
|
<upload @input="onInput"></upload>
|
|
|
</div>
|
|
|
@@ -161,10 +161,10 @@
|
|
|
|
|
|
<div class="template-list">
|
|
|
<div v-for="(template, index) in visibleTemplates" :key="index" class="template-item"
|
|
|
- @click="form.selectTemplate = template" v-log="{ describe: { action: '点击选择详情模板', template_name: template.template_name } }">
|
|
|
+ @click="selectTemplate(template)" v-log="{ describe: { action: '点击选择详情模板', template_name: template.template_name } }">
|
|
|
<el-image :src="template.template_cover_image" fit="contain" class="cur-p"
|
|
|
style="width: 100%; display: block;" />
|
|
|
- <div class="select-warp" :class="form.selectTemplate.id == template.id ? 'active' : ''">
|
|
|
+ <div class="select-warp" :class="form.selectTemplate?.id == template.id ? 'active' : ''">
|
|
|
<el-icon color="#FFFFFF">
|
|
|
<Select />
|
|
|
</el-icon>
|
|
|
@@ -178,22 +178,35 @@
|
|
|
|
|
|
<div class="template-tips c-333 fs-14 line-20 te-l mar-top-20 flex left">
|
|
|
<el-icon><WarningFilled /></el-icon>
|
|
|
- <span class="mar-left-10">该模版图片顺序说明:{{form.selectTemplate.template_image_order}}</span>
|
|
|
+ <span class="mar-left-10">该模版图片顺序说明:{{form.selectTemplate?.template_image_order}}</span>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 模板下:一键上架 和 国内电商平台(多选) -->
|
|
|
- <div class="publish-section flex left" v-if="onlineStores.length">
|
|
|
+ <!-- 模板下:一键上架 和 电商平台(多选) -->
|
|
|
+ <div class="publish-section flex left" v-if="onlineStoreTempList.length || onlineStoreTempListForeign.length">
|
|
|
<div class="form-item flex left">
|
|
|
<div class="fw-b">一键上架:</div>
|
|
|
</div>
|
|
|
- <div class="form-item flex left mar-top-10">
|
|
|
+ <div class="form-item flex left mar-top-10" style="margin-right: 10px !important;" v-if="onlineStoreTempList.length">
|
|
|
<div class="label">国内电商平台:</div>
|
|
|
<el-select v-model="domesticPlatforms" multiple placeholder="请选择平台" style="min-width: 200px;">
|
|
|
<el-option
|
|
|
- v-for="store in onlineStores"
|
|
|
- :key="store"
|
|
|
- :label="store"
|
|
|
- :value="store"
|
|
|
+ v-for="store in onlineStoreTempList"
|
|
|
+ :key="store.show_name"
|
|
|
+ :label="store.show_name"
|
|
|
+ :value="store.online_store_name"
|
|
|
+ :disabled="!store.channel_status"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="form-item flex left mar-top-10" v-if="onlineStoreTempListForeign.length">
|
|
|
+ <div class="label">国外电商平台:</div>
|
|
|
+ <el-select v-model="foreignPlatforms" multiple placeholder="请选择平台" style="min-width: 200px;">
|
|
|
+ <el-option
|
|
|
+ v-for="store in onlineStoreTempListForeign"
|
|
|
+ :key="store.show_name"
|
|
|
+ :label="store.show_name"
|
|
|
+ :value="store.online_store_name"
|
|
|
+ :disabled="!store.channel_status"
|
|
|
/>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
@@ -283,7 +296,7 @@
|
|
|
:disabled-button="disabledButton" @button-click="handleComplete">
|
|
|
<template v-if="partErrList && partErrList.length > 0" #errList>
|
|
|
<div v-for="(item, idx) in partErrList" :key="idx">
|
|
|
- <span>{{ item.goods_art_no }}</span>:<span>{{ item.info }}</span>
|
|
|
+ <span v-if="item.goods_art_no">{{ item.goods_art_no }}:</span><span>{{ item.info }}</span>
|
|
|
</div>
|
|
|
</template>
|
|
|
<template #progressMessages>
|
|
|
@@ -291,7 +304,7 @@
|
|
|
<div class="message-header">
|
|
|
<span>处理进度</span>
|
|
|
<div class="flex right" style="gap:8px; align-items:center;">
|
|
|
-<!-- <el-button type="text" @click="openOutputDir" v-log="{ describe: { action: '点击打开输出目录' } }">打开目录</el-button>-->
|
|
|
+ <el-button type="text" @click="openOutputDir" v-log="{ describe: { action: '点击打开输出目录' } }">打开目录</el-button>
|
|
|
<el-button type="text" @click="showMessageHistory = !showMessageHistory" v-log="{ describe: { action: '点击查看进度详情' } }">
|
|
|
{{ showMessageHistory ? '收起' : '查看详情' }}
|
|
|
</el-button>
|
|
|
@@ -344,7 +357,7 @@ import { clickLog, setLogInfo } from '@/utils/log'
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
|
|
|
import headerBar from '@/components/header-bar/index.vue'
|
|
|
-import { ref, computed, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
|
|
+import { ref, computed, reactive, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
|
|
|
import { Select, EditPen } from '@element-plus/icons-vue'
|
|
|
import upload from '@/components/upload'
|
|
|
import client from "@/stores/modules/client";
|
|
|
@@ -457,6 +470,13 @@ onMounted(() => {
|
|
|
loadDetailCache()
|
|
|
})
|
|
|
|
|
|
+// 监听数据类型变化,自动保存到缓存
|
|
|
+watch(() => form.dataType, (newValue) => {
|
|
|
+ if (newValue) {
|
|
|
+ saveDataTypeToCache(newValue)
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
// 页面卸载时清理监听器
|
|
|
onBeforeUnmount(() => {
|
|
|
clientStore.ipc.removeAllListeners(icpList.socket.message + '_detail_progress');
|
|
|
@@ -486,7 +506,15 @@ const viewTemplate = (template) => {
|
|
|
const getCompanyTemplates = async () => {
|
|
|
const { data } = await getCompanyTemplatesApi()
|
|
|
templates.value = data.list
|
|
|
- onlineStores.value = data.online_stores || [] // 获取电商平台列表
|
|
|
+ // 获取电商平台列表 - 支持新的数据结构
|
|
|
+ if (data.online_store_temp_list) {
|
|
|
+ onlineStoreTempList.value = data.online_store_temp_list
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data.online_store_temp_list_foreign) {
|
|
|
+ onlineStoreTempListForeign.value = data.online_store_temp_list_foreign
|
|
|
+ }
|
|
|
+
|
|
|
// 默认选中第一个模板
|
|
|
if (templates.value.length > 0) {
|
|
|
form.selectTemplate = templates.value[0]
|
|
|
@@ -511,20 +539,16 @@ const toggleService = (key: string) => {
|
|
|
const idx = form.services.indexOf(key)
|
|
|
if (idx > -1) form.services.splice(idx, 1)
|
|
|
else form.services.push(key)
|
|
|
+
|
|
|
+ // 保存服务选择状态到缓存
|
|
|
+ saveServicesToCache(form.services)
|
|
|
}
|
|
|
|
|
|
-// 国内电商平台多选与一键上架
|
|
|
+// 电商平台多选与一键上架
|
|
|
const domesticPlatforms = ref<string[]>([])
|
|
|
-const onlineStores = ref<any[]>([]) // 从接口获取的电商平台列表
|
|
|
-const publishToPlatforms = () => {
|
|
|
- if (!domesticPlatforms.value.length) {
|
|
|
- ElMessage.warning('请选择至少一个电商平台')
|
|
|
- return
|
|
|
- }
|
|
|
- clickLog({ describe: { action: '点击一键上架', platforms: domesticPlatforms.value } }, route)
|
|
|
- // 具体上架逻辑按后续接口对接
|
|
|
-}
|
|
|
-
|
|
|
+const foreignPlatforms = ref<string[]>([])
|
|
|
+const onlineStoreTempList = ref<any[]>([]) // 国内电商平台列表
|
|
|
+const onlineStoreTempListForeign = ref<any[]>([]) // 国外电商平台列表
|
|
|
// 模特与场景弹窗
|
|
|
const modelDialogVisible = ref(false)
|
|
|
const scenePromptDialogVisible = ref(false)
|
|
|
@@ -534,6 +558,9 @@ const scenePrompt = ref('')
|
|
|
// 本地缓存键(与弹窗组件保持一致)
|
|
|
const DETAIL_MODEL_CACHE_KEY = 'model_selection_cache'
|
|
|
const DETAIL_SCENE_PROMPT_CACHE_KEY = 'scene_prompt_cache'
|
|
|
+const DETAIL_LOGO_CACHE_KEY = 'detail_logo_cache'
|
|
|
+const DETAIL_DATA_TYPE_CACHE_KEY = 'detail_data_type_cache'
|
|
|
+const DETAIL_SERVICES_CACHE_KEY = 'detail_services_cache'
|
|
|
|
|
|
// 读取本地缓存
|
|
|
const loadDetailCache = () => {
|
|
|
@@ -557,6 +584,48 @@ const loadDetailCache = () => {
|
|
|
console.log(scenePrompt.value);
|
|
|
}
|
|
|
} catch {}
|
|
|
+
|
|
|
+ // 加载LOGO缓存
|
|
|
+ try {
|
|
|
+ const logo = localStorage.getItem(DETAIL_LOGO_CACHE_KEY)
|
|
|
+ if (logo) {
|
|
|
+ form.logo_path = logo
|
|
|
+ console.log('loadDetailCache - logo:', logo);
|
|
|
+ }
|
|
|
+ } catch {}
|
|
|
+
|
|
|
+ // 加载数据类型缓存
|
|
|
+ try {
|
|
|
+ const dataType = localStorage.getItem(DETAIL_DATA_TYPE_CACHE_KEY)
|
|
|
+ if (dataType) {
|
|
|
+ form.dataType = dataType
|
|
|
+ console.log('loadDetailCache - dataType:', dataType);
|
|
|
+ }
|
|
|
+ } catch {}
|
|
|
+
|
|
|
+ // 加载模板缓存
|
|
|
+ try {
|
|
|
+ const template = localStorage.getItem('detail_template_cache')
|
|
|
+ if (template) {
|
|
|
+ const parsed = JSON.parse(template)
|
|
|
+ if (parsed && parsed.id) {
|
|
|
+ form.selectTemplate = parsed
|
|
|
+ console.log('loadDetailCache - template:', parsed);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch {}
|
|
|
+
|
|
|
+ // 加载服务选择状态缓存
|
|
|
+ try {
|
|
|
+ const services = localStorage.getItem(DETAIL_SERVICES_CACHE_KEY)
|
|
|
+ if (services) {
|
|
|
+ const parsed = JSON.parse(services)
|
|
|
+ if (Array.isArray(parsed)) {
|
|
|
+ form.services = parsed
|
|
|
+ console.log('loadDetailCache - services:', parsed);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch {}
|
|
|
}
|
|
|
|
|
|
// 保存到本地缓存(仅保存必要字段)
|
|
|
@@ -590,12 +659,56 @@ const saveScenePromptToCache = (prompt: string) => {
|
|
|
} catch {}
|
|
|
}
|
|
|
|
|
|
+// 保存LOGO到缓存
|
|
|
+const saveLogoToCache = (logoPath: string) => {
|
|
|
+ try {
|
|
|
+ if (logoPath) {
|
|
|
+ localStorage.setItem(DETAIL_LOGO_CACHE_KEY, logoPath)
|
|
|
+ console.log('saveLogoToCache:', logoPath);
|
|
|
+ }
|
|
|
+ } catch {}
|
|
|
+}
|
|
|
+
|
|
|
+// 保存数据类型到缓存
|
|
|
+const saveDataTypeToCache = (dataType: string) => {
|
|
|
+ try {
|
|
|
+ if (dataType) {
|
|
|
+ localStorage.setItem(DETAIL_DATA_TYPE_CACHE_KEY, dataType)
|
|
|
+ console.log('saveDataTypeToCache:', dataType);
|
|
|
+ }
|
|
|
+ } catch {}
|
|
|
+}
|
|
|
+
|
|
|
+const saveServicesToCache = (services: string[]) => {
|
|
|
+ try {
|
|
|
+ localStorage.setItem(DETAIL_SERVICES_CACHE_KEY, JSON.stringify(services))
|
|
|
+ console.log('saveServicesToCache:', services);
|
|
|
+ } catch {}
|
|
|
+}
|
|
|
+
|
|
|
const openModelDialog = () => {
|
|
|
modelDialogVisible.value = true
|
|
|
}
|
|
|
const openScenePromptDialog = () => {
|
|
|
scenePromptDialogVisible.value = true
|
|
|
}
|
|
|
+
|
|
|
+// 选择模板
|
|
|
+const selectTemplate = (template: any) => {
|
|
|
+ form.selectTemplate = template
|
|
|
+ // 保存模板选择到缓存
|
|
|
+ try {
|
|
|
+ localStorage.setItem('detail_template_cache', JSON.stringify(template))
|
|
|
+ console.log('selectTemplate - saved to cache:', template);
|
|
|
+ } catch {}
|
|
|
+}
|
|
|
+
|
|
|
+// 选择LOGO
|
|
|
+const selectLogo = (logoPath: string) => {
|
|
|
+ form.logo_path = logoPath
|
|
|
+ // 保存LOGO选择到缓存
|
|
|
+ saveLogoToCache(logoPath)
|
|
|
+}
|
|
|
const handleModelSelection = (models: { female: any; male: any }) => {
|
|
|
selectedModels.value = models
|
|
|
saveModelsToCache(models)
|
|
|
@@ -721,16 +834,19 @@ const handleUploadGoodsProgressMessage = (data: any) => {
|
|
|
// 打开输出目录:appConfig.appPath + '/build/extraResources/py/output'
|
|
|
const openOutputDir = () => {
|
|
|
try {
|
|
|
- const appPath = useConfigInfoStore?.appConfig?.appPath || ''
|
|
|
- if (!appPath) {
|
|
|
+
|
|
|
+ const pyPath = useConfigInfoStore?.appConfig?.pyPath || ''
|
|
|
+ if (!pyPath) {
|
|
|
ElMessage.error('未获取到应用目录 appPath')
|
|
|
return
|
|
|
}
|
|
|
- const fullPath = `${appPath}/build/extraResources/py/output`
|
|
|
+ console.log(pyPath);
|
|
|
+ const fullPath = `${pyPath}\\output`
|
|
|
+ console.log(fullPath);
|
|
|
clientStore.ipc.removeAllListeners(icpList.utils.shellFun);
|
|
|
clientStore.ipc.send(icpList.utils.shellFun, {
|
|
|
action: 'openPath',
|
|
|
- params: fullPath.replaceAll('/', '\\')
|
|
|
+ params: fullPath.replace(/\//g, '\\')
|
|
|
});
|
|
|
} catch (e) {
|
|
|
console.error(e)
|
|
|
@@ -751,7 +867,7 @@ const generate = async function () {
|
|
|
action: '点击开始生成详情页',
|
|
|
services: form.services,
|
|
|
dataType: form.dataType,
|
|
|
- template_name: form.selectTemplate.template_name,
|
|
|
+ template_name: form.selectTemplate?.template_name,
|
|
|
goods_count: goods_art_nos.value.length,
|
|
|
goods_art_nos: goods_art_nos.value
|
|
|
}
|
|
|
@@ -804,14 +920,14 @@ const generate = async function () {
|
|
|
const params = {
|
|
|
goods_art_no: JSON.parse(JSON.stringify(goods_art_nos.value)),
|
|
|
logo_path: form.logo_path || '',
|
|
|
- temp_name: form.selectTemplate.template_id || '',
|
|
|
+ temp_name: form.selectTemplate?.template_id || '',
|
|
|
excel_path: form.dataType == '1' ? form.excel_path : '',
|
|
|
- template_image_order: form.selectTemplate.template_image_order,
|
|
|
+ template_image_order: form.selectTemplate?.template_image_order,
|
|
|
temp_list,
|
|
|
token,
|
|
|
uuid: uuidStore.getUuid || '',
|
|
|
- // 新增服务参数
|
|
|
- online_stores: Object.values(domesticPlatforms.value || {}),
|
|
|
+ // 新增服务参数 - 合并国内和国外平台
|
|
|
+ online_stores: [...(domesticPlatforms.value || []), ...(foreignPlatforms.value || [])],
|
|
|
is_detail: isDetail,
|
|
|
is_product_scene: isProductScene,
|
|
|
is_upper_footer: isUpperFooter,
|
|
|
@@ -1023,8 +1139,10 @@ const getLogolist = async () => {
|
|
|
logoList.value = result.data || []
|
|
|
console.log('getLogoList')
|
|
|
console.log(result.data)
|
|
|
- if(logoList.value.length){
|
|
|
+ if(logoList.value.length && !form.logo_path){
|
|
|
form.logo_path = logoList.value[0]
|
|
|
+ // 保存默认LOGO到缓存
|
|
|
+ saveLogoToCache(form.logo_path)
|
|
|
}
|
|
|
clientStore.ipc.removeAllListeners(icpList.generate.getLogoList);
|
|
|
})
|
|
|
@@ -1044,6 +1162,8 @@ const addLogo = async (path) => {
|
|
|
console.log(result)
|
|
|
if(result.data.logo){
|
|
|
form.logo_path = result.data.logo
|
|
|
+ // 保存新添加的LOGO到缓存
|
|
|
+ saveLogoToCache(form.logo_path)
|
|
|
if(logoList.value.indexOf(result.data.logo) <0){
|
|
|
logoList.value.push(result.data.logo)
|
|
|
}
|
|
|
@@ -1102,7 +1222,7 @@ const handleComplete = () => {
|
|
|
clientStore.ipc.removeAllListeners(icpList.utils.shellFun);
|
|
|
let params = {
|
|
|
action: 'openPath',
|
|
|
- params: completeDirectory.value?.replaceAll('/', '\\')
|
|
|
+ params: completeDirectory.value?.replace(/\//g, '\\')
|
|
|
}
|
|
|
clientStore.ipc.send(icpList.utils.shellFun, params);
|
|
|
}
|