Commit 0b174356 authored by liuyang's avatar liuyang

课程添加功能,暂存

parent d3d9ff85
......@@ -20,6 +20,8 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Date;
......@@ -49,6 +51,15 @@ public class AliyunService {
vodClient = initVodClient();
}
}
@PreDestroy
private void clean(){
if (ossClient != null){
ossClient.shutdown();
}
if (vodClient != null){
vodClient.shutdown();
}
}
private DefaultAcsClient initVodClient() {
DefaultProfile profile = DefaultProfile.getProfile(aliyunConfig.getRegion(),aliyunConfig.getAccessKeyId(),aliyunConfig.getAccessKeySecret());
......@@ -139,4 +150,11 @@ public class AliyunService {
map.put("region",aliyunConfig.getRegion());
return map;
}
public void uploadFile(String fullFileName, InputStream fileInputStream){
ossClient.putObject(aliyunConfig.getBucket(),fullFileName,fileInputStream);
}
public String getPublicUrl() {
return "https://"+aliyunConfig.getBucket()+"."+aliyunConfig.getEndpoint();
}
}
package com.qkdata.biz.enums;
public enum CourseAllowEnum {
/**
* 全部
*/
ALL,
/**
* 指定企业
*/
SPECIFY
}
package com.qkdata.biz.enums;
public enum CourseModelEnum {
/**
* 直播
*/
LIVE,
/**
* 点播
*/
VOD,
/**
* 一对一
*/
ONE_TO_ONE
}
package com.qkdata.biz.enums;
public enum CourseTypeEnum {
/**
* 单集
*/
SINGLE,
/**
* 系列
*/
SERIES
}
package com.qkdata.biz.management.controller;
import com.qkdata.biz.common.BizConstants;
import com.qkdata.biz.management.service.CourseService;
import com.qkdata.biz.management.vo.CourseListItemModel;
import com.qkdata.biz.management.vo.QueryCourseModel;
import com.qkdata.biz.management.vo.*;
import com.qkdata.common.annotation.SysLog;
import com.qkdata.common.base.model.PageResult;
import com.qkdata.common.base.model.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
......@@ -32,8 +34,53 @@ public class CourseController {
@ApiOperation("课程查询")
@PostMapping("/list")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR},logical = Logical.OR)
public PageResult<CourseListItemModel> list(@RequestBody QueryCourseModel param){
return courseService.queryPageList(param);
}
@ApiOperation("获取课程详情")
@GetMapping("/{id}")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR},logical = Logical.OR)
public Result<CourseDetailModel> courseDetail(@PathVariable Long id){
return Result.succeed(courseService.getCourseDetail(id));
}
@ApiOperation("课程上、下架操作")
@PostMapping("/modifyStatus")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR},logical = Logical.OR)
public Result<String> modifyStatus(@RequestBody ModifyCourseStatusModel model){
courseService.modifyStatus(model);
return Result.succeed("ok");
}
@ApiOperation("添加课程(第一步保存)")
@PostMapping("/saveStep1")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR},logical = Logical.OR)
@SysLog(value = "添加课程",includeParam = false)
public Result<Long> saveStep1(@RequestBody CourseStep1SaveModel model){
Long id = courseService.saveStep1(model);
return Result.succeed(id);
}
@ApiOperation("添加课程(第二步保存)")
@PostMapping("/saveStep2")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR},logical = Logical.OR)
public Result<String> saveStep2(@RequestBody List<CourseChaperModel> chaperList){
courseService.saveStep2(chaperList);
return Result.succeed("ok");
}
@ApiOperation("修改章节名称")
@PostMapping("/modifyChaperName")
@SysLog("修改章节名称")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR},logical = Logical.OR)
public Result<String> modifyChaperName(@RequestBody ModifyChaperNameModel model){
courseService.modifyChaperName(model);
return Result.succeed("ok");
}
@ApiOperation("删除章节")
@GetMapping("/delChaper/{chaperId}")
@SysLog("删除章节")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR},logical = Logical.OR)
public Result<String> delChaper(@PathVariable Long chaperId){
courseService.delChaper(chaperId);
return Result.succeed("ok");
}
}
package com.qkdata.biz.management.controller;
import com.qkdata.biz.management.service.ResourceService;
import com.qkdata.biz.management.vo.ResourceModel;
import com.qkdata.common.base.exception.BusinessException;
import com.qkdata.common.base.model.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
/**
* <p>
......@@ -16,7 +25,21 @@ import org.springframework.web.bind.annotation.RestController;
*/
@Api(tags = "资源管理")
@RestController
@RequestMapping("/api/management/resource-po")
@RequestMapping("/api/mgr/resource")
public class ResourceController {
@Autowired
private ResourceService resourceService;
@ApiOperation("上传文件")
@PostMapping("/uploadFile")
public Result<ResourceModel> uploadFile(@RequestParam("file")MultipartFile file){
if (file.isEmpty()){
throw new BusinessException("请求错误,文件不存在");
}
return Result.succeed(resourceService.uploadFile(file));
}
}
package com.qkdata.biz.management.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.qkdata.common.base.entity.BasePO;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 课程附件
* </p>
*
* @author liuyang
* @since 2021-05-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("course_attachment")
public class CourseAttachmentPO extends BasePO {
private static final long serialVersionUID = 1L;
/**
* 课程ID
*/
private Long courseId;
/**
* 资源ID
*/
private Long resourceId;
}
package com.qkdata.biz.management.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.qkdata.biz.enums.CourseChargeModelEnum;
import com.qkdata.biz.enums.CourseStatusEnum;
import com.qkdata.biz.enums.*;
import com.qkdata.common.base.entity.BasePO;
import lombok.Data;
import lombok.EqualsAndHashCode;
......@@ -26,7 +27,7 @@ public class CoursePO extends BasePO {
/**
* 课程类型(单集、系列)
*/
private String type;
private CourseTypeEnum type;
/**
* 课程名称
......@@ -37,6 +38,10 @@ public class CoursePO extends BasePO {
* 课程简介
*/
private String introduce;
/**
* 课程介绍
*/
private String detail;
/**
* 课程封面url
......@@ -76,7 +81,7 @@ public class CoursePO extends BasePO {
/**
* 课程形态(点播、直播、一对一)
*/
private String model;
private CourseModelEnum model;
/**
* 系列ID
......@@ -86,11 +91,12 @@ public class CoursePO extends BasePO {
/**
* 可见范围(全部、指定企业)
*/
private String allow;
private CourseAllowEnum allow;
/**
* 删除标识
*/
@TableLogic
private Boolean isDel;
......
package com.qkdata.biz.management.mapper;
import com.qkdata.biz.management.entity.CourseAttachmentPO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 课程附件 Mapper 接口
* </p>
*
* @author liuyang
* @since 2021-05-20
*/
@Mapper
public interface CourseAttachmentMapper extends BaseMapper<CourseAttachmentPO> {
}
package com.qkdata.biz.management.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qkdata.biz.enums.CourseStatusEnum;
import com.qkdata.biz.management.entity.CoursePO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qkdata.biz.management.vo.CourseListItemModel;
......@@ -22,4 +23,6 @@ import java.util.List;
public interface CourseMapper extends BaseMapper<CoursePO> {
List<CourseListItemModel> queryPageList(Page page, @Param("p") QueryCourseModel param);
void updateStatusById(@Param("id") Long id, @Param("status") CourseStatusEnum status);
}
......@@ -2,8 +2,11 @@ package com.qkdata.biz.management.mapper;
import com.qkdata.biz.management.entity.CourseTagRelPO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qkdata.biz.management.vo.CourseTagsModel;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* <p>
* 课程与标签关联表 Mapper 接口
......@@ -15,4 +18,5 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CourseTagRelMapper extends BaseMapper<CourseTagRelPO> {
List<CourseTagsModel> selectModelList(Long courseId);
}
package com.qkdata.biz.management.service;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qkdata.biz.management.entity.CoursePO;
import com.qkdata.biz.management.entity.CourseTagPO;
import com.qkdata.biz.management.mapper.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qkdata.biz.management.vo.CourseListItemModel;
import com.qkdata.biz.management.vo.QueryCourseModel;
import com.google.common.collect.Lists;
import com.qkdata.biz.enums.CourseAllowEnum;
import com.qkdata.biz.enums.CourseChargeModelEnum;
import com.qkdata.biz.enums.CourseModelEnum;
import com.qkdata.biz.enums.CourseStatusEnum;
import com.qkdata.biz.management.entity.*;
import com.qkdata.biz.management.mapper.*;
import com.qkdata.biz.management.vo.*;
import com.qkdata.common.base.enums.CodeEnum;
import com.qkdata.common.base.exception.BusinessException;
import com.qkdata.common.base.model.PageResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
......@@ -36,6 +44,8 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> {
private CourseTagRelMapper tagRelMapper;
@Autowired
private CourseTagService tagService;
@Autowired
private TeacherService teacherService;
public PageResult<CourseListItemModel> queryPageList(QueryCourseModel param) {
Page page = new Page(param.getPageIndex(),param.getPageSize());
......@@ -49,4 +59,114 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> {
}
return PageResult.<CourseListItemModel>builder().code(CodeEnum.SUCCESS.getCode()).count(page.getTotal()).data(list).build();
}
@Transactional
public Long saveStep1(CourseStep1SaveModel model) {
CoursePO po = convertToPO(model);
if (po.getId() == null){
save(po);
}else {
updateById(po);
}
if (CollUtil.isNotEmpty(model.getTagIds())){
updateCourseTags(po.getId(),model.getTagIds());
}
if (model.getAllow() == CourseAllowEnum.SPECIFY){
updateCourseAllowOrg(po.getId(),model.getAllowOrgIds());
}
return po.getId();
}
private void updateCourseAllowOrg(Long id, List<Long> allowOrgIds) {
//TODO
}
private void updateCourseTags(Long id, List<Long> tagIds) {
//TODO
}
private CoursePO convertToPO(CourseStep1SaveModel model) {
CoursePO po = new CoursePO();
po.setId(model.getId());
po.setName(model.getName());
po.setType(model.getType());
po.setIntroduce(model.getIntroduce());
po.setDetail(model.getDetail());
po.setLogoUrl(model.getLogoUrl());
po.setStatus(CourseStatusEnum.UP);
po.setTeacherId(model.getTeacherId());
po.setChargeModel(model.getChargeModel());
if (po.getChargeModel() == CourseChargeModelEnum.PAY){
po.setPrice(model.getPrice());
po.setValidPeriod(model.getValidPeriod());
po.setVipPrice(model.getVipPrice());
}
po.setModel(CourseModelEnum.VOD);
po.setAllow(model.getAllow());
po.setSeriesId(model.getSeriesId());
return po;
}
@Transactional
public void saveStep2(List<CourseChaperModel> chaperList) {
for (CourseChaperModel model : chaperList){
CourseChapterPO po = new CourseChapterPO();
po.setCourseId(model.getCourseId());
po.setName(model.getName());
po.setResourceId(model.getResourceId());
chapterMapper.insert(po);
}
}
public CourseDetailModel getCourseDetail(Long id) {
CoursePO po = getById(id);
if (po == null){
throw new BusinessException("请求错误,课程不存在");
}
CourseDetailModel model = new CourseDetailModel();
BeanUtils.copyProperties(po,model);
addTeacherInfo(model);
addSeriesInfo(model);
addTags(model);
//TODO
return model;
}
private void addTags(CourseDetailModel model) {
List<CourseTagsModel> tags = tagRelMapper.selectModelList(model.getId());
model.setTagList(tags);
}
private void addSeriesInfo(CourseDetailModel model) {
CourseSeriesPO po = seriesMapper.selectById(model.getSeriesId());
if (po != null){
model.setSeriesName(po.getName());
}
}
private void addTeacherInfo(CourseDetailModel model) {
TeacherPO teacherPO = teacherService.getById(model.getTeacherId());
if (teacherPO != null){
model.setTeacherName(teacherPO.getName());
}
}
public void modifyChaperName(ModifyChaperNameModel model) {
CourseChapterPO po = chapterMapper.selectById(model.getChaperId());
if (po == null){
throw new BusinessException("请求错误,章节不存在");
}
po.setName(model.getChaperName());
chapterMapper.updateById(po);
}
public void delChaper(Long chaperId) {
chapterMapper.deleteById(chaperId);
}
public void modifyStatus(ModifyCourseStatusModel model) {
baseMapper.updateStatusById(model.getId(),model.getStatus());
}
}
\ No newline at end of file
package com.qkdata.biz.management.service;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qkdata.biz.aliyun.service.AliyunService;
import com.qkdata.biz.management.entity.ResourcePO;
import com.qkdata.biz.management.mapper.ResourceMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qkdata.biz.management.vo.ResourceModel;
import com.qkdata.common.base.exception.BusinessException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
/**
* <p>
......@@ -16,4 +24,29 @@ import org.springframework.stereotype.Service;
@Service
public class ResourceService extends ServiceImpl<ResourceMapper, ResourcePO> {
@Autowired
private AliyunService aliyunService;
public ResourceModel uploadFile(MultipartFile file) {
try {
String originalFileName = file.getOriginalFilename();
String[] ary = StrUtil.split(originalFileName,StrUtil.DOT);
String extName = ary.length > 1 ? StrUtil.DOT + ary[1] : "";
String newFileNaem = generateFileName() + extName;
aliyunService.uploadFile(newFileNaem,file.getInputStream());
//保存ResourcePO
ResourcePO po = new ResourcePO();
po.setName(originalFileName);
po.setUrl(aliyunService.getPublicUrl()+"/"+newFileNaem);
save(po);
ResourceModel model = new ResourceModel();
BeanUtils.copyProperties(po,model);
return model;
}catch (Exception e){
throw new BusinessException("上传文件错误");
}
}
private String generateFileName(){
return System.currentTimeMillis() + RandomUtil.randomString(4);
}
}
\ No newline at end of file
package com.qkdata.biz.management.vo;
import lombok.Data;
@Data
public class CourseAllowEnterpriseModel {
private Long courseId;
private Long orgId;
private String orgName;
}
package com.qkdata.biz.management.vo;
import lombok.Data;
@Data
public class CourseAttachmentModel {
private Long courseId;
private Long resourceId;
private String resourceName;
private String resourceUrl;
}
package com.qkdata.biz.management.vo;
import lombok.Data;
@Data
public class CourseChaperModel {
private Long id;
/**
* 所属课程ID
*/
private Long courseId;
/**
* 章节名称
*/
private String name;
/**
* 视频ID
*/
private Long resourceId;
/**
* 视频URL
*/
private String videoUrl;
}
package com.qkdata.biz.management.vo;
import com.qkdata.biz.enums.CourseAllowEnum;
import com.qkdata.biz.enums.CourseChargeModelEnum;
import com.qkdata.biz.enums.CourseTypeEnum;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
public class CourseDetailModel {
private Long id;
/**
* 课程名称
*/
private String name;
/**
* 课程类型(单集、系列)
*/
private CourseTypeEnum type;
/**
* 课程简介
*/
private String introduce;
/**
* 课程介绍
*/
private String detail;
/**
* 课程封面url
*/
private String logoUrl;
/**
* 讲师ID
*/
private Long teacherId;
/**
* 讲师名称
*/
private String teacherName;
/**
* 收费模式(免费、会员免费、付费点播)
*/
private CourseChargeModelEnum chargeModel;
/**
* 付费点播普通用户价
*/
private BigDecimal price;
/**
* 付费点播会员价
*/
private BigDecimal vipPrice;
/**
* 有效时间(小时)
*/
private Integer validPeriod;
/**
* 系列ID
*/
private Long seriesId;
/**
* 系列名称
*/
private String seriesName;
/**
* 可见范围(全部、指定企业)
*/
private CourseAllowEnum allow;
/**
* 指定企业的列表
*/
private List<CourseAllowEnterpriseModel> allowOrgList;
/**
* 标签列表
*/
private List<CourseTagsModel> tagList;
/**
* 课程章节列表
*/
private List<CourseChaperModel> chaperList;
/**
* 课程附件列表
*/
private List<CourseAttachmentModel> attachmentList;
}
package com.qkdata.biz.management.vo;
import com.qkdata.biz.enums.CourseAllowEnum;
import com.qkdata.biz.enums.CourseChargeModelEnum;
import com.qkdata.biz.enums.CourseTypeEnum;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
public class CourseStep1SaveModel {
private Long id;
/**
* 课程名称
*/
private String name;
/**
* 课程类型(单集、系列)
*/
private CourseTypeEnum type;
/**
* 课程简介
*/
private String introduce;
/**
* 课程介绍
*/
private String detail;
/**
* 课程封面url
*/
private String logoUrl;
/**
* 讲师ID
*/
private Long teacherId;
/**
* 讲师名称
*/
private String teacherName;
/**
* 收费模式(免费、会员免费、付费点播)
*/
private CourseChargeModelEnum chargeModel;
/**
* 付费点播普通用户价
*/
private BigDecimal price;
/**
* 付费点播会员价
*/
private BigDecimal vipPrice;
/**
* 有效时间(小时)
*/
private Integer validPeriod;
/**
* 系列ID
*/
private Long seriesId;
/**
* 可见范围(全部、指定企业)
*/
private CourseAllowEnum allow;
/**
* 指定企业的列表
*/
private List<Long> allowOrgIds;
/**
* 标签列表
*/
private List<Long> tagIds;
}
package com.qkdata.biz.management.vo;
import lombok.Data;
@Data
public class CourseTagsModel {
private Long courseId;
private Long tagId;
private String tagName;
}
package com.qkdata.biz.management.vo;
import lombok.Data;
@Data
public class ModifyChaperNameModel {
private Long chaperId;
private String chaperName;
}
package com.qkdata.biz.management.vo;
import com.qkdata.biz.enums.CourseStatusEnum;
import lombok.Data;
@Data
public class ModifyCourseStatusModel {
private Long id;
private CourseStatusEnum status;
}
package com.qkdata.biz.management.vo;
import lombok.Data;
@Data
public class ResourceModel {
private Long id;
private String name;
private String url;
}
......@@ -2,9 +2,6 @@ server:
port: 80
servlet:
context-path: /online-edu-backend
multipart:
enable: true
max-file-size: 10M
# ssl:
# key-store: classpath:3275085_datahub.qiankundata.com.pfx
# key-store-password: cDU6D68N
......@@ -20,6 +17,10 @@ management:
# health:
# show-details: always
spring:
servlet:
multipart:
enabled: true
max-file-size: 10MB
datasource:
druid:
url: jdbc:mysql://mysql:3306/framework?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
......
ALTER TABLE `course`
ADD COLUMN `detail` text NULL COMMENT '课程介绍' AFTER `introduce`;
CREATE TABLE `course_attachment` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`course_id` bigint(11) NOT NULL COMMENT '课程ID',
`resource_id` bigint(11) NOT NULL COMMENT '资源ID',
PRIMARY KEY (`id`)
) COMMENT = '课程附件';
\ No newline at end of file
<?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.qkdata.biz.management.mapper.CourseMapper">
<update id="updateStatusById">
update course set `status` = #{status} where id = #{id}
</update>
<select id="queryPageList" resultType="com.qkdata.biz.management.vo.CourseListItemModel">
SELECT c.id,
......
<?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.qkdata.biz.management.mapper.CourseAttachmentMapper">
</mapper>
......@@ -2,4 +2,10 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qkdata.biz.management.mapper.CourseTagRelMapper">
<select id="selectModelList" resultType="com.qkdata.biz.management.vo.CourseTagsModel">
SELECT r.course_id,r.tag_id,t.`name` tag_name
FROM course_tag_rel r
INNER JOIN course_tag t on r.tag_id = t.id
WHERE r.course_id = #{courseId}
</select>
</mapper>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment