3232
This commit is contained in:
parent
429192cdd2
commit
00f0187a82
|
|
@ -4,7 +4,7 @@
|
|||
"id": 7,
|
||||
"reservation_id": 3,
|
||||
"user_id": 3796,
|
||||
"role": 1,
|
||||
"role": 1, // 角色 1 发起者 0 参与者
|
||||
"join_time": "2025/09/03 04:05:40",
|
||||
"status": 0,
|
||||
"userName": "闪光大帕鲁",
|
||||
|
|
@ -13,11 +13,11 @@
|
|||
}
|
||||
],
|
||||
"id": 3,
|
||||
"title": "测试1",
|
||||
"title": "测试1", //祖居名称
|
||||
"room_id": 3,
|
||||
"room_name": "306小包间",
|
||||
"start_time": "2025/09/13 21:09:43",
|
||||
"end_time": "2025/09/13 21:34:43",
|
||||
"room_name": "306小包间",// 房间名称
|
||||
"start_time": "2025/09/13 21:09:43", //开始时间
|
||||
"end_time": "2025/09/13 21:34:43",//结束时间
|
||||
"duration_minutes": 25,
|
||||
"player_count": 4,
|
||||
"game_type": "扑克",
|
||||
|
|
|
|||
|
|
@ -74,28 +74,7 @@ const shouldUseCache = () => {
|
|||
export const getReservation = async (index = 1, size = 20) => {
|
||||
const res = await getReservationList(index, size);
|
||||
if (res != null && res.length > 0) {
|
||||
// {
|
||||
// id: '',
|
||||
// status: '',
|
||||
// description: '',
|
||||
// time: '',
|
||||
// room: '',
|
||||
// requirements: '',
|
||||
// personCount: 4, //总人数
|
||||
// joinPerson: [{
|
||||
// id: 1,
|
||||
// name: '张三',
|
||||
// avatar: '',
|
||||
// phone: '',
|
||||
// }], //已加入人
|
||||
// }
|
||||
//[{"participants":[{"id":7,"reservation_id":3,"user_id":3796,"role":1,"join_time":"2025/09/03 04:05:40",
|
||||
// "status":0,"userName":"闪光大帕鲁","avatarImage":"https://admin-1308826010.cos.ap-shanghai.myqcloud.com/
|
||||
// users20250908/20250908152502_6366.png","userBlackStatus":0}],
|
||||
// "id":3,"title":"测试1","room_id":3,"room_name":"306小包间",
|
||||
// "start_time":"2025/09/13 21:09:43","end_time":"2025/09/13 21:34:43",
|
||||
// "duration_minutes":25,"player_count":4,"game_type":"扑克","game_rule":"跑得快",
|
||||
// "extra_info":"11","is_smoking":1,"gender_limit":2,"credit_limit":0.0,"min_age":0,"max_age":0,"deposit_fee":0.00,"status":0,"created_at":"2025/09/03 00:21:16","updated_at":"2025/09/03 21:10:21","remarks":""}]
|
||||
|
||||
console.log("记录", res);
|
||||
var list = res.map(item => {
|
||||
let start_time = parseTimeString(item.start_time);
|
||||
|
|
@ -127,6 +106,7 @@ export const getReservation = async (index = 1, size = 20) => {
|
|||
let requirements = requirementsList.join(",");
|
||||
return {
|
||||
id: item.id,
|
||||
data: item,
|
||||
status: item.status,
|
||||
description: item.title,
|
||||
dateStr: formatTime(start_time, "yyyy-MM-dd"),
|
||||
|
|
@ -150,6 +130,7 @@ export const getReservation = async (index = 1, size = 20) => {
|
|||
});
|
||||
|
||||
return list;
|
||||
// return [];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import request from '@/common/system/request';
|
|||
export const getReservationList = async (index = 1, size = 20) => {
|
||||
console.log('getReservationList', index, size);
|
||||
|
||||
const res = await request.get("sq/GetReservationList", { pageIndex: index, pageSize: size });
|
||||
const res = await request.getOrCache("sq/GetReservationList", { pageIndex: index, pageSize: size }, 5);
|
||||
if (res.code == 0) {
|
||||
return res.data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,33 @@ export function showModal(options = {}) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} title
|
||||
* @param {String} content
|
||||
* @returns
|
||||
*/
|
||||
export function showModalConfirm(title, content) {
|
||||
return new Promise((resolve) => {
|
||||
uni.showModal({
|
||||
title: title || '提示',
|
||||
content: content || '',
|
||||
confirmText: '确定',
|
||||
cancelText: '取消',
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
confirmColor: '#1989FA',
|
||||
cancelColor: '#9F9F9F',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
resolve(true);
|
||||
} else if (res.cancel) {
|
||||
resolve(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 显示提示信息
|
||||
* @param {*} title 提示信息
|
||||
|
|
|
|||
2
components.d.ts
vendored
2
components.d.ts
vendored
|
|
@ -11,6 +11,8 @@ declare module 'vue' {
|
|||
Container: typeof import('./components/com/page/container.vue')['default']
|
||||
MahjongCard: typeof import('./components/index/MahjongCard.vue')['default']
|
||||
NoData: typeof import('./components/com/page/no-data.vue')['default']
|
||||
NoEmpty: typeof import('./components/com/index/NoEmpty.vue')['default']
|
||||
ReservationPopup: typeof import('./components/com/index/ReservationPopup.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
UniNavBar: typeof import('./components/uni-nav-bar/uni-nav-bar.vue')['default']
|
||||
|
|
|
|||
53
components/com/index/NoEmpty.vue
Normal file
53
components/com/index/NoEmpty.vue
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<view class="page">
|
||||
<view class="image-container">
|
||||
<image
|
||||
class="empty-image"
|
||||
src="@@:app/static/index/no.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
</view>
|
||||
<view class="text-container">
|
||||
<text class="empty-text">
|
||||
现在还没人预约~
|
||||
<br />
|
||||
休息一会吧
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page {
|
||||
.image-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.empty-image {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
}
|
||||
|
||||
.text-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
width: 210rpx;
|
||||
height: 80rpx;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 500;
|
||||
font-size: 28rpx;
|
||||
color: #6F6F6F;
|
||||
text-align: center;
|
||||
font-style: normal;
|
||||
text-transform: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
259
components/com/index/ReservationPopup.vue
Normal file
259
components/com/index/ReservationPopup.vue
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
<template>
|
||||
<uni-popup ref="popup" type="center">
|
||||
<view class="column center"
|
||||
style="width: 680rpx; background-color: white; border-radius: 10rpx; padding: 20rpx;">
|
||||
|
||||
<text style="">预约信息</text>
|
||||
|
||||
<view class="column"
|
||||
style="width: 100%; height: 180rpx; background-color: #E3E2E2; margin-top: 20rpx; border-radius: 10rpx;">
|
||||
<view class="row" style="margin-top: 20rpx; align-items: center; margin-left: 20rpx;">
|
||||
<text style="font-size: 22rpx;">发起者</text>
|
||||
<image :src="initiatorInfo.avatarImage || ''"
|
||||
style="width: 50rpx; height: 50rpx; background-color: antiquewhite; border-radius: 50%; margin-left: 20rpx;"
|
||||
mode=""></image>
|
||||
<text style="font-size: 20rpx; margin-left: 15rpx;">{{ initiatorInfo.userName || '' }}</text>
|
||||
</view>
|
||||
<view class="row" style="margin-top: 30rpx; align-items: center; margin-left: 20rpx;">
|
||||
<text style="font-size: 22rpx;">参与者</text>
|
||||
|
||||
<view class="row" v-for="(item, index) in participantList" :key="index"
|
||||
style="align-items: center;">
|
||||
|
||||
<view class="" style="position: relative; width: 50rpx; height: 50rpx; display: flex;">
|
||||
<image :src="item.avatarImage || ''" @click="openUserPop(item)"
|
||||
style="width: 50rpx; height: 50rpx; background-color: antiquewhite; border-radius: 50%; margin-left: 20rpx; position: absolute;"
|
||||
mode=""></image>
|
||||
|
||||
<view v-if="item.userBlackStatus === 1" class="center"
|
||||
style="width: 50rpx; height: 20rpx; background-color: #FFB7B7; position: absolute; left: 40%; top: -10rpx;">
|
||||
<text style="font-size: 10rpx;">黑名单</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<text
|
||||
style="font-size: 20rpx; margin-left: 30rpx; width: 100rpx; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">{{
|
||||
item.userName || '' }}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
|
||||
<view class="column"
|
||||
style="width: 100%; height: 180rpx; background-color: #E3E2E2; margin-top: 20rpx; border-radius: 10rpx;font-size: 22rpx;">
|
||||
|
||||
<view class="row" style="justify-content: space-between; margin: 20rpx;">
|
||||
<text>开始时间</text>
|
||||
<text>{{ formatTime(reservationData.start_time) }}</text>
|
||||
</view>
|
||||
<view class="row" style="justify-content: space-between; margin: 0 20rpx;">
|
||||
<text>结束时间</text>
|
||||
<text>{{ formatTime(reservationData.end_time) }}</text>
|
||||
</view>
|
||||
|
||||
<text style="margin: 30rpx 20rpx 0;">合计:{{ formatDuration(reservationData.duration_minutes) }}</text>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="column"
|
||||
style="width: 100%; background-color: #E3E2E2; margin-top: 20rpx; border-radius: 10rpx; font-size: 22rpx;">
|
||||
<text style="margin: 20rpx 20rpx 10rpx; font-size: 24rpx;">房间号:{{ reservationData.room_name || ''
|
||||
}}</text>
|
||||
<text style="margin: 10rpx 20rpx;">人数:{{ reservationData.player_count || 0 }}人</text>
|
||||
<text style="margin: 10rpx 20rpx;">玩法类型:{{ reservationData.game_type || '' }}</text>
|
||||
<text style="margin: 10rpx 20rpx;">具体规则:{{ reservationData.game_rule || '' }}</text>
|
||||
<text style="margin: 10rpx 20rpx 20rpx;">补充信息:{{ reservationData.extra_info || '无' }}</text>
|
||||
</view>
|
||||
|
||||
<view class="column"
|
||||
style="width: 100%; background-color: #E3E2E2; margin-top: 20rpx; border-radius: 10rpx; font-size: 22rpx;">
|
||||
<text style="margin: 20rpx 20rpx 10rpx; font-size: 24rpx;">是否禁烟:{{
|
||||
getSmokingText(reservationData.is_smoking) }}</text>
|
||||
<text style="margin: 10rpx 20rpx;">性别:{{ getGenderText(reservationData.gender_limit) }}</text>
|
||||
<text style="margin: 10rpx 20rpx 20rpx;">信誉:≧{{ reservationData.credit_limit || 0 }}</text>
|
||||
</view>
|
||||
|
||||
<view class="column"
|
||||
style="width: 100%; background-color: #E3E2E2; margin-top: 20rpx; border-radius: 10rpx; font-size: 22rpx;">
|
||||
<text style="margin: 20rpx 20rpx 10rpx; font-size: 24rpx;">鸽子费:{{ reservationData.deposit_fee || 0
|
||||
}}元</text>
|
||||
<text
|
||||
style="margin: 10rpx 20rpx 20rpx; color: #9F9F9F;">组局成功后若有牌友未赴约,其鸽子费平均分给其他牌友。组局成功或失败后鸽子费将全额返还。</text>
|
||||
</view>
|
||||
|
||||
<view class="row" v-if="isAddhandleJoin == 0" style="width: 100%; margin-top: 30rpx;">
|
||||
<view class="center" @click="close"
|
||||
style="height: 80rpx; flex: 1; background-color: #9F9F9F; border-radius: 10rpx;">
|
||||
<text style="font-size: 24rpx; font-weight: 600; color: white;">关闭</text>
|
||||
</view>
|
||||
<view class="center" @click="handleJoin"
|
||||
style="height: 80rpx; flex: 3; background-color: #1989FA; border-radius: 10rpx; margin-left: 20rpx;">
|
||||
<text style="font-size: 24rpx; font-weight: 600; color: white;">参与组局</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row" v-if="isAddhandleJoin == 1" style="width: 100%; margin-top: 30rpx;">
|
||||
<view class="center" @click="close"
|
||||
style="height: 80rpx; flex: 1; background-color: #9F9F9F; border-radius: 10rpx;">
|
||||
<text style="font-size: 24rpx; font-weight: 600; color: white;">关闭</text>
|
||||
</view>
|
||||
<view class="center" @click="exitJoin"
|
||||
style="height: 80rpx; flex: 3; background-color: #1989FA; border-radius: 10rpx; margin-left: 20rpx;">
|
||||
<text style="font-size: 24rpx; font-weight: 600; color: white;">退出组局</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row" v-if="isAddhandleJoin == 2" style="width: 100%; margin-top: 30rpx;">
|
||||
<view class="center" @click="close"
|
||||
style="height: 80rpx; flex: 1; background-color: #9F9F9F; border-radius: 10rpx;">
|
||||
<text style="font-size: 24rpx; font-weight: 600; color: white;">关闭</text>
|
||||
</view>
|
||||
<view class="center" @click="cancelJoin"
|
||||
style="height: 80rpx; flex: 3; background-color: #1989FA; border-radius: 10rpx; margin-left: 20rpx;">
|
||||
<text style="font-size: 24rpx; font-weight: 600; color: white;">取消组局</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { userInfo } from '@/common/server/user'
|
||||
import { showModalConfirm } from '@/common/utils'
|
||||
|
||||
// 组件引用
|
||||
const popup = ref(null)
|
||||
|
||||
// 预约数据
|
||||
const reservationData = ref({})
|
||||
|
||||
// 计算属性:发起者信息
|
||||
const initiatorInfo = computed(() => {
|
||||
if (reservationData.value.participants && reservationData.value.participants.length > 0) {
|
||||
return reservationData.value.participants.find(p => p.role === 1) || {}
|
||||
}
|
||||
return {}
|
||||
})
|
||||
|
||||
// 计算属性:参与者列表
|
||||
const participantList = computed(() => {
|
||||
if (reservationData.value.participants && reservationData.value.participants.length > 0) {
|
||||
return reservationData.value.participants.filter(p => p.role === 0) || []
|
||||
}
|
||||
return []
|
||||
});
|
||||
|
||||
var isAddhandleJoin = ref(0);
|
||||
// 显示弹窗
|
||||
const show = (item) => {
|
||||
reservationData.value = item || {}
|
||||
if (userInfo.value != null) {
|
||||
var _initiatorInfo = item.participants.find(p => p.role === 1);
|
||||
if (_initiatorInfo != null) {
|
||||
if (userInfo.value.id == _initiatorInfo.user_id) {
|
||||
isAddhandleJoin.value = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
popup.value.open()
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const close = () => {
|
||||
popup.value.close()
|
||||
}
|
||||
|
||||
// 格式化时间
|
||||
const formatTime = (timeStr) => {
|
||||
if (!timeStr) return ''
|
||||
// 将 "2025/09/13 21:09:43" 格式转换为 "2025/09/13 21:09"
|
||||
const date = new Date(timeStr)
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
const hours = String(date.getHours()).padStart(2, '0')
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}`
|
||||
}
|
||||
|
||||
// 格式化时长
|
||||
const formatDuration = (minutes) => {
|
||||
if (!minutes) return '0分钟'
|
||||
const hours = Math.floor(minutes / 60)
|
||||
const mins = minutes % 60
|
||||
if (hours > 0) {
|
||||
return mins > 0 ? `${hours}小时${mins}分钟` : `${hours}小时`
|
||||
}
|
||||
return `${mins}分钟`
|
||||
}
|
||||
|
||||
// 获取禁烟文本
|
||||
const getSmokingText = (isSmoking) => {
|
||||
return isSmoking === 1 ? '禁烟' : '不禁烟'
|
||||
}
|
||||
|
||||
// 获取性别限制文本
|
||||
const getGenderText = (genderLimit) => {
|
||||
switch (genderLimit) {
|
||||
case 0:
|
||||
return '不限'
|
||||
case 1:
|
||||
return '男'
|
||||
case 2:
|
||||
return '女'
|
||||
default:
|
||||
return '不限'
|
||||
}
|
||||
}
|
||||
|
||||
// 处理加入组局
|
||||
const handleJoin = () => {
|
||||
// 触发父组件的加入事件
|
||||
emit('join', reservationData.value)
|
||||
}
|
||||
const cancelJoin = async () => {
|
||||
var res = await showModalConfirm('提示', '确定要取消组局吗?')
|
||||
if (res) {
|
||||
emit('cancelJoin', reservationData.value)
|
||||
}
|
||||
}
|
||||
const exitJoin = async () => {
|
||||
var res = await showModalConfirm('提示', '确定要退出组局吗?')
|
||||
if (res) {
|
||||
emit('exitJoin', reservationData.value)
|
||||
}
|
||||
}
|
||||
// 打开用户信息弹窗
|
||||
const openUserPop = (user) => {
|
||||
// 触发父组件的用户信息弹窗事件
|
||||
emit('openUserPop', user)
|
||||
}
|
||||
|
||||
// 定义事件
|
||||
const emit = defineEmits(['join', 'openUserPop', 'cancelJoin', 'exitJoin'])
|
||||
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
show,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -11,6 +11,9 @@
|
|||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template #empty>
|
||||
<com-index-NoEmpty></com-index-NoEmpty>
|
||||
</template>
|
||||
|
||||
<view style="z-index: 100;margin-top:10rpx;height:532rpx;">
|
||||
<view style="width: 100%;width:100%;display:flex;justify-content: center;"
|
||||
|
|
@ -34,102 +37,12 @@
|
|||
</z-paging>
|
||||
|
||||
|
||||
<uni-popup ref="cardInfo" type="center">
|
||||
|
||||
<view class="column center"
|
||||
style="width: 680rpx; background-color: white; border-radius: 10rpx; padding: 20rpx;">
|
||||
|
||||
<text style="">预约信息</text>
|
||||
|
||||
<view class="column"
|
||||
style="width: 100%; height: 180rpx; background-color: #E3E2E2; margin-top: 20rpx; border-radius: 10rpx;">
|
||||
<view class="row" style="margin-top: 20rpx; align-items: center; margin-left: 20rpx;">
|
||||
<text style="font-size: 22rpx;">发起者</text>
|
||||
<image src=""
|
||||
style="width: 50rpx; height: 50rpx; background-color: antiquewhite; border-radius: 50%; margin-left: 20rpx;"
|
||||
mode=""></image>
|
||||
<text style="font-size: 20rpx; margin-left: 15rpx;">苏家辉</text>
|
||||
</view>
|
||||
<view class="row" style="margin-top: 30rpx; align-items: center; margin-left: 20rpx;">
|
||||
<text style="font-size: 22rpx;">参与者</text>
|
||||
|
||||
<view class="row" v-for="(item, index) in 3" :key="index" style="align-items: center;">
|
||||
|
||||
<view class="" style="position: relative; width: 50rpx; height: 50rpx; display: flex;">
|
||||
<image src="" @click="openUserPop()"
|
||||
style="width: 50rpx; height: 50rpx; background-color: antiquewhite; border-radius: 50%; margin-left: 20rpx; position: absolute;"
|
||||
mode=""></image>
|
||||
|
||||
<view class="center"
|
||||
style="width: 50rpx; height: 20rpx; background-color: #FFB7B7; position: absolute; left: 40%; top: -10rpx;">
|
||||
<text style="font-size: 10rpx;">黑名单</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<text
|
||||
style="font-size: 20rpx; margin-left: 30rpx; width: 100rpx; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">树下的胖子</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
|
||||
<view class="column"
|
||||
style="width: 100%; height: 180rpx; background-color: #E3E2E2; margin-top: 20rpx; border-radius: 10rpx;font-size: 22rpx;">
|
||||
|
||||
<view class="row" style="justify-content: space-between; margin: 20rpx;">
|
||||
<text>开始时间</text>
|
||||
<text>2025/08/27 15:30</text>
|
||||
</view>
|
||||
<view class="row" style="justify-content: space-between; margin: 0 20rpx;">
|
||||
<text>结束时间</text>
|
||||
<text>2025/08/27 17:30</text>
|
||||
</view>
|
||||
|
||||
<text style="margin: 30rpx 20rpx 0;">合计:2小时</text>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="column"
|
||||
style="width: 100%; background-color: #E3E2E2; margin-top: 20rpx; border-radius: 10rpx; font-size: 22rpx;">
|
||||
<text style="margin: 20rpx 20rpx 10rpx; font-size: 24rpx;">房间号:304号-大包,30元/小时</text>
|
||||
<text style="margin: 10rpx 20rpx;">人数:3人</text>
|
||||
<text style="margin: 10rpx 20rpx;">玩法类型:扑克</text>
|
||||
<text style="margin: 10rpx 20rpx;">具体规则:斗地主</text>
|
||||
<text style="margin: 10rpx 20rpx 20rpx;">补充信息:无</text>
|
||||
</view>
|
||||
|
||||
<view class="column"
|
||||
style="width: 100%; background-color: #E3E2E2; margin-top: 20rpx; border-radius: 10rpx; font-size: 22rpx;">
|
||||
<text style="margin: 20rpx 20rpx 10rpx; font-size: 24rpx;">是否禁烟:禁烟</text>
|
||||
<text style="margin: 10rpx 20rpx;">性别:不限</text>
|
||||
<text style="margin: 10rpx 20rpx 20rpx;">信誉:≧4.0</text>
|
||||
</view>
|
||||
|
||||
<view class="column"
|
||||
style="width: 100%; background-color: #E3E2E2; margin-top: 20rpx; border-radius: 10rpx; font-size: 22rpx;">
|
||||
<text style="margin: 20rpx 20rpx 10rpx; font-size: 24rpx;">鸽子费:0元</text>
|
||||
<text
|
||||
style="margin: 10rpx 20rpx 20rpx; color: #9F9F9F;">组局成功后若有牌友未赴约,其鸽子费平均分给其他牌友。组局成功或失败后鸽子费将全额返还。</text>
|
||||
</view>
|
||||
|
||||
<view class="row" style="width: 100%; margin-top: 30rpx;">
|
||||
<view class="center" @click="clasePop()"
|
||||
style="height: 80rpx; flex: 1; background-color: #9F9F9F; border-radius: 10rpx;">
|
||||
<text style="font-size: 24rpx; font-weight: 600; color: white;">关闭</text>
|
||||
</view>
|
||||
<view class="center"
|
||||
style="height: 80rpx; flex: 3; background-color: #1989FA; border-radius: 10rpx; margin-left: 20rpx;">
|
||||
<text style="font-size: 24rpx; font-weight: 600; color: white;">参与组局</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
<!-- 预约信息弹窗组件 -->
|
||||
<ReservationPopup ref="reservationPopup" @join="handleJoin" @openUserPop="openUserPop" />
|
||||
|
||||
|
||||
|
||||
<uni-popup ref="userInfo" type="center">
|
||||
<uni-popup ref="userInfo_popup" type="center">
|
||||
|
||||
<view class="column" style="width: 500rpx; background-color: white; padding: 20rpx;">
|
||||
|
||||
|
|
@ -185,6 +98,7 @@ import {
|
|||
} from 'vue'
|
||||
import zPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||
import MahjongCard from '@/components/index/MahjongCard.vue'
|
||||
import ReservationPopup from '@/components/com/index/ReservationPopup.vue'
|
||||
import {
|
||||
homeData,
|
||||
preloadHomeData,
|
||||
|
|
@ -195,6 +109,7 @@ import {
|
|||
getConfigData,
|
||||
preloadConfigData
|
||||
} from '@/common/server/config'
|
||||
import { userInfo, loadUserInfo } from '@/common/server/user'
|
||||
const statusBarHeight = ref(uni.getSystemInfoSync().statusBarHeight);
|
||||
const getBackgroundImg = () => {
|
||||
return {
|
||||
|
|
@ -217,8 +132,8 @@ const mockData = ref([]) // 模拟数据源
|
|||
|
||||
// 组件引用
|
||||
const pagePaging = ref(null)
|
||||
const cardInfo = ref(null)
|
||||
const userInfo = ref(null)
|
||||
const reservationPopup = ref(null)
|
||||
const userInfo_popup = ref(null)
|
||||
|
||||
// 初始化模拟数据
|
||||
const initMockData = () => {
|
||||
|
|
@ -277,20 +192,16 @@ const clearData = () => {
|
|||
}
|
||||
|
||||
// 弹窗相关方法
|
||||
const openPop = () => {
|
||||
cardInfo.value.open()
|
||||
}
|
||||
|
||||
const clasePop = () => {
|
||||
cardInfo.value.close()
|
||||
const openPop = (item) => {
|
||||
reservationPopup.value.show(item.data)
|
||||
}
|
||||
|
||||
const openUserPop = () => {
|
||||
userInfo.value.open()
|
||||
userInfo_popup.value.open()
|
||||
}
|
||||
|
||||
const closeUserPop = () => {
|
||||
userInfo.value.close()
|
||||
userInfo_popup.value.close()
|
||||
}
|
||||
|
||||
const onChange = (e) => {
|
||||
|
|
@ -306,6 +217,8 @@ const handleJoin = (item) => {
|
|||
icon: 'success',
|
||||
duration: 1500
|
||||
})
|
||||
// 关闭弹窗
|
||||
reservationPopup.value.close()
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
|
|
@ -317,6 +230,7 @@ onMounted(() => {
|
|||
onLoad(async () => {
|
||||
if (!homeData.value) preloadHomeData();
|
||||
if (!configData.value) preloadConfigData();
|
||||
await loadUserInfo();
|
||||
// initMockData();
|
||||
// initMockData();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,58 +1,34 @@
|
|||
<template>
|
||||
<view class="login-container">
|
||||
<!-- 背景装饰 -->
|
||||
<view class="bg-decoration">
|
||||
<!-- 云朵装饰 -->
|
||||
<view class="cloud cloud-1"></view>
|
||||
<view class="cloud cloud-2"></view>
|
||||
<view class="cloud cloud-3"></view>
|
||||
<!-- 小鸟装饰 -->
|
||||
<view class="bird bird-1"></view>
|
||||
<view class="bird bird-2"></view>
|
||||
</view>
|
||||
|
||||
<!-- 头部区域 -->
|
||||
<view class="header">
|
||||
<image src="@@:app/static/Logo.jpg" class="logo" mode="aspectFit"></image>
|
||||
<text class="welcome-text">欢迎登录</text>
|
||||
</view>
|
||||
|
||||
<!-- 登录表单 -->
|
||||
<view></view>
|
||||
<view class="login-form">
|
||||
<!-- 一键登录按钮 -->
|
||||
<view class="one-click-login">
|
||||
<button v-if="agreedToTerms && isMobile" class="quick-login-btn" :class="{ disabled: loading }"
|
||||
open-type="getPhoneNumber" @getphonenumber="mobileClickLogin">
|
||||
<text>{{ loading ? '登录中...' : '一键登录' }}</text>
|
||||
</button>
|
||||
<button v-if="!agreedToTerms" class="quick-login-btn" :class="{ disabled: loading }"
|
||||
@click="agreementClickLogin">
|
||||
<text>{{ loading ? '登录中...' : '一键登录' }}</text>
|
||||
</button>
|
||||
<button v-if="agreedToTerms && !isMobile" class="quick-login-btn" :class="{ disabled: loading }"
|
||||
@click="anonymousLoginClickLogin">
|
||||
<text>{{ loading ? '登录中...' : '一键登录' }}</text>
|
||||
</button>
|
||||
</view>
|
||||
<image src="@@:app/static/login/logo_5.png" style="width: 500rpx;height:500rpx;" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="login-button-container">
|
||||
|
||||
<!-- 用户协议同意 -->
|
||||
<view class="agreement-section">
|
||||
<view class="agreement-checkbox" @click="toggleAgreement">
|
||||
|
||||
<checkbox :value="agreedToTerms" :checked="agreedToTerms"
|
||||
style="transform:scale(0.5);margin-top: -8rpx;" />
|
||||
<text class="agreement-text">
|
||||
我已阅读并同意
|
||||
<text class="agreement-link" @click.stop="showUserAgreement">《用户协议》</text>
|
||||
和
|
||||
<text class="agreement-link" @click.stop="showPrivacyPolicy">《隐私政策》</text>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 暂不登录按钮 -->
|
||||
<view class="skip-login-btn" @click="skipLogin">
|
||||
<text>暂不登录</text>
|
||||
<button v-if="agreedToTerms && isMobile" class="login-button" :class="{ disabled: loading }"
|
||||
open-type="getPhoneNumber" @getphonenumber="mobileClickLogin">
|
||||
<view class="login-button-text">{{ (loading ? '登录中...' : '一键登录') }}</view>
|
||||
</button>
|
||||
<button v-if="!agreedToTerms" class="login-button" :class="{ disabled: loading }"
|
||||
@click="agreementClickLogin">
|
||||
<view class="login-button-text">{{ (loading ? '登录中...' : '一键登录') }}</view>
|
||||
</button>
|
||||
<button v-if="agreedToTerms && !isMobile" class="login-button" :class="{ disabled: loading }"
|
||||
@click="anonymousLoginClickLogin">
|
||||
<view class="login-button-text">{{ (loading ? '登录中...' : '一键登录') }}</view>
|
||||
</button>
|
||||
</view>
|
||||
<view class="agreement-container">
|
||||
<view class="agreement-checkbox" @click="toggleAgreement">
|
||||
<checkbox :value="agreedToTerms" :checked="agreedToTerms"
|
||||
style="transform:scale(0.5);margin-top: -8rpx;position: relative;left: 8px;" />
|
||||
<text class="agreement-text">
|
||||
我已阅读并同意
|
||||
<text class="agreement-link" @click.stop="showUserAgreement">《用户协议》</text>
|
||||
和
|
||||
<text class="agreement-link" @click.stop="showPrivacyPolicy">《隐私政策》</text>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -127,7 +103,6 @@ const mobileClickLogin = async (e) => {
|
|||
}
|
||||
const anonymousLoginClickLogin = async (e) => {
|
||||
console.log('aaa');
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
// 这里调用一键登录API(如运营商一键登录)
|
||||
|
|
@ -198,354 +173,78 @@ onLoad(() => {
|
|||
<style lang="scss" scoped>
|
||||
.login-container {
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(180deg, #87CEEB 0%, #98FB98 50%, #F0E68C 100%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: #F7F7F7;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
.login-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
padding-top: 400rpx;
|
||||
}
|
||||
|
||||
.login-button {
|
||||
width: 642rpx;
|
||||
height: 80rpx;
|
||||
background: #00AC4E;
|
||||
box-shadow: 0rpx 0rpx 10rpx 2rpx rgba(0, 0, 0, 0.25);
|
||||
border-radius: 16rpx 16rpx 16rpx 16rpx;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bg-decoration {
|
||||
.login-button-text {
|
||||
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 500;
|
||||
font-size: 30rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.login-button-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 280rpx;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
&.disabled {
|
||||
background: linear-gradient(135deg, #D3D3D3 0%, #A9A9A9 100%);
|
||||
color: #666;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 云朵样式
|
||||
.cloud {
|
||||
.agreement-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
border-radius: 50rpx;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.cloud-1 {
|
||||
width: 120rpx;
|
||||
height: 40rpx;
|
||||
top: 15%;
|
||||
left: 10%;
|
||||
|
||||
&::before {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
top: -25rpx;
|
||||
left: 10rpx;
|
||||
}
|
||||
|
||||
&::after {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
top: -30rpx;
|
||||
right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.cloud-2 {
|
||||
width: 100rpx;
|
||||
height: 35rpx;
|
||||
top: 25%;
|
||||
right: 15%;
|
||||
|
||||
&::before {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
top: -20rpx;
|
||||
left: 8rpx;
|
||||
}
|
||||
|
||||
&::after {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
top: -25rpx;
|
||||
right: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.cloud-3 {
|
||||
width: 80rpx;
|
||||
height: 30rpx;
|
||||
top: 70%;
|
||||
left: 20%;
|
||||
|
||||
&::before {
|
||||
width: 35rpx;
|
||||
height: 35rpx;
|
||||
top: -17rpx;
|
||||
left: 6rpx;
|
||||
}
|
||||
|
||||
&::after {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
top: -20rpx;
|
||||
right: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 小鸟样式
|
||||
.bird {
|
||||
position: absolute;
|
||||
width: 20rpx;
|
||||
height: 15rpx;
|
||||
background: #8B4513;
|
||||
border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 8rpx;
|
||||
height: 6rpx;
|
||||
background: #8B4513;
|
||||
border-radius: 50%;
|
||||
top: 2rpx;
|
||||
left: -5rpx;
|
||||
transform: rotate(-20deg);
|
||||
}
|
||||
|
||||
&.bird-1 {
|
||||
top: 20%;
|
||||
right: 25%;
|
||||
animation: fly 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
&.bird-2 {
|
||||
top: 60%;
|
||||
left: 15%;
|
||||
animation: fly 4s ease-in-out infinite reverse;
|
||||
}
|
||||
}
|
||||
|
||||
// 花朵样式
|
||||
.flower {
|
||||
position: absolute;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: radial-gradient(circle, #FFB6C1 30%, #FF69B4 70%);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 6rpx;
|
||||
height: 20rpx;
|
||||
background: #228B22;
|
||||
border-radius: 3rpx;
|
||||
bottom: -20rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
&.flower-1 {
|
||||
top: 40%;
|
||||
left: 8%;
|
||||
animation: sway 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
&.flower-2 {
|
||||
top: 80%;
|
||||
right: 10%;
|
||||
animation: sway 2.5s ease-in-out infinite reverse;
|
||||
}
|
||||
|
||||
&.flower-3 {
|
||||
top: 50%;
|
||||
right: 30%;
|
||||
animation: sway 3s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
|
||||
// 动画效果
|
||||
@keyframes fly {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: translateX(0) translateY(0);
|
||||
}
|
||||
|
||||
25% {
|
||||
transform: translateX(10rpx) translateY(-5rpx);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateX(20rpx) translateY(0);
|
||||
}
|
||||
|
||||
75% {
|
||||
transform: translateX(10rpx) translateY(5rpx);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sway {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
25% {
|
||||
transform: rotate(2deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
75% {
|
||||
transform: rotate(-2deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shine {
|
||||
0% {
|
||||
transform: translateX(-100%) translateY(-100%) rotate(45deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(100%) translateY(100%) rotate(45deg);
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 80rpx;
|
||||
|
||||
.logo {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 30rpx;
|
||||
border: 8rpx solid #FFE4B5;
|
||||
box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.app-name {
|
||||
display: block;
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #8B4513;
|
||||
margin-bottom: 20rpx;
|
||||
text-shadow: 2rpx 2rpx 4rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.welcome-text {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #228B22;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form {
|
||||
padding: 0 60rpx;
|
||||
bottom: 180rpx;
|
||||
width: 100%;
|
||||
max-width: 600rpx;
|
||||
}
|
||||
|
||||
.one-click-login {
|
||||
margin: 40rpx 0;
|
||||
.agreement-text {
|
||||
|
||||
.quick-login-btn {
|
||||
background: linear-gradient(135deg, #F36903 0%, #E55A00 100%);
|
||||
color: white;
|
||||
height: 100rpx;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 8rpx 20rpx rgba(243, 105, 3, 0.3);
|
||||
border: 4rpx solid #FFE4B5;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transform: rotate(45deg);
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
&:active::before {
|
||||
animation: shine 0.6s ease-in-out;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background: linear-gradient(135deg, #D3D3D3 0%, #A9A9A9 100%);
|
||||
color: #666;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.quick-login-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
}
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
color: #515151;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.agreement-section {
|
||||
margin: 30rpx 0;
|
||||
|
||||
.agreement-checkbox {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
||||
.checkbox {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
margin-right: 15rpx;
|
||||
margin-top: 5rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.agreement-text {
|
||||
font-size: 24rpx;
|
||||
color: #8B4513;
|
||||
line-height: 1.5;
|
||||
|
||||
.agreement-link {
|
||||
color: blue;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skip-login-btn {
|
||||
text-align: center;
|
||||
margin: 40rpx 0;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #8B4513;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
}
|
||||
.agreement-link {
|
||||
color: #00AC4E;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user