展示页面
This commit is contained in:
parent
9698522be2
commit
83785dc20c
|
|
@ -105,6 +105,20 @@ export function setButlerQrcode(imageUrl: string) {
|
|||
return request.post('/admin/config/butlerQrcode', { imageUrl })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取展示页长图
|
||||
*/
|
||||
export function getDisplayPageImage() {
|
||||
return request.get('/admin/config/displayPageImage')
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置展示页长图
|
||||
*/
|
||||
export function setDisplayPageImage(imageUrl: string) {
|
||||
return request.post('/admin/config/displayPageImage', { imageUrl })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会员图标
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ const internalPageOptions = [
|
|||
{ label: '设置页面', value: '/pages/settings/index' },
|
||||
{ label: '关于我们', value: '/pages/about/index' },
|
||||
{ label: '用户协议', value: '/pages/agreement/user' },
|
||||
{ label: '隐私政策', value: '/pages/agreement/privacy' }
|
||||
{ label: '隐私政策', value: '/pages/agreement/privacy' },
|
||||
{ label: '展示页', value: '/pages/display/index' }
|
||||
]
|
||||
|
||||
// 链接类型提示
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ const internalPageOptions = [
|
|||
{ label: '我解锁的', value: '/pages/interact/myUnlocked' },
|
||||
{ label: '联系我们', value: '/pages/butler/index' },
|
||||
{ label: '用户协议', value: '/pages/agreement/index?type=user' },
|
||||
{ label: '隐私政策', value: '/pages/agreement/index?type=privacy' }
|
||||
{ label: '隐私政策', value: '/pages/agreement/index?type=privacy' },
|
||||
{ label: '展示页', value: '/pages/display/index' }
|
||||
]
|
||||
|
||||
// 链接类型提示
|
||||
|
|
|
|||
|
|
@ -103,6 +103,28 @@
|
|||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 展示页长图设置 -->
|
||||
<el-form-item label="展示页长图">
|
||||
<div class="qrcode-upload">
|
||||
<el-upload
|
||||
class="qrcode-uploader"
|
||||
:action="uploadUrl"
|
||||
:headers="uploadHeaders"
|
||||
:show-file-list="false"
|
||||
:on-success="handleDisplayPageImageSuccess"
|
||||
:before-upload="beforeAvatarUpload"
|
||||
accept="image/*"
|
||||
>
|
||||
<img v-if="configForm.displayPageImage" :src="getFullUrl(configForm.displayPageImage)" class="qrcode-preview" />
|
||||
<el-icon v-else class="qrcode-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
<div class="avatar-tip">
|
||||
<p>支持格式:JPG、PNG</p>
|
||||
<p>小程序展示页面展示的长图,可从Banner、金刚位跳转</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 会员图标设置 -->
|
||||
<el-form-item label="不限时会员图标">
|
||||
<div class="icon-upload">
|
||||
|
|
@ -301,6 +323,8 @@ import {
|
|||
setRealNameBanner,
|
||||
getButlerQrcode,
|
||||
setButlerQrcode,
|
||||
getDisplayPageImage,
|
||||
setDisplayPageImage,
|
||||
getMemberIcons,
|
||||
setMemberIcons,
|
||||
getMemberEntryImage,
|
||||
|
|
@ -321,6 +345,7 @@ const configForm = ref({
|
|||
searchBanner: '',
|
||||
realNameBanner: '',
|
||||
butlerQrcode: '',
|
||||
displayPageImage: '',
|
||||
unlimitedMemberIcon: '',
|
||||
sincereMemberIcon: '',
|
||||
familyMemberIcon: '',
|
||||
|
|
@ -352,14 +377,15 @@ const getFullUrl = (url) => {
|
|||
|
||||
const loadConfig = async () => {
|
||||
try {
|
||||
const [avatarRes, bannerRes, realNameBannerRes, qrcodeRes, memberIconsRes, memberEntryRes, realNamePriceRes] = await Promise.all([
|
||||
const [avatarRes, bannerRes, realNameBannerRes, qrcodeRes, memberIconsRes, memberEntryRes, realNamePriceRes, displayPageRes] = await Promise.all([
|
||||
getDefaultAvatar(),
|
||||
getSearchBanner(),
|
||||
getRealNameBanner(),
|
||||
getButlerQrcode(),
|
||||
getMemberIcons(),
|
||||
getMemberEntryImage(),
|
||||
getRealNamePrice()
|
||||
getRealNamePrice(),
|
||||
getDisplayPageImage()
|
||||
])
|
||||
if (avatarRes) {
|
||||
configForm.value.defaultAvatar = avatarRes.avatarUrl || ''
|
||||
|
|
@ -385,6 +411,9 @@ const loadConfig = async () => {
|
|||
if (realNamePriceRes) {
|
||||
configForm.value.realNamePrice = realNamePriceRes.price || 88
|
||||
}
|
||||
if (displayPageRes) {
|
||||
configForm.value.displayPageImage = displayPageRes.imageUrl || ''
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载配置失败:', error)
|
||||
}
|
||||
|
|
@ -445,6 +474,15 @@ const handleQrcodeSuccess = (response) => {
|
|||
}
|
||||
}
|
||||
|
||||
const handleDisplayPageImageSuccess = (response) => {
|
||||
if (response.code === 0 && response.data) {
|
||||
configForm.value.displayPageImage = response.data.url
|
||||
ElMessage.success('上传成功')
|
||||
} else {
|
||||
ElMessage.error(response.message || '上传失败')
|
||||
}
|
||||
}
|
||||
|
||||
const handleUnlimitedMemberIconSuccess = (response) => {
|
||||
if (response.code === 0 && response.data) {
|
||||
configForm.value.unlimitedMemberIcon = response.data.url
|
||||
|
|
@ -521,6 +559,9 @@ const saveBasicConfig = async () => {
|
|||
if (configForm.value.butlerQrcode) {
|
||||
promises.push(setButlerQrcode(configForm.value.butlerQrcode))
|
||||
}
|
||||
if (configForm.value.displayPageImage) {
|
||||
promises.push(setDisplayPageImage(configForm.value.displayPageImage))
|
||||
}
|
||||
if (configForm.value.memberEntryImage) {
|
||||
promises.push(setMemberEntryImage(configForm.value.memberEntryImage))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,6 +152,13 @@
|
|||
"navigationBarTitleText": "联系我们"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/display/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/webview/index",
|
||||
"style": {
|
||||
|
|
|
|||
188
miniapp/pages/display/index.vue
Normal file
188
miniapp/pages/display/index.vue
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
<template>
|
||||
<view class="display-page">
|
||||
<!-- 页面加载状态 -->
|
||||
<Loading type="page" :loading="pageLoading" />
|
||||
|
||||
<!-- 顶部背景图 -->
|
||||
<view class="top-bg">
|
||||
<image src="/static/title_bg.png" mode="aspectFill" class="bg-img" />
|
||||
</view>
|
||||
|
||||
<!-- 自定义导航栏 -->
|
||||
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||||
<view class="navbar-content">
|
||||
<view class="navbar-back" @click="handleBack">
|
||||
<text class="back-icon">‹</text>
|
||||
</view>
|
||||
<text class="navbar-title"></text>
|
||||
<view class="navbar-placeholder"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 内容区域 - 可滚动 -->
|
||||
<scroll-view class="content-area" scroll-y
|
||||
:style="{ marginTop: (statusBarHeight + 44) + 'px', height: 'calc(100vh - ' + (statusBarHeight + 44) + 'px)' }">
|
||||
<view class="content-wrapper">
|
||||
<view class="image-card">
|
||||
<image v-if="displayImage" class="display-img" :src="displayImage" mode="widthFix"
|
||||
@click="previewImage" />
|
||||
<view v-else class="image-placeholder">
|
||||
<text>暂无内容</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useConfigStore } from '@/store/config.js'
|
||||
import { getFullImageUrl } from '@/utils/image.js'
|
||||
import Loading from '@/components/Loading/index.vue'
|
||||
|
||||
const configStore = useConfigStore()
|
||||
|
||||
const statusBarHeight = ref(20)
|
||||
const pageLoading = ref(true)
|
||||
|
||||
const displayImage = computed(() => {
|
||||
const img = configStore.displayPageImage
|
||||
return img ? getFullImageUrl(img) : ''
|
||||
})
|
||||
|
||||
const getSystemInfo = () => {
|
||||
try {
|
||||
const res = uni.getSystemInfoSync()
|
||||
statusBarHeight.value = res.statusBarHeight || 20
|
||||
} catch (error) {
|
||||
console.error('获取系统信息失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleBack = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
const previewImage = () => {
|
||||
if (!displayImage.value) return
|
||||
uni.previewImage({
|
||||
urls: [displayImage.value]
|
||||
})
|
||||
}
|
||||
|
||||
const initPage = async () => {
|
||||
pageLoading.value = true
|
||||
try {
|
||||
getSystemInfo()
|
||||
configStore.isLoaded = false
|
||||
await configStore.loadAppConfig()
|
||||
} catch (error) {
|
||||
console.error('初始化页面失败:', error)
|
||||
} finally {
|
||||
pageLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initPage()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.display-page {
|
||||
height: 100vh;
|
||||
background-color: #f5f6fa;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.top-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 400rpx;
|
||||
z-index: 0;
|
||||
|
||||
.bg-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
|
||||
.navbar-content {
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 24rpx;
|
||||
|
||||
.navbar-back {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.back-icon {
|
||||
font-size: 56rpx;
|
||||
color: #333;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.navbar-placeholder {
|
||||
width: 80rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-area {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
padding: 24rpx 0 80rpx;
|
||||
}
|
||||
|
||||
.image-card {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.display-img {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.image-placeholder {
|
||||
width: 90%;
|
||||
height: 400rpx;
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -41,6 +41,7 @@ export const useConfigStore = defineStore('config', {
|
|||
searchBanner: '',
|
||||
realNameBanner: '',
|
||||
butlerQrcode: '', // 管家指导二维码
|
||||
displayPageImage: '', // 展示页长图
|
||||
memberEntryImage: '', // 会员入口图
|
||||
|
||||
// 会员图标配置
|
||||
|
|
@ -133,6 +134,7 @@ export const useConfigStore = defineStore('config', {
|
|||
this.searchBanner = config.searchBanner || ''
|
||||
this.realNameBanner = config.realNameBanner || ''
|
||||
this.butlerQrcode = config.butlerQrcode || ''
|
||||
this.displayPageImage = config.displayPageImage || ''
|
||||
this.memberEntryImage = config.memberEntryImage || ''
|
||||
|
||||
// 会员图标配置
|
||||
|
|
|
|||
|
|
@ -231,6 +231,34 @@ public class AdminConfigController : ControllerBase
|
|||
return result ? ApiResponse.Success("设置成功") : ApiResponse.Error(40001, "设置失败");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取展示页长图
|
||||
/// </summary>
|
||||
[HttpGet("displayPageImage")]
|
||||
public async Task<ApiResponse<DisplayPageImageResponse>> GetDisplayPageImage()
|
||||
{
|
||||
var imageUrl = await _configService.GetDisplayPageImageAsync();
|
||||
return ApiResponse<DisplayPageImageResponse>.Success(new DisplayPageImageResponse
|
||||
{
|
||||
ImageUrl = imageUrl
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置展示页长图
|
||||
/// </summary>
|
||||
[HttpPost("displayPageImage")]
|
||||
public async Task<ApiResponse> SetDisplayPageImage([FromBody] SetDisplayPageImageRequest request)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(request.ImageUrl))
|
||||
{
|
||||
return ApiResponse.Error(40001, "图片URL不能为空");
|
||||
}
|
||||
|
||||
var result = await _configService.SetDisplayPageImageAsync(request.ImageUrl);
|
||||
return result ? ApiResponse.Success("设置成功") : ApiResponse.Error(40001, "设置失败");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取会员图标
|
||||
/// </summary>
|
||||
|
|
@ -533,3 +561,25 @@ public class SetRealNamePriceRequest
|
|||
/// </summary>
|
||||
public decimal Price { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 展示页长图响应
|
||||
/// </summary>
|
||||
public class DisplayPageImageResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片URL
|
||||
/// </summary>
|
||||
public string? ImageUrl { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置展示页长图请求
|
||||
/// </summary>
|
||||
public class SetDisplayPageImageRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片URL
|
||||
/// </summary>
|
||||
public string ImageUrl { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,11 @@ public class AppConfigResponse
|
|||
/// </summary>
|
||||
public string? ButlerQrcode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 展示页长图URL
|
||||
/// </summary>
|
||||
public string? DisplayPageImage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 会员图标配置
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -92,6 +92,16 @@ public interface ISystemConfigService
|
|||
/// </summary>
|
||||
Task<bool> SetButlerQrcodeAsync(string imageUrl);
|
||||
|
||||
/// <summary>
|
||||
/// 获取展示页长图URL
|
||||
/// </summary>
|
||||
Task<string?> GetDisplayPageImageAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 设置展示页长图URL
|
||||
/// </summary>
|
||||
Task<bool> SetDisplayPageImageAsync(string imageUrl);
|
||||
|
||||
/// <summary>
|
||||
/// 获取会员图标URL(已废弃,请使用GetMemberIconsAsync)
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public class ConfigService : IConfigService
|
|||
var searchBanner = await _systemConfigService.GetSearchBannerAsync();
|
||||
var realNameBanner = await _systemConfigService.GetRealNameBannerAsync();
|
||||
var butlerQrcode = await _systemConfigService.GetButlerQrcodeAsync();
|
||||
var displayPageImage = await _systemConfigService.GetDisplayPageImageAsync();
|
||||
var memberIcons = await _systemConfigService.GetMemberIconsAsync();
|
||||
var dailyPopup = await GetPopupConfigAsync(1); // 每日弹窗
|
||||
var serviceAccountPopup = await GetPopupConfigAsync(2); // 服务号关注弹窗
|
||||
|
|
@ -65,6 +66,7 @@ public class ConfigService : IConfigService
|
|||
SearchBanner = searchBanner,
|
||||
RealNameBanner = realNameBanner,
|
||||
ButlerQrcode = butlerQrcode,
|
||||
DisplayPageImage = displayPageImage,
|
||||
MemberIcons = memberIcons,
|
||||
DailyPopup = dailyPopup,
|
||||
ServiceAccountPopup = serviceAccountPopup,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@ public class SystemConfigService : ISystemConfigService
|
|||
/// </summary>
|
||||
public const string ButlerQrcodeKey = "butler_qrcode";
|
||||
|
||||
/// <summary>
|
||||
/// 展示页长图配置键
|
||||
/// </summary>
|
||||
public const string DisplayPageImageKey = "display_page_image";
|
||||
|
||||
/// <summary>
|
||||
/// 会员图标配置键
|
||||
/// </summary>
|
||||
|
|
@ -240,6 +245,18 @@ public class SystemConfigService : ISystemConfigService
|
|||
return await SetConfigValueAsync(ButlerQrcodeKey, imageUrl, "管家指导二维码URL");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string?> GetDisplayPageImageAsync()
|
||||
{
|
||||
return await GetConfigValueAsync(DisplayPageImageKey);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> SetDisplayPageImageAsync(string imageUrl)
|
||||
{
|
||||
return await SetConfigValueAsync(DisplayPageImageKey, imageUrl, "展示页长图URL");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string?> GetMemberIconAsync()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user