瀏覽代碼

【feat】【第二版开发】

1.主页、记录查询相关页增加骨架屏
2.登录页、中户中心页修复昵称输入框样式异常
3.增加刮刮乐记录撤销功能
ChenYL 1 年之前
父節點
當前提交
da65ebee63

+ 4 - 4
package-lock.json

@@ -1,12 +1,12 @@
 {
-  "name": "uni-preset-vue",
-  "version": "0.0.0",
+  "name": "punch-settle-miniprogram",
+  "version": "1.0.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
-      "name": "uni-preset-vue",
-      "version": "0.0.0",
+      "name": "punch-settle-miniprogram",
+      "version": "1.0.0",
       "dependencies": {
         "@dcloudio/uni-app": "3.0.0-4030620241128001",
         "@dcloudio/uni-app-harmony": "3.0.0-4030620241128001",

+ 31 - 20
src/pages/index/index.vue

@@ -130,6 +130,8 @@
 					<span>计时</span>
 				</view>
 			</view>
+
+			<uni-load-more status="no-more" v-if="!punchIns || punchIns.length == 0" />
 		</view>
 
 		<!-- 刮刮乐弹出框 -->
@@ -179,13 +181,15 @@
 		<uni-popup ref="timeTrackInputDialog" type="dialog" :is-mask-click="false">
 			<uni-popup-dialog mode="input" :before-close="true" title="计时记录" confirmText="保存"
 				@confirm="timeTrackFormConfirm" @close="timeTrackFormClose">
-				<view style="width: 100%;">
-					<uni-forms ref="timeTrackForm" :modelValue="timeTrackFormData" :rules="timeTrackFormRules"
-						label-position="top" :label-width="150">
+				<view class="pick-box" @click="timeTrackClick">
+					<picker mode="time" :value="timeTrackFormData.timeTrack" @change="timeTrackChange">
+						<view class="pick-box-time">{{ timeTrackFormData.timeTrack }}</view>
+					</picker>
+				</view>
+				<view style="display: none;">
+					<uni-forms ref="timeTrackForm" :modelValue="timeTrackFormData" :rules="timeTrackFormRules">
 						<uni-forms-item name="timeTrack">
-							<picker mode="time" :value="timeTrackFormData.timeTrack" @change="timeTrackChange">
-								<view class="pick-box">{{ timeTrackFormData.timeTrack }}</view>
-							</picker>
+							<uni-easyinput v-model="timeTrackFormData.timeTrack" />
 						</uni-forms-item>
 					</uni-forms>
 				</view>
@@ -916,20 +920,27 @@ onPullDownRefresh(() => {
 }
 
 .pick-box {
-	display: flex;
-	box-sizing: border-box;
-	flex-direction: row;
-	align-items: center;
-	border: 1px solid #dcdfe6;
-	border-radius: 4px;
+	width: 100%;
+	height: 100rpx;
+	border-radius: 8px;
+	background: #ffffff;
+	// 阴影
+	border: 0.5px solid #e4e4e4;
+
+	picker {
+		width: 100%;
+		height: 100%;
 
-	width: auto;
-	position: relative;
-	overflow: hidden;
-	flex: 1;
-	line-height: 1;
-	font-size: 14px;
-	height: 35px;
-	padding-left: 10px;
+		.pick-box-time {
+			width: 100%;
+			height: 100rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			color: #000000;
+			border-radius: 24rpx;
+			text-align: center;
+		}
+	}
 }
 </style>

+ 51 - 48
src/pages/login/login.vue

@@ -6,27 +6,30 @@
 					<uni-icons type="person" size="60"></uni-icons>
 				</view>
 				<view class="login-nickname">
+					<input v-model="loginFormData.nickname" placeholder="请输入昵称" />
+				</view>
+
+				<view style="display: none">
 					<uni-forms ref="loginForm" :modelValue="loginFormData" :rules="loginFormRules"
 						err-show-type="modal">
 						<uni-forms-item name="nickname">
 							<uni-easyinput type="text" v-model="loginFormData.nickname" placeholder="请输入昵称"
-								:clearable="false" :inputBorder="false" :styles="nicknameInputStyle" />
+								:clearable="false" :inputBorder="false" />
 						</uni-forms-item>
 					</uni-forms>
 				</view>
 
 				<view class="login-btn" @click="login">登录</view>
-
 			</view>
 		</template>
 	</main-layout>
 </template>
 
 <script setup>
-import { ref } from 'vue';
-import { loginApi } from '@/service/apis.js';
-import router from '@/common/constants/router.js';
-import { useUserInfoStore } from '@/stores/userInfo.js';
+import { ref } from "vue";
+import { loginApi } from "@/service/apis.js";
+import router from "@/common/constants/router.js";
+import { useUserInfoStore } from "@/stores/userInfo.js";
 
 // 组件
 /**
@@ -44,7 +47,7 @@ const userInfoStore = useUserInfoStore();
  * 登录表单数据
  */
 const loginFormData = ref({
-	nickname: "蜗牛"
+	nickname: "蜗牛",
 });
 
 /**
@@ -52,70 +55,58 @@ const loginFormData = ref({
  */
 const loginFormRules = ref({
 	nickname: {
-		rules: [{
-			required: true,
-			errorMessage: '昵称不能为空'
-		}, {
-			maxLength: 30,
-			errorMessage: '昵称不能超过{maxLength}个字符'
-		}]
-	}
+		rules: [
+			{
+				required: true,
+				errorMessage: "昵称不能为空",
+			},
+			{
+				maxLength: 30,
+				errorMessage: "昵称不能超过{maxLength}个字符",
+			},
+		],
+	},
 });
 
-/**
- * 昵称输入框样式
- */
-const nicknameInputStyle = {
-	width: 100 + '%',
-	height: 100 + '%',
-	fontSize: 36 + 'rpx',
-	fontWeight: 700,
-	letterSpacing: 0 + 'rpx',
-	lineHeight: 52.13 + 'rpx',
-	color: '#000000',
-	borderRadius: 24 + 'rpx',
-	textAlign: 'center'
-};
-
 // 方法
 const login = async () => {
 	try {
 		let formData = await loginForm.value.validate();
 		uni.showLoading({
-			title: '登录中...'
+			title: "登录中...",
 		});
 		// 获取供应商
-		let providerResult = await uni.getProvider({ service: 'oauth' });
+		let providerResult = await uni.getProvider({ service: "oauth" });
 		// 获取登录code
 		let loginResult = await uni.login({ provider: providerResult.provider[0] });
 		// 登录
 		let token = await loginApi.login({
-			"code": loginResult.code,
-			"nickname": formData.nickname
+			code: loginResult.code,
+			nickname: formData.nickname,
 		});
 
 		// 保存用户信息(token)
 		userInfoStore.$patch({
 			token,
-			nickname: formData.nickname
+			nickname: formData.nickname,
 		});
 
 		uni.showToast({
-			title: '登录成功',
-			icon: 'success',
-			duration: 1000
+			title: "登录成功",
+			icon: "success",
+			duration: 1000,
 		});
 
 		// 登录结束返回主页
 		setTimeout(() => {
 			uni.navigateTo({
-				url: router.INDEX_URL
+				url: router.INDEX_URL,
 			});
 		}, 1000);
 	} finally {
 		uni.hideLoading();
 	}
-}
+};
 </script>
 
 <style lang="scss" scoped>
@@ -132,12 +123,12 @@ const login = async () => {
 	.login-avator {
 		width: 200rpx;
 		height: 200rpx;
-		background: #FFFFFF;
+		background: #ffffff;
 		border-radius: 50%;
 
 		// 阴影
-		border: 0.5px solid #E4E4E4;
-		box-shadow: 0px 1px 6px #D8D8D8;
+		border: 0.5px solid #e4e4e4;
+		box-shadow: 0px 1px 6px #d8d8d8;
 
 		display: flex;
 		justify-content: center;
@@ -150,11 +141,23 @@ const login = async () => {
 		width: 599rpx;
 		height: 100rpx;
 		border-radius: 8px;
-		background: #FFFFFF;
+		background: #ffffff;
 
 		// 阴影
-		border: 0.5px solid #E4E4E4;
-		box-shadow: 0px 1px 6px #D8D8D8;
+		border: 0.5px solid #e4e4e4;
+		box-shadow: 0px 1px 6px #d8d8d8;
+
+		input {
+			width: 100%;
+			height: 100%;
+			font-size: 36rpx;
+			font-weight: 700;
+			letter-spacing: 0rpx;
+			line-height: 52.13rpx;
+			color: #000000;
+			border-radius: 24rpx;
+			text-align: center;
+		}
 	}
 
 	.login-btn {
@@ -163,13 +166,13 @@ const login = async () => {
 		width: 599rpx;
 		height: 100rpx;
 		border-radius: 24rpx;
-		background: #406CE7;
+		background: #406ce7;
 
 		font-size: 36rpx;
 		font-weight: 400;
 		letter-spacing: 0rpx;
 		line-height: 52.13rpx;
-		color: #FFFFFF;
+		color: #ffffff;
 
 		display: flex;
 		justify-content: center;

+ 321 - 326
src/pages/punchin-detail/punchin-detail.vue

@@ -1,235 +1,228 @@
 <template>
 	<main-layout :showHome="true" :showBack="true">
-		<uni-calendar 
-			:start-date="punchInData.startDate"
-			:end-date="punchInData.endDate"
-			:selected="punchInData.calendarSelected"
-			@monthSwitch="calendarMonthSwitchChange"/>	
+		<uni-calendar :start-date="punchInData.startDate" :end-date="punchInData.endDate"
+			:selected="punchInData.calendarSelected" @monthSwitch="calendarMonthSwitchChange" />
 		<viwe class="info-box">
-			<view class="left">打卡:{{punchInData.punchInNum}}次</view>
-			<view class="right">全勤率:{{punchInData.punchInRate}}%</view>
+			<view class="left">打卡:{{ punchInData.punchInNum }}次</view>
+			<view class="right">全勤率:{{ punchInData.punchInRate }}%</view>
 		</viwe>
 		<view class="log-box">
 			<uni-section title="打卡记录" type="line">
 				<uni-list>
 					<uni-list-item v-for="record in punchInData.punchInRecords" :key="record.punchInDate">
 						<template v-slot:body>
-							{{record.punchInDate}}
+							{{ record.punchInDate }}
 							<span v-if="record.punchInStatus == 1 || record.punchInStatus == 3"> 完成打卡</span>
 							<span v-else> 未完成打卡</span>
-							<span v-if="record.settleCategory == 1">,打卡{{record.countTrack}}次</span>
-							<span v-if="record.settleCategory == 2">,打卡时长{{record.timeTrack}}</span>
+							<span v-if="record.settleCategory == 1">,打卡{{ record.countTrack }}次</span>
+							<span v-if="record.settleCategory == 2">,打卡时长{{ record.timeTrack }}</span>
 						</template>
 					</uni-list-item>
 				</uni-list>
+				<uni-load-more status="no-more" v-if="punchInData.punchInRecords.length == 0" />
 			</uni-section>
 		</view>
-		<uni-fab ref="fabBtn" :content="fabContent" :pattern="fabPattern" horizontal="right" vertical="bottom" direction="vertical"  @trigger="trigger"/>
-		
+		<uni-fab ref="fabBtn" :content="fabContent" :pattern="fabPattern" horizontal="right" vertical="bottom"
+			direction="vertical" @trigger="trigger" />
+
 		<!-- 删除确认框 -->
 		<uni-popup ref="deleteDialog" type="dialog">
-			<uni-popup-dialog  mode="base" :before-close="true"
-				title="删除提示" content="确认删除当前任务?"
+			<uni-popup-dialog mode="base" :before-close="true" title="删除提示" content="确认删除当前任务?"
 				@confirm="deleteDialogConfirm" @close="deleteDialogClose"></uni-popup-dialog>
 		</uni-popup>
-		
+
 		<!-- 归档确认框 -->
 		<uni-popup ref="archiveDialog" type="dialog">
-			<uni-popup-dialog  mode="base" :before-close="true"
-				title="归档提示" content="确认归档当前任务?"
+			<uni-popup-dialog mode="base" :before-close="true" title="归档提示" content="确认归档当前任务?"
 				@confirm="archiveDialogConfirm" @close="archiveDialogClose"></uni-popup-dialog>
 		</uni-popup>
-		
+
 		<!-- 撤销确认框 -->
 		<uni-popup ref="revokeDialog" type="dialog">
-			<uni-popup-dialog  mode="base" :before-close="true"
-				title="撤销提示" content="确认撤销打卡?"
+			<uni-popup-dialog mode="base" :before-close="true" title="撤销提示" content="确认撤销打卡?"
 				@confirm="revokeDialogConfirm" @close="revokeDialogClose"></uni-popup-dialog>
 		</uni-popup>
-		
+
 		<!-- 补卡弹出框 -->
 		<uni-popup ref="remakeInputDialog" type="dialog" :is-mask-click="false">
-			<uni-popup-dialog
-				mode="input" 
-				:before-close="true" 
-				title="补卡" 
-				@confirm="remakeFormConfirm"
+			<uni-popup-dialog mode="input" :before-close="true" title="补卡" @confirm="remakeFormConfirm"
 				@close="remakeFormClose">
 				<view style="width: 100%;">
-					<uni-forms ref="remakeForm" :modelValue="remakeFormData" :rules="remakeFormRules" label-position="top" :label-width="150">
+					<uni-forms ref="remakeForm" :modelValue="remakeFormData" :rules="remakeFormRules"
+						label-position="top" :label-width="150">
 						<uni-forms-item name="punchInDate">
 							<picker mode="date" :value="remakeFormData.punchInDate" @change="remakePunchInDateChange">
-								<view class="pick-box">{{remakeFormData.punchInDate}}</view>
+								<view class="pick-box">{{ remakeFormData.punchInDate }}</view>
 							</picker>
 						</uni-forms-item>
 					</uni-forms>
 				</view>
 			</uni-popup-dialog>
 		</uni-popup>
-		
+
 	</main-layout>
 </template>
 
 <script setup>
-	import { ref } from 'vue';
-	import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app';
-	import router from '@/common/constants/router';
-	import { punchInApi } from '@/service/apis.js';
-	import dateUtils from '@/utils/date';
-	
-	// 组件
-	const fabBtn = ref(null);
-	/**
-	 * 删除弹出框
-	 */
-	const deleteDialog = ref(null);
-	
-	/**
-	 * 归档弹出框
-	 */
-	const archiveDialog = ref(null);
-	
-	/**
-	 * 补卡弹出框
-	 */
-	const remakeInputDialog = ref(null);
-	
-	/**
-	 * 补卡表单
-	 */
-	const remakeForm = ref(null);
-	
-	/**
-	 * 撤销弹出框
-	 */
-	const revokeDialog = ref(null);
-	
-	// 属性
-	/**
-	 * 任务ID
-	 */
-	const punchInId = ref(null);
-	
-	/**
-	 * 悬浮菜单样式
-	 */
-	const fabPattern = ref({
-		icon: 'compose'
-	});
+import { ref } from 'vue';
+import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app';
+import router from '@/common/constants/router';
+import { punchInApi } from '@/service/apis.js';
+import dateUtils from '@/utils/date';
 
-	/**
-	 * 悬浮按钮菜单
-	 */
-	const fabContent = [{
-			text: '删除',
-			active: false,
-			iconPath: '/static/delete.svg',
-			selectedIconPath: '/static/delete-active.svg',
-			func: "delete"
-		},
-		{
-			text: '归档',
-			active: false,
-			iconPath: '/static/archive.svg',
-			selectedIconPath: '/static/archive-active.svg',
-			func: "archive"
-		},
-		{
-			text: '撤销',
-			active: false,
-			iconPath: '/static/revoke.svg',
-			selectedIconPath: '/static/revoke_active.svg',
-			func: "revoke"
-		},
-		{
-			text: '补卡',
-			active: false,
-			iconPath: '/static/append.svg',
-			selectedIconPath: '/static/append-active.svg',
-			func: "remake"
-		},
-		{
-			text: '编辑',
-			active: false,
-			iconPath: '/static/edit.svg',
-			selectedIconPath: '/static/edit-active.svg',
-			func: "edit"
-		}
-	];
-	
-	/**
-	 * 补卡表单数据
-	 */
-	const remakeFormData = ref({
-		punchIndate: '2024-12-16'
-	});
-	
-	/**
-	 * 补卡表单校验规则
-	 */
-	const remakeFormRules = ref({
-		punchInDate: {
-			rules: [{
-				required: true,
-				errorMessage: '补卡日期不能为空'
-			}]
-		}
-	});
-	
-	/**
-	 * 查询条件
-	 */
-	const queryData = ref(null);
-	
-	/**
-	 * 打卡日历数据
-	 */
-	const punchInData = ref({
-		startDate: '2024-12-01',
-		endDate: '2024-12-31',
-		punchInNum: 0,
-		punchInRate: 0,
-		calendarSelected: [],
-		punchInRecords: []
-	});
-	
-	// 方法
-	/**
-	 * 悬浮按钮点击事件
-	 */
-	const trigger = (e) => {
-		if (e.item.func == 'delete') {
-			deleteDialog.value.open();
-		}
-		if (e.item.func == 'archive') {
-			archiveDialog.value.open();
-		}
-		if (e.item.func == 'revoke') {
-			revokeDialog.value.open();
-		}
-		if (e.item.func == 'remake') {
-			// 初始化上一轮的数据
-			remakeFormData.value = {
-				punchInId: punchInId.value,
-				punchInDate: dateUtils.getYesterday()
-			};
-			
-			remakeInputDialog.value.open();
-		}
-		if (e.item.func == 'edit') {
-			uni.navigateTo({
-				url: router.PUNCHIN_EDIT_URL + "?id=" + punchInId.value
-			});
-		}
-		
-		fabBtn.value.close();
+// 组件
+const fabBtn = ref(null);
+/**
+ * 删除弹出框
+ */
+const deleteDialog = ref(null);
+
+/**
+ * 归档弹出框
+ */
+const archiveDialog = ref(null);
+
+/**
+ * 补卡弹出框
+ */
+const remakeInputDialog = ref(null);
+
+/**
+ * 补卡表单
+ */
+const remakeForm = ref(null);
+
+/**
+ * 撤销弹出框
+ */
+const revokeDialog = ref(null);
+
+// 属性
+/**
+ * 任务ID
+ */
+const punchInId = ref(null);
+
+/**
+ * 悬浮菜单样式
+ */
+const fabPattern = ref({
+	icon: 'compose'
+});
+
+/**
+ * 悬浮按钮菜单
+ */
+const fabContent = [{
+	text: '删除',
+	active: false,
+	iconPath: '/static/delete.svg',
+	selectedIconPath: '/static/delete-active.svg',
+	func: "delete"
+},
+{
+	text: '归档',
+	active: false,
+	iconPath: '/static/archive.svg',
+	selectedIconPath: '/static/archive-active.svg',
+	func: "archive"
+},
+{
+	text: '撤销',
+	active: false,
+	iconPath: '/static/revoke.svg',
+	selectedIconPath: '/static/revoke_active.svg',
+	func: "revoke"
+},
+{
+	text: '补卡',
+	active: false,
+	iconPath: '/static/append.svg',
+	selectedIconPath: '/static/append-active.svg',
+	func: "remake"
+},
+{
+	text: '编辑',
+	active: false,
+	iconPath: '/static/edit.svg',
+	selectedIconPath: '/static/edit-active.svg',
+	func: "edit"
+}
+];
+
+/**
+ * 补卡表单数据
+ */
+const remakeFormData = ref({
+	punchIndate: '2024-12-16'
+});
+
+/**
+ * 补卡表单校验规则
+ */
+const remakeFormRules = ref({
+	punchInDate: {
+		rules: [{
+			required: true,
+			errorMessage: '补卡日期不能为空'
+		}]
 	}
-	
-	/**
-	 * 删除确认
-	 */
-	const deleteDialogConfirm = async () => {
-		punchInApi.deletePunchIn({id: punchInId.value})
+});
+
+/**
+ * 查询条件
+ */
+const queryData = ref(null);
+
+/**
+ * 打卡日历数据
+ */
+const punchInData = ref({
+	startDate: '2024-12-01',
+	endDate: '2024-12-31',
+	punchInNum: 0,
+	punchInRate: 0,
+	calendarSelected: [],
+	punchInRecords: []
+});
+
+// 方法
+/**
+ * 悬浮按钮点击事件
+ */
+const trigger = (e) => {
+	if (e.item.func == 'delete') {
+		deleteDialog.value.open();
+	}
+	if (e.item.func == 'archive') {
+		archiveDialog.value.open();
+	}
+	if (e.item.func == 'revoke') {
+		revokeDialog.value.open();
+	}
+	if (e.item.func == 'remake') {
+		// 初始化上一轮的数据
+		remakeFormData.value = {
+			punchInId: punchInId.value,
+			punchInDate: dateUtils.getYesterday()
+		};
+
+		remakeInputDialog.value.open();
+	}
+	if (e.item.func == 'edit') {
+		uni.navigateTo({
+			url: router.PUNCHIN_EDIT_URL + "?id=" + punchInId.value
+		});
+	}
+
+	fabBtn.value.close();
+}
+
+/**
+ * 删除确认
+ */
+const deleteDialogConfirm = async () => {
+	punchInApi.deletePunchIn({ id: punchInId.value })
 		.then(ret => {
 			deleteDialog.value.close();
 			uni.showToast({
@@ -246,20 +239,20 @@
 				icon: 'error'
 			});
 		});
-	}
-	
-	/**
-	 * 删除取消
-	 */
-	const deleteDialogClose = () => {
-		deleteDialog.value.close();
-	}
-	
-	/**
-	 * 归档确认
-	 */
-	const archiveDialogConfirm = async () => {
-		punchInApi.archivePunchIn({id: punchInId.value})
+}
+
+/**
+ * 删除取消
+ */
+const deleteDialogClose = () => {
+	deleteDialog.value.close();
+}
+
+/**
+ * 归档确认
+ */
+const archiveDialogConfirm = async () => {
+	punchInApi.archivePunchIn({ id: punchInId.value })
 		.then(ret => {
 			archiveDialog.value.close();
 			uni.showToast({
@@ -276,55 +269,55 @@
 				icon: 'error'
 			});
 		});
-	}
-	
-	/**
-	 * 归档取消
-	 */
-	const archiveDialogClose = () => {
-		archiveDialog.value.close();
-	}
-	
-	/**
-	 * 补卡时间选择监听
-	 */
-	const remakePunchInDateChange = (e) => {
-		remakeFormData.value.punchInDate = e.detail.value;
-	}
-	
-	/**
-	 * 补卡表单提交
-	 */
-	const remakeFormConfirm = async () => {
-		remakeForm.value.validate(['punchInId']).then(data => {
-			return punchInApi.remakePunchIn(data);
-		}).then(e => {
-			remakeInputDialog.value.close();
-			uni.showToast({
-				title: '补卡成功',
-				icon: 'success'
-			});
-			loadData();
-		}).catch(err => {
-			uni.showToast({
-				title: '补卡失败',
-				icon: 'error'
-			});
-		})
-	}
-	
-	/**
-	 * 补卡表单取消
-	 */
-	const remakeFormClose = async () => {
+}
+
+/**
+ * 归档取消
+ */
+const archiveDialogClose = () => {
+	archiveDialog.value.close();
+}
+
+/**
+ * 补卡时间选择监听
+ */
+const remakePunchInDateChange = (e) => {
+	remakeFormData.value.punchInDate = e.detail.value;
+}
+
+/**
+ * 补卡表单提交
+ */
+const remakeFormConfirm = async () => {
+	remakeForm.value.validate(['punchInId']).then(data => {
+		return punchInApi.remakePunchIn(data);
+	}).then(e => {
 		remakeInputDialog.value.close();
-	}
-	
-	/**
-	 * 撤销确认
-	 */
-	const revokeDialogConfirm = async () => {
-		punchInApi.revokePunchIn({id: punchInId.value})
+		uni.showToast({
+			title: '补卡成功',
+			icon: 'success'
+		});
+		loadData();
+	}).catch(err => {
+		uni.showToast({
+			title: '补卡失败',
+			icon: 'error'
+		});
+	})
+}
+
+/**
+ * 补卡表单取消
+ */
+const remakeFormClose = async () => {
+	remakeInputDialog.value.close();
+}
+
+/**
+ * 撤销确认
+ */
+const revokeDialogConfirm = async () => {
+	punchInApi.revokePunchIn({ id: punchInId.value })
 		.then(ret => {
 			revokeDialog.value.close();
 			uni.showToast({
@@ -339,91 +332,93 @@
 				icon: 'error'
 			});
 		});
-	}
-	
-	/**
-	 * 撤销取消
-	 */
-	const revokeDialogClose = () => {
-		revokeDialog.value.close();
-	}
-	
-	/**
-	 * 日历月份切换
-	 */
-	const calendarMonthSwitchChange = (e) => {
-		queryData.value = e;
-		loadData();
-	}
-	
-	/**
-	 * 加载数据
-	 */
-	const loadData = () => {
-		punchInApi.queryPunchInData({
-			id: punchInId.value,
-			year: queryData.value.year,
-			month: queryData.value.month,
-		}).then(data => {
-			punchInData.value = data;
-		}).catch(err => {
-			uni.showToast({
-				title: '加载失败',
-				icon: 'error'
-			});
+}
+
+/**
+ * 撤销取消
+ */
+const revokeDialogClose = () => {
+	revokeDialog.value.close();
+}
+
+/**
+ * 日历月份切换
+ */
+const calendarMonthSwitchChange = (e) => {
+	queryData.value = e;
+	loadData();
+}
+
+/**
+ * 加载数据
+ */
+const loadData = () => {
+	punchInApi.queryPunchInData({
+		id: punchInId.value,
+		year: queryData.value.year,
+		month: queryData.value.month,
+	}).then(data => {
+		punchInData.value = data;
+	}).catch(err => {
+		uni.showToast({
+			title: '加载失败',
+			icon: 'error'
 		});
-	}
-	
-	onLoad(async (e) => {
-		if (e.id) {
-			punchInId.value = e.id;
-			// 初始化查询条件
-			queryData.value = dateUtils.getTodayYearMonthObj();
-			
-			// 加载数据
-			loadData();
-		}
 	});
-	
-	onPullDownRefresh(() => {
+}
+
+onLoad(async (e) => {
+	if (e.id) {
+		punchInId.value = e.id;
+		// 初始化查询条件
+		queryData.value = dateUtils.getTodayYearMonthObj();
+
+		// 加载数据
 		loadData();
-		uni.stopPullDownRefresh();
-	});
+	}
+});
+
+onPullDownRefresh(() => {
+	loadData();
+	uni.stopPullDownRefresh();
+});
 </script>
 
 <style lang="scss" scoped>
-	.info-box, .log-box {
-		margin-top: 24rpx;
-	}
-	
-	.info-box {
-		display: flex;
-		background-color: #FFFFFF;
-		padding: 20rpx 10rpx;
-		
-		.left, .right {
-			flex: 1;
-			display: flex;
-			align-items: center;
-			justify-content: center;
-		}
-	}
-	
-	.pick-box {
+.info-box,
+.log-box {
+	margin-top: 24rpx;
+}
+
+.info-box {
+	display: flex;
+	background-color: #FFFFFF;
+	padding: 20rpx 10rpx;
+
+	.left,
+	.right {
+		flex: 1;
 		display: flex;
-		box-sizing: border-box;
-		flex-direction: row;
 		align-items: center;
-		border: 1px solid #dcdfe6;
-		border-radius: 4px;
-		
-		width: auto;
-		position: relative;
-		overflow: hidden;
-		flex: 1;
-		line-height: 1;
-		font-size: 14px;
-		height: 35px;
-		padding-left: 10px;
+		justify-content: center;
 	}
+}
+
+.pick-box {
+	display: flex;
+	box-sizing: border-box;
+	flex-direction: row;
+	align-items: center;
+	border: 1px solid #dcdfe6;
+	border-radius: 4px;
+
+	width: auto;
+	position: relative;
+	overflow: hidden;
+	flex: 1;
+	line-height: 1;
+	font-size: 14px;
+	height: 35px;
+	padding-left: 10px;
+}
 </style>

+ 69 - 67
src/pages/reward-record-list/reward-record-list.vue

@@ -1,89 +1,91 @@
 <template>
 	<main-layout :showHome="true" :showBack="true">
 		<view class="selector">
-			<uni-datetime-picker type="daterange" v-model="datePickerValue" @change="dateChange"/>
+			<uni-datetime-picker type="daterange" v-model="datePickerValue" @change="dateChange" />
 		</view>
 		<uni-list :border="true">
 			<uni-list-item v-for="item in listData" :key="item.id">
 				<template v-slot:body>
-					<p>{{item.claimRewardTime}}</p>
+					<p>{{ item.claimRewardTime }}</p>
 					<p>
-						领取奖励:{{item.claimRewardNum}},领取前奖励:{{item.beforeClaimRewardNum}},领取后奖励:{{item.afterClaimRewardNum}}
+						领取奖励:{{ item.claimRewardNum }},领取前奖励:{{ item.beforeClaimRewardNum }},领取后奖励:{{
+							item.afterClaimRewardNum }}
 					</p>
 				</template>
 			</uni-list-item>
 		</uni-list>
+		<uni-load-more status="no-more" v-if="!listData || listData.length == 0" />
 	</main-layout>
 </template>
 
 <script setup>
-	import {ref} from 'vue';
-	import { onLoad, onPullDownRefresh } from "@dcloudio/uni-app";
-	import dateUtils from '@/utils/date';
-	import { rewardApi } from '@/service/apis';
-	
-	//属性
-	/**
-	 * 日期选择器值/
-	 */
-	const datePickerValue = ref([]);
-	
-	/**
-	 * 查询条件
-	 */
-	const queryData = ref(null);
-	
-	/**
-	 * 列表数据
-	 */
-	const listData = ref(null);
-	
-	// 方法
-	/**
-	 * 日期选择监听
-	 */
-	const dateChange = (e) => {
-		if (e.length == 0) {
-			queryData.value = {};
-			return;
-		}
-		
-		queryData.value = {
-			startDate: e[0],
-			endDate: e[1]
-		};
-		loadData();
-	}
-	
-	/**
-	 * 加载数据
-	 */
-	const loadData = () => {
-		rewardApi.queryClaimRewardRecords(queryData.value).then(res => {
-			listData.value = res;
-		});
+import { ref } from 'vue';
+import { onLoad, onPullDownRefresh } from "@dcloudio/uni-app";
+import dateUtils from '@/utils/date';
+import { rewardApi } from '@/service/apis';
+
+//属性
+/**
+ * 日期选择器值/
+ */
+const datePickerValue = ref([]);
+
+/**
+ * 查询条件
+ */
+const queryData = ref(null);
+
+/**
+ * 列表数据
+ */
+const listData = ref(null);
+
+// 方法
+/**
+ * 日期选择监听
+ */
+const dateChange = (e) => {
+	if (e.length == 0) {
+		queryData.value = {};
+		return;
 	}
-	
-	// 生命周期
-	onLoad(() => {
-		const startDate = dateUtils.getFirstDayOfMonth();
-		const endDate = dateUtils.getLastDayOfMonth();
-		datePickerValue.value = [startDate, endDate];
-		queryData.value = {
-			startDate,
-			endDate
-		}
-		loadData();
-	});
-	
-	onPullDownRefresh(() => {
-		loadData();
-		uni.stopPullDownRefresh();
+
+	queryData.value = {
+		startDate: e[0],
+		endDate: e[1]
+	};
+	loadData();
+}
+
+/**
+ * 加载数据
+ */
+const loadData = () => {
+	rewardApi.queryClaimRewardRecords(queryData.value).then(res => {
+		listData.value = res;
 	});
+}
+
+// 生命周期
+onLoad(() => {
+	const startDate = dateUtils.getFirstDayOfMonth();
+	const endDate = dateUtils.getLastDayOfMonth();
+	datePickerValue.value = [startDate, endDate];
+	queryData.value = {
+		startDate,
+		endDate
+	}
+	loadData();
+});
+
+onPullDownRefresh(() => {
+	loadData();
+	uni.stopPullDownRefresh();
+});
 </script>
 
 <style lang="scss" scoped>
-	.selector {
-		background-color: #FFFFFF;
-	}
+.selector {
+	background-color: #FFFFFF;
+}
 </style>

+ 151 - 73
src/pages/scratch-record-list/scratch-record-list.vue

@@ -1,96 +1,174 @@
 <template>
 	<main-layout :showHome="true" :showBack="true">
 		<view class="selector">
-			<uni-datetime-picker type="daterange" v-model="datePickerValue" @change="dateChange"/>
+			<uni-datetime-picker type="daterange" v-model="datePickerValue" @change="dateChange" />
 		</view>
 		<uni-list :border="true">
 			<uni-list-item v-for="item in listData" :key="item.id">
 				<template v-slot:body>
-					<p>{{item.creationTime}}</p>
-					<p>
-						<span v-if="item.actionType == 0">购买</span>
-						<span v-if="item.source == 'WELFARE_LOTTERY'">福彩</span>
-						<span v-if="item.source == 'SPORTS_LOTTERY'">体彩</span>
-						<span v-if="item.category == 'XINYUN88'">幸运88</span>
-						<span v-if="item.category == 'CHAOGEILI'">超给力</span>
-						<span v-if="item.actionType == 0">花费</span>
-						<span v-if="item.actionType == 1">中奖</span>
-						{{item.amount}}元
-					</p>
+					<view class="box">
+						<view class="content">
+							<p>{{ item.creationTime }}</p>
+							<p>
+								<span v-if="item.actionType == 0">购买</span>
+								<span v-if="item.source == 'WELFARE_LOTTERY'">福彩</span>
+								<span v-if="item.source == 'SPORTS_LOTTERY'">体彩</span>
+								<span v-if="item.category == 'XINYUN88'">幸运88</span>
+								<span v-if="item.category == 'CHAOGEILI'">超给力</span>
+								<span v-if="item.actionType == 0">花费</span>
+								<span v-if="item.actionType == 1">中奖</span>
+								{{ item.amount }}元
+							</p>
+						</view>
+						<view class="icon" @click="oepnRevokeDialog(item.id)">
+							<uni-icons type="closeempty" size="30" />
+						</view>
+					</view>
 				</template>
 			</uni-list-item>
+			<uni-load-more status="no-more" v-if="!listData || listData.length == 0" />
 		</uni-list>
+
+		<!-- 撤销确认框 -->
+		<uni-popup ref="revokeDialog" type="dialog">
+			<uni-popup-dialog mode="base" :before-close="true" title="撤销提示" content="确认撤销记录?"
+				@confirm="revokeDialogConfirm" @close="revokeDialogClose"></uni-popup-dialog>
+		</uni-popup>
 	</main-layout>
 </template>
 
 <script setup>
-	import {ref} from 'vue';
-	import { onLoad, onPullDownRefresh } from "@dcloudio/uni-app";
-	import dateUtils from '@/utils/date';
-	import { scratchApi } from '@/service/apis';
-	
-	//属性
-	/**
-	 * 日期选择器值/
-	 */
-	const datePickerValue = ref([]);
-	
-	/**
-	 * 查询条件
-	 */
-	const queryData = ref(null);
-	
-	/**
-	 * 列表数据
-	 */
-	const listData = ref(null);
-	
-	// 方法
-	/**
-	 * 日期选择监听
-	 */
-	const dateChange = (e) => {
-		if (e.length == 0) {
-			queryData.value = {};
-			return;
-		}
-		
-		queryData.value = {
-			startDate: e[0],
-			endDate: e[1]
-		};
-		loadData();
+import { ref } from 'vue';
+import { onLoad, onPullDownRefresh } from "@dcloudio/uni-app";
+import dateUtils from '@/utils/date';
+import { scratchApi } from '@/service/apis';
+
+// 组件
+const revokeDialog = ref(null);
+
+//属性
+/**
+ * 日期选择器值/
+ */
+const datePickerValue = ref([]);
+
+/**
+ * 查询条件
+ */
+const queryData = ref(null);
+
+/**
+ * 列表数据
+ */
+const listData = ref(null);
+
+/**
+ * 待撤销的记录ID
+ */
+const scratchRecordId = ref(null);
+
+// 方法
+/**
+ * 日期选择监听
+ */
+const dateChange = (e) => {
+	if (e.length == 0) {
+		queryData.value = {};
+		return;
 	}
-	
-	/**
-	 * 加载数据
+
+	queryData.value = {
+		startDate: e[0],
+		endDate: e[1]
+	};
+	loadData();
+}
+
+/**
+ * 加载数据
+ */
+const loadData = async () => {
+	scratchApi.queryScratchRecord(queryData.value).then(res => {
+		listData.value = res;
+	});
+}
+
+/**
+ * 打卡撤销dialog
+ * @param id 
+ */
+const oepnRevokeDialog = (id) => {
+	scratchRecordId.value = id;
+	revokeDialog.value.open();
+}
+
+/**
+	 * 撤销确认
 	 */
-	const loadData = () => {
-		scratchApi.queryScratchRecord(queryData.value).then(res => {
-			listData.value = res;
+const revokeDialogConfirm = async () => {
+	try {
+		let res = await scratchApi.revokeScratchRecord({
+			id: scratchRecordId.value
+		});
+		uni.showToast({
+			title: '撤销成功',
+			icon: 'success'
+		});
+		setTimeout(() => {
+			loadData();
+		}, 2000);
+	} catch (e) {
+		uni.showToast({
+			title: '撤销失败',
+			icon: 'error',
+			duration: 5000
 		});
+	} finally {
+		revokeDialogClose();
 	}
-	
-	// 生命周期
-	onLoad(() => {
-		const startDate = dateUtils.getFirstDayOfMonth();
-		const endDate = dateUtils.getLastDayOfMonth();
-		datePickerValue.value = [startDate, endDate];
-		queryData.value = {
-			startDate,
-			endDate
-		}
-		loadData();
-	});
-	
-	onPullDownRefresh(() => {
-		loadData();
-		uni.stopPullDownRefresh();
-	});
+}
+
+/**
+ * 撤销取消
+ */
+const revokeDialogClose = () => {
+	// 重置数据
+	scratchRecordId.value = null;
+	revokeDialog.value.close();
+}
+
+// 生命周期
+onLoad(() => {
+	const startDate = dateUtils.getFirstDayOfMonth();
+	const endDate = dateUtils.getLastDayOfMonth();
+	datePickerValue.value = [startDate, endDate];
+	queryData.value = {
+		startDate,
+		endDate
+	}
+	loadData();
+});
+
+onPullDownRefresh(() => {
+	loadData();
+	uni.stopPullDownRefresh();
+});
 </script>
 
 <style lang="scss" scoped>
-	.selector {
-		background-color: #FFFFFF;
+.selector {
+	background-color: #FFFFFF;
+}
+
+.box {
+	width: 100%;
+	height: 100%;
+
+	display: flex;
+	align-items: center;
+
+	.content {
+		flex-grow: 1;
 	}
+}
 </style>

+ 69 - 66
src/pages/settle-list/settle-list.vue

@@ -1,86 +1,89 @@
 <template>
 	<main-layout :showHome="true" :showBack="true">
 		<view class="selector">
-			<uni-datetime-picker type="daterange" v-model="datePickerValue" @change="dateChange"/>
+			<uni-datetime-picker type="daterange" v-model="datePickerValue" @change="dateChange" />
 		</view>
 		<uni-list :border="true">
 			<uni-list-item v-for="settle in settleData" :key="settle.id">
 				<template v-slot:body>
-					结算时间:{{settle.settlementTime}} 结算前奖励:{{settle.beforeSettleRewardNum}},结算奖励:{{settle.settleRewardNum}},结算后奖励:{{settle.afterSettleRewardNum}}
+					结算时间:{{ settle.settlementTime }}
+					结算前奖励:{{ settle.beforeSettleRewardNum }},结算奖励:{{ settle.settleRewardNum }},结算后奖励:{{
+						settle.afterSettleRewardNum }}
 				</template>
 			</uni-list-item>
 		</uni-list>
+		<uni-load-more status="no-more" v-if="!settleData || settleData.length == 0" />
 	</main-layout>
 </template>
 
 <script setup>
-	import {ref} from 'vue';
-	import { onLoad, onPullDownRefresh } from "@dcloudio/uni-app";
-	import dateUtils from '@/utils/date';
-	import { settleApi } from '@/service/apis';
-	
-	//属性
-	/**
-	 * 日期选择器值/
-	 */
-	const datePickerValue = ref([]);
-	
-	/**
-	 * 查询条件
-	 */
-	const queryData = ref(null);
-	
-	/**
-	 * 结算数据
-	 */
-	const settleData = ref(null);
-	
-	// 方法
-	/**
-	 * 日期选择监听
-	 */
-	const dateChange = (e) => {
-		if (e.length == 0) {
-			queryData.value = {};
-			return;
-		}
-		
-		queryData.value = {
-			startDate: e[0],
-			endDate: e[1]
-		};
-		loadData();
-	}
-	
-	/**
-	 * 加载数据
-	 */
-	const loadData = () => {
-		settleApi.querySettle(queryData.value).then(res => {
-			settleData.value = res;
-		});
+import { ref } from 'vue';
+import { onLoad, onPullDownRefresh } from "@dcloudio/uni-app";
+import dateUtils from '@/utils/date';
+import { settleApi } from '@/service/apis';
+
+//属性
+/**
+ * 日期选择器值/
+ */
+const datePickerValue = ref([]);
+
+/**
+ * 查询条件
+ */
+const queryData = ref(null);
+
+/**
+ * 结算数据
+ */
+const settleData = ref(null);
+
+// 方法
+/**
+ * 日期选择监听
+ */
+const dateChange = (e) => {
+	if (e.length == 0) {
+		queryData.value = {};
+		return;
 	}
-	
-	// 生命周期
-	onLoad(() => {
-		const startDate = dateUtils.getFirstDayOfMonth();
-		const endDate = dateUtils.getLastDayOfMonth();
-		datePickerValue.value = [startDate, endDate];
-		queryData.value = {
-			startDate,
-			endDate
-		}
-		loadData();
-	});
-	
-	onPullDownRefresh(() => {
-		loadData();
-		uni.stopPullDownRefresh();
+
+	queryData.value = {
+		startDate: e[0],
+		endDate: e[1]
+	};
+	loadData();
+}
+
+/**
+ * 加载数据
+ */
+const loadData = () => {
+	settleApi.querySettle(queryData.value).then(res => {
+		settleData.value = res;
 	});
+}
+
+// 生命周期
+onLoad(() => {
+	const startDate = dateUtils.getFirstDayOfMonth();
+	const endDate = dateUtils.getLastDayOfMonth();
+	datePickerValue.value = [startDate, endDate];
+	queryData.value = {
+		startDate,
+		endDate
+	}
+	loadData();
+});
+
+onPullDownRefresh(() => {
+	loadData();
+	uni.stopPullDownRefresh();
+});
 </script>
 
 <style lang="scss" scoped>
-	.selector {
-		background-color: #FFFFFF;
-	}
+.selector {
+	background-color: #FFFFFF;
+}
 </style>

+ 203 - 182
src/pages/user-info/user-info.vue

@@ -3,56 +3,53 @@
 		<template>
 			<view class="header">
 				<view class="avatar">
-					<uni-icons type="person" size="70"></uni-icons>	
+					<uni-icons type="person" size="70"></uni-icons>
 				</view>
-				<span class="nickname">{{userInfoStore.nickname}}</span>
+				<span class="nickname">{{ userInfoStore.nickname }}</span>
 			</view>
-			
+
 			<view class="func-wrap">
 				<uni-list :border="true">
-					<uni-list-item title="修改昵称"
-						:showArrow="true" :showExtraIcon="true" 
-						:extraIcon="{color: '#000000',size: 22, type: 'compose'}"
-						:clickable="true" @click="modifyNickname">
+					<uni-list-item title="修改昵称" :showArrow="true" :showExtraIcon="true"
+						:extraIcon="{ color: '#000000', size: 22, type: 'compose' }" :clickable="true"
+						@click="modifyNickname">
 					</uni-list-item>
 				</uni-list>
 			</view>
-			
+
 			<view class="func-wrap">
 				<uni-list :border="true">
-					<uni-list-item title="奖励结算记录" 
-						:showArrow="true" :showExtraIcon="true" 
-						:extraIcon="{color: '#000000',size: 22, type: 'list'}"
-						link="navigateTo" :to="router.SETTLE_LIST_URL">
+					<uni-list-item title="奖励结算记录" :showArrow="true" :showExtraIcon="true"
+						:extraIcon="{ color: '#000000', size: 22, type: 'list' }" link="navigateTo"
+						:to="router.SETTLE_LIST_URL">
 					</uni-list-item>
-					<uni-list-item title="奖励领取记录"
-						:showArrow="true" :showExtraIcon="true" 
-						:extraIcon="{color: '#000000',size: 22, type: 'list'}"
-						link="navigateTo" :to="router.REWARD_RECORD_LIST_URL">
+					<uni-list-item title="奖励领取记录" :showArrow="true" :showExtraIcon="true"
+						:extraIcon="{ color: '#000000', size: 22, type: 'list' }" link="navigateTo"
+						:to="router.REWARD_RECORD_LIST_URL">
 					</uni-list-item>
-					<uni-list-item title="刮刮乐投入与中奖记录"
-						:showArrow="true" :showExtraIcon="true" 
-						:extraIcon="{color: '#000000',size: 22, type: 'list'}"
-						link="navigateTo" :to="router.SCRATCH_RECORD_LIST_URL">
+					<uni-list-item title="刮刮乐投入与中奖记录" :showArrow="true" :showExtraIcon="true"
+						:extraIcon="{ color: '#000000', size: 22, type: 'list' }" link="navigateTo"
+						:to="router.SCRATCH_RECORD_LIST_URL">
 					</uni-list-item>
 				</uni-list>
 			</view>
 
 			<view class="cancel-btn" @click="logout">注销</view>
-			
+
 			<!-- 修改昵称弹出框 -->
 			<uni-popup ref="nicknameInputDialog" type="dialog" :is-mask-click="false">
-				<uni-popup-dialog
-					mode="input" 
-					:before-close="true" 
-					title="修改昵称" 
-					confirmText="保存" 
-					@confirm="nicknameFormConfirm"
-					@close="nicknameFormClose">
-					<view style="width: 100%;">
-						<uni-forms ref="nicknameForm" :modelValue="nicknameFormData" :rules="nicknameFormRules" label-position="top" :label-width="150">
+				<uni-popup-dialog mode="input" :before-close="true" title="修改昵称" confirmText="保存"
+					@confirm="nicknameFormConfirm" @close="nicknameFormClose">
+					<view class=".nickname-dialog">
+						<input class=".nickname" v-model="nicknameFormData.nickname" placeholder="请输入昵称" />
+					</view>
+
+					<view style="display: none">
+						<uni-forms ref="nicknameForm" :modelValue="nicknameFormData" :rules="nicknameFormRules"
+							label-position="top" :label-width="150" err-show-type="modal">
 							<uni-forms-item name="nickname">
-								<uni-easyinput type="text" placeholder="请输入昵称" v-model="nicknameFormData.nickname"></uni-easyinput>
+								<uni-easyinput type="text" placeholder="请输入昵称"
+									v-model="nicknameFormData.nickname"></uni-easyinput>
 							</uni-forms-item>
 						</uni-forms>
 					</view>
@@ -63,167 +60,191 @@
 </template>
 
 <script setup>
-	import { ref } from 'vue';
-	import router from '@/common/constants/router.js';
-	import { useUserInfoStore } from '@/stores/userInfo';
-	import { userApi } from '@/service/apis.js';
-	
-	// 组件
-	/**
-	 * 昵称弹出框
-	 */
-	const nicknameInputDialog = ref(null);
-
-	/**
-	 * 昵称表单
-	 */
-	const nicknameForm = ref(null);
-	
-	// 属性
-	/**
-	 * 用户信息
-	 */
-	const userInfoStore = useUserInfoStore();
-	
-	/**
-	 * 昵称表单数据
-	 */
-	const nicknameFormData = ref({
-		nickname: userInfoStore.nickname
-	});
-	
-	/**
-	 * 昵称表单验证规则
-	 */
-	const nicknameFormRules = ref({
-		nickname: {
-			rules: [{
+import { ref } from "vue";
+import router from "@/common/constants/router.js";
+import { useUserInfoStore } from "@/stores/userInfo";
+import { userApi } from "@/service/apis.js";
+
+// 组件
+/**
+ * 昵称弹出框
+ */
+const nicknameInputDialog = ref(null);
+
+/**
+ * 昵称表单
+ */
+const nicknameForm = ref(null);
+
+// 属性
+/**
+ * 用户信息
+ */
+const userInfoStore = useUserInfoStore();
+
+/**
+ * 昵称表单数据
+ */
+const nicknameFormData = ref({
+	nickname: userInfoStore.nickname,
+});
+
+/**
+ * 昵称表单验证规则
+ */
+const nicknameFormRules = ref({
+	nickname: {
+		rules: [
+			{
 				required: true,
-				errorMessage: '昵称不能为空'
-			}, {
+				errorMessage: "昵称不能为空",
+			},
+			{
 				maxLength: 30,
-				errorMessage: '昵称不能超过{maxLength}个字符'
-			}],
-		}	
-	})
-	
-	// 方法
-	/**
-	 * 注销登录
-	 */
-	const logout = () => {
-		userInfoStore.$reset();
-		uni.reLaunch({
-			url: router.INDEX_URL
-		});
-	}
-	
-	/**
-	 * 跳转结算列表页
-	 */
-	const goSettleListPage = () => {
-		uni.navigateTo({
-			url: router.SETTLE_LIST_URL
-		});
-	}
-	
-	/**
-	 * 跳转奖励领取记录列表页
-	 */
-	const goClaimRewardListPage = () => {
-		uni.navigateTo({
-			url: router.CLAIM_REWARD_LIST_URL
-		});
-	}
-	
-	/**
-	 * 跳转刮刮乐记录列表页
-	 */
-	const goScratchListPage = () => {
-		uni.navigateTo({
-			url: router.SCRATCH_LIST_URL
-		});
-	}
-	
-	const modifyNickname = (e) => {
-		nicknameInputDialog.value.open();
-	}
-	
-	/**
-	 * 领取奖励表单提交
-	 */
-	const nicknameFormConfirm = async () => {
-		let data = await nicknameForm.value.validate();
-		await userApi.modifyNickname(data);
-		userInfoStore.nickname = data.nickname;
-		nicknameInputDialog.value.close();
-		uni.showToast({
-			title: '修改成功',
-			icon: 'success'
-		});
-	}
-	
-	/**
-	 * 领取奖励表单取消
-	 */
-	const nicknameFormClose = async () => {
-		nicknameInputDialog.value.close();
-	}
+				errorMessage: "昵称不能超过{maxLength}个字符",
+			},
+		],
+	},
+});
+
+// 方法
+/**
+ * 注销登录
+ */
+const logout = () => {
+	userInfoStore.$reset();
+	uni.reLaunch({
+		url: router.INDEX_URL,
+	});
+};
+
+/**
+ * 跳转结算列表页
+ */
+const goSettleListPage = () => {
+	uni.navigateTo({
+		url: router.SETTLE_LIST_URL,
+	});
+};
+
+/**
+ * 跳转奖励领取记录列表页
+ */
+const goClaimRewardListPage = () => {
+	uni.navigateTo({
+		url: router.CLAIM_REWARD_LIST_URL,
+	});
+};
+
+/**
+ * 跳转刮刮乐记录列表页
+ */
+const goScratchListPage = () => {
+	uni.navigateTo({
+		url: router.SCRATCH_LIST_URL,
+	});
+};
+
+const modifyNickname = (e) => {
+	nicknameInputDialog.value.open();
+};
+
+/**
+ * 领取奖励表单提交
+ */
+const nicknameFormConfirm = async () => {
+	let data = await nicknameForm.value.validate();
+	await userApi.modifyNickname(data);
+	userInfoStore.nickname = data.nickname;
+	nicknameInputDialog.value.close();
+	uni.showToast({
+		title: "修改成功",
+		icon: "success",
+	});
+};
+
+/**
+ * 领取奖励表单取消
+ */
+const nicknameFormClose = async () => {
+	nicknameInputDialog.value.close();
+};
 </script>
 
 <style lang="scss" scoped>
-	.header {
+.header {
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	flex-direction: column;
+
+	margin-top: 100rpx;
+
+	.avatar {
+		width: 180rpx;
+		height: 180rpx;
+		opacity: 1;
+		background: #ffffff;
+		border-radius: 50%;
+
 		display: flex;
 		justify-content: center;
 		align-items: center;
-		flex-direction: column;
-		
-		margin-top: 100rpx;
-		
-		.avatar {
-			width: 180rpx;
-			height: 180rpx;
-			opacity: 1;
-			background: #FFFFFF;
-			border-radius: 50%;
-			
-			display: flex;
-			justify-content: center;
-			align-items: center;
-		}
-		
-		.nickname {
-			margin-top: 16rpx;
-			font-size: 36rpx;
-			font-weight: 400;
-			letter-spacing: 0px;
-			line-height: 52.13rpx;
-			color: #000000;
-		}
 	}
-	
-	.func-wrap {
-		background: #FFFFFF;
-		margin-top: 24rpx;
-	}
-	
-	.cancel-btn {
-		margin-top: 24rpx;
-		height: 54rpx;
-		opacity: 1;
-		border-radius: 24rpx;
-		background: #F2607A;
-		
-		/** 文本1 */
-		font-size: 26rpx;
+
+	.nickname {
+		margin-top: 16rpx;
+		font-size: 36rpx;
 		font-weight: 400;
+		letter-spacing: 0px;
+		line-height: 52.13rpx;
+		color: #000000;
+	}
+}
+
+.func-wrap {
+	background: #ffffff;
+	margin-top: 24rpx;
+}
+
+.cancel-btn {
+	margin-top: 24rpx;
+	height: 54rpx;
+	opacity: 1;
+	border-radius: 24rpx;
+	background: #f2607a;
+
+	/** 文本1 */
+	font-size: 26rpx;
+	font-weight: 400;
+	letter-spacing: 0rpx;
+	// line-height: 37.65rpx;
+	color: #ffffff;
+
+	display: flex;
+	justify-content: center;
+	align-content: center;
+	align-items: center;
+}
+
+.nickname-dialog {
+	width: 100%;
+	height: 100rpx;
+	border-radius: 8px;
+	background: #ffffff;
+	// 阴影
+	border: 0.5px solid #e4e4e4;
+
+	input {
+		width: 100%;
+		height: 100%;
+		font-size: 36rpx;
+		font-weight: 700;
 		letter-spacing: 0rpx;
-		// line-height: 37.65rpx;
-		color: #FFFFFF;
-		
-		display: flex;
-		justify-content: center;
-		align-content: center;
-		align-items: center;
+		line-height: 52.13rpx;
+		color: #000000;
+		border-radius: 24rpx;
+		text-align: center;
 	}
+}
 </style>

+ 13 - 0
src/service/scratchApi.js

@@ -26,4 +26,17 @@ export function queryScratchRecord(data) {
 		loading: true,
 		loadingText: '查询中...'
 	});
+}
+
+/**
+ * 撤销投入/中奖记录
+ */
+export function revokeScratchRecord(data) {
+	return request({
+		url: '/scratch/revokeScratchRecord',
+		method: 'post',
+		data,
+		loading: true,
+		loadingText: '撤销中...'
+	});
 }