1
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
package com.ruoyi.jarvis.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
/**
|
||||
* TG 黄牛电话库 jarvis_tg_scalper_phone
|
||||
* TG黄牛电话库(开/慢开前置命中则不走TG,一条可含多个 11 位手机号)
|
||||
*
|
||||
* @author jarvis
|
||||
*/
|
||||
public class TgScalperPhone extends BaseEntity
|
||||
{
|
||||
@@ -14,11 +16,13 @@ public class TgScalperPhone extends BaseEntity
|
||||
|
||||
private Long id;
|
||||
|
||||
/** 11位手机号 */
|
||||
@Excel(name = "手机号")
|
||||
private String phone;
|
||||
/** JSON 数组字符串,如 ["13800138000","13900139000"] */
|
||||
@Excel(name = "手机号数组")
|
||||
private String phones;
|
||||
|
||||
/** 列表查询条件:匹配号码(JSON 数组包含精确匹配,或 phones 文本模糊) */
|
||||
private String phoneQuery;
|
||||
|
||||
/** 命中时直接回复企微的备注 */
|
||||
@Excel(name = "备注")
|
||||
private String remark;
|
||||
|
||||
@@ -26,56 +30,36 @@ public class TgScalperPhone extends BaseEntity
|
||||
@Excel(name = "状态", readConverterExp = "0=禁用,1=启用")
|
||||
private Integer status;
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
public String getPhone()
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone)
|
||||
{
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getRemark()
|
||||
{
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark)
|
||||
{
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public Integer getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
public String getPhones() { return phones; }
|
||||
public void setPhones(String phones) { this.phones = phones; }
|
||||
public String getPhoneQuery() { return phoneQuery; }
|
||||
public void setPhoneQuery(String phoneQuery) { this.phoneQuery = phoneQuery; }
|
||||
public String getRemark() { return remark; }
|
||||
public void setRemark(String remark) { this.remark = remark; }
|
||||
public Integer getStatus() { return status; }
|
||||
public void setStatus(Integer status) { this.status = status; }
|
||||
@Override
|
||||
public Date getCreateTime() { return createTime; }
|
||||
@Override
|
||||
public void setCreateTime(Date createTime) { this.createTime = createTime; }
|
||||
@Override
|
||||
public Date getUpdateTime() { return updateTime; }
|
||||
@Override
|
||||
public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("id", getId())
|
||||
.append("phone", getPhone())
|
||||
.append("remark", getRemark())
|
||||
.append("status", getStatus())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.toString();
|
||||
return "TgScalperPhone{id=" + id + ", phones=" + phones + ", remark=" + remark + ", status=" + status + "}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ruoyi.jarvis.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.ruoyi.jarvis.domain.TgScalperPhone;
|
||||
|
||||
/**
|
||||
@@ -12,8 +13,8 @@ public interface TgScalperPhoneMapper
|
||||
|
||||
List<TgScalperPhone> selectTgScalperPhoneList(TgScalperPhone q);
|
||||
|
||||
/** 按手机号查(不限状态,供唯一性校验) */
|
||||
TgScalperPhone selectTgScalperPhoneByPhone(String phone);
|
||||
/** 某号码是否已被其它行占用(JSON 数组含该号) */
|
||||
Long selectIdHavingPhone(@Param("excludeId") Long excludeId, @Param("cellPhone") String cellPhone);
|
||||
|
||||
/** 启用状态下按手机号查(开/慢走前置) */
|
||||
TgScalperPhone selectEnabledByPhone(String phone);
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package com.ruoyi.jarvis.service.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.jarvis.domain.TgScalperPhone;
|
||||
import com.ruoyi.jarvis.mapper.TgScalperPhoneMapper;
|
||||
@@ -37,44 +42,41 @@ public class TgScalperPhoneServiceImpl implements ITgScalperPhoneService
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return tgScalperPhoneMapper.selectEnabledByPhone(phone.trim());
|
||||
String p = phone.trim();
|
||||
if (!MOBILE_11.matcher(p).matches())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return tgScalperPhoneMapper.selectEnabledByPhone(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertTgScalperPhone(TgScalperPhone row)
|
||||
{
|
||||
validatePhone(row.getPhone());
|
||||
String phonesJson = normalizePhonesJson(row.getPhones());
|
||||
row.setPhones(phonesJson);
|
||||
if (!StringUtils.hasText(row.getRemark()))
|
||||
{
|
||||
throw new ServiceException("备注不能为空");
|
||||
}
|
||||
TgScalperPhone exist = tgScalperPhoneMapper.selectTgScalperPhoneByPhone(row.getPhone().trim());
|
||||
if (exist != null)
|
||||
{
|
||||
throw new ServiceException("手机号已存在");
|
||||
}
|
||||
assertNoPhoneConflictAcrossRows(null, phonesJson);
|
||||
if (row.getStatus() == null)
|
||||
{
|
||||
row.setStatus(1);
|
||||
}
|
||||
row.setPhone(row.getPhone().trim());
|
||||
return tgScalperPhoneMapper.insertTgScalperPhone(row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateTgScalperPhone(TgScalperPhone row)
|
||||
{
|
||||
validatePhone(row.getPhone());
|
||||
String phonesJson = normalizePhonesJson(row.getPhones());
|
||||
row.setPhones(phonesJson);
|
||||
if (!StringUtils.hasText(row.getRemark()))
|
||||
{
|
||||
throw new ServiceException("备注不能为空");
|
||||
}
|
||||
TgScalperPhone other = tgScalperPhoneMapper.selectTgScalperPhoneByPhone(row.getPhone().trim());
|
||||
if (other != null && !other.getId().equals(row.getId()))
|
||||
{
|
||||
throw new ServiceException("手机号已存在");
|
||||
}
|
||||
row.setPhone(row.getPhone().trim());
|
||||
assertNoPhoneConflictAcrossRows(row.getId(), phonesJson);
|
||||
return tgScalperPhoneMapper.updateTgScalperPhone(row);
|
||||
}
|
||||
|
||||
@@ -90,11 +92,92 @@ public class TgScalperPhoneServiceImpl implements ITgScalperPhoneService
|
||||
return tgScalperPhoneMapper.deleteTgScalperPhoneById(id);
|
||||
}
|
||||
|
||||
private static void validatePhone(String phone)
|
||||
private void assertNoPhoneConflictAcrossRows(Long excludeId, String phonesJson)
|
||||
{
|
||||
if (!StringUtils.hasText(phone) || !MOBILE_11.matcher(phone.trim()).matches())
|
||||
for (String cell : parseDistinctPhones(phonesJson))
|
||||
{
|
||||
throw new ServiceException("请输入正确的11位手机号");
|
||||
Long hit = tgScalperPhoneMapper.selectIdHavingPhone(excludeId, cell);
|
||||
if (hit != null)
|
||||
{
|
||||
throw new ServiceException("手机号已在其他记录中出现:" + cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 接受 JSON 数组字符串或非 JSON 的单个号码,规范为 JSON 数组字符串 */
|
||||
private static String normalizePhonesJson(String raw)
|
||||
{
|
||||
if (!StringUtils.hasText(raw))
|
||||
{
|
||||
throw new ServiceException("请至少填写一个11位手机号");
|
||||
}
|
||||
String s = raw.trim();
|
||||
List<String> cells = new ArrayList<>();
|
||||
if (s.startsWith("["))
|
||||
{
|
||||
try
|
||||
{
|
||||
JSONArray arr = JSON.parseArray(s);
|
||||
for (int i = 0; i < arr.size(); i++)
|
||||
{
|
||||
Object o = arr.get(i);
|
||||
if (o != null)
|
||||
{
|
||||
cells.add(String.valueOf(o).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ServiceException("phones 须为 JSON 数组,如 [\"13800138000\"]");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (String part : s.split("[,,;;\\s]+"))
|
||||
{
|
||||
String t = part.trim();
|
||||
if (StringUtils.hasText(t))
|
||||
{
|
||||
cells.add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<String> uniq = new LinkedHashSet<>();
|
||||
for (String c : cells)
|
||||
{
|
||||
if (!MOBILE_11.matcher(c).matches())
|
||||
{
|
||||
throw new ServiceException("请输入正确的11位手机号:" + c);
|
||||
}
|
||||
uniq.add(c);
|
||||
}
|
||||
if (uniq.isEmpty())
|
||||
{
|
||||
throw new ServiceException("请至少填写一个11位手机号");
|
||||
}
|
||||
return JSON.toJSONString(new ArrayList<>(uniq));
|
||||
}
|
||||
|
||||
private static List<String> parseDistinctPhones(String phonesJson)
|
||||
{
|
||||
List<String> out = new ArrayList<>();
|
||||
try
|
||||
{
|
||||
JSONArray arr = JSON.parseArray(phonesJson);
|
||||
for (int i = 0; i < arr.size(); i++)
|
||||
{
|
||||
Object o = arr.get(i);
|
||||
if (o != null)
|
||||
{
|
||||
out.add(String.valueOf(o).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ServiceException("数据损坏:phones 非合法 JSON 数组");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<resultMap type="TgScalperPhone" id="TgScalperPhoneResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="phone" column="phone" />
|
||||
<result property="phones" column="phones" />
|
||||
<result property="remark" column="remark" />
|
||||
<result property="status" column="status" />
|
||||
<result property="createTime" column="create_time" />
|
||||
@@ -14,14 +14,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectTgScalperPhoneVo">
|
||||
select id, phone, remark, status, create_time, update_time
|
||||
select id, phones, remark, status, create_time, update_time
|
||||
from jarvis_tg_scalper_phone
|
||||
</sql>
|
||||
|
||||
<select id="selectTgScalperPhoneList" parameterType="TgScalperPhone" resultMap="TgScalperPhoneResult">
|
||||
<include refid="selectTgScalperPhoneVo"/>
|
||||
<where>
|
||||
<if test="phone != null and phone != ''"> and phone like concat('%', #{phone}, '%')</if>
|
||||
<if test="phoneQuery != null and phoneQuery != ''">
|
||||
and (
|
||||
JSON_CONTAINS(phones, JSON_QUOTE(#{phoneQuery}), '$')
|
||||
or phones like concat('%', #{phoneQuery}, '%')
|
||||
)
|
||||
</if>
|
||||
<if test="remark != null and remark != ''"> and remark like concat('%', #{remark}, '%')</if>
|
||||
<if test="status != null"> and status = #{status}</if>
|
||||
</where>
|
||||
@@ -33,28 +38,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectTgScalperPhoneByPhone" parameterType="String" resultMap="TgScalperPhoneResult">
|
||||
<include refid="selectTgScalperPhoneVo"/>
|
||||
where phone = #{phone}
|
||||
<select id="selectIdHavingPhone" resultType="java.lang.Long">
|
||||
select id from jarvis_tg_scalper_phone
|
||||
where JSON_CONTAINS(phones, JSON_QUOTE(#{cellPhone}), '$')
|
||||
<if test="excludeId != null">and id != #{excludeId}</if>
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectEnabledByPhone" parameterType="String" resultMap="TgScalperPhoneResult">
|
||||
<include refid="selectTgScalperPhoneVo"/>
|
||||
where phone = #{phone} and status = 1
|
||||
where status = 1 and JSON_CONTAINS(phones, JSON_QUOTE(#{phone}), '$')
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<insert id="insertTgScalperPhone" parameterType="TgScalperPhone" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into jarvis_tg_scalper_phone
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="phone != null and phone != ''">phone,</if>
|
||||
<if test="phones != null and phones != ''">phones,</if>
|
||||
<if test="remark != null">remark,</if>
|
||||
<if test="status != null">status,</if>
|
||||
create_time,
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="phone != null and phone != ''">#{phone},</if>
|
||||
<if test="phones != null and phones != ''">#{phones},</if>
|
||||
<if test="remark != null">#{remark},</if>
|
||||
<if test="status != null">#{status},</if>
|
||||
sysdate(),
|
||||
@@ -64,7 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<update id="updateTgScalperPhone" parameterType="TgScalperPhone">
|
||||
update jarvis_tg_scalper_phone
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="phone != null and phone != ''">phone = #{phone},</if>
|
||||
<if test="phones != null and phones != ''">phones = #{phones},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
update_time = sysdate(),
|
||||
|
||||
Reference in New Issue
Block a user