diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e8ec2a --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +.DS_Store +node_modules +/dist + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* +target \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/controller/AppletMonthlyStatisticsController.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/controller/AppletMonthlyStatisticsController.java new file mode 100644 index 0000000..1c5b792 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/controller/AppletMonthlyStatisticsController.java @@ -0,0 +1,171 @@ +package org.jeecg.modules.appletMonthlyStatistics.controller; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.appletMonthlyStatistics.entity.AppletMonthlyStatistics; +import org.jeecg.modules.appletMonthlyStatistics.service.IAppletMonthlyStatisticsService; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.base.controller.JeecgController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import com.alibaba.fastjson.JSON; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.jeecg.common.aspect.annotation.AutoLog; + + /** + * @Description: 月度打卡情况统计 + * @Author: jeecg-boot + * @Date: 2025-10-13 + * @Version: V1.0 + */ +@Api(tags="月度打卡情况统计") +@RestController +@RequestMapping("/appletMonthlyStatistics/appletMonthlyStatistics") +@Slf4j +public class AppletMonthlyStatisticsController extends JeecgController { + @Autowired + private IAppletMonthlyStatisticsService appletMonthlyStatisticsService; + + /** + * 分页列表查询 + * + * @param appletMonthlyStatistics + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "月度打卡情况统计-分页列表查询") + @ApiOperation(value="月度打卡情况统计-分页列表查询", notes="月度打卡情况统计-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(AppletMonthlyStatistics appletMonthlyStatistics, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(appletMonthlyStatistics, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = appletMonthlyStatisticsService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param appletMonthlyStatistics + * @return + */ + @AutoLog(value = "月度打卡情况统计-添加") + @ApiOperation(value="月度打卡情况统计-添加", notes="月度打卡情况统计-添加") + @PostMapping(value = "/add") + public Result add(@RequestBody AppletMonthlyStatistics appletMonthlyStatistics) { + appletMonthlyStatisticsService.save(appletMonthlyStatistics); + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param appletMonthlyStatistics + * @return + */ + @AutoLog(value = "月度打卡情况统计-编辑") + @ApiOperation(value="月度打卡情况统计-编辑", notes="月度打卡情况统计-编辑") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody AppletMonthlyStatistics appletMonthlyStatistics) { + appletMonthlyStatisticsService.updateById(appletMonthlyStatistics); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "月度打卡情况统计-通过id删除") + @ApiOperation(value="月度打卡情况统计-通过id删除", notes="月度打卡情况统计-通过id删除") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + appletMonthlyStatisticsService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "月度打卡情况统计-批量删除") + @ApiOperation(value="月度打卡情况统计-批量删除", notes="月度打卡情况统计-批量删除") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.appletMonthlyStatisticsService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "月度打卡情况统计-通过id查询") + @ApiOperation(value="月度打卡情况统计-通过id查询", notes="月度打卡情况统计-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name="id",required=true) String id) { + AppletMonthlyStatistics appletMonthlyStatistics = appletMonthlyStatisticsService.getById(id); + if(appletMonthlyStatistics==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(appletMonthlyStatistics); + } + + /** + * 导出excel + * + * @param request + * @param appletMonthlyStatistics + */ + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, AppletMonthlyStatistics appletMonthlyStatistics) { + return super.exportXls(request, appletMonthlyStatistics, AppletMonthlyStatistics.class, "月度打卡情况统计"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, AppletMonthlyStatistics.class); + } + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/entity/AppletMonthlyStatistics.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/entity/AppletMonthlyStatistics.java new file mode 100644 index 0000000..2d541ea --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/entity/AppletMonthlyStatistics.java @@ -0,0 +1,67 @@ +package org.jeecg.modules.appletMonthlyStatistics.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.math.BigDecimal; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * @Description: 月度打卡情况统计 + * @Author: jeecg-boot + * @Date: 2025-10-13 + * @Version: V1.0 + */ +@Data +@TableName("applet_monthly_statistics") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value="applet_monthly_statistics对象", description="月度打卡情况统计") +public class AppletMonthlyStatistics implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键") + private java.lang.String id; + /**创建人*/ + @ApiModelProperty(value = "创建人") + private java.lang.String createBy; + /**创建日期*/ + @ApiModelProperty(value = "创建日期") + private java.util.Date createTime; + /**更新人*/ + @ApiModelProperty(value = "更新人") + private java.lang.String updateBy; + /**更新日期*/ + @ApiModelProperty(value = "更新日期") + private java.util.Date updateTime; + /**所属部门*/ + @ApiModelProperty(value = "所属部门") + private java.lang.String sysOrgCode; + /**用户*/ + @Excel(name = "用户", width = 15) + @ApiModelProperty(value = "用户") + private java.lang.String userId; + /**未打卡次数*/ + @Excel(name = "未打卡次数", width = 15) + @ApiModelProperty(value = "未打卡次数") + private java.lang.Integer notCheckeNumber; + /**月份*/ + @Excel(name = "月份", width = 15, format = "yyyy-MM-dd") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + @ApiModelProperty(value = "月份") + private java.util.Date month; +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/mapper/AppletMonthlyStatisticsMapper.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/mapper/AppletMonthlyStatisticsMapper.java new file mode 100644 index 0000000..893abc6 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/mapper/AppletMonthlyStatisticsMapper.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.appletMonthlyStatistics.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import org.jeecg.modules.appletMonthlyStatistics.entity.AppletMonthlyStatistics; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: 月度打卡情况统计 + * @Author: jeecg-boot + * @Date: 2025-10-13 + * @Version: V1.0 + */ +public interface AppletMonthlyStatisticsMapper extends BaseMapper { + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/mapper/xml/AppletMonthlyStatisticsMapper.xml b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/mapper/xml/AppletMonthlyStatisticsMapper.xml new file mode 100644 index 0000000..874e4ba --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/mapper/xml/AppletMonthlyStatisticsMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/service/IAppletMonthlyStatisticsService.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/service/IAppletMonthlyStatisticsService.java new file mode 100644 index 0000000..8fd2ee6 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/service/IAppletMonthlyStatisticsService.java @@ -0,0 +1,14 @@ +package org.jeecg.modules.appletMonthlyStatistics.service; + +import org.jeecg.modules.appletMonthlyStatistics.entity.AppletMonthlyStatistics; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @Description: 月度打卡情况统计 + * @Author: jeecg-boot + * @Date: 2025-10-13 + * @Version: V1.0 + */ +public interface IAppletMonthlyStatisticsService extends IService { + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/service/impl/AppletMonthlyStatisticsServiceImpl.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/service/impl/AppletMonthlyStatisticsServiceImpl.java new file mode 100644 index 0000000..b188410 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/service/impl/AppletMonthlyStatisticsServiceImpl.java @@ -0,0 +1,19 @@ +package org.jeecg.modules.appletMonthlyStatistics.service.impl; + +import org.jeecg.modules.appletMonthlyStatistics.entity.AppletMonthlyStatistics; +import org.jeecg.modules.appletMonthlyStatistics.mapper.AppletMonthlyStatisticsMapper; +import org.jeecg.modules.appletMonthlyStatistics.service.IAppletMonthlyStatisticsService; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * @Description: 月度打卡情况统计 + * @Author: jeecg-boot + * @Date: 2025-10-13 + * @Version: V1.0 + */ +@Service +public class AppletMonthlyStatisticsServiceImpl extends ServiceImpl implements IAppletMonthlyStatisticsService { + +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/AppletMonthlyStatisticsList.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/AppletMonthlyStatisticsList.vue new file mode 100644 index 0000000..496ae1b --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/AppletMonthlyStatisticsList.vue @@ -0,0 +1,186 @@ + + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/modules/AppletMonthlyStatisticsForm.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/modules/AppletMonthlyStatisticsForm.vue new file mode 100644 index 0000000..5e89694 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/modules/AppletMonthlyStatisticsForm.vue @@ -0,0 +1,114 @@ + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/modules/AppletMonthlyStatisticsModal.Style#Drawer.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/modules/AppletMonthlyStatisticsModal.Style#Drawer.vue new file mode 100644 index 0000000..67698d0 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/modules/AppletMonthlyStatisticsModal.Style#Drawer.vue @@ -0,0 +1,84 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/modules/AppletMonthlyStatisticsModal.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/modules/AppletMonthlyStatisticsModal.vue new file mode 100644 index 0000000..62d3473 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue/modules/AppletMonthlyStatisticsModal.vue @@ -0,0 +1,60 @@ + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/AppletMonthlyStatistics.api.ts b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/AppletMonthlyStatistics.api.ts new file mode 100644 index 0000000..111a0f8 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/AppletMonthlyStatistics.api.ts @@ -0,0 +1,61 @@ +import {defHttp} from '/@/utils/http/axios'; +import {Modal} from 'ant-design-vue'; + +enum Api { + list = '/appletMonthlyStatistics/appletMonthlyStatistics/list', + save='/appletMonthlyStatistics/appletMonthlyStatistics/add', + edit='/appletMonthlyStatistics/appletMonthlyStatistics/edit', + deleteOne = '/appletMonthlyStatistics/appletMonthlyStatistics/delete', + deleteBatch = '/appletMonthlyStatistics/appletMonthlyStatistics/deleteBatch', + importExcel = '/appletMonthlyStatistics/appletMonthlyStatistics/importExcel', + exportXls = '/appletMonthlyStatistics/appletMonthlyStatistics/exportXls', +} +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; +/** + * 导入api + */ +export const getImportUrl = Api.importExcel; +/** + * 列表接口 + * @param params + */ +export const list = (params) => + defHttp.get({url: Api.list, params}); + +/** + * 删除单个 + */ +export const deleteOne = (params,handleSuccess) => { + return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); +} +/** + * 批量删除 + * @param params + */ +export const batchDelete = (params, handleSuccess) => { + Modal.confirm({ + title: '确认删除', + content: '是否删除选中数据', + okText: '确认', + cancelText: '取消', + onOk: () => { + return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); + } + }); +} +/** + * 保存或者更新 + * @param params + */ +export const saveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({url: url, params}); +} diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/AppletMonthlyStatistics.data.ts b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/AppletMonthlyStatistics.data.ts new file mode 100644 index 0000000..bc67272 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/AppletMonthlyStatistics.data.ts @@ -0,0 +1,46 @@ +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +//列表数据 +export const columns: BasicColumn[] = [ + { + title: '用户', + align:"center", + dataIndex: 'userId' + }, + { + title: '未打卡次数', + align:"center", + dataIndex: 'notCheckeNumber' + }, + { + title: '月份', + align:"center", + dataIndex: 'month', + customRender:({text}) =>{ + return !text?"":(text.length>10?text.substr(0,10):text) + }, + }, +]; +//查询数据 +export const searchFormSchema: FormSchema[] = [ +]; +//表单数据 +export const formSchema: FormSchema[] = [ + { + label: '用户', + field: 'userId', + component: 'Input', + }, + { + label: '未打卡次数', + field: 'notCheckeNumber', + component: 'InputNumber', + }, + { + label: '月份', + field: 'month', + component: 'DatePicker', + }, +]; diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/AppletMonthlyStatisticsList.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/AppletMonthlyStatisticsList.vue new file mode 100644 index 0000000..60146a6 --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/AppletMonthlyStatisticsList.vue @@ -0,0 +1,162 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/components/AppletMonthlyStatisticsModal.vue b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/components/AppletMonthlyStatisticsModal.vue new file mode 100644 index 0000000..95fc4cd --- /dev/null +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/appletMonthlyStatistics/vue3/components/AppletMonthlyStatisticsModal.vue @@ -0,0 +1,58 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/clockinlog/service/impl/ClockinLogServiceImpl.java b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/clockinlog/service/impl/ClockinLogServiceImpl.java index a1ee32c..9c1703e 100644 --- a/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/clockinlog/service/impl/ClockinLogServiceImpl.java +++ b/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/modules/clockinlog/service/impl/ClockinLogServiceImpl.java @@ -28,4 +28,5 @@ public class ClockinLogServiceImpl extends ServiceImpl { +// try { +// Thread.sleep(15000); +// monthlyStatisticsJob(); +// } catch (InterruptedException e) { +// log.error("初始化执行任务被中断: {}", e.getMessage()); +// } +// }).start(); +// } + + /** + * 定时任务:每5分钟执行一次,统计上个月每个用户的未打卡次数 + * cron表达式:0 5 * * * ? 表示每5分钟执行一次(用于测试) + * 生产环境应改为:0 0 4 1 * ? (每月第一天4点执行) + */ + @Scheduled(cron = "0 0 4 1 * ?") + public void monthlyStatisticsJob() { + log.info("开始执行月度打卡统计定时任务..."); + + try { + // 获取上个月的日期 + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.MONTH, -1); + Date lastMonth = calendar.getTime(); + + // 获取所有有效用户 + List allUsers = clockinAuthService.lambdaQuery() +// .eq(HanHaiMember::getDeleteFlag, "0") +// .eq(HanHaiMember::getFrozenFlag, "0") + .list(); + + log.info("找到 {} 个有效用户需要统计", allUsers.size()); + + for (ClockinAuth user : allUsers) { + try { + // 统计该用户上个月的未打卡次数 + int notCheckedCount = calculateUserNotCheckedCount(user.getUserId(), lastMonth); + + // 保存统计结果 + saveMonthlyStatistics(user.getUserId(), lastMonth, notCheckedCount); + + log.debug("用户 {} 上个月未打卡次数: {}", user.getName(), notCheckedCount); + } catch (Exception e) { + log.error("统计用户 {} 的打卡数据时发生错误: {}", user.getName(), e.getMessage(), e); + } + } + + log.info("月度打卡统计定时任务执行完成"); + } catch (Exception e) { + log.error("执行月度打卡统计定时任务时发生错误: {}", e.getMessage(), e); + } + } + + /** + * 手动触发月度统计任务(用于测试) + */ + public void manualTriggerMonthlyStatistics() { + log.info("手动触发月度打卡统计任务..."); + monthlyStatisticsJob(); + } + + /** + * 计算用户指定月份的未打卡次数 + */ + private int calculateUserNotCheckedCount(String userId, Date month) { + // 获取用户所在团队 + ClockinTeamLog clockinTeamLog = clockinTeamLogService.lambdaQuery() + .eq(ClockinTeamLog::getDelFlag, 0) + .eq(ClockinTeamLog::getUserId, userId) + .one(); + + if (clockinTeamLog == null) { + log.warn("用户 {} 未绑定团队,跳过统计", userId); + return 0; + } + + // 获取团队对应的项目 + ClockInProject clockInProject = clockInProjectService.lambdaQuery() + .eq(ClockInProject::getDelFlag, 0) + .eq(ClockInProject::getTeamId, clockinTeamLog.getTeamId()) + .one(); + + if (clockInProject == null) { + log.warn("用户 {} 所在团队未配置项目,跳过统计", userId); + return 0; + } + + // 获取指定月份的天数 + String nowDay2 = DateUtils2.getNowDay2(DateUtils2.currentXDayOfMonth(month)); + Integer n = Integer.parseInt(nowDay2); + String yyyymm = DateUtils2.getYYYYMM(month); + + int notCheckedCount = 0; + Long todayDate = DateUtils2.getTodayTwelve(); + + for (int i = 1; i <= n; i++) { + String dd = i + ""; + if (i < 10) { + dd = "0" + i; + } + dd = "-" + dd; + String yyyymmdd = yyyymm + dd; + Long milliSecond = DateUtils2.getMilliSecond(yyyymmdd + " 23:59:59"); + + // 如果是未来日期,跳过 + if (milliSecond > todayDate) { + break; + } + + Date date2 = DateUtils2.getDate(yyyymmdd + " 23:59:59"); + LocalDateTime localDateTime = DateUtils2.dateToDateTime(date2); + Integer type = 0; + if (DayOfWeek.SATURDAY.equals(localDateTime.getDayOfWeek()) || DayOfWeek.SUNDAY.equals(localDateTime.getDayOfWeek())) { + type = 1; + } + + // 获取该日期应该打卡的次数 + List clockInProjectItemList = clockInProjectItemService.lambdaQuery() + .eq(ClockInProjectItem::getDelFlag, 0) + .eq(ClockInProjectItem::getType, type) + .eq(ClockInProjectItem::getProjectId, clockInProject.getId()) + .list(); + + // 获取用户实际打卡次数 + Integer clockInTotal = clockinLogService.getClockInTotal(userId, yyyymmdd); + + notCheckedCount += clockInTotal >= clockInProjectItemList.size() ? 0 : clockInProjectItemList.size() - clockInTotal; + } + + return notCheckedCount; + } + + /** + * 保存月度统计结果 + */ + private void saveMonthlyStatistics(String userId, Date month, int notCheckedCount) { + // 检查是否已存在该用户该月份的统计记录 + AppletMonthlyStatistics existingRecord = appletMonthlyStatisticsService.lambdaQuery() + .eq(AppletMonthlyStatistics::getUserId, userId) + .eq(AppletMonthlyStatistics::getMonth, month) + .one(); + + if (existingRecord != null) { + // 更新现有记录 + existingRecord.setNotCheckeNumber(notCheckedCount); + existingRecord.setUpdateTime(new Date()); + appletMonthlyStatisticsService.updateById(existingRecord); + log.debug("更新用户 {} 月度统计记录", userId); + } else { + // 创建新记录 + AppletMonthlyStatistics newRecord = new AppletMonthlyStatistics(); + newRecord.setUserId(userId); + newRecord.setMonth(month); + newRecord.setNotCheckeNumber(notCheckedCount); + newRecord.setCreateTime(new Date()); + appletMonthlyStatisticsService.save(newRecord); + log.debug("创建用户 {} 月度统计记录", userId); + } + } + +} diff --git a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/xcx/clockin/service/impl/ClockinServiceImpl.java b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/xcx/clockin/service/impl/ClockinServiceImpl.java index 3bd5eea..32afb64 100644 --- a/jeecg-boot-module-system/src/main/java/org/jeecg/modules/xcx/clockin/service/impl/ClockinServiceImpl.java +++ b/jeecg-boot-module-system/src/main/java/org/jeecg/modules/xcx/clockin/service/impl/ClockinServiceImpl.java @@ -232,7 +232,7 @@ public class ClockinServiceImpl implements IClockinService { Integer clockInTotal = clockinLogService.getClockInTotal(hanHaiMember.getId(), yyyymmdd); clockInTotalResp.setDate(yyyymmdd); - if(clockInTotal == 0){ + if(clockInTotal == 0){// 2未打卡 abnormal = abnormal+1; @@ -242,7 +242,7 @@ public class ClockinServiceImpl implements IClockinService { }else if(clockInTotal