diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/controller/CaiUserVisitorController.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/controller/CaiUserVisitorController.java new file mode 100644 index 00000000..847e3e84 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/controller/CaiUserVisitorController.java @@ -0,0 +1,95 @@ +package com.ruoyi.cai.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.cai.domain.CaiUserVisitor; +import com.ruoyi.cai.service.CaiUserVisitorService; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.validate.AddGroup; +import com.ruoyi.common.core.validate.EditGroup; +import com.ruoyi.common.enums.BusinessType; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; + +/** + * 用户来访记录 + * + * @author 77 + * @date 2023-12-24 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/cai/userVisitor") +public class CaiUserVisitorController extends BaseController { + + private final CaiUserVisitorService caiUserVisitorService; + + /** + * 查询用户来访记录列表 + */ + @SaCheckPermission("cai:userVisitor:list") + @GetMapping("/list") + public TableDataInfo list(CaiUserVisitor bo, PageQuery pageQuery) { + Page page = caiUserVisitorService.page(pageQuery.build(), Wrappers.lambdaQuery(bo)); + return TableDataInfo.build(page); + } + + /** + * 获取用户来访记录详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("cai:userVisitor:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(caiUserVisitorService.getById(id)); + } + + /** + * 新增用户来访记录 + */ + @SaCheckPermission("cai:userVisitor:add") + @Log(title = "用户来访记录", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody CaiUserVisitor bo) { + return toAjax(caiUserVisitorService.save(bo)); + } + + /** + * 修改用户来访记录 + */ + @SaCheckPermission("cai:userVisitor:edit") + @Log(title = "用户来访记录", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody CaiUserVisitor bo) { + return toAjax(caiUserVisitorService.updateById(bo)); + } + + /** + * 删除用户来访记录 + * + * @param ids 主键串 + */ + @SaCheckPermission("cai:userVisitor:remove") + @Log(title = "用户来访记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(caiUserVisitorService.removeBatchByIds(Arrays.asList(ids), true)); + } +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/controller/app/CaiAnchorAppController.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/controller/app/CaiAnchorAppController.java index b80671ab..37e46db8 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/controller/app/CaiAnchorAppController.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/controller/app/CaiAnchorAppController.java @@ -3,8 +3,8 @@ package com.ruoyi.cai.controller.app; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.cai.dto.app.query.AnchorListQuery; -import com.ruoyi.cai.dto.app.query.GiveGiftQuery; -import com.ruoyi.cai.dto.app.query.GiveGuardQuery; +import com.ruoyi.cai.dto.app.query.GiveGiftRes; +import com.ruoyi.cai.dto.app.query.GiveGuardRes; import com.ruoyi.cai.dto.app.vo.AnchorListVo; import com.ruoyi.cai.service.CaiAnchorService; import com.ruoyi.cai.service.CaiGuardTotalService; @@ -37,13 +37,13 @@ public class CaiAnchorAppController { } @PostMapping("/give/guard") - public R giveGuard(GiveGuardQuery query){ + public R giveGuard(GiveGuardRes query){ boolean res = guardTotalService.giveGuard(query); return R.ok(res); } @PostMapping("/give/gift") - public R giveGift(GiveGiftQuery query){ + public R giveGift(GiveGiftRes query){ boolean res = userGiftService.giveGift(query); return R.ok(res); } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/controller/app/CaiUserStartAppController.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/controller/app/CaiUserStartAppController.java new file mode 100644 index 00000000..d020f57c --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/controller/app/CaiUserStartAppController.java @@ -0,0 +1,40 @@ +package com.ruoyi.cai.controller.app; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.cai.dto.app.query.StarQuery; +import com.ruoyi.cai.dto.app.query.StarRes; +import com.ruoyi.cai.dto.app.vo.UserStarOrVisitorList; +import com.ruoyi.cai.service.CaiUserFollowService; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.page.TableDataInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController("/user/star") +public class CaiUserStartAppController { + + @Autowired + private CaiUserFollowService userFollowService; + + @PostMapping("/star") + public R star(StarRes starRes){ + boolean bool = userFollowService.star(starRes); + return R.ok(bool); + } + + @PostMapping("/unstar") + public R unStar(StarRes starRes){ + boolean bool = userFollowService.unStar(starRes); + return R.ok(bool); + } + + @GetMapping("/page") + public TableDataInfo page(StarQuery query, PageQuery pageQuery){ + Page res = userFollowService.pageApp(pageQuery,query); + return TableDataInfo.build(res); + } + +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/domain/CaiUserVisitor.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/domain/CaiUserVisitor.java new file mode 100644 index 00000000..7cf89620 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/domain/CaiUserVisitor.java @@ -0,0 +1,42 @@ +package com.ruoyi.cai.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 用户来访记录对象 cai_user_visitor + * + * @author 77 + * @date 2023-12-24 + */ +@Data +@TableName("cai_user_visitor") +public class CaiUserVisitor implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * + */ + @TableId(value = "id") + private Long id; + /** + * 被访用户ID + */ + private Integer userId; + /** + * 访客用户ID + */ + private Long visitorId; + /** + * 是否查看 0 未查看 1 已查看 + */ + private Integer isWatch; + + private LocalDateTime createTime; + +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGiftQuery.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGiftRes.java similarity index 89% rename from ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGiftQuery.java rename to ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGiftRes.java index f2fada0a..632f5692 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGiftQuery.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGiftRes.java @@ -3,7 +3,7 @@ package com.ruoyi.cai.dto.app.query; import lombok.Data; @Data -public class GiveGiftQuery { +public class GiveGiftRes { /** * 类型 1 个人详情页 2.IM页面 3视频页 diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGuardQuery.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGuardRes.java similarity index 80% rename from ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGuardQuery.java rename to ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGuardRes.java index 702d5c67..82439593 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGuardQuery.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/GiveGuardRes.java @@ -3,7 +3,7 @@ package com.ruoyi.cai.dto.app.query; import lombok.Data; @Data -public class GiveGuardQuery { +public class GiveGuardRes { private Long toUserId; diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/StarQuery.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/StarQuery.java new file mode 100644 index 00000000..eea3a340 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/StarQuery.java @@ -0,0 +1,11 @@ +package com.ruoyi.cai.dto.app.query; + +import lombok.Data; + +@Data +public class StarQuery { + // 1=查询我的关注 2=查询我的粉丝 + private Integer type = 1; + + private Long userId; +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/StarRes.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/StarRes.java new file mode 100644 index 00000000..03fe6bed --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/query/StarRes.java @@ -0,0 +1,8 @@ +package com.ruoyi.cai.dto.app.query; + +import lombok.Data; + +@Data +public class StarRes { + private Long toUserId; +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserBaseVo.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserBaseVo.java new file mode 100644 index 00000000..6498b34b --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserBaseVo.java @@ -0,0 +1,34 @@ + +package com.ruoyi.cai.dto.app.vo; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class UserBaseVo { + + /** + * 头像 + */ + private String avatar; + + /** + * 性别 0 未知 1 女 2 男 + */ + private Integer gender; + /** + * 城市 + */ + private Long city; + /** + * 昵称 + */ + private String nickname; + /** + * 用户号/ID号 + */ + private String usercode; + + private Integer age; +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserListVo.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserListVo.java index ca8fd629..ae917f1b 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserListVo.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserListVo.java @@ -7,31 +7,7 @@ import java.math.BigDecimal; import java.time.LocalDateTime; @Data -public class UserListVo { - - /** - * 头像 - */ - private String avatar; - - /** - * 性别 0 未知 1 女 2 男 - */ - private Integer gender; - /** - * 城市 - */ - private Long city; - /** - * 昵称 - */ - private String nickname; - /** - * 用户号/ID号 - */ - private String usercode; - - private Integer age; +public class UserListVo extends UserBaseVo { /** * 最后在线时间 */ diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserStarOrVisitorList.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserStarOrVisitorList.java new file mode 100644 index 00000000..5390a8c2 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/UserStarOrVisitorList.java @@ -0,0 +1,11 @@ +package com.ruoyi.cai.dto.app.vo; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class UserStarOrVisitorList { + + private LocalDateTime happenTime; +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/CaiUserFollowMapper.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/CaiUserFollowMapper.java index 297467d2..2926f80e 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/CaiUserFollowMapper.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/CaiUserFollowMapper.java @@ -1,7 +1,11 @@ package com.ruoyi.cai.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.cai.domain.CaiUserFollow; +import com.ruoyi.cai.dto.app.query.StarQuery; +import com.ruoyi.cai.dto.app.vo.UserStarOrVisitorList; +import org.apache.ibatis.annotations.Param; /** * 关注表Mapper接口 @@ -11,4 +15,5 @@ import com.ruoyi.cai.domain.CaiUserFollow; */ public interface CaiUserFollowMapper extends BaseMapper { + Page pageApp(@Param("build") Page build, @Param("query") StarQuery query); } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/CaiUserVisitorMapper.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/CaiUserVisitorMapper.java new file mode 100644 index 00000000..d1346e37 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/CaiUserVisitorMapper.java @@ -0,0 +1,14 @@ +package com.ruoyi.cai.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.cai.domain.CaiUserVisitor; + +/** + * 用户来访记录Mapper接口 + * + * @author 77 + * @date 2023-12-24 + */ +public interface CaiUserVisitorMapper extends BaseMapper { + +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiGuardTotalService.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiGuardTotalService.java index f975a5d2..0c496692 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiGuardTotalService.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiGuardTotalService.java @@ -2,7 +2,7 @@ package com.ruoyi.cai.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.cai.domain.CaiGuardTotal; -import com.ruoyi.cai.dto.app.query.GiveGuardQuery; +import com.ruoyi.cai.dto.app.query.GiveGuardRes; import com.ruoyi.cai.dto.app.vo.GuardTotalVo; import java.util.List; @@ -17,5 +17,5 @@ public interface CaiGuardTotalService extends IService { List selectGuardTotalLimit(Long fromUserId,Integer limit); - boolean giveGuard(GiveGuardQuery query); + boolean giveGuard(GiveGuardRes query); } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserFollowService.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserFollowService.java index 00f82674..fa49af61 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserFollowService.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserFollowService.java @@ -1,7 +1,12 @@ package com.ruoyi.cai.service; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.cai.domain.CaiUserFollow; +import com.ruoyi.cai.dto.app.query.StarQuery; +import com.ruoyi.cai.dto.app.query.StarRes; +import com.ruoyi.cai.dto.app.vo.UserStarOrVisitorList; +import com.ruoyi.common.core.domain.PageQuery; /** * 关注表Service接口 @@ -14,4 +19,10 @@ public interface CaiUserFollowService extends IService { Long getFansNumByUserId(Long userId); boolean checkStar(Long userId, Long followUserId); + + boolean star(StarRes starRes); + + boolean unStar(StarRes starRes); + + Page pageApp(PageQuery pageQuery, StarQuery query); } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserGiftService.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserGiftService.java index 6ba105e1..5f4a5c21 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserGiftService.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserGiftService.java @@ -2,7 +2,7 @@ package com.ruoyi.cai.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.cai.domain.CaiUserGift; -import com.ruoyi.cai.dto.app.query.GiveGiftQuery; +import com.ruoyi.cai.dto.app.query.GiveGiftRes; import com.ruoyi.cai.dto.app.vo.UserGiftVo; import java.util.List; @@ -17,5 +17,5 @@ public interface CaiUserGiftService extends IService { List selectGiftList(Long userId); - boolean giveGift(GiveGiftQuery query); + boolean giveGift(GiveGiftRes query); } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserVisitorService.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserVisitorService.java new file mode 100644 index 00000000..d55114ae --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/CaiUserVisitorService.java @@ -0,0 +1,14 @@ +package com.ruoyi.cai.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.cai.domain.CaiUserVisitor; + +/** + * 用户来访记录Service接口 + * + * @author 77 + * @date 2023-12-24 + */ +public interface CaiUserVisitorService extends IService { + +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/CaiGuardTotalServiceImpl.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/CaiGuardTotalServiceImpl.java index 5628704a..5590b2b6 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/CaiGuardTotalServiceImpl.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/CaiGuardTotalServiceImpl.java @@ -3,13 +3,11 @@ package com.ruoyi.cai.service.impl; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.cai.domain.CaiAccount; -import com.ruoyi.cai.domain.CaiAccountDetail; import com.ruoyi.cai.domain.CaiGuardTotal; import com.ruoyi.cai.domain.CaiUser; -import com.ruoyi.cai.dto.app.query.GiveGuardQuery; +import com.ruoyi.cai.dto.app.query.GiveGuardRes; import com.ruoyi.cai.dto.app.vo.GuardTotalVo; import com.ruoyi.cai.mapper.CaiGuardTotalMapper; -import com.ruoyi.cai.service.CaiAccountDetailService; import com.ruoyi.cai.service.CaiAccountService; import com.ruoyi.cai.service.CaiGuardTotalService; import com.ruoyi.cai.service.CaiUserService; @@ -43,7 +41,7 @@ public class CaiGuardTotalServiceImpl extends ServiceImpl pageApp(PageQuery pageQuery, StarQuery query) { + query.setUserId(LoginHelper.getUserId()); + return baseMapper.pageApp(pageQuery.build(),query); + } } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/CaiUserGiftServiceImpl.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/CaiUserGiftServiceImpl.java index 4af6507a..fec8e893 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/CaiUserGiftServiceImpl.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/CaiUserGiftServiceImpl.java @@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.cai.domain.CaiAccount; import com.ruoyi.cai.domain.CaiGift; import com.ruoyi.cai.domain.CaiUserGift; -import com.ruoyi.cai.dto.app.query.GiveGiftQuery; +import com.ruoyi.cai.dto.app.query.GiveGiftRes; import com.ruoyi.cai.dto.app.vo.UserGiftVo; import com.ruoyi.cai.mapper.CaiUserGiftMapper; import com.ruoyi.cai.service.CaiAccountService; @@ -13,7 +13,6 @@ import com.ruoyi.cai.service.CaiUserGiftService; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.helper.LoginHelper; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.HierarchicalBeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -40,7 +39,7 @@ public class CaiUserGiftServiceImpl extends ServiceImpl implements CaiUserVisitorService { +} diff --git a/ruoyi-cai/src/main/resources/mapper/cai/CaiUserFollowMapper.xml b/ruoyi-cai/src/main/resources/mapper/cai/CaiUserFollowMapper.xml index c228f112..33df5506 100644 --- a/ruoyi-cai/src/main/resources/mapper/cai/CaiUserFollowMapper.xml +++ b/ruoyi-cai/src/main/resources/mapper/cai/CaiUserFollowMapper.xml @@ -11,6 +11,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-cai/src/main/resources/mapper/cai/CaiUserVisitorMapper.xml b/ruoyi-cai/src/main/resources/mapper/cai/CaiUserVisitorMapper.xml new file mode 100644 index 00000000..a49632ef --- /dev/null +++ b/ruoyi-cai/src/main/resources/mapper/cai/CaiUserVisitorMapper.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + +