细节修改
This commit is contained in:
parent
bf2da0c6d2
commit
4dcb830b93
|
|
@ -127,3 +127,17 @@ export function getMemberIcons() {
|
|||
export function setMemberIcons(icons: MemberIconsConfig) {
|
||||
return request.post('/admin/config/memberIcons', icons)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会员入口图
|
||||
*/
|
||||
export function getMemberEntryImage() {
|
||||
return request.get('/admin/config/memberEntryImage')
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置会员入口图
|
||||
*/
|
||||
export function setMemberEntryImage(imageUrl: string) {
|
||||
return request.post('/admin/config/memberEntryImage', { imageUrl })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,12 +56,15 @@ const internalPageOptions = [
|
|||
{ label: '会员中心', value: '/pages/member/index' },
|
||||
{ label: '填写资料', value: '/pages/profile/edit' },
|
||||
{ label: '实名认证', value: '/pages/realname/index' },
|
||||
{ label: '我的收藏', value: '/pages/favorite/index' },
|
||||
{ label: '浏览记录', value: '/pages/history/index' },
|
||||
{ label: '设置页面', value: '/pages/settings/index' },
|
||||
{ label: '关于我们', value: '/pages/about/index' },
|
||||
{ label: '用户协议', value: '/pages/agreement/user' },
|
||||
{ label: '隐私政策', value: '/pages/agreement/privacy' }
|
||||
{ label: '看过我', value: '/pages/interact/viewedMe' },
|
||||
{ label: '收藏我', value: '/pages/interact/favoritedMe' },
|
||||
{ label: '解锁我', value: '/pages/interact/unlockedMe' },
|
||||
{ label: '我看过的', value: '/pages/interact/myViewed' },
|
||||
{ label: '我收藏的', value: '/pages/interact/myFavorite' },
|
||||
{ label: '我解锁的', value: '/pages/interact/myUnlocked' },
|
||||
{ label: '联系我们', value: '/pages/butler/index' },
|
||||
{ label: '用户协议', value: '/pages/agreement/index?type=user' },
|
||||
{ label: '隐私政策', value: '/pages/agreement/index?type=privacy' }
|
||||
]
|
||||
|
||||
// 链接类型提示
|
||||
|
|
|
|||
|
|
@ -147,6 +147,29 @@
|
|||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 会员入口图设置 -->
|
||||
<el-form-item label="会员入口图">
|
||||
<div class="banner-upload">
|
||||
<el-upload
|
||||
class="banner-uploader"
|
||||
:action="uploadUrl"
|
||||
:headers="uploadHeaders"
|
||||
:show-file-list="false"
|
||||
:on-success="handleMemberEntryImageSuccess"
|
||||
:before-upload="beforeAvatarUpload"
|
||||
accept="image/*"
|
||||
>
|
||||
<img v-if="configForm.memberEntryImage" :src="getFullUrl(configForm.memberEntryImage)" class="banner-preview" />
|
||||
<el-icon v-else class="banner-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
<div class="avatar-tip">
|
||||
<p>建议尺寸:686x120像素</p>
|
||||
<p>支持格式:JPG、PNG</p>
|
||||
<p>小程序"我的"页面会员入口横幅图片</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="saveBasicConfig" :loading="saving">
|
||||
保存配置
|
||||
|
|
@ -213,7 +236,9 @@ import {
|
|||
getButlerQrcode,
|
||||
setButlerQrcode,
|
||||
getMemberIcons,
|
||||
setMemberIcons
|
||||
setMemberIcons,
|
||||
getMemberEntryImage,
|
||||
setMemberEntryImage
|
||||
} from '@/api/config'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
|
|
@ -229,7 +254,8 @@ const configForm = ref({
|
|||
butlerQrcode: '',
|
||||
unlimitedMemberIcon: '',
|
||||
sincereMemberIcon: '',
|
||||
familyMemberIcon: ''
|
||||
familyMemberIcon: '',
|
||||
memberEntryImage: ''
|
||||
})
|
||||
|
||||
const agreementForm = ref({
|
||||
|
|
@ -255,11 +281,12 @@ const getFullUrl = (url) => {
|
|||
|
||||
const loadConfig = async () => {
|
||||
try {
|
||||
const [avatarRes, bannerRes, qrcodeRes, memberIconsRes] = await Promise.all([
|
||||
const [avatarRes, bannerRes, qrcodeRes, memberIconsRes, memberEntryRes] = await Promise.all([
|
||||
getDefaultAvatar(),
|
||||
getSearchBanner(),
|
||||
getButlerQrcode(),
|
||||
getMemberIcons()
|
||||
getMemberIcons(),
|
||||
getMemberEntryImage()
|
||||
])
|
||||
if (avatarRes) {
|
||||
configForm.value.defaultAvatar = avatarRes.avatarUrl || ''
|
||||
|
|
@ -275,6 +302,9 @@ const loadConfig = async () => {
|
|||
configForm.value.sincereMemberIcon = memberIconsRes.sincereMemberIcon || ''
|
||||
configForm.value.familyMemberIcon = memberIconsRes.familyMemberIcon || ''
|
||||
}
|
||||
if (memberEntryRes) {
|
||||
configForm.value.memberEntryImage = memberEntryRes.imageUrl || ''
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载配置失败:', error)
|
||||
}
|
||||
|
|
@ -353,6 +383,15 @@ const handleFamilyMemberIconSuccess = (response) => {
|
|||
}
|
||||
}
|
||||
|
||||
const handleMemberEntryImageSuccess = (response) => {
|
||||
if (response.code === 0 && response.data) {
|
||||
configForm.value.memberEntryImage = response.data.url
|
||||
ElMessage.success('上传成功')
|
||||
} else {
|
||||
ElMessage.error(response.message || '上传失败')
|
||||
}
|
||||
}
|
||||
|
||||
const beforeAvatarUpload = (file) => {
|
||||
const isImage = file.type.startsWith('image/')
|
||||
const isLt2M = file.size / 1024 / 1024 < 2
|
||||
|
|
@ -381,6 +420,9 @@ const saveBasicConfig = async () => {
|
|||
if (configForm.value.butlerQrcode) {
|
||||
promises.push(setButlerQrcode(configForm.value.butlerQrcode))
|
||||
}
|
||||
if (configForm.value.memberEntryImage) {
|
||||
promises.push(setMemberEntryImage(configForm.value.memberEntryImage))
|
||||
}
|
||||
// 保存会员图标
|
||||
const memberIcons = {
|
||||
unlimitedMemberIcon: configForm.value.unlimitedMemberIcon || undefined,
|
||||
|
|
|
|||
|
|
@ -134,17 +134,8 @@ const handleEditMemberLevel = () => {
|
|||
// 确认修改会员等级
|
||||
const handleConfirmMemberLevel = async () => {
|
||||
try {
|
||||
const { memberLevel, memberExpireTime } = memberLevelForm.value
|
||||
// 等级2、3需要到期时间
|
||||
if (memberLevel > 1 && !memberExpireTime) {
|
||||
ElMessage.warning('请选择会员到期时间')
|
||||
return
|
||||
}
|
||||
await updateMemberLevel(
|
||||
userId.value,
|
||||
memberLevel,
|
||||
memberLevel > 1 ? memberExpireTime : undefined
|
||||
)
|
||||
const { memberLevel } = memberLevelForm.value
|
||||
await updateMemberLevel(userId.value, memberLevel, undefined)
|
||||
ElMessage.success('修改成功')
|
||||
memberLevelDialogVisible.value = false
|
||||
fetchUserDetail()
|
||||
|
|
@ -670,23 +661,6 @@ onMounted(() => {
|
|||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="memberLevelForm.memberLevel > 1"
|
||||
label="到期时间"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="memberLevelForm.memberExpireTime"
|
||||
type="date"
|
||||
placeholder="选择到期日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="memberLevelForm.memberLevel === 1">
|
||||
<el-text type="info">
|
||||
不限时会员无需设置到期时间
|
||||
</el-text>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="memberLevelDialogVisible = false">
|
||||
|
|
|
|||
|
|
@ -28,10 +28,9 @@
|
|||
v-if="imageUrl"
|
||||
class="popup-image"
|
||||
:src="imageUrl"
|
||||
mode="aspectFit"
|
||||
mode="widthFix"
|
||||
@click="handleImageClick"
|
||||
/>
|
||||
<view v-if="title" class="popup-title">{{ title }}</view>
|
||||
<button
|
||||
v-if="buttonText"
|
||||
class="popup-btn"
|
||||
|
|
@ -265,7 +264,6 @@ export default {
|
|||
|
||||
.popup-image {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
|
@ -305,6 +303,35 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
// 每日弹窗/会员广告样式 - 透明背景只显示图片
|
||||
.popup-daily,
|
||||
.popup-member {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
width: auto;
|
||||
max-width: 85%;
|
||||
|
||||
.popup-image {
|
||||
width: 600rpx;
|
||||
border-radius: 24rpx;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
top: -60rpx;
|
||||
right: 0;
|
||||
|
||||
text {
|
||||
color: #fff;
|
||||
font-size: 50rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.popup-btn {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 性别选择弹窗样式
|
||||
.popup-gender {
|
||||
.gender-options {
|
||||
|
|
|
|||
|
|
@ -300,11 +300,11 @@ export default {
|
|||
.tag {
|
||||
font-size: 22rpx;
|
||||
padding: 6rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
&.tag-realname {
|
||||
background: #e8f5e9;
|
||||
color: #4caf50;
|
||||
background: #3d4a4a;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.tag-member {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const ENV = {
|
|||
}
|
||||
|
||||
// 当前环境 - 开发时使用 development,打包时改为 production
|
||||
const CURRENT_ENV = 'production'
|
||||
const CURRENT_ENV = 'development'
|
||||
|
||||
// 导出配置
|
||||
export const config = {
|
||||
|
|
|
|||
|
|
@ -585,6 +585,12 @@
|
|||
onShow() {
|
||||
const configStore = useConfigStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// 从服务器刷新用户信息(同步后台修改的状态)
|
||||
if (userStore.isLoggedIn) {
|
||||
userStore.refreshFromServer()
|
||||
}
|
||||
|
||||
configStore.checkPopupDisplay({
|
||||
genderPreference: userStore.genderPreference,
|
||||
isProfileCompleted: userStore.isProfileCompleted,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
<view class="user-detail">
|
||||
<view class="user-name-row">
|
||||
<text class="user-nickname">{{ userInfo.nickname || '用户名' }}</text>
|
||||
<image v-if="userInfo.isMember && memberIconUrl" class="member-icon" :src="memberIconUrl" mode="aspectFit" />
|
||||
<text class="edit-icon">✎</text>
|
||||
</view>
|
||||
<text class="user-xiangqin-no">相亲编号:{{ userInfo.xiangQinNo || '未设置' }}</text>
|
||||
|
|
@ -87,12 +88,15 @@
|
|||
</view>
|
||||
|
||||
<!-- 会员公告横幅 -->
|
||||
<view class="vip-banner" @click="handleMember">
|
||||
<view class="banner-content">
|
||||
<text class="banner-title">会员权益升级公告</text>
|
||||
<text class="banner-desc">最新会员体系重磅上线</text>
|
||||
</view>
|
||||
<image src="/static/logo.png" mode="aspectFit" class="banner-icon" />
|
||||
<view class="vip-banner" :class="{ 'has-image': memberEntryImageUrl }" @click="handleMember">
|
||||
<image v-if="memberEntryImageUrl" :src="memberEntryImageUrl" mode="widthFix" class="banner-full-img" />
|
||||
<template v-else>
|
||||
<view class="banner-content">
|
||||
<text class="banner-title">会员权益升级公告</text>
|
||||
<text class="banner-desc">最新会员体系重磅上线</text>
|
||||
</view>
|
||||
<image src="/static/logo.png" mode="aspectFit" class="banner-icon" />
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 常用功能 -->
|
||||
|
|
@ -195,6 +199,18 @@ export default {
|
|||
isRealName: userStore.isRealName
|
||||
}))
|
||||
|
||||
// 会员图标URL
|
||||
const memberIconUrl = computed(() => {
|
||||
if (!userStore.isMember || !userStore.memberLevel) return ''
|
||||
const iconUrl = configStore.getMemberIcon(userStore.memberLevel)
|
||||
return iconUrl ? getFullImageUrl(iconUrl) : ''
|
||||
})
|
||||
|
||||
// 会员入口图URL
|
||||
const memberEntryImageUrl = computed(() => {
|
||||
return configStore.memberEntryImage ? getFullImageUrl(configStore.memberEntryImage) : ''
|
||||
})
|
||||
|
||||
// 加载互动统计
|
||||
const loadInteractCounts = async () => {
|
||||
if (!userStore.isLoggedIn) return
|
||||
|
|
@ -366,6 +382,8 @@ export default {
|
|||
userInfo,
|
||||
interactCounts,
|
||||
defaultAvatar,
|
||||
memberIconUrl,
|
||||
memberEntryImageUrl,
|
||||
avatarLoadError,
|
||||
onAvatarError,
|
||||
handleLogin,
|
||||
|
|
@ -488,6 +506,12 @@ export default {
|
|||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.member-icon {
|
||||
width: 100rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.edit-icon {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
|
|
@ -668,12 +692,27 @@ export default {
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
margin: 0 32rpx 32rpx;
|
||||
padding: 32rpx;
|
||||
background: linear-gradient(135deg, #4a3728 0%, #2d1f15 100%);
|
||||
border-radius: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
|
||||
&.has-image {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&:not(.has-image) {
|
||||
padding: 32rpx;
|
||||
background: linear-gradient(135deg, #4a3728 0%, #2d1f15 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.banner-full-img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
.banner-content {
|
||||
.banner-title {
|
||||
|
|
|
|||
|
|
@ -346,8 +346,8 @@
|
|||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 步骤4: 择偶要求 -->
|
||||
<view v-show="currentStep === 3" class="form-section requirement-section">
|
||||
<!-- 步骤5: 择偶要求 -->
|
||||
<view v-show="currentStep === 4" class="form-section requirement-section">
|
||||
<view class="section-title">择偶要求</view>
|
||||
<view class="section-tip">以下条件均为可选,帮助您更精准匹配</view>
|
||||
|
||||
|
|
@ -520,8 +520,8 @@
|
|||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 步骤5: 父母情况 -->
|
||||
<view v-show="currentStep === 4" class="form-section">
|
||||
<!-- 步骤4: 父母情况 -->
|
||||
<view v-show="currentStep === 3" class="form-section">
|
||||
<view class="section-title">父母情况</view>
|
||||
|
||||
<!-- 是否独居 -->
|
||||
|
|
@ -729,8 +729,8 @@ const steps = [
|
|||
{ label: '基础信息' },
|
||||
{ label: '详细信息' },
|
||||
{ label: '孩子介绍' },
|
||||
{ label: '择偶要求' },
|
||||
{ label: '父母情况' },
|
||||
{ label: '择偶要求' },
|
||||
{ label: '联系方式' }
|
||||
]
|
||||
|
||||
|
|
@ -1358,17 +1358,17 @@ const validateStep = (step) => {
|
|||
}
|
||||
return true
|
||||
|
||||
case 3: // 择偶要求
|
||||
// 意向城市至少选择1个
|
||||
if (!formData.requirement.city1Province || !formData.requirement.city1City) {
|
||||
uni.showToast({ title: '请至少选择一个意向城市', icon: 'none' })
|
||||
case 3: // 父母情况
|
||||
if (!formData.parentStatus) {
|
||||
uni.showToast({ title: '请选择父母情况', icon: 'none' })
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
case 4: // 父母情况
|
||||
if (!formData.parentStatus) {
|
||||
uni.showToast({ title: '请选择父母情况', icon: 'none' })
|
||||
case 4: // 择偶要求
|
||||
// 意向城市至少选择1个
|
||||
if (!formData.requirement.city1Province || !formData.requirement.city1City) {
|
||||
uni.showToast({ title: '请至少选择一个意向城市', icon: 'none' })
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export const useConfigStore = defineStore('config', {
|
|||
defaultAvatar: getDefaultAvatar() || '/static/logo.png',
|
||||
searchBanner: '',
|
||||
butlerQrcode: '', // 管家指导二维码
|
||||
memberEntryImage: '', // 会员入口图
|
||||
|
||||
// 会员图标配置
|
||||
memberIcons: {
|
||||
|
|
@ -104,6 +105,7 @@ export const useConfigStore = defineStore('config', {
|
|||
}
|
||||
this.searchBanner = config.searchBanner || ''
|
||||
this.butlerQrcode = config.butlerQrcode || ''
|
||||
this.memberEntryImage = config.memberEntryImage || ''
|
||||
|
||||
// 会员图标配置
|
||||
if (config.memberIcons) {
|
||||
|
|
@ -151,8 +153,8 @@ export const useConfigStore = defineStore('config', {
|
|||
}
|
||||
|
||||
// 会员广告
|
||||
if (!isMember && this.memberAdConfig && this.memberAdConfig.status === 1) {
|
||||
const displayMode = this.memberAdConfig.displayMode || 2
|
||||
if (!isMember && this.memberAdConfig && (this.memberAdConfig.status === 1 || this.memberAdConfig.Status === 1)) {
|
||||
const displayMode = this.memberAdConfig.displayMode || this.memberAdConfig.DisplayMode || 2
|
||||
|
||||
if (displayMode === 1) {
|
||||
this.showMemberAd = true
|
||||
|
|
@ -183,7 +185,7 @@ export const useConfigStore = defineStore('config', {
|
|||
const today = getTodayDateString()
|
||||
this.showMemberAd = false
|
||||
|
||||
const displayMode = this.memberAdConfig?.displayMode || 2
|
||||
const displayMode = this.memberAdConfig?.displayMode || this.memberAdConfig?.DisplayMode || 2
|
||||
|
||||
if (displayMode === 2) {
|
||||
this.memberAdClosedDate = today
|
||||
|
|
@ -192,6 +194,7 @@ export const useConfigStore = defineStore('config', {
|
|||
this.memberAdClosedForever = true
|
||||
setMemberAdClosedForever(true)
|
||||
}
|
||||
// displayMode === 1 时不保存任何状态,下次进入页面会重新显示
|
||||
},
|
||||
|
||||
reset() {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
getUserInfo, setUserInfo, removeUserInfo,
|
||||
getGenderPreference, setGenderPreference
|
||||
} from '../utils/storage.js'
|
||||
import { getMyProfile } from '../api/profile.js'
|
||||
|
||||
/**
|
||||
* 用户状态定义
|
||||
|
|
@ -191,6 +192,33 @@ export const useUserStore = defineStore('user', {
|
|||
setRealNameStatus(isRealName) {
|
||||
this.isRealName = isRealName
|
||||
this.updateUserInfo({ isRealName })
|
||||
},
|
||||
|
||||
/**
|
||||
* 从服务器刷新用户信息
|
||||
* 用于同步后台修改的用户状态(如会员等级变更)
|
||||
*/
|
||||
async refreshFromServer() {
|
||||
if (!this.token) return
|
||||
|
||||
try {
|
||||
const res = await getMyProfile()
|
||||
if (res && res.code === 0 && res.data) {
|
||||
const data = res.data
|
||||
this.updateUserInfo({
|
||||
userId: data.userId,
|
||||
nickname: data.nickname,
|
||||
avatar: data.avatar,
|
||||
xiangQinNo: data.xiangQinNo,
|
||||
isProfileCompleted: data.auditStatus === 1,
|
||||
isMember: data.isMember,
|
||||
memberLevel: data.memberLevel,
|
||||
isRealName: data.isRealName
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('刷新用户信息失败:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -250,6 +250,34 @@ public class AdminConfigController : ControllerBase
|
|||
var result = await _configService.SetMemberIconsAsync(request);
|
||||
return result ? ApiResponse.Success("设置成功") : ApiResponse.Error(40001, "设置失败");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取会员入口图
|
||||
/// </summary>
|
||||
[HttpGet("memberEntryImage")]
|
||||
public async Task<ApiResponse<MemberEntryImageResponse>> GetMemberEntryImage()
|
||||
{
|
||||
var imageUrl = await _configService.GetMemberEntryImageAsync();
|
||||
return ApiResponse<MemberEntryImageResponse>.Success(new MemberEntryImageResponse
|
||||
{
|
||||
ImageUrl = imageUrl
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置会员入口图
|
||||
/// </summary>
|
||||
[HttpPost("memberEntryImage")]
|
||||
public async Task<ApiResponse> SetMemberEntryImage([FromBody] SetMemberEntryImageRequest request)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(request.ImageUrl))
|
||||
{
|
||||
return ApiResponse.Error(40001, "图片URL不能为空");
|
||||
}
|
||||
|
||||
var result = await _configService.SetMemberEntryImageAsync(request.ImageUrl);
|
||||
return result ? ApiResponse.Success("设置成功") : ApiResponse.Error(40001, "设置失败");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -383,3 +411,25 @@ public class SetMemberIconRequest
|
|||
/// </summary>
|
||||
public string ImageUrl { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 会员入口图响应
|
||||
/// </summary>
|
||||
public class MemberEntryImageResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片URL
|
||||
/// </summary>
|
||||
public string? ImageUrl { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置会员入口图请求
|
||||
/// </summary>
|
||||
public class SetMemberEntryImageRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片URL
|
||||
/// </summary>
|
||||
public string ImageUrl { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,11 @@ public class AppConfigResponse
|
|||
/// 会员广告弹窗配置
|
||||
/// </summary>
|
||||
public PopupConfigResponse? MemberAdPopup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 会员入口图片URL(我的页面)
|
||||
/// </summary>
|
||||
public string? MemberEntryImage { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -101,4 +101,14 @@ public interface ISystemConfigService
|
|||
/// 设置所有会员图标
|
||||
/// </summary>
|
||||
Task<bool> SetMemberIconsAsync(MemberIconsDto icons);
|
||||
|
||||
/// <summary>
|
||||
/// 获取会员入口图URL
|
||||
/// </summary>
|
||||
Task<string?> GetMemberEntryImageAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 设置会员入口图URL
|
||||
/// </summary>
|
||||
Task<bool> SetMemberEntryImageAsync(string imageUrl);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -323,11 +323,7 @@ public class AdminAccountService : IAdminAccountService
|
|||
|
||||
private static string? MaskPhone(string? phone)
|
||||
{
|
||||
if (string.IsNullOrEmpty(phone) || phone.Length < 7)
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
return $"{phone[..3]}****{phone[^4..]}";
|
||||
return phone;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -244,11 +244,7 @@ public class AdminMemberService : IAdminMemberService
|
|||
/// </summary>
|
||||
private static string? MaskPhone(string? phone)
|
||||
{
|
||||
if (string.IsNullOrEmpty(phone) || phone.Length < 7)
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
return $"{phone[..3]}****{phone[^4..]}";
|
||||
return phone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -602,11 +602,7 @@ public class AdminOrderService : IAdminOrderService
|
|||
/// </summary>
|
||||
private static string? MaskPhone(string? phone)
|
||||
{
|
||||
if (string.IsNullOrEmpty(phone) || phone.Length < 7)
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
return $"{phone[..3]}****{phone[^4..]}";
|
||||
return phone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -346,11 +346,7 @@ public class AdminProfileAuditService : IAdminProfileAuditService
|
|||
|
||||
private static string? MaskPhone(string? phone)
|
||||
{
|
||||
if (string.IsNullOrEmpty(phone) || phone.Length < 7)
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
return $"{phone[..3]}****{phone[^4..]}";
|
||||
return phone;
|
||||
}
|
||||
|
||||
private static string GetGenderText(int gender)
|
||||
|
|
|
|||
|
|
@ -507,11 +507,7 @@ public class AdminReportService : IAdminReportService
|
|||
|
||||
private static string? MaskPhone(string? phone)
|
||||
{
|
||||
if (string.IsNullOrEmpty(phone) || phone.Length < 7)
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
return $"{phone[..3]}****{phone[^4..]}";
|
||||
return phone;
|
||||
}
|
||||
|
||||
private static string GetReportTypeText(int reportType)
|
||||
|
|
|
|||
|
|
@ -671,15 +671,11 @@ public class AdminUserService : IAdminUserService
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// 手机号脱敏
|
||||
/// 手机号(管理后台不脱敏)
|
||||
/// </summary>
|
||||
private static string? MaskPhone(string? phone)
|
||||
{
|
||||
if (string.IsNullOrEmpty(phone) || phone.Length < 7)
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
return $"{phone[..3]}****{phone[^4..]}";
|
||||
return phone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ public class ConfigService : IConfigService
|
|||
var memberIcons = await _systemConfigService.GetMemberIconsAsync();
|
||||
var dailyPopup = await GetPopupConfigAsync(1); // 每日弹窗
|
||||
var memberAdPopup = await GetPopupConfigAsync(3); // 会员广告弹窗
|
||||
var memberEntryImage = await _systemConfigService.GetMemberEntryImageAsync();
|
||||
|
||||
return new AppConfigResponse
|
||||
{
|
||||
|
|
@ -61,7 +62,8 @@ public class ConfigService : IConfigService
|
|||
ButlerQrcode = butlerQrcode,
|
||||
MemberIcons = memberIcons,
|
||||
DailyPopup = dailyPopup,
|
||||
MemberAdPopup = memberAdPopup
|
||||
MemberAdPopup = memberAdPopup,
|
||||
MemberEntryImage = memberEntryImage
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,29 +19,10 @@ public class OrderService : IOrderService
|
|||
private readonly IRepository<Order> _orderRepository;
|
||||
private readonly IRepository<User> _userRepository;
|
||||
private readonly IRepository<Member> _memberRepository;
|
||||
private readonly IRepository<MemberTierConfig> _tierConfigRepository;
|
||||
private readonly IWeChatService _weChatService;
|
||||
private readonly ILogger<OrderService> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// 会员等级价格配置(单位:元)
|
||||
/// </summary>
|
||||
private static readonly Dictionary<int, decimal> MemberPrices = new()
|
||||
{
|
||||
{ 1, 1299m }, // 不限时会员
|
||||
{ 2, 1999m }, // 诚意会员
|
||||
{ 3, 2999m } // 家庭版会员
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 会员等级名称
|
||||
/// </summary>
|
||||
private static readonly Dictionary<int, string> MemberLevelNames = new()
|
||||
{
|
||||
{ 1, "不限时会员" },
|
||||
{ 2, "诚意会员" },
|
||||
{ 3, "家庭版会员" }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 订单类型名称
|
||||
/// </summary>
|
||||
|
|
@ -71,12 +52,14 @@ public class OrderService : IOrderService
|
|||
IRepository<Order> orderRepository,
|
||||
IRepository<User> userRepository,
|
||||
IRepository<Member> memberRepository,
|
||||
IRepository<MemberTierConfig> tierConfigRepository,
|
||||
IWeChatService weChatService,
|
||||
ILogger<OrderService> logger)
|
||||
{
|
||||
_orderRepository = orderRepository;
|
||||
_userRepository = userRepository;
|
||||
_memberRepository = memberRepository;
|
||||
_tierConfigRepository = tierConfigRepository;
|
||||
_weChatService = weChatService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
|
@ -103,20 +86,28 @@ public class OrderService : IOrderService
|
|||
|
||||
if (request.OrderType == (int)OrderType.Membership)
|
||||
{
|
||||
// 会员订单
|
||||
if (!request.MemberLevel.HasValue || !MemberPrices.ContainsKey(request.MemberLevel.Value))
|
||||
// 会员订单 - 从数据库读取价格配置
|
||||
if (!request.MemberLevel.HasValue || request.MemberLevel < 1 || request.MemberLevel > 3)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.InvalidParameter, "无效的会员等级");
|
||||
}
|
||||
|
||||
// 获取会员等级配置
|
||||
var tierConfigs = await _tierConfigRepository.GetListAsync(t => t.Level == request.MemberLevel.Value && t.Status == 1);
|
||||
var tierConfig = tierConfigs.FirstOrDefault();
|
||||
if (tierConfig == null)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.InvalidParameter, "会员等级配置不存在");
|
||||
}
|
||||
|
||||
// 检查是否已是会员
|
||||
if (user.IsMember && user.MemberLevel >= request.MemberLevel.Value)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.MembershipRequired, "您已是该等级或更高等级会员");
|
||||
}
|
||||
|
||||
amount = MemberPrices[request.MemberLevel.Value];
|
||||
productName = MemberLevelNames[request.MemberLevel.Value];
|
||||
amount = tierConfig.Price;
|
||||
productName = tierConfig.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -63,6 +63,11 @@ public class SystemConfigService : ISystemConfigService
|
|||
/// </summary>
|
||||
public const string FamilyMemberIconKey = "family_member_icon";
|
||||
|
||||
/// <summary>
|
||||
/// 会员入口图配置键
|
||||
/// </summary>
|
||||
public const string MemberEntryImageKey = "member_entry_image";
|
||||
|
||||
public SystemConfigService(
|
||||
IRepository<SystemConfig> configRepository,
|
||||
ILogger<SystemConfigService> logger)
|
||||
|
|
@ -250,6 +255,18 @@ public class SystemConfigService : ISystemConfigService
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string?> GetMemberEntryImageAsync()
|
||||
{
|
||||
return await GetConfigValueAsync(MemberEntryImageKey);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> SetMemberEntryImageAsync(string imageUrl)
|
||||
{
|
||||
return await SetConfigValueAsync(MemberEntryImageKey, imageUrl, "会员入口图URL");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user