后端代码提交

This commit is contained in:
zzp
2025-06-24 16:36:16 +08:00
parent 9c139cb43f
commit 15c340fd4d
643 changed files with 21444 additions and 0 deletions

View File

@@ -0,0 +1,142 @@
package com.zbkj.admin.controller;
import cn.hutool.core.date.DateUtil;
import com.zbkj.common.constants.DateConstants;
import com.zbkj.common.model.acticitystyle.ActivityStyle;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.ActivityStyleRequest;
import com.zbkj.common.request.ActivityStyleSearchRequest;
import com.zbkj.common.request.ActivityStyleUpdateStatusRequest;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.response.ActivityStyleResponse;
import com.zbkj.common.result.CommonResult;
import com.zbkj.common.utils.CrmebDateUtil;
import com.zbkj.service.service.ActivityStyleService;
import com.zbkj.service.service.SystemAttachmentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
/**
* 活动样式 前端控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/activitystyle")
@Api(tags = "活动样式") //配合swagger使用
public class ActivityStyleController {
@Autowired
private ActivityStyleService activityStyleService;
@Autowired
private SystemAttachmentService systemAttachmentService;
/**
* 分页显示
*
* @param request 搜索条件
* @param pageParamRequest 分页参数
* @author dazongzi
* @since 2023-01-05
*/
@PreAuthorize("hasAuthority('admin:activitystyle:list')")
@ApiOperation(value = "分页列表") //配合swagger使用
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<CommonPage<ActivityStyleResponse>> getList(@Validated ActivityStyleSearchRequest request,
@ModelAttribute PageParamRequest pageParamRequest) {
CommonPage<ActivityStyleResponse> activityStyleCommonPage = CommonPage.restPage(activityStyleService.getList(request, pageParamRequest));
return CommonResult.success(activityStyleCommonPage);
}
/**
* 新增
*
* @param activityStyleRequest 新增参数
* @author dazongzi
* @since 2023-01-05
*/
@PreAuthorize("hasAuthority('admin:activitystyle:save')")
@ApiOperation(value = "新增")
@RequestMapping(value = "/save", method = RequestMethod.POST)
public CommonResult<String> save(@RequestBody @Validated ActivityStyleRequest activityStyleRequest) {
ActivityStyle activityStyle = new ActivityStyle();
BeanUtils.copyProperties(activityStyleRequest, activityStyle);
activityStyle.setStarttime(CrmebDateUtil.strToDate(activityStyleRequest.getStarttime(), DateConstants.DATE_FORMAT));
activityStyle.setEndtime(CrmebDateUtil.strToDate(activityStyleRequest.getEndtime(), DateConstants.DATE_FORMAT));
activityStyle.setStyle(systemAttachmentService.clearPrefix(activityStyle.getStyle()));
if (activityStyleService.save(activityStyle)) {
return CommonResult.success();
} else {
return CommonResult.failed();
}
}
/**
* 删除
*
* @param id Integer
* @author dazongzi
* @since 2023-01-05
*/
@PreAuthorize("hasAuthority('admin:activitystyle:delete')")
@ApiOperation(value = "删除")
@RequestMapping(value = "/delete", method = RequestMethod.GET)
public CommonResult<String> delete(@RequestParam(value = "id") Integer id) {
if (activityStyleService.removeById(id)) {
return CommonResult.success();
} else {
return CommonResult.failed();
}
}
/**
* 修改
*
* @param activityStyleRequest 修改参数
* @author dazongzi
* @since 2023-01-05
*/
@PreAuthorize("hasAuthority('admin:activitystyle:edite')")
@ApiOperation(value = "修改")
@RequestMapping(value = "/update", method = RequestMethod.POST)
public CommonResult<String> update(@RequestBody @Validated ActivityStyleRequest activityStyleRequest) {
ActivityStyle activityStyle = new ActivityStyle();
BeanUtils.copyProperties(activityStyleRequest, activityStyle);
activityStyle.setId(activityStyleRequest.getId());
activityStyle.setStyle(systemAttachmentService.clearPrefix(activityStyle.getStyle()));
activityStyle.setStarttime(CrmebDateUtil.strToDate(activityStyleRequest.getStarttime(), DateConstants.DATE_FORMAT));
activityStyle.setEndtime(CrmebDateUtil.strToDate(activityStyleRequest.getEndtime(), DateConstants.DATE_FORMAT));
activityStyle.setUpdatetime(DateUtil.date());
if (activityStyleService.updateById(activityStyle)) {
return CommonResult.success();
} else {
return CommonResult.failed();
}
}
/**
* 更新状态
*/
@PreAuthorize("hasAuthority('admin:activitystyle:updatestatus')")
@ApiOperation(value = "更新状态")
@RequestMapping(value = "/status", method = RequestMethod.POST)
public CommonResult<String> updateStatus(@RequestBody @Validated ActivityStyleUpdateStatusRequest activityStyleUpdateStatusRequest) {
boolean result = activityStyleService.updateStatus(activityStyleUpdateStatusRequest.getId(), activityStyleUpdateStatusRequest.getStatus());
if (result) {
return CommonResult.success();
} else {
return CommonResult.failed();
}
}
}

View File

@@ -0,0 +1,47 @@
package com.zbkj.admin.controller;
import com.zbkj.admin.copyright.CopyrightInfoResponse;
import com.zbkj.admin.copyright.CopyrightUpdateInfoRequest;
import com.zbkj.admin.service.CopyrightService;
import com.zbkj.common.result.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* 版权控制器
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Slf4j
@RestController
@RequestMapping("api/admin/copyright")
@Api(tags = "版权控制器")
public class CopyrightController {
@Autowired
private CopyrightService copyrightService;
@PreAuthorize("hasAuthority('admin:copyright:get:info')")
@ApiOperation(value = "获取版权信息")
@RequestMapping(value = "/get/info", method = RequestMethod.GET)
public CommonResult<CopyrightInfoResponse> getInfo() {
return CommonResult.success(copyrightService.getInfo());
}
}

View File

@@ -0,0 +1,173 @@
package com.zbkj.admin.controller;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.page.PageDiy;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.page.PageDiyEditNameRequest;
import com.zbkj.common.request.page.PageDiyRequest;
import com.zbkj.common.response.page.PageDiyResponse;
import com.zbkj.common.result.CommonResult;
import com.zbkj.service.service.PageDiyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* DIY数据表 前端控制器
*/
@Slf4j
@RestController
@RequestMapping("api/admin/pagediy")
@Api(tags = "DIY 控制器") //配合swagger使用
public class PageDiyController {
@Autowired
private PageDiyService pageDiyService;
/**
* 分页显示DIY数据表
* @author dazongzi
* @since 2023-05-16
*/
@PreAuthorize("hasAuthority('admin:pagediy:list')")
@ApiOperation(value = "分页列表") //配合swagger使用
@RequestMapping(value = "/list", method = RequestMethod.GET)
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "搜索关键子", dataType = "String")
})
public CommonResult<CommonPage<PageDiy>> getList(@RequestParam String name,PageParamRequest pageParamRequest){
CommonPage<PageDiy> pageDiyCommonPage = CommonPage.restPage(pageDiyService.getList(name, pageParamRequest));
return CommonResult.success(pageDiyCommonPage);
}
/**
* 设置首页
* @param id 待设置的首页id
* @author dazongzi
* @since 2023-05-16
*/
@PreAuthorize("hasAuthority('admin:pagediy:setdefault')")
@ApiOperation(value = "设置商城首页")
@RequestMapping(value = "/setdefault/{id}", method = RequestMethod.GET)
public CommonResult<String> setDefault(@PathVariable(value = "id") Integer id ){
if(pageDiyService.setDiyPageHome(id)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 获取已经设置的首页模版数据
* @return 首页模版id
*/
@PreAuthorize("hasAuthority('admin:pagediy:getdefault')")
@ApiOperation(value = "获取商城首页")
@RequestMapping(value = "/getdefault", method = RequestMethod.GET)
public CommonResult<Integer> getDefault(){
return CommonResult.success(pageDiyService.getDiyPageHome(Boolean.TRUE).getId());
}
/**
* 新增DIY数据表
* @param pageDiyRequest 新增参数
* @author dazongzi
* @since 2023-05-16
*/
@PreAuthorize("hasAuthority('admin:pagediy:save')")
@ApiOperation(value = "新增")
@RequestMapping(value = "/save", method = RequestMethod.POST)
public CommonResult<PageDiy> save(@RequestBody @Validated PageDiyRequest pageDiyRequest){
PageDiy pageDiy = new PageDiy();
BeanUtils.copyProperties(pageDiyRequest, pageDiy);
pageDiy.setValue(JSON.toJSONString(pageDiyRequest.getValue()));
return CommonResult.success(pageDiyService.savePageDiy(pageDiy));
}
/**
* 删除DIY数据表
* @param id Integer
* @author dazongzi
* @since 2023-05-16
*/
@PreAuthorize("hasAuthority('admin:pagediy:delete')")
@ApiOperation(value = "删除")
@RequestMapping(value = "/delete", method = RequestMethod.GET)
public CommonResult<String> delete(@RequestParam(value = "id") Integer id){
if(pageDiyService.removeById(id)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 修改DIY数据表
* @param pageDiyRequest 修改参数
* @author dazongzi
* @since 2023-05-16
*/
@PreAuthorize("hasAuthority('admin:pagediy:update')")
@ApiOperation(value = "修改")
@RequestMapping(value = "/update", method = RequestMethod.POST)
public CommonResult<String> update(@RequestBody @Validated PageDiyRequest pageDiyRequest){
PageDiy pageDiy = new PageDiy();
BeanUtils.copyProperties(pageDiyRequest, pageDiy);
pageDiy.setValue(JSON.toJSONString(pageDiyRequest.getValue()));
if(pageDiyService.editPageDiy(pageDiy)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* DIY 模版名称更新
* @param pageDiyEditNameRequest 更新模版名称对象
* @return 更新结果
*/
@PreAuthorize("hasAuthority('admin:pagediy:updatename')")
@ApiOperation(value = "DIY 模版名称更新")
@RequestMapping(value = "/updatename", method = RequestMethod.POST)
public CommonResult<String> update(@RequestBody @Validated PageDiyEditNameRequest pageDiyEditNameRequest){
if(pageDiyService.editPageDiyName(pageDiyEditNameRequest)){
return CommonResult.success();
}else{
return CommonResult.failed();
}
}
/**
* 查询DIY数据表信息
* @param id Integer
* @author dazongzi
* @since 2023-05-16
*/
@PreAuthorize("hasAuthority('admin:pagediy:info')")
@ApiOperation(value = "详情")
@RequestMapping(value = "/info/{id}", method = RequestMethod.GET)
public CommonResult<PageDiyResponse> info(@PathVariable(value = "id") Integer id){
PageDiy pageDiy = pageDiyService.getDiyPageByPageIdForAdmin(id);
if(ObjectUtil.isNull(pageDiy)) throw new CrmebException("未找到对应模版信息");
PageDiyResponse response = new PageDiyResponse();
BeanUtils.copyProperties(pageDiy, response);
response.setValue(JSON.parseObject(pageDiy.getValue()));
return CommonResult.success(response);
}
}

View File

@@ -0,0 +1,158 @@
package com.zbkj.admin.controller;
import com.alibaba.fastjson.JSONObject;
import com.zbkj.common.response.pagelayout.PageLayoutBottomNavigationResponse;
import com.zbkj.common.result.CommonResult;
import com.zbkj.service.service.PageLayoutService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* 页面布局 前端控制器
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Slf4j
@RestController
@RequestMapping("api/admin/page/layout")
@Api(tags = "页面布局管理")
public class PageLayoutController {
@Autowired
private PageLayoutService pageLayoutService;
/**
* 页面首页
*/
@PreAuthorize("hasAuthority('admin:page:layout:index')")
@ApiOperation(value = "页面首页")
@RequestMapping(value = "/index", method = RequestMethod.GET)
public CommonResult<HashMap<String, Object>> index() {
return CommonResult.success(pageLayoutService.index());
}
/**
* 页面首页保存
*/
@PreAuthorize("hasAuthority('admin:page:layout:save')")
@ApiOperation(value = "页面首页保存(不建议调用)")
@RequestMapping(value = "/save", method = RequestMethod.POST)
public CommonResult<Object> save(@RequestBody JSONObject jsonObject) {
if (pageLayoutService.save(jsonObject)) {
return CommonResult.success();
}
return CommonResult.failed();
}
/**
* 页面首页banner保存
*/
@PreAuthorize("hasAuthority('admin:page:layout:index:banner:save')")
@ApiOperation(value = "页面首页banner保存")
@RequestMapping(value = "/index/banner/save", method = RequestMethod.POST)
public CommonResult<Object> indexBannerSave(@RequestBody JSONObject jsonObject) {
if (pageLayoutService.indexBannerSave(jsonObject)) {
return CommonResult.success();
}
return CommonResult.failed();
}
/**
* 页面首页menu保存
*/
@PreAuthorize("hasAuthority('admin:page:layout:index:menu:save')")
@ApiOperation(value = "页面首页menu保存")
@RequestMapping(value = "/index/menu/save", method = RequestMethod.POST)
public CommonResult<Object> indexMenuSave(@RequestBody JSONObject jsonObject) {
if (pageLayoutService.indexMenuSave(jsonObject)) {
return CommonResult.success();
}
return CommonResult.failed();
}
/**
* 页面首页新闻保存
*/
@PreAuthorize("hasAuthority('admin:page:layout:index:news:save')")
@ApiOperation(value = "页面首页新闻保存")
@RequestMapping(value = "/index/news/save", method = RequestMethod.POST)
public CommonResult<Object> indexNewsSave(@RequestBody JSONObject jsonObject) {
if (pageLayoutService.indexNewsSave(jsonObject)) {
return CommonResult.success();
}
return CommonResult.failed();
}
/**
* 页面用户中心banner保存
*/
@PreAuthorize("hasAuthority('admin:page:layout:index:banner:save')")
@ApiOperation(value = "页面用户中心banner保存")
@RequestMapping(value = "/user/banner/save", method = RequestMethod.POST)
public CommonResult<Object> userBannerSave(@RequestBody JSONObject jsonObject) {
if (pageLayoutService.userBannerSave(jsonObject)) {
return CommonResult.success();
}
return CommonResult.failed();
}
/**
* 页面用户中心导航保存
*/
@PreAuthorize("hasAuthority('admin:page:layout:user:menu:save')")
@ApiOperation(value = "页面用户中心导航保存")
@RequestMapping(value = "/user/menu/save", method = RequestMethod.POST)
public CommonResult<Object> userMenuSave(@RequestBody JSONObject jsonObject) {
if (pageLayoutService.userMenuSave(jsonObject)) {
return CommonResult.success();
}
return CommonResult.failed();
}
/**
* 页面用户中心商品table保存
*/
@PreAuthorize("hasAuthority('admin:page:layout:index:table:save')")
@ApiOperation(value = "页面用户中心商品table保存")
@RequestMapping(value = "/index/table/save", method = RequestMethod.POST)
public CommonResult<Object> indexTableSave(@RequestBody JSONObject jsonObject) {
if (pageLayoutService.indexTableSave(jsonObject)) {
return CommonResult.success();
}
return CommonResult.failed();
}
@PreAuthorize("hasAuthority('admin:page:layout:bottom:navigation')")
@ApiOperation(value = "页面底部导航")
@RequestMapping(value = "/bottom/navigation/get", method = RequestMethod.GET)
public CommonResult<PageLayoutBottomNavigationResponse> getBottomNavigation() {
return CommonResult.success(pageLayoutService.getBottomNavigation());
}
@PreAuthorize("hasAuthority('admin:page:layout:bottom:navigation:save')")
@ApiOperation(value = "底部导航保存")
@RequestMapping(value = "/bottom/navigation/save", method = RequestMethod.POST)
public CommonResult<Object> bottomNavigationSave(@RequestBody JSONObject jsonObject) {
if (pageLayoutService.bottomNavigationSave(jsonObject)) {
return CommonResult.success();
}
return CommonResult.failed();
}
}

View File

@@ -0,0 +1,124 @@
package com.zbkj.admin.controller;
import com.zbkj.admin.model.ScheduleJob;
import com.zbkj.admin.model.ScheduleJobLog;
import com.zbkj.admin.service.ScheduleJobLogService;
import com.zbkj.admin.service.ScheduleJobService;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.ScheduleJobLogSearchRequest;
import com.zbkj.common.request.ScheduleJobRequest;
import com.zbkj.common.result.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 定时任务控制器
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Slf4j
@RestController
@RequestMapping("api/admin/schedule/job")
@Api(tags = "定时任务控制器")
public class ScheduleJobController {
@Autowired
private ScheduleJobService scheduleJobService;
@Autowired
private ScheduleJobLogService scheduleJobLogService;
@PreAuthorize("hasAuthority('admin:schedule:job:list')")
@ApiOperation(value = "定时任务列表")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<List<ScheduleJob>> getList() {
return CommonResult.success(scheduleJobService.getAll());
}
@PreAuthorize("hasAuthority('admin:schedule:job:add')")
@ApiOperation(value = "添加定时任务")
@RequestMapping(value = "/add", method = RequestMethod.POST)
public CommonResult<String> add(@RequestBody @Validated ScheduleJobRequest request) {
if (scheduleJobService.add(request)) {
return CommonResult.success();
}
return CommonResult.failed();
}
@PreAuthorize("hasAuthority('admin:schedule:job:update')")
@ApiOperation(value = "定时任务编辑")
@RequestMapping(value = "/update", method = RequestMethod.POST)
public CommonResult<String> update(@RequestBody @Validated ScheduleJobRequest request) {
if (scheduleJobService.edit(request)) {
return CommonResult.success();
}
return CommonResult.failed();
}
@PreAuthorize("hasAuthority('admin:schedule:job:suspend')")
@ApiOperation(value = "暂停定时任务")
@RequestMapping(value = "/suspend/{jobId}", method = RequestMethod.POST)
public CommonResult<String> suspend(@PathVariable(value = "jobId") Integer jobId) {
if (scheduleJobService.suspend(jobId)) {
return CommonResult.success();
}
return CommonResult.failed();
}
@PreAuthorize("hasAuthority('admin:schedule:job:start')")
@ApiOperation(value = "启动定时任务")
@RequestMapping(value = "/start/{jobId}", method = RequestMethod.POST)
public CommonResult<String> start(@PathVariable(value = "jobId") Integer jobId) {
if (scheduleJobService.start(jobId)) {
return CommonResult.success();
}
return CommonResult.failed();
}
@PreAuthorize("hasAuthority('admin:schedule:job:delete')")
@ApiOperation(value = "删除定时任务")
@RequestMapping(value = "/delete/{jobId}", method = RequestMethod.POST)
public CommonResult<String> delete(@PathVariable(value = "jobId") Integer jobId) {
if (scheduleJobService.delete(jobId)) {
return CommonResult.success();
}
return CommonResult.failed();
}
@PreAuthorize("hasAuthority('admin:schedule:job:trig')")
@ApiOperation(value = "立即执行定时任务(一次)")
@RequestMapping(value = "/trig/{jobId}", method = RequestMethod.POST)
public CommonResult<String> trig(@PathVariable(value = "jobId") Integer jobId) {
if (scheduleJobService.trig(jobId)) {
return CommonResult.success();
}
return CommonResult.failed();
}
@PreAuthorize("hasAuthority('admin:schedule:job:log:list')")
@ApiOperation(value = "定时任务日志分页列表")
@RequestMapping(value = "/log/list", method = RequestMethod.GET)
public CommonResult<CommonPage<ScheduleJobLog>> getLogList(@Validated ScheduleJobLogSearchRequest request,
@Validated PageParamRequest pageParamRequest) {
return CommonResult.success(CommonPage.restPage(scheduleJobLogService.findLogPageList(request, pageParamRequest)));
}
}

View File

@@ -0,0 +1,59 @@
package com.zbkj.admin.controller;
import com.zbkj.common.response.*;
import com.zbkj.common.result.CommonResult;
import com.zbkj.service.service.UserStatisticsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 统计 -- 用户统计
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Slf4j
@RestController
@RequestMapping("api/admin/statistics/user")
@Api(tags = "用户统计")
public class UserStatisticsController {
@Autowired
private UserStatisticsService statisticsService;
@PreAuthorize("hasAuthority('admin:statistics:user:overview')")
@ApiOperation(value = "用户概览")
@RequestMapping(value = "/overview", method = RequestMethod.GET)
public CommonResult<UserOverviewResponse> getOverview(@RequestParam(value = "dateLimit", defaultValue = "") String dateLimit) {
return CommonResult.success(statisticsService.getOverview(dateLimit));
}
@PreAuthorize("hasAuthority('admin:statistics:user:channel')")
@ApiOperation(value = "用户渠道数据")
@RequestMapping(value = "/channel", method = RequestMethod.GET)
public CommonResult<List<UserChannelDataResponse>> getChannelData() {
return CommonResult.success(statisticsService.getChannelData());
}
@PreAuthorize("hasAuthority('admin:statistics:user:overview:list')")
@ApiOperation(value = "用户概览列表")
@RequestMapping(value = "/overview/list", method = RequestMethod.GET)
public CommonResult<List<UserOverviewDateResponse>> getOverviewList(@RequestParam(value = "dateLimit", defaultValue = "") String dateLimit) {
return CommonResult.success(statisticsService.getOverviewList(dateLimit));
}
}

View File

@@ -0,0 +1,50 @@
package com.zbkj.admin.copyright;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 版权信息响应对象
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "CopyrightInfoResponse对象", description = "版权信息响应对象")
public class CopyrightInfoResponse {
@ApiModelProperty(value = "管理端API域名")
private String domainUrl;
@ApiModelProperty(value = "项目版本号")
private String version;
@ApiModelProperty(value = "版权标签")
private Integer label;
@ApiModelProperty(value = "授权码")
private String authCode;
@ApiModelProperty(value = "版权状态:-2=API域名未配置 -1=未提交0-待审核1-授权成功2-审核失败")
private Integer status;
@ApiModelProperty(value = "公司信息")
private String companyName;
@ApiModelProperty(value = "公司图片")
private String companyImage;
@ApiModelProperty(value = "版权码")
private String copyright;
}

View File

@@ -0,0 +1,36 @@
package com.zbkj.admin.copyright;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
/**
* 编辑公司版权信息请求对象
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "CopyrightUpdateInfoRequest对象", description = "编辑公司版权信息请求对象")
public class CopyrightUpdateInfoRequest {
@ApiModelProperty(value = "公司信息")
@NotBlank(message = "公司信息不能为空")
private String companyName;
@ApiModelProperty(value = "公司图片")
// @NotBlank(message = "公司版权图片不能为空")
private String companyImage;
}

View File

@@ -0,0 +1,16 @@
package com.zbkj.admin.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.admin.model.ScheduleJob;
/**
* <p>
* 定时任务 Mapper 接口
* </p>
*
* @author HZW
* @since 2021-11-30
*/
public interface ScheduleJobDao extends BaseMapper<ScheduleJob> {
}

View File

@@ -0,0 +1,16 @@
package com.zbkj.admin.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.admin.model.ScheduleJobLog;
/**
* <p>
* 定时任务日志 Mapper 接口
* </p>
*
* @author HZW
* @since 2021-11-30
*/
public interface ScheduleJobLogDao extends BaseMapper<ScheduleJobLog> {
}

View File

@@ -0,0 +1,61 @@
package com.zbkj.admin.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 定时任务
* </p>
*
* @author HZW
* @since 2021-11-30
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_schedule_job")
@ApiModel(value="ScheduleJob对象", description="定时任务")
public class ScheduleJob implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "任务id")
@TableId(value = "job_id", type = IdType.AUTO)
private Integer jobId;
@ApiModelProperty(value = "spring bean名称")
private String beanName;
@ApiModelProperty(value = "方法名")
private String methodName;
@ApiModelProperty(value = "参数")
private String params;
@ApiModelProperty(value = "cron表达式")
private String cronExpression;
@ApiModelProperty(value = "任务状态 0正常 1暂停")
private Integer status;
@ApiModelProperty(value = "备注")
private String remark;
@ApiModelProperty(value = "是否删除")
private Boolean isDelte;
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

View File

@@ -0,0 +1,61 @@
package com.zbkj.admin.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 定时任务日志
* </p>
*
* @author HZW
* @since 2021-11-30
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_schedule_job_log")
@ApiModel(value="ScheduleJobLog对象", description="定时任务日志")
public class ScheduleJobLog implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "任务日志id")
@TableId(value = "log_id", type = IdType.AUTO)
private Integer logId;
@ApiModelProperty(value = "任务id")
private Integer jobId;
@ApiModelProperty(value = "spring bean名称")
private String beanName;
@ApiModelProperty(value = "方法名")
private String methodName;
@ApiModelProperty(value = "参数")
private String params;
@ApiModelProperty(value = "任务状态 0成功 1失败")
private Integer status;
@ApiModelProperty(value = "失败信息")
private String error;
@ApiModelProperty(value = "耗时(单位:毫秒)")
private Integer times;
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

View File

@@ -0,0 +1,55 @@
package com.zbkj.admin.pub;
import com.anji.captcha.model.common.ResponseModel;
import com.zbkj.common.result.CommonResult;
import com.zbkj.service.service.SafetyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* 安全验证控制器
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Slf4j
@RestController
@RequestMapping("api/public/safety")
@Api(tags = "安全验证控制器")
public class SafetyController {
@Autowired
private SafetyService safetyService;
@ApiOperation(value = "获取行为验证码")
@RequestMapping(value = "/get", method = RequestMethod.POST)
public CommonResult<ResponseModel> getSafetyCode(@RequestBody com.anji.captcha.model.vo.CaptchaVO data, HttpServletRequest request) {
return CommonResult.success(safetyService.getSafetyCode(data, request));
}
@ApiOperation(value = "验证行为验证码")
@RequestMapping(value = "/check", method = RequestMethod.POST)
public CommonResult<ResponseModel> checkSafetyCode(@RequestBody com.anji.captcha.model.vo.CaptchaVO data, HttpServletRequest request) {
return CommonResult.success(safetyService.checkSafetyCode(data, request));
}
@ApiOperation(value = "行为验证码二次校验")
@RequestMapping(value = "/verify", method = RequestMethod.POST)
public CommonResult<ResponseModel> verifySafetyCode(@RequestBody com.anji.captcha.model.vo.CaptchaVO data, HttpServletRequest request) {
return CommonResult.success(safetyService.verifySafetyCode(data));
}
}

View File

@@ -0,0 +1,43 @@
package com.zbkj.admin.pub;
import com.alibaba.fastjson.JSONObject;
import com.zbkj.common.result.CommonResult;
import com.zbkj.common.vo.QrCodeVo;
import com.zbkj.service.service.QrCodeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* 类的详细说明
*
* @author Han
* @version 1.0.0
* @Date 2025/11/25
*/
@Slf4j
@RestController
@RequestMapping("api/public/wechat/mini")
@Api(tags = "微信小程序公共控制器")
public class WechatMiniCommonController {
@Autowired
private QrCodeService qrCodeService;
@ApiOperation(value = "获取微信二维码")
@RequestMapping(value = "/get/qrcode", method = RequestMethod.POST)
@ApiImplicitParams({
@ApiImplicitParam(name = "data", value = "生成小程序码 path 和 scene 不能为空 可查看具体参数https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html#%E8%B0%83%E7%94%A8%E6%96%B9%E5%BC%8F", dataType = "JSONObject", required = true, paramType = "body")
})
public CommonResult<QrCodeVo> getWecahtQrCode(@RequestBody JSONObject data) {
return CommonResult.success(qrCodeService.getWecahtQrCode(data));
}
}

View File

@@ -0,0 +1,35 @@
package com.zbkj.admin.quartz;
import com.zbkj.admin.model.ScheduleJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
/**
* 该类将会被org.springframework.scheduling.quartz.SpringBeanJobFactory 实例化
* 并使@Autowired 生效
* @Author 指缝de阳光
* @Date 2021/11/30 12:10
* @Version 1.0
*/
@Slf4j
@DisallowConcurrentExecution
public class QuartzJob implements Job {
@Autowired
private ApplicationEventPublisher publisher;
/**
* 任务调度参数key
*/
public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY";
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDataMap mergedJobDataMap = jobExecutionContext.getMergedJobDataMap();
Object o = mergedJobDataMap.get(JOB_PARAM_KEY);
ScheduleJob sysJob = (ScheduleJob) o;
publisher.publishEvent(new ScheduleJobEvent(sysJob));
}
}

View File

@@ -0,0 +1,13 @@
package com.zbkj.admin.quartz;
/**
* @Author 指缝de阳光
* @Date 2021/11/30 12:19
* @Version 1.0
*/
public class ScheduleConstants {
public static final Integer NORMAL = 0;// 正常
public static final Integer PAUSE = 1;// 暂停
}

View File

@@ -0,0 +1,15 @@
package com.zbkj.admin.quartz;
import com.zbkj.admin.model.ScheduleJob;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 定时任务事件
*/
@Getter
@AllArgsConstructor
public class ScheduleJobEvent {
private final ScheduleJob scheduleJob;
}

View File

@@ -0,0 +1,165 @@
package com.zbkj.admin.quartz;
import com.zbkj.admin.model.ScheduleJob;
import lombok.AllArgsConstructor;
import org.quartz.*;
import org.springframework.stereotype.Component;
/**
* 定时任务工具类
* @Author 指缝de阳光
* @Date 2021/11/30 12:16
* @Version 1.0
*/
@Component
@AllArgsConstructor
public class ScheduleManager {
private final static String JOB_NAME = "TASK_";
private final Scheduler scheduler;
/**
* 获取触发器key
*/
private TriggerKey getTriggerKey(ScheduleJob scheduleJob) {
return TriggerKey.triggerKey(JOB_NAME + scheduleJob.getJobId());
}
/**
* 获取jobKey
*/
private JobKey getJobKey(ScheduleJob scheduleJob) {
return JobKey.jobKey(JOB_NAME + scheduleJob.getJobId());
}
/**
* 获取表达式触发器
*/
public CronTrigger getCronTrigger(ScheduleJob scheduleJob) {
try {
return (CronTrigger) scheduler.getTrigger(getTriggerKey(scheduleJob));
} catch (SchedulerException e) {
throw new RuntimeException("获取定时任务CronTrigger出现异常", e);
}
}
/**
* 创建定时任务
*/
public void createScheduleJob(ScheduleJob scheduleJob) {
try {
//构建job信息
JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class).withIdentity(getJobKey(scheduleJob)).build();
//表达式调度构建器可以根据scheduleJob修改withMisfireHandling方法但是使用异步执行定时任务没必要
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
.withMisfireHandlingInstructionFireAndProceed();
//按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob)).withSchedule(scheduleBuilder).build();
//放入参数,运行时的方法可以获取
jobDetail.getJobDataMap().put(QuartzJob.JOB_PARAM_KEY, scheduleJob);
scheduler.scheduleJob(jobDetail, trigger);
//暂停任务
if (scheduleJob.getStatus().equals(ScheduleConstants.PAUSE)) {
pauseJob(scheduleJob);
}
} catch (SchedulerException e) {
throw new RuntimeException("创建定时任务失败", e);
}
}
/**
* 更新定时任务
*/
public void updateScheduleJob(ScheduleJob scheduleJob) {
try {
TriggerKey triggerKey = getTriggerKey(scheduleJob);
//表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()).withMisfireHandlingInstructionFireAndProceed();
CronTrigger trigger = getCronTrigger(scheduleJob);
// 如果定时任务不存在,则创建定时任务
if (trigger == null) {
createScheduleJob(scheduleJob);
return;
}
//按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
//参数
trigger.getJobDataMap().put(QuartzJob.JOB_PARAM_KEY, scheduleJob);
scheduler.rescheduleJob(triggerKey, trigger);
//暂停任务
if (scheduleJob.getStatus().equals(ScheduleConstants.PAUSE)) {
pauseJob(scheduleJob);
}
} catch (SchedulerException e) {
throw new RuntimeException("更新定时任务失败", e);
}
}
/**
* 立即执行任务
*/
public void run(ScheduleJob scheduleJob) {
try {
//参数
JobDataMap dataMap = new JobDataMap();
dataMap.put(QuartzJob.JOB_PARAM_KEY, scheduleJob);
scheduler.triggerJob(getJobKey(scheduleJob), dataMap);
} catch (SchedulerException e) {
throw new RuntimeException("立即执行定时任务失败", e);
}
}
/**
* 暂停任务
*/
public void pauseJob(ScheduleJob scheduleJob) {
try {
scheduler.pauseJob(getJobKey(scheduleJob));
} catch (SchedulerException e) {
throw new RuntimeException("暂停定时任务失败", e);
}
}
/**
* 恢复任务
*/
public void resumeJob(ScheduleJob scheduleJob) {
try {
scheduler.resumeJob(getJobKey(scheduleJob));
} catch (SchedulerException e) {
throw new RuntimeException("恢复定时任务失败", e);
}
}
/**
* 删除定时任务
*/
public void deleteScheduleJob(ScheduleJob scheduleJob) {
try {
// 停止触发器
scheduler.pauseTrigger(getTriggerKey(scheduleJob));
//移除触发器
scheduler.unscheduleJob(getTriggerKey(scheduleJob));
//删除任务
scheduler.deleteJob(getJobKey(scheduleJob));
} catch (SchedulerException e) {
throw new RuntimeException("删除定时任务失败", e);
}
}
}

View File

@@ -0,0 +1,74 @@
package com.zbkj.admin.quartz;
import cn.hutool.core.date.SystemClock;
import cn.hutool.core.util.StrUtil;
import com.zbkj.admin.model.ScheduleJob;
import com.zbkj.admin.model.ScheduleJobLog;
import com.zbkj.admin.service.ScheduleJobLogService;
import com.zbkj.admin.util.SpringBeanTaskUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 异步监听定时任务事件解决job线程无故丢失的问题
* @Author 指缝de阳光
* @Date 2021/11/30 16:59
* @Version 1.0
*/
@Slf4j
@Component
@EnableAsync
@AllArgsConstructor
public class SysJobListener {
private final ScheduleJobLogService scheduleJobLogService;
@Async
@EventListener(ScheduleJobEvent.class)
public void scheduleJobEventListener(ScheduleJobEvent event) {
ScheduleJob scheduleJob = event.getScheduleJob();
//数据库保存执行记录
ScheduleJobLog jobLog = new ScheduleJobLog();
jobLog.setJobId(scheduleJob.getJobId());
jobLog.setBeanName(scheduleJob.getBeanName());
jobLog.setMethodName(scheduleJob.getMethodName());
jobLog.setParams(scheduleJob.getParams());
jobLog.setCreateTime(new Date());
//任务开始时间
long startTime = SystemClock.now();
try {
//执行任务
log.info("任务准备执行任务ID" + scheduleJob.getJobId());
SpringBeanTaskUtil.invokeMethod(scheduleJob);
//任务执行总时长
long times = SystemClock.now() - startTime;
jobLog.setTimes((int)times);
jobLog.setStatus(1);
StringBuilder sb = new StringBuilder();
log.info(sb.append("任务执行完毕任务ID").append(jobLog.getJobId()).append(" 总共耗时:").append(times).append("毫秒").toString());
} catch (Exception e) {
log.error("任务执行失败任务ID" + scheduleJob.getJobId(), e);
//任务执行总时长
long times = SystemClock.now() - startTime;
jobLog.setTimes((int)times);
jobLog.setStatus(0);
jobLog.setError(StrUtil.sub(e.toString(), 0, 2000));
} finally {
scheduleJobLogService.save(jobLog);
}
}
}

View File

@@ -0,0 +1,25 @@
package com.zbkj.admin.service;
import com.zbkj.admin.copyright.CopyrightInfoResponse;
import com.zbkj.admin.copyright.CopyrightUpdateInfoRequest;
/**
* 版权服务
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public interface CopyrightService {
/**
* 获取版权信息
*/
CopyrightInfoResponse getInfo();
}

View File

@@ -0,0 +1,29 @@
package com.zbkj.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.pagehelper.PageInfo;
import com.zbkj.admin.model.ScheduleJobLog;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.ScheduleJobLogSearchRequest;
/**
* @author HZW
* @description ScheduleJobLogService 接口
* @date 2021-11-30
*/
public interface ScheduleJobLogService extends IService<ScheduleJobLog> {
/**
* 自动删除日志
*/
void autoDeleteLog();
/**
* 日志分页列表
*
* @param request 搜索参数
* @param pageRequest 分页参数
* @return PageInfo
*/
PageInfo<ScheduleJobLog> findLogPageList(ScheduleJobLogSearchRequest request, PageParamRequest pageRequest);
}

View File

@@ -0,0 +1,69 @@
package com.zbkj.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zbkj.admin.model.ScheduleJob;
import com.zbkj.common.request.ScheduleJobRequest;
import java.util.List;
/**
* ScheduleJobService 接口
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public interface ScheduleJobService extends IService<ScheduleJob> {
/**
* 所有定时任务列表
*/
List<ScheduleJob> getAll();
/**
* 添加定时任务
*
* @param request 参数
*/
Boolean add(ScheduleJobRequest request);
/**
* 定时任务编辑
*
* @param request 编辑参数
*/
Boolean edit(ScheduleJobRequest request);
/**
* 暂停定时任务
*
* @param jobId 定时任务ID
*/
Boolean suspend(Integer jobId);
/**
* 启动定时任务
*
* @param jobId 定时任务ID
*/
Boolean start(Integer jobId);
/**
* 删除定时任务
*
* @param jobId 定时任务ID
*/
Boolean delete(Integer jobId);
/**
* 立即触发定时任务(一次)
*
* @param jobId 定时任务ID
*/
Boolean trig(Integer jobId);
}

View File

@@ -0,0 +1,56 @@
package com.zbkj.admin.service.impl;
import com.anji.captcha.service.CaptchaCacheService;
import com.zbkj.common.utils.RedisUtil;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
* 对于分布式部署的应用我们建议应用自己实现CaptchaCacheService比如用Redis参考service/spring-boot代码示例。
* 如果应用是单点的也没有使用redis那默认使用内存。
* 内存缓存只适合单节点部署的应用,否则验证码生产与验证在节点之间信息不同步,导致失败。
*
* ☆☆☆ SPI 在resources目录新建META-INF.services文件夹(两层)参考当前服务resources。
*
* @author Han
* @version 1.0.0
* @Date 2025/6/13
*/
public class CaptchaCacheServiceRedisImpl implements CaptchaCacheService {
@Resource
private RedisUtil redisUtil;
@Override
public String type() {
return "redis";
}
@Override
public void set(String key, String value, long expiresInSeconds) {
redisUtil.getRedisTemplate().opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS);
}
@Override
public boolean exists(String key) {
return Boolean.TRUE.equals(redisUtil.getRedisTemplate().hasKey(key));
}
@Override
public void delete(String key) {
redisUtil.getRedisTemplate().delete(key);
}
@Override
public String get(String key) {
return (String) redisUtil.getRedisTemplate().opsForValue().get(key);
}
@Override
public Long increment(String key, long val) {
return redisUtil.getRedisTemplate().opsForValue().increment(key,val);
}
}

View File

@@ -0,0 +1,88 @@
package com.zbkj.admin.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.zbkj.admin.copyright.CopyrightInfoResponse;
import com.zbkj.admin.copyright.CopyrightUpdateInfoRequest;
import com.zbkj.admin.service.CopyrightService;
import com.zbkj.common.config.CrmebConfig;
import com.zbkj.common.constants.Constants;
import com.zbkj.common.constants.SysConfigConstants;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.utils.RestTemplateUtil;
import com.zbkj.service.service.SystemAttachmentService;
import com.zbkj.service.service.SystemConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 版权服务实现类
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Service
public class CopyrightServiceImpl implements CopyrightService {
@Autowired
private SystemConfigService systemConfigService;
@Autowired
private CrmebConfig crmebConfig;
@Autowired
private RestTemplateUtil restTemplateUtil;
private static final String CRMEB_COPYRIGHT_URL = "https://authorize.crmeb.net/api/auth_cert_query?domain_name={}&label={}&version={}";
private static final String CRMEB_COPYRIGHT_URL_DATA = "data";
private static final String CRMEB_COPYRIGHT_URL_STATUS = "status";
private static final String CRMEB_COPYRIGHT_URL_COPYRIGHT = "copyright";
private static final String CRMEB_COPYRIGHT_URL_AUTHCODE = "auth_code";
/**
* 获取版权信息
*/
@Override
public CopyrightInfoResponse getInfo() {
CopyrightInfoResponse response = new CopyrightInfoResponse();
String domainName = systemConfigService.getValueByKey(Constants.CONFIG_KEY_API_URL);
if (StrUtil.isBlank(domainName)) {
response.setStatus(-2);
return response;
}
String label = systemConfigService.getValueByKey(SysConfigConstants.CONFIG_COPYRIGHT_LABEL);
String version = crmebConfig.getVersion();
if (StrUtil.isBlank(version)) {
throw new CrmebException("请先在yml中配置版本号");
}
response.setDomainUrl(domainName);
response.setLabel(Integer.parseInt(label));
response.setVersion(version);
JSONObject jsonObject = restTemplateUtil.post(StrUtil.format(CRMEB_COPYRIGHT_URL, domainName, label, version));
if (ObjectUtil.isNull(jsonObject.getInteger("status")) || !jsonObject.getInteger("status").equals(200)) {
throw new CrmebException("CRMEB版权接口调用失败," + jsonObject);
}
System.out.println("==================================== " + jsonObject.toString());
JSONObject dataJson = jsonObject.getJSONObject(CRMEB_COPYRIGHT_URL_DATA);
response.setStatus(dataJson.getInteger(CRMEB_COPYRIGHT_URL_STATUS));
response.setCopyright(dataJson.getString(CRMEB_COPYRIGHT_URL_COPYRIGHT));
if (!dataJson.getInteger(CRMEB_COPYRIGHT_URL_STATUS).equals(1)) {
return response;
}
response.setAuthCode(dataJson.getString(CRMEB_COPYRIGHT_URL_AUTHCODE));
response.setCompanyName(systemConfigService.getValueByKey(SysConfigConstants.CONFIG_COPYRIGHT_COMPANY_INFO));
response.setCompanyImage(systemConfigService.getValueByKey(SysConfigConstants.CONFIG_COPYRIGHT_COMPANY_IMAGE));
return response;
}
}

View File

@@ -0,0 +1,75 @@
package com.zbkj.admin.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.admin.dao.ScheduleJobLogDao;
import com.zbkj.admin.model.ScheduleJobLog;
import com.zbkj.admin.service.ScheduleJobLogService;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.ScheduleJobLogSearchRequest;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
* @author HZW
* @description ScheduleJobLogServiceImpl 接口实现
* @date 2021-11-30
*/
@Service
public class ScheduleJobLogServiceImpl extends ServiceImpl<ScheduleJobLogDao, ScheduleJobLog> implements ScheduleJobLogService {
@Resource
private ScheduleJobLogDao dao;
/**
* 自动删除日志
*/
@Override
public void autoDeleteLog() {
String beforeDate = DateUtil.offsetDay(new Date(), -9).toString("yyyy-MM-dd");
UpdateWrapper<ScheduleJobLog> wrapper = Wrappers.update();
wrapper.lt("create_time", beforeDate);
dao.delete(wrapper);
}
/**
* 日志分页列表
*
* @param request 搜索参数
* @param pageRequest 分页参数
* @return PageInfo
*/
@Override
public PageInfo<ScheduleJobLog> findLogPageList(ScheduleJobLogSearchRequest request, PageParamRequest pageRequest) {
Page<ScheduleJobLog> page = PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit());
LambdaQueryWrapper<ScheduleJobLog> lqw = Wrappers.lambdaQuery();
if (ObjectUtil.isNotNull(request.getJobId())) {
lqw.eq(ScheduleJobLog::getJobId, request.getJobId());
}
if (StrUtil.isNotBlank(request.getBeanName())) {
lqw.eq(ScheduleJobLog::getBeanName, request.getBeanName());
}
if (StrUtil.isNotBlank(request.getMethodName())) {
lqw.eq(ScheduleJobLog::getMethodName, request.getMethodName());
}
if (ObjectUtil.isNotNull(request.getStatus())) {
lqw.eq(ScheduleJobLog::getStatus, request.getStatus());
}
lqw.orderByDesc(ScheduleJobLog::getLogId);
List<ScheduleJobLog> list = dao.selectList(lqw);
return CommonPage.copyPageInfo(page, list);
}
}

View File

@@ -0,0 +1,194 @@
package com.zbkj.admin.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zbkj.admin.dao.ScheduleJobDao;
import com.zbkj.admin.model.ScheduleJob;
import com.zbkj.admin.quartz.ScheduleConstants;
import com.zbkj.admin.quartz.ScheduleManager;
import com.zbkj.admin.service.ScheduleJobService;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.request.ScheduleJobRequest;
import org.quartz.CronTrigger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
/**
* ScheduleJobServiceImpl 接口实现
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Service
public class ScheduleJobServiceImpl extends ServiceImpl<ScheduleJobDao, ScheduleJob> implements ScheduleJobService {
@Resource
private ScheduleJobDao dao;
@Autowired
private ScheduleManager scheduleManager;
/**
* 项目启动时,初始化定时器
*/
@PostConstruct
public void init() {
getAll().forEach(scheduleJob -> {
CronTrigger trigger = scheduleManager.getCronTrigger(scheduleJob);
// 如果定时任务不存在,则创建定时任务
if (trigger == null) {
scheduleManager.createScheduleJob(scheduleJob);
} else if (ScheduleConstants.NORMAL.equals(scheduleJob.getStatus())) {
scheduleManager.resumeJob(scheduleJob);
} else if (ScheduleConstants.PAUSE.equals(scheduleJob.getStatus())) {
scheduleManager.pauseJob(scheduleJob);
}
});
}
/**
* 获取所有的job
*
* @return List<ScheduleJob>
*/
@Order
public List<ScheduleJob> getAll() {
LambdaQueryWrapper<ScheduleJob> lqw = Wrappers.lambdaQuery();
lqw.eq(ScheduleJob::getIsDelte, false);
lqw.orderByDesc(ScheduleJob::getJobId);
return dao.selectList(lqw);
}
/**
* 添加定时任务
*
* @param request 参数
*/
@Override
public Boolean add(ScheduleJobRequest request) {
ScheduleJob scheduleJob = new ScheduleJob();
BeanUtils.copyProperties(request, scheduleJob);
scheduleJob.setJobId(null);
scheduleJob.setStatus(ScheduleConstants.PAUSE);
scheduleJob.setIsDelte(false);
boolean save = save(scheduleJob);
if (save) {
scheduleManager.createScheduleJob(scheduleJob);
}
return save;
}
/**
* 定时任务编辑
*
* @param request 编辑参数
*/
@Override
public Boolean edit(ScheduleJobRequest request) {
if (ObjectUtil.isNull(request.getJobId())) {
throw new CrmebException("定时任务ID不能为空");
}
ScheduleJob scheduleJob = getByIdException(request.getJobId());
if (scheduleJob.getStatus().equals(ScheduleConstants.NORMAL)) {
throw new CrmebException("请先暂停定时任务");
}
BeanUtils.copyProperties(request, scheduleJob);
boolean update = updateById(scheduleJob);
if (update) {
scheduleManager.updateScheduleJob(scheduleJob);
}
return update;
}
/**
* 暂停定时任务
*
* @param jobId 定时任务ID
*/
@Override
public Boolean suspend(Integer jobId) {
ScheduleJob scheduleJob = getByIdException(jobId);
if (scheduleJob.getStatus().equals(ScheduleConstants.PAUSE)) {
throw new CrmebException("定时任务已暂停,请勿重复操作");
}
scheduleJob.setStatus(ScheduleConstants.PAUSE);
boolean update = updateById(scheduleJob);
if (update) {
scheduleManager.pauseJob(scheduleJob);
}
return update;
}
/**
* 启动定时任务
*
* @param jobId 定时任务ID
*/
@Override
public Boolean start(Integer jobId) {
ScheduleJob scheduleJob = getByIdException(jobId);
if (scheduleJob.getStatus().equals(ScheduleConstants.NORMAL)) {
throw new CrmebException("定时任务已启动,请勿重复操作");
}
scheduleJob.setStatus(ScheduleConstants.NORMAL);
boolean update = updateById(scheduleJob);
if (update) {
scheduleManager.resumeJob(scheduleJob);
}
return update;
}
/**
* 删除定时任务
*
* @param jobId 定时任务ID
*/
@Override
public Boolean delete(Integer jobId) {
ScheduleJob scheduleJob = getByIdException(jobId);
if (scheduleJob.getStatus().equals(ScheduleConstants.NORMAL)) {
throw new CrmebException("请先暂停定时任务");
}
scheduleJob.setIsDelte(true);
boolean delete = updateById(scheduleJob);
if (delete) {
scheduleManager.deleteScheduleJob(scheduleJob);
}
return delete;
}
/**
* 立即触发定时任务(一次)
*
* @param jobId 定时任务ID
*/
@Override
public Boolean trig(Integer jobId) {
ScheduleJob scheduleJob = getByIdException(jobId);
scheduleManager.run(scheduleJob);
return Boolean.TRUE;
}
private ScheduleJob getByIdException(Integer jobId) {
ScheduleJob scheduleJob = getById(jobId);
if (ObjectUtil.isNull(scheduleJob) || scheduleJob.getIsDelte()) {
throw new CrmebException("定时任务不存在");
}
return scheduleJob;
}
}

View File

@@ -0,0 +1,41 @@
package com.zbkj.admin.task.order;
import com.zbkj.common.utils.CrmebDateUtil;
import com.zbkj.service.service.OrderTaskService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 系统自动确认收货Task
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB赋能开发者助力企业发展 ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Component("OrderAutoReceiptTask")
public class OrderAutoReceiptTask {
private static final Logger LOGGER = LoggerFactory.getLogger(OrderAutoReceiptTask.class);
@Autowired
private OrderTaskService orderTaskService;
public void autoTakeDelivery() {
// cron : 0 0 0 */1 * ?
LOGGER.info("---OrderAutoReceiptTask task------produce Data with fixed rate task: Execution Time - {}", CrmebDateUtil.nowDateTime());
try {
orderTaskService.autoTakeDelivery();
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("OrderAutoReceiptTask.exception" + " | msg : " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,36 @@
package com.zbkj.admin.util;
import cn.hutool.core.util.StrUtil;
import com.zbkj.common.utils.SpringUtil;
import com.zbkj.admin.model.ScheduleJob;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
/**
* 定时任务spring bean 执行定时任务
* @Author 指缝de阳光
* @Date 2021/11/30 17:00
* @Version 1.0
*/
public class SpringBeanTaskUtil {
public static void invokeMethod(ScheduleJob scheduleJob) {
Object target = SpringUtil.getBean(scheduleJob.getBeanName());
try {
if (StrUtil.isNotEmpty(scheduleJob.getParams())) {
Method method = target.getClass().getDeclaredMethod(scheduleJob.getMethodName(), String.class);
ReflectionUtils.makeAccessible(method);
method.invoke(target, scheduleJob.getParams());
} else {
Method method = target.getClass().getDeclaredMethod(scheduleJob.getMethodName());
ReflectionUtils.makeAccessible(method);
method.invoke(target);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("执行定时任务失败", e);
}
}
}

View File

@@ -0,0 +1,9 @@
{
"properties": [
{
"name": "wx.miniapp.configs",
"type": "java.util.List",
"description": "Description for wx.miniapp.configs."
}
]
}

View File

@@ -0,0 +1 @@
com.zbkj.admin.service.impl.CaptchaCacheServiceRedisImpl

View File

@@ -0,0 +1,68 @@
# CRMEB 相关配置
crmeb:
version: CRMEB-JAVA-KY-v1.4 # 当前代码版本
domain: #配合swagger使用 # 待部署域名
wechat-api-url: #请求微信接口中专服务器
wechat-js-api-debug: false #微信js api系列是否开启调试模式
wechat-js-api-beta: true #微信js api是否是beta版本
asyncConfig: true #是否同步config表数据到redis
asyncWeChatProgramTempList: false #是否同步小程序公共模板库
imagePath: /JAVA_PROJECT/SINGLE/trip/admin/ # 服务器图片路径配置 斜杠结尾
captchaOn: false # 是否开启行为验证码
demoSite: true # 是否演示站点 所有手机号码都会掩码
server:
port: 20500
spring:
profiles:
# 配置的环境
active: prod
servlet:
multipart:
max-file-size: 50MB #设置单个文件大小
max-request-size: 50MB #设置单次请求文件的总大小
# 数据库配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/java_trip?characterEncoding=utf-8&useSSL=false&serverTimeZone=GMT+8
username: java_trip
password: 111111
redis:
host: 127.0.0.1 #地址
port: 6379 #端口
password: 111111
timeout: 10000 # 连接超时时间(毫秒)
database: 5 #默认数据库
jedis:
pool:
max-active: 200 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
time-between-eviction-runs: -1 #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
debug: true
logging:
level:
io.swagger.*: error
com.zbjk.crmeb: debug
org.springframework.boot.autoconfigure: ERROR
config: classpath:logback-spring.xml
file:
path: ./crmeb_log
# mybatis 配置
mybatis-plus:
# 配置sql打印日志
configuration:
log-impl:
#swagger 配置
swagger:
basic:
enable: true #是否开启界面
check: false #是否打开验证
username: crmeb #访问swagger的账号
password: crmeb.com #访问swagger的密码

View File

Binary file not shown.

View File

@@ -0,0 +1,55 @@
文泉驿是一个开源汉字字体项目
由旅美学者房骞骞FangQ
于2004年10月创建
集中力量解决GNU/Linux
高质量中文字体匮乏的状况
目前,文泉驿已经开发并发布了
第一个完整覆盖GB18030汉字
包含27000多个汉字
的多规格点阵汉字字型文件
第一个覆盖GBK字符集的
开源矢量字型文件(文泉驿正黑)
并提供了目前包含字符数目最多的
开源字体——GNU Unifont——中
绝大多数中日韩文相关的符号
这些字型文件已经逐渐成为
主流Linux/Unix发行版
中文桌面的首选中文字体
目前Ubuntu、Fedora、Slackware
Magic Linux、CDLinux
使用文泉驿作为默认中文字体
Debian、Gentoo、Mandriva
ArchLinux、Frugalware
则提供了官方源支持
而FreeBSD则在其ports中有提供
所以,今天我们所要分享的就是
文泉驿正黑体
可在Linux/UNIX,Windows
Mac OS和嵌入式操作系统中使用

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zbkj.admin.dao.ScheduleJobLogDao">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zbkj.admin.dao.ScheduleJobDao">
</mapper>