3333
This commit is contained in:
parent
a8f03063d8
commit
53cb4a7b89
|
|
@ -13,4 +13,9 @@ export const preloadConfigData = async () => {
|
|||
configData.value = {
|
||||
config: res
|
||||
};
|
||||
console.log("configData.value",configData.value);
|
||||
};
|
||||
|
||||
export const getConfigData = () => {
|
||||
return configData.value;
|
||||
}
|
||||
1
components.d.ts
vendored
1
components.d.ts
vendored
|
|
@ -8,6 +8,7 @@ export {}
|
|||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
MahjongCard: typeof import('./components/index/MahjongCard.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
}
|
||||
|
|
|
|||
309
components/index/MahjongCard.vue
Normal file
309
components/index/MahjongCard.vue
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
<template>
|
||||
<view class="grid-item" @click="handleCardClick">
|
||||
<uni-card margin="0px" padding="0px" spacing="0px">
|
||||
<view
|
||||
style="position:absolute;top:0;right:0;width:100%; background: linear-gradient(to bottom, rgba(255, 108, 0, 0.9), rgba(255, 108, 0, 0.7));box-shadow: 0 2px 8px rgba(235,135,58, 0.3);z-index:999;border-radius:4px 4px 0 0;font-size:24rpx;color:#fff;font-weight: 500; opacity: 0.7;">
|
||||
<text style="padding-left:10rpx;">{{ item.status }}</text>
|
||||
</view>
|
||||
<view class="item-content column">
|
||||
<!-- 麻将桌区域 -->
|
||||
<view class="mahjong-table">
|
||||
<!-- 九宫格布局 -->
|
||||
<view style="width:300rpx;height: 300rpx;">
|
||||
<view class="nine-grid-container">
|
||||
<!-- 第一行 -->
|
||||
<view class="grid-cell"></view>
|
||||
<view class="grid-cell" :class="getCellClass(0)">
|
||||
<view v-if="getPlayerAtPosition(0)" class="player-avatar">
|
||||
<image :src="getPlayerAtPosition(0).avatar || ''" class="avatar-img"></image>
|
||||
</view>
|
||||
<view v-else-if="canJoinAtPosition(0)" class="join-button" @click.stop="handleJoin">
|
||||
<text class="join-text">+</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid-cell"></view>
|
||||
|
||||
<!-- 第二行 -->
|
||||
<view class="grid-cell" :class="getCellClass(1)">
|
||||
<view v-if="getPlayerAtPosition(1)" class="player-avatar">
|
||||
<image :src="getPlayerAtPosition(1).avatar || ''" class="avatar-img"></image>
|
||||
</view>
|
||||
<view v-else-if="canJoinAtPosition(1)" class="join-button" @click.stop="handleJoin">
|
||||
<text class="join-text">+</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid-cell center-cell">
|
||||
<!-- 麻将桌背景图 -->
|
||||
<image src="/static/9.png" class="table-bg" mode=""></image>
|
||||
</view>
|
||||
<view class="grid-cell" :class="getCellClass(2)">
|
||||
<view v-if="getPlayerAtPosition(2)" class="player-avatar">
|
||||
<image :src="getPlayerAtPosition(2).avatar || ''" class="avatar-img"></image>
|
||||
</view>
|
||||
<view v-else-if="canJoinAtPosition(2)" class="join-button" @click.stop="handleJoin">
|
||||
<text class="join-text">+</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 第三行 -->
|
||||
<view class="grid-cell"></view>
|
||||
<view class="grid-cell" :class="getCellClass(3)">
|
||||
<view v-if="getPlayerAtPosition(3)" class="player-avatar">
|
||||
<image :src="getPlayerAtPosition(3).avatar || ''" class="avatar-img"></image>
|
||||
</view>
|
||||
<view v-else-if="canJoinAtPosition(3)" class="join-button" @click.stop="handleJoin">
|
||||
<text class="join-text">+</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid-cell"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 信息区域 -->
|
||||
<view class="info-section">
|
||||
<text class="info-text" style="font-size: 26rpx;font-weight: 600;color: #FA690B;">{{
|
||||
item.description }}</text>
|
||||
<text class="info-text" style="margin-top: -7rpx;">{{ item.room }}</text>
|
||||
<text class="info-text" style="font-size: 22rpx;font-weight: 600;line-height:28rpx;">2025-09-06</text>
|
||||
<text class="info-text" style="font-size: 22rpx;font-weight: 600;line-height:28rpx;">{{ item.time }}</text>
|
||||
<text class="info-text" style="color:#FA690B;line-height:30rpx;margin-top:6rpx;">{{ item.requirements }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps, defineEmits, computed } from 'vue'
|
||||
|
||||
// 定义 props
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({
|
||||
id: '',
|
||||
status: '',
|
||||
description: '',
|
||||
time: '',
|
||||
room: '',
|
||||
requirements: '',
|
||||
personCount: 4,//总人数
|
||||
joinPerson: [
|
||||
{
|
||||
id: 1,
|
||||
name: '张三',
|
||||
avatar: '',
|
||||
phone: '',
|
||||
}
|
||||
],//已加入人
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 定义 emits
|
||||
const emit = defineEmits(['click', 'join'])
|
||||
|
||||
// 计算属性:获取玩家位置布局
|
||||
const playerPositions = computed(() => {
|
||||
const { personCount, joinPerson } = props.item
|
||||
const joinedCount = joinPerson.length
|
||||
|
||||
// 根据总人数确定布局
|
||||
if (personCount === 2) {
|
||||
// 2人局:第二行左边和右边
|
||||
return {
|
||||
positions: [null, joinPerson[0] || null, joinPerson[1] || null, null],
|
||||
joinPositions: [null, !joinPerson[0], !joinPerson[1], null]
|
||||
}
|
||||
} else if (personCount === 3) {
|
||||
// 3人局:第一行中间、第二行左边和右边
|
||||
return {
|
||||
positions: [joinPerson[2] || null, joinPerson[0] || null, joinPerson[1] || null, null],
|
||||
joinPositions: [!joinPerson[2], !joinPerson[0], !joinPerson[1], null]
|
||||
}
|
||||
} else {
|
||||
// 4人局:标准布局(上、左、右、下)
|
||||
return {
|
||||
positions: [
|
||||
joinPerson[2] || null, // 第一行中间
|
||||
joinPerson[0] || null, // 第二行左边
|
||||
joinPerson[1] || null, // 第二行右边
|
||||
joinPerson[3] || null // 第三行中间
|
||||
],
|
||||
joinPositions: [
|
||||
!joinPerson[2], // 第一行中间
|
||||
!joinPerson[0], // 第二行左边
|
||||
!joinPerson[1], // 第二行右边
|
||||
!joinPerson[3] // 第三行中间
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 获取指定位置的玩家
|
||||
const getPlayerAtPosition = (position) => {
|
||||
return playerPositions.value.positions[position]
|
||||
}
|
||||
|
||||
// 判断指定位置是否可以加入
|
||||
const canJoinAtPosition = (position) => {
|
||||
const { personCount, joinPerson } = props.item
|
||||
const joinedCount = joinPerson.length
|
||||
|
||||
// 如果已满员,不能加入
|
||||
if (joinedCount >= personCount) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 直接使用计算属性中的 joinPositions
|
||||
return playerPositions.value.joinPositions[position]
|
||||
}
|
||||
|
||||
// 获取单元格样式类
|
||||
const getCellClass = (position) => {
|
||||
if (getPlayerAtPosition(position)) {
|
||||
return 'player-cell'
|
||||
} else if (canJoinAtPosition(position)) {
|
||||
return 'join-cell'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
// 处理卡片点击事件
|
||||
const handleCardClick = () => {
|
||||
emit('click', props.item)
|
||||
}
|
||||
|
||||
// 处理加入按钮点击事件
|
||||
const handleJoin = () => {
|
||||
emit('join', props.item)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item-content {
|
||||
height: 540rpx;
|
||||
color: white;
|
||||
border-radius: 10rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.mahjong-table {
|
||||
width: 100%;
|
||||
background-color: #D4D4D4;
|
||||
border-radius: 10rpx 10rpx 0 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
position: absolute;
|
||||
left: 15rpx;
|
||||
top: 15rpx;
|
||||
font-size: 16rpx;
|
||||
color: black;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* 九宫格容器 */
|
||||
.nine-grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr 1fr;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 网格单元格 */
|
||||
.grid-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 玩家头像单元格 */
|
||||
.player-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 中心单元格(麻将桌) */
|
||||
.center-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 加入按钮单元格 */
|
||||
.join-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 麻将桌背景图 */
|
||||
.table-bg {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
|
||||
/* 玩家头像 */
|
||||
.player-avatar {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.avatar-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: aqua;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* 加入按钮 */
|
||||
.join-button {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.join-button:hover {
|
||||
transform: scale(1.1);
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.join-text {
|
||||
color: black;
|
||||
font-size: 24rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
padding: 10rpx;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
font-size: 24rpx;
|
||||
color: black;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -43,7 +43,9 @@
|
|||
/* ios打包配置 */
|
||||
"ios" : {},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {}
|
||||
"sdkConfigs" : {
|
||||
"oauth" : {}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,13 @@
|
|||
"navigationBarTitleText": "",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/me/login",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
|
|
|||
|
|
@ -1,77 +1,31 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
|
||||
|
||||
<view class="content" :style="getBackgroundImg()">
|
||||
<!-- 使用 z-paging 组件实现分页功能 -->
|
||||
<z-paging ref="paging" v-model="dataList" @query="queryList" :refresher-enabled="true"
|
||||
<z-paging ref="pagePaging" v-model="dataList" @query="queryList" :refresher-enabled="true"
|
||||
:loading-more-enabled="true" :auto="true" :empty-view-text="'暂无麻将局数据'" :empty-view-img="'/static/empty.png'"
|
||||
:refresher-threshold="80" :loading-more-threshold="50" style="flex: 1; width: 95%; margin-top: 10rpx;">
|
||||
<view style="z-index: 100;position: sticky;top :0;">
|
||||
<view class="" style="width: 100%; height: 386rpx; background-color: antiquewhite;">
|
||||
<swiper class="img-swiper" :indicator-dots="false" circular autoplay interval="3000">
|
||||
<swiper-item v-for="(item, index) in imgList" :key="index">
|
||||
<image :src="item" mode="widthFix" class="slide-img"></image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view :style="{ height: statusBarHeight + 'px' }" style="background-color: #fff;" class="status-bar">
|
||||
</view>
|
||||
<view style="height: 10rpx;background-color: #fff;"></view>
|
||||
</view>
|
||||
<view class="grid-container">
|
||||
<view class="grid-item" v-for="(item, index) in dataList" :key="index" @click="openPop()">
|
||||
<view class="item-content column">
|
||||
|
||||
<view class="center"
|
||||
style="width: 100%; height: 400rpx; background-color: #D4D4D4; border-radius: 10rpx 10rpx 0 0; position: relative;">
|
||||
|
||||
<text
|
||||
style="position: absolute; left: 15rpx; top: 15rpx; font-size: 16rpx; color: black;">{{
|
||||
item.status }}</text>
|
||||
|
||||
<image src="/static/9.png" style="width: 100rpx; height: 100rpx; position: absolute;"
|
||||
mode=""></image>
|
||||
|
||||
<view class=""
|
||||
style="width: 60rpx; height: 60rpx; background-color: white; position: absolute; top: 50rpx; border-radius: 50%;">
|
||||
<image src=""
|
||||
style="width: 100%; height: 100%; background-color: aqua; border-radius: 50%;">
|
||||
</image>
|
||||
</view>
|
||||
|
||||
<view class=""
|
||||
style="width: 60rpx; height: 60rpx; background-color: white; position: absolute; left: 30rpx; border-radius: 50%;">
|
||||
<image src=""
|
||||
style="width: 100%; height: 100%; background-color: aqua; border-radius: 50%;">
|
||||
</image>
|
||||
</view>
|
||||
|
||||
<view class=""
|
||||
style="width: 60rpx; height: 60rpx; background-color: white; position: absolute; right: 30rpx; border-radius: 50%;">
|
||||
<image src=""
|
||||
style="width: 100%; height: 100%; background-color: aqua; border-radius: 50%;">
|
||||
</image>
|
||||
</view>
|
||||
|
||||
<view class="center"
|
||||
style="width: 60rpx; height: 60rpx; background-color: white; position: absolute; bottom: 50rpx; border-radius: 50%;">
|
||||
<!-- <image src="" style="width: 100%; height: 100%; border-radius: 50%;"></image> -->
|
||||
<text style="color: black;">+</text>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
|
||||
<text style="font-size: 24rpx; color: black; margin-top: 10rpx; margin-left: 10rpx;">{{
|
||||
item.description }}</text>
|
||||
<text style="font-size: 24rpx; color: black; margin-top: 10rpx; margin-left: 10rpx;">{{
|
||||
item.time }}</text>
|
||||
<text style="font-size: 24rpx; color: black; margin-top: 10rpx; margin-left: 10rpx;">{{
|
||||
item.room }}</text>
|
||||
<text style="font-size: 24rpx; color: black; margin-top: 10rpx; margin-left: 10rpx;">{{
|
||||
item.requirements }}</text>
|
||||
|
||||
|
||||
<view style="z-index: 100;margin-top:10rpx;"
|
||||
v-if="homeData != null && homeData.advertList != null && homeData.advertList.length > 0">
|
||||
<view style="width: 100%;width:100%;display:flex;justify-content: center;">
|
||||
<view class="" style="width:97%; height: 386rpx;border-radius: 25rpx;">
|
||||
<swiper class="img-swiper" :indicator-dots="false" circular autoplay interval="3000">
|
||||
<swiper-item v-for="(item, index) in homeData.advertList" :key="index">
|
||||
<image :src="item.imageUrl" mode="scaleToFill" class="slide-img"
|
||||
style="border-radius:25rpx;"> </image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
<view style="height: 10rpx;"></view>
|
||||
</view>
|
||||
<view class="grid-container">
|
||||
<MahjongCard v-for="(item, index) in dataList" :key="index" :item="item" @click="openPop"
|
||||
@join="handleJoin" />
|
||||
</view>
|
||||
</z-paging>
|
||||
|
||||
|
|
@ -124,12 +78,12 @@
|
|||
<text>开始时间</text>
|
||||
<text>2025/08/27 15:30</text>
|
||||
</view>
|
||||
<view class="row" style="justify-content: space-between; margin: 0 20rpx; 0">
|
||||
<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>
|
||||
<text style="margin: 30rpx 20rpx 0;">合计:2小时</text>
|
||||
|
||||
</view>
|
||||
|
||||
|
|
@ -220,136 +174,189 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import zPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
onMounted
|
||||
} from 'vue'
|
||||
import zPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
|
||||
import MahjongCard from '@/components/index/MahjongCard.vue'
|
||||
import {
|
||||
homeData,
|
||||
preloadHomeData
|
||||
} from '@/common/server/index'
|
||||
import {
|
||||
configData,
|
||||
getConfigData,
|
||||
preloadConfigData
|
||||
} from '@/common/server/config'
|
||||
const statusBarHeight = ref(uni.getSystemInfoSync().statusBarHeight);
|
||||
const getBackgroundImg = () => {
|
||||
return {
|
||||
background: `url(${configData.value.config.defaultImage}) 100% 100% `,
|
||||
backgroundSize: '100% 100%'
|
||||
};
|
||||
}
|
||||
// 响应式数据
|
||||
const title = ref('Hello')
|
||||
const imgList = ref([1, 2, 3, 4, 5])
|
||||
const dataList = ref([]) // 分页数据列表
|
||||
const rateValue = ref(3.5)
|
||||
const mockData = ref([]) // 模拟数据源
|
||||
|
||||
// 响应式数据
|
||||
const title = ref('Hello')
|
||||
const imgList = ref([1, 2, 3, 4, 5])
|
||||
const dataList = ref([]) // 分页数据列表
|
||||
const rateValue = ref(3.5)
|
||||
const mockData = ref([]) // 模拟数据源
|
||||
// 组件引用
|
||||
const pagePaging = ref(null)
|
||||
const cardInfo = ref(null)
|
||||
const userInfo = ref(null)
|
||||
|
||||
// 组件引用
|
||||
const paging = ref(null)
|
||||
const cardInfo = ref(null)
|
||||
const userInfo = ref(null)
|
||||
// 初始化模拟数据
|
||||
const initMockData = () => {
|
||||
mockData.value = []
|
||||
for (let i = 1; i <= 50; i++) {
|
||||
// 随机生成不同人数的麻将局
|
||||
const personCount = [2, 3, 4][Math.floor(Math.random() * 3)]
|
||||
const joinedCount = Math.floor(Math.random() * (personCount + 1))
|
||||
|
||||
// 初始化模拟数据
|
||||
const initMockData = () => {
|
||||
mockData.value = []
|
||||
for (let i = 1; i <= 50; i++) {
|
||||
mockData.value.push({
|
||||
id: i,
|
||||
title: `麻将局 ${i}`,
|
||||
status: '组局中',
|
||||
time: '20:00 ~ 04:30 共8小时30分钟',
|
||||
room: '304包厢-大包,4人',
|
||||
description: '休闲局,随便来',
|
||||
requirements: '不可吸烟、性别不限、信誉≧4.0'
|
||||
// 生成已加入的玩家
|
||||
const joinPerson = []
|
||||
for (let j = 0; j < joinedCount; j++) {
|
||||
joinPerson.push({
|
||||
id: j + 1,
|
||||
name: `玩家${j + 1}`,
|
||||
avatar: '',
|
||||
phone: `138****${String(j + 1).padStart(4, '0')}`
|
||||
})
|
||||
}
|
||||
|
||||
mockData.value.push({
|
||||
id: i,
|
||||
title: `麻将局 ${i}`,
|
||||
status: joinedCount >= personCount ? '已满员' : '组局中',
|
||||
time: '20:00 ~ 04:30 共8小时30分钟',
|
||||
room: `304包厢-大包,${personCount}人`,
|
||||
description: '休闲局,随便来',
|
||||
requirements: '麻将、斗地主、不可吸烟、性别不限、信誉≧4.0',
|
||||
personCount: personCount,
|
||||
joinPerson: joinPerson
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 分页查询方法
|
||||
const queryList = (pageNo, pageSize) => {
|
||||
console.log(`加载第${pageNo}页,每页${pageSize}条数据`)
|
||||
// 分页查询方法
|
||||
const queryList = (pageNo, pageSize) => {
|
||||
console.log(`加载第${pageNo}页,每页${pageSize}条数据`)
|
||||
|
||||
// 模拟网络请求延迟
|
||||
setTimeout(() => {
|
||||
const startIndex = (pageNo - 1) * pageSize
|
||||
const endIndex = startIndex + pageSize
|
||||
const pageData = mockData.value.slice(startIndex, endIndex)
|
||||
// 模拟网络请求延迟
|
||||
setTimeout(() => {
|
||||
const startIndex = (pageNo - 1) * pageSize
|
||||
const endIndex = startIndex + pageSize
|
||||
const pageData = mockData.value.slice(startIndex, endIndex)
|
||||
|
||||
// 调用 z-paging 的完成方法
|
||||
paging.value.complete(pageData)
|
||||
// 调用 z-paging 的完成方法
|
||||
pagePaging.value.complete(pageData)
|
||||
|
||||
// 如果是第一页,显示加载完成提示
|
||||
if (pageNo === 1) {
|
||||
uni.showToast({
|
||||
title: '刷新成功',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
})
|
||||
}
|
||||
}, 100) // 模拟1秒网络延迟
|
||||
}
|
||||
// 如果是第一页,显示加载完成提示
|
||||
// if (pageNo === 1) {
|
||||
// uni.showToast({
|
||||
// title: '刷新成功',
|
||||
// icon: 'success',
|
||||
// duration: 1500
|
||||
// })
|
||||
// }
|
||||
}, 100) // 模拟1秒网络延迟
|
||||
}
|
||||
|
||||
// 手动刷新
|
||||
const refreshData = () => {
|
||||
paging.value.reload()
|
||||
}
|
||||
// 手动刷新
|
||||
const refreshData = () => {
|
||||
pagePaging.value.reload()
|
||||
}
|
||||
|
||||
// 清空数据
|
||||
const clearData = () => {
|
||||
paging.value.clear()
|
||||
}
|
||||
// 清空数据
|
||||
const clearData = () => {
|
||||
pagePaging.value.clear()
|
||||
}
|
||||
|
||||
// 弹窗相关方法
|
||||
const openPop = () => {
|
||||
cardInfo.value.open()
|
||||
}
|
||||
// 弹窗相关方法
|
||||
const openPop = () => {
|
||||
cardInfo.value.open()
|
||||
}
|
||||
|
||||
const clasePop = () => {
|
||||
cardInfo.value.close()
|
||||
}
|
||||
const clasePop = () => {
|
||||
cardInfo.value.close()
|
||||
}
|
||||
|
||||
const openUserPop = () => {
|
||||
userInfo.value.open()
|
||||
}
|
||||
const openUserPop = () => {
|
||||
userInfo.value.open()
|
||||
}
|
||||
|
||||
const closeUserPop = () => {
|
||||
userInfo.value.close()
|
||||
}
|
||||
const closeUserPop = () => {
|
||||
userInfo.value.close()
|
||||
}
|
||||
|
||||
const onChange = (e) => {
|
||||
console.log('rate发生改变:' + JSON.stringify(e))
|
||||
}
|
||||
const onChange = (e) => {
|
||||
console.log('rate发生改变:' + JSON.stringify(e))
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
// 初始化模拟数据
|
||||
initMockData()
|
||||
// 处理加入麻将局事件
|
||||
const handleJoin = (item) => {
|
||||
console.log('加入麻将局:', item)
|
||||
// 这里可以添加加入逻辑,比如调用API
|
||||
uni.showToast({
|
||||
title: '加入成功',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
})
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
// 初始化模拟数据
|
||||
initMockData()
|
||||
})
|
||||
|
||||
onLoad(async () => {
|
||||
if (!homeData.value) preloadHomeData();
|
||||
if (!configData.value) preloadConfigData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.content {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
.img-swiper {
|
||||
width: 100%;
|
||||
height: 386rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.slide-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
background-color: aqua;
|
||||
}
|
||||
.img-swiper {
|
||||
width: 100%;
|
||||
height: 386rpx;
|
||||
}
|
||||
|
||||
/* 网格容器 - 2列布局 */
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
/* 2列,每列宽度相等 */
|
||||
gap: 20rpx;
|
||||
/* 网格间距(行列间距相同) */
|
||||
padding: 0 10rpx;
|
||||
}
|
||||
.slide-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
/* 网格项内容 */
|
||||
.item-content {
|
||||
height: 630rpx;
|
||||
background-color: #E6E6E6;
|
||||
color: white;
|
||||
border-radius: 10rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 网格容器 - 2列布局 */
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
/* 2列,每列宽度相等 */
|
||||
gap: 20rpx;
|
||||
/* 网格间距(行列间距相同) */
|
||||
padding: 0 15rpx;
|
||||
}
|
||||
|
||||
/* 网格项内容 */
|
||||
.item-content {
|
||||
height: 630rpx;
|
||||
// background-color: #E6E6E6;
|
||||
color: white;
|
||||
border-radius: 10rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
</style>
|
||||
465
pages/me/login.vue
Normal file
465
pages/me/login.vue
Normal file
|
|
@ -0,0 +1,465 @@
|
|||
<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 class="login-form">
|
||||
<!-- 一键登录按钮 -->
|
||||
<view class="one-click-login">
|
||||
<view class="quick-login-btn" @click="handleOneClickLogin" :class="{ disabled: loading }">
|
||||
<text>{{ loading ? '登录中...' : '一键登录' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 用户协议同意 -->
|
||||
<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>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
|
||||
// 响应式数据
|
||||
const loading = ref(false)
|
||||
const agreedToTerms = ref(false)
|
||||
|
||||
// 方法
|
||||
const toggleAgreement = () => {
|
||||
agreedToTerms.value = !agreedToTerms.value
|
||||
}
|
||||
|
||||
const handleOneClickLogin = async () => {
|
||||
if (loading.value) return
|
||||
|
||||
if (!agreedToTerms.value) {
|
||||
uni.showToast({
|
||||
title: '请先同意用户协议和隐私政策',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
// 这里调用一键登录API(如运营商一键登录)
|
||||
// const response = await oneClickLoginApi()
|
||||
|
||||
// 模拟一键登录成功
|
||||
await new Promise(resolve => setTimeout(resolve, 2000))
|
||||
|
||||
// 生成随机手机号用于演示
|
||||
const randomPhone = '138' + Math.floor(Math.random() * 100000000).toString().padStart(8, '0')
|
||||
|
||||
// 保存登录状态
|
||||
uni.setStorageSync('userInfo', {
|
||||
phone: randomPhone,
|
||||
nickname: '用户' + randomPhone.slice(-4),
|
||||
uid: 'U' + Date.now(),
|
||||
avatar: '@@:app/nouser.png',
|
||||
rating: 4.6,
|
||||
reputation: 5.0,
|
||||
cardQuality: 4.5,
|
||||
cardSkill: 4.5,
|
||||
pigeonCount: 0
|
||||
})
|
||||
|
||||
uni.showToast({
|
||||
title: '登录成功',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
// 延迟跳转
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
|
||||
} catch (error) {
|
||||
console.error('一键登录失败:', error)
|
||||
uni.showToast({
|
||||
title: '登录失败,请重试',
|
||||
icon: 'error'
|
||||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const skipLogin = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
const showUserAgreement = () => {
|
||||
uni.showModal({
|
||||
title: '用户协议',
|
||||
content: '这里是用户协议的内容...\n\n1. 用户权利和义务\n2. 服务条款\n3. 免责声明\n4. 其他条款',
|
||||
showCancel: false,
|
||||
confirmText: '我知道了'
|
||||
})
|
||||
}
|
||||
|
||||
const showPrivacyPolicy = () => {
|
||||
uni.showModal({
|
||||
title: '隐私政策',
|
||||
content: '这里是隐私政策的内容...\n\n1. 信息收集\n2. 信息使用\n3. 信息保护\n4. 信息共享',
|
||||
showCancel: false,
|
||||
confirmText: '我知道了'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login-container {
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(180deg, #87CEEB 0%, #98FB98 50%, #F0E68C 100%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bg-decoration {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// 云朵样式
|
||||
.cloud {
|
||||
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;
|
||||
width: 100%;
|
||||
max-width: 600rpx;
|
||||
}
|
||||
|
||||
.one-click-login {
|
||||
margin: 40rpx 0;
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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: #FF69B4;
|
||||
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;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,49 +1,51 @@
|
|||
<template>
|
||||
<view class="content column">
|
||||
|
||||
<view class="row" style="margin-top: 150rpx; align-items: center; margin-left: 40rpx;">
|
||||
<image src="" style="width: 80rpx; height: 80rpx; background-color: aquamarine; border-radius: 50%;"
|
||||
mode=""></image>
|
||||
|
||||
<!-- <text style="margin-left: 50rpx; font-size: 24rpx;">点击登录</text> -->
|
||||
|
||||
<view class="column" style="margin-left: 50rpx; font-size: 24rpx;">
|
||||
|
||||
<view class="row" @click="toEditInfo()" style="align-items: center;">
|
||||
<text>树下的胖子</text>
|
||||
<image src="/static/edit_info.png" style="width: 30rpx; height: 30rpx; margin-left: 10rpx;" mode="">
|
||||
</image>
|
||||
</view>
|
||||
<text style="margin-top: 10rpx;">UID:123456</text>
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view v-if="loading" class="loading-container">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="column" @click="openPop()"
|
||||
<view class="row" style="margin-top: 150rpx; align-items: center; margin-left: 40rpx;">
|
||||
<image :src="userInfo.avatar" style="width: 80rpx; height: 80rpx; border-radius: 50%;" mode=""></image>
|
||||
<view class="column" style="margin-left: 50rpx; font-size: 24rpx;">
|
||||
<view class="row" @click="toEditInfo()" style="align-items: center;">
|
||||
<text>{{ userInfo.nickname }}</text>
|
||||
</view>
|
||||
<text v-if="userInfo.uid" style="margin-top: 10rpx;">UID:{{ userInfo.uid }}</text>
|
||||
<text v-else style="margin-top: 10rpx; color: #999;" @click="toLogin()">点击登录</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="column" @click="currentAppointment ? openPop() : null"
|
||||
style="width: 90%; border-radius: 10rpx; background-color: #F2F3F5; margin: 40rpx auto 0;">
|
||||
|
||||
<!-- <view class="row" style="align-items: center; margin: 20rpx;">
|
||||
<!-- 无预约状态 -->
|
||||
<view v-if="!currentAppointment" class="row" style="align-items: center; margin: 20rpx;">
|
||||
<image src="/static/no_content.png" style="width: 150rpx; height: 150rpx;" mode=""></image>
|
||||
<text style="margin-left: 40rpx;">当前没有预约</text>
|
||||
</view> -->
|
||||
|
||||
<text style="font-size: 24rpx; margin-left: 20rpx; margin-top: 25rpx;">2025/08/13 20:00 ~ 2025/08/13 22:00
|
||||
共2小时</text>
|
||||
<text style="font-size: 24rpx; margin-left: 20rpx; margin-top: 10rpx;">803包厢-大包</text>
|
||||
|
||||
<view class="row"
|
||||
style="font-size: 24rpx; margin-left: 20rpx; margin-top: 20rpx; align-items: center; margin-bottom: 20rpx;">
|
||||
<text>已预约人员</text>
|
||||
<image src="" v-for="(item,index) in 3"
|
||||
style="width: 30rpx; height: 30rpx; background-color: antiquewhite; border-radius: 50%; margin-left: 10rpx;"
|
||||
mode=""></image>
|
||||
|
||||
<text style="font-size: 24rpx; margin-left: auto; margin-right: 20rpx;">查看详情</text>
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 有预约状态 -->
|
||||
<template v-else>
|
||||
<text style="font-size: 24rpx; margin-left: 20rpx; margin-top: 25rpx;">
|
||||
{{ currentAppointment.startTime }} ~ {{ currentAppointment.endTime }} 共{{
|
||||
currentAppointment.duration }}
|
||||
</text>
|
||||
<text style="font-size: 24rpx; margin-left: 20rpx; margin-top: 10rpx;">{{ currentAppointment.room
|
||||
}}</text>
|
||||
|
||||
<view class="row"
|
||||
style="font-size: 24rpx; margin-left: 20rpx; margin-top: 20rpx; align-items: center; margin-bottom: 20rpx;">
|
||||
<text>已预约人员</text>
|
||||
<image v-for="(participant, index) in currentAppointment.participants" :key="index"
|
||||
:src="participant.avatar || ''"
|
||||
style="width: 30rpx; height: 30rpx; background-color: antiquewhite; border-radius: 50%; margin-left: 10rpx;"
|
||||
mode=""></image>
|
||||
|
||||
<text style="font-size: 24rpx; margin-left: auto; margin-right: 20rpx;">查看详情</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
|
||||
|
||||
|
|
@ -52,44 +54,48 @@
|
|||
|
||||
<view class="row" style="align-items: center; margin-top: 30rpx; margin-left: 20rpx;">
|
||||
<text style="font-size: 24rpx;">我的评分</text>
|
||||
<text style="font-size: 34rpx; color: #ED3535; margin-left: 10rpx;">4.6</text>
|
||||
<text v-if="userInfo.rating > 0" style="font-size: 34rpx; color: #ED3535; margin-left: 10rpx;">{{
|
||||
userInfo.rating }}</text>
|
||||
<text v-else style="font-size: 24rpx; color: #999; margin-left: 10rpx;">未评分</text>
|
||||
<text style="font-size: 24rpx; margin-left: 180rpx;">我的信誉</text>
|
||||
<text style="font-size: 34rpx; color: #ED3535; margin-left: 10rpx;">5.0</text>
|
||||
<text v-if="userInfo.reputation > 0" style="font-size: 34rpx; color: #ED3535; margin-left: 10rpx;">{{
|
||||
userInfo.reputation }}</text>
|
||||
<text v-else style="font-size: 24rpx; color: #999; margin-left: 10rpx;">未评级</text>
|
||||
</view>
|
||||
|
||||
<view class="row" style="align-items: center; margin-top: 20rpx; margin-left: 20rpx;">
|
||||
<text style="font-size: 24rpx;">牌品</text>
|
||||
<uni-rate style="margin-left: 20rpx;" :readonly="true" v-model="rateValue" />
|
||||
<uni-rate style="margin-left: 20rpx;" :readonly="true" v-model="userInfo.cardQuality" />
|
||||
</view>
|
||||
|
||||
<view class="row" style="align-items: center; margin-top: 20rpx; margin-left: 20rpx;">
|
||||
<text style="font-size: 24rpx;">牌技</text>
|
||||
<uni-rate style="margin-left: 20rpx;" :readonly="true" v-model="rateValue" />
|
||||
<uni-rate style="margin-left: 20rpx;" :readonly="true" v-model="userInfo.cardSkill" />
|
||||
</view>
|
||||
|
||||
<text style="font-size: 24rpx; margin: 20rpx;">鸽子数 0次</text>
|
||||
<text style="font-size: 24rpx; margin: 20rpx;">鸽子数 {{ userInfo.pigeonCount }}次</text>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="row" style="width: 90%; margin: 40rpx auto 0;">
|
||||
|
||||
<view class="column" @click="toAppointment()" style="align-items: center;">
|
||||
<image src="/static/appoin_record.png" style="width: 50rpx; height: 50rpx;" mode=""></image>
|
||||
<image src="@@:app/static/appoin_record.png" style="width: 50rpx; height: 50rpx;" mode=""></image>
|
||||
<text style="font-size: 24rpx; margin-top: 20rpx;">预约记录</text>
|
||||
</view>
|
||||
|
||||
<view class="column" style="align-items: center; margin-left: 40rpx;">
|
||||
<image src="/static/problem.png" style="width: 50rpx; height: 50rpx;" mode=""></image>
|
||||
<image src="@@:app/static/problem.png" style="width: 50rpx; height: 50rpx;" mode=""></image>
|
||||
<text style="font-size: 24rpx; margin-top: 20rpx;">常见问题</text>
|
||||
</view>
|
||||
|
||||
<view class="column" style="align-items: center; margin-left: 40rpx;">
|
||||
<image src="/static/customer_s.png" style="width: 50rpx; height: 50rpx;" mode=""></image>
|
||||
<image src="@@:app/static/customer_s.png" style="width: 50rpx; height: 50rpx;" mode=""></image>
|
||||
<text style="font-size: 24rpx; margin-top: 20rpx;">联系我们</text>
|
||||
</view>
|
||||
|
||||
<view class="column" @click="toBlacklist()" style="align-items: center; margin-left: 40rpx;">
|
||||
<image src="/static/blacklist.png" style="width: 50rpx; height: 50rpx;" mode=""></image>
|
||||
<image src="@@:app/static/blacklist.png" style="width: 50rpx; height: 50rpx;" mode=""></image>
|
||||
<text style="font-size: 24rpx; margin-top: 20rpx;">黑名单</text>
|
||||
</view>
|
||||
|
||||
|
|
@ -109,29 +115,31 @@
|
|||
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=""
|
||||
<image :src="appointmentDetail.organizer.avatar"
|
||||
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>
|
||||
<text style="font-size: 20rpx; margin-left: 15rpx;">{{ appointmentDetail.organizer.name }}</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" style="align-items: center;">
|
||||
<view class="row" v-for="(participant, index) in appointmentDetail.participants" :key="index"
|
||||
style="align-items: center;">
|
||||
|
||||
<view class="" style="position: relative; width: 50rpx; height: 50rpx; display: flex;">
|
||||
<image src="" @click="openUserPop()"
|
||||
<image :src="participant.avatar" @click="openUserPop()"
|
||||
style="width: 50rpx; height: 50rpx; background-color: antiquewhite; border-radius: 50%; margin-left: 20rpx; position: absolute;"
|
||||
mode=""></image>
|
||||
|
||||
<view class="center"
|
||||
<view v-if="participant.isBlacklisted" 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>
|
||||
style="font-size: 20rpx; margin-left: 30rpx; width: 100rpx; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">{{
|
||||
participant.name }}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
|
@ -144,36 +152,39 @@
|
|||
|
||||
<view class="row" style="justify-content: space-between; margin: 20rpx;">
|
||||
<text>开始时间</text>
|
||||
<text>2025/08/27 15:30</text>
|
||||
<text>{{ appointmentDetail.timeInfo.startTime }}</text>
|
||||
</view>
|
||||
<view class="row" style="justify-content: space-between; margin: 0 20rpx; 0">
|
||||
<view class="row" style="justify-content: space-between; margin: 0 20rpx;">
|
||||
<text>结束时间</text>
|
||||
<text>2025/08/27 17:30</text>
|
||||
<text>{{ appointmentDetail.timeInfo.endTime }}</text>
|
||||
</view>
|
||||
|
||||
<text style="margin: 30rpx 20rpx; 0">合计:2小时</text>
|
||||
<text style="margin: 30rpx 20rpx 0;">合计:{{ appointmentDetail.timeInfo.duration }}</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>
|
||||
<text style="margin: 20rpx 20rpx 10rpx; font-size: 24rpx;">房间号:{{ appointmentDetail.roomInfo.roomNumber
|
||||
}},{{ appointmentDetail.roomInfo.price }}</text>
|
||||
<text style="margin: 10rpx 20rpx;">人数:{{ appointmentDetail.roomInfo.playerCount }}人</text>
|
||||
<text style="margin: 10rpx 20rpx;">玩法类型:{{ appointmentDetail.roomInfo.gameType }}</text>
|
||||
<text style="margin: 10rpx 20rpx;">具体规则:{{ appointmentDetail.roomInfo.rules }}</text>
|
||||
<text style="margin: 10rpx 20rpx 20rpx;">补充信息:{{ appointmentDetail.roomInfo.additionalInfo }}</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>
|
||||
<text style="margin: 20rpx 20rpx 10rpx; font-size: 24rpx;">是否禁烟:{{
|
||||
appointmentDetail.requirements.smoking
|
||||
}}</text>
|
||||
<text style="margin: 10rpx 20rpx;">性别:{{ appointmentDetail.requirements.gender }}</text>
|
||||
<text style="margin: 10rpx 20rpx 20rpx;">信誉:{{ appointmentDetail.requirements.reputation }}</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: 20rpx 20rpx 10rpx; font-size: 24rpx;">鸽子费:{{ appointmentDetail.pigeonFee }}</text>
|
||||
<text
|
||||
style="margin: 10rpx 20rpx 20rpx; color: #9F9F9F;">组局成功后若有牌友未赴约,其鸽子费平均分给其他牌友。组局成功或失败后鸽子费将全额返还。</text>
|
||||
</view>
|
||||
|
|
@ -190,48 +201,228 @@
|
|||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
rateValue: 4.5
|
||||
}
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
|
||||
// 响应式数据
|
||||
const rateValue = ref(4.5)
|
||||
const infoPop = ref(null)
|
||||
const loading = ref(false)
|
||||
|
||||
// 用户信息 - 未登录状态
|
||||
const userInfo = reactive({
|
||||
nickname: '未登录',
|
||||
uid: '',
|
||||
avatar: '@@:app/nouser.png',
|
||||
rating: 0,
|
||||
reputation: 0,
|
||||
cardQuality: 0,
|
||||
cardSkill: 0,
|
||||
pigeonCount: 0
|
||||
})
|
||||
|
||||
// 当前预约信息
|
||||
const currentAppointment = ref(null)
|
||||
|
||||
// 预约详情数据
|
||||
const appointmentDetail = reactive({
|
||||
organizer: {
|
||||
name: '苏家辉',
|
||||
avatar: '',
|
||||
isBlacklisted: false
|
||||
},
|
||||
participants: [
|
||||
{
|
||||
name: '树下的胖子',
|
||||
avatar: '',
|
||||
isBlacklisted: true
|
||||
},
|
||||
methods: {
|
||||
{
|
||||
name: '张三',
|
||||
avatar: '',
|
||||
isBlacklisted: false
|
||||
},
|
||||
{
|
||||
name: '李四',
|
||||
avatar: '',
|
||||
isBlacklisted: false
|
||||
}
|
||||
],
|
||||
timeInfo: {
|
||||
startTime: '2025/08/27 15:30',
|
||||
endTime: '2025/08/27 17:30',
|
||||
duration: '2小时'
|
||||
},
|
||||
roomInfo: {
|
||||
roomNumber: '304号-大包',
|
||||
price: '30元/小时',
|
||||
playerCount: 3,
|
||||
gameType: '扑克',
|
||||
rules: '斗地主',
|
||||
additionalInfo: '无'
|
||||
},
|
||||
requirements: {
|
||||
smoking: '禁烟',
|
||||
gender: '不限',
|
||||
reputation: '≧4.0'
|
||||
},
|
||||
pigeonFee: '0元'
|
||||
})
|
||||
|
||||
openPop() {
|
||||
this.$refs.infoPop.open();
|
||||
},
|
||||
// 方法
|
||||
const openPop = () => {
|
||||
infoPop.value.open();
|
||||
}
|
||||
|
||||
clasePop() {
|
||||
this.$refs.infoPop.close();
|
||||
},
|
||||
const clasePop = () => {
|
||||
infoPop.value.close();
|
||||
}
|
||||
|
||||
toAppointment() {
|
||||
const toAppointment = () => {
|
||||
// 未登录状态,提示登录
|
||||
if (!userInfo.uid) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请先登录查看预约记录',
|
||||
showCancel: false,
|
||||
success: () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/appointment-record-page'
|
||||
});
|
||||
},
|
||||
|
||||
toEditInfo() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/edit-info'
|
||||
});
|
||||
},
|
||||
|
||||
toBlacklist() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/blacklist-page'
|
||||
url: '/pages/me/login'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/appointment-record-page'
|
||||
});
|
||||
}
|
||||
|
||||
const toEditInfo = () => {
|
||||
// 未登录状态,跳转到登录页面
|
||||
if (!userInfo.uid) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请先登录',
|
||||
showCancel: false,
|
||||
success: () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/login'
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/edit-info'
|
||||
});
|
||||
}
|
||||
|
||||
const toBlacklist = () => {
|
||||
// 未登录状态,提示登录
|
||||
if (!userInfo.uid) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请先登录查看黑名单',
|
||||
showCancel: false,
|
||||
success: () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/login'
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/blacklist-page'
|
||||
});
|
||||
}
|
||||
|
||||
const openUserPop = () => {
|
||||
// 打开用户详情弹窗的逻辑
|
||||
console.log('打开用户详情弹窗');
|
||||
}
|
||||
|
||||
const toLogin = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/login'
|
||||
});
|
||||
}
|
||||
|
||||
// 加载用户数据 - 未登录状态
|
||||
const loadUserData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
// 未登录状态,不加载用户数据
|
||||
// 保持默认的未登录状态
|
||||
userInfo.nickname = '未登录'
|
||||
userInfo.uid = ''
|
||||
userInfo.rating = 0
|
||||
userInfo.reputation = 0
|
||||
userInfo.cardQuality = 0
|
||||
userInfo.cardSkill = 0
|
||||
userInfo.pigeonCount = 0
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载用户数据失败:', error)
|
||||
uni.showToast({
|
||||
title: '加载失败',
|
||||
icon: 'error'
|
||||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 加载当前预约信息 - 未登录状态
|
||||
const loadCurrentAppointment = async () => {
|
||||
try {
|
||||
// 未登录状态,没有预约数据
|
||||
currentAppointment.value = null
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载预约信息失败:', error)
|
||||
currentAppointment.value = null
|
||||
}
|
||||
}
|
||||
|
||||
// 组件挂载时加载数据
|
||||
onMounted(() => {
|
||||
loadUserData()
|
||||
loadCurrentAppointment()
|
||||
})
|
||||
|
||||
// 页面显示时重新加载数据(用于登录后刷新)
|
||||
// onShow(() => {
|
||||
// // 检查是否有登录状态
|
||||
// const savedUserInfo = uni.getStorageSync('userInfo')
|
||||
// if (savedUserInfo && savedUserInfo.uid) {
|
||||
// // 如果已登录,更新用户信息
|
||||
// Object.assign(userInfo, savedUserInfo)
|
||||
// // 重新加载预约信息
|
||||
// loadCurrentAppointment()
|
||||
// }
|
||||
// })
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
color: white;
|
||||
padding: 20rpx 40rpx;
|
||||
border-radius: 10rpx;
|
||||
z-index: 9999;
|
||||
}
|
||||
</style>
|
||||
26
uni_modules/uni-card/changelog.md
Normal file
26
uni_modules/uni-card/changelog.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
## 1.3.1(2021-12-20)
|
||||
- 修复 在vue页面下略缩图显示不正常的bug
|
||||
## 1.3.0(2021-11-19)
|
||||
- 重构插槽的用法 ,header 替换为 title
|
||||
- 新增 actions 插槽
|
||||
- 新增 cover 封面图属性和插槽
|
||||
- 新增 padding 内容默认内边距离
|
||||
- 新增 margin 卡片默认外边距离
|
||||
- 新增 spacing 卡片默认内边距
|
||||
- 新增 shadow 卡片阴影属性
|
||||
- 取消 mode 属性,可使用组合插槽代替
|
||||
- 取消 note 属性 ,使用actions插槽代替
|
||||
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-card](https://uniapp.dcloud.io/component/uniui/uni-card)
|
||||
## 1.2.1(2021-07-30)
|
||||
- 优化 vue3下事件警告的问题
|
||||
## 1.2.0(2021-07-13)
|
||||
- 组件兼容 vue3,如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||
## 1.1.8(2021-07-01)
|
||||
- 优化 图文卡片无图片加载时,提供占位图标
|
||||
- 新增 header 插槽,自定义卡片头部( 图文卡片 mode="style" 时,不支持)
|
||||
- 修复 thumbnail 不存在仍然占位的 bug
|
||||
## 1.1.7(2021-05-12)
|
||||
- 新增 组件示例地址
|
||||
## 1.1.6(2021-02-04)
|
||||
- 调整为uni_modules目录规范
|
||||
270
uni_modules/uni-card/components/uni-card/uni-card.vue
Normal file
270
uni_modules/uni-card/components/uni-card/uni-card.vue
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
<template>
|
||||
<view class="uni-card" :class="{ 'uni-card--full': isFull, 'uni-card--shadow': isShadow,'uni-card--border':border}"
|
||||
:style="{'margin':isFull?0:margin,'padding':spacing,'box-shadow':isShadow?shadow:''}">
|
||||
<!-- 封面 -->
|
||||
<slot name="cover">
|
||||
<view v-if="cover" class="uni-card__cover">
|
||||
<image class="uni-card__cover-image" mode="widthFix" @click="onClick('cover')" :src="cover"></image>
|
||||
</view>
|
||||
</slot>
|
||||
<slot name="title">
|
||||
<view v-if="title || extra" class="uni-card__header">
|
||||
<!-- 卡片标题 -->
|
||||
<view class="uni-card__header-box" @click="onClick('title')">
|
||||
<view v-if="thumbnail" class="uni-card__header-avatar">
|
||||
<image class="uni-card__header-avatar-image" :src="thumbnail" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="uni-card__header-content">
|
||||
<text class="uni-card__header-content-title uni-ellipsis">{{ title }}</text>
|
||||
<text v-if="title&&subTitle"
|
||||
class="uni-card__header-content-subtitle uni-ellipsis">{{ subTitle }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-card__header-extra" @click="onClick('extra')">
|
||||
<text class="uni-card__header-extra-text">{{ extra }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</slot>
|
||||
<!-- 卡片内容 -->
|
||||
<view class="uni-card__content" :style="{padding:padding}" @click="onClick('content')">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view class="uni-card__actions" @click="onClick('actions')">
|
||||
<slot name="actions"></slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* Card 卡片
|
||||
* @description 卡片视图组件
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=22
|
||||
* @property {String} title 标题文字
|
||||
* @property {String} subTitle 副标题
|
||||
* @property {Number} padding 内容内边距
|
||||
* @property {Number} margin 卡片外边距
|
||||
* @property {Number} spacing 卡片内边距
|
||||
* @property {String} extra 标题额外信息
|
||||
* @property {String} cover 封面图(本地路径需要引入)
|
||||
* @property {String} thumbnail 标题左侧缩略图
|
||||
* @property {Boolean} is-full = [true | false] 卡片内容是否通栏,为 true 时将去除padding值
|
||||
* @property {Boolean} is-shadow = [true | false] 卡片内容是否开启阴影
|
||||
* @property {String} shadow 卡片阴影
|
||||
* @property {Boolean} border 卡片边框
|
||||
* @event {Function} click 点击 Card 触发事件
|
||||
*/
|
||||
export default {
|
||||
name: 'UniCard',
|
||||
emits: ['click'],
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
subTitle: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
padding: {
|
||||
type: String,
|
||||
default: '10px'
|
||||
},
|
||||
margin: {
|
||||
type: String,
|
||||
default: '15px'
|
||||
},
|
||||
spacing: {
|
||||
type: String,
|
||||
default: '0 10px'
|
||||
},
|
||||
extra: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
cover: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
thumbnail: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
isFull: {
|
||||
// 内容区域是否通栏
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isShadow: {
|
||||
// 是否开启阴影
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
shadow: {
|
||||
type: String,
|
||||
default: '0px 0px 3px 1px rgba(0, 0, 0, 0.08)'
|
||||
},
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick(type) {
|
||||
this.$emit('click', type)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
$uni-border-3: #EBEEF5 !default;
|
||||
$uni-shadow-base:0 0px 6px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
|
||||
$uni-main-color: #3a3a3a !default;
|
||||
$uni-base-color: #6a6a6a !default;
|
||||
$uni-secondary-color: #909399 !default;
|
||||
$uni-spacing-sm: 8px !default;
|
||||
$uni-border-color:$uni-border-3;
|
||||
$uni-shadow: $uni-shadow-base;
|
||||
$uni-card-title: 15px;
|
||||
$uni-cart-title-color:$uni-main-color;
|
||||
$uni-card-subtitle: 12px;
|
||||
$uni-cart-subtitle-color:$uni-secondary-color;
|
||||
$uni-card-spacing: 10px;
|
||||
$uni-card-content-color: $uni-base-color;
|
||||
|
||||
.uni-card {
|
||||
margin: $uni-card-spacing;
|
||||
padding: 0 $uni-spacing-sm;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
|
||||
background-color: #fff;
|
||||
flex: 1;
|
||||
|
||||
.uni-card__cover {
|
||||
position: relative;
|
||||
margin-top: $uni-card-spacing;
|
||||
flex-direction: row;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
.uni-card__cover-image {
|
||||
flex: 1;
|
||||
// width: 100%;
|
||||
/* #ifndef APP-PLUS */
|
||||
vertical-align: middle;
|
||||
/* #endif */
|
||||
}
|
||||
}
|
||||
|
||||
.uni-card__header {
|
||||
display: flex;
|
||||
border-bottom: 1px $uni-border-color solid;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: $uni-card-spacing;
|
||||
overflow: hidden;
|
||||
|
||||
.uni-card__header-box {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-card__header-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
margin-right: $uni-card-spacing;
|
||||
.uni-card__header-avatar-image {
|
||||
flex: 1;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.uni-card__header-content {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
// height: 40px;
|
||||
overflow: hidden;
|
||||
|
||||
.uni-card__header-content-title {
|
||||
font-size: $uni-card-title;
|
||||
color: $uni-cart-title-color;
|
||||
// line-height: 22px;
|
||||
}
|
||||
|
||||
.uni-card__header-content-subtitle {
|
||||
font-size: $uni-card-subtitle;
|
||||
margin-top: 5px;
|
||||
color: $uni-cart-subtitle-color;
|
||||
}
|
||||
}
|
||||
|
||||
.uni-card__header-extra {
|
||||
line-height: 12px;
|
||||
|
||||
.uni-card__header-extra-text {
|
||||
font-size: 12px;
|
||||
color: $uni-cart-subtitle-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.uni-card__content {
|
||||
padding: $uni-card-spacing;
|
||||
font-size: 14px;
|
||||
color: $uni-card-content-color;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.uni-card__actions {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.uni-card--border {
|
||||
border: 1px solid $uni-border-color;
|
||||
}
|
||||
|
||||
.uni-card--shadow {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
box-shadow: $uni-shadow;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-card--full {
|
||||
margin: 0;
|
||||
border-left-width: 0;
|
||||
border-left-width: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
.uni-card--full:after {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
.uni-ellipsis {
|
||||
/* #ifndef APP-NVUE */
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
/* #endif */
|
||||
/* #ifdef APP-NVUE */
|
||||
lines: 1;
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
||||
90
uni_modules/uni-card/package.json
Normal file
90
uni_modules/uni-card/package.json
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"id": "uni-card",
|
||||
"displayName": "uni-card 卡片",
|
||||
"version": "1.3.1",
|
||||
"description": "Card 组件,提供常见的卡片样式。",
|
||||
"keywords": [
|
||||
"uni-ui",
|
||||
"uniui",
|
||||
"card",
|
||||
"",
|
||||
"卡片"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": ""
|
||||
},
|
||||
"directories": {
|
||||
"example": "../../temps/example_temps"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [
|
||||
"uni-icons",
|
||||
"uni-scss"
|
||||
],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
uni_modules/uni-card/readme.md
Normal file
12
uni_modules/uni-card/readme.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
|
||||
## Card 卡片
|
||||
> **组件名:uni-card**
|
||||
> 代码块: `uCard`
|
||||
|
||||
卡片视图组件。
|
||||
|
||||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-card)
|
||||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ export default defineConfig({
|
|||
/@@:([^\s"'()<>]+?\.(png|jpe?g|gif|svg|webp))/g,
|
||||
(match, path) => {
|
||||
count++
|
||||
return `https://guyu-1308826010.cos.ap-shanghai.myqcloud.com/${path}`
|
||||
return `https://admin-1308826010.cos.ap-shanghai.myqcloud.com/${path}`
|
||||
}
|
||||
);
|
||||
if (count > 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user