feat: 新增显示签到记录
This commit is contained in:
@@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Volo.Abp.Application.Dtos;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Integral
|
||||||
|
{
|
||||||
|
public class SignInDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 签到数据
|
||||||
|
/// </summary>
|
||||||
|
public List<SignInItemDto> SignInItem { get; set; }=new List<SignInItemDto>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前连续签到次数
|
||||||
|
/// </summary>
|
||||||
|
public int CurrentContinuousNumber { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SignInItemDto : EntityDto<Guid>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 签到时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreationTime { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,10 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Volo.Abp.Application.Services;
|
using Volo.Abp.Application.Services;
|
||||||
using Volo.Abp.Users;
|
using Volo.Abp.Users;
|
||||||
|
using Yi.Framework.Bbs.Application.Contracts.Dtos.Integral;
|
||||||
using Yi.Framework.Bbs.Domain.Managers;
|
using Yi.Framework.Bbs.Domain.Managers;
|
||||||
|
|
||||||
namespace Yi.Framework.Bbs.Application.Services.Integral
|
namespace Yi.Framework.Bbs.Application.Services.Integral
|
||||||
@@ -31,5 +33,43 @@ namespace Yi.Framework.Bbs.Application.Services.Integral
|
|||||||
var value = await _integralManager.SignInAsync(_currentUser.Id ?? Guid.Empty);
|
var value = await _integralManager.SignInAsync(_currentUser.Id ?? Guid.Empty);
|
||||||
return new { value };
|
return new { value };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取本月签到记录
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet("integral/sign-in/record")]
|
||||||
|
public async Task<SignInDto> GetSignInRecordAsync()
|
||||||
|
{
|
||||||
|
var output = new SignInDto();
|
||||||
|
DateTime lastMonth = DateTime.Now.AddMonths(-1);
|
||||||
|
DateTime lastDayOfMonth = new DateTime(lastMonth.Year, lastMonth.Month, 1).AddMonths(1).AddDays(-1);
|
||||||
|
DateTime startOfLastDay = new DateTime(lastDayOfMonth.Year, lastDayOfMonth.Month, lastDayOfMonth.Day, 0, 0, 0);
|
||||||
|
|
||||||
|
//获取当前用户本月的数据+上个月最后一天的数据
|
||||||
|
var entities = await _integralManager._signInRepository.GetListAsync(x => x.CreatorId == CurrentUser.Id
|
||||||
|
&& x.CreationTime >= startOfLastDay);
|
||||||
|
|
||||||
|
if (entities is null)
|
||||||
|
{
|
||||||
|
//返回默认值
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
//拿到最末尾的数据
|
||||||
|
var lastEntity = entities.OrderBy(x => x.CreationTime).LastOrDefault();
|
||||||
|
|
||||||
|
//判断当前时间和最后时间是否为连续的
|
||||||
|
if (lastEntity.CreationTime.Day >= DateTime.Now.AddDays(-1).Day)
|
||||||
|
{
|
||||||
|
|
||||||
|
output.CurrentContinuousNumber = lastEntity.ContinuousNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
//去除上个月查询的数据
|
||||||
|
output.SignInItem = entities.Where(x=>x.CreationTime.Month==DateTime.Now.Month) .Select(x => new SignInItemDto { Id = x.Id, CreationTime = x.CreationTime }).OrderBy(x=>x.CreationTime).ToList();
|
||||||
|
return output;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ namespace Yi.Framework.Bbs.Domain.Managers
|
|||||||
{
|
{
|
||||||
public class IntegralManager : DomainService
|
public class IntegralManager : DomainService
|
||||||
{
|
{
|
||||||
private ISqlSugarRepository<LevelEntity> _levelRepository;
|
public ISqlSugarRepository<LevelEntity> _levelRepository;
|
||||||
private ISqlSugarRepository<SignInEntity> _signInRepository;
|
public ISqlSugarRepository<SignInEntity> _signInRepository;
|
||||||
private readonly ILocalEventBus _localEventBus;
|
private readonly ILocalEventBus _localEventBus;
|
||||||
public IntegralManager(ISqlSugarRepository<LevelEntity> levelRepository, ISqlSugarRepository<SignInEntity> signInRepository, ILocalEventBus localEventBus)
|
public IntegralManager(ISqlSugarRepository<LevelEntity> levelRepository, ISqlSugarRepository<SignInEntity> signInRepository, ILocalEventBus localEventBus)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,3 +6,10 @@ export function signIn() {
|
|||||||
method: "post"
|
method: "post"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function signInRecord() {
|
||||||
|
return request({
|
||||||
|
url: "/integral/sign-in/record",
|
||||||
|
method: "get"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { ElMessage, ElMessageBox } from "element-plus";
|
|||||||
import useUserStore from "@/stores/user";
|
import useUserStore from "@/stores/user";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { Session, Local } from "@/utils/storage";
|
import { Session, Local } from "@/utils/storage";
|
||||||
|
import{computed} from 'vue'
|
||||||
import {
|
import {
|
||||||
userLogin,
|
userLogin,
|
||||||
getUserDetailInfo,
|
getUserDetailInfo,
|
||||||
@@ -15,6 +16,8 @@ export const AUTH_USER = "AUTH_USER";
|
|||||||
|
|
||||||
export default function useAuths(opt) {
|
export default function useAuths(opt) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const defaultOpt = {
|
const defaultOpt = {
|
||||||
loginUrl: "/login", // 登录页跳转url 默认: /login
|
loginUrl: "/login", // 登录页跳转url 默认: /login
|
||||||
loginReUrl: "", // 登录页登陆成功后带重定向redirect=的跳转url 默认为空
|
loginReUrl: "", // 登录页登陆成功后带重定向redirect=的跳转url 默认为空
|
||||||
@@ -33,6 +36,14 @@ export default function useAuths(opt) {
|
|||||||
return token;
|
return token;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const isLogin=computed(()=>{
|
||||||
|
|
||||||
|
var token= Local.get(TokenKey);
|
||||||
|
return token? true : false;
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
// 存储token到cookies
|
// 存储token到cookies
|
||||||
const setToken = (token) => {
|
const setToken = (token) => {
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
@@ -179,6 +190,7 @@ export default function useAuths(opt) {
|
|||||||
logoutFun,
|
logoutFun,
|
||||||
clearStorage,
|
clearStorage,
|
||||||
registerFun,
|
registerFun,
|
||||||
loginSuccess
|
loginSuccess,
|
||||||
|
isLogin
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ import useAuths from "@/hooks/useAuths";
|
|||||||
import { Session } from "@/utils/storage";
|
import { Session } from "@/utils/storage";
|
||||||
import signalR from "@/utils/signalR";
|
import signalR from "@/utils/signalR";
|
||||||
|
|
||||||
const { getToken, clearStorage } = useAuths();
|
const { isLogin, clearStorage } = useAuths();
|
||||||
const configStore = useConfigStore();
|
const configStore = useConfigStore();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -130,8 +130,6 @@ const search = () => {
|
|||||||
router.push(routerPer);
|
router.push(routerPer);
|
||||||
};
|
};
|
||||||
|
|
||||||
const isLogin = getToken("AccessToken") ? true : false;
|
|
||||||
|
|
||||||
const handleGitClick = () => {
|
const handleGitClick = () => {
|
||||||
window.open("https://gitee.com/ccnetcore/Yi");
|
window.open("https://gitee.com/ccnetcore/Yi");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,26 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="everyday-box">
|
<div class="everyday-box">
|
||||||
<h4>每日签到页持续coding中~~~</h4>
|
<h4>每日签到页持续coding中~~~</h4>
|
||||||
|
<h5>当前已连续签到{{number}}天</h5>
|
||||||
|
|
||||||
<el-button type="primary" @click="signInOnclic">点击完成签到</el-button>
|
<el-button type="primary" @click="signInOnclic">点击完成签到</el-button>
|
||||||
|
|
||||||
|
<el-calendar v-model="signInRecordData">
|
||||||
|
<template #date-cell="{ data }">
|
||||||
|
<p :class="containSameDay(data.date) ? 'is-selected' : ''">
|
||||||
|
{{ data.day.split("-").slice(1).join("月") + "日" }}
|
||||||
|
<br/>
|
||||||
|
{{containSameDay(data.date)? "已签到✔️" : "" }}
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
</el-calendar>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref, reactive, computed, nextTick, watch } from "vue";
|
import { onMounted, ref, reactive, computed, nextTick, watch } from "vue";
|
||||||
import { signIn } from "@/apis/integralApi.js";
|
import { signIn, signInRecord } from "@/apis/integralApi.js";
|
||||||
|
import useAuths from "@/hooks/useAuths";
|
||||||
|
const { isLogin } = useAuths();
|
||||||
|
const number=ref(0);
|
||||||
|
const signInData=ref([]);
|
||||||
|
const signInRecordData = ref(new Date());
|
||||||
|
const signInOnclic = async () => {
|
||||||
|
const { data: data } = await signIn();
|
||||||
|
|
||||||
const signInOnclic= async()=>{
|
ElMessage({
|
||||||
const { data: data}= await signIn();
|
message: `恭喜!运气爆棚,今日获得:${data.value} 钱钱`,
|
||||||
|
type: "success",
|
||||||
ElMessage({
|
});
|
||||||
message: `恭喜!运气爆棚,今日获得:${data.value} 钱钱`,
|
};
|
||||||
type: "success",
|
|
||||||
});
|
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
//登录后才去查询签到记录
|
||||||
|
if (isLogin) {
|
||||||
|
const { data:{signInItem,currentContinuousNumber} } = await signInRecord();
|
||||||
|
number.value=currentContinuousNumber;
|
||||||
|
signInData.value=signInItem;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const containSameDay=(time)=>{
|
||||||
|
return signInData.value.filter(x=>isSameDay(x.creationTime,time)).length==0?false:true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断两个时间是否为同一天
|
||||||
|
const isSameDay=(time1, time2)=> {
|
||||||
|
const date1 = new Date(time1);
|
||||||
|
const date2 = new Date(time2);
|
||||||
|
return (
|
||||||
|
date1.getFullYear() === date2.getFullYear() &&
|
||||||
|
date1.getMonth() === date2.getMonth() &&
|
||||||
|
date1.getDate() === date2.getDate()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -30,4 +64,7 @@ const signInOnclic= async()=>{
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
.is-selected {
|
||||||
|
color: #1989fa;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user