动态管理修改及加盟商资格面试
This commit is contained in:
@@ -86,6 +86,18 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<!-- TRTC 生成 userSig 依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.github.tencentyun</groupId>
|
||||
<artifactId>tls-sig-api-v2</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
<!-- OpenPDF -->
|
||||
<dependency>
|
||||
<groupId>com.github.librepdf</groupId>
|
||||
<artifactId>openpdf</artifactId>
|
||||
<version>1.3.30</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -44,6 +44,8 @@ public enum ErrorCodeEnum {
|
||||
USER_GROUP_NAME_EXIST(1021076, "用户分组名称已存在", null),
|
||||
USER_GROUP_NOT_EXIST(1021077, "用户分组不存在", null),
|
||||
GET_INFO_ERROR(1021078, "获取信息异常", null),
|
||||
|
||||
INTERVIEW_ENTER_FAIL(1021101, "进入面试间失败", null),
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.cool.store.utils;
|
||||
|
||||
import com.lowagie.text.Document;
|
||||
import com.lowagie.text.Font;
|
||||
import com.lowagie.text.Image;
|
||||
import com.lowagie.text.Paragraph;
|
||||
import com.lowagie.text.pdf.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* 使用 OpenPDF 封装的 pdf 工具类
|
||||
*/
|
||||
public class PDFUtils {
|
||||
|
||||
private static final int[] A4Size = {595, 842};
|
||||
|
||||
/**
|
||||
* 设置 pdf 背景图片(A4)
|
||||
* 每页都需要单独设置
|
||||
*/
|
||||
public static void setBackgroundImgA4(Document document, Image image) {
|
||||
//图片顶格
|
||||
image.setAbsolutePosition(0, 0);
|
||||
//填满 A4 大小的页面
|
||||
image.scaleAbsolute(A4Size[0], A4Size[1]);
|
||||
document.add(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 pdf 背景图片
|
||||
* 每页都需要单独设置
|
||||
*/
|
||||
public static void setBackgroundImg(Document document, Image image, int width, int height) {
|
||||
//图片顶格
|
||||
image.setAbsolutePosition(0, 0);
|
||||
image.scaleAbsolute(width, height);
|
||||
document.add(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文本放在 pdf 的绝对位置上来抠模板(不指定字体,默认为 OpenPDF 自带的 STSong-Light Normal)
|
||||
* @param reader PdfReader 流
|
||||
* @param outputStream 输出流
|
||||
* @param x 左边距
|
||||
* @param y 下边距
|
||||
* @param content 要插入的文本
|
||||
* @param fontSize 字体大小
|
||||
* @param color 文本颜色
|
||||
*/
|
||||
public static void putParagraphAbsolutely(PdfReader reader, OutputStream outputStream, float x, float y, String content, float fontSize, Color color) {
|
||||
try {
|
||||
BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
|
||||
addContent(reader, outputStream, content, x, y, baseFont, fontSize, 0, color);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定字体的文本绝对位置插入方法
|
||||
* @param reader PdfReader 流
|
||||
* @param outputStream 输出流
|
||||
* @param x 左边距
|
||||
* @param y 下边距
|
||||
* @param content 要插入的文本
|
||||
* @param baseFont 字体设置(如果不使用 OpenPDF 自带的字体,就需要将字体文件放在项目路径下)
|
||||
* 自定义字体方式
|
||||
* ttf 字体
|
||||
* 1. BaseFont baseFont = BaseFont.createFont("arial.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
|
||||
* ttc 字体(包含了两种字体,所以需要选择 0 或 1)
|
||||
* 2. BaseFont baseFont = BaseFont.createFont("simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
|
||||
* @param fontSize 字体大小
|
||||
* @param fontStyle 字体风格()
|
||||
* NORMAL = 0; BOLD = 1; ITALIC = 2; UNDERLINE = 4; STRIKETHRU = 8; BOLDITALIC = BOLD | ITALIC;
|
||||
* @param color 字体颜色
|
||||
*/
|
||||
public static void putParagraphAbsolutely(PdfReader reader, OutputStream outputStream, float x, float y, String content, BaseFont baseFont, float fontSize, int fontStyle, Color color) {
|
||||
addContent(reader, outputStream, content, x, y, baseFont, fontSize, fontStyle, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入文本的 raw 方法
|
||||
* @param reader PDF 读取流
|
||||
* @param outputStream 输出流
|
||||
* @param content 插入文本
|
||||
* @param x 左边距
|
||||
* @param y 下边距
|
||||
* @param baseFont 字体和编码设置
|
||||
* @param fontSize 字体大小
|
||||
* @param fontStyle 字体风格
|
||||
* @param color 字体颜色
|
||||
*/
|
||||
private static void addContent(PdfReader reader, OutputStream outputStream, String content, float x, float y, BaseFont baseFont, float fontSize, int fontStyle, Color color) {
|
||||
try {
|
||||
//生成 paragraph 并放在正确位置
|
||||
//抠模板
|
||||
PdfStamper stamper = new PdfStamper(reader, outputStream);
|
||||
PdfContentByte over = stamper.getOverContent(1);
|
||||
Font font = new Font(baseFont, fontSize, fontStyle, color);
|
||||
Paragraph insertContent = new Paragraph(content, font);
|
||||
|
||||
ColumnText columnText = new ColumnText(over);
|
||||
// llx 和 urx 最小的值决定离左边的距离. lly 和 ury 最大的值决定离下边的距离
|
||||
columnText.setSimpleColumn(x, y, Float.MAX_VALUE, Float.MIN_VALUE);
|
||||
columnText.addElement(insertContent);
|
||||
columnText.go();
|
||||
stamper.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.cool.store.utils;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.lowagie.text.Document;
|
||||
import com.lowagie.text.Image;
|
||||
import com.lowagie.text.pdf.PdfReader;
|
||||
import com.lowagie.text.pdf.PdfWriter;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
//生成资格面试通过函的工具
|
||||
public class PassLetterUtils {
|
||||
|
||||
/**
|
||||
* 生成通过函的方法
|
||||
* 返回通过函编码
|
||||
* @param partnerName 加盟商姓名
|
||||
* @param verifyCity 审批城市
|
||||
* @param passTime 审批通过时间
|
||||
*/
|
||||
public static String genPassLetter(String partnerName, String passCode, String verifyCity, DateTime passTime) {
|
||||
String randomNum = RandomUtil.randomNumbers(5);
|
||||
if (ObjectUtil.isEmpty(passCode)) {
|
||||
passCode = "HSAY" + DateUtil.format(passTime, "yyMMdd") + "-" + randomNum;
|
||||
}
|
||||
String passTimeStr = DateUtil.format(passTime, "yyyy年MM月dd日");
|
||||
Document document = new Document();
|
||||
try {
|
||||
//1. 创建 pdf document
|
||||
// ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
FileOutputStream outputStream = new FileOutputStream("passLetter.pdf");
|
||||
PdfWriter.getInstance(document, outputStream);
|
||||
document.open();
|
||||
|
||||
//2. 添加背景图片
|
||||
Image img = Image.getInstance(PassLetterUtils.class.getResource("/static/passLetterBg.jpg").toString());
|
||||
PDFUtils.setBackgroundImgA4(document, img);
|
||||
document.close();
|
||||
|
||||
//3. 填写通过函模板信息
|
||||
addContentToPdf(partnerName + " 先生/女士", 122, 640);
|
||||
addContentToPdf(passCode, 122, 558);
|
||||
addContentToPdf(verifyCity, 155, 494);
|
||||
addContentToPdf("60天", 135, 450);
|
||||
addContentToPdf(passTimeStr, 393, 152);
|
||||
return passCode;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addContentToPdf(String content, float x, float y) {
|
||||
try {
|
||||
PdfReader pdfReader = new PdfReader(Files.newInputStream(Paths.get("passLetter.pdf")));
|
||||
OutputStream outputStream = Files.newOutputStream(Paths.get("passLetter.pdf"));
|
||||
PDFUtils.putParagraphAbsolutely(pdfReader, outputStream, x, y, content, 20, new Color(255, 82,25));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.cool.store.utils;
|
||||
|
||||
import com.tencentyun.TLSSigAPIv2;
|
||||
|
||||
/**
|
||||
* 腾讯实时音视频TRTC工具类
|
||||
*/
|
||||
public class TRTCUtils {
|
||||
|
||||
/**
|
||||
* 默认过期时间 30 s
|
||||
*/
|
||||
private static final Long expired = 30L;
|
||||
|
||||
/**
|
||||
* 生成 userSig 用于进入会议
|
||||
* 详见 https://cloud.tencent.com/document/product/647/17275#.E8.B0.83.E8.AF.95.E8.B7.91.E9.80.9A.E9.98.B6.E6.AE.B5.E5.A6.82.E4.BD.95.E8.AE.A1.E7.AE.97-UserSig.EF.BC.9F
|
||||
*/
|
||||
public static String genUserSig(Long sdkAppId, String key, String userId) {
|
||||
TLSSigAPIv2 tlsSigAPIv2 = new TLSSigAPIv2(sdkAppId, key);
|
||||
return tlsSigAPIv2.genUserSig(userId, expired);
|
||||
}
|
||||
|
||||
public static String genUserSig(Long sdkAppId, String key, String userId, Long expiredTime) {
|
||||
TLSSigAPIv2 tlsSigAPIv2 = new TLSSigAPIv2(sdkAppId, key);
|
||||
return tlsSigAPIv2.genUserSig(userId, expiredTime);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import com.cool.store.dto.content.ContentQueryListDto;
|
||||
import com.cool.store.dto.content.ContentUpdateDto;
|
||||
import com.cool.store.entity.HyContentInfoDO;
|
||||
import com.cool.store.mapper.HyContentInfoMapper;
|
||||
import com.cool.store.vo.HyContentInfoVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -36,7 +37,7 @@ public class ContentDAO {
|
||||
contentInfoMapper.updateByPrimaryKeySelective(hyContentInfoDO);
|
||||
}
|
||||
|
||||
public List<HyContentInfoDO> queryContentList(ContentQueryListDto dto) {
|
||||
public List<HyContentInfoVO> queryContentList(ContentQueryListDto dto) {
|
||||
return contentInfoMapper.queryContentList(dto);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.cool.store.mapper;
|
||||
|
||||
import com.cool.store.dto.content.ContentQueryListDto;
|
||||
import com.cool.store.entity.HyContentInfoDO;
|
||||
import com.cool.store.vo.HyContentInfoVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
@@ -36,7 +37,7 @@ public interface HyContentInfoMapper {
|
||||
* 分页查询动态列表
|
||||
* 根据传入参数匹配
|
||||
*/
|
||||
List<HyContentInfoDO> queryContentList(ContentQueryListDto dto);
|
||||
List<HyContentInfoVO> queryContentList(ContentQueryListDto dto);
|
||||
|
||||
/**
|
||||
* 根据contentId查询动态详情
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.cool.store.mapper;
|
||||
|
||||
import com.cool.store.entity.HyPartnerInterviewDO;
|
||||
import com.cool.store.vo.PartnerInterviewInfoVO;
|
||||
import com.cool.store.vo.PartnerPassLetterDetailVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
@@ -31,4 +32,40 @@ public interface HyPartnerInterviewMapper {
|
||||
*/
|
||||
PartnerInterviewInfoVO queryByPartnerId(@Param("partnerId") String partnerId);
|
||||
|
||||
/**
|
||||
* 修改面试状态
|
||||
* 预约状态 0 待预约;1待面试;2已开始;3待审核;4审批中;5审批通过;6拒绝
|
||||
*/
|
||||
int updateInterviewStatus(@Param("interviewId") String interviewId, @Param("status") Integer status);
|
||||
|
||||
/**
|
||||
* 修改面试实际开始时间
|
||||
* @param dateTime "yyyy-MM-dd HH:mm:ss"
|
||||
*/
|
||||
int updateActualStartTime(@Param("interviewId") String interviewId, @Param("dateTime") String dateTime);
|
||||
|
||||
/**
|
||||
* 修改加盟商或面试官进入面试时间
|
||||
* @param userType 1.面试官2.加盟商3.其他
|
||||
* @param dateTime "yyyy-MM-dd HH:mm:ss"
|
||||
* @return
|
||||
*/
|
||||
int updateEnterTime(@Param("interviewId") String interviewId, @Param("userType") Integer userType, @Param("dateTime") String dateTime);
|
||||
|
||||
/**
|
||||
* 将加盟商是否参会修改为参会
|
||||
* 0未参加,1参加
|
||||
*/
|
||||
int updateWhetherPartnerEnter(@Param("interviewId") String interviewId);
|
||||
|
||||
/**
|
||||
* 根据会议 id 查询面试官 id
|
||||
*/
|
||||
String getInterviewerByInterviewId(@Param("interviewId") String interviewId);
|
||||
|
||||
/**
|
||||
* 获取通知函详情
|
||||
*/
|
||||
PartnerPassLetterDetailVO getPassLetterDetail(@Param("interviewId") String interviewId);
|
||||
|
||||
}
|
||||
@@ -17,8 +17,14 @@
|
||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.cool.store.entity.HyContentInfoDO">
|
||||
<result column="content" jdbcType="LONGVARCHAR" property="content" />
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="HyContentInfoVOList" type="com.cool.store.vo.HyContentInfoVO">
|
||||
<association property="updateUserName" column="update_user_id" select="getUpdateUserName"></association>
|
||||
<association property="updateUserPhone" column="update_user_id" select="getUpdateUserPhone"></association>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, content_title, subject, content_type, cover, status, deleted, create_time, update_time,
|
||||
id, content_title, subject, content_type, cover, content, status, deleted, create_time, update_time,
|
||||
create_user_id, update_user_id
|
||||
</sql>
|
||||
<sql id="Blob_Column_List">
|
||||
@@ -42,9 +48,6 @@
|
||||
<if test="record.status != null">
|
||||
status,
|
||||
</if>
|
||||
<if test="record.deleted != null">
|
||||
deleted,
|
||||
</if>
|
||||
<if test="record.createTime != null">
|
||||
create_time,
|
||||
</if>
|
||||
@@ -143,8 +146,8 @@
|
||||
</set>
|
||||
where id = #{contentId}
|
||||
</update>
|
||||
<select id="queryContentList" resultType="com.cool.store.entity.HyContentInfoDO">
|
||||
select <include refid="Base_Column_List"></include>
|
||||
<select id="queryContentList" resultMap="HyContentInfoVOList">
|
||||
select <include refid="Base_Column_List"></include>, update_user_id updateUserId
|
||||
from hy_content_info
|
||||
where deleted = 0
|
||||
<if test="contentTitle != null and contentTitle != ''">
|
||||
@@ -156,6 +159,24 @@
|
||||
<if test="contentType != null and contentType != ''">
|
||||
and content_type = #{contentType}
|
||||
</if>
|
||||
<if test="startTime != null and startTime != ''">
|
||||
and update_time >= #{startTime}
|
||||
</if>
|
||||
<if test="endTime != null and endTime != ''">
|
||||
and update_time <= #{endTime}
|
||||
</if>
|
||||
</select>
|
||||
<select id="getUpdateUserName" resultType="string">
|
||||
select name
|
||||
from enterprise_user
|
||||
where deleted = 0
|
||||
and user_id = #{updateUserId}
|
||||
</select>
|
||||
<select id="getUpdateUserPhone" resultType="string">
|
||||
select mobile
|
||||
from enterprise_user
|
||||
where deleted = 0
|
||||
and user_id = #{updateUserId}
|
||||
</select>
|
||||
|
||||
<!-- 查询动态详情 -->
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
<association property="interviewerName" column="interviewerId" select="queryInterviewerName" javaType="string"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="passLetterDetail" type="com.cool.store.vo.PartnerPassLetterDetailVO">
|
||||
<association property="partnerName" column="partner_id" select="queryPartnerName"></association>
|
||||
<association property="verifyCity" column="partner_id" select="getVerifyCity"></association>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, status, partner_line_id, interview_plan_id, partner_id, deadline, interviewer,
|
||||
recorder, process_info, record_time, summary, auth_code, pass_file_url, expiry_date,
|
||||
@@ -261,4 +266,68 @@
|
||||
WHERE deleted = 0
|
||||
AND user_id = #{interview}
|
||||
</select>
|
||||
|
||||
<!-- 修改面试状态 -->
|
||||
<update id="updateInterviewStatus">
|
||||
UPDATE hy_partner_interview
|
||||
SET `status` = #{status}
|
||||
WHERE id = #{interviewId}
|
||||
</update>
|
||||
|
||||
<!-- 修改面试实际开始时间 -->
|
||||
<update id="updateActualStartTime">
|
||||
UPDATE hy_partner_interview_plan
|
||||
SET actual_start_time = IF(actual_start_time IS NULL, #{dateTime}, actual_start_time)
|
||||
WHERE id = (
|
||||
SELECT interview_plan_id
|
||||
FROM hy_partner_interview
|
||||
WHERE id = #{interviewId}
|
||||
)
|
||||
</update>
|
||||
|
||||
<!-- 修改面试官或加盟商入会时间 -->
|
||||
<update id="updateEnterTime">
|
||||
UPDATE hy_partner_interview
|
||||
<set>
|
||||
<if test="userType != null and userType == 1">
|
||||
interviewer_enter_time = IF(interviewer_enter_time IS NULL, #{dateTime}, interviewer_enter_time),
|
||||
</if>
|
||||
<if test="userType != null and userType == 2">
|
||||
partner_enter_time = IF(partner_enter_time IS NULL, #{dateTime}, partner_enter_time)
|
||||
</if>
|
||||
</set>
|
||||
WHERE id = 1
|
||||
</update>
|
||||
|
||||
<!-- 修改加盟商参会状态为参加 -->
|
||||
<update id="updateWhetherPartnerEnter">
|
||||
UPDATE hy_partner_interview_plan
|
||||
SET is_partner_interview = 1
|
||||
WHERE id = (
|
||||
SELECT interview_plan_id
|
||||
FROM hy_partner_interview
|
||||
WHERE id = #{interviewId}
|
||||
)
|
||||
</update>
|
||||
|
||||
<!-- 根据会议 id 获取面试官 id -->
|
||||
<select id="getInterviewerByInterviewId" resultType="java.lang.String">
|
||||
SELECT interviewer
|
||||
FROM hy_partner_interview
|
||||
WHERE id = #{interviewId}
|
||||
</select>
|
||||
|
||||
<!-- 获取通知函详情 -->
|
||||
<select id="getPassLetterDetail" resultMap="passLetterDetail">
|
||||
SELECT pass_code, pass_file_url, expiry_date, partner_id
|
||||
FROM hy_partner_interview
|
||||
WHERE id = #{interviewId}
|
||||
</select>
|
||||
<!-- 获取意向开店区域 -->
|
||||
<select id="getVerifyCity" resultType="string">
|
||||
SELECT want_shop_area
|
||||
FROM hy_partner_intent_info
|
||||
WHERE partner_id = #{partner_id}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -18,4 +18,10 @@ public class ContentQueryListDto extends PageBasicInfo {
|
||||
@ApiModelProperty("类型,默认选中全部时不传值")
|
||||
private String contentType;
|
||||
|
||||
@ApiModelProperty("筛选开始时间")
|
||||
private String startTime;
|
||||
|
||||
@ApiModelProperty("筛选结束时间")
|
||||
private String endTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.cool.store.dto.partner;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EnterInterviewDto {
|
||||
|
||||
@ApiModelProperty(value = "会议id", required = true)
|
||||
private String interviewId;
|
||||
|
||||
@ApiModelProperty(value = "用户id", required = true)
|
||||
private String userId;
|
||||
|
||||
@ApiModelProperty(value = "1.面试官2.加盟商3.其他", required = true)
|
||||
private Integer userType;
|
||||
|
||||
}
|
||||
@@ -40,10 +40,10 @@ public class HyContentInfoDO implements Serializable {
|
||||
private Integer deleted;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
private Date createTime;
|
||||
private String createTime;
|
||||
|
||||
@ApiModelProperty("更新时间")
|
||||
private Date updateTime;
|
||||
private String updateTime;
|
||||
|
||||
@ApiModelProperty("新建人ID")
|
||||
private String createUserId;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.cool.store.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class HyContentInfoVO {
|
||||
|
||||
@ApiModelProperty("")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("内容标题")
|
||||
private String contentTitle;
|
||||
|
||||
@ApiModelProperty("栏目CODE")
|
||||
private String subject;
|
||||
|
||||
@ApiModelProperty("类型 image-图文 video-视频")
|
||||
private String contentType;
|
||||
|
||||
@ApiModelProperty("封面URL")
|
||||
private String cover;
|
||||
|
||||
@ApiModelProperty("状态 0-启用 1-禁用")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
private String createTime;
|
||||
|
||||
@ApiModelProperty("更新时间")
|
||||
private String updateTime;
|
||||
|
||||
@ApiModelProperty("新建人ID")
|
||||
private String createUserId;
|
||||
|
||||
@ApiModelProperty("更新人ID")
|
||||
private String updateUserId;
|
||||
|
||||
@ApiModelProperty("更新人姓名")
|
||||
private String updateUserName;
|
||||
|
||||
@ApiModelProperty("更新人电话")
|
||||
private String updateUserPhone;
|
||||
|
||||
@ApiModelProperty("图文内容或者视频文件URL")
|
||||
private String content;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.cool.store.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PartnerEnterInterviewVO {
|
||||
|
||||
@ApiModelProperty("userSig 进入会议需要的用户签名")
|
||||
private String userSign;
|
||||
|
||||
@ApiModelProperty("面试官id")
|
||||
private String interviewerId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.cool.store.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PartnerPassLetterDetailVO {
|
||||
|
||||
@ApiModelProperty("加盟商姓名")
|
||||
private String partnerName;
|
||||
|
||||
@ApiModelProperty("编码")
|
||||
private String passCode;
|
||||
|
||||
@ApiModelProperty("审核城市")
|
||||
private String verifyCity;
|
||||
|
||||
@ApiModelProperty("函文件URL")
|
||||
private String passFileUrl;
|
||||
|
||||
@ApiModelProperty("生成日期:YYYY-MM-DD")
|
||||
private String createTime;
|
||||
|
||||
@ApiModelProperty("有效期截至")
|
||||
private String expiryDate;
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.cool.store.dto.content.ContentAddDto;
|
||||
import com.cool.store.dto.content.ContentQueryListDto;
|
||||
import com.cool.store.dto.content.ContentUpdateDto;
|
||||
import com.cool.store.entity.HyContentInfoDO;
|
||||
import com.cool.store.vo.HyContentInfoVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -31,7 +32,7 @@ public interface ContentService {
|
||||
/**
|
||||
* 查询动态列表
|
||||
*/
|
||||
List<HyContentInfoDO> queryContentList(ContentQueryListDto dto);
|
||||
List<HyContentInfoVO> queryContentList(ContentQueryListDto dto);
|
||||
|
||||
/**
|
||||
* 查询动态详情
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.cool.store.service;
|
||||
|
||||
import com.cool.store.dto.partner.EnterInterviewDto;
|
||||
import com.cool.store.vo.PartnerEnterInterviewVO;
|
||||
import com.cool.store.vo.PartnerInterviewInfoVO;
|
||||
import com.cool.store.vo.PartnerPassLetterDetailVO;
|
||||
|
||||
public interface PartnerInterviewService {
|
||||
|
||||
@@ -11,4 +14,17 @@ public interface PartnerInterviewService {
|
||||
*/
|
||||
PartnerInterviewInfoVO queryByPartnerId(String partnerId);
|
||||
|
||||
/**
|
||||
* 进入面试间的方法
|
||||
* 修改一些面试状态
|
||||
* 最后返回 userSign 用于进入腾讯云音视频房间
|
||||
* @return userSign 进入视频所需签名
|
||||
*/
|
||||
PartnerEnterInterviewVO enterInterviewRoom(EnterInterviewDto dto);
|
||||
|
||||
/**
|
||||
* 获取通知函详情
|
||||
*/
|
||||
PartnerPassLetterDetailVO passLetterDetail(String interviewId);
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.cool.store.dto.content.ContentUpdateDto;
|
||||
import com.cool.store.entity.HyContentInfoDO;
|
||||
import com.cool.store.mapper.HyContentInfoMapper;
|
||||
import com.cool.store.service.ContentService;
|
||||
import com.cool.store.vo.HyContentInfoVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -60,7 +61,7 @@ public class ContentServiceImpl implements ContentService {
|
||||
* 查询动态列表
|
||||
*/
|
||||
@Override
|
||||
public List<HyContentInfoDO> queryContentList(ContentQueryListDto dto) {
|
||||
public List<HyContentInfoVO> queryContentList(ContentQueryListDto dto) {
|
||||
return contentInfoMapper.queryContentList(dto);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
package com.cool.store.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.cool.store.dto.partner.EnterInterviewDto;
|
||||
import com.cool.store.enums.ErrorCodeEnum;
|
||||
import com.cool.store.exception.ServiceException;
|
||||
import com.cool.store.mapper.HyPartnerInterviewMapper;
|
||||
import com.cool.store.service.PartnerInterviewService;
|
||||
import com.cool.store.utils.PDFUtils;
|
||||
import com.cool.store.utils.PassLetterUtils;
|
||||
import com.cool.store.utils.TRTCUtils;
|
||||
import com.cool.store.vo.PartnerEnterInterviewVO;
|
||||
import com.cool.store.vo.PartnerInterviewInfoVO;
|
||||
import com.cool.store.vo.PartnerPassLetterDetailVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
@Service
|
||||
public class PartnerInterviewServiceImpl implements PartnerInterviewService {
|
||||
@@ -12,8 +28,15 @@ public class PartnerInterviewServiceImpl implements PartnerInterviewService {
|
||||
@Autowired
|
||||
private HyPartnerInterviewMapper interviewMapper;
|
||||
|
||||
@Value("${trtc.sdkAppId}")
|
||||
private Long sdkAppId;
|
||||
|
||||
@Value("${trtc.secretKey}")
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 加盟商查询面试信息
|
||||
*
|
||||
* @param partnerId
|
||||
* @return
|
||||
*/
|
||||
@@ -22,4 +45,70 @@ public class PartnerInterviewServiceImpl implements PartnerInterviewService {
|
||||
return interviewMapper.queryByPartnerId(partnerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 进入面试间的方法
|
||||
* 修改一些面试状态
|
||||
* 最后返回 userSign 用于进入腾讯云音视频房间
|
||||
*
|
||||
* @return userSign 进入视频所需签名
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public PartnerEnterInterviewVO enterInterviewRoom(EnterInterviewDto dto) {
|
||||
try {
|
||||
//1. 将面试状态改为 --> 2已开始
|
||||
interviewMapper.updateInterviewStatus(dto.getInterviewId(), 2);
|
||||
//3. 修改面试实际开始时间,以第一个人进来的时间为准,后续不再修改
|
||||
interviewMapper.updateActualStartTime(dto.getInterviewId(), DateUtil.now());
|
||||
//4. 修改加盟商或面试官进入面试时间
|
||||
interviewMapper.updateEnterTime(dto.getInterviewId(), dto.getUserType(), DateUtil.now());
|
||||
//5. 加盟商如果进入了,就修改面试计划表 is_partner_interview 字段
|
||||
interviewMapper.updateWhetherPartnerEnter(dto.getInterviewId());
|
||||
//6. 查询对应的面试官id
|
||||
String interviewId = interviewMapper.getInterviewerByInterviewId(dto.getInterviewId());
|
||||
//生成 userSign
|
||||
String userSig = TRTCUtils.genUserSig(sdkAppId, key, dto.getUserId());
|
||||
PartnerEnterInterviewVO vo = new PartnerEnterInterviewVO();
|
||||
vo.setUserSign(userSig);
|
||||
vo.setInterviewerId(interviewId);
|
||||
return vo;
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException(ErrorCodeEnum.INTERVIEW_ENTER_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通知函详情
|
||||
* TODO 暂时将生成通过函文件的功能放在这里方便测试和联调,审批通过的回调方法完成后应该放到该方法中
|
||||
*/
|
||||
@Override
|
||||
public PartnerPassLetterDetailVO passLetterDetail(String interviewId) {
|
||||
PartnerPassLetterDetailVO vo = interviewMapper.getPassLetterDetail(interviewId);
|
||||
//有效期为审批通过次日起第 60 天的 23:59:59,由此倒推 createTime
|
||||
DateTime expiryDate = DateUtil.parseDate(vo.getExpiryDate());
|
||||
DateTime createTime = DateUtil.offsetDay(expiryDate, -61);
|
||||
vo.setCreateTime(DateUtil.format(createTime, "yyyy-MM-dd"));
|
||||
//解析意向开店区域为市级行政区
|
||||
String verifyCity = vo.getVerifyCity();
|
||||
if (verifyCity == null) {
|
||||
String passCode = PassLetterUtils.genPassLetter(vo.getPartnerName(), verifyCity, vo.getPassCode(), createTime);
|
||||
vo.setPassCode(passCode);
|
||||
return vo;
|
||||
}
|
||||
String[] split = verifyCity.split("/");
|
||||
//根据长度来取市级行政区域
|
||||
if (split.length == 2) {
|
||||
vo.setVerifyCity(split[1]);
|
||||
} else if (split.length == 3) {
|
||||
vo.setVerifyCity(split[1]);
|
||||
} else if (split.length == 4) {
|
||||
vo.setVerifyCity(split[2]);
|
||||
} else {
|
||||
System.out.println("wrong");
|
||||
}
|
||||
String passCode = PassLetterUtils.genPassLetter(vo.getPartnerName(), verifyCity, vo.getPassCode(), createTime);
|
||||
vo.setPassCode(passCode);
|
||||
return vo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.cool.store.dto.content.ContentUpdateDto;
|
||||
import com.cool.store.entity.HyContentInfoDO;
|
||||
import com.cool.store.response.ResponseResult;
|
||||
import com.cool.store.service.ContentService;
|
||||
import com.cool.store.vo.HyContentInfoVO;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@@ -43,10 +44,10 @@ public class ContentController {
|
||||
|
||||
@PostMapping("/queryContentList")
|
||||
@ApiOperation("查询动态列表")
|
||||
public ResponseResult<PageInfo<HyContentInfoDO>> queryContentList(@RequestBody ContentQueryListDto dto) {
|
||||
public ResponseResult<PageInfo<HyContentInfoVO>> queryContentList(@RequestBody ContentQueryListDto dto) {
|
||||
PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
|
||||
List<HyContentInfoDO> list = contentService.queryContentList(dto);
|
||||
PageInfo<HyContentInfoDO> page = new PageInfo<>(list);
|
||||
List<HyContentInfoVO> list = contentService.queryContentList(dto);
|
||||
PageInfo<HyContentInfoVO> page = new PageInfo<>(list);
|
||||
return ResponseResult.success(page);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,3 +48,7 @@ oss.accessKeySecret=FFsl8d9batprJ0vXr0k4Y8ada40Wm2
|
||||
oss.endpoint=oss-cn-hangzhou.aliyuncs.com
|
||||
oss.bucket=cool-store-hsay
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -47,4 +47,8 @@ oss.accessKeyId=LTAI5tKSnAbkEbmT6CeBwNN3
|
||||
oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -47,4 +47,8 @@ oss.accessKeyId=LTAI5tKSnAbkEbmT6CeBwNN3
|
||||
oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -49,4 +49,8 @@ oss.accessKeyId=LTAI5tRSXy2MrqaaBJ6gReur
|
||||
oss.accessKeySecret=FFsl8d9batprJ0vXr0k4Y8ada40Wm2
|
||||
oss.endpoint=oss-cn-hangzhou.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -47,4 +47,8 @@ oss.accessKeyId=LTAI5tKSnAbkEbmT6CeBwNN3
|
||||
oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -47,4 +47,8 @@ oss.accessKeyId=LTAI5tKSnAbkEbmT6CeBwNN3
|
||||
oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -47,4 +47,8 @@ oss.accessKeyId=LTAI5tKSnAbkEbmT6CeBwNN3
|
||||
oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -1,15 +1,26 @@
|
||||
package com.cool.store.controller;
|
||||
|
||||
import com.cool.store.dto.partner.EnterInterviewDto;
|
||||
import com.cool.store.response.ResponseResult;
|
||||
import com.cool.store.service.PartnerInterviewService;
|
||||
import com.cool.store.utils.PDFUtils;
|
||||
import com.cool.store.vo.PartnerEnterInterviewVO;
|
||||
import com.cool.store.vo.PartnerInterviewInfoVO;
|
||||
import com.cool.store.vo.PartnerPassLetterDetailVO;
|
||||
import com.lowagie.text.Document;
|
||||
import com.lowagie.text.Image;
|
||||
import com.lowagie.text.pdf.PdfWriter;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
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.bind.annotation.*;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@Api(tags = "加盟商资格面试")
|
||||
@RestController
|
||||
@@ -25,4 +36,16 @@ public class InterviewController {
|
||||
return ResponseResult.success(interviewService.queryByPartnerId(partnerId));
|
||||
}
|
||||
|
||||
@PostMapping("/enter")
|
||||
@ApiOperation("进入面试间")
|
||||
public ResponseResult<PartnerEnterInterviewVO> enterInterviewRoom(@RequestBody EnterInterviewDto dto) {
|
||||
return ResponseResult.success(interviewService.enterInterviewRoom(dto));
|
||||
}
|
||||
|
||||
@PostMapping("/passLetter/detail")
|
||||
@ApiOperation("通过函详情")
|
||||
public ResponseResult<PartnerPassLetterDetailVO> passLetterDetail(@RequestParam String interviewId) {
|
||||
return ResponseResult.success(interviewService.passLetterDetail(interviewId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,4 +47,8 @@ oss.accessKeyId=LTAI5tRSXy2MrqaaBJ6gReur
|
||||
oss.accessKeySecret=FFsl8d9batprJ0vXr0k4Y8ada40Wm2
|
||||
oss.endpoint=oss-cn-hangzhou.aliyuncs.com
|
||||
oss.bucket=cool-store-hsay
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -47,4 +47,8 @@ oss.accessKeyId=LTAI5tKSnAbkEbmT6CeBwNN3
|
||||
oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -45,4 +45,8 @@ oss.accessKeyId=LTAI5tKSnAbkEbmT6CeBwNN3
|
||||
oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -51,3 +51,7 @@ oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
|
||||
@@ -45,4 +45,8 @@ oss.accessKeyId=LTAI5tKSnAbkEbmT6CeBwNN3
|
||||
oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -45,4 +45,8 @@ oss.accessKeyId=LTAI5tKSnAbkEbmT6CeBwNN3
|
||||
oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
@@ -45,4 +45,8 @@ oss.accessKeyId=LTAI5tKSnAbkEbmT6CeBwNN3
|
||||
oss.accessKeySecret=PbXOzUFwAvZ2K5zIawwa7NAJE2pFXS
|
||||
oss.endpoint=oss-cn-shanghai.aliyuncs.com
|
||||
oss.bucket=vec-coolstore
|
||||
corp.id = 171cddee76471740
|
||||
corp.id = 171cddee76471740
|
||||
|
||||
#TRTC
|
||||
trtc.sdkAppId=1400811820
|
||||
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 942 KiB |
Reference in New Issue
Block a user