merge webdecoration

This commit is contained in:
maqian
2026-06-05 14:41:13 +08:00
parent afc8619fae
commit 90be424554
21 changed files with 985 additions and 255 deletions

View File

@@ -282,7 +282,7 @@ export function getAppcenterUrl(params) {
export function loginUsercenter(params) {
return fetch({
url: '/company/usercenter/login',
method: 'get',
method: 'post',
params
})
}

View File

@@ -44,6 +44,7 @@
<el-button type="text" style="margin-right: 10px" @click="handleShowConfig">
<i class="el-icon-setting" style="color: #8080ff" /> {{ $t('6880d32e.701fa5') }}
</el-button>
<!-- ECX-8712: 总部/店铺模版装修隐藏导航配置 -->
<el-button type="text" @click="handleShowTabConfig">
<i class="el-icon-setting" style="color: #8080ff" /> {{ $t('6880d32e.f9a598') }}
</el-button>
@@ -134,9 +135,12 @@
<span class="btn" @click="copyTemplate(item.pages_template_id)">{{
$t('6880d32e.79d3ab')
}}</span>
<!-- ECX-8712: 总部/店铺模版装修隐藏导航配置 -->
<!--
<span class="btn" @click="handleClickNav(item.pages_template_id)">{{
$t('6880d32e.056f2d')
}}</span>
-->
<span class="btn" @click="abandonTemplate(item.pages_template_id)">{{
$t('6880d32e.0044f6')
}}</span>

View File

@@ -41,11 +41,6 @@
</style>
<template>
<div class="picker-link">
<!-- <SpFilterForm :model="formData" size="small" @onSearch="onSearch" @onReset="onSearch">
<SpFilterFormItem prop="keywords">
<el-input v-model="formData.keywords" placeholder="请输入页面名称" />
</SpFilterFormItem>
</SpFilterForm> -->
<SpFinder
ref="finder"
:show-pager="false"
@@ -71,6 +66,36 @@
import { i18n } from '@/i18n'
import BasePicker from './base'
import PageMixin from '../mixins/page'
const BASE_LINK_PAGES = [
{ id: 'vipgrades', titleKey: '223cc8af.f035ca' },
{ id: 'applyChief', titleKey: '223cc8af.38d966' },
{ id: 'recharge', titleKey: '223cc8af.1200d5' },
{ id: 'purchase', titleKey: '223cc8af.d0465c' },
{ id: 'pointShop', titleKey: '223cc8af.a13364' },
{ id: 'registActivity', titleKey: '223cc8af.7fb92b' },
{ id: 'group', titleKey: '223cc8af.75a1d2' },
{ id: 'coupon_list', titleKey: '223cc8af.2f3635' },
{ id: 'my_coupon', titleKey: '223cc8af.a8f3e2' },
{ id: 'my_collect', titleKey: '223cc8af.975ff6' },
{ id: 'address', titleKey: '223cc8af.bca1ea' },
{ id: 'groups_list', titleKey: '223cc8af.f38e72' },
{ id: 'hottopic', titleKey: '223cc8af.26b2d6' },
{ id: 'zitiOrder', titleKey: '223cc8af.d50361' },
{ id: 'homeSearch', titleKey: '223cc8af.e5f71f' },
{ id: 'settings', titleKey: '223cc8af.e366cc' },
{ id: 'kujiale', titleKey: '223cc8af.f2d3e5' },
{ id: 'nearby_store', titleKey: '223cc8af.3b02dd' },
{ id: 'itemList', titleKey: '223cc8af.437974' }
]
function mapPageTitles(vm, items) {
return items.map(({ id, titleKey }) => ({
id,
title: vm.$t(titleKey)
}))
}
export default {
name: 'PickerLink',
extends: BasePicker,
@@ -87,54 +112,42 @@ export default {
formData: {
keywords: ''
},
list: [
{ id: 'vipgrades', title: this.$t('223cc8af.f035ca') },
{ id: 'applyChief', title: this.$t('223cc8af.38d966') },
{ id: 'recharge', title: this.$t('223cc8af.1200d5') },
{ id: 'purchase', title: this.$t('223cc8af.d0465c') },
{ id: 'pointShop', title: this.$t('223cc8af.a13364') },
{ id: 'registActivity', title: this.$t('223cc8af.7fb92b') },
{ id: 'group', title: this.$t('223cc8af.75a1d2') },
{ id: 'coupon_list', title: this.$t('223cc8af.2f3635') },
{ id: 'my_coupon', title: this.$t('223cc8af.a8f3e2') },
{ id: 'my_collect', title: this.$t('223cc8af.975ff6') },
{ id: 'address', title: this.$t('223cc8af.bca1ea') },
{ id: 'groups_list', title: this.$t('223cc8af.f38e72') },
{ id: 'hottopic', title: this.$t('223cc8af.26b2d6') },
{ id: 'zitiOrder', title: this.$t('223cc8af.d50361') },
{ id: 'homeSearch', title: this.$t('223cc8af.e5f71f') },
{ id: 'settings', title: this.$t('223cc8af.e366cc') },
{ id: 'kujiale', title: this.$t('223cc8af.f2d3e5') },
{ id: 'nearby_store', title: this.$t('223cc8af.3b02dd') },
{ id: 'nearby_store', title: this.$t('223cc8af.3b02dd') },
{ id: 'itemList', title: '商品列表' }
],
multiple: this.value?.multiple ?? true
}
},
computed: {
list() {
// 依赖 locale切换语言后页面名称会重新翻译
const locale = this.$i18n?.locale
void locale
if (this.value?.guide === 'share_page') {
return mapPageTitles(this, [
{ id: 'coupon_list', titleKey: '223cc8af.9c356b' },
{ id: 'my_coupon', titleKey: '223cc8af.a8f3e2' },
{ id: 'page_index', titleKey: '223cc8af.db1c89' },
{ id: 'category', titleKey: '223cc8af.d0771a' },
{ id: 'hottopic', titleKey: '223cc8af.26b2d6' }
])
}
const items = [...BASE_LINK_PAGES]
if (!this.VERSION_PLATFORM() && !this.VERSION_B2C()) {
items.push(
{ id: 'boost_activity', titleKey: '223cc8af.5c34aa' },
{ id: 'boost_order', titleKey: '223cc8af.94b1e6' }
)
}
if (!this.VERSION_STANDARD()) {
items.push({ id: 'tenants', titleKey: '223cc8af.1107a8' })
}
if (!this.VERSION_IN_PURCHASE()) {
items.push({ id: 'community_group_enable', titleKey: '223cc8af.d0f121' })
}
return mapPageTitles(this, items)
}
},
mounted() {
if (!this.VERSION_PLATFORM() && !this.VERSION_B2C()) {
// 平台版&b2c隐藏助力活动和助力订单
this.list.push(
{ id: 'boost_activity', title: this.$t('223cc8af.5c34aa') },
{ id: 'boost_order', title: this.$t('223cc8af.94b1e6') }
)
}
if (!this.VERSION_STANDARD()) {
this.list.push({ id: 'tenants', title: this.$t('223cc8af.1107a8') })
}
if (!this.VERSION_IN_PURCHASE()) {
this.list.push({ id: 'community_group_enable', title: this.$t('223cc8af.d0f121') })
}
if (this.value.guide == 'share_page') {
this.list = [
{ id: 'coupon_list', title: this.$t('223cc8af.9c356b') },
{ id: 'my_coupon', title: this.$t('223cc8af.a8f3e2') },
{ id: 'page_index', title: this.$t('223cc8af.db1c89') },
{ id: 'category', title: this.$t('223cc8af.d0771a') },
{ id: 'hottopic', title: this.$t('223cc8af.26b2d6') }
]
}
const raw = this.value?.data
if (raw == null || raw === '') return
const selectedIds = Array.isArray(raw) ? raw : [raw]
@@ -155,11 +168,9 @@ export default {
// this.updateVal(selection)
} else {
const { finderTable } = this.$refs.finder.$refs
console.log('finderTable:', finderTable)
finderTable.clearSelection()
setTimeout(() => {
finderTable.$refs.finderTable.setSelection([row])
// this.updateVal([row])
})
}
},

View File

@@ -4,9 +4,12 @@
class="box-border flex min-h-14 items-center justify-between gap-3 border-b border-[#e6e9ef] bg-white/95 px-[14px] py-2 max-[1360px]:flex-wrap max-[1360px]:items-stretch"
>
<div class="flex min-w-0 items-center gap-2.5">
<el-button class="!shrink-0" circle size="mini" @click="$emit('back')">
<ArrowLeft :size="16" class="text-[#606266]" :stroke-width="2" />
</el-button>
<span
class="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-[#eef4ff] text-[#2563eb]"
aria-hidden="true"
>
<LayoutTemplate :size="18" :stroke-width="2" />
</span>
<div class="flex min-w-0 flex-col items-start gap-0.5">
<div class="text-sm font-semibold leading-5 text-[#18222f]">{{ titleText }}</div>
<div class="flex items-center gap-2 whitespace-nowrap text-[11px] text-[#6b7785]">

View File

@@ -98,22 +98,6 @@
@input="updateField('tab_label', $event)"
/>
</section>
<section class="space-y-2">
<div class="text-sm text-muted-foreground">规格</div>
<el-select
:value="settings.size || sectionSize"
size="small"
class="w-full"
@change="updateSize"
>
<el-option value="xsmall" label="特小" />
<el-option value="small" label="小" />
<el-option value="medium" label="中" />
<el-option value="large" label="大" />
<el-option value="xlarge" label="特大" />
</el-select>
</section>
</div>
</template>
@@ -154,10 +138,6 @@ export default {
return this.selectedProducts.map(
(id) => snapshotMap.get(id) || { item_id: id, item_name: id }
)
},
sectionSize() {
const value = this.section?.settings?.size
return ['xsmall', 'small', 'medium', 'large', 'xlarge'].includes(value) ? value : 'medium'
}
},
methods: {
@@ -173,9 +153,6 @@ export default {
product_snapshots: snapshots
})
},
updateSize(value) {
this.$emit('change', { size: value, size_override: true })
},
clearProducts() {
this.$emit('change', { product_ids: [], product_snapshots: [] })
},

View File

@@ -367,6 +367,13 @@ export function serializeDsl(dsl) {
const nextDsl = cloneValue(dsl)
Object.keys(nextDsl.sections || {}).forEach((sectionId) => {
const section = nextDsl.sections[sectionId]
Object.keys(section.blocks || {}).forEach((blockId) => {
const block = section.blocks[blockId]
if (block?.type === 'product-tab' && block.settings) {
delete block.settings.size
delete block.settings.size_override
}
})
section.block_order = cloneValue(section.blockOrder || [])
})
return nextDsl

View File

@@ -51,16 +51,8 @@ export function normalizeProductTabBlockSettings(settings = {}) {
nextSettings.limit = Number.isFinite(Number(nextSettings.limit))
? Math.min(24, Math.max(2, Number(nextSettings.limit)))
: 8
if (
nextSettings.size !== undefined &&
!['xsmall', 'small', 'medium', 'large', 'xlarge'].includes(nextSettings.size)
) {
delete nextSettings.size
delete nextSettings.size_override
}
if (!nextSettings.size_override) {
delete nextSettings.size_override
}
delete nextSettings.size
delete nextSettings.size_override
if (nextSettings.columns !== undefined) {
nextSettings.columns = [2, 3, 4].includes(Number(nextSettings.columns))
? Number(nextSettings.columns)

View File

@@ -17960,6 +17960,8 @@
"39e3acc2.45394d": "مشاركة النشاط",
"39e3acc2.5925d6": "يظهر عند المشاركة عبر بطاقة البرنامج. مقاس 300*240، png/jpg، 2M كحد أقصى",
"39e3acc2.9742f1": "يرجى اختيار صورة النشاط",
"39e3acc2.a8c1e2": "ملصق قائمة النشاط",
"39e3acc2.b9d3f4": "يرجى رفع ملصق قائمة النشاط",
"39e3acc2.98fbb0": "ملصق النشاط",
"39e3acc2.818403": "مقترح: عرض 640px، ارتفاع تلقائي",
"39e3acc2.90a4b4": "يرجى اختيار ملصق النشاط",
@@ -18000,8 +18002,8 @@
"39e3acc2.040c4d": "قائمة السلع / التفاصيل",
"39e3acc2.c017be": "السلة",
"39e3acc2.482b55": "الدفع",
"39e3acc2.028f5b": "وصف الخصم",
"39e3acc2.8e568f": "عرض وصف الخصم في صفحة الدفع عند التفعيل",
"39e3acc2.028f5b": "تذكير الشراء الداخلي",
"39e3acc2.8e568f": "عرض تذكير الشراء الداخلي في صفحة الدفع عند التفعيل",
"39e3acc2.d0bea4": "تذكير الشراء للموظفين",
"39e3acc2.6a03e7": "مواضع العرض: صفحة تفاصيل المنتج، صفحة سلة التسوق، صفحة الدفع",
"39e3acc2.592c59": "وقت البداية",
@@ -22590,8 +22592,9 @@
"223cc8af.d50361": "طلب استلام ذاتي",
"223cc8af.e5f71f": "بحث",
"223cc8af.e366cc": "تبديل اللغة",
"223cc8af.f2d3e5": "",
"223cc8af.3b02dd": "",
"223cc8af.f2d3e5": "مكتبة حالات Kujiale",
"223cc8af.3b02dd": "قائمة جميع المتاجر",
"223cc8af.437974": "قائمة المنتجات",
"223cc8af.5c34aa": "دعم الفعالية",
"223cc8af.94b1e6": "طلبات التعزيز",
"223cc8af.1107a8": "انضمام التاجر",

View File

@@ -17962,6 +17962,8 @@
"39e3acc2.45394d": "Share activity",
"39e3acc2.5925d6": "Shown when sharing via mini-program card. Recommended 300*240, png/jpg, max 2M",
"39e3acc2.9742f1": "Please select activity image",
"39e3acc2.a8c1e2": "Activity list poster",
"39e3acc2.b9d3f4": "Please upload activity list poster",
"39e3acc2.98fbb0": "Activity poster",
"39e3acc2.818403": "Recommended: width 640px, height auto",
"39e3acc2.90a4b4": "Please select activity poster",
@@ -18002,8 +18004,8 @@
"39e3acc2.040c4d": "Goods list / detail",
"39e3acc2.c017be": "Cart",
"39e3acc2.482b55": "Checkout",
"39e3acc2.028f5b": "Discount description",
"39e3acc2.8e568f": "Show discount description on checkout when enabled",
"39e3acc2.028f5b": "Internal purchase reminder",
"39e3acc2.8e568f": "Show internal purchase reminder on checkout when enabled",
"39e3acc2.d0bea4": "Employee purchase reminder",
"39e3acc2.6a03e7": "Display locations: product detail page, shopping cart, checkout page",
"39e3acc2.592c59": "Start time",
@@ -22591,8 +22593,9 @@
"223cc8af.d50361": "Self-pickup order",
"223cc8af.e5f71f": "Search",
"223cc8af.e366cc": "Switch language",
"223cc8af.f2d3e5": "",
"223cc8af.3b02dd": "",
"223cc8af.f2d3e5": "Kujiale case library",
"223cc8af.3b02dd": "All store list",
"223cc8af.437974": "Product list",
"223cc8af.5c34aa": "Support the event",
"223cc8af.94b1e6": "Boost orders",
"223cc8af.1107a8": "Merchant entry",

View File

@@ -18052,6 +18052,8 @@
"39e3acc2.45394d": "分享活动",
"39e3acc2.5925d6": "员工通过小程序卡片分享活动时展示建议尺寸300*240支持 png、jpg 格式,文件大小为 2M 内",
"39e3acc2.9742f1": "请选择活动图片",
"39e3acc2.a8c1e2": "活动列表海报",
"39e3acc2.b9d3f4": "请上传活动列表海报",
"39e3acc2.98fbb0": "活动海报",
"39e3acc2.818403": "建议尺寸:宽度640px高度自适应",
"39e3acc2.90a4b4": "请选择活动海报",
@@ -18092,8 +18094,8 @@
"39e3acc2.040c4d": "商品列表/商详页面",
"39e3acc2.c017be": "购物车",
"39e3acc2.482b55": "结算页",
"39e3acc2.028f5b": "优惠说明",
"39e3acc2.8e568f": "开启优惠说明展示在结算页,关闭不展示",
"39e3acc2.028f5b": "内购提醒",
"39e3acc2.8e568f": "开启内购提醒展示在结算页,关闭不展示",
"39e3acc2.d0bea4": "内购提醒",
"39e3acc2.6a03e7": "显示位置:商品详情页、购物车页面、结算页",
"39e3acc2.592c59": "开始时间",
@@ -22593,6 +22595,7 @@
"223cc8af.e366cc": "切换语言",
"223cc8af.f2d3e5": "酷家乐案例库",
"223cc8af.3b02dd": "所有门店列表",
"223cc8af.437974": "商品列表",
"223cc8af.5c34aa": "助力活动",
"223cc8af.94b1e6": "助力订单",
"223cc8af.1107a8": "商家入驻",

View File

@@ -438,6 +438,17 @@ const routes = [
permissions: ['applications.kujiale.kujiale-products']
},
component: () => import('@/views/applications/kujiale/list')
},
{
name: 'appcenter',
path: 'shopex/appcenter',
meta: {
aliasName: 'shopex-appcenter',
icon: 'icon-products',
title: '商派应用中心',
permissions: ['applications.shopex-appcenter']
},
component: () => import('@/views/applications/application-center/shopex-appcenter')
}
]
}

View File

@@ -405,6 +405,11 @@ export default {
path: 'community/chiefupload',
name: '5286ac37.5ad881',
component: () => import('@/view/member/members/upload_chief')
},
{
path: 'shopex/appcenter',
name: '商派用户中心',
component: () => import('@/views/applications/application-center/shopex-appcenter')
}
]
}

View File

@@ -360,9 +360,11 @@ export default {
findWidgetForPersistedName(persistedName) {
const key = String(persistedName || '').toLowerCase()
if (!key || !this.widgets.length) return null
let w = this.widgets.find((item) => (item.name || '').toLowerCase() === key)
// 附近商家已合并到店铺挂件,历史数据 name 仍为 nearbyShop
const lookupKey = key === 'nearbyshop' ? 'shop' : key
let w = this.widgets.find((item) => (item.name || '').toLowerCase() === lookupKey)
if (w) return w
w = this.widgets.find((item) => String(item.config?.name || '').toLowerCase() === key)
w = this.widgets.find((item) => String(item.config?.name || '').toLowerCase() === lookupKey)
if (w) return w
if (String(this.localScene) === '1005' && key === 'goods') {
return (

View File

@@ -9,7 +9,6 @@ import WgtFilm from './wgt_film'
import WgtCoupon from './wgt_coupon'
import WgtShop from './wgt_shop'
import WgtMarquees from './wgt_marquees'
import WgtNearbyShop from './wgt_nearbyShop'
import WgtGoodsCard from './wgt_goodsCard'
import WgtWriting from './wgt_writing'
import WgtHeading from './wgt_heading'

View File

@@ -3,6 +3,60 @@ import { i18n } from '@/i18n'
import AttrStore from './attr-store'
import { transformInBase, createTransformOutBase } from '../../comps/transform-utils'
const NEARBY_SETTING_KEYS = [
'title',
'subtitle',
'padded',
'show_nearby_merchants',
'merchantsNumber',
'quantityNumber'
]
const SHARED_BASE_KEYS = [
'dataType',
'outerMargin',
'innerPadding',
'outerBackground',
'innerBackground',
'wgtCustName',
'track',
...NEARBY_SETTING_KEYS
]
function isNearbyDataType(v, raw = {}) {
if (raw.name === 'nearbyShop') return true
const base = raw.base || {}
return (base.dataType || v.dataType) === 'nearby'
}
function buildNearbySetting() {
return [
{ label: i18n.t('9b7fb994.4707ba'), key: 'padded', component: 'switch', value: false },
{
label: i18n.t('9b7fb994.f417a5'),
key: 'show_nearby_merchants',
component: 'switch',
value: false
},
{
label: i18n.t('9b7fb994.35f408'),
key: 'merchantsNumber',
component: 'number',
value: 4,
min: 1,
max: 100
},
{
label: i18n.t('9b7fb994.81756c'),
key: 'quantityNumber',
component: 'number',
value: 4,
min: 1,
max: 100
}
]
}
const config = {
name: 'shop',
setting: [
@@ -22,13 +76,17 @@ const config = {
label: i18n.t('ca99873f.185f7b'),
key: 'dataType',
component: 'select',
options: [{ label: i18n.t('ca99873f.fcf7d8'), value: 'specify' }],
options: [
{ label: i18n.t('ca99873f.fcf7d8'), value: 'specify' },
{ label: i18n.t('5e1ae7f2.0c0d95'), value: 'nearby' }
],
value: 'specify',
onchange: function (e, vm) {
vm.value.data = []
if (e === 'nearby') {
vm.value.data = []
}
}
},
{
label: i18n.t('ca99873f.e7af71'),
key: 'data',
@@ -38,117 +96,86 @@ const config = {
v-model={this.value[key]}
on-change={() => {
if (this.value[key].id === '') {
this.value['items'] = []
this.value['tags'] = []
this.value.items = []
this.value.tags = []
}
}}
/>
)
},
value: [],
isShow: function () {
isShow() {
return this.value.dataType === 'specify'
}
}
// {
// label: '组件外边距',
// key: 'outerMargin',
// component: function (h, { key }) {
// return (
// <CompStyle
// showBgsetting={false}
// v-model={this.value[key]}
// uuid={this.value.uuid}
// showLabel={false}
// showLeft={false}
// showRight={false}
// />
// )
// },
// value: {
// paddedt: 10,
// paddedb: 10
// }
// },
// {
// label: '组件内边距',
// key: 'innerPadding',
// component: function (h, { key }) {
// return (
// <CompStyle
// showBgsetting={false}
// v-model={this.value[key]}
// uuid={this.value.uuid}
// showLabel={false}
// />
// )
// },
// value: {
// paddedt: 10,
// paddedb: 10,
// paddedl: 10,
// paddedr: 10
// }
// },
// {
// label: '组件外背景',
// key: 'outerBackground',
// component: function (h, { key }) {
// return <CompOuter v-model={this.value[key]} uuid={this.value.uuid} />
// },
// value: { color: '#f8f8f8', image: '' }
// },
// {
// label: '组件内背景',
// key: 'innerBackground',
// component: function (h, { key }) {
// return <CompInner v-model={this.value[key]} uuid={this.value.uuid} />
// },
// value: { type: 'solid', color: '#ffffff', startColor: '#ffffff', endColor: '#ffffff' }
// }
},
...buildNearbySetting().map((item) => ({
...item,
isShow() {
return this.value.dataType === 'nearby'
}
}))
],
transformIn: (v) => {
const { name, base, data, meber_tags = [], no_meber_tags = [], tagsType } = v
// 使用公共函数处理 base 中的样式数据转换
const nearby = isNearbyDataType(v, v)
const base = v.base || {}
const transformedBase = transformInBase(base, ['outerMargin', 'innerPadding'])
return {
const tags = {
type: v.tagsType || '2',
meber_tags: v.meber_tags || [],
no_meber_tags: v.no_meber_tags || []
}
const common = {
id: v?.id,
name,
name: 'shop',
dataType: nearby ? 'nearby' : base.dataType || 'specify',
...transformedBase,
data: data,
tags: {
type: tagsType || '2',
meber_tags: meber_tags || [],
no_meber_tags: no_meber_tags || []
wgtCustName: base.wgtCustName ?? '',
track: v.track ?? base.track ?? '',
tags
}
if (nearby) {
return {
...common,
data: [],
title: base.title ?? '',
subtitle: base.subtitle ?? '',
padded: base.padded ?? false,
show_nearby_merchants: base.show_nearby_merchants ?? false,
merchantsNumber: base.merchantsNumber ?? 4,
quantityNumber: base.quantityNumber ?? 4
}
}
return {
...common,
data: v.data || [],
padded: false,
show_nearby_merchants: false,
merchantsNumber: 4,
quantityNumber: 4,
title: '',
subtitle: ''
}
},
transformOut: (v, wgtList, regionauth_id) => {
return pickBy(v, {
const nearby = v.dataType === 'nearby'
const baseKeys = nearby
? SHARED_BASE_KEYS
: SHARED_BASE_KEYS.filter((k) => !NEARBY_SETTING_KEYS.includes(k))
const out = {
id: 'id',
name: 'name',
base: (v) => {
// 使用公共函数处理 outerMargin 和 innerPadding 转换,同时保留其他字段
const baseData = createTransformOutBase(
[
'dataType',
'outerMargin',
'innerPadding',
'outerBackground',
'innerBackground',
'wgtCustName',
'track'
],
['outerMargin', 'innerPadding']
)(v)
return baseData
},
data: 'data',
name: () => 'shop',
base: createTransformOutBase(baseKeys, ['outerMargin', 'innerPadding']),
meber_tags: 'tags.meber_tags',
no_meber_tags: 'tags.no_meber_tags',
tagsType: 'tags.type',
noRegionauth: !regionauth_id
})
}
if (nearby) {
out.data = () => []
} else {
out.data = 'data'
}
return pickBy(v, out)
}
}

View File

@@ -4,21 +4,21 @@
<div
:class="[
'wgt-shop-container-list',
{ 'wgt-shop-container-list-single': value.data.length == 1 }
{ 'wgt-shop-container-list-single': displayShops.length == 1 }
]"
>
<div
v-for="(item, index) in value.data"
:key="index"
v-for="(shop, index) in displayShops"
:key="shopRowKey(shop, index)"
class="wgt-shop-item"
:style="innerStyle"
>
<div class="shop-header">
<div class="shop-info">
<div class="shop-logo">
<img :src="value.distributor?.logo || defaultShopLogo" alt="店铺logo" />
<img :src="shopLogo(shop)" alt="店铺logo" />
</div>
<div class="shop-name">{{ item?.name || 'ADIDAS' }}</div>
<div class="shop-name">{{ shopName(shop) }}</div>
</div>
<div class="shop-actions">
<div class="favorite-btn">
@@ -28,19 +28,23 @@
</div>
</div>
<div class="shop-products">
<div v-for="(item, index) in distributorData" :key="index" class="product-item">
<div
v-for="(product, pIndex) in productsForShop(shop)"
:key="`${index}-${pIndex}`"
class="product-item"
>
<div class="product-image">
<el-image
:src="item?.pics && item?.pics.length > 0 ? item?.pics[0] : ''"
:src="productImage(product)"
alt="商品图片"
>
<div slot="error" class="image-slot" />
</el-image>
</div>
<div class="product-title">{{ item?.item_name || i18n.t('1d819fcf.1fd1d5') }}</div>
<div class="product-title">{{ product?.item_name || i18n.t('1d819fcf.1fd1d5') }}</div>
<div class="product-tags">
<span
v-for="(tag, tagIndex) in item?.tags || ['4折', '活动标']"
v-for="(tag, tagIndex) in productTags(product)"
:key="tagIndex"
class="tag"
:class="'tag-' + tagIndex"
@@ -49,8 +53,8 @@
</div>
<div class="product-price">
<span class="current-price-symbol">¥</span>
<span class="current-price">{{ item?.price / 100 }}</span>
<span class="original-price">{{ item?.market_price / 100 }}</span>
<span class="current-price">{{ (product?.price || 0) / 100 }}</span>
<span class="original-price">{{ (product?.market_price || 0) / 100 }}</span>
</div>
</div>
</div>
@@ -63,7 +67,23 @@
import { i18n } from '@/i18n'
import config from './config'
import { getOuterStyle, getInnerStyle } from '../../comps/style-utils'
const defaultShopLogo = require('@/assets/imgs/decorate/default-shop-logo.png')
const NEARBY_PLACEHOLDER_PRODUCT = {
item_name: '',
price: 19900,
market_price: 29900,
pics: [],
tags: ['4折', '活动标']
}
function clampCount(n, fallback = 4, max = 100) {
const num = Number(n)
if (!Number.isFinite(num) || num < 1) return fallback
return Math.min(Math.floor(num), max)
}
export default {
name: 'Shop',
wgtName: i18n.t('1d819fcf.295713'),
@@ -75,9 +95,32 @@ export default {
value: [Object, Array]
},
data() {
return { i18n, currentIndex: 1, defaultShopLogo, distributorData: null }
return {
i18n,
defaultShopLogo,
distributorData: []
}
},
computed: {
isNearbyType() {
return this.value?.dataType === 'nearby'
},
nearbyMerchantsCount() {
return clampCount(this.value?.merchantsNumber)
},
nearbyProductsCount() {
return clampCount(this.value?.quantityNumber)
},
displayShops() {
if (this.isNearbyType) {
return Array.from({ length: this.nearbyMerchantsCount }, (_, index) => ({
_placeholder: true,
distributor_id: `nearby-placeholder-${index}`,
name: i18n.t('5e1ae7f2.0c0d95')
}))
}
return this.value?.data || []
},
outerStyle() {
return getOuterStyle(this.value)
},
@@ -86,32 +129,61 @@ export default {
}
},
watch: {
value: {
handler(newVal) {},
immediate: true,
deep: true
},
'value.data': {
handler(newVal) {
if (newVal.length > 0) {
this.getList()
if (!this.isNearbyType && newVal && newVal.length > 0) {
this.loadSpecifyGoods()
} else if (!this.isNearbyType) {
this.distributorData = []
}
},
immediate: true,
deep: true
},
'value.dataType'() {
if (!this.isNearbyType) {
this.loadSpecifyGoods()
} else {
this.distributorData = []
}
}
},
created() {},
methods: {
async getList() {
const query = {
data_type: 'distributor',
data_value: this.value?.data[0]?.distributor_id
shopRowKey(shop, index) {
return shop.distributor_id || shop.id || `shop-${index}`
},
shopLogo(shop) {
return shop.logo || this.defaultShopLogo
},
shopName(shop) {
return shop.name || shop.distributor_name || 'ADIDAS'
},
productsForShop(shop) {
if (this.isNearbyType) {
return Array.from({ length: this.nearbyProductsCount }, () => ({
...NEARBY_PLACEHOLDER_PRODUCT,
item_name: i18n.t('1d819fcf.1fd1d5')
}))
}
console.log(this.value?.data, 'getSeckdistributorilldata')
const res = await this.$api.template.getShelvesGoods(query)
console.log(res, 'getSeckdistributorilldata')
this.distributorData = res
return this.distributorData || []
},
productImage(product) {
return product?.pics && product.pics.length > 0 ? product.pics[0] : ''
},
productTags(product) {
return product?.tags || ['4折', '活动标']
},
async loadSpecifyGoods() {
const first = this.value?.data?.[0]
if (!first?.distributor_id) {
this.distributorData = []
return
}
const res = await this.$api.template.getShelvesGoods({
data_type: 'distributor',
data_value: first.distributor_id
})
this.distributorData = res || []
}
}
}

View File

@@ -187,6 +187,8 @@
<el-form-item :label="$t('4d1aec94.53c3dd')">
<el-switch
v-model="aftersalesRemindForm.is_open"
active-value="true"
inactive-value="false"
active-color="#13ce66"
inactive-color="#ff4949"
/>
@@ -282,7 +284,7 @@ export default {
],
aftersalesRemindForm: {
intro: '',
is_open: false
is_open: 'false'
},
aftersalesRemindVisible: false,
aftersalesRemindTitle: i18n.t('4d1aec94.117b5a'),
@@ -816,11 +818,17 @@ export default {
})
}
},
normalizeAftersalesRemindIsOpen(value) {
return value === 'true' || value === true || value === 1 || value === '1' ? 'true' : 'false'
},
async aftersalesRemindAction() {
// 请求提醒数据
const data = await this.$api.aftersales.getAftersalesRemind()
if (data) {
this.aftersalesRemindForm = data
this.aftersalesRemindForm = {
intro: data.intro || '',
is_open: this.normalizeAftersalesRemindIsOpen(data.is_open)
}
}
this.aftersalesRemindVisible = true
},
@@ -830,12 +838,12 @@ export default {
handleCancel() {
this.aftersalesRemindVisible = false
this.aftersalesRemindForm.intro = ''
this.aftersalesRemindForm.is_open = false
this.aftersalesRemindForm.is_open = 'false'
},
async submitAftersalesRemind() {
let params = {
intro: this.aftersalesRemindForm.intro,
is_open: this.aftersalesRemindForm.is_open
is_open: this.normalizeAftersalesRemindIsOpen(this.aftersalesRemindForm.is_open)
}
await this.$api.aftersales.setAftersalesRemind(params)
this.$message({
@@ -843,6 +851,9 @@ export default {
message: this.$t('4d1aec94.3b1083')
})
this.aftersalesRemindVisible = false
this.$nextTick(() => {
this.$refs.finder?.refresh()
})
},
handleSelectionChange(val) {
console.log('handleSelectionChange', val)

View File

@@ -346,6 +346,7 @@ export default {
title: '',
linkHome: null,
share_pic: '',
list_pic: '',
pic: ''
},
formBaseList: [],
@@ -506,6 +507,19 @@ export default {
}
}
},
{
label: t('39e3acc2.a8c1e2'),
key: 'list_pic',
component: () => <SpImagePicker v-model={self.formBase.list_pic} />,
tip: t('39e3acc2.818403'),
validator: (rule, value, callback) => {
if (isEmpty(self.formBase.list_pic)) {
callback(new Error(t('39e3acc2.b9d3f4')))
} else {
callback()
}
}
},
{
label: t('39e3acc2.98fbb0'),
key: 'pic',
@@ -1091,6 +1105,7 @@ export default {
title: res.title,
linkHome,
share_pic: res.share_pic,
list_pic: res.list_pic || res.pic || '',
pic: res.pic
}
@@ -1158,11 +1173,31 @@ export default {
enterprise_id: res.enterprise_id
})
// res.price_display_config = {"cart_page": {"sale_price": "true", "market_price": "false", "activity_price": "false"}, "items_page": {"sale_price": "true", "market_price": "true", "activity_price": "false"}, "checkout_page": {"sale_price": "true", "market_price": "false", "activity_price": "false"}, "order_detail_page": {"sale_price": "true", "market_price": "false", "activity_price": "true"}}
//价格展示处理
const priceData = this.priceShowData(res.price_display_config, 'detail')
console.log('priceData', priceData)
const phraseMap = {}
;(res.passphrase_enterprises || []).forEach((pe) => {
const eid = pe.enterprise_id
phraseMap[eid] = {
participate_quota: pe.participate_quota,
passphrase_code: pe.passphrase_code || '',
passphrase_limitfee:
pe.passphrase_limitfee != null && pe.passphrase_limitfee !== ''
? Number(pe.passphrase_limitfee) / 100
: ''
}
})
const passphraseRows = list.map((c) => {
const pm = phraseMap[c.id]
return {
enterprise_id: c.id,
name: c.name,
enterprise_sn: c.enterprise_sn || '',
participate_quota: pm ? pm.participate_quota : '',
passphrase_code: pm ? pm.passphrase_code : '',
passphrase_limitfee: pm ? pm.passphrase_limitfee : ''
}
})
const phraseMap = {}
;(res.passphrase_enterprises || []).forEach((pe) => {
@@ -1383,33 +1418,48 @@ export default {
this.passphraseBatchCodeGenerating = false
}
},
priceShowData(form, isDetail) {
//接口需要
// cart_page: {sale_price: "true", market_price: "false", activity_price: "false"},
// items_page: {sale_price: "true", market_price: "false", activity_price: "false"},
// checkout_page: {sale_price: "true", market_price: "false", activity_price: "false"},
// order_detail_page: {sale_price: "true", market_price: "false", activity_price: "false"}
let keys = ['items_page', 'cart_page', 'order_detail_page', 'checkout_page']
let prices = ['sale_price', 'market_price', 'activity_price']
if (isDetail) {
//编辑获取详情数据处理
return keys.reduce((prev, cur) => {
let _arr = []
prices.forEach((item) => {
_arr = Object.keys(form[cur]).filter((item2) => form[cur][item2] == 'true')
console.log(Object.keys(form[cur]))
})
prev[cur] = _arr
return prev
}, {})
normalizePriceDisplayConfig(raw) {
const defaultChecked = ['sale_price', 'activity_price']
const pageKeys = ['items_page', 'cart_page', 'order_detail_page', 'checkout_page']
const priceKeys = ['sale_price', 'market_price', 'activity_price']
let config = raw
if (config == null || config === '') {
config = {}
} else if (typeof config === 'string') {
try {
config = JSON.parse(config)
} catch (e) {
config = {}
}
}
return keys.reduce((prev, cur) => {
let _obj = {}
prices.forEach((item) => {
_obj[item] = form[cur].includes(item) + ''
})
prev[cur] = _obj
if (typeof config !== 'object') {
config = {}
}
return pageKeys.reduce((prev, pageKey) => {
const pageConfig = config[pageKey]
if (pageConfig && typeof pageConfig === 'object' && !Array.isArray(pageConfig)) {
prev[pageKey] = priceKeys.filter((k) => pageConfig[k] === 'true' || pageConfig[k] === true)
} else if (Array.isArray(pageConfig)) {
prev[pageKey] = pageConfig
} else {
prev[pageKey] = defaultChecked.slice()
}
return prev
}, {})
},
priceShowData(form, isDetail) {
const pageKeys = ['items_page', 'cart_page', 'order_detail_page', 'checkout_page']
const priceKeys = ['sale_price', 'market_price', 'activity_price']
if (isDetail) {
return this.normalizePriceDisplayConfig(form)
}
const normalized = this.normalizePriceDisplayConfig(form)
return pageKeys.reduce((prev, cur) => {
const checked = normalized[cur] || []
prev[cur] = priceKeys.reduce((obj, item) => {
obj[item] = String(checked.includes(item))
return obj
}, {})
return prev
}, {})
},
@@ -1421,6 +1471,7 @@ export default {
title,
linkHome: { pages_template_id },
share_pic,
list_pic,
pic
} = this.formBase
const {
@@ -1458,6 +1509,7 @@ export default {
title,
pages_template_id,
share_pic: share_pic,
list_pic: list_pic,
pic: pic,
enterprise_id: companyList.map((item) => item.id),
display_time: preheatMoment.unix(),

View File

@@ -138,12 +138,15 @@
<span class="btn" @click="copyTemplate(item.pages_template_id)">{{
$t('a066f499.79d3ab')
}}</span>
<!-- ECX-8712: 总部/店铺模版装修隐藏导航配置 -->
<!--
<span
v-if="!isDistributorTemplate"
class="btn"
@click="handleClickNav(item.pages_template_id)"
>{{ $t('a066f499.056f2d') }}</span
>
-->
<span class="btn" @click="abandonTemplate(item.pages_template_id)">{{
$t('a066f499.0044f6')
}}</span>

View File

@@ -0,0 +1,546 @@
<!--
Copyright © ShopeX http://www.shopex.cn. All rights reserved.
See LICENSE file for license details.
-->
<template>
<SpPage
v-loading="loading && viewMode !== 'iframe'"
class="user-center-page"
:no-sticky="true"
>
<div v-if="viewMode === 'goods'" v-loading="loading" class="appcenter-embed">
<div class="appcenter-workspace">
<div class="appcenter-tabs appcenter-tabs--no-user">
<div class="appcenter-tabs-main">
<button type="button" class="appcenter-tab active">应用市场</button>
</div>
</div>
<div class="appcenter-tab-panel active">
<div
v-if="!loading && goodsList.length === 0"
class="appcenter-empty"
>
{{ pageInfo.empty_text || '暂无可展示应用' }}
</div>
<div v-else class="appcenter-items appcenter-layout-grid">
<div
v-for="item in goodsList"
:key="item.goods_bn"
class="appcenter-card"
:data-goods-bn="item.goods_bn"
>
<div class="appcenter-card-main">
<h2>{{ item.display_name || item.goods?.name }}</h2>
<p>{{ item.goods_bn }}</p>
<div class="appcenter-meta">
<span>商品 BN{{ item.goods?.bn || item.goods_bn }}</span>
<span>价格¥{{ formatPrice(item.goods?.price) }}</span>
</div>
</div>
<form
class="appcenter-buy-form"
@submit.prevent="handleAppClick(item)"
>
<button
type="submit"
class="appcenter-action"
:disabled="openingBn === item.goods_bn"
data-appcenter-buy="1"
>
{{ openingBn === item.goods_bn ? '处理中...' : '立即购买' }}
</button>
</form>
</div>
</div>
</div>
</div>
</div>
<div v-else class="usercenter-iframe-wrap">
<iframe
v-if="iframeUrl"
:key="iframeUrl"
:src="iframeUrl"
class="usercenter-iframe"
frameborder="0"
scrolling="auto"
title="应用中心"
/>
<div v-else v-loading="loading" class="usercenter-iframe-placeholder" />
</div>
<el-dialog
title="用户中心授权"
:visible.sync="authDialogVisible"
width="480px"
top="12vh"
append-to-body
destroy-on-close
custom-class="usercenter-auth-dialog"
@closed="handleAuthDialogClosed"
>
<iframe
v-if="authIframeUrl"
ref="authIframe"
:key="authIframeUrl"
:src="authIframeUrl"
class="usercenter-auth-iframe"
frameborder="0"
scrolling="auto"
title="用户中心授权"
@load="onAuthIframeLoad"
/>
</el-dialog>
</SpPage>
</template>
<script>
import {
getAppcenterUrl,
getUsercenterAuthorizeUrl,
getAppcenterGoods,
getCertificate,
loginUsercenter
} from '@/api/company'
import { setUsercenterLoginSuccess } from '@/utils/usercenter-storage'
export default {
data() {
return {
loading: false,
openingBn: '',
pageInfo: {},
goodsList: [],
channel: 'ecshopx',
viewMode: 'goods',
iframeUrl: '',
authDialogVisible: false,
authIframeUrl: '',
authRedirecting: false,
codeLoginPromise: null
}
},
mounted() {
this.initPage()
},
beforeDestroy() {
this.codeLoginPromise = null
},
methods: {
async initPage() {
const code = (this.$route.query.code || '').trim()
if (code) {
// 授权回调会先落在弹窗 iframe 内,避免在 iframe 中重复换票
if (window.self !== window.top) {
return
}
if (this.codeLoginPromise) {
await this.codeLoginPromise
return
}
this.codeLoginPromise = this.handleOAuthCallback(code)
try {
await this.codeLoginPromise
} finally {
this.codeLoginPromise = null
}
return
}
if (await this.hasAppcenterCertificate()) {
await this.openAppcenterIframe()
return
}
await this.bootstrapGoodsView()
},
async handleOAuthCallback(code) {
const ok = await this.exchangeCodeAndLogin(code)
if (ok) {
await this.openAppcenterIframe()
} else {
await this.bootstrapGoodsView()
}
},
async hasAppcenterCertificate() {
try {
const response = await getCertificate()
const data = response?.data?.data || {}
const nodeId = String(data.node_id || '').trim()
const shopexUid = String(data.shopex_uid || '').trim()
return !!(nodeId && shopexUid)
} catch (error) {
return false
}
},
async bootstrapGoodsView() {
this.viewMode = 'goods'
this.iframeUrl = ''
this.authDialogVisible = false
this.authIframeUrl = ''
await this.loadGoods()
},
async exchangeCodeAndLogin(code) {
this.loading = true
try {
await loginUsercenter({ code })
setUsercenterLoginSuccess()
await this.$router.replace({ path: this.$route.path, query: {} })
this.$message.success('授权登录成功')
return true
} catch (error) {
this.$message.error(this.resolveErrorMessage(error))
await this.$router.replace({ path: this.$route.path, query: {} })
return false
} finally {
this.loading = false
}
},
async openAppcenterIframe() {
this.authDialogVisible = false
this.authIframeUrl = ''
this.viewMode = 'iframe'
this.iframeUrl = ''
this.loading = true
try {
this.iframeUrl = await this.fetchAppcenterUrl()
} catch (error) {
this.$message.error(this.resolveErrorMessage(error))
await this.bootstrapGoodsView()
} finally {
this.loading = false
}
},
async fetchAppcenterUrl() {
const urlResponse = await getAppcenterUrl()
const urlData = urlResponse?.data?.data
const url =
(typeof urlData === 'string' ? urlData : '') || urlData?.url || ''
if (!url) {
throw new Error('获取应用中心地址失败')
}
return url
},
async loadGoods() {
this.loading = true
try {
const goodsRes = await getAppcenterGoods()
const data = goodsRes?.data?.data || {}
this.pageInfo = data.page || {}
this.goodsList = Array.isArray(data.items) ? data.items : []
this.channel = data.channel || 'ecshopx'
} catch (error) {
this.$message.error(this.resolveErrorMessage(error))
this.goodsList = []
} finally {
this.loading = false
}
},
async handleAppClick(item) {
if (this.openingBn) return
this.openingBn = item.goods_bn
try {
const response = await getUsercenterAuthorizeUrl()
const data = response?.data?.data
const url = (typeof data === 'string' ? data : '') || data?.url || ''
if (!url) {
this.$message.error('获取授权链接失败')
return
}
this.authRedirecting = false
this.authIframeUrl = url
this.authDialogVisible = true
} catch (error) {
this.$message.error(this.resolveErrorMessage(error))
} finally {
this.openingBn = ''
}
},
handleAuthDialogClosed() {
this.authIframeUrl = ''
this.authRedirecting = false
},
onAuthIframeLoad() {
if (!this.authDialogVisible || this.authRedirecting) return
try {
const iframe = this.$refs.authIframe
const loc = iframe?.contentWindow?.location
if (!loc?.href) return
const code = new URL(loc.href).searchParams.get('code')
if (!code) return
const callbackPath = this.$route.path
if (!loc.pathname.endsWith(callbackPath)) return
this.authRedirecting = true
window.location.href = loc.href
} catch (e) {
// 授权页跨域阶段无法读取 iframe 地址,待回调至同源 redirect_uri 后再处理
}
},
formatPrice(price) {
const num = Number(price)
if (Number.isNaN(num)) return price || '0.00'
return num.toFixed(2)
},
resolveErrorMessage(error) {
return (
error?.data?.data?.message ||
error?.data?.message ||
error?.response?.data?.data?.message ||
error?.response?.data?.message ||
error?.message ||
'操作失败'
)
}
}
}
</script>
<style lang="scss">
.sp-page.user-center-page {
min-height: 0;
background: #fff;
border-radius: 6px;
overflow: hidden;
.sp-page__content {
padding: 14px;
background: #fff;
}
.appcenter-embed {
box-sizing: border-box;
min-height: calc(100vh - 160px);
margin: 0;
padding: 0;
background: #f5f7fb;
overflow: hidden;
color: #263445;
font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
font-size: 14px;
line-height: 1.5;
text-align: left;
*,
*::before,
*::after {
box-sizing: border-box;
}
}
.appcenter-workspace {
position: relative;
margin: 14px;
background: #fff;
border: 1px solid #e2e8f0;
border-radius: 8px;
box-shadow: 0 1px 5px rgba(20, 35, 60, 0.05);
}
.appcenter-tabs {
min-height: 0;
padding: 0 16px;
border-bottom: 1px solid #e5ebf3;
background: #fbfcfe;
border-radius: 8px 8px 0 0;
&.appcenter-tabs--no-user {
padding-right: 16px;
}
}
.appcenter-tabs-main {
white-space: nowrap;
overflow: hidden;
}
.appcenter-tab {
display: inline-block;
margin: 0 22px 0 0;
padding: 11px 2px 9px;
border: 0;
border-bottom: 2px solid transparent;
background: transparent;
color: #667789;
font-size: 14px;
cursor: default;
outline: none;
appearance: none;
-webkit-appearance: none;
&.active {
border-bottom-color: #263445;
color: #1f2d3d;
font-weight: 600;
}
}
.appcenter-tab-panel {
display: block;
}
.appcenter-items {
padding: 18px;
}
.appcenter-layout-grid {
font-size: 0;
.appcenter-card {
display: inline-block;
width: 48%;
margin-right: 1.5%;
vertical-align: top;
min-height: 142px;
font-size: 14px;
}
}
.appcenter-card {
position: relative;
box-sizing: border-box;
margin-bottom: 14px;
padding: 16px;
background: #fff;
border: 1px solid #e4e9f1;
border-radius: 8px;
box-shadow: 0 1px 5px rgba(20, 35, 60, 0.06);
h2 {
margin: 0 0 8px;
padding: 0;
font-size: 17px;
font-weight: 600;
color: #1f2d3d;
}
p {
margin: 0 0 12px;
padding: 0;
color: #697789;
font-size: 13px;
line-height: 1.6;
}
}
.appcenter-meta {
color: #8a97a6;
font-size: 12px;
span {
display: inline-block;
margin-right: 12px;
}
}
.appcenter-buy-form {
margin: 0;
padding: 0;
}
.appcenter-action {
display: inline-block;
margin-top: 14px;
padding: 7px 14px;
border: 0;
border-radius: 4px;
background: #263445;
color: #fff;
font-size: 13px;
line-height: 1.4;
text-decoration: none;
cursor: pointer;
outline: none;
appearance: none;
-webkit-appearance: none;
}
button.appcenter-action[disabled] {
background: #a6b0bd;
cursor: default;
}
.appcenter-empty {
margin: 22px 18px;
padding: 36px 16px;
border: 1px dashed #ccd5e2;
border-radius: 8px;
background: #fff;
color: #8a97a6;
text-align: center;
}
.appcenter-card-main {
display: block;
}
.usercenter-iframe-wrap {
display: flex;
flex-direction: column;
min-height: calc(100vh - 160px);
background: #f5f7fb;
overflow: hidden;
}
.usercenter-iframe {
flex: 1;
width: 100%;
min-height: 520px;
border: 0;
background: #fff;
}
.usercenter-iframe-placeholder {
flex: 1;
min-height: 520px;
}
@media (max-width: 640px) {
.sp-page__content {
padding: 14px;
}
.appcenter-layout-grid .appcenter-card {
display: block;
width: auto;
margin-right: 0;
}
}
}
.usercenter-auth-dialog {
max-width: calc(100vw - 32px);
border-radius: 8px;
overflow: hidden;
.el-dialog__header {
padding: 14px 20px 10px;
}
.el-dialog__title {
font-size: 16px;
line-height: 1.4;
}
.el-dialog__body {
padding: 0;
height: 420px;
overflow: hidden;
}
.usercenter-auth-iframe {
display: block;
width: 100%;
height: 420px;
border: 0;
background: #fff;
}
}
</style>

View File

@@ -27,7 +27,6 @@
:scene="scene"
:template-id="templateId"
:title="decorationTitle"
@back="decorationHandleBack"
@save="decorationHandleSave"
/>
</div>