261 lines
10 KiB
Plaintext
261 lines
10 KiB
Plaintext
<template>
|
|
<view class="admin-data-config anim-fade-in">
|
|
<!-- 椤堕儴鏍囬 -->
|
|
<view class="page-header border-shadow">
|
|
<view class="header-left">
|
|
<text class="page-title">鏁版嵁閰嶇疆</text>
|
|
</view>
|
|
<view class="header-right">
|
|
<view class="btn-save" @click="handleSave">
|
|
<text class="save-txt">淇濆瓨</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 涓诲唴瀹瑰尯锛氫笁鏍忓竷灞€ -->
|
|
<view class="main-content">
|
|
<view class="card-container border-shadow">
|
|
<!-- A. 宸︽爮锛氶厤缃垎绫昏彍鍗?-->
|
|
<MenuSide
|
|
:categories="categories"
|
|
:activeKey="activeKey"
|
|
@change="k => activeKey = k"
|
|
/>
|
|
|
|
<!-- B. 涓爮锛氭墜鏈洪瑙?-->
|
|
<PhonePreview
|
|
:activeKey="activeKey"
|
|
:activeLabel="activeLabel"
|
|
:activeConfig="activeConfig"
|
|
/>
|
|
|
|
<!-- C. 鍙虫爮锛氶厤缃〃鍗?-->
|
|
<view class="settings-column">
|
|
<view class="settings-header">
|
|
<view class="title-marker"></view>
|
|
<text class="settings-title">{{ activeTitle }}</text>
|
|
</view>
|
|
<view class="settings-desc-box">
|
|
<text class="settings-desc">{{ activeCategory?.recommendSizeText }}</text>
|
|
</view>
|
|
|
|
<!-- 寮€灞忓箍鍛婄壒鏈夊瓧娈?-->
|
|
<view v-if="activeKey === 'ad'" class="ad-special-fields">
|
|
<view class="form-row">
|
|
<text class="field-label">寮€鍚箍鍛?/text>
|
|
<switch :checked="activeConfig.enabled" @change="handleSwitchAd" color="#2d8cf0" />
|
|
</view>
|
|
<view class="form-row">
|
|
<text class="field-label">骞垮憡鏃堕棿</text>
|
|
<view class="input-with-unit">
|
|
<input type="number" class="time-input" v-model="activeConfig.durationSeconds" />
|
|
<text class="unit-txt">鍗曚綅(绉?</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 鍥剧墖椤圭紪杈戝櫒 -->
|
|
<view v-if="activeKey !== 'ad' || activeConfig.enabled">
|
|
<CarouselEditor
|
|
:items="activeConfig.items"
|
|
:max="activeConfig.max"
|
|
@add="handleAddItem"
|
|
@remove="handleRemoveItem"
|
|
@move="handleMove"
|
|
@update-item="handleUpdateItem"
|
|
@select-link="handleSelectLink"
|
|
/>
|
|
</view>
|
|
<view v-else class="ad-disabled-placeholder">
|
|
<text class="disabled-txt">寮€灞忓箍鍛婂凡鍏抽棴锛屽紑鍚悗鍙厤缃浘鐗?/text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="uts">
|
|
import { ref, computed, reactive } from 'vue'
|
|
import { type Category, type ConfigData, type LinkType } from '@/pages/mall/admin/decoration/components/types.uts'
|
|
import MenuSide from '@/pages/mall/admin/decoration/components/MenuSide.uvue'
|
|
import PhonePreview from '@/pages/mall/admin/decoration/components/PhonePreview.uvue'
|
|
import CarouselEditor from '@/pages/mall/admin/decoration/components/CarouselEditor.uvue'
|
|
|
|
// 鐘舵€佸畾涔?
|
|
const activeKey = ref('jingpin')
|
|
|
|
const categories = reactive<Category[]>([
|
|
{ key: 'jingpin', label: '棣栭〉绮惧搧鎺ㄨ崘鍥剧墖', type: 'carousel', recommendSizeText: '寤鸿灏哄锛?90 * 240px锛屾嫋鎷藉浘鐗囧彲璋冩暣鍥剧墖椤哄簭鍝︼紝鏈€澶氭坊鍔犱簲寮? },
|
|
{ key: 'hot', label: '鐑棬姒滃崟鎺ㄨ崘鍥剧墖', type: 'carousel', recommendSizeText: '寤鸿灏哄锛?90 * 240px锛屾嫋鎷藉浘鐗囧彲璋冩暣鍥剧墖椤哄簭鍝︼紝鏈€澶氭坊鍔犱簲寮? },
|
|
{ key: 'new', label: '棣栧彂鏂板搧鎺ㄨ崘鍥剧墖', type: 'carousel', recommendSizeText: '寤鸿灏哄锛?90 * 240px锛屾嫋鎷藉浘鐗囧彲璋冩暣鍥剧墖椤哄簭鍝︼紝鏈€澶氭坊鍔犱簲寮? },
|
|
{ key: 'promo', label: '淇冮攢鍗曞搧鎺ㄨ崘鍥剧墖', type: 'carousel', recommendSizeText: '寤鸿灏哄锛?90 * 240px锛屾嫋鎷藉浘鐗囧彲璋冩暣鍥剧墖椤哄簭鍝︼紝鏈€澶氭坊鍔犱簲寮? },
|
|
{ key: 'login', label: '鍚庡彴鐧诲綍椤甸潰骞荤伅鐗?, type: 'carousel', recommendSizeText: '寤鸿灏哄锛?90 * 240px锛屾嫋鎷藉浘鐗囧彲璋冩暣鍥剧墖椤哄簭鍝︼紝鏈€澶氭坊鍔犱簲寮? },
|
|
{ key: 'group', label: '鎷煎洟鍒楄〃杞挱鍥?, type: 'carousel', recommendSizeText: '寤鸿灏哄锛?10 * 300px锛屾嫋鎷藉浘鐗囧彲璋冩暣鍥剧墖椤哄簭鍝︼紝鏈€澶氭坊鍔犱簲寮? },
|
|
{ key: 'points', label: '绉垎鍟嗗煄杞挱鍥?, type: 'carousel', recommendSizeText: '寤鸿灏哄锛?10 * 300px锛屾嫋鎷藉浘鐗囧彲璋冩暣鍥剧墖椤哄簭鍝︼紝鏈€澶氭坊鍔犱簲寮? },
|
|
{ key: 'ad', label: '寮€灞忓箍鍛?, type: 'ad', recommendSizeText: '寤鸿灏哄锛?50 * 1334px锛屾嫋鎷藉浘鐗囧彲璋冩暣鍥剧墖椤哄簭鍝︼紝鏈€澶氭坊鍔犱簲寮? }
|
|
])
|
|
|
|
// 鍒濆鍖栨暟鎹?
|
|
const configMap = reactive<Record<string, ConfigData>>({
|
|
'jingpin': { max: 5, items: [{ id: 1, name: '1', imageUrl: '', link: { type: 'internal', value: '/pages/points_mall/integral_index' }, sort: 0 }] },
|
|
'hot': { max: 5, items: [{ id: 1, name: '1', imageUrl: '', link: { type: 'internal', value: '/pages/index/index' }, sort: 0 }] },
|
|
'new': { max: 5, items: [{ id: 1, name: '1', imageUrl: '', link: { type: 'internal', value: '/pages/index/index' }, sort: 0 }] },
|
|
'promo': { max: 5, items: [{ id: 1, name: '1', imageUrl: '', link: { type: 'internal', value: '/pages/points_mall/integral_index' }, sort: 0 }] },
|
|
'login': { max: 5, items: [{ id: 1, name: '1', imageUrl: '', link: { type: 'internal', value: '' }, sort: 0 }] },
|
|
'group': { max: 5, items: [{ id: 1, name: '鎷煎洟', imageUrl: '', link: { type: 'internal', value: '/pages/activity/goods_combination/index' }, sort: 0 }] },
|
|
'points': { max: 5, items: [{ id: 1, name: '1', imageUrl: '', link: { type: 'internal', value: '/pages/points_mall/integral_index' }, sort: 0 }] },
|
|
'ad': { enabled: false, durationSeconds: 3, max: 5, items: [] }
|
|
})
|
|
|
|
// 璁$畻灞炴€?
|
|
const activeCategory = computed(() => categories.find(c => c.key === activeKey.value))
|
|
const activeLabel = computed(() => activeCategory.value?.label ?? '')
|
|
const activeConfig = computed(() => configMap[activeKey.value])
|
|
const activeTitle = computed(() => {
|
|
if (activeKey.value === 'ad') return '寮曞椤佃缃?
|
|
if (activeKey.value === 'login') return '骞荤伅鐗囪缃?
|
|
return '杞挱鍥捐缃?
|
|
})
|
|
|
|
// 鏂规硶
|
|
const handleSave = () => {
|
|
uni.showLoading({ title: '淇濆瓨涓?..' })
|
|
setTimeout(() => {
|
|
uni.hideLoading()
|
|
uni.showToast({ title: '淇濆瓨鎴愬姛', icon: 'success' })
|
|
}, 800)
|
|
}
|
|
|
|
const handleSwitchAd = (e: any) => {
|
|
configMap['ad'].enabled = e.detail.value
|
|
}
|
|
|
|
const handleAddItem = () => {
|
|
const config = activeConfig.value
|
|
if (config.items.length >= config.max) {
|
|
uni.showToast({ title: `鏈€澶氭坊鍔?${config.max} 鏉, icon: 'none' })
|
|
return
|
|
}
|
|
config.items.push({
|
|
id: Date.now(),
|
|
name: (config.items.length + 1).toString(),
|
|
imageUrl: '',
|
|
link: { type: 'internal', value: '' },
|
|
sort: config.items.length
|
|
})
|
|
}
|
|
|
|
const handleRemoveItem = (index: number) => {
|
|
activeConfig.value.items.splice(index, 1)
|
|
}
|
|
|
|
const handleMove = (index: number, direction: number) => {
|
|
const items = activeConfig.value.items
|
|
const targetIndex = index + direction
|
|
if (targetIndex < 0 || targetIndex >= items.length) return
|
|
|
|
const temp = items[index]
|
|
items[index] = items[targetIndex]
|
|
items[targetIndex] = temp
|
|
}
|
|
|
|
const handleUpdateItem = (payload: any) => {
|
|
const { index, key, value } = payload
|
|
activeConfig.value.items[index][key] = value
|
|
}
|
|
|
|
const handleSelectLink = (index: number) => {
|
|
uni.showActionSheet({
|
|
itemList: ['鍐呴儴椤甸潰', '澶栭儴閾炬帴', '鍏朵粬灏忕▼搴?],
|
|
success: (res) => {
|
|
const types: LinkType[] = ['internal', 'external', 'miniProgram']
|
|
activeConfig.value.items[index].link.type = types[res.tapIndex]
|
|
uni.showToast({ title: '鍔熻兘寤鸿涓?, icon: 'none' })
|
|
}
|
|
})
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.admin-data-config {
|
|
background-color: #f0f2f5;
|
|
min-height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.border-shadow {
|
|
background-color: #fff;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
.page-header {
|
|
height: 60px;
|
|
padding: 0 24px;
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
z-index: 100;
|
|
}
|
|
|
|
.page-title { font-size: 16px; font-weight: bold; color: #333; }
|
|
|
|
.btn-save {
|
|
background-color: #2d8cf0;
|
|
padding: 6px 24px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
}
|
|
.save-txt { color: #fff; font-size: 14px; }
|
|
|
|
.main-content {
|
|
flex: 1;
|
|
padding: 24px;
|
|
}
|
|
|
|
.card-container {
|
|
display: flex;
|
|
flex-direction: row;
|
|
min-height: 800px;
|
|
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* 鍙充晶璁剧疆 */
|
|
.settings-column {
|
|
flex: 1;
|
|
padding: 30px;
|
|
background-color: #fff;
|
|
}
|
|
|
|
.settings-header {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
margin-bottom: 8px;
|
|
}
|
|
.title-marker { width: 3px; height: 16px; background-color: #1890ff; margin-right: 10px; border-radius: 2px; }
|
|
.settings-title { font-size: 16px; font-weight: bold; color: #333; }
|
|
|
|
.settings-desc-box { margin-bottom: 24px; padding-left: 13px; }
|
|
.settings-desc { font-size: 13px; color: #999; }
|
|
|
|
/* 寮€灞忓箍鍛婄壒鏈夋牱寮?*/
|
|
.ad-special-fields { padding: 20px; background-color: #f6f8fb; border-radius: 8px; margin-bottom: 20px; }
|
|
.form-row { display: flex; flex-direction: row; align-items: center; margin-bottom: 15px; }
|
|
.field-label { width: 80px; font-size: 14px; color: #333; }
|
|
.input-with-unit { display: flex; flex-direction: row; align-items: center; }
|
|
.time-input { width: 80px; height: 32px; border: 1px solid #dcdfe6; border-radius: 4px; padding: 0 10px; margin-right: 8px; background-color: #fff; }
|
|
.unit-txt { font-size: 12px; color: #999; }
|
|
|
|
.ad-disabled-placeholder { height: 200px; display: flex; align-items: center; justify-content: center; border: 1px dashed #eee; border-radius: 8px; }
|
|
.disabled-txt { color: #999; font-size: 14px; }
|
|
|
|
.anim-fade-in { animation: fadeIn 0.4s ease-out; }
|
|
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
|
</style>
|
|
|