Browse Source

feature-1.0-img: 新增用户等级功能

feature-1.0-img-prototype
penny 3 years ago
parent
commit
1ae110efb7
  1. 81
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/LevelInfoController.java
  2. 14
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/domain/Creator.java
  3. 68
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/domain/LevelInfo.java
  4. 41
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/LevelInfoDto.java
  5. 21
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/LevelInfoPageDto.java
  6. 9
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/mapper/LevelInfoMapper.java
  7. 52
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/LevelInfoService.java
  8. 77
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/LevelInfoServiceImpl.java
  9. 6
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/CreatorDetailsVo.java
  10. 6
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/CreatorFollowVo.java
  11. 6
      bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/CreatorVo.java
  12. 16
      bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/CreatorMapper.xml
  13. 23
      bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/LevelInfoMapper.xml

81
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/LevelInfoController.java

@ -0,0 +1,81 @@
package com.bnyer.img.controller;
import com.alibaba.fastjson.JSON;
import com.bnyer.common.core.utils.DesensitizedUtils;
import com.bnyer.common.core.web.controller.BaseController;
import com.bnyer.common.core.web.domain.AjaxResult;
import com.bnyer.common.core.web.page.TableDataInfo;
import com.bnyer.img.domain.LevelInfo;
import com.bnyer.img.dto.LevelInfoDto;
import com.bnyer.img.dto.LevelInfoPageDto;
import com.bnyer.img.dto.StatusDto;
import com.bnyer.img.service.LevelInfoService;
import com.github.pagehelper.PageHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api(value = "【图文平台】等级信息接口",tags = "【图文平台】等级信息接口")
@RestController
@RequestMapping("/img/levelInfo")
@Slf4j
public class LevelInfoController extends BaseController {
@Autowired
private LevelInfoService levelInfoService;
//@RequiresPermissions("system:config:list")
@ApiOperation(value="查询等级信息分页")
@PostMapping("/page")
public TableDataInfo pageLevelInfo(@RequestBody @ApiParam("分页对象") LevelInfoPageDto dto){
PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
List<LevelInfo> levelInfos = levelInfoService.queryList(dto);
return getDataTable(levelInfos);
}
//@RequiresPermissions("system:config:list")
@ApiOperation(value="新增等级信息")
@PostMapping(value = "/insert")
public AjaxResult insertLevelInfo(@Validated @RequestBody @ApiParam("levelInfo对象") LevelInfoDto dto){
log.debug("【图文平台后台】新增等级信息参数为:{}", DesensitizedUtils.getJson(dto));
return AjaxResult.success(levelInfoService.insert(dto.extractParam()));
}
//@RequiresPermissions("system:config:list")
@ApiOperation(value="修改等级信息")
@PostMapping(value = "/update")
public AjaxResult updateLevelInfo(@Validated @RequestBody @ApiParam("levelInfo对象") LevelInfoDto dto){
log.debug("【图文平台后台】修改等级信息参数为:{}", JSON.toJSONString(dto));
return AjaxResult.success(levelInfoService.update(dto.extractParam()));
}
//@RequiresPermissions("system:config:list")
@ApiOperation(value="删除levelInfo")
@DeleteMapping(value = "/delete/{ids}")
public AjaxResult deleteLevelInfo(@PathVariable @ApiParam("主键ids") List<Long> ids){
log.debug("【图文平台后台】删除等级信息参数为:{}", JSON.toJSONString(ids));
return AjaxResult.success(levelInfoService.delete(ids));
}
//@RequiresPermissions("system:config:list")
@ApiOperation(value="查询等级信息详情")
@GetMapping(value = "/details/{id}")
public AjaxResult detailsLevelInfo(@PathVariable @ApiParam("主键id") Long id){
log.debug("【图文平台后台】查询等级信息详情参数为:{}", id);
return AjaxResult.success(levelInfoService.queryDetails(id));
}
//@RequiresPermissions("system:config:list")
@ApiOperation(value="变更type显示状态")
@PostMapping(value = "/changeStatus")
public AjaxResult changeStatus(@Validated @RequestBody @ApiParam("type状态对象") StatusDto dto){
log.debug("【图文平台后台】变更type参数为:{}", JSON.toJSONString(dto));
return AjaxResult.success(levelInfoService.changeStatus(dto.getId(),dto.getStatus()));
}
}

14
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/domain/Creator.java

@ -119,5 +119,19 @@ public class Creator extends BaseDomain {
@ApiModelProperty(value="最后登录时间") @ApiModelProperty(value="最后登录时间")
private Date lastLoginTime; private Date lastLoginTime;
/**
* 等级id
*/
@TableField(value = "level_id")
@ApiModelProperty(value="等级id")
private Long levelId;
/**
* 经验值
*/
@TableField(value = "exp")
@ApiModelProperty(value="经验值")
private Integer exp;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }

68
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/domain/LevelInfo.java

@ -0,0 +1,68 @@
package com.bnyer.img.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@ApiModel(value="com-bnyer-img-domain-LevelInfo")
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "img_level_info")
public class LevelInfo extends BaseDomain {
/**
* 主键id
*/
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value="主键id")
private Long id;
/**
* 等级头衔名称
*/
@TableField(value = "title")
@ApiModelProperty(value="等级头衔名称")
private String title;
/**
* 头衔图标
*/
@TableField(value = "title_icon")
@ApiModelProperty(value="头衔图标")
private String titleIcon;
/**
* 最小经验值
*/
@TableField(value = "min_exp")
@ApiModelProperty(value="最小经验值")
private Integer minExp;
/**
* 最大经验值
*/
@TableField(value = "max_exp")
@ApiModelProperty(value="最大经验值")
private Integer maxExp;
/**
* 等级类型(0->用户;1->创作者)
*/
@TableField(value = "type")
@ApiModelProperty(value="等级类型(0->用户;1->创作者)")
private String type;
private static final long serialVersionUID = 1L;
}

41
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/LevelInfoDto.java

@ -0,0 +1,41 @@
package com.bnyer.img.dto;
import com.bnyer.common.core.utils.bean.BeanUtils;
import com.bnyer.img.domain.LevelInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Getter
@Setter
@ApiModel("等级信息接收类")
public class LevelInfoDto implements Serializable {
@ApiModelProperty(value="主键id")
private Long id;
@ApiModelProperty(value="等级头衔名称")
private String title;
@ApiModelProperty(value="头衔图标")
private String titleIcon;
@ApiModelProperty(value="最小经验值")
private Integer minExp;
@ApiModelProperty(value="最大经验值")
private Integer maxExp;
@ApiModelProperty(value="等级类型(0->用户;1->创作者)")
private String type;
public LevelInfo extractParam(){
LevelInfo levelInfo = new LevelInfo();
BeanUtils.copyProperties(this,levelInfo);
return levelInfo;
}
}

21
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/dto/LevelInfoPageDto.java

@ -0,0 +1,21 @@
package com.bnyer.img.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@ApiModel("等级分页接收类")
public class LevelInfoPageDto extends BasePageDto {
@ApiModelProperty(value="等级头衔名称")
private String title;
@ApiModelProperty(value="等级类型(0->用户;1->创作者)")
private String type;
@ApiModelProperty(value="是否显示")
private String isShow;
}

9
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/mapper/LevelInfoMapper.java

@ -0,0 +1,9 @@
package com.bnyer.img.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bnyer.img.domain.LevelInfo;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface LevelInfoMapper extends BaseMapper<LevelInfo> {
}

52
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/LevelInfoService.java

@ -0,0 +1,52 @@
package com.bnyer.img.service;
import com.bnyer.img.domain.LevelInfo;
import com.bnyer.img.dto.LevelInfoPageDto;
import java.util.List;
public interface LevelInfoService {
/**
* 新增等级
* @param levelInfo 等级信息
* @return -
*/
int insert(LevelInfo levelInfo);
/**
* 修改等级
* @param levelInfo 等级信息
* @return -
*/
int update(LevelInfo levelInfo);
/**
* 批量删除等级信息
* @param ids 主键ids
* @return -
*/
int delete(List<Long> ids);
/**
* 查询等级列表分页
* @param params 分页参数
* @return -
*/
List<LevelInfo> queryList(LevelInfoPageDto params);
/**
* 查询等级详情
* @param id 主键Id
* @return -
*/
LevelInfo queryDetails(Long id);
/**
* 变更显示状态
* @param id 主键id
* @param status 状态
* @return -
*/
int changeStatus(Long id, String status);
}

77
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/LevelInfoServiceImpl.java

@ -0,0 +1,77 @@
package com.bnyer.img.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.bnyer.common.core.utils.StringUtils;
import com.bnyer.img.domain.LevelInfo;
import com.bnyer.img.domain.Notice;
import com.bnyer.img.dto.LevelInfoPageDto;
import com.bnyer.img.mapper.LevelInfoMapper;
import com.bnyer.img.service.LevelInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
@Service
public class LevelInfoServiceImpl implements LevelInfoService {
@Autowired
private LevelInfoMapper levelInfoMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public int insert(LevelInfo levelInfo) {
levelInfo.setCreateTime(new Date());
levelInfo.setUpdateTime(new Date());
levelInfo.setIsShow("1");
levelInfo.setSort(0);
return levelInfoMapper.insert(levelInfo);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int update(LevelInfo levelInfo) {
levelInfo.setUpdateTime(new Date());
return levelInfoMapper.updateById(levelInfo);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int delete(List<Long> ids) {
return levelInfoMapper.deleteBatchIds(ids);
}
@Override
public List<LevelInfo> queryList(LevelInfoPageDto params) {
LambdaQueryWrapper<LevelInfo> wrapper = new LambdaQueryWrapper<>();
if(StringUtils.isNotBlank(params.getTitle())){
wrapper.like(LevelInfo::getTitle, params.getTitle());
}
if(StringUtils.isNotBlank(params.getType())){
wrapper.eq(LevelInfo::getType, params.getType());
}
if(StringUtils.isNotBlank(params.getIsShow())){
wrapper.eq(LevelInfo::getIsShow, params.getIsShow());
}
wrapper.orderByDesc(LevelInfo::getSort);
return levelInfoMapper.selectList(wrapper);
}
@Override
public LevelInfo queryDetails(Long id) {
return levelInfoMapper.selectById(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int changeStatus(Long id, String status) {
LambdaUpdateWrapper<LevelInfo> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(LevelInfo::getId, id);
LevelInfo levelInfo = new LevelInfo();
levelInfo.setIsShow(status);
return levelInfoMapper.update(levelInfo,wrapper);
}
}

6
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/CreatorDetailsVo.java

@ -26,6 +26,12 @@ public class CreatorDetailsVo implements Serializable {
@ApiModelProperty(value="头像img地址") @ApiModelProperty(value="头像img地址")
private String img; private String img;
@ApiModelProperty(value="等级名称")
private String levelName;
@ApiModelProperty(value="等级图标")
private String levelIcon;
@ApiModelProperty(value="序号") @ApiModelProperty(value="序号")
private Integer sort; private Integer sort;

6
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/CreatorFollowVo.java

@ -19,6 +19,12 @@ public class CreatorFollowVo implements Serializable {
@ApiModelProperty(value="搜索码") @ApiModelProperty(value="搜索码")
private String scanCode; private String scanCode;
@ApiModelProperty(value="等级名称")
private String levelName;
@ApiModelProperty(value="等级图标")
private String levelIcon;
@ApiModelProperty(value="是否热门") @ApiModelProperty(value="是否热门")
private String isHot; private String isHot;

6
bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/CreatorVo.java

@ -41,6 +41,12 @@ public class CreatorVo implements Serializable {
@ApiModelProperty(value="图片喜欢数量") @ApiModelProperty(value="图片喜欢数量")
private Integer imgLikeNum; private Integer imgLikeNum;
@ApiModelProperty(value="等级名称")
private String levelName;
@ApiModelProperty(value="等级图标")
private String levelIcon;
@ApiModelProperty(value="图片列表") @ApiModelProperty(value="图片列表")
List<TiktokImgVo> imgList; List<TiktokImgVo> imgList;

16
bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/CreatorMapper.xml

@ -15,6 +15,8 @@
<result column="invite_code" jdbcType="VARCHAR" property="inviteCode" /> <result column="invite_code" jdbcType="VARCHAR" property="inviteCode" />
<result column="url" jdbcType="VARCHAR" property="url" /> <result column="url" jdbcType="VARCHAR" property="url" />
<result column="status" jdbcType="CHAR" property="status" /> <result column="status" jdbcType="CHAR" property="status" />
<result column="level_id" jdbcType="BIGINT" property="levelId" />
<result column="exp" jdbcType="INTEGER" property="exp" />
<result column="is_hot" jdbcType="CHAR" property="isHot" /> <result column="is_hot" jdbcType="CHAR" property="isHot" />
<result column="is_show" jdbcType="CHAR" property="isShow" /> <result column="is_show" jdbcType="CHAR" property="isShow" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
@ -32,6 +34,8 @@
<result column="isHot" jdbcType="CHAR" property="isHot" /> <result column="isHot" jdbcType="CHAR" property="isHot" />
<result column="sort" jdbcType="INTEGER" property="sort" /> <result column="sort" jdbcType="INTEGER" property="sort" />
<result column="intro" jdbcType="VARCHAR" property="intro" /> <result column="intro" jdbcType="VARCHAR" property="intro" />
<result column="levelName" jdbcType="VARCHAR" property="levelName" />
<result column="levelIcon" jdbcType="VARCHAR" property="levelIcon" />
<result column="imgTotalNum" jdbcType="INTEGER" property="imgTotalNum" /> <result column="imgTotalNum" jdbcType="INTEGER" property="imgTotalNum" />
<result column="imgCollectionNum" jdbcType="INTEGER" property="imgCollectionNum" /> <result column="imgCollectionNum" jdbcType="INTEGER" property="imgCollectionNum" />
<result column="imgLikeNum" jdbcType="INTEGER" property="imgLikeNum" /> <result column="imgLikeNum" jdbcType="INTEGER" property="imgLikeNum" />
@ -43,6 +47,8 @@
<result column="scanCode" jdbcType="VARCHAR" property="scanCode" /> <result column="scanCode" jdbcType="VARCHAR" property="scanCode" />
<result column="img" jdbcType="VARCHAR" property="img" /> <result column="img" jdbcType="VARCHAR" property="img" />
<result column="isHot" jdbcType="CHAR" property="isHot" /> <result column="isHot" jdbcType="CHAR" property="isHot" />
<result column="levelName" jdbcType="VARCHAR" property="levelName" />
<result column="levelIcon" jdbcType="VARCHAR" property="levelIcon" />
<result column="sort" jdbcType="INTEGER" property="sort" /> <result column="sort" jdbcType="INTEGER" property="sort" />
<result column="intro" jdbcType="VARCHAR" property="intro" /> <result column="intro" jdbcType="VARCHAR" property="intro" />
<result column="imgTotalNum" jdbcType="INTEGER" property="imgTotalNum" /> <result column="imgTotalNum" jdbcType="INTEGER" property="imgTotalNum" />
@ -54,16 +60,18 @@
<sql id="Base_Column_List"> <sql id="Base_Column_List">
<!--@mbg.generated--> <!--@mbg.generated-->
id, `name`,password, scan_code, phone, img, intro, invite_code, url, status, is_hot, is_show, create_time, id, `name`,password, scan_code, phone, img, intro, invite_code, url, status, is_hot, is_show, create_time,
update_time, sort, amt, last_login_time update_time, sort, amt, last_login_time,level_id,exp
</sql> </sql>
<select id="queryThreeImgCreatorList" resultMap="CreatorThreeList"> <select id="queryThreeImgCreatorList" resultMap="CreatorThreeList">
select select
ic.id as id, ic.scan_code as scanCode,ic.img as img,ic.is_hot as isHot,ic.sort as sort,ic.intro as intro, ic.id as id, ic.scan_code as scanCode,ic.img as img,ic.is_hot as isHot,ic.sort as sort,ic.intro as intro,
ili.title as levelName,ili.title_icon as levelIcon,
(select count(id) from img_tiktok_img where creator_id = ic.id) as imgTotalNum, (select count(id) from img_tiktok_img where creator_id = ic.id) as imgTotalNum,
(select sum(great_num) from img_tiktok_img where creator_id = ic.id) as imgLikeNum, (select sum(great_num) from img_tiktok_img where creator_id = ic.id) as imgLikeNum,
(select sum(collection_num) from img_tiktok_img where creator_id = ic.id) as imgCollectionNum (select sum(collection_num) from img_tiktok_img where creator_id = ic.id) as imgCollectionNum
from img_creator ic from img_creator ic
join img_level_info ili on ili.id = ic.level_id
where ic.is_show = '1' and ic.status = '1' where ic.is_show = '1' and ic.status = '1'
order by ic.create_time asc order by ic.create_time asc
</select> </select>
@ -127,17 +135,21 @@
<select id="queryCreatorDetailsByScanCode" resultMap="CreatorTypeList"> <select id="queryCreatorDetailsByScanCode" resultMap="CreatorTypeList">
select select
ic.id as id, ic.scan_code as scanCode,ic.img as img,ic.is_hot as isHot,ic.sort as sort,ic.intro as intro, ic.id as id, ic.scan_code as scanCode,ic.img as img,ic.is_hot as isHot,ic.sort as sort,ic.intro as intro,
ili.title as levelName,ili.title_icon as levelIcon,
(select count(id) from img_tiktok_img where creator_id = ic.id) as imgTotalNum, (select count(id) from img_tiktok_img where creator_id = ic.id) as imgTotalNum,
(select sum(great_num) from img_tiktok_img where creator_id = ic.id) as imgLikeNum, (select sum(great_num) from img_tiktok_img where creator_id = ic.id) as imgLikeNum,
(select sum(collection_num) from img_tiktok_img where creator_id = ic.id) as imgCollectionNum (select sum(collection_num) from img_tiktok_img where creator_id = ic.id) as imgCollectionNum
from img_creator ic from img_creator ic
join img_level_info ili on ili.id = ic.level_id
where ic.is_show = '1' and ic.status = '1' and ic.scan_code = #{scanCode} where ic.is_show = '1' and ic.status = '1' and ic.scan_code = #{scanCode}
</select> </select>
<select id="queryFollowCreator" resultType="com.bnyer.img.vo.CreatorFollowVo"> <select id="queryFollowCreator" resultType="com.bnyer.img.vo.CreatorFollowVo">
select select
ic.id as id,ic.scan_code as scanCode,ic.is_hot as isHot, ic.id as id,ic.scan_code as scanCode,ic.is_hot as isHot,
ic.img as img,ic.sort as sort,ic.intro as intro ic.img as img,ic.sort as sort,ic.intro as intro,
ili.title as levelName,ili.title_icon as levelIcon
from img_creator ic from img_creator ic
join img_level_info ili on ili.id = ic.level_id
where ic.is_show = '1' and ic.status = '1' and ic.id in where ic.is_show = '1' and ic.status = '1' and ic.id in
<foreach collection="idList" item="id" index="index" open="(" close=")" separator=","> <foreach collection="idList" item="id" index="index" open="(" close=")" separator=",">
#{id} #{id}

23
bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/LevelInfoMapper.xml

@ -0,0 +1,23 @@
<?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.bnyer.img.mapper.LevelInfoMapper">
<resultMap id="BaseResultMap" type="com.bnyer.img.domain.LevelInfo">
<!--@mbg.generated-->
<!--@Table img_level_info-->
<id column="id" jdbcType="BIGINT" property="id" />
<result column="title" jdbcType="VARCHAR" property="title" />
<result column="title_icon" jdbcType="VARCHAR" property="titleIcon" />
<result column="min_exp" jdbcType="INTEGER" property="minExp" />
<result column="max_exp" jdbcType="INTEGER" property="maxExp" />
<result column="type" jdbcType="CHAR" property="type" />
<result column="is_show" jdbcType="CHAR" property="isShow" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
<result column="sort" jdbcType="INTEGER" property="sort" />
</resultMap>
<sql id="Base_Column_List">
<!--@mbg.generated-->
id, title, title_icon, min_exp, max_exp, `type`, is_show, create_time, update_time,
sort
</sql>
</mapper>
Loading…
Cancel
Save