From d2b61c6d95a4f10075c476d828dce88aa5fa441d Mon Sep 17 00:00:00 2001 From: GoCo Date: Sat, 16 Aug 2025 17:19:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20=E8=AF=84=E8=AE=BA?= =?UTF-8?q?=E8=A1=A8&=E8=AF=BE=E7=A8=8B=E8=AF=84=E8=AE=BA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../biz/controller/CommentBizController.java | 52 +++++ .../biz/controller/ResourceBizController.java | 2 +- .../biz/controller/UserBizController.java | 2 +- .../modules/biz/dto/CommentWithUserInfo.java | 20 ++ .../biz/service/ICommentBizService.java | 20 ++ .../service/impl/CommentBizServiceImpl.java | 69 ++++++ .../comment/controller/CommentController.java | 182 +++++++++++++++ .../modules/gen/comment/entity/Comment.java | 84 +++++++ .../gen/comment/mapper/CommentMapper.java | 17 ++ .../gen/comment/mapper/xml/CommentMapper.xml | 5 + .../gen/comment/service/ICommentService.java | 14 ++ .../service/impl/CommentServiceImpl.java | 19 ++ .../controller/HomeworkController.java | 182 +++++++++++++++ .../modules/gen/homework/entity/Homework.java | 93 ++++++++ .../gen/homework/mapper/HomeworkMapper.java | 17 ++ .../homework/mapper/xml/HomeworkMapper.xml | 5 + .../homework/service/IHomeworkService.java | 14 ++ .../service/impl/HomeworkServiceImpl.java | 19 ++ .../src/views/gen/homework/Homework.api.ts | 64 ++++++ .../src/views/gen/homework/Homework.data.ts | 136 +++++++++++ .../src/views/gen/homework/HomeworkList.vue | 215 ++++++++++++++++++ .../gen/homework/components/HomeworkForm.vue | 70 ++++++ .../gen/homework/components/HomeworkModal.vue | 99 ++++++++ 23 files changed, 1398 insertions(+), 2 deletions(-) create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/CommentBizController.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/dto/CommentWithUserInfo.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/service/ICommentBizService.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/service/impl/CommentBizServiceImpl.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/controller/CommentController.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/entity/Comment.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/mapper/CommentMapper.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/mapper/xml/CommentMapper.xml create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/service/ICommentService.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/service/impl/CommentServiceImpl.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/controller/HomeworkController.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/entity/Homework.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/mapper/HomeworkMapper.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/mapper/xml/HomeworkMapper.xml create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/service/IHomeworkService.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/service/impl/HomeworkServiceImpl.java create mode 100644 jeecgboot-vue3/src/views/gen/homework/Homework.api.ts create mode 100644 jeecgboot-vue3/src/views/gen/homework/Homework.data.ts create mode 100644 jeecgboot-vue3/src/views/gen/homework/HomeworkList.vue create mode 100644 jeecgboot-vue3/src/views/gen/homework/components/HomeworkForm.vue create mode 100644 jeecgboot-vue3/src/views/gen/homework/components/HomeworkModal.vue diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/CommentBizController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/CommentBizController.java new file mode 100644 index 00000000..007ca1b9 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/CommentBizController.java @@ -0,0 +1,52 @@ +package org.jeecg.modules.biz.controller; + +import java.util.List; + +import org.jeecg.common.api.vo.Result; +import org.jeecg.config.shiro.IgnoreAuth; +import org.jeecg.modules.biz.dto.CommentWithUserInfo; +import org.jeecg.modules.biz.service.ICommentBizService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; + + +@Tag(name = "评论") +@RestController +@RequestMapping("/biz/comment") +@Slf4j +public class CommentBizController { + + @Autowired + private ICommentBizService commentBizService; + + @GetMapping("/course/{courseId}/list") + @Operation(summary = "查询课程评论列表", description = "根据课程ID查询课程评论列表,包含用户信息") + @IgnoreAuth + public Result> queryCourseCommentList(@PathVariable("courseId") String courseId) { + List list = commentBizService.getCommentList("course", courseId); + return Result.OK(list); + } + + // @GetMapping("/activity/{activityId}/list") + // @Operation(summary = "查询活动评论列表", description = "根据活动ID查询活动评论列表,包含用户信息") + // public Result> queryActivityCommentList(@PathVariable("activityId") String activityId) { + // List list = commentBizService.getCommentList("activity", activityId); + // return Result.OK(list); + // } + + // @GetMapping("/{targetType}/{targetId}/list") + // @Operation(summary = "查询通用评论列表", description = "根据目标类型和目标ID查询评论列表,包含用户信息") + // public Result> queryCommentList( + // @PathVariable("targetType") String targetType, + // @PathVariable("targetId") String targetId) { + // List list = commentBizService.getCommentList(targetType, targetId); + // return Result.OK(list); + // } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/ResourceBizController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/ResourceBizController.java index e5791372..31b6f04a 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/ResourceBizController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/ResourceBizController.java @@ -29,7 +29,7 @@ import org.jeecg.modules.gen.resource.entity.Resource; import io.swagger.v3.oas.annotations.Operation; -@Tag(name = "资源") +@Tag(name = "02-资源管理") @RestController @RequestMapping("/biz/resource") @Slf4j diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/UserBizController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/UserBizController.java index 5b0f8ee1..d3689a00 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/UserBizController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/controller/UserBizController.java @@ -38,7 +38,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; -@Tag(name = "用户") +@Tag(name = "03-用户管理") @RestController @RequestMapping("/biz/user") @Slf4j diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/dto/CommentWithUserInfo.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/dto/CommentWithUserInfo.java new file mode 100644 index 00000000..bd826f54 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/dto/CommentWithUserInfo.java @@ -0,0 +1,20 @@ +package org.jeecg.modules.biz.dto; + +import org.jeecg.modules.gen.comment.entity.Comment; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = false) +@Schema(description = "评论信息(包含用户信息)") +public class CommentWithUserInfo extends Comment { + @Schema(description = "用户姓名") + private String userName; + + @Schema(description = "用户头像") + private String userAvatar; + + @Schema(description = "用户标签") + private String userTag; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/service/ICommentBizService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/service/ICommentBizService.java new file mode 100644 index 00000000..d2efbccd --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/service/ICommentBizService.java @@ -0,0 +1,20 @@ +package org.jeecg.modules.biz.service; + +import java.util.List; + +import org.jeecg.modules.biz.dto.CommentWithUserInfo; +import org.jeecg.modules.gen.comment.entity.*; + +import com.baomidou.mybatisplus.extension.service.IService; + +public interface ICommentBizService extends IService { + + /** + * 根据目标类型和目标ID查询评论列表(包含用户信息) + * @param targetType 目标类型 + * @param targetId 目标ID + * @return + */ + List getCommentList(String targetType, String targetId); + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/service/impl/CommentBizServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/service/impl/CommentBizServiceImpl.java new file mode 100644 index 00000000..b313d89d --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/biz/service/impl/CommentBizServiceImpl.java @@ -0,0 +1,69 @@ +package org.jeecg.modules.biz.service.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.jeecg.modules.biz.dto.CommentWithUserInfo; +import org.jeecg.modules.biz.service.ICommentBizService; +import org.jeecg.modules.gen.comment.entity.Comment; +import org.jeecg.modules.gen.comment.mapper.CommentMapper; +import org.jeecg.modules.gen.userinfo.entity.UserInfo; +import org.jeecg.modules.gen.userinfo.mapper.UserInfoMapper; +import org.jeecg.modules.system.entity.SysUser; +import org.jeecg.modules.system.mapper.SysUserMapper; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +@Service +public class CommentBizServiceImpl extends ServiceImpl implements ICommentBizService { + + @Autowired + private UserInfoMapper userInfoMapper; + @Autowired + private SysUserMapper sysUserMapper; + + @Override + public List getCommentList(String targetType, String targetId) { + // 1. 根据目标类型和目标ID查询评论列表 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("target_type", targetType) + .eq("target_id", targetId) + .orderByDesc("iz_top") // 置顶评论在前 + .orderByDesc("create_time"); // 按时间倒序 + + List comments = this.list(queryWrapper); + + // 2. 根据userid关联查询用户信息,构建包含用户信息的评论列表 + List result = new ArrayList<>(); + for (Comment comment : comments) { + CommentWithUserInfo commentWithUser = new CommentWithUserInfo(); + // 复制评论基本信息 + BeanUtils.copyProperties(comment, commentWithUser); + + // 查询用户基本信息 + SysUser sysUser = sysUserMapper.selectById(comment.getUserId()); + if (sysUser != null) { + commentWithUser.setUserName(sysUser.getRealname()); + commentWithUser.setUserAvatar(sysUser.getAvatar()); + + // 查询用户扩展信息 + UserInfo userInfo = userInfoMapper.selectOne( + new QueryWrapper().eq("user_id", comment.getUserId()) + ); + if (userInfo != null) { + commentWithUser.setUserTag(userInfo.getTag()); + } + } + + result.add(commentWithUser); + } + + // 3. 返回评论列表 + return result; + } + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/controller/CommentController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/controller/CommentController.java new file mode 100644 index 00000000..a0bd18a5 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/controller/CommentController.java @@ -0,0 +1,182 @@ +package org.jeecg.modules.gen.comment.controller; + +import java.util.Arrays; +import java.util.HashMap; +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.system.query.QueryRuleEnum; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.gen.comment.entity.Comment; +import org.jeecg.modules.gen.comment.service.ICommentService; + +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.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; + /** + * @Description: 评论 + * @Author: jeecg-boot + * @Date: 2025-08-16 + * @Version: V1.0 + */ +@Tag(name="评论") +@RestController +@RequestMapping("/gen/comment/comment") +@Slf4j +public class CommentController extends JeecgController { + @Autowired + private ICommentService commentService; + + /** + * 分页列表查询 + * + * @param comment + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "评论-分页列表查询") + @Operation(summary="评论-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(Comment comment, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + + + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(comment, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = commentService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param comment + * @return + */ + @AutoLog(value = "评论-添加") + @Operation(summary="评论-添加") + @RequiresPermissions("gen.comment:comment:add") + @PostMapping(value = "/add") + public Result add(@RequestBody Comment comment) { + commentService.save(comment); + + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param comment + * @return + */ + @AutoLog(value = "评论-编辑") + @Operation(summary="评论-编辑") + @RequiresPermissions("gen.comment:comment:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody Comment comment) { + commentService.updateById(comment); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "评论-通过id删除") + @Operation(summary="评论-通过id删除") + @RequiresPermissions("gen.comment:comment:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + commentService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "评论-批量删除") + @Operation(summary="评论-批量删除") + @RequiresPermissions("gen.comment:comment:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.commentService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "评论-通过id查询") + @Operation(summary="评论-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name="id",required=true) String id) { + Comment comment = commentService.getById(id); + if(comment==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(comment); + } + + /** + * 导出excel + * + * @param request + * @param comment + */ + @RequiresPermissions("gen.comment:comment:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, Comment comment) { + return super.exportXls(request, comment, Comment.class, "评论"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("gen.comment:comment:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, Comment.class); + } + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/entity/Comment.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/entity/Comment.java new file mode 100644 index 00000000..dbe59c92 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/entity/Comment.java @@ -0,0 +1,84 @@ +package org.jeecg.modules.gen.comment.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 com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +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.v3.oas.annotations.media.Schema; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * @Description: 评论 + * @Author: jeecg-boot + * @Date: 2025-08-16 + * @Version: V1.0 + */ +@Data +@TableName("comment") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Schema(description="评论") +public class Comment implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键") + private java.lang.String id; + /**用户id*/ + @Excel(name = "用户id", width = 15) + @Schema(description = "用户id") + private java.lang.String userId; + /**目标类型*/ + @Excel(name = "目标类型", width = 15) + @Schema(description = "目标类型") + private java.lang.String targetType; + /**目标id*/ + @Excel(name = "目标id", width = 15) + @Schema(description = "目标id") + private java.lang.String targetId; + /**内容*/ + @Excel(name = "内容", width = 15) + @Schema(description = "内容") + private java.lang.String content; + /**图片*/ + @Excel(name = "图片", width = 15) + @Schema(description = "图片") + private java.lang.String imgs; + /**是否置顶*/ + @Excel(name = "是否置顶", width = 15) + @Schema(description = "是否置顶") + private java.lang.Integer izTop; + /**点赞数*/ + @Excel(name = "点赞数", width = 15) + @Schema(description = "点赞数") + private java.lang.Integer likeCount; + /**创建人*/ + @Schema(description = "创建人") + private java.lang.String createBy; + /**创建日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "创建日期") + private java.util.Date createTime; + /**更新人*/ + @Schema(description = "更新人") + private java.lang.String updateBy; + /**更新日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "更新日期") + private java.util.Date updateTime; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/mapper/CommentMapper.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/mapper/CommentMapper.java new file mode 100644 index 00000000..518a14f2 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/mapper/CommentMapper.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.gen.comment.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import org.jeecg.modules.gen.comment.entity.Comment; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: 评论 + * @Author: jeecg-boot + * @Date: 2025-08-16 + * @Version: V1.0 + */ +public interface CommentMapper extends BaseMapper { + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/mapper/xml/CommentMapper.xml b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/mapper/xml/CommentMapper.xml new file mode 100644 index 00000000..126ff44d --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/mapper/xml/CommentMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/service/ICommentService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/service/ICommentService.java new file mode 100644 index 00000000..ceb57b9c --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/service/ICommentService.java @@ -0,0 +1,14 @@ +package org.jeecg.modules.gen.comment.service; + +import org.jeecg.modules.gen.comment.entity.Comment; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @Description: 评论 + * @Author: jeecg-boot + * @Date: 2025-08-16 + * @Version: V1.0 + */ +public interface ICommentService extends IService { + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/service/impl/CommentServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/service/impl/CommentServiceImpl.java new file mode 100644 index 00000000..4b05a63a --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/comment/service/impl/CommentServiceImpl.java @@ -0,0 +1,19 @@ +package org.jeecg.modules.gen.comment.service.impl; + +import org.jeecg.modules.gen.comment.entity.Comment; +import org.jeecg.modules.gen.comment.mapper.CommentMapper; +import org.jeecg.modules.gen.comment.service.ICommentService; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * @Description: 评论 + * @Author: jeecg-boot + * @Date: 2025-08-16 + * @Version: V1.0 + */ +@Service +public class CommentServiceImpl extends ServiceImpl implements ICommentService { + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/controller/HomeworkController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/controller/HomeworkController.java new file mode 100644 index 00000000..82e6eeac --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/controller/HomeworkController.java @@ -0,0 +1,182 @@ +package org.jeecg.modules.gen.homework.controller; + +import java.util.Arrays; +import java.util.HashMap; +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.system.query.QueryRuleEnum; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.gen.homework.entity.Homework; +import org.jeecg.modules.gen.homework.service.IHomeworkService; + +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.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; + /** + * @Description: 作业 + * @Author: jeecg-boot + * @Date: 2025-08-16 + * @Version: V1.0 + */ +@Tag(name="作业") +@RestController +@RequestMapping("/gen/homework/homework") +@Slf4j +public class HomeworkController extends JeecgController { + @Autowired + private IHomeworkService homeworkService; + + /** + * 分页列表查询 + * + * @param homework + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "作业-分页列表查询") + @Operation(summary="作业-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(Homework homework, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + + + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(homework, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = homeworkService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param homework + * @return + */ + @AutoLog(value = "作业-添加") + @Operation(summary="作业-添加") + @RequiresPermissions("gen.homework:homework:add") + @PostMapping(value = "/add") + public Result add(@RequestBody Homework homework) { + homeworkService.save(homework); + + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param homework + * @return + */ + @AutoLog(value = "作业-编辑") + @Operation(summary="作业-编辑") + @RequiresPermissions("gen.homework:homework:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody Homework homework) { + homeworkService.updateById(homework); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "作业-通过id删除") + @Operation(summary="作业-通过id删除") + @RequiresPermissions("gen.homework:homework:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + homeworkService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "作业-批量删除") + @Operation(summary="作业-批量删除") + @RequiresPermissions("gen.homework:homework:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.homeworkService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "作业-通过id查询") + @Operation(summary="作业-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name="id",required=true) String id) { + Homework homework = homeworkService.getById(id); + if(homework==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(homework); + } + + /** + * 导出excel + * + * @param request + * @param homework + */ + @RequiresPermissions("gen.homework:homework:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, Homework homework) { + return super.exportXls(request, homework, Homework.class, "作业"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("gen.homework:homework:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, Homework.class); + } + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/entity/Homework.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/entity/Homework.java new file mode 100644 index 00000000..bdf1258d --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/entity/Homework.java @@ -0,0 +1,93 @@ +package org.jeecg.modules.gen.homework.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 com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +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.v3.oas.annotations.media.Schema; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * @Description: 作业 + * @Author: jeecg-boot + * @Date: 2025-08-16 + * @Version: V1.0 + */ +@Data +@TableName("homework") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Schema(description="作业") +public class Homework implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键") + private java.lang.String id; + /**标题*/ + @Excel(name = "标题", width = 15) + @Schema(description = "标题") + private java.lang.String title; + /**说明*/ + @Excel(name = "说明", width = 15) + @Schema(description = "说明") + private java.lang.String description; + /**附件*/ + @Excel(name = "附件", width = 15) + @Schema(description = "附件") + private java.lang.String attachment; + /**满分*/ + @Excel(name = "满分", width = 15) + @Schema(description = "满分") + private java.lang.Integer maxScore; + /**及格分数*/ + @Excel(name = "及格分数", width = 15) + @Schema(description = "及格分数") + private java.lang.Integer passScore; + /**开始时间*/ + @Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "开始时间") + private java.util.Date startTime; + /**结束时间*/ + @Excel(name = "结束时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "结束时间") + private java.util.Date endTime; + /**状态*/ + @Excel(name = "状态", width = 15, dicCode = "course_status") + @Dict(dicCode = "course_status") + @Schema(description = "状态") + private java.lang.Integer status; + /**创建人*/ + @Schema(description = "创建人") + private java.lang.String createBy; + /**创建日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "创建日期") + private java.util.Date createTime; + /**更新人*/ + @Schema(description = "更新人") + private java.lang.String updateBy; + /**更新日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "更新日期") + private java.util.Date updateTime; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/mapper/HomeworkMapper.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/mapper/HomeworkMapper.java new file mode 100644 index 00000000..3981960d --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/mapper/HomeworkMapper.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.gen.homework.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import org.jeecg.modules.gen.homework.entity.Homework; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: 作业 + * @Author: jeecg-boot + * @Date: 2025-08-16 + * @Version: V1.0 + */ +public interface HomeworkMapper extends BaseMapper { + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/mapper/xml/HomeworkMapper.xml b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/mapper/xml/HomeworkMapper.xml new file mode 100644 index 00000000..65893c9e --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/mapper/xml/HomeworkMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/service/IHomeworkService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/service/IHomeworkService.java new file mode 100644 index 00000000..a56a74bb --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/service/IHomeworkService.java @@ -0,0 +1,14 @@ +package org.jeecg.modules.gen.homework.service; + +import org.jeecg.modules.gen.homework.entity.Homework; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @Description: 作业 + * @Author: jeecg-boot + * @Date: 2025-08-16 + * @Version: V1.0 + */ +public interface IHomeworkService extends IService { + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/service/impl/HomeworkServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/service/impl/HomeworkServiceImpl.java new file mode 100644 index 00000000..3ee4a418 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-learn/src/main/java/org/jeecg/modules/gen/homework/service/impl/HomeworkServiceImpl.java @@ -0,0 +1,19 @@ +package org.jeecg.modules.gen.homework.service.impl; + +import org.jeecg.modules.gen.homework.entity.Homework; +import org.jeecg.modules.gen.homework.mapper.HomeworkMapper; +import org.jeecg.modules.gen.homework.service.IHomeworkService; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * @Description: 作业 + * @Author: jeecg-boot + * @Date: 2025-08-16 + * @Version: V1.0 + */ +@Service +public class HomeworkServiceImpl extends ServiceImpl implements IHomeworkService { + +} diff --git a/jeecgboot-vue3/src/views/gen/homework/Homework.api.ts b/jeecgboot-vue3/src/views/gen/homework/Homework.api.ts new file mode 100644 index 00000000..0db53775 --- /dev/null +++ b/jeecgboot-vue3/src/views/gen/homework/Homework.api.ts @@ -0,0 +1,64 @@ +import {defHttp} from '/@/utils/http/axios'; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/gen/homework/homework/list', + save='/gen/homework/homework/add', + edit='/gen/homework/homework/edit', + deleteOne = '/gen/homework/homework/delete', + deleteBatch = '/gen/homework/homework/deleteBatch', + importExcel = '/gen/homework/homework/importExcel', + exportXls = '/gen/homework/homework/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) => { + createConfirm({ + iconType: 'warning', + 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/jeecgboot-vue3/src/views/gen/homework/Homework.data.ts b/jeecgboot-vue3/src/views/gen/homework/Homework.data.ts new file mode 100644 index 00000000..4ee7f9c2 --- /dev/null +++ b/jeecgboot-vue3/src/views/gen/homework/Homework.data.ts @@ -0,0 +1,136 @@ +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + { + title: '标题', + align:"center", + dataIndex: 'title' + }, + { + title: '说明', + align:"center", + dataIndex: 'description', + }, + { + title: '附件', + align:"center", + dataIndex: 'attachment', + }, + { + title: '满分', + align:"center", + dataIndex: 'maxScore' + }, + { + title: '及格分数', + align:"center", + dataIndex: 'passScore' + }, + { + title: '开始时间', + align:"center", + dataIndex: 'startTime' + }, + { + title: '结束时间', + align:"center", + dataIndex: 'endTime' + }, + { + title: '状态', + align:"center", + dataIndex: 'status_dictText' + }, +]; +//查询数据 +export const searchFormSchema: FormSchema[] = [ +]; +//表单数据 +export const formSchema: FormSchema[] = [ + { + label: '标题', + field: 'title', + component: 'Input', + }, + { + label: '说明', + field: 'description', + component: 'JEditor', + }, + { + label: '附件', + field: 'attachment', + component: 'JUpload', + componentProps:{ + }, + }, + { + label: '满分', + field: 'maxScore', + component: 'InputNumber', + }, + { + label: '及格分数', + field: 'passScore', + component: 'InputNumber', + }, + { + label: '开始时间', + field: 'startTime', + component: 'DatePicker', + componentProps: { + showTime: true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + }, + { + label: '结束时间', + field: 'endTime', + component: 'DatePicker', + componentProps: { + showTime: true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + }, + { + label: '状态', + field: 'status', + component: 'JDictSelectTag', + componentProps:{ + dictCode:"course_status", + type: "radio" + }, + }, + // TODO 主键隐藏字段,目前写死为ID + { + label: '', + field: 'id', + component: 'Input', + show: false + }, +]; + +// 高级查询数据 +export const superQuerySchema = { + title: {title: '标题',order: 0,view: 'text', type: 'string',}, + description: {title: '说明',order: 1,view: 'umeditor', type: 'string',}, + attachment: {title: '附件',order: 2,view: 'file', type: 'string',}, + maxScore: {title: '满分',order: 3,view: 'number', type: 'number',}, + passScore: {title: '及格分数',order: 4,view: 'number', type: 'number',}, + startTime: {title: '开始时间',order: 5,view: 'datetime', type: 'string',}, + endTime: {title: '结束时间',order: 6,view: 'datetime', type: 'string',}, + status: {title: '状态',order: 7,view: 'number', type: 'number',dictCode: 'course_status',}, +}; + +/** +* 流程表单调用这个方法获取formSchema +* @param param +*/ +export function getBpmFormSchema(_formData): FormSchema[]{ + // 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema + return formSchema; +} \ No newline at end of file diff --git a/jeecgboot-vue3/src/views/gen/homework/HomeworkList.vue b/jeecgboot-vue3/src/views/gen/homework/HomeworkList.vue new file mode 100644 index 00000000..45828d4b --- /dev/null +++ b/jeecgboot-vue3/src/views/gen/homework/HomeworkList.vue @@ -0,0 +1,215 @@ + + + + + \ No newline at end of file diff --git a/jeecgboot-vue3/src/views/gen/homework/components/HomeworkForm.vue b/jeecgboot-vue3/src/views/gen/homework/components/HomeworkForm.vue new file mode 100644 index 00000000..3265df83 --- /dev/null +++ b/jeecgboot-vue3/src/views/gen/homework/components/HomeworkForm.vue @@ -0,0 +1,70 @@ + + + \ No newline at end of file diff --git a/jeecgboot-vue3/src/views/gen/homework/components/HomeworkModal.vue b/jeecgboot-vue3/src/views/gen/homework/components/HomeworkModal.vue new file mode 100644 index 00000000..0605cfd7 --- /dev/null +++ b/jeecgboot-vue3/src/views/gen/homework/components/HomeworkModal.vue @@ -0,0 +1,99 @@ + + + + + \ No newline at end of file