13 changed files with 586 additions and 1 deletions
@ -0,0 +1,80 @@ |
|||
package com.bnyer.img.controller; |
|||
|
|||
import com.alibaba.fastjson.JSON; |
|||
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.UserVip; |
|||
import com.bnyer.img.dto.UserVipDto; |
|||
import com.bnyer.img.dto.UserVipPageDto; |
|||
import com.bnyer.img.dto.StatusDto; |
|||
import com.bnyer.img.service.UserVipService; |
|||
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 = "【图文平台】用户会员vip接口",tags = "【图文平台】用户会员vip接口") |
|||
@RestController |
|||
@RequestMapping("/img/userVip") |
|||
@Slf4j |
|||
public class UserVipController extends BaseController { |
|||
|
|||
@Autowired |
|||
private UserVipService userVipService; |
|||
|
|||
//@RequiresPermissions("system:config:list")
|
|||
@ApiOperation(value="查询用户会员vip分页") |
|||
@PostMapping("/page") |
|||
public TableDataInfo pageUserVip(@RequestBody @ApiParam("分页对象") UserVipPageDto dto){ |
|||
PageHelper.startPage(dto.getPageNum(), dto.getPageSize()); |
|||
List<UserVip> userVips = userVipService.queryPage(dto); |
|||
return getDataTable(userVips); |
|||
} |
|||
|
|||
//@RequiresPermissions("system:config:list")
|
|||
@ApiOperation(value="新增用户会员vip") |
|||
@PostMapping(value = "/insert") |
|||
public AjaxResult insertUserVip(@Validated @RequestBody @ApiParam("用户会员vip对象") UserVipDto dto){ |
|||
log.debug("【图文平台后台】新增用户会员vip参数为:{}", JSON.toJSONString(dto)); |
|||
return AjaxResult.success(userVipService.insert(dto.extractParam())); |
|||
} |
|||
|
|||
//@RequiresPermissions("system:config:list")
|
|||
@ApiOperation(value="修改用户会员vip") |
|||
@PostMapping(value = "/update") |
|||
public AjaxResult updateUserVip(@Validated @RequestBody @ApiParam("用户会员vip对象")UserVipDto dto){ |
|||
log.debug("【图文平台后台】修改用户会员vip参数为:{}", JSON.toJSONString(dto)); |
|||
return AjaxResult.success(userVipService.update(dto.extractParam())); |
|||
} |
|||
|
|||
//@RequiresPermissions("system:config:list")
|
|||
@ApiOperation(value="删除用户会员vip") |
|||
@DeleteMapping(value = "/delete/{ids}") |
|||
public AjaxResult deleteUserVip(@PathVariable @ApiParam("主键ids") List<Long> ids){ |
|||
log.debug("【图文平台后台】删除用户会员vip参数为:{}", JSON.toJSONString(ids)); |
|||
return AjaxResult.success(userVipService.delete(ids)); |
|||
} |
|||
|
|||
//@RequiresPermissions("system:config:list")
|
|||
@ApiOperation(value="查询用户会员vip详情") |
|||
@GetMapping(value = "/details/{id}") |
|||
public AjaxResult detailsUserVip(@PathVariable @ApiParam("主键id") Long id){ |
|||
log.debug("【图文平台后台】查询用户会员vip详情参数为:{}", id); |
|||
return AjaxResult.success(userVipService.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(userVipService.changeStatus(dto.getId(),dto.getStatus())); |
|||
} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
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.math.BigDecimal; |
|||
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-UserVip") |
|||
@Getter |
|||
@Setter |
|||
@ToString |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
@TableName(value = "img_user_vip") |
|||
public class UserVip extends BaseDomain { |
|||
/** |
|||
* 主键Id |
|||
*/ |
|||
@TableId(value = "id", type = IdType.AUTO) |
|||
@ApiModelProperty(value="主键Id") |
|||
private Long id; |
|||
|
|||
/** |
|||
* vip名称 |
|||
*/ |
|||
@TableField(value = "vip_name") |
|||
@ApiModelProperty(value="vip名称") |
|||
private String vipName; |
|||
|
|||
/** |
|||
* vip编码 |
|||
*/ |
|||
@TableField(value = "vip_code") |
|||
@ApiModelProperty(value="vip编码") |
|||
private String vipCode; |
|||
|
|||
/** |
|||
* 原价 |
|||
*/ |
|||
@TableField(value = "origin_price") |
|||
@ApiModelProperty(value="原价") |
|||
private BigDecimal originPrice; |
|||
|
|||
/** |
|||
* 售价 |
|||
*/ |
|||
@TableField(value = "price") |
|||
@ApiModelProperty(value="售价") |
|||
private BigDecimal price; |
|||
|
|||
/** |
|||
* 描述 |
|||
*/ |
|||
@TableField(value = "description") |
|||
@ApiModelProperty(value="描述") |
|||
private String description; |
|||
|
|||
/** |
|||
* 热门描述 |
|||
*/ |
|||
@TableField(value = "hot_sign_desc") |
|||
@ApiModelProperty(value="热门描述") |
|||
private String hotSignDesc; |
|||
|
|||
/** |
|||
* 时长天数 |
|||
*/ |
|||
@TableField(value = "days") |
|||
@ApiModelProperty(value="时长天数") |
|||
private Integer days; |
|||
|
|||
/** |
|||
* 是否到期自动续费(0>否;1->是) |
|||
*/ |
|||
@TableField(value = "is_delay") |
|||
@ApiModelProperty(value="是否到期自动续费(0>否;1->是)") |
|||
private String isDelay; |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
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-UserVipRecord") |
|||
@Getter |
|||
@Setter |
|||
@ToString |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
@TableName(value = "img_user_vip_record") |
|||
public class UserVipRecord extends BaseDomain { |
|||
/** |
|||
* 主键id |
|||
*/ |
|||
@TableId(value = "id", type = IdType.AUTO) |
|||
@ApiModelProperty(value="主键id") |
|||
private Long id; |
|||
|
|||
/** |
|||
* 用户手机号 |
|||
*/ |
|||
@TableField(value = "phone") |
|||
@ApiModelProperty(value="用户手机号") |
|||
private String phone; |
|||
|
|||
/** |
|||
* 用户vip表id |
|||
*/ |
|||
@TableField(value = "user_vip_id") |
|||
@ApiModelProperty(value="用户vip表id") |
|||
private Long userVipId; |
|||
|
|||
/** |
|||
* 开始时间 |
|||
*/ |
|||
@TableField(value = "start_time") |
|||
@ApiModelProperty(value="开始时间") |
|||
private Date startTime; |
|||
|
|||
/** |
|||
* 到期时间 |
|||
*/ |
|||
@TableField(value = "end_time") |
|||
@ApiModelProperty(value="到期时间") |
|||
private Date endTime; |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
package com.bnyer.img.dto; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.TableField; |
|||
import com.bnyer.common.core.utils.StringUtils; |
|||
import com.bnyer.common.core.utils.bean.BeanUtils; |
|||
import com.bnyer.img.domain.Banner; |
|||
import com.bnyer.img.domain.UserVip; |
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Getter; |
|||
import lombok.Setter; |
|||
|
|||
import javax.validation.constraints.NotNull; |
|||
import java.io.Serializable; |
|||
import java.math.BigDecimal; |
|||
|
|||
|
|||
@Getter |
|||
@Setter |
|||
@ApiModel("用户会员vip接收类") |
|||
public class UserVipDto implements Serializable { |
|||
|
|||
@ApiModelProperty(value="主键Id") |
|||
private Long id; |
|||
|
|||
@ApiModelProperty(value="vip名称") |
|||
private String vipName; |
|||
|
|||
@ApiModelProperty(value="原价") |
|||
private String originPrice; |
|||
|
|||
@ApiModelProperty(value="售价") |
|||
private String price; |
|||
|
|||
@ApiModelProperty(value="描述") |
|||
private String description; |
|||
|
|||
@ApiModelProperty(value="热门描述") |
|||
private String hotSignDesc; |
|||
|
|||
@ApiModelProperty(value="时长天数") |
|||
private Integer days; |
|||
|
|||
@ApiModelProperty(value="是否到期自动续费(0>否;1->是)") |
|||
private String isDelay; |
|||
|
|||
public UserVip extractParam(){ |
|||
UserVip userVip = new UserVip(); |
|||
if(this.getId() != null){ |
|||
userVip.setId(this.getId()); |
|||
} |
|||
userVip.setVipName(this.getVipName()); |
|||
userVip.setOriginPrice(new BigDecimal(this.getOriginPrice())); |
|||
userVip.setPrice(new BigDecimal(this.getPrice())); |
|||
if(StringUtils.isNotBlank(this.getDescription())){ |
|||
userVip.setDescription(this.getDescription()); |
|||
} |
|||
if(StringUtils.isNotBlank(this.getHotSignDesc())){ |
|||
userVip.setHotSignDesc(this.getHotSignDesc()); |
|||
} |
|||
userVip.setDays(this.getDays()); |
|||
userVip.setIsDelay(this.getIsDelay()); |
|||
return userVip; |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
package com.bnyer.img.dto; |
|||
|
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Getter; |
|||
import lombok.Setter; |
|||
|
|||
|
|||
@Getter |
|||
@Setter |
|||
@ApiModel("会员vip分页接收类") |
|||
public class UserVipPageDto extends BasePageDto { |
|||
|
|||
@ApiModelProperty(value="vip名称") |
|||
private String vipName; |
|||
|
|||
@ApiModelProperty(value="vip编码") |
|||
private String vipCode; |
|||
|
|||
@ApiModelProperty(value="是否到期自动续费(0>否;1->是)") |
|||
private String isDelay; |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
package com.bnyer.img.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.bnyer.img.domain.UserVip; |
|||
import com.bnyer.img.vo.UserVipVo; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
|
|||
import java.util.List; |
|||
|
|||
@Mapper |
|||
public interface UserVipMapper extends BaseMapper<UserVip> { |
|||
|
|||
/** |
|||
* 获取小程序端会员vip列表 |
|||
* @return - |
|||
*/ |
|||
List<UserVipVo> queryFront(); |
|||
|
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
package com.bnyer.img.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.bnyer.img.domain.UserVipRecord; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
|
|||
@Mapper |
|||
public interface UserVipRecordMapper extends BaseMapper<UserVipRecord> { |
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
package com.bnyer.img.service; |
|||
|
|||
import com.bnyer.img.domain.UserVip; |
|||
import com.bnyer.img.dto.UserVipPageDto; |
|||
import com.bnyer.img.vo.UserVipVo; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface UserVipService { |
|||
|
|||
/** |
|||
* 新增会员vip |
|||
* @param userVip vip |
|||
* @return - |
|||
*/ |
|||
int insert(UserVip userVip); |
|||
|
|||
/** |
|||
* 修改会员vip |
|||
* @param userVip vip |
|||
* @return - |
|||
*/ |
|||
int update(UserVip userVip); |
|||
|
|||
/** |
|||
* 删除会员vip |
|||
* @param ids vip列表 |
|||
* @return - |
|||
*/ |
|||
int delete(List<Long> ids); |
|||
|
|||
/** |
|||
* 获取会员vip详情 |
|||
* @param id 主键id |
|||
* @return - |
|||
*/ |
|||
UserVip queryDetails(Long id); |
|||
|
|||
/** |
|||
* 获取会员vip分页 |
|||
* @param param 分页参数 |
|||
* @return - |
|||
*/ |
|||
List<UserVip> queryPage(UserVipPageDto param); |
|||
|
|||
/** |
|||
* 变更显示状态 |
|||
* @param id 主键id |
|||
* @param status 状态 |
|||
* @return - |
|||
*/ |
|||
int changeStatus(Long id,String status); |
|||
|
|||
/** |
|||
* 获取小程序端会员vip列表 |
|||
* @return - |
|||
*/ |
|||
List<UserVipVo> queryFront(); |
|||
} |
|||
@ -0,0 +1,85 @@ |
|||
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.common.core.utils.uuid.IdUtils; |
|||
import com.bnyer.img.domain.Banner; |
|||
import com.bnyer.img.domain.UserVip; |
|||
import com.bnyer.img.dto.UserVipPageDto; |
|||
import com.bnyer.img.mapper.UserVipMapper; |
|||
import com.bnyer.img.service.UserVipService; |
|||
import com.bnyer.img.vo.UserVipVo; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
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 |
|||
@Slf4j |
|||
public class UserVipServiceImpl implements UserVipService { |
|||
|
|||
@Autowired |
|||
private UserVipMapper userVipMapper; |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public int insert(UserVip userVip) { |
|||
userVip.setVipCode(IdUtils.fastSimpleUUID()); |
|||
userVip.setCreateTime(new Date()); |
|||
userVip.setUpdateTime(new Date()); |
|||
userVip.setIsShow("1"); |
|||
return userVipMapper.insert(userVip); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public int update(UserVip userVip) { |
|||
userVip.setUpdateTime(new Date()); |
|||
return userVipMapper.updateById(userVip); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public int delete(List<Long> ids) { |
|||
return userVipMapper.deleteBatchIds(ids); |
|||
} |
|||
|
|||
@Override |
|||
public UserVip queryDetails(Long id) { |
|||
return userVipMapper.selectById(id); |
|||
} |
|||
|
|||
@Override |
|||
public List<UserVip> queryPage(UserVipPageDto param) { |
|||
LambdaQueryWrapper<UserVip> wrapper = new LambdaQueryWrapper<>(); |
|||
if(StringUtils.isNotBlank(param.getVipName())){ |
|||
wrapper.like(UserVip::getVipName, param.getVipName()); |
|||
} |
|||
if(StringUtils.isNotBlank(param.getVipCode())){ |
|||
wrapper.eq(UserVip::getVipCode, param.getVipCode()); |
|||
} |
|||
if(StringUtils.isNotBlank(param.getIsDelay())){ |
|||
wrapper.eq(UserVip::getIsDelay, param.getIsDelay()); |
|||
} |
|||
wrapper.orderByDesc(UserVip::getSort); |
|||
return userVipMapper.selectList(wrapper); |
|||
} |
|||
|
|||
@Override |
|||
public int changeStatus(Long id, String status) { |
|||
LambdaUpdateWrapper<UserVip> wrapper = new LambdaUpdateWrapper<>(); |
|||
wrapper.eq(UserVip::getId, id); |
|||
UserVip userVip = new UserVip(); |
|||
userVip.setIsShow(status); |
|||
return userVipMapper.update(userVip,wrapper); |
|||
} |
|||
|
|||
@Override |
|||
public List<UserVipVo> queryFront() { |
|||
return userVipMapper.queryFront(); |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
package com.bnyer.img.vo; |
|||
|
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Getter; |
|||
import lombok.Setter; |
|||
|
|||
import java.io.Serializable; |
|||
import java.math.BigDecimal; |
|||
|
|||
|
|||
@Getter |
|||
@Setter |
|||
@ApiModel("会员vip响应类") |
|||
public class UserVipVo implements Serializable { |
|||
|
|||
@ApiModelProperty(value="主键Id") |
|||
private Long id; |
|||
|
|||
@ApiModelProperty(value="vip名称") |
|||
private String vipName; |
|||
|
|||
@ApiModelProperty(value="原价") |
|||
private BigDecimal originPrice; |
|||
|
|||
@ApiModelProperty(value="售价") |
|||
private BigDecimal price; |
|||
|
|||
@ApiModelProperty(value="描述") |
|||
private String description; |
|||
|
|||
@ApiModelProperty(value="热门描述") |
|||
private String hotSignDesc; |
|||
|
|||
@ApiModelProperty(value="排序") |
|||
private Integer sort; |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
<?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.UserVipMapper"> |
|||
<resultMap id="BaseResultMap" type="com.bnyer.img.domain.UserVip"> |
|||
<!--@mbg.generated--> |
|||
<!--@Table img_user_vip--> |
|||
<id column="id" jdbcType="BIGINT" property="id" /> |
|||
<result column="vip_name" jdbcType="VARCHAR" property="vipName" /> |
|||
<result column="vip_code" jdbcType="VARCHAR" property="vipCode" /> |
|||
<result column="origin_price" jdbcType="DECIMAL" property="originPrice" /> |
|||
<result column="price" jdbcType="DECIMAL" property="price" /> |
|||
<result column="description" jdbcType="VARCHAR" property="description" /> |
|||
<result column="hot_sign_desc" jdbcType="VARCHAR" property="hotSignDesc" /> |
|||
<result column="days" jdbcType="INTEGER" property="days" /> |
|||
<result column="is_delay" jdbcType="CHAR" property="isDelay" /> |
|||
<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, vip_name, vip_code, origin_price, price, description, hot_sign_desc, `days`, |
|||
is_delay, is_show, create_time, update_time, sort |
|||
</sql> |
|||
<select id="queryFront" resultType="com.bnyer.img.vo.UserVipVo"> |
|||
select |
|||
id, vip_name,origin_price, price, description,hot_sign_desc,sort |
|||
from img_user_vip |
|||
where is_show = '1' |
|||
order by sort desc |
|||
</select> |
|||
</mapper> |
|||
@ -0,0 +1,22 @@ |
|||
<?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.UserVipRecordMapper"> |
|||
<resultMap id="BaseResultMap" type="com.bnyer.img.domain.UserVipRecord"> |
|||
<!--@mbg.generated--> |
|||
<!--@Table img_user_vip_record--> |
|||
<id column="id" jdbcType="BIGINT" property="id" /> |
|||
<result column="phone" jdbcType="VARCHAR" property="phone" /> |
|||
<result column="user_vip_id" jdbcType="BIGINT" property="userVipId" /> |
|||
<result column="start_time" jdbcType="TIMESTAMP" property="startTime" /> |
|||
<result column="end_time" jdbcType="TIMESTAMP" property="endTime" /> |
|||
<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, phone, user_vip_id, start_time, end_time, is_show, create_time, update_time, |
|||
sort |
|||
</sql> |
|||
</mapper> |
|||
Loading…
Reference in new issue