update:新增模板市场功能

This commit is contained in:
lihaoyuan 2025-12-10 11:39:52 +08:00
parent 33291bf573
commit 6331ab74da
7 changed files with 1127 additions and 14 deletions

View File

@ -40,3 +40,44 @@ export function manage(params) {
params,
})
}
export function getBlankTpl() {
return request({
url: URL.shop.page.app.getBlankTpl,
method: 'get',
})
}
export function listMarketPage(params){
return request({
url: URL.shop.page.app.listMarketPage,
method: 'get',
params
})
}
export function editPageApp(param){
return request({
url: URL.shop.page.app.editPageApp,
method: 'post',
data:param,
headers: {
'Content-Type': 'application/json' // 明确指定JSON格式
}
})
}
export function copyDiyByAppId(params){
return request({
url: URL.shop.page.app.copyDiyByAppId,
method: 'post',
params:params
})
}
export function pageAppPublish(params){
return request({
url: URL.shop.page.app.pageAppPublish,
method: 'post',
params:params
})
}

View File

@ -1243,6 +1243,11 @@ let url = {
editApp: api_url + '/admin/shop/shop-page-app/editApp',
setThemes: api_url + '/admin/shop/shop-page-app/setThemes',
manage: api_url + '/admin/shop/shop-page-base/list',
getBlankTpl: api_url + '/admin/shop/shop-page-app/getBlankTpl',
listMarketPage:api_url + '/admin/shop/shop-page-app/listMarketPage',
editPageApp:api_url + '/admin/shop/shop-page-app/editPageApp',
copyDiyByAppId:api_url + '/admin/shop/shop-page-app/copyDiyByAppId',
pageAppPublish:api_url + '/admin/shop/shop-page-app/pageAppPubish',
},
base: {
doEdit: api_url + '/admin/shop/shop-page-base/edit',
@ -1289,6 +1294,11 @@ let url = {
doDelete: api_url + '/admin/shop/shop_plantform_feedback/delete',
},
},
esign:{
signFlow:{
createByFile:api_url+'/admin/shop/esign/sign-flow/create-by-file',
}
},
analytics: {
access: {
history: {

View File

@ -0,0 +1,299 @@
<template>
<el-dialog
title="编辑图片信息"
width="40%"
:visible.sync="visible"
custom-class="template-dialog"
:before-close="handleClose"
>
<div>
<el-form
:model="form"
ref="form"
label-width="100px"
:rules="rules"
size="normal"
>
<el-form-item label="模板id" prop="app_id">
<el-input v-model="form.app_id" disabled />
</el-form-item>
<el-form-item label="模板名称" prop="app_name">
<el-input v-model="form.app_name" placeholder="请输入模板名称" />
</el-form-item>
<el-form-item label="模板类型">
<el-select v-model="form.app_industry" clearable filterable @change="">
<el-option v-for="item in shopModelList"
:key="item.id"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="模板主图" prop="tpl_image">
<upload
:image="form.tpl_image"
@upImage="handleMainImageUpload"
/>
</el-form-item>
<el-form-item label="市场图" prop="app_market_images">
<div v-for="(item, index) in form.app_market_images" :key="index" class="market-image-item">
<upload
:image="item.imageUrl"
@upImage="url => handleMarketImageUpload(index, url)"
/>
<el-input
v-model="item.content"
placeholder="请输入描述"
style="margin-left: 10px; width: 300px;"
/>
<el-button
type="text"
icon="el-icon-delete"
style="margin-left: 10px; color: red;"
@click="removeMarketImage(index)"
/>
</div>
<el-button type="text" icon="el-icon-plus" @click="addMarketImage">添加市场图</el-button>
</el-form-item>
<el-form-item label="是否上架" prop="is_pulish">
<el-select v-model="form.is_pulish" placeholder="请选择">
<el-option label="撤回" value="0" />
<el-option label="上架" value="1" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSave" :loading="saving">保存修改</el-button>
<el-button @click="handleClose">取消</el-button>
</el-form-item>
</el-form>
</div>
</el-dialog>
</template>
<script>
import { editPageApp } from '@/api/page/app'
import upload from '@/components/upload'
export default {
name: 'decoarationDetail',
components: {
upload
},
data() {
return {
visible: false,
saving: false,
form: {
app_id: '',
app_name: '',
app_market_images: [], //
tpl_image: '',
is_pulish: '0',
appIndustry:'0',
},
shopModelList:[
{id:"1",label:'超市',value:'1'},
{id:"2",label:'数码家电',value:'2'},
{id:"3",label:'水果生鲜',value:'3'},
{id:"4",label:'烘培饮品',value:'4'},
{id:"5",label:'社区团购',value:'5'},
{id:"6",label:'时尚美妆',value:'6'},
{id:"7",label:'婴儿服饰',value:'7'},
{id:"8",label:'家居',value:'8'},
{id:"9",label:'汽车',value:'9'},
{id:"10",label:'酒店旅游',value:'10'},
{id:"11",label:'鲜花绿植',value:'11'},
{id:"12",label:'医药健康',value:'12'},
{id:"13",label:'工业五金',value:'13'},
{id:"14",label:'节日模板',value:'14'},
{id:"0",label:'其他行业',value:'0'},
],
rules: {
app_name: [
{ required: true, message: '请输入模板名称', trigger: 'blur' },
{ min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
],
tpl_image: [
{ required: true, message: '请输入模板主图URL', trigger: 'blur' }
],
app_market_images: [
{
required: true,
validator: (rule, value, callback) => {
if (!value || value.length === 0) {
callback(new Error('请至少添加一张市场图'))
} else if (value.some(item => !item.imageUrl)) {
callback(new Error('市场图图片URL不能为空'))
} else {
callback()
}
},
trigger: 'change'
}
]
},
originalData: {}
}
},
methods: {
//
open(pageData) {
this.visible = true
this.originalData = JSON.parse(JSON.stringify(pageData))
//
this.form = {
app_id: pageData.app_id || '',
app_name: pageData.app_name || '',
tpl_image: pageData.tpl_image || '',
is_pulish: pageData.is_pulish || pageData.isPublish || '0',
app_market_images: [],
app_industry:pageData.app_industry||'0'
}
//
if (pageData.app_market_images) {
try {
const marketImages = typeof pageData.app_market_images === 'string'
? JSON.parse(pageData.app_market_images)
: pageData.app_market_images
if (Array.isArray(marketImages)) {
this.form.app_market_images = []
marketImages.forEach(item => {
// itemURL
if (item.imageUrl && item.imageUrl.includes(',')) {
const urls = item.imageUrl.split(',')
urls.forEach(url => {
this.form.app_market_images.push({
imageUrl: url.trim(),
content: item.content || item.description || ''
})
})
} else {
//
this.form.app_market_images.push({
imageUrl: item.imageUrl || '',
content: item.content || item.description || ''
})
}
})
}
} catch (e) {
console.error('解析市场图失败:', e)
this.form.app_market_images = []
}
}
//
if (!this.form.app_market_images.length) {
this.addMarketImage()
}
},
//
addMarketImage() {
this.form.app_market_images.push({
imageUrl: '',
content: ''
})
},
handleMainImageUpload(imageUrl) {
this.form.tpl_image = imageUrl;
},
//
removeMarketImage(index) {
this.form.app_market_images.splice(index, 1)
//
if (!this.form.app_market_images.length) {
this.addMarketImage()
}
},
//
handleMarketImageUpload(index, url) {
this.form.app_market_images[index].imageUrl = url;
},
//
async handleSave() {
try {
await this.$refs.form.validate()
this.saving = true
//
const marketImagesArray = this.form.app_market_images.map(item => ({
imageUrl: item.imageUrl,
content: item.content
}))
//
const requestData = {
app_id: this.form.app_id,
app_name: this.form.app_name,
app_market_images: JSON.stringify(marketImagesArray), // JSON
tpl_image: this.form.tpl_image,
is_pulish: parseInt(this.form.is_pulish),
app_industry:this.form.app_industry
}
console.log('最终提交JSON:', requestData)
console.log('app_market_images解析后:', JSON.parse(requestData.app_market_images))
//
const response = await editPageApp(requestData)
if(response.status==200){
this.$message.success('保存成功哈哈哈哈!')
this.visible = false
// this.$emit('update-success', this.form)
this.$emit('editSuccess')
}
} catch (error) {
console.error('保存失败:', error)
this.$message.error('保存失败,请重试!')
} finally {
this.saving = false
}
},
//
handleClose() {
this.visible = false
if (this.$refs.form) {
this.$refs.form.resetFields()
}
}
}
}
</script>
<style scoped>
.template-dialog {
height: 700px !important;
display: flex;
flex-direction: column;
}
.template-dialog .el-dialog__body {
flex: 1;
overflow-y: auto;
max-height: 600px;
}
.market-image-item {
display: flex;
align-items: center;
margin-bottom: 10px;
padding: 8px;
background: #f9f9f9;
border-radius: 4px;
}
</style>

View File

@ -0,0 +1,259 @@
<template>
<el-dialog
title="模板市场"
width="80%"
:visible.sync="visible"
custom-class="template-dialog"
:z-index="2000"
>
<div class="dialog-content">
<div class="search">
<el-select v-model="selectType" clearable filterable @change="searchByType">
<el-option v-for="item in shopModelList"
:key="item.id"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<ul class="ulCls">
<li v-if="emptyPage" class="liCls">
<div align="center" class="div_img_cls">
<img
class="imgCls"
:src="emptyPage.tpl_image"
style="object-fit: fill"
/>
<p class="fontCls">{{ emptyPage.tpl_name }}</p>
</div>
<div class="lightBtn">
<div class="enableExit">
<el-button
type="primary"
@click=""
>
{{ __('创建空白模板') }}
</el-button>
</div>
</div>
</li>
<template v-if="templateList.records.length > 0">
<li v-for="(page, i) in templateList.records" :key="page.app_id || i" class="liCls">
<div align="center" class="div_img_cls">
<img
class="imgCls"
:src="page.tpl_image"
style="object-fit: fill"
/>
<p class="fontCls">{{ page.app_name }}</p>
</div>
<div class="lightBtn">
<div class="enableExit">
<el-button type="primary" @click="openCopy(page)">
{{ __('创建模板') }}
</el-button>
<el-button type="primary" @click="openPreview(page)">
{{ __('预览') }}
</el-button>
</div>
</div>
</li>
</template>
<li v-else class="empty-li">
<el-empty
description="该分类暂无模板"
/>
</li>
</ul>
<copyTemplate ref="copyTemplateRef"></copyTemplate>
<previewTemplate ref="previewTemplateRef"></previewTemplate>
</div>
</el-dialog>
</template>
<script>
import { listMarketPage, setThemes, getBlankTpl } from '@/api/page/app'
import copyTemplate from '@/views/page/sellerApp/copyTemplate.vue'
import previewTemplate from '@/views/page/sellerApp/previewTemplate.vue'
export default {
name: 'TemplateMenu',
components: { copyTemplate, previewTemplate },
data() {
return {
visible: false,
templateList: { records: [] },
emptyPage: null,
app_market_images: null,
copyTemplateRef: null,
previewTemplateRef: null,
selectType:'',
shopModelList:[
{id:"1",label:'超市',value:'1'},
{id:"2",label:'数码家电',value:'2'},
{id:"3",label:'水果生鲜',value:'3'},
{id:"4",label:'烘培饮品',value:'4'},
{id:"5",label:'社区团购',value:'5'},
{id:"6",label:'时尚美妆',value:'6'},
{id:"7",label:'婴儿服饰',value:'7'},
{id:"8",label:'家居',value:'8'},
{id:"9",label:'汽车',value:'9'},
{id:"10",label:'酒店旅游',value:'10'},
{id:"11",label:'鲜花绿植',value:'11'},
{id:"12",label:'医药健康',value:'12'},
{id:"13",label:'工业五金',value:'13'},
{id:"14",label:'节日模板',value:'14'},
{id:"0",label:'其他行业',value:'0'},
],
}
},
created() {
this.getListMarketPages()
this.getBlankTplPage()
},
methods: {
open() {
this.visible = true;
},
async getListMarketPages() {
let data = await listMarketPage()
this.templateList = data;
console.log("aaaaaaaaaaaaaaa")
},
async getBlankTplPage() {
try {
const { data, msg, status } = await getBlankTpl()
if (status === 200) {
this.emptyPage = data
}
} catch (error) {
console.error('获取空白模板失败:', error)
}
},
async searchByType(){
try {
// appIndustry
let data = await listMarketPage({ appIndustry: this.selectType });
this.templateList = data && typeof data === 'object' ? data : { records: [] }
} catch (error) {
console.error('筛选模板失败:', error)
this.templateList = { records: [] }
}
},
showEditApp(page) {
if (page.tpl_id === 107) {
this.$router.push({
path: '/appTemplate',
query: {
app_id: page.app_id,
tpl_id: page.tpl_id,
app_type: 0,
},
})
} else {
this.$router.push({
path: '/setupshop',
})
}
},
async setThemes(tpl_id, tpl_label, app_id) {
this.$baseConfirm(this.__('确定启用此模板风格?'), null, async () => {
const { msg, status } = await setThemes({
tpl_id: tpl_id,
store_template: tpl_label,
app_id: app_id,
})
if (200 == status) {
this.$baseMessage(msg, 'success')
} else {
this.$baseMessage(msg, 'error')
}
this.getAppPages()
})
},
openCopy(page) {
this.$refs.copyTemplateRef?.open(page)
},
openPreview(page) {
this.$refs.previewTemplateRef?.open(page)
},
}
}
</script>
<style scoped>
/* 内容容器样式 */
.dialog-content {
width: 100%;
height: 100%;
}
.ulCls {
list-style: none;
padding: 0;
margin: 0;
}
.ulCls li {
position: relative;
float: left;
width: 195px;
margin: 0 20px 30px;
background-color: #fafafa;
}
.div_img_cls {
height: 328px;
}
.imgCls {
width: 165px;
height: 328px;
}
.fontCls {
color: #979898;
font-weight: bold;
}
.lightBtn {
position: absolute;
opacity: 0;
top: 0;
width: 100%;
height: 328px;
}
.lightBtn:hover {
opacity: 1;
background-color: rgba(151, 152, 152, 0.5);
transition: all 0.5s;
}
.lightBtn:hover .enableExit {
transition: all 0.5s;
transform: translateY(150%);
}
.enableExit {
position: relative;
top: 30%;
width: 100%;
margin-top: -15px;
text-align: center;
}
::v-deep .template-dialog .el-dialog__body {
max-height: 600px; /* 固定最大高度,可根据需求调整 */
overflow-y: auto; /* 超出时显示纵向滚动条 */
overflow-x: hidden; /* 禁止横向滚动 */
padding: 15px;
}
.search{
width: 100%;
margin: 20px;
}
</style>

View File

@ -0,0 +1,108 @@
<template>
<el-dialog
title="创建店铺"
width="30%"
:visible.sync="visible"
custom-class="template-dialog"
:z-index="2020"
:append-to-body="true"
height="300px"
>
<el-form
:model="form"
ref="form"
label-width="80px"
:inline="false"
size="normal"
>
<el-form-item label="app_id" size="normal">
{{ form.app_id }}
</el-form-item>
<el-form-item label="模板名字">
<el-input v-model="form.appName"></el-input>
</el-form-item>
<el-form-item label="模板类型">
<el-select v-model="form.app_industry" clearable filterable @change="">
<el-option v-for="item in shopModelList"
:key="item.id"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="copy">创建模板</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
<script>
import {copyDiyByAppId} from '@/api/page/app'
export default{
name:'copyTemplate',
data(){
return{
visible: false,
form:{
app_id:'',
appName:'',
appIndustry:''
},
shopModelList:[
{id:"1",label:'超市',value:'1'},
{id:"2",label:'数码家电',value:'2'},
{id:"3",label:'水果生鲜',value:'3'},
{id:"4",label:'烘培饮品',value:'4'},
{id:"5",label:'社区团购',value:'5'},
{id:"6",label:'时尚美妆',value:'6'},
{id:"7",label:'婴儿服饰',value:'7'},
{id:"8",label:'家居',value:'8'},
{id:"9",label:'汽车',value:'9'},
{id:"10",label:'酒店旅游',value:'10'},
{id:"11",label:'鲜花绿植',value:'11'},
{id:"12",label:'医药健康',value:'12'},
{id:"13",label:'工业五金',value:'13'},
{id:"14",label:'节日模板',value:'14'},
{id:"0",label:'其他行业',value:'0'},
],
}
},
methods:{
open(page){
this.visible = true
this.form=page
console.log("pagehhhhhhh",page)
},
async copy(){
let params={
appId:this.form.app_id,
appName:this.form.appName,
appIndustry:this.form.app_industry
}
let res=await copyDiyByAppId(params)
if(res.status==200){
this.$message.success('模板创建成功!')
this.visible = false
this.$emit('copySuccess') //
}
}
}
}
</script>
<style scoped>
.template-dialog {
height: 300px !important;
display: flex;
flex-direction: column;
}
.template-dialog .el-dialog__body {
flex: 1;
overflow-y: auto;
max-height: 300px;
}
</style>

View File

@ -2,8 +2,16 @@
<div class="page-app-container">
<el-row>
<el-card class="box-card">
<div slot="header" class="clearfix">
<div slot="header" class="clearfix header-row">
<span>{{ __('当前使用的模板') }}</span>
<el-button
type="primary"
size="default"
@click="createNewTemplate"
class="create-btn"
>
{{ __('创建店铺模板') }}
</el-button>
</div>
<div>
<div style="width: 100%">
@ -23,7 +31,7 @@
{{ __('模板名称') }}{{ usePage.app_name }}
</span>
<el-button type="primary" @click="showEditApp(usePage)">
{{ __('编辑模版') }}
{{ __('去装修') }}
</el-button>
</div>
</div>
@ -48,14 +56,79 @@
</div>
<div class="lightBtn">
<div class="enableExit">
<div style="margin-bottom: 10px;">
<el-button
type="primary"
@click="setThemes(page.tpl_id, page.tpl_label,page.app_id)"
@click="setThemes(page.tpl_id, page.tpl_label, page.app_id)"
>
{{ __('启用') }}
</el-button>
<el-button type="primary" @click="showEditApp(page)">
{{ __('去装修') }}
</el-button>
</div>
<!-- 下拉菜单 -->
<el-dropdown size="large" @command="handleDropdownCommand(page, $event)">
<el-button type="primary">
{{ __('更多') }}<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="edit">
{{ __('编辑') }}
</el-dropdown-item>
<el-dropdown-item command="upload" v-if="page.is_pulish==0">
{{ __('发布') }}
</el-dropdown-item>
<el-dropdown-item command="pull" v-if="page.is_pulish==1">
{{ __('下架') }}
</el-dropdown-item>
<el-dropdown-item command="preview">
{{ __('预览') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</li>
</ul>
</div>
</el-card>
</el-row>
<el-row>
<el-card>
<div slot="header" class="clearfix header-row">
<span>{{ __('模板市场') }}</span>
<el-button
type="primary"
size="default"
@click="createNewTemplate"
class="create-btn"
>
{{ __('查看更多模板') }}
</el-button>
</div>
<div>
<ul class="ulCls" style="position: relative">
<li
v-for="(page, i) in templateList.records"
:key="i"
class="liCls"
>
<div align="center" class="div_img_cls">
<img
class="imgCls"
:src="page.tpl_image"
style="object-fit: fill"
/>
<p class="fontCls">{{ page.app_name }}</p>
</div>
<div class="lightBtn">
<div class="enableExit">
<el-button type="primary" @click="openCopy(page)">
{{ __('创建模板') }}
</el-button>
<el-button type="primary" @click="openPreview(page)">
{{ __('预览') }}
</el-button>
</div>
</div>
@ -64,23 +137,46 @@
</div>
</el-card>
</el-row>
<templateMenu ref="templateMenuRef"></templateMenu>
<decoarationDetail ref="decoarationDetailRef" @editSuccess="refreshAllData"></decoarationDetail>
<copyTemplate ref="copyTemplateRef" @copySuccess="refreshAllData"></copyTemplate>
<previewTemplate ref="previewTemplateRef"></previewTemplate>
</div>
</template>
<script>
import { getList, setThemes } from '@/api/page/app'
import {
getList,
setThemes,
listMarketPage,
getBlankTpl,
pageAppPublish
} from '@/api/page/app'
import { translateTitle as __ } from '@/utils/i18n'
import templateMenu from '@/views/page/sellerApp/TemplateMenu.vue'
import decoarationDetail from '@/views/page/sellerApp/DecorationDetail.vue'
import copyTemplate from '@/views/page/sellerApp/copyTemplate.vue'
import previewTemplate from '@/views/page/sellerApp/previewTemplate.vue'
export default {
name: 'PageApp',
components: {},
components: { templateMenu, decoarationDetail,copyTemplate,previewTemplate },
data() {
return {
usePage: {},
list: [],
templateMenuRef: null,
decoarationDetailRef: null,
copyTemplateRef:null,
previewTemplateRef:null,
templateList: [],
emptyPage: null,
app_market_images: null,
}
},
created() {
this.getAppPages()
this.getListMarketPages()
this.getBlankTplPage()
},
methods: {
__,
@ -88,7 +184,6 @@
const { data, msg, status } = await getList()
this.list = data.items
this.usePage = data.current_tpl
//this.getUsePage(data.items)
},
showEditApp(page) {
if (page.tpl_id === 107) {
@ -115,7 +210,7 @@
}
}
},
async setThemes(tpl_id, tpl_label,app_id) {
async setThemes(tpl_id, tpl_label, app_id) {
this.$baseConfirm(this.__('确定启用此模板风格?'), null, async () => {
const { msg, status } = await setThemes({
tpl_id: tpl_id,
@ -130,6 +225,67 @@
this.getAppPages()
})
},
createNewTemplate() {
this.$refs.templateMenuRef?.open()
},
async getListMarketPages() {
let data = await listMarketPage()
this.templateList = data
},
async getBlankTplPage() {
try {
const { data, msg, status } = await getBlankTpl()
if (status === 200) {
this.emptyPage = data
}
} catch (error) {
console.error('获取空白模板失败:', error)
}
},
openDetailEdit(page) {
this.$refs.decoarationDetailRef?.open(page)
},
openCopy(page) {
this.$refs.copyTemplateRef?.open(page)
},
openPreview(page){
this.$refs.previewTemplateRef?.open(page)
},
//
handleDropdownCommand(page, command) {
switch(command) {
case 'edit':
this.openDetailEdit(page)
break
case 'upload':
//
this.handleUpload(page,1)
break
case 'pull':
this.handleUpload(page,0)
break
case 'preview':
this.openPreview(page)
break
}
},
// ,
async handleUpload(page,publishStatus) {
const params={
appId:page.app_id,
isPublish:publishStatus
}
let res=await pageAppPublish(params)
if(res.status==200){
this.$message.success('操作成功7777')
this.refreshAllData()
}
},
//
async refreshAllData() {
await this.getAppPages()
await this.getListMarketPages()
}
},
}
</script>
@ -138,6 +294,13 @@
font-size: 18px;
}
/* 头部行样式 */
.header-row {
display: flex;
justify-content: space-between;
align-items: center;
}
.usertemplate {
float: left;
display: inline-block;
@ -217,4 +380,9 @@
margin-top: -15px;
text-align: center;
}
/* 下拉菜单样式调整 */
.el-dropdown {
display: inline-block;
}
</style>

View File

@ -0,0 +1,228 @@
<template>
<el-dialog
title="模板预览"
width="20%"
:visible.sync="visible"
custom-class="template-dialog"
:z-index="2020"
:append-to-body="true"
>
<div class="preview-container">
<div class="basic-info">
<p><strong>模板ID</strong>{{ form.app_id }}</p>
<p><strong>模板名称</strong>{{ form.app_name }}</p>
</div>
<div class="carousel-container">
<el-carousel
height="450px"
arrow="always"
:interval="3000"
indicator-position="none"
v-if="imageList.length > 0"
>
<el-carousel-item v-for="(img, index) in imageList" :key="index">
<div class="carousel-item">
<img
:src="img.imageUrl"
:alt="`图片${index+1}`"
class="carousel-image"
@error="handleImageError(index)"
/>
<div class="image-desc" v-if="img.content">
{{ img.content }}
</div>
</div>
</el-carousel-item>
</el-carousel>
<!-- 无图片时的占位 -->
<div class="no-images" v-else>
<el-empty description="暂无图片数据"></el-empty>
</div>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'previewTemplate',
data() {
return {
visible: false,
form: {
app_id: '',
app_name: '',
app_market_images: ''
},
imageList: [] //
}
},
methods: {
open(page) {
this.visible = true
this.form = { ...page }
// app_market_images
this.processImages(page.app_market_images)
},
//
processImages(imagesData) {
this.imageList = []
if (!imagesData) return
try {
// JSON
let parsedData = typeof imagesData === 'string'
? JSON.parse(imagesData)
: imagesData
// 使
if (Array.isArray(parsedData)) {
parsedData.forEach(item => {
// imageUrl
if (item.imageUrl && item.imageUrl.includes(',')) {
const urls = item.imageUrl.split(',')
urls.forEach(url => {
this.imageList.push({
imageUrl: url.trim(),
content: item.content || ''
})
})
} else if (item.imageUrl) {
this.imageList.push({
imageUrl: item.imageUrl,
content: item.content || ''
})
}
})
}
//
else if (parsedData.imageUrl) {
if (parsedData.imageUrl.includes(',')) {
const urls = parsedData.imageUrl.split(',')
urls.forEach(url => {
this.imageList.push({
imageUrl: url.trim(),
content: parsedData.content || ''
})
})
} else {
this.imageList.push({
imageUrl: parsedData.imageUrl,
content: parsedData.content || ''
})
}
}
} catch (error) {
console.error('解析图片数据失败:', error)
// URL
if (typeof imagesData === 'string' && imagesData.startsWith('http')) {
this.imageList.push({ imageUrl: imagesData })
}
}
},
//
handleImageError(index) {
this.imageList[index].imageUrl = 'https://via.placeholder.com/400x600?text=图片加载失败'
}
}
}
</script>
<style scoped>
.template-dialog {
width: 90% !important;
max-width: 1200px;
height: 700px !important;
}
.preview-container {
padding: 20px;
}
.basic-info {
margin-bottom: 20px;
padding: 10px;
background-color: #f5f7fa;
border-radius: 4px;
}
.basic-info p {
margin: 5px 0;
}
.carousel-container {
margin-top: 20px;
}
.el-carousel {
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}
.carousel-item {
position: relative;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #f9f9f9;
}
.carousel-image {
max-width: 100%;
max-height: 450px;
object-fit: contain;
}
.image-desc {
position: absolute;
bottom: 20px;
left: 0;
right: 0;
padding: 10px;
background-color: rgba(0, 0, 0, 0.5);
color: white;
text-align: center;
font-size: 14px;
}
.no-images {
height: 450px;
display: flex;
align-items: center;
justify-content: center;
background-color: #f5f5f5;
border-radius: 8px;
}
/* 轮播指示器样式 */
::v-deep .el-carousel__indicator {
background-color: rgba(255, 255, 255, 0.5);
}
::v-deep .el-carousel__indicator--active {
background-color: #ffffff;
}
/* 轮播箭头样式 */
::v-deep .el-carousel__arrow {
background-color: rgba(0, 0, 0, 0.3);
width: 40px;
height: 40px;
border-radius: 50%;
}
::v-deep .el-carousel__arrow:hover {
background-color: rgba(0, 0, 0, 0.5);
}
::v-deep .el-dialog__body{
padding: 0;
}
</style>