This commit is contained in:
yziiy
2025-12-03 18:59:18 +08:00
parent edd856475e
commit 0b1c5b39bd
180 changed files with 1336 additions and 2930 deletions

View File

@@ -234,7 +234,7 @@
} else {
uni.showToast({
title: "提交失败",
icon: 'error'
icon: 'none'
});
uni.hideLoading()
}
@@ -242,7 +242,7 @@
}).catch(error => {
uni.showToast({
title: "提交失败",
icon: 'error'
icon: 'none'
});
uni.hideLoading()
});

View File

@@ -1,6 +1,6 @@
<template>
<view class="view-page">
<navBar :style="{marginTop: `${statusBarHeight}${uni.getSystemInfoSync().platform === 'ios' ? 'px': 'dp'}`}"
<navBar :style="{paddingTop: `${statusBarHeight}${uni.getSystemInfoSync().platform === 'ios' ? 'px': 'dp'}`}"
:navTitle="'举报'" bgColor="#fff" :emitBack="true" @backEvent="back">
</navBar>
<view class="content">

View File

@@ -378,7 +378,7 @@
if (code) {
uni.showToast({
title: '绑定成功',
icon: 'success',
icon: 'none',
mask: true,
duration: 1000
});
@@ -387,7 +387,7 @@
} else {
uni.showToast({
title: msg,
icon: 'error',
icon: 'none',
mask: true,
duration: 1000
});
@@ -399,7 +399,7 @@
} else {
uni.showToast({
title: '请输入邀请码',
icon: 'error',
icon: 'none',
mask: true,
duration: 1000
});

View File

@@ -1,79 +0,0 @@
<template>
<view class="view-page" :style="{backgroundImage: `url('${ThemeData?.app_bg || baseBgUrl}')`}">
<navBar :style="{marginTop: `${statusBarHeight}${uni.getSystemInfoSync().platform === 'ios' ? 'px': 'dp'}`}"
:navTitle="'测试页面'">
</navBar>
<view class="content">
{{content}}
</view>
</view>
</template>
<script>
import navBar from '@/component/nav.vue';
import http from '@/until/http.js';
import baseBgUrl from '@/static/image/general/fy_bg.jpg';
export default {
components: {
navBar
},
data() {
return {
content: '测试一下',
statusBarHeight: 0,
ThemeData: {},
baseBgUrl
}
},
onLoad(options) {
const {
id
} = options
uni.setStorageSync('token', id)
http.get('/api/Guild/guild_list', {
page: 1,
limit: 10,
search_id: '',
token: uni.getStorageSync('token') || ''
}).then(response => {
this.content = `token:${id}+++++++++++++${JSON.stringify(response)}`
}).catch(error => {
this.content = `token:${id}+++++++++++++${JSON.stringify(response)}`
});
// uni.request({
// url: 'https://md.xscmmidi.site/api/Guild/guild_list',
// data:{
// page: 1,
// limit: 5,
// search_id: '',
// token: id || ''
// },
// method: 'GET',
// success: (res) => {
// this.content = `token:${id}+++++++++++++${JSON.stringify(res)}`
// },
// fail: (err) => {
// this.content = `token:${id}+++++++++++++${JSON.stringify(res)}`
// }
// });
// const {
// id
// } = options
// uni.setStorageSync('token', id)
// this.content = id
// if (uni.getStorageSync('token')) {
// this.getList()
// }
},
methods: {}
}
</script>
<style scoped>
.view-page {
min-height: 100vh;
font-family: Source Han Sans CN, Source Han Sans CN;
background-repeat: no-repeat;
background-size: 100% 100%;
}
</style>

View File

@@ -164,6 +164,9 @@
</view>
<view v-else>
</view>
<uni-popup ref="message" type="message">
<uni-popup-message :type="msgType" :message="messageText" :duration="2000"></uni-popup-message>
</uni-popup>
</view>
</template>
@@ -184,7 +187,9 @@
decorateDetail: null,
currentMenuIndex: 0,
payData: null,
isShow: true
isShow: true,
msgType:"success",
messageText:"操作成功"
}
},
onLoad(options) {
@@ -310,12 +315,9 @@
if (this.decorateDetail.tab.type !== 12) {
if (this.payData.price > this.decorateDetail.user_info.user_coin) {
// 余额不足
uni.showToast({
title: '余额不足',
icon: 'none',
mask: true,
duration: 500
});
this.messageText = "余额不足"
this.msgType = 'error'
this.$refs.message.open()
return
}
@@ -323,12 +325,9 @@
// 降身卡
if (this.payData.allPrice > this.decorateDetail.user_info.user_coin) {
// 余额不足
uni.showToast({
title: '余额不足',
icon: 'none',
mask: true,
duration: 500
});
this.messageText = "余额不足"
this.msgType = 'error'
this.$refs.message.open()
return
}
}
@@ -346,21 +345,15 @@
num: type !== 12 ? 0 : this.payData.number
}).then(response => {
if (response.code) {
uni.showToast({
title: '购买成功',
icon: 'success',
mask: true,
duration: 1000
});
this.messageText = "购买成功"
this.msgType = 'success'
this.$refs.message.open()
uni.hideLoading()
this.closePopup()
} else {
uni.showToast({
title: response.msg,
icon: 'none',
mask: true,
duration: 1000
});
this.messageText = response.msg
this.msgType = 'error'
this.$refs.message.open()
}
}).catch(error => {});

70
pages/union/agreement.vue Normal file
View File

@@ -0,0 +1,70 @@
<template>
<view class="view-page" :style="{backgroundImage: `url('${ThemeData?.app_bg || baseBgUrl}')`}">
<navBar :style="{marginTop: `${statusBarHeight}${uni.getSystemInfoSync().platform === 'ios' ? 'px': 'dp'}`}"
:navTitle="'公会协议'">
</navBar>
<view class="dec-view" v-if="detailData">
<web-view :src="detailData.agreement"></web-view>
</view>
</view>
</template>
<script>
import http from '@/until/http.js';
import navBar from '@/component/nav.vue';
import config from '@/until/config.js';
export default {
components: {
navBar
},
data() {
return {
baseBgUrl: config.new_unionUrl || '',
unionBgUrl: config.unicon_url || '',
statusBarHeight: 0,
ThemeData: null,
detailData:null
}
},
onLoad(options) {
const {
h
} = options
this.statusBarHeight = h
uni.setStorageSync('BarHeight', h)
if(uni.getStorageSync('token'))this.getInfo()
},
methods:{
async getInfo() {
http.get('/api/Guild/my_guild', {
token: uni.getStorageSync('token') || ''
}).then(response => {
const {
data,
code
} = response
// console.log(data)
this.detailData = code ? data : false
})
}
}
}
</script>
<style lang="scss" scoped>
.view-page {
min-height: 100vh;
font-family: Source Han Sans CN, Source Han Sans CN;
background-repeat: no-repeat;
background-size: 100% 100%;
.dec-view {
min-height: calc(99vh - 160rpx);
position: relative;
border-radius: 16rpx;
margin: 24rpx;
// background-color: white;
}
}
</style>

View File

@@ -1,681 +0,0 @@
<template>
<view class="view-page" :style="{backgroundImage: `url('${ThemeData?.app_bg || baseBgUrl}')`}">
<headerHeight />
<navBar :navTitle="'公会详情'">
<template #rightView>
<view class="icon-right flex-line" @click="exit"
v-if="detailData && detailData.is_join && detailData.is_leader === 0">
<img :src="logout" alt="" />
</view>
</template>
</navBar>
<view class="content" v-if="detailData">
<view class="union-info">
<view class="left-view">
<view class="head-portrait">
<img :src="detailData.cover || logo" alt="" />
</view>
<view class="info-detail">
<view class="union-title">
{{ detailData.guild_name }}
</view>
<view class="union-id">
ID:{{ detailData.guild_special_id }}
</view>
<view class="union-date">
{{ detailData.createtime }}
</view>
</view>
</view>
<view class="like-box">
<uni-icons type="heart" color="#fff" size="20"></uni-icons>
<view class="ml-6" style="display: inline-flex;align-items: baseline;">
{{ detailData.total_transaction }}
</view>
</view>
</view>
<!-- 公会按钮 是会长可以看公会成员 不是不能看 -->
<view class="icon-wrap">
<img class="icon-box" @click.stop="viewDetails(0)" src="@/static/image/union/ghfj.png" alt="" />
<img class="icon-box" @click.stop="viewDetails(1)" src="@/static/image/union/ghcy.png" alt="" />
<img class="icon-box" v-if="detailData.is_leader" @click.stop="viewDetails(2)"
src="@/static/image/union/ghbt.png" alt="" />
<img class="icon-box" v-if="detailData.is_join" @click.stop="viewDetails(3)"
src="@/static/image/union/qlsz.png" alt="" />
</view>
<!-- 公会会长信息 -->
<view class="union-user">
<view class="user-title">
公会会长
</view>
<view class="user-info" @click="jumpHomePage(detailData)">
<view class="flex-line">
<view class="head-portrait">
<img :src="detailData.user_data.avatar" alt="" />
</view>
<view class="info-view">
<view class="">
{{ detailData.user_data.nickname }}
</view>
<view class="iconTag-view"
v-if="detailData.user_data.icon || detailData.user_data.icon.length">
<view class="icon-tag" v-for="icon in detailData.user_data.icon" :key="icon">
<img :src="icon" alt="" />
</view>
</view>
</view>
</view>
<view class="">
<uni-icons type="right" size="20"></uni-icons>
</view>
</view>
</view>
<!-- 公会介绍 -->
<view class="union-dec">
<view class="user-title">
公会介绍
</view>
<view class="user-dec">
{{ detailData.intro || '暂无数据' }}
</view>
</view>
<view class="footer" v-if="!detailData.is_join">
<view class="confirm-button" @click="applyToJoin">
<view class="button">
{{ buttonText }}
</view>
</view>
</view>
<view class="footer" v-if="detailData.is_leader">
<view class="confirm-button" @click="dissolveUnion">
<view class="button">
{{ buttonText }}
</view>
</view>
</view>
</view>
<uni-popup ref="message" type="message">
<uni-popup-message :type="msgType" :message="messageText" :duration="2000"></uni-popup-message>
</uni-popup>
<uni-popup ref="popup" type="center">
<view class="popup_view">
<view class="color-3 font-32 popup_title">
温馨提示
</view>
<view class="color-3 font-24 messageContent">
{{ messageContent }}
</view>
<view class="popup_button flex-line">
<view class="close_button flex-line" @click="closePopup">
取消
</view>
<view class="confirm-button flex-line" @click="confirmPopup">
确认
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import headerHeight from '@/component/headerHeight.vue';
import config from '@/until/config.js';
import navBar from '@/component/nav.vue';
import http from '@/until/http.js';
import logout from '@/static/image/union/logout.png'
import logo from '@/static/image/logo.png';
export default {
components: {
headerHeight,
navBar
},
data() {
return {
detailData: null,
baseBgUrl:config.PRIMARY_BGURL,
logo,
logout,
buttonStatus: null,
buttonText: '申请加入公会',
// 弹出窗状态 null 不展示 0 申请退出 1申请加入公会 2 付费退出 3实名认证
popupStstus: null,
messageText: "",
messageContent: '',
msgType: "success",
ThemeData: null
}
},
onLoad(options) {
const {
id
} = options
if (id) {
this.getDetail(id)
this.getUserInfo()
}
if (uni.getStorageSync('Theme_Data')) {
this.ThemeData = JSON.parse(uni.getStorageSync('Theme_Data'))
}
},
onShow() {
this.getUserInfo()
},
methods: {
// 获取用户信息 拿实名信息
async getUserInfo() {
http.get('/api/User/get_user_info', {
token: uni.getStorageSync('token') || ''
}).then(response => {
const {
data,
code
} = response
this.isAuth = code ? data.auth : 0
})
},
// 获取公会信息
async getDetail(Id) {
uni.showLoading({
mask: true,
title: '加载中'
})
http.get('/api/Guild/guild_detail', {
id: Id,
token: uni.getStorageSync('token') || ''
}).then(response => {
uni.hideLoading()
const {
data,
code
} = response
this.detailData = code ? data : null
if (data) {
this.buttonText = !data.is_leader ? data.is_join ? '退出公会' : '申请加入公会' : '解散公会'
this.buttonStatus = !data.is_leader ? data.is_join ? 0 : 1 : 2
}
})
},
// 点击房间
viewDetails(index) {
// 0 公会房间 1 公会成员 2公会补贴 3 群聊设置
if (index) {
if (index === 1) {
// 公会成员
uni.navigateTo({
url: `/pages/union/unionMembers?id=${this.detailData.id || null}&leader=${this.detailData.is_leader || 0}`
});
} else if (index === 2) {
// 公会补贴
uni.navigateTo({
url: `/pages/union/subsidy?id=${this.detailData.id || null}&leader=${this.detailData.is_leader || 0}`
});
} else {
// 群聊抛出
const platform = uni.getSystemInfoSync().platform;
const ParmData = {
group_id: this.detailData.group_id,
cover: this.detailData.cover,
guild_name: this.detailData.guild_name
}
if (platform === 'ios') {
// 通过 messageHandlers 调用 iOS 原生方法
window.webkit.messageHandlers.nativeHandler.postMessage({
'action': 'enterGroupChat',
'data': ParmData
});
} else if (platform === 'android') {
// 调用 Android 原生方法
window.Android.enterGroupChat(this.detailData.group_id, this.detailData.cover, this.detailData
.guild_name);
}
}
} else {
// 房间
uni.navigateTo({
url: `/pages/union/roomAndflow?id=${this.detailData.id || null}&leader=${this.detailData.is_leader || 0}`
});
}
},
//申请加入公会
applyToJoin() {
if (this.buttonStatus === 1) {
if (this.isAuth) {
this.popupStstus = 1
this.messageContent = "是否选择加入当前公会"
this.$refs.popup.open('center')
} else {
this.popupStstus = 3
this.messageContent = "当前尚未实名认证,是否跳转到实名认证页面?"
this.$refs.popup.open('center')
}
}
},
// 申请加入公会
async joinUnionize() {
http.post('/api/Guild/join_guild', {
guild_id: this.detailData.id,
token: uni.getStorageSync('token') || ''
}).then(response => {
const {
data,
code,
msg
} = response
if (code) {
this.messageText = `加入成功`
this.$refs.message.open()
this.msgType = 'success'
this.getDetail(this.detailData.id)
} else {
this.messageText = msg
this.msgType = 'error'
this.$refs.message.open()
}
this.closePopup()
})
},
// 退出公会
exit() {
uni.showActionSheet({
itemList: ["申请退出", "付费退出"],
success: (res) => {
if (res.tapIndex === 0) {
this.applyToWithdraw();
} else if (res.tapIndex === 1) {
this.paidWithdrawal();
}
},
fail: (err) => {
console.error("用户取消选择:", err);
},
});
},
// 申请退出
applyToWithdraw() {
this.popupStstus = 0
this.messageContent = "亲爱的会员会长将在3天内审核若超时未通过您将自动退出并可加入其他公会若通过则30天内无法加入其他公会是否还需要申请退出"
this.$refs.popup.open('center')
},
// 付费退出
paidWithdrawal() {
this.popupStstus = 2
this.messageContent = `亲爱的会员,支付${this.detailData.quit_guild_gold || 0}金币,即可及时退出公会!是否需要付费退出?`
this.$refs.popup.open('center')
},
// 解散公会
dissolveUnion() {
this.popupStstus = 4
this.messageContent = `亲爱的会长,您当前操作将解散公会,是否解散?`
this.$refs.popup.open('center')
},
closePopup() {
this.popupStstus = null
this.messageContent = ""
this.$refs.popup.close()
},
confirmPopup() {
if (this.popupStstus !== null) {
if (this.popupStstus === 0) {
this.exitUnionize(1)
} else if (this.popupStstus === 1) {
this.joinUnionize()
} else if (this.popupStstus === 2) {
// 付费退出
this.exitUnionize(2)
} else if (this.popupStstus === 3) {
// 实名认证页面
this.authConfirm()
} else if (this.popupStstus === 4) {
// 解散公会
if (this.detailData.is_leader) {
this.unionDissolve()
}
}
}
},
authConfirm() {
// 去实名认证页面
const platform = uni.getSystemInfoSync().platform;
if (platform === 'ios') {
window.webkit.messageHandlers.nativeHandler.postMessage({
'action': 'enterAuthent'
});
} else if (platform === 'android') {
window.Android.enterAuthent();
}
this.closePopup()
},
// 跳转公会长个人页面
jumpHomePage(data) {
const platform = uni.getSystemInfoSync().platform;
if (platform === 'ios') {
window.webkit.messageHandlers.nativeHandler.postMessage({
'action': 'jumpWebPage',
'data': {
userId: data.user_id
}
});
} else if (platform === 'android') {
window.Android.jumpWebPage(data.user_id);
}
},
// 会长解散公会
async unionDissolve() {
http.post('/api/Guild/diss_guild', {
guild_id: this.detailData.id,
token: uni.getStorageSync('token') || ''
}).then(response => {
const {
data,
code,
msg
} = response
if (code === 1) {
this.msgType = 'success'
this.messageText = `操作成功,将返回上一页!`
this.$refs.message.open()
uni.$emit('refreshList');
uni.navigateBack()
} else {
this.messageText = msg
this.msgType = 'error'
this.$refs.message.open()
}
this.closePopup()
})
},
// 申请退出公会接口
async exitUnionize(type) {
http.post('/api/Guild/quit_guild', {
guild_id: this.detailData.id,
type: type,
token: uni.getStorageSync('token') || ''
}).then(response => {
const {
data,
code,
msg
} = response
if (code === 1) {
this.msgType = 'success'
this.messageText = `${type === 1 ? '退出申请已提交,请等待审核' : '付费退出成功'}`
this.$refs.message.open()
this.getDetail(this.detailData.id)
} else {
this.messageText = msg
this.msgType = 'error'
this.$refs.message.open()
}
this.closePopup()
})
}
}
}
</script>
<style lang="scss" scoped>
.view-page {
// padding: 32rpx;
display: flex;
flex-direction: column;
background-image: url('@/static/image/help/bg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
min-height: 100vh;
.content {
padding: 0 32rpx;
flex: 1;
/* 关键:撑满剩余空间 */
overflow: auto;
/* 允许内容滚动 */
}
.icon-right {
width: 56rpx;
height: 56rpx;
img {
width: 100%;
height: 100%;
}
}
.popup_view {
width: 550rpx;
// height: 40vh;
background-color: #fff;
border-radius: 32rpx;
padding: 32rpx;
.popup_title {
text-align: center;
}
.messageContent {
margin: 24rpx 0;
}
.popup_button {
margin-top: 24rpx;
width: 100%;
justify-content: space-around;
.close_button,
.confirm-button {
width: 200rpx;
height: 84rpx;
background: #F3F3F3;
border-radius: 106rpx;
color: #999999;
justify-content: center;
}
.confirm-button {
background: var(--primary-color);
color: var(--font-button-color);
}
}
}
.footer {
// background: #f0f0f0;
padding: 20rpx;
text-align: center;
/* 适配iPhoneX等刘海屏 */
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
}
/* 确保容器占满屏幕 */
.union-info {
width: 100%;
display: inline-flex;
align-items: center;
flex-wrap: nowrap;
justify-content: space-between;
flex-direction: row;
/* 头像 */
.head-portrait {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
// background-color: aquamarine;
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.left-view {
display: inline-flex;
align-items: center;
flex-wrap: nowrap;
justify-content: space-between;
flex-direction: row;
.info-detail {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
margin-left: 24rpx;
.union-title {
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.union-id {
font-size: 28rpx;
color: #666666;
}
.union-date {
font-size: 24rpx;
color: #999999;
}
}
}
.like-box {
display: inline-flex;
align-items: flex-end;
flex-wrap: nowrap;
flex-direction: row;
padding: 6rpx 24rpx;
border-radius: 35rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
background: var(--primary-color);
color: var(--font-button-color);
margin: 8rpx 0;
}
}
.icon-wrap {
display: flex;
flex-wrap: wrap;
gap: 25px;
margin: 24rpx 0;
.icon-box {
width: 48%;
height: 30%;
flex: 1;
max-width: calc(50% - 12.5px);
border-radius: 15px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
}
.union-user,
.union-dec {
padding: 24rpx;
height: 220rpx;
background: #fff;
border-radius: 22rpx;
margin-bottom: 24rpx;
.user-title {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 32rpx;
color: #333333;
margin-bottom: 24rpx;
}
.user-info {
display: inline-flex;
align-items: center;
flex-wrap: nowrap;
justify-content: space-between;
flex-direction: row;
width: 100%;
/* 头像 */
.head-portrait {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
background-color: aquamarine;
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.info-view {
margin-left: 24rpx;
.iconTag-view {
display: inline-flex;
align-items: center;
flex-wrap: nowrap;
justify-content: space-between;
flex-direction: row;
padding: 12rpx 0;
.icon-tag {
width: 148rpx;
height: 34rpx;
img {
width: 100%;
height: 100%;
}
}
}
}
}
}
.union-dec {
min-height: 220rpx;
.user-dec {
text-indent: 2em;
font-weight: 400;
font-size: 28rpx;
color: #333333;
}
}
.confirm-button {
padding: 0 50rpx;
.button {
display: block;
width: 100%;
height: 84rpx;
border-radius: 106rpx;
line-height: 84rpx;
background: var(--primary-color);
color: var(--font-button-color);
text-align: center;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

530
pages/union/list.vue Normal file
View File

@@ -0,0 +1,530 @@
<template>
<view class="view-page" :style="{backgroundImage: `url('${ThemeData?.app_bg || baseBgUrl}')`}">
<navBar :style="{marginTop: `${statusBarHeight}${uni.getSystemInfoSync().platform === 'ios' ? 'px': 'dp'}`}"
:navTitle="'公会中心'">
<template #rightView>
<view class="icon-right flex-line" @click="exit" v-if="isHasUnicon && !isLeader">
<img :src="logout" alt="" />
</view>
</template>
</navBar>
<view class="content">
<view class="flex-input">
<uni-easyinput prefixIcon="search" clearSize="18" v-model="searchValue"
placeholder="请输入公会ID/昵称">
</uni-easyinput>
<view class="search-button" @click="search">
搜索
</view>
</view>
<view class="hotspot-view">
<view class="hotspot-box" v-for="data in listData" :key="data.id">
<view class="flex-line">
<view class="head-portrait">
<img :src="data.cover || logo" alt="" />
</view>
<view class="info-box ml-20">
<view class="flex-line">
<span class="truncate">{{data.guild_name}}</span><span
class="id-title">ID:{{data.guild_special_id}}</span>
<img @click.stop="copyData(data.guild_special_id)" class="icon-box"
src="@/static/image/union/copy.png" alt="" />
</view>
<view class="subhead-title truncate">
{{data.intro}}
</view>
<view class="chairman">
<view class="chairman-portrait">
<img :src="data.user_avatar" alt="暂无头像" />
</view>
<view class="chairman-name">
{{data.user_name}}
</view>
</view>
</view>
</view>
<view class="right-button">
<view class="apply-button" @click="applyUnion(data)">
申请
</view>
<view class="online-view">
<view v-show="data.guild_user_list.length">
<view class="avatars-container">
<view class="avatar" v-for="ele in data.guild_user_list.slice(0,3)" :key="ele.id">
<img :src="ele.avatar" alt="" />
</view>
</view>
</view>
<view class="online-people">
{{data.num}}
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 弹窗 -->
<uni-popup ref="message" type="message">
<uni-popup-message :type="msgType" :message="messageText" :duration="2000"></uni-popup-message>
</uni-popup>
<uni-popup ref="popup" type="center">
<view class="popup_view">
<view class="color-3 font-32 popup_title">
温馨提示
</view>
<view class="color-3 font-24 messageContent">
{{ messageContent }}
</view>
<view class="popup_button flex-line">
<view class="close_button flex-line" @click="closePopup">
取消
</view>
<view class="confirm-button flex-line" @click="confirmPopup">
确认
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import navBar from '@/component/nav.vue';
import http from '@/until/http.js';
import logo from '@/static/image/logo.png';
import config from '@/until/config.js';
import logout from '@/static/image/union/logout.png'
export default {
components: {
navBar
},
data() {
return {
searchValue: '',
noUnionImage: config.not_unionUrl,
baseBgUrl: config.new_unionUrl,
unionBgUrl: config.unicon_url,
logo,
logout,
loading: false,
noMore: false,
isMerber: null,
listData: [],
UnionByUser: null,
statusBarHeight: 0,
ThemeData: null,
// 是否實名
isAuth: false,
// 是否为公会长,
isLeader: false,
// 是否有公会
isHasUnicon: false,
messageContent: '',
popupStstus: 0,
messageText: "",
msgType: "success",
detailData:null
}
},
onLoad(options) {
if (uni.getStorageSync('token')) {
this.getUserInfo()
} else {
uni.navigateBack()
}
if (uni.getStorageSync('BarHeight')) {
this.statusBarHeight = uni.getStorageSync('BarHeight')
}
if (uni.getStorageSync('Theme_Data')) {
this.ThemeData = JSON.parse(uni.getStorageSync('Theme_Data'))
}
},
methods: {
// 获取用户信息 拿实名信息
async getUserInfo() {
http.get('/api/User/get_user_info', {
token: uni.getStorageSync('token') || ''
}).then(response => {
const {
data,
code
} = response
this.isAuth = code ? data.auth : 0
})
},
async getUnionList(name) {
this.loading = true
http.get('/api/Guild/guild_list', {
page: 1,
limit: 1000,
search_id: name,
token: uni.getStorageSync('token') || ''
}).then(response => {
const {
data,
code
} = response
if (code) {
this.loading = false
this.listData = data.list || []
}
}).catch(error => {
this.loading = false
});
},
search() {
if (this.searchValue) {
// 搜索
this.getUnionList(this.searchValue)
}
},
// 申請加入工會
applyUnion(data) {
if (this.isAuth) {
this.detailData = data
this.popupStstus = 1
this.messageContent = "是否选择加入当前公会"
this.$refs.popup.open('center')
} else {
this.popupStstus = 3
this.messageContent = "当前尚未实名认证,是否跳转到实名认证页面?"
this.$refs.popup.open('center')
}
},
closePopup() {
this.popupStstus = null
this.detailData = null
this.messageContent = ""
this.$refs.popup.close()
},
confirmPopup() {
if (this.popupStstus !== null) {
if (this.popupStstus === 1) {
this.joinUnionize()
} else if (this.popupStstus === 3) {
// 实名认证页面
this.authConfirm()
}
}
},
authConfirm() {
// 去实名认证页面
const platform = uni.getSystemInfoSync().platform;
if (platform === 'ios') {
window.webkit.messageHandlers.nativeHandler.postMessage({
'action': 'enterAuthent'
});
} else if (platform === 'android') {
window.Android.enterAuthent();
}
this.closePopup()
},
// 申请加入公会
async joinUnionize() {
http.post('/api/Guild/join_guild', {
guild_id: this.detailData.id,
token: uni.getStorageSync('token') || ''
}).then(response => {
const {
data,
code,
msg
} = response
if (code) {
this.messageText = `加入成功`
this.$refs.message.open()
this.msgType = 'success'
uni.$emit('refreshList');
uni.navigateBack()
} else {
this.messageText = msg
this.msgType = 'error'
this.$refs.message.open()
}
this.closePopup()
})
}
}
}
</script>
<style lang="scss" scoped>
.view-page {
// padding: 32rpx;
// min-height: 100vh;
min-height: 100vh;
font-family: Source Han Sans CN, Source Han Sans CN;
// background-image: url('@/static/image/help/bg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
.popup_view {
width: 550rpx;
// height: 40vh;
background-color: #fff;
border-radius: 32rpx;
padding: 32rpx;
.popup_title {
text-align: center;
}
.messageContent {
margin: 24rpx 0;
}
.popup_button {
margin-top: 24rpx;
width: 100%;
justify-content: space-around;
.close_button,
.confirm-button {
width: 200rpx;
height: 84rpx;
background: #F3F3F3;
border-radius: 106rpx;
color: #999999;
justify-content: center;
}
.confirm-button {
background: var(--primary-color);
color: var(--font-button-color);
}
}
}
.content {
padding: 0 32rpx;
}
// /* 搜索框 */
.flex-input {
width: 100%;
display: inline-flex;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
.search-button {
padding: 0 0 0 20rpx;
}
}
/* 热门公会 */
.hotspot-view {
margin-top: 28rpx;
.hotspot-box {
width: calc(100% - 48rpx);
padding: 24rpx;
position: relative;
// min-height: calc(268rpx - 48rpx);
background: #FFFFFF;
border-radius: 20rpx;
margin-bottom: 24rpx;
/* */
display: inline-flex;
align-items: center;
flex-wrap: nowrap;
justify-content: space-between;
flex-direction: row;
/* 头像 */
.head-portrait {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
/* 中间信息 */
.info-box {
padding: 0 24rpx;
// max-width: 40%;
width: 55%;
.icon-box {
width: 20rpx;
height: 20rpx;
margin-left: 5rpx;
}
/* 会长样式 */
.chairman {
min-width: 106rpx;
height: 36rpx;
padding: 0 12rpx;
color: #fff;
font-size: 24rpx;
text-align: right;
background: var(--subss-color);
border-radius: 116rpx 116rpx 116rpx 116rpx;
border: 2rpx solid var(--subss-color);
position: relative;
left: 10rpx;
margin: 32rpx 0;
display: inline-flex;
.truncate-three {
text-align: left;
}
.chairman-portrait {
width: 50rpx;
height: 50rpx;
border-radius: 50%;
border: 2rpx solid #FFFFFF;
position: absolute;
top: -10rpx;
left: -20rpx;
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.chairman-name {
margin-left: 0.9rem;
}
}
.id-title {
font-size: 24rpx;
color: #666666;
margin-left: 24rpx;
}
.subhead-title {
display: block;
font-weight: 400;
font-size: 24rpx;
color: #666666;
margin: 8rpx 0;
}
.like-box {
display: inline-flex;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
padding: 6rpx 24rpx;
background: #2AFEC0;
border-radius: 35rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 28rpx;
color: #333333;
margin: 8rpx 0;
}
}
/* 右边按钮 */
.right-button {
text-align: right;
position: absolute;
right: 30rpx;
bottom: 50rpx;
.apply-button {
display: inline-block;
background: var(--primary-color);
font-size: var(--font-button-size);
color: var(--font-button-color);
border-radius: 68rpx;
text-align: center;
padding: 4rpx 30rpx;
}
.online-view {
.avatar {
width: 44rpx;
height: 44rpx;
border-radius: 50%;
position: absolute;
border: 2px solid white;
/* 白色边框 */
background-size: cover;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
transition: all 0.4s ease;
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
/* 头像位置 */
.avatar:nth-child(1) {
left: calc(50% - 60rpx);
z-index: 3;
}
.avatar:nth-child(2) {
left: calc(50% - 35rpx);
z-index: 2;
}
.avatar:nth-child(3) {
left: calc(50% - 10rpx);
z-index: 1;
}
/* 悬停效果 */
.avatar:hover {
transform: translateY(-10px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.25);
z-index: 10;
}
// display: inline-block;
margin-top: 24rpx;
padding: 12rpx 8rpx;
text-align: right;
width: 160rpx;
height: 44rpx;
line-height: 44rpx;
// background: #333333;
border-radius: 92rpx 92rpx 92rpx 92rpx;
position: relative;
.avatars-container {
position: absolute;
top: 10rpx;
left: 40%;
}
.online-people {
color: rgba(0, 0, 0, 0.5);
font-size: 24rpx;
text-align: left;
display: inline-block;
/* width: 6ch; */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
word-break: keep-all;
}
}
}
}
}
}
</style>

View File

@@ -1,235 +0,0 @@
<template>
<view class="view-page" :style="{backgroundImage : `url('${ThemeData?.app_bg || $config.PRIMARY_BGURL}')`}">
<headerHeight />
<navBar :navTitle="`${ leaderStatus ? '公会房间及流水' : '公会房间'}`">
<template #rightView>
</template>
</navBar>
<view class="content_view">
<view>
<uni-datetime-picker type="range" style="background-color: #f8f8f8;" start-placeholder="开始时间" :end="currentDate" end-placeholder="结束时间"
v-model="dateSearch" rangeSeparator="至" @change="changeDate" />
</view>
<view class="header-view" v-if="flowDetail && leaderStatus">
<view class="flex-line flow-view w-fill flex-spaceB">
<view class="flowTitle color-3">
总流水
</view>
</view>
<view class="flowNumber">
{{flowDetail.total_transaction}}
</view>
</view>
<view class="room-list flex-line" v-if="flowList && flowList.length">
<view class="room-line flex-line flex-spaceB" v-for="data in flowList" :key="data.room_id" @click="jumpRoomPage(data)">
<view class="flex-line">
<view class="head-portrait">
<img :src="data.room_cover || logo" alt="" />
</view>
<view class="ml-20">
<view class="color-3 font-32 font-w500">
{{data.room_name}}
</view>
<view class="color-6 font-24">
ID:{{data.room_number}}
</view>
</view>
</view>
<view class="flex-line" v-if="leaderStatus">
<view class="flowIcon">
<img src="@/static/image/union/flowIcon.png" alt="" />
</view>
<view class="ml-20">
{{data.total_price || 0}}
</view>
</view>
</view>
</view>
<view class="mt-24">
<uni-load-more :status="loading ? 'loading' : noMore ? 'noMore' : 'more'" />
</view>
</view>
</view>
</template>
<script>
import headerHeight from '@/component/headerHeight.vue';
import navBar from '@/component/nav.vue';
import http from '@/until/http.js';
import logo from '@/static/image/logo.png'
export default {
components: {
headerHeight,
navBar
},
data() {
return {
dateSearch: [new Date(),new Date()],
currentDate: +new Date(),
logo,
loading: false,
noMore: false,
detailData: null,
pageConfig: {
pageSize: 20,
currentPage: 1,
total: 0
},
searchParams: {
guild_id: 0,
start_time:new Date(),
end_time: new Date(),
token: uni.getStorageSync('token') || '',
page: 1,
page_size: 20
},
leaderStatus: null,
flowDetail: null,
flowList:[],
ThemeData:null
}
},
onLoad(options) {
const {
id,
leader
} = options
this.leaderStatus = +leader
this.searchParams.start_time = this.formatDate(new Date())
this.searchParams.end_time = this.formatDate(new Date())
this.searchParams.guild_id = id
if (id) this.getFlow()
if (uni.getStorageSync('Theme_Data')) {
this.ThemeData = JSON.parse(uni.getStorageSync('Theme_Data'))
}
},
onReachBottom() {
if (!this.loading && !this.noMore) {
this.getFlow()
}
},
methods: {
formatDate(timestamp) {
const date = new Date(timestamp);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始需+1
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
},
// 获取流水
async getFlow() {
const {
code,
data
} = await http.get('/api/Guild/guild_flow', {
...this.searchParams,
page: this.pageConfig.currentPage,
page_size: this.pageConfig.pageSize,
})
if(code) {
this.flowDetail = data
this.pageConfig.total = data.count
this.loading = false
const newData = data.list || []
if (newData.length === 0) {
this.noMore = true
return
}
this.flowList = [...this.flowList, ...newData]
this.pageConfig.currentPage++
if (this.flowList.length === this.pageConfig.total) {
this.noMore = true
return
}
// console.log(this.flowList.length === this.pageConfig.total)
}
},
jumpRoomPage(data){
const platform = uni.getSystemInfoSync().platform;
if (platform === 'ios') {
window.webkit.messageHandlers.nativeHandler.postMessage({
'action': 'jumpRoomPage',
'data': {
room_id: data.room_id
}
});
} else if (platform === 'android') {
window.Android.jumpRoomPage(data.room_id);
}
},
// 日期范围
changeDate(date) {
this.searchParams.start_time = date.length ? date[0] : ''
this.searchParams.end_time = date.length ? date[1] : ''
this.getFlow()
}
}
}
</script>
<style scoped lang="scss">
.view-page {
// padding: 24rpx 32rpx;
min-height: 100vh;
font-family: Source Han Sans CN, Source Han Sans CN;
background-image: url('@/static/image/help/bg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
.content_view {
padding: 0 24rpx;
}
.header-view {
padding: 24rpx;
margin-top: 24rpx;
background-image: url('/static/image/union/flowbg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
height: 152rpx;
.flow-view {
font-weight: 400;
font-size: 24rpx;
}
.flowNumber {
font-weight: 500;
font-size: 40rpx;
color: #333;
margin-top: 24rpx;
}
}
.room-list {
flex-wrap: wrap;
width: 100%;
.room-line {
width: 100%;
// background-color: #004D3C;
margin-top: 24rpx;
padding:24rpx;
border-radius: 10rpx;
background-color: #fff;
.flowIcon {
width: 48rpx;
height: 48rpx;
}
.head-portrait {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
img {
border-radius: 50%;
}
}
}
}
}
</style>

View File

@@ -177,7 +177,7 @@
} else {
uni.showToast({
title: "提交失败",
icon: 'error'
icon: 'none'
});
uni.hideLoading()
}

View File

@@ -1,121 +0,0 @@
<template>
<view class="view-page" :style="{backgroundImage : `url('${ThemeData?.app_bg || $config.PRIMARY_BGURL}')`}">
<headerHeight />
<navBar :navTitle="`公会补贴`">
<template #rightView>
<view class="icon-right flex-line" @click="exit"
v-if="detailData && leaderStatus" >
<view @click="historyRecord" class="font-24 minUnicon" style="white-space: nowrap">
历史记录
</view>
</view>
</template>
</navBar>
<view class="content-view" v-if="detailData">
<view class="bottom" v-for="(data,index) in detailData" :key="index">
<view class="flex-line flex-spaceB w-fill">
<view class="color-3 font-w500 font-32">
{{data.name}}
</view>
<view class="font-28" :style="{'color' : data.status_str === '已发放' ? '#999' : '#DEB52E'}">
</view>
</view>
<view class="line">
</view>
<view class="flex-line flex-spaceB w-fill">
<view class="cumulative font-28 font-w400">
累计流水{{data.total_transaction}}
</view>
<view class="subsidy font-28">
获得补贴{{data.subsidy_amount}}
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import headerHeight from '@/component/headerHeight.vue';
import navBar from '@/component/nav.vue';
import http from '@/until/http.js';
import logo from '@/static/image/logo.png'
export default {
components: {
headerHeight,
navBar
},
data() {
return {
logo,
detailData: null,
searchParams: {
guild_id: 0,
token: uni.getStorageSync('token') || '',
},
ThemeData:null
}
},
onLoad(options) {
const {
id,
leader
} = options
this.leaderStatus = +leader
this.searchParams.guild_id = id
if (id) this.getSubsidy()
if(uni.getStorageSync('Theme_Data')) {
this.ThemeData = JSON.parse(uni.getStorageSync('Theme_Data'))
}
},
methods: {
//
async getSubsidy() {
const {
code,
data
} = await http.get('/api/Guild/guild_subsidy', this.searchParams)
this.detailData = code ? data.list : null
},
historyRecord(){
uni.navigateTo({
url: `/pages/union/historyRecord?id=${this.searchParams.guild_id}`
});
},
}
}
</script>
<style scoped lang="scss">
.view-page {
min-height: 100vh;
font-family: Source Han Sans CN, Source Han Sans CN;
// background-image: url('@/static/image/help/bg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
.minUnicon{
color: var(--primary-color);
}
.content-view{
padding: 0 24rpx;
}
.bottom{
margin-top: 40rpx;
}
.cumulative {
color: var(--primary-color);
}
.line {
background-color: #ECECEC;
height: 1rpx;
margin: 24rpx 0;
}
.subsidy {
color: var(--warn-color);
}
}
</style>

View File

@@ -1,719 +0,0 @@
<template>
<div class="wealth-level-page">
<!-- 顶部导航栏 -->
<div class="header">
<div class="back-btn" @click="goBack">
<i class="icon-back"></i>
</div>
<div class="title-section">
<h1 class="main-title">财富等级</h1>
<span class="sub-title">主播等级</span>
</div>
<div class="help-btn" @click="showHelp">
<i class="icon-help">?</i>
</div>
</div>
<!-- 等级进度环形图 -->
<div class="level-progress-section">
<div class="progress-ring-container">
<!-- 等级标签 -->
<div class="level-labels">
<div
class="level-label"
v-for="(level, index) in levels"
:key="index"
:class="{ active: currentLevelIndex >= index }"
>
<span class="level-name">{{ level.name }}</span>
<div
class="level-dot"
:class="{ active: currentLevelIndex >= index }"
></div>
</div>
</div>
<!-- 中心头像和信息 -->
<div class="center-info">
<div class="avatar">
<img :src="userAvatar" alt="用户头像" />
</div>
<div class="experience-info">
<div class="current-exp">
<span class="exp-number">{{ currentExp }}</span>
<span class="exp-label">当前经验</span>
</div>
<div class="next-level-exp">
<span class="exp-number">{{ nextLevelExp }}</span>
<span class="exp-label">距离下一个等级</span>
</div>
</div>
</div>
<!-- 进度弧线 -->
<svg class="progress-ring" viewBox="0 0 200 200">
<circle
class="progress-ring-bg"
cx="100"
cy="100"
r="85"
fill="none"
stroke="#2a2a2a"
stroke-width="4"
/>
<circle
class="progress-ring-progress"
cx="100"
cy="100"
r="85"
fill="none"
stroke="#00ff88"
stroke-width="4"
stroke-linecap="round"
:stroke-dasharray="circumference"
:stroke-dashoffset="progressOffset"
transform="rotate(-90 100 100)"
/>
</svg>
</div>
</div>
<!-- 当前等级卡片 -->
<div class="current-level-card">
<div class="level-badge">
<img :src="currentLevel.badge" alt="等级徽章" />
</div>
<div class="level-info">
<h2 class="level-title">{{ currentLevel.name }}</h2>
<p class="level-description">{{ currentLevel.description }}</p>
<div class="level-progress-bar">
<div class="progress-track">
<div
class="progress-fill"
:style="{ width: levelProgress + '%' }"
></div>
</div>
<div class="progress-labels">
<span>Lv.{{ currentLevel.level }}</span>
<span>Lv.{{ currentLevel.level + 1 }}</span>
</div>
</div>
<p class="next-level-requirement">{{ nextLevelRequirement }}</p>
</div>
</div>
<!-- 每日奖励 -->
<div class="daily-rewards-section">
<h3 class="section-title">每日奖励</h3>
<div class="reward-item">
<div class="reward-icon">
<img src="/icons/coin.png" alt="金币" />
</div>
<div class="reward-info">
<p class="reward-title">段位达到富豪8</p>
<p class="reward-desc">可每日领取金币</p>
</div>
<button
class="claim-btn"
@click="claimDailyReward"
:disabled="dailyRewardClaimed"
>
{{ dailyRewardClaimed ? "已领取" : "立即领取" }}
</button>
</div>
</div>
<!-- 等级需求及福利 -->
<div class="level-benefits-section">
<h3 class="section-title">等级需求及福利</h3>
<div class="benefits-grid">
<div
class="benefit-item"
v-for="(benefit, index) in levelBenefits"
:key="index"
>
<div class="benefit-icon">
<img :src="benefit.icon" alt="福利图标" />
</div>
<p class="benefit-value">{{ benefit.value }}</p>
<p class="benefit-desc">{{ benefit.description }}</p>
</div>
</div>
</div>
<!-- 财富特权 -->
<div class="wealth-privileges-section">
<h3 class="section-title">财富特权</h3>
<div class="privileges-grid">
<div
class="privilege-item"
v-for="(privilege, index) in wealthPrivileges"
:key="index"
>
<div class="privilege-icon">
<img :src="privilege.icon" alt="特权图标" />
</div>
<p class="privilege-name">{{ privilege.name }}</p>
<p class="privilege-level">{{ privilege.level }}</p>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "WealthLevelPage",
data() {
return {
// 用户信息
userAvatar: "",
currentExp: 1608,
nextLevelExp: 1608,
currentLevelIndex: 1,
dailyRewardClaimed: false,
// 等级配置
levels: [
{ name: "新人", value: 0 },
{ name: "富豪", value: 1000 },
{ name: "星爵", value: 5000 },
{ name: "星侯", value: 15000 },
{ name: "星王", value: 50000 },
],
// 当前等级信息
currentLevel: {
name: "星爵",
level: 1,
description: "进30天保段已成功",
badge: "",
requirement: 10000,
},
// 等级福利
levelBenefits: [
{
icon: "",
value: "100万",
description: "所需经验值",
},
{
icon: "",
value: "100万",
description: "保段经验值",
},
{
icon: "",
value: "100万",
description: "每日可领",
},
{
icon: "",
value: "吉普",
description: "专属座驾",
},
],
// 财富特权
wealthPrivileges: Array(12)
.fill()
.map((_, index) => ({
name: "吉普",
level: "富豪6解锁",
icon: "",
})),
};
},
computed: {
// 计算圆形进度条
circumference() {
return 2 * Math.PI * 85;
},
progressOffset() {
const progress = this.levelProgress / 100;
return this.circumference - progress * this.circumference;
},
// 计算当前等级进度
levelProgress() {
const currentLevelExp = this.levels[this.currentLevelIndex].value;
const nextLevelExp =
this.levels[this.currentLevelIndex + 1]?.value ||
currentLevelExp + 10000;
const progress =
((this.currentExp - currentLevelExp) /
(nextLevelExp - currentLevelExp)) *
100;
return Math.min(Math.max(progress, 0), 100);
},
// 下一等级需求
nextLevelRequirement() {
const nextLevel = this.levels[this.currentLevelIndex + 1];
if (nextLevel) {
const remaining = nextLevel.value - this.currentExp;
return `距离下一个段位还差${remaining.toLocaleString()}经验`;
}
return "已达到最高等级";
},
},
methods: {
// 返回上一页
goBack() {
this.$router.go(-1);
},
// 显示帮助
showHelp() {
this.$toast("帮助信息");
},
// 领取每日奖励
claimDailyReward() {
if (this.dailyRewardClaimed) return;
this.dailyRewardClaimed = true;
this.$toast("领取成功!");
// 这里可以调用API
this.apiClaimDailyReward();
},
// API调用示例
async apiClaimDailyReward() {
try {
// const response = await this.$api.claimDailyReward()
console.log("API: 领取每日奖励");
} catch (error) {
console.error("领取失败:", error);
this.dailyRewardClaimed = false;
}
},
// 获取用户等级数据
async fetchUserLevelData() {
try {
// const response = await this.$api.getUserLevel()
// this.currentExp = response.currentExp
// this.currentLevelIndex = response.levelIndex
console.log("API: 获取用户等级数据");
} catch (error) {
console.error("获取数据失败:", error);
}
},
},
mounted() {
this.fetchUserLevelData();
},
};
</script>
<style scoped>
.wealth-level-page {
min-height: 100vh;
background: linear-gradient(180deg, #1a1a1a 0%, #2d2d2d 50%, #f5f5f5 50%);
color: #fff;
padding-bottom: 20px;
}
/* 顶部导航 */
.header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 44px 20px 20px;
position: relative;
}
.back-btn,
.help-btn {
width: 32px;
height: 32px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: background 0.2s;
}
.back-btn:hover,
.help-btn:hover {
background: rgba(255, 255, 255, 0.2);
}
.icon-back {
font-size: 18px;
font-weight: bold;
}
.icon-help {
font-size: 14px;
font-weight: bold;
}
.title-section {
text-align: center;
}
.main-title {
font-size: 18px;
font-weight: 600;
margin: 0 0 4px 0;
}
.sub-title {
font-size: 12px;
color: #999;
}
/* 等级进度环形图 */
.level-progress-section {
padding: 20px;
display: flex;
justify-content: center;
}
.progress-ring-container {
position: relative;
width: 280px;
height: 280px;
}
.level-labels {
position: absolute;
width: 100%;
height: 100%;
z-index: 2;
}
.level-label {
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
font-size: 12px;
}
.level-label:nth-child(1) {
top: 10px;
left: 20px;
} /* 新人 */
.level-label:nth-child(2) {
top: 40px;
right: 10px;
} /* 富豪 */
.level-label:nth-child(3) {
bottom: 40px;
right: 10px;
} /* 星爵 */
.level-label:nth-child(4) {
bottom: 10px;
left: 20px;
} /* 星侯 */
.level-label:nth-child(5) {
top: 50%;
right: 0;
transform: translateY(-50%);
} /* 星王 */
.level-name {
margin-bottom: 4px;
color: #999;
}
.level-label.active .level-name {
color: #00ff88;
}
.level-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: #333;
border: 2px solid #555;
}
.level-dot.active {
background: #00ff88;
border-color: #00ff88;
}
.center-info {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
z-index: 3;
}
.avatar {
width: 60px;
height: 60px;
border-radius: 50%;
overflow: hidden;
margin: 0 auto 16px;
border: 3px solid #00ff88;
}
.avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.experience-info {
display: flex;
justify-content: space-between;
width: 200px;
margin-top: 16px;
}
.current-exp,
.next-level-exp {
text-align: center;
}
.exp-number {
display: block;
font-size: 18px;
font-weight: bold;
color: #00ff88;
}
.exp-label {
font-size: 10px;
color: #999;
margin-top: 2px;
}
.progress-ring {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: rotate(-90deg);
}
.progress-ring-progress {
transition: stroke-dashoffset 0.5s ease;
}
/* 当前等级卡片 */
.current-level-card {
margin: 20px;
background: rgba(255, 255, 255, 0.1);
border-radius: 16px;
padding: 20px;
display: flex;
align-items: center;
backdrop-filter: blur(10px);
}
.level-badge {
width: 60px;
height: 60px;
margin-right: 16px;
flex-shrink: 0;
}
.level-badge img {
width: 100%;
height: 100%;
object-fit: contain;
}
.level-info {
flex: 1;
}
.level-title {
font-size: 20px;
font-weight: bold;
margin: 0 0 4px 0;
color: #00ff88;
}
.level-description {
font-size: 12px;
color: #ccc;
margin: 0 0 12px 0;
}
.level-progress-bar {
margin: 8px 0;
}
.progress-track {
height: 4px;
background: #333;
border-radius: 2px;
overflow: hidden;
margin-bottom: 4px;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #00ff88, #00ccff);
border-radius: 2px;
transition: width 0.5s ease;
}
.progress-labels {
display: flex;
justify-content: space-between;
font-size: 10px;
color: #999;
}
.next-level-requirement {
font-size: 11px;
color: #999;
margin: 8px 0 0 0;
}
/* 每日奖励和福利区域 */
.daily-rewards-section,
.level-benefits-section,
.wealth-privileges-section {
background: #fff;
color: #333;
padding: 20px;
}
.section-title {
font-size: 16px;
font-weight: 600;
margin: 0 0 16px 0;
color: #333;
}
.reward-item {
display: flex;
align-items: center;
padding: 16px;
background: #f8f9fa;
border-radius: 12px;
}
.reward-icon {
width: 40px;
height: 40px;
margin-right: 12px;
}
.reward-icon img {
width: 100%;
height: 100%;
object-fit: contain;
}
.reward-info {
flex: 1;
}
.reward-title {
font-size: 14px;
font-weight: 500;
margin: 0 0 2px 0;
}
.reward-desc {
font-size: 12px;
color: #666;
margin: 0;
}
.claim-btn {
background: #00ff88;
color: #fff;
border: none;
border-radius: 20px;
padding: 8px 16px;
font-size: 12px;
cursor: pointer;
transition: background 0.2s;
}
.claim-btn:hover:not(:disabled) {
background: #00e67a;
}
.claim-btn:disabled {
background: #ccc;
cursor: not-allowed;
}
/* 福利网格 */
.benefits-grid,
.privileges-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
}
.benefit-item,
.privilege-item {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 12px;
background: #f8f9fa;
border-radius: 8px;
}
.benefit-icon,
.privilege-icon {
width: 32px;
height: 32px;
margin-bottom: 8px;
}
.benefit-icon img,
.privilege-icon img {
width: 100%;
height: 100%;
object-fit: contain;
}
.benefit-value,
.privilege-name {
font-size: 12px;
font-weight: 500;
margin: 0 0 2px 0;
color: #333;
}
.benefit-desc,
.privilege-level {
font-size: 10px;
color: #666;
margin: 0;
}
/* 响应式设计 */
@media (max-width: 375px) {
.progress-ring-container {
width: 240px;
height: 240px;
}
.experience-info {
width: 160px;
}
.benefits-grid,
.privileges-grid {
grid-template-columns: repeat(2, 1fr);
}
}
</style>

View File

@@ -1,397 +0,0 @@
<template>
<view class="view-page" :style="{backgroundImage : `url('${ThemeData?.app_bg || $config.PRIMARY_BGURL}')`}">
<headerHeight />
<navBar :navTitle="`公会成员`">
<template #rightView>
<view class="icon-right flex-line" v-if="leaderStatus" @click="application">
<view class="font-24" style="color:#333;white-space: nowrap">
退出审核
</view>
</view>
</template>
</navBar>
<view class="content_view">
<view v-if="leaderStatus">
<uni-datetime-picker style="background-color: #f8f8f8;" start-placeholder="开始时间" :end="currentDate"
end-placeholder="结束时间" v-model="dateSearch" type="range" rangeSeparator="至" @change="changeDate" />
</view>
<view class="header-view" v-if="flowDetail && leaderStatus">
<view class="flex-line flow-view w-fill flex-spaceB">
<view class="flowTitle color-3">
总支出
</view>
</view>
<view class="flowNumber">
{{ flowDetail.total_consumption }}
</view>
</view>
<view class="room-list flex-line mt-24" v-if="dataList && dataList.length">
<view class="room-line w-fill" v-for="data in dataList" :key="data.room_id">
<view class="w-fill flex-line flex-spaceB" @click="jumpHomePage(data)">
<view class="flex-line w-fill">
<view class="head-portrait-view">
<view class="head-portrait">
<img :src="data.avatar || logo" alt="" />
</view>
<view class="tip" v-if="data.is_deacon === 1">
<img src="@/static/image/union/ghz_tip.png" alt="" />
</view>
</view>
<view class="ml-20">
<view class="color-3 font-32 font-w500">
{{ data.nickname }}
</view>
<view class="color-6 font-24" style="margin-top: 12rpx;">
ID:{{ data.user_code }}
</view>
</view>
</view>
<view class="flex-line" v-if="leaderStatus">
<view class="flowIcon">
<img src="@/static/image/union/flowIcon.png" alt="" />
</view>
<view class="ml-20">
{{ data.total_consumption || 0 }}
</view>
</view>
</view>
<view class="w-fill operate_button" v-if="leaderStatus && data.is_deacon === 2">
<view class="color-f font-24 button" @click="kickGuild(data)">
踢出公会
</view>
</view>
</view>
</view>
<view class="mt-24">
<uni-load-more :status="loading ? 'loading' : noMore ? 'noMore' : 'more'" />
</view>
</view>
<uni-popup ref="message" type="message">
<uni-popup-message :type="msgType" :message="messageText" :duration="2000"></uni-popup-message>
</uni-popup>
<uni-popup ref="popup" type="center">
<view class="popup_view">
<view class="color-3 font-32 popup_title">
温馨提示
</view>
<view class="color-3 font-24 messageContent">
{{ messageContent }}
</view>
<view class="popup_button flex-line">
<view class="close_button flex-line" @click="closePopup">
取消
</view>
<view class="confirm-button flex-line" @click="confirmPopup">
确认
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import headerHeight from '@/component/headerHeight.vue';
import navBar from '@/component/nav.vue';
import http from '@/until/http.js';
import logo from '@/static/image/logo.png'
export default {
components: {
headerHeight,
navBar
},
data() {
return {
dateSearch: [new Date(), new Date()],
currentDate: +new Date(),
logo,
loading: false,
noMore: false,
detailData: null,
pageConfig: {
pageSize: 10,
currentPage: 1,
total: 0
},
searchParams: {
guild_id: 0,
start_time: '',
end_time: '',
token: uni.getStorageSync('token') || '',
page: 1,
page_size: 20
},
leaderStatus: null,
flowDetail: null,
msgType: '',
messageText: '',
messageContent: '',
dataList: [],
currentUserData: null,
ThemeData: null
}
},
onLoad(options) {
const {
id,
leader
} = options
this.leaderStatus = +leader
this.searchParams.guild_id = id
this.searchParams.start_time = this.formatDate(new Date())
this.searchParams.end_time = this.formatDate(new Date())
if (id) this.getList()
if (uni.getStorageSync('Theme_Data')) {
this.ThemeData = JSON.parse(uni.getStorageSync('Theme_Data'))
}
},
onReachBottom() {
if (!this.loading && !this.noMore) {
this.getList()
}
},
methods: {
application() {
uni.navigateTo({
url: `/pages/union/exitApplication?id=${this.searchParams.guild_id}`
});
},
formatDate(timestamp) {
const date = new Date(timestamp);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始需+1
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
},
// 获取成员列表
async getList() {
const {
code,
data
} = await http.get('/api/Guild/get_guild_member_list', {
...this.searchParams,
page: this.pageConfig.currentPage,
page_limit: this.pageConfig.pageSize,
})
if (code) {
this.flowDetail = data
this.pageConfig.total = data.count
this.loading = false
const newData = data.list || []
if (newData.length === 0) {
this.noMore = true
return
}
this.dataList = [...this.dataList, ...newData]
this.pageConfig.currentPage++
if (this.dataList.length === this.pageConfig.total) {
this.noMore = true
return
}
}
},
// 日期范围
changeDate(date) {
this.searchParams.start_time = date.length ? date[0] : ''
this.searchParams.end_time = date.length ? date[1] : ''
this.getList()
},
// 踢出公会
kickGuild(userData) {
this.currentUserData = userData
this.messageContent = `亲爱的会长,您当前操作将踢出该成员,是否继续?`
this.$refs.popup.open('center')
},
jumpHomePage(data) {
const platform = uni.getSystemInfoSync().platform;
if (platform === 'ios') {
window.webkit.messageHandlers.nativeHandler.postMessage({
'action': 'jumpWebPage',
'data': {
userId: data.user_id
}
});
} else if (platform === 'android') {
window.Android.jumpWebPage(data.user_id);
}
},
confirmPopup() {
this.kickUser()
},
closePopup() {
this.currentUserData = null
this.messageContent = ""
this.$refs.popup.close()
},
async kickUser() {
http.post('/api/Guild/kick_guild_member', {
guild_id: this.currentUserData.guild_id,
user_id: this.currentUserData.user_id,
token: uni.getStorageSync('token') || ''
}).then(response => {
const {
data,
code,
msg
} = response
if (code) {
this.msgType = 'success'
this.messageText = `操作成功`
this.$refs.message.open()
this.dataList = []
this.pageConfig.currentPage = 1
this.getList()
} else {
this.messageText = msg
this.msgType = 'error'
this.$refs.message.open()
}
this.currentUserData = null
this.closePopup()
})
}
}
}
</script>
<style scoped lang="scss">
.view-page {
// padding: 24rpx 32rpx;
min-height: 100vh;
font-family: Source Han Sans CN, Source Han Sans CN;
// background-image: url('@/static/image/help/bg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
.content_view {
padding: 0 24rpx;
}
.popup_view {
width: 550rpx;
// height: 40vh;
background-color: #fff;
border-radius: 32rpx;
padding: 32rpx;
.popup_title {
text-align: center;
}
.messageContent {
margin: 24rpx 0;
}
.popup_button {
margin-top: 24rpx;
width: 100%;
justify-content: space-around;
.close_button,
.confirm-button {
width: 200rpx;
height: 84rpx;
background: #F3F3F3;
border-radius: 106rpx;
color: #999999;
justify-content: center;
}
.confirm-button {
background: var(--primary-color);
color: var(--font-button-color);
}
}
}
.header-view {
padding: 24rpx;
margin-top: 24rpx;
background-image: url('/static/image/union/flowbg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
height: 152rpx;
.flow-view {
font-weight: 400;
font-size: 24rpx;
}
.flowNumber {
font-weight: 500;
font-size: 40rpx;
color: #333;
margin-top: 24rpx;
}
}
.room-list {
flex-wrap: wrap;
width: 100%;
.operate_button {
border-top: 1rpx solid #E2E2E2;
margin-top: 24rpx;
padding-top: 24rpx;
.button {
padding: 12rpx 24rpx;
background-color: #333;
display: inline-flex;
border-radius: 32rpx;
}
}
.room-line {
width: 100%;
// background-color: #004D3C;
margin-bottom: 24rpx;
padding: 24rpx;
border-radius: 10rpx;
background-color: #fff;
.flowIcon {
width: 48rpx;
height: 48rpx;
}
.head-portrait {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
img {
border-radius: 50%;
}
}
.head-portrait-view {
position: relative;
.tip {
position: absolute;
bottom: 0;
left: 5rpx;
right: 0;
width: 96rpx;
height: 26rpx;
border-radius: 0;
img {
width: 100%;
height: 100%;
}
}
}
}
}
}
</style>