Bladeren bron

【feat】【第一版开发】

1.完善页面布局
ChenYL 1 jaar geleden
bovenliggende
commit
c7e7298f31
8 gewijzigde bestanden met toevoegingen van 298 en 142 verwijderingen
  1. 9 0
      README.md
  2. 15 1
      common/style/common-style.scss
  3. 2 2
      package.json
  4. 49 37
      pages/detail/detail.vue
  5. 69 63
      pages/index/index.vue
  6. 33 19
      pages/login/login.vue
  7. 33 20
      pages/userInfo/userInfo.vue
  8. 88 0
      utils/system.js

+ 9 - 0
README.md

@@ -8,6 +8,15 @@
 
 
 
+待办列表
+
+* 前端样式和使用细节优化
+* ~~uniapp环境配置分离~~
+* ~~前端开发~~
+* ~~前端原型图设计~~
+
+
+
 ## 全局变量
 
 | 变量         | 描述        |

+ 15 - 1
common/style/common-style.scss

@@ -2,6 +2,20 @@ view {
 	box-sizing: border-box;
 }
 
-.page-bg {
+.layout-container {
+	display: flex;
+	flex-direction: column;
+	height: 100vh;
 	background: linear-gradient(180deg, #B9D3FF 0%, #F2F7FF 22.23%);
+	
+	.capsule-container {
+		padding-left: 16rpx;
+		padding-right: 16rpx;
+	}
+	
+	.content-container {
+		/* 内容区域占满剩余空间 */
+		flex-grow: 1;
+		padding: 16rpx;
+	}
 }

+ 2 - 2
package.json

@@ -6,14 +6,14 @@
 				"browser": "chrome",
 				"env": {
 					"UNI_PLATFORM": "h5",
-					"BASE_API_URL": "http://loclhost:8080"
+					"BASE_API_URL": "http://localhost:8080"
 				}
 			},
 			"wp-dev": {
 				"title": "微信小程序 开发环境",
 				"env": {
 					"UNI_PLATFORM": "mp-weixin",
-					"BASE_API_URL": "http://loclhost:8080"
+					"BASE_API_URL": "http://localhost:8080"
 				}
 			},
 			"wp-sit": {

+ 49 - 37
pages/detail/detail.vue

@@ -1,33 +1,54 @@
 <template>
-	<view class="container page-bg">
-		<view class="back-container">
-			<navigator url="/pages/index/index">
-				<uni-icons type="back" size="40" color="#FFFFFF"></uni-icons>
-			</navigator>
-		</view>
-		<view class="edit-container">
-			<view class="input-item">
-				<view class="input-title">任务名称</view>
-				<input class="input-box" placeholder="请输入任务名称" v-model="punchIn.taskName"/>
-			</view>
-			<view class="input-item">
-				<view class="input-title">奖励倍数</view>
-				<input class="input-box" type="number" placeholder="请输入任务倍数" v-model="punchIn.rewardNum"/>
-			</view>
-			<view class="switch-item">
-				<view class="input-title">周末双倍</view>
-				<switch class="input-switch" :checked="punchIn.weekendDoubleFlag" @change="weekendDoubleSwitchChange"/>
-			</view>
-			<view class="switch-item">
-				<view class="input-title">全勤奖励</view>
-				<switch class="input-switch" :checked="punchIn.fullAttendanceFlag" @change="fullAttendanceSwitchChange"/>
+	<view class="layout-container">
+		<!-- 顶部填充区 -->
+		<view class="top-fill" :style="{height: safeArea.statusBarHeight+'px'}"></view>
+		
+		<!-- 顶部胶囊区 -->
+		<view class="capsule-container" 
+		:style="{
+			height: safeArea.capsuleBarHeight+'px',
+			width: safeArea.capsuleBarLeft+'px',
+			'padding-top': safeArea.capsuleBarMarginTop+'px', 
+			'padding-bottom': safeArea.capsuleBarMarginBottom+'px'}">
+			<view class="back-container" :style="{
+				height: safeArea.capsuleBarContentHeight+'px',
+				width: safeArea.capsuleBarContentHeight+'px',
+			}">
+				<navigator url="/pages/index/index">
+					<uni-icons type="back" :size="safeArea.capsuleBarContentHeight" color="#FFFFFF"></uni-icons>
+				</navigator>
 			</view>
-			<view class="btn-container">
-				<view class="cancel-btn" @click="cancel">取消</view>
-				<view class="save-btn" @click="savePunchIn">保存</view>
+		</view>
+		
+		<!-- 内容区 -->
+		<view class="content-container">
+			<view class="edit-container">
+				<view class="input-item">
+					<view class="input-title">任务名称</view>
+					<input class="input-box" placeholder="请输入任务名称" v-model="punchIn.taskName"/>
+				</view>
+				<view class="input-item">
+					<view class="input-title">奖励倍数</view>
+					<input class="input-box" type="number" placeholder="请输入任务倍数" v-model="punchIn.rewardNum"/>
+				</view>
+				<view class="switch-item">
+					<view class="input-title">周末双倍</view>
+					<switch class="input-switch" :checked="punchIn.weekendDoubleFlag" @change="weekendDoubleSwitchChange"/>
+				</view>
+				<view class="switch-item">
+					<view class="input-title">全勤奖励</view>
+					<switch class="input-switch" :checked="punchIn.fullAttendanceFlag" @change="fullAttendanceSwitchChange"/>
+				</view>
+				<view class="btn-container">
+					<view class="cancel-btn" @click="cancel">取消</view>
+					<view class="save-btn" @click="savePunchIn">保存</view>
+				</view>
 			</view>
 		</view>
 		
+		<!-- 底部填充区 -->
+		<view class="bottom-fill" :style="{height: safeArea.bottomHeight+'px'}"></view>
+
 	</view>
 </template>
 
@@ -35,6 +56,7 @@
 	import { ref } from 'vue';
 	import { onLoad } from '@dcloudio/uni-app';
 	import { punchInApi } from '@/service/apis';
+	import safeArea from '@/utils/system.js';
 	
 	/**
 	 * 打卡任务
@@ -85,16 +107,7 @@
 </script>
 
 <style lang="scss" scoped>
-.container {
-	width: 100vw;
-	height: 100vh;
-	padding: 16rpx;
-	
 	.back-container {
-		left: 16rpx;
-		top: 39px;
-		width: 90rpx;
-		height: 90rpx;
 		border-radius: 50%;
 		background-color: rgba(0, 0, 0, 0.1);
 		
@@ -174,7 +187,7 @@
 			letter-spacing: 0rpx;
 			line-height: 52.13rpx;
 			color: #FFFFFF;
-
+	
 		}
 		
 		.save-btn {
@@ -186,7 +199,7 @@
 			display: flex;
 			justify-content: center;
 			align-items: center;
-
+	
 			font-size: 36rpx;
 			font-weight: 400;
 			letter-spacing: 0rpx;
@@ -194,5 +207,4 @@
 			color: #FFFFFF;
 		}
 	}
-}
 </style>

+ 69 - 63
pages/index/index.vue

@@ -1,62 +1,83 @@
 <template>
-	<view class="container page-bg">
-		<view class="header-container">
-			<view class="user-info" @click="goUserInfoPage">
-				<uni-icons type="person" size="30" color="#FFFFFF"></uni-icons>
-			</view>
-		</view>
-		<view class="settle-container">
-			<view class="settle-text-container">
-				<view class="settle-title">待领取奖励数</view>
-				<view class="settle-num">{{reward}}</view>
+	<view class="layout-container">
+		<!-- 顶部填充区 -->
+		<view class="top-fill" :style="{height: safeArea.statusBarHeight+'px'}"></view>
+		
+		<!-- 顶部胶囊区 -->
+		<view class="capsule-container" 
+		:style="{
+			height: safeArea.capsuleBarHeight+'px',
+			width: safeArea.capsuleBarLeft+'px',
+			'padding-top': safeArea.capsuleBarMarginTop+'px', 
+			'padding-bottom': safeArea.capsuleBarMarginBottom+'px'}">
+			<view class="user-info" @click="goUserInfoPage" :style="{
+				height: safeArea.capsuleBarContentHeight+'px',
+				width: safeArea.capsuleBarContentHeight+'px',
+			}">
+				<uni-icons type="person" :size="safeArea.capsuleBarContentHeight" color="#FFFFFF"></uni-icons>
 			</view>
-			<view class="settle-btn" @click="claimReward">领取</view>
 		</view>
-		<view class="task-container">
-			<view class="task-header">
-				<view class="task-title">任务(3个)</view>
-				<view class="task-add-btn" @click="goPunchInDetailPage">
-					<uni-icons type="plusempty" size="30" color="#406CE7"></uni-icons>
+		
+		<!-- 内容区 -->
+		<view class="content-container">
+			<view class="settle-container">
+				<view class="settle-text-container">
+					<view class="settle-title">待领取奖励数</view>
+					<view class="settle-num">{{reward}}</view>
 				</view>
+				<view class="settle-btn" @click="claimReward">领取</view>
 			</view>
-			<view class="task-item" v-for="punchIn in punchIns" :key="punchIn.punchInId">
-				<view class="item-header">
-					<view class="item-title">{{punchIn.taskName}}</view>
-					<navigator :url="'/pages/detail/detail?id='+punchIn.punchInId">
-						<uni-icons class="item-icon" type="settings" size="30" color="#C4C4C4"></uni-icons>
-					</navigator>
-					<view class="item-tag-container">
-						<view class="item-tag" v-if="punchIn.fullAttendanceFlag">全勤奖励</view>
-						<view class="item-tag" v-if="punchIn.weekendDoubleFlag">周末双倍</view>
+			<view class="task-container">
+				<view class="task-header">
+					<view class="task-title">任务(3个)</view>
+					<view class="task-add-btn" @click="goPunchInDetailPage">
+						<uni-icons type="plusempty" size="30" color="#406CE7"></uni-icons>
 					</view>
-					<view class="item-btn" @click="doPunchIn(punchIn.punchInId)">完成</view>
 				</view>
-				<view class="item-detail-list">
-					<view class="item-detail" v-for="punchInRecord in punchIn.punchInRecords" :key="punchInRecord.punchInDate">
-						<view class="detail-text">
-							<uni-dateformat :date="punchInRecord.punchInDate" format="M月d日"></uni-dateformat>
+				<view class="task-item" v-for="punchIn in punchIns" :key="punchIn.punchInId">
+					<view class="item-header">
+						<view class="item-title">{{punchIn.taskName}}</view>
+						<navigator :url="'/pages/detail/detail?id='+punchIn.punchInId">
+							<uni-icons class="item-icon" type="settings" size="30" color="#C4C4C4"></uni-icons>
+						</navigator>
+						<view class="item-tag-container">
+							<view class="item-tag" v-if="punchIn.fullAttendanceFlag">全勤奖励</view>
+							<view class="item-tag" v-if="punchIn.weekendDoubleFlag">周末双倍</view>
+						</view>
+						<view class="item-btn" @click="doPunchIn(punchIn.punchInId)">完成</view>
+					</view>
+					<view class="item-detail-list">
+						<view class="item-detail" v-for="punchInRecord in punchIn.punchInRecords" :key="punchInRecord.punchInDate">
+							<view class="detail-text">
+								<uni-dateformat :date="punchInRecord.punchInDate" format="M月d日"></uni-dateformat>
+							</view>
+							<view class="detail-box" style="background-color: #E5E5E5;" v-if="punchInRecord.punchInStatus == 'uncreated'"></view>
+							<view class="detail-box" style="background-color: #A5D63F;" v-if="punchInRecord.punchInStatus == 'punchIn'"></view>
+							<view class="detail-box" style="background-color: #D43030;" v-if="punchInRecord.punchInStatus == 'unPunchIn'"></view>
+							<view class="detail-box" v-if="punchInRecord.punchInStatus == 'futureTime' || punchInRecord.punchInStatus == 'todayUnknown'"></view>
 						</view>
-						<view class="detail-box" style="background-color: #E5E5E5;" v-if="punchInRecord.punchInStatus == 'uncreated'"></view>
-						<view class="detail-box" style="background-color: #A5D63F;" v-if="punchInRecord.punchInStatus == 'punchIn'"></view>
-						<view class="detail-box" style="background-color: #D43030;" v-if="punchInRecord.punchInStatus == 'unPunchIn'"></view>
-						<view class="detail-box" v-if="punchInRecord.punchInStatus == 'futureTime' || punchInRecord.punchInStatus == 'todayUnknown'"></view>
 					</view>
 				</view>
 			</view>
 		</view>
 		
+		<!-- 弹出框 -->
 		<view>
 			<uni-popup ref="claimRewardDialog" type="dialog">
 				<uni-popup-dialog ref="inputClose" mode="input" title="领取奖励" value="对话框预置提示内容!"
 					placeholder="请输入领取的奖励数" @confirm="claimRewardConfirm"></uni-popup-dialog>
 			</uni-popup>
 		</view>
+		
+		<!-- 底部填充区 -->
+		<view class="bottom-fill" :style="{height: safeArea.bottomHeight+'px'}"></view>
 	</view>
 </template>
 
 <script setup>
 	import { onMounted, ref } from 'vue';
 	import { rewardApi, punchInApi } from '@/service/apis.js';
+	import safeArea from '@/utils/system.js';
 	
 	/**
 	 * 可领取奖励
@@ -144,40 +165,25 @@
 		getReward();
 		// 获取打卡
 		getPunchIn();
-	})
+	});
 </script>
 
 <style lang="scss" scoped>
-	.container {
-		width: 100vw;
-		height: 100vh;
-		padding: 16rpx;
-
-		.header-container {
-			position: relative;
-			height: 83rpx;
-
-			.user-info {
-				width: 83rpx;
-				height: 83rpx;
-
-				display: flex;
-				justify-content: center;
-				/* 水平居中 */
-				align-items: center;
-				/* 垂直居中 */
-
-				position: absolute;
-				right: 0rpx;
-				top: 0rpx;
-
-				border-radius: 50%;
-				background: rgba(210, 239, 243, 1);
-			}
-		}
+	.user-info {
+		display: flex;
+		justify-content: center;
+		/* 水平居中 */
+		align-items: center;
+		/* 垂直居中 */
+		
+		border-radius: 50%;
+		background: rgba(210, 239, 243, 1);
+	}
+	
+	.content-container {
 
 		.settle-container {
-			margin-top: 16rpx;
+			// margin-top: 16rpx;
 			height: 228rpx;
 			position: relative;
 			border-radius: 20rpx;

+ 33 - 19
pages/login/login.vue

@@ -1,22 +1,46 @@
 <template>
-	<view class="page-bg container">
-		<view class="back-container">
-			<navigator url="/pages/index/index">
-				<uni-icons type="back" size="40" color="#FFFFFF"></uni-icons>
-			</navigator>
+	<view class="layout-container">
+		<!-- 顶部填充区 -->
+		<view class="top-fill" :style="{height: safeArea.statusBarHeight+'px'}"></view>
+		
+		<!-- 顶部胶囊区 -->
+		<view class="capsule-container" 
+		:style="{
+			height: safeArea.capsuleBarHeight+'px',
+			width: safeArea.capsuleBarLeft+'px',
+			'padding-top': safeArea.capsuleBarMarginTop+'px', 
+			'padding-bottom': safeArea.capsuleBarMarginBottom+'px'}">
+			<view class="back-container" :style="{
+				height: safeArea.capsuleBarContentHeight+'px',
+				width: safeArea.capsuleBarContentHeight+'px',
+			}">
+				<navigator url="/pages/index/index">
+					<uni-icons type="back" :size="safeArea.capsuleBarContentHeight" color="#FFFFFF"></uni-icons>
+				</navigator>
+			</view>
 		</view>
-		<view class="login-container">
-			<view class="avator-container">
-				<uni-icons type="person" size="130" color="#FFFFFF"></uni-icons>
+		
+		<!-- 内容区 -->
+		<view class="content-container">
+			<view class="login-container">
+				<view class="avator-container">
+					<uni-icons type="person" size="130" color="#FFFFFF"></uni-icons>
+				</view>
+				<view class="btn-container" @click="login">登录</view>
 			</view>
-			<view class="btn-container" @click="login">登录</view>
 		</view>
+		
+		<!-- 底部填充区 -->
+		<view class="bottom-fill" :style="{height: safeArea.bottomHeight+'px'}"></view>
+
 	</view>
 </template>
 
 <script setup>
 	import { ref } from 'vue';
 	import { loginApi } from '@/service/apis.js';
+	import safeArea from '@/utils/system.js';
+	
 	/**
 	 * 头像
 	 */
@@ -63,16 +87,7 @@
 </script>
 
 <style lang="scss" scoped>
-.container {
-	width: 100vw;
-	height: 100vh;
-	padding: 16rpx;
-	
 	.back-container {
-		left: 16rpx;
-		top: 39px;
-		width: 90rpx;
-		height: 90rpx;
 		border-radius: 50%;
 		background-color: rgba(0, 0, 0, 0.1);
 		
@@ -122,5 +137,4 @@
 			align-items: center;
 		}
 	}
-}	       
 </style>

+ 33 - 20
pages/userInfo/userInfo.vue

@@ -1,20 +1,43 @@
 <template>
-	<view class="page-bg container">
-		<view class="back-container">
-			<navigator url="/pages/index/index">
-				<uni-icons type="back" size="40" color="#FFFFFF"></uni-icons>
-			</navigator>
+	<view class="layout-container">
+		<!-- 顶部填充区 -->
+		<view class="top-fill" :style="{height: safeArea.statusBarHeight+'px'}"></view>
+		
+		<!-- 顶部胶囊区 -->
+		<view class="capsule-container" 
+		:style="{
+			height: safeArea.capsuleBarHeight+'px',
+			width: safeArea.capsuleBarLeft+'px',
+			'padding-top': safeArea.capsuleBarMarginTop+'px', 
+			'padding-bottom': safeArea.capsuleBarMarginBottom+'px'}">
+			<view class="back-container" :style="{
+				height: safeArea.capsuleBarContentHeight+'px',
+				width: safeArea.capsuleBarContentHeight+'px',
+			}">
+				<navigator url="/pages/index/index">
+					<uni-icons type="back" :size="safeArea.capsuleBarContentHeight" color="#FFFFFF"></uni-icons>
+				</navigator>
+			</view>
 		</view>
-		<view class="login-container">
-			<view class="avator-container">
-				<uni-icons type="person" size="130" color="#FFFFFF"></uni-icons>
+		
+		<!-- 内容区 -->
+		<view class="content-container">
+			<view class="login-container">
+				<view class="avator-container">
+					<uni-icons type="person" size="130" color="#FFFFFF"></uni-icons>
+				</view>
+				<view class="btn-container" @click="logout">注销</view>
 			</view>
-			<view class="btn-container" @click="logout">注销</view>
 		</view>
+		
+		<!-- 底部填充区 -->
+		<view class="bottom-fill" :style="{height: safeArea.bottomHeight+'px'}"></view>
 	</view>
 </template>
 
 <script setup>
+	import safeArea from '@/utils/system.js';
+	
 	const logout = () => {
 		uni.removeStorageSync("token");
 		uni.reLaunch({
@@ -24,16 +47,7 @@
 </script>
 
 <style lang="scss" scoped>
-.container {
-	width: 100vw;
-	height: 100vh;
-	padding: 16rpx;
-	
 	.back-container {
-		left: 16rpx;
-		top: 39px;
-		width: 90rpx;
-		height: 90rpx;
 		border-radius: 50%;
 		background-color: rgba(0, 0, 0, 0.1);
 		
@@ -82,6 +96,5 @@
 			justify-content: center;
 			align-items: center;
 		}
-	}
-}	       
+	}	   
 </style>

+ 88 - 0
utils/system.js

@@ -0,0 +1,88 @@
+const SYSTEM_INFO = uni.getSystemInfoSync();
+
+/**
+ * 状态栏高度
+ * @returns {number}
+ */
+export const getStatusBarHeight = () => {
+	return SYSTEM_INFO.safeAreaInsets.top || 0;
+}
+
+/**
+ * 获取胶囊按钮高度(即微信小程序上边的按钮)
+ * @returns {number}
+ */
+export const getCapsuleBarHeight = () => {
+	if (uni.getMenuButtonBoundingClientRect) {
+		let {
+			top,
+			height
+		} = uni.getMenuButtonBoundingClientRect();
+		return height + (top - getStatusBarHeight()) * 2;
+	}
+
+	return 40;
+}
+
+/**
+ * 获取胶囊按钮信息(即微信小程序上边的按钮)
+ * capsuleBarHeight 胶囊按钮栏高度
+ * capsuleBarLeft 胶囊按钮栏左边距离
+ * capsuleBarMargin 胶囊按钮栏边距
+ * capsuleBarMarginTop 胶囊按钮栏上边距
+ * capsuleBarMarginBottom 胶囊按钮栏下边距
+ * capsuleBarContentHeight 胶囊按钮内容高度
+ * @returns {{capsuleBarHeight: number, capsuleBarLeft: number, capsuleBarMarginTop: number, capsuleBarMarginBottom: number, capsuleBarContentHeight: number}}
+ */
+export const getCapsuleBarInfo = () => {
+	if (uni.getMenuButtonBoundingClientRect) {
+		let { top, height, left} = uni.getMenuButtonBoundingClientRect();
+		let barMargin = top - getStatusBarHeight()
+		return {
+			"capsuleBarHeight": height + barMargin * 2,
+			"capsuleBarLeft": left,
+			"capsuleBarMargin": barMargin,
+			"capsuleBarMarginTop": barMargin,
+			"capsuleBarMarginBottom": barMargin,
+			"capsuleBarContentHeight": height
+		}
+	}
+
+	return {
+		"capsuleBarHeight": 40,
+		"capsuleBarLeft": SYSTEM_INFO.screenWidth,
+		"capsuleBarMargin": 4,
+		"capsuleBarMarginTop": 4,
+		"capsuleBarMarginBottom": 4,
+		"capsuleBarContentHeight": 32
+	};
+}
+
+/**
+ * 获取安全区数据
+ * statusBarHeight: 状态栏高度
+ * capsuleBarHeight: 胶囊按钮高度
+ * topHeight: 状态栏+胶囊按钮高度
+ * bottomHeight: 底部安全区高度
+ * capsuleBarHeight 胶囊按钮栏高度
+ * capsuleBarLeft 胶囊按钮栏左边距离
+ * capsuleBarMargin 胶囊按钮栏边距
+ * capsuleBarMarginTop 胶囊按钮栏上边距
+ * capsuleBarMarginBottom 胶囊按钮栏下边距
+ * capsuleBarContentHeight 胶囊按钮内容高度
+ * @returns {{topHeight: number, bottomHeight: number, statusBarHeight: number, capsuleBarHeight: number, capsuleBarLeft: number, capsuleBarMarginTop: number, capsuleBarMarginBottom: number, capsuleBarContentHeight: number}}
+ */
+const getSafeArea = () => {
+	let tempSafeArea = getCapsuleBarInfo();
+	tempSafeArea.statusBarHeight = getStatusBarHeight();
+	tempSafeArea.bottomHeight = SYSTEM_INFO.safeAreaInsets.bottom || 0;
+	tempSafeArea.topHeight = getStatusBarHeight() + tempSafeArea.capsuleBarHeight;
+	return tempSafeArea;
+}
+
+/**
+ * 安全区数据
+ */
+const safeArea = getSafeArea();
+
+export default safeArea;