This commit is contained in:
Vinjor 2025-11-06 17:51:25 +08:00
parent 9fd56c5745
commit fb0d8cde1e
30 changed files with 1079 additions and 268 deletions

View File

@ -4,8 +4,13 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.cus.vo.CusMainVO;
import com.ruoyi.utils.CodeGenerator;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -38,7 +43,36 @@ public class CusMainController extends BaseController
{
@Autowired
private ICusMainService cusMainService;
@Autowired
private CodeGenerator codeGenerator;
/**
* 生成客户编码
*/
@GetMapping("/generateCode")
public AjaxResult generateCustomerCode() {
try {
String code = codeGenerator.generate();
return AjaxResult.success("编码生成成功", code);
} catch (RuntimeException e) {
return AjaxResult.error(e.getMessage());
}
}
/**
* 校验编码是否重复
*/
@GetMapping("/checkCode")
public AjaxResult checkCode(String code) {
try {
LambdaQueryWrapper<CusMain> queryWrapper = new LambdaQueryWrapper<CusMain>().eq(CusMain::getCusCode, code);
if (cusMainService.count(queryWrapper) > 0) {
return AjaxResult.error("编码重复");
}
return success();
} catch (RuntimeException e) {
return AjaxResult.error(e.getMessage());
}
}
/**
* 查询客户信息列表
*/
@ -82,9 +116,9 @@ public class CusMainController extends BaseController
@PreAuthorize("@ss.hasPermi('cus:main:add')")
@Log(title = "客户信息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody CusMain cusMain)
{
return toAjax(cusMainService.save(cusMain));
public AjaxResult add(@RequestBody CusMainVO cusMainVO){
cusMainService.saveNewCus(cusMainVO);
return success();
}
/**

View File

@ -66,14 +66,5 @@ public class CusBank extends DlBaseEntity
@Excel(name = "税号")
private String taxId;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updatedTime;
}

View File

@ -50,14 +50,5 @@ public class CusCompany extends DlBaseEntity
@Excel(name = "联系地址")
private String contactAddress;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updatedTime;
}

View File

@ -27,7 +27,6 @@ public class CusContacts extends DlBaseEntity
private static final long serialVersionUID = 1L;
/** 主键(使用雪花算法生成唯一主键) */
@TableId(type = IdType.ASSIGN_UUID)
private Long id;
/** 客户ID */
@ -79,14 +78,5 @@ public class CusContacts extends DlBaseEntity
@Excel(name = "是否默认联系人")
private Boolean ifDefault;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updatedTime;
}

View File

@ -70,14 +70,6 @@ public class CusEmail extends DlBaseEntity
@Excel(name = "是否已读")
private Integer ifRead;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updatedTime;
}

View File

@ -122,14 +122,5 @@ public class CusFollow extends DlBaseEntity
@Excel(name = "是否完成")
private Integer ifCompleted;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updatedTime;
}

View File

@ -74,12 +74,4 @@ public class CusMain extends DlBaseEntity
/** 附件 */
private String files;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** 更新时间 */
private Date updatedTime;
}

View File

@ -54,14 +54,5 @@ public class CusManager extends DlBaseEntity
@Excel(name = "原部门")
private String oldDept;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updatedTime;
}

View File

@ -46,14 +46,5 @@ public class CusMark extends DlBaseEntity
@Excel(name = "图形文件路径")
private String imageUrl;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updatedTime;
}

View File

@ -54,14 +54,5 @@ public class CusTimeAxis extends DlBaseEntity
@Excel(name = "备注")
private String remark;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updatedTime;
}

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cus.domain.CusMain;
import com.ruoyi.cus.vo.CusMainVO;
/**
* 客户信息Service接口
@ -15,4 +16,12 @@ import com.ruoyi.cus.domain.CusMain;
public interface ICusMainService extends IService<CusMain>
{
IPage<CusMain> queryListPage(CusMain pageReqVO, Page<CusMain> page);
/**
* 新增客户信息
* @author vinjor-M
* @date 15:56 2025/11/6
* @param cusMainVO TODO
**/
void saveNewCus(CusMainVO cusMainVO);
}

View File

@ -3,12 +3,15 @@ package com.ruoyi.cus.service.impl;
import java.util.List;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.cus.domain.*;
import com.ruoyi.cus.mapper.*;
import com.ruoyi.cus.service.*;
import com.ruoyi.cus.vo.CusMainVO;
import com.ruoyi.utils.SnowflakeIdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cus.mapper.CusMainMapper;
import com.ruoyi.cus.domain.CusMain;
import com.ruoyi.cus.service.ICusMainService;
import org.springframework.transaction.annotation.Transactional;
/**
* 客户信息Service业务层处理
@ -21,9 +24,62 @@ public class CusMainServiceImpl extends ServiceImpl<CusMainMapper,CusMain> impl
{
@Autowired
private CusMainMapper cusMainMapper;
@Autowired
private SnowflakeIdGenerator snowflakeIdGenerator;
@Autowired
private ICusContactsService cusContactsService;
@Autowired
private ICusManagerService cusManagerService;
@Autowired
private ICusCompanyService cusCompanyService;
@Autowired
private ICusBankService cusBankService;
@Autowired
private ICusMarkService cusMarkService;
@Override
public IPage<CusMain> queryListPage(CusMain pageReqVO, Page<CusMain> page) {
return cusMainMapper.queryListPage(pageReqVO, page);
}
/**
* 新增客户信息
*
* @param cusMainVO TODO
* @author vinjor-M
* @date 15:56 2025/11/6
**/
@Override
@Transactional(rollbackFor = Exception.class)
public void saveNewCus(CusMainVO cusMainVO) {
CusMain cusMain = cusMainVO.getMainInfo();
cusMainMapper.insert(cusMain);
//联系人信息
List<CusContacts> contacts = cusMainVO.getContact();
for (CusContacts contact : contacts) {
contact.setId(snowflakeIdGenerator.generateId());
contact.setCusId(cusMain.getId());
}
cusContactsService.saveBatch(contacts);
//公司信息
CusCompany cusCompany = cusMainVO.getCompanyInfo();
cusCompany.setCusId(cusMain.getId());
cusCompanyService.save(cusCompany);
//管理信息
CusManager cusManager = cusMainVO.getManagementInfo();
cusManager.setCusId(cusMain.getId());
cusManagerService.save(cusManager);
//银行信息
List<CusBank> bankList = cusMainVO.getBankInfo();
if(!bankList.isEmpty()){
bankList.forEach(bank -> bank.setCusId(cusMain.getId()));
cusBankService.saveBatch(bankList);
}
//唛头信息
List<CusMark> markList = cusMainVO.getMark();
if(!markList.isEmpty()){
markList.forEach(mark -> mark.setCusId(cusMain.getId()));
cusMarkService.saveBatch(markList);
}
}
}

View File

@ -0,0 +1,22 @@
package com.ruoyi.cus.vo;
import com.ruoyi.cus.domain.*;
import lombok.Data;
import java.util.List;
@Data
public class CusMainVO {
/** 客户信息 */
private CusMain mainInfo;
/** 联系人信息 */
private List<CusContacts> contact;
/** 公司信息 */
private CusCompany companyInfo;
/** 管理信息 */
private CusManager managementInfo;
/** 银行信息 */
private List<CusBank> bankInfo;
/** 唛头信息 */
private List<CusMark> mark;
}

View File

@ -0,0 +1,66 @@
package com.ruoyi.utils;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
/**
* 编码生成工具
* @author vinjor-M
* @date 15:31 2025/11/6
**/
@Component
public class CodeGenerator {
/**
* Redis键前缀存储每日自增序号
*/
private static final String REDIS_KEY_PREFIX = "customer:code:seq:";
/**
* 编码前缀
*/
private static final String CODE_PREFIX = "CD";
/**
* 自增序号位数不足补0
*/
private static final int SEQ_LENGTH = 3;
/**
* 每日最大序号3位最大为999
*/
private static final long MAX_SEQ = 999L;
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* 生成客户编码
* @return 格式CD+年月日+3位自增数
*/
public String generate() {
// 1. 获取当天日期字符串yyyyMMdd
String dateStr = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
// 2. 构建Redis键每日一个独立键实现序号日重置
String redisKey = REDIS_KEY_PREFIX + dateStr;
// 3. Redis原子自增保证并发安全
Long seq = redisTemplate.opsForValue().increment(redisKey, 1);
// 4. 校验序号是否超出最大值
if (seq == null || seq > MAX_SEQ) {
throw new RuntimeException("今日客户编码已达上限999个请明日再试");
}
// 5. 序号补零不足3位前面补0
String seqStr = String.format("%0" + SEQ_LENGTH + "d", seq);
// 6. 拼接最终编码
return CODE_PREFIX + dateStr + seqStr;
}
}

View File

@ -0,0 +1,172 @@
package com.ruoyi.utils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.concurrent.atomic.AtomicLong;
/**
* 雪花算法ID生成器适配RuoYi框架支持16表分表
* 分表逻辑ID % 16 0-15对应16个分表
*/
@Component
public class SnowflakeIdGenerator implements InitializingBean {
/**
* 起始时间戳2025-01-01 00:00:00可自定义
*/
private static final long START_TIMESTAMP = 1735689600000L;
/**
* 数据中心ID位数5位支持0-31
*/
private static final int DATA_CENTER_ID_BITS = 5;
/**
* 机器ID位数5位支持0-31
*/
private static final int MACHINE_ID_BITS = 5;
/**
* 序列号位数12位支持0-4095
*/
private static final int SEQUENCE_BITS = 12;
/**
* 最大数据中心ID31
*/
private static final long MAX_DATA_CENTER_ID = ~(-1L << DATA_CENTER_ID_BITS);
/**
* 最大机器ID31
*/
private static final long MAX_MACHINE_ID = ~(-1L << MACHINE_ID_BITS);
/**
* 序列号掩码4095
*/
private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
/**
* 机器ID左移位数12位
*/
private static final int MACHINE_ID_SHIFT = SEQUENCE_BITS;
/**
* 数据中心ID左移位数12+5=17位
*/
private static final int DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS;
/**
* 时间戳左移位数12+5+5=22位
*/
private static final int TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS + DATA_CENTER_ID_BITS;
/**
* 数据中心ID从配置文件读取
*/
@Value("${snowflake.data-center-id:0}")
private long dataCenterId;
/**
* 机器ID从配置文件读取分布式部署时需唯一
*/
@Value("${snowflake.machine-id:0}")
private long machineId;
/**
* 上次生成ID的时间戳
*/
private volatile long lastTimestamp = -1L;
/**
* 序列号原子类保证线程安全
*/
private final AtomicLong sequence = new AtomicLong(0L);
/**
* 初始化校验机器ID和数据中心ID不能超出最大值
*/
@Override
public void afterPropertiesSet() throws Exception {
if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) {
throw new IllegalArgumentException(String.format("数据中心ID必须在0-%d之间", MAX_DATA_CENTER_ID));
}
if (machineId > MAX_MACHINE_ID || machineId < 0) {
throw new IllegalArgumentException(String.format("机器ID必须在0-%d之间", MAX_MACHINE_ID));
}
}
/**
* 生成雪花算法IDLong类型
*/
public synchronized long generateId() {
long currentTimestamp = System.currentTimeMillis();
// 处理时钟回拨避免ID重复
if (currentTimestamp < lastTimestamp) {
throw new RuntimeException(String.format("时钟回拨异常!当前时间戳:%d上次时间戳%d", currentTimestamp, lastTimestamp));
}
// 同一时间戳内序列号自增
if (currentTimestamp == lastTimestamp) {
sequence.set((sequence.get() + 1) & SEQUENCE_MASK);
// 序列号用尽等待下一毫秒
if (sequence.get() == 0) {
currentTimestamp = waitNextMillis(lastTimestamp);
}
} else {
// 新的时间戳序列号重置为0
sequence.set(0L);
}
// 更新上次生成ID的时间戳
lastTimestamp = currentTimestamp;
// 拼接64位ID时间戳左移22位 + 数据中心ID左移17位 + 机器ID左移12位 + 序列号
return ((currentTimestamp - START_TIMESTAMP) << TIMESTAMP_LEFT_SHIFT)
| (dataCenterId << DATA_CENTER_ID_SHIFT)
| (machineId << MACHINE_ID_SHIFT)
| sequence.get();
}
/**
* 等待下一毫秒避免序列号用尽
*/
private long waitNextMillis(long lastTimestamp) {
long currentTimestamp = System.currentTimeMillis();
while (currentTimestamp <= lastTimestamp) {
currentTimestamp = System.currentTimeMillis();
}
return currentTimestamp;
}
/**
* 生成IDString类型避免前端Long精度丢失
*/
public String generateIdStr() {
return String.valueOf(generateId());
}
/**
* 根据ID获取分表索引0-15用于16表分表
* @param id 雪花算法生成的ID
* @return 分表索引0-15
*/
public int getTableIndex(Long id) {
if (id == null) {
throw new IllegalArgumentException("ID不能为空");
}
// 取序列号部分低12位再取模16保证均匀分布到16个表
return (int) (id & 0xF); // 0xF = 15等价于 id % 16
}
/**
* 重载支持String类型ID
*/
public int getTableIndex(String idStr) {
if (idStr == null || idStr.isEmpty()) {
throw new IllegalArgumentException("ID字符串不能为空");
}
return getTableIndex(Long.parseLong(idStr));
}
}

View File

@ -153,32 +153,16 @@ aliyun:
access-key-id: LTAI5tLThQFWgMLRTf3siNjb
access-key-secret: M5HjOyB8ir5tYEPFOQwImfJNgsumaG
bucket-name: dianliang123
# Dify API 配置
dify:
api:
key: app-tRfIOnRtIb5fTeXRcJ46aWVh
url: https://api.dify.ai/v1
#dify:
# api:
# key: app-ahgDwrLi8KQ6V0aEKKwT6Io7
# url: http://10.19.128.77/v1
# 登录相关配置
login:
# 是否限制单用户登录
single: true
# Python环境配置
python:
# Python可执行文件路径
path: python3
# 脚本超时时间(分钟)
timeoutMinutes: 30
# 脚本
scripts:
# 信通院爬虫脚本
caict: /Users/menfutong/workspace/myproject/design-spider/dl_industry_ai/dl_admin/python_scripts/busi_caict_spider.py
# 雪花算法配置
snowflake:
data-center-id: 0 # 数据中心ID0-31多数据中心部署时区分
machine-id: 0 # 机器ID0-31同一数据中心内机器唯一分布式部署必填不同值

View File

@ -17,13 +17,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="taxId" column="tax_id" />
<result property="delFlag" column="del_flag" />
<result property="creator" column="creator" />
<result property="createdTime" column="created_time" />
<result property="createTime" column="create_time" />
<result property="updater" column="updater" />
<result property="updatedTime" column="updated_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectCusBankVo">
select id, cus_id, bank_account, bank_name, currency, bank_code, swift_code, bank_address, branch_code, tax_id, del_flag, creator, created_time, updater, updated_time from cus_bank
select id, cus_id, bank_account, bank_name, currency, bank_code, swift_code, bank_address, branch_code, tax_id, del_flag, creator, create_time, updater, update_time from cus_bank
</sql>
<select id="queryListPage" parameterType="CusBank" resultMap="CusBankResult">
@ -38,8 +38,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="entity.bankAddress != null and entity.bankAddress != ''"> and bank_address = #{entity.bankAddress}</if>
<if test="entity.branchCode != null and entity.branchCode != ''"> and branch_code = #{entity.branchCode}</if>
<if test="entity.taxId != null and entity.taxId != ''"> and tax_id = #{entity.taxId}</if>
<if test="entity.createdTime != null "> and created_time = #{entity.createdTime}</if>
<if test="entity.updatedTime != null "> and updated_time = #{entity.updatedTime}</if>
<if test="entity.createTime != null "> and create_time = #{entity.createTime}</if>
<if test="entity.updateTime != null "> and update_time = #{entity.updateTime}</if>
</where>
</select>
</mapper>

View File

@ -13,13 +13,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="contactAddress" column="contact_address" />
<result property="delFlag" column="del_flag" />
<result property="creator" column="creator" />
<result property="createdTime" column="created_time" />
<result property="createTime" column="create_time" />
<result property="updater" column="updater" />
<result property="updatedTime" column="updated_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectCusCompanyVo">
select id, cus_id, cus_from, cus_level, busi_type, contact_address, del_flag, creator, created_time, updater, updated_time from cus_company
select id, cus_id, cus_from, cus_level, busi_type, contact_address, del_flag, creator, create_time, updater, update_time from cus_company
</sql>
<select id="queryListPage" parameterType="CusCompany" resultMap="CusCompanyResult">
@ -30,8 +30,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="entity.cusLevel != null and entity.cusLevel != ''"> and cus_level = #{entity.cusLevel}</if>
<if test="entity.busiType != null and entity.busiType != ''"> and busi_type = #{entity.busiType}</if>
<if test="entity.contactAddress != null and entity.contactAddress != ''"> and contact_address = #{entity.contactAddress}</if>
<if test="entity.createdTime != null "> and created_time = #{entity.createdTime}</if>
<if test="entity.updatedTime != null "> and updated_time = #{entity.updatedTime}</if>
<if test="entity.createTime != null "> and create_time = #{entity.createTime}</if>
<if test="entity.updateTime != null "> and update_time = #{entity.updateTime}</if>
</where>
</select>
</mapper>

View File

@ -19,13 +19,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="qq" column="qq" />
<result property="delFlag" column="del_flag" />
<result property="creator" column="creator" />
<result property="createdTime" column="created_time" />
<result property="createTime" column="create_time" />
<result property="updater" column="updater" />
<result property="updatedTime" column="updated_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectCusContactsVo">
select id, cus_id, name, nick_name, sex, birthday, email, contact_address, telephone, whats_app, wechat, qq, del_flag, creator, created_time, updater, updated_time from cus_contacts
select id, cus_id, name, nick_name, sex, birthday, email, contact_address, telephone, whats_app, wechat, qq, del_flag, creator, create_time, updater, update_time from cus_contacts
</sql>
<select id="queryListPage" parameterType="CusContacts" resultMap="CusContactsResult">
@ -42,8 +42,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="entity.whatsApp != null and entity.whatsApp != ''"> and whats_app = #{entity.whatsApp}</if>
<if test="entity.wechat != null and entity.wechat != ''"> and wechat = #{entity.wechat}</if>
<if test="entity.qq != null and entity.qq != ''"> and qq = #{entity.qq}</if>
<if test="entity.createdTime != null "> and created_time = #{entity.createdTime}</if>
<if test="entity.updatedTime != null "> and updated_time = #{entity.updatedTime}</if>
<if test="entity.createTime != null "> and create_time = #{entity.createTime}</if>
<if test="entity.updateTime != null "> and update_time = #{entity.updateTime}</if>
</where>
</select>
</mapper>

View File

@ -18,13 +18,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="ifRead" column="if_read" />
<result property="delFlag" column="del_flag" />
<result property="creator" column="creator" />
<result property="createdTime" column="created_time" />
<result property="createTime" column="create_time" />
<result property="updater" column="updater" />
<result property="updatedTime" column="updated_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectCusEmailVo">
select id, cus_id, contact_id, sender, receiver, send_type, subject, content, files, if_star, if_read, del_flag, creator, created_time, updater, updated_time from cus_email
select id, cus_id, contact_id, sender, receiver, send_type, subject, content, files, if_star, if_read, del_flag, creator, create_time, updater, update_time from cus_email
</sql>
<select id="queryListPage" parameterType="CusEmail" resultMap="CusEmailResult">
@ -40,8 +40,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="entity.files != null and entity.files != ''"> and files = #{entity.files}</if>
<if test="entity.ifStar != null "> and if_star = #{entity.ifStar}</if>
<if test="entity.ifRead != null "> and if_read = #{entity.ifRead}</if>
<if test="entity.createdTime != null "> and created_time = #{entity.createdTime}</if>
<if test="entity.updatedTime != null "> and updated_time = #{entity.updatedTime}</if>
<if test="entity.createTime != null "> and create_time = #{entity.createTime}</if>
<if test="entity.updateTime != null "> and update_time = #{entity.updateTime}</if>
</where>
</select>
</mapper>

View File

@ -30,13 +30,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="ifCompleted" column="if_completed" />
<result property="delFlag" column="del_flag" />
<result property="creator" column="creator" />
<result property="createdTime" column="created_time" />
<result property="createTime" column="create_time" />
<result property="updater" column="updater" />
<result property="updatedTime" column="updated_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectCusFollowVo">
select id, cus_id, contact_id, follow_type, follow_content, follow_time, schedule_color, files, follow_way, follow_step, if_sync_cus, again_time, if_always_remind, cycle_type, cycle_other_type, cycle_other_value, cycle_start, cycle_end, busi_name, busi_id, user_id, other_user_ids, if_completed, del_flag, creator, created_time, updater, updated_time from cus_follow
select id, cus_id, contact_id, follow_type, follow_content, follow_time, schedule_color, files, follow_way, follow_step, if_sync_cus, again_time, if_always_remind, cycle_type, cycle_other_type, cycle_other_value, cycle_start, cycle_end, busi_name, busi_id, user_id, other_user_ids, if_completed, del_flag, creator, create_time, updater, update_time from cus_follow
</sql>
<select id="queryListPage" parameterType="CusFollow" resultMap="CusFollowResult">
@ -64,8 +64,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="entity.userId != null "> and user_id = #{entity.userId}</if>
<if test="entity.otherUserIds != null and entity.otherUserIds != ''"> and other_user_ids = #{entity.otherUserIds}</if>
<if test="entity.ifCompleted != null "> and if_completed = #{entity.ifCompleted}</if>
<if test="entity.createdTime != null "> and created_time = #{entity.createdTime}</if>
<if test="entity.updatedTime != null "> and updated_time = #{entity.updatedTime}</if>
<if test="entity.createTime != null "> and create_time = #{entity.createTime}</if>
<if test="entity.updateTime != null "> and update_time = #{entity.updateTime}</if>
</where>
</select>
</mapper>

View File

@ -19,13 +19,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="files" column="files" />
<result property="delFlag" column="del_flag" />
<result property="creator" column="creator" />
<result property="createdTime" column="created_time" />
<result property="createTime" column="create_time" />
<result property="updater" column="updater" />
<result property="updatedTime" column="updated_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectCusMainVo">
select id, cus_labels, cus_code, full_name, short_name, cus_type, country, zone_name, main_prods, site_url, remark, files, del_flag, creator, created_time, updater, updated_time from cus_main
select id, cus_labels, cus_code, full_name, short_name, cus_type, country, zone_name, main_prods, site_url, remark, files, del_flag, creator, create_time, updater, update_time from cus_main
</sql>
<select id="queryListPage" parameterType="CusMain" resultMap="CusMainResult">

View File

@ -14,13 +14,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="oldDept" column="old_dept" />
<result property="delFlag" column="del_flag" />
<result property="creator" column="creator" />
<result property="createdTime" column="created_time" />
<result property="createTime" column="create_time" />
<result property="updater" column="updater" />
<result property="updatedTime" column="updated_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectCusManagerVo">
select id, cus_id, user_id, follow_step, seas_reason, seas_group, old_dept, del_flag, creator, created_time, updater, updated_time from cus_manager
select id, cus_id, user_id, follow_step, seas_reason, seas_group, old_dept, del_flag, creator, create_time, updater, update_time from cus_manager
</sql>
<select id="queryListPage" parameterType="CusManager" resultMap="CusManagerResult">
@ -32,8 +32,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="entity.seasReason != null and entity.seasReason != ''"> and seas_reason = #{entity.seasReason}</if>
<if test="entity.seasGroup != null and entity.seasGroup != ''"> and seas_group = #{entity.seasGroup}</if>
<if test="entity.oldDept != null and entity.oldDept != ''"> and old_dept = #{entity.oldDept}</if>
<if test="entity.createdTime != null "> and created_time = #{entity.createdTime}</if>
<if test="entity.updatedTime != null "> and updated_time = #{entity.updatedTime}</if>
<if test="entity.createTime != null "> and create_time = #{entity.createTime}</if>
<if test="entity.updateTime != null "> and update_time = #{entity.updateTime}</if>
</where>
</select>
</mapper>

View File

@ -12,13 +12,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="imageUrl" column="image_url" />
<result property="delFlag" column="del_flag" />
<result property="creator" column="creator" />
<result property="createdTime" column="created_time" />
<result property="createTime" column="create_time" />
<result property="updater" column="updater" />
<result property="updatedTime" column="updated_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectCusMarkVo">
select id, cus_id, mark_position, text_content, image_url, del_flag, creator, created_time, updater, updated_time from cus_mark
select id, cus_id, mark_position, text_content, image_url, del_flag, creator, create_time, updater, update_time from cus_mark
</sql>
<select id="queryListPage" parameterType="CusMark" resultMap="CusMarkResult">
@ -28,8 +28,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="entity.markPosition != null and entity.markPosition != ''"> and mark_position = #{entity.markPosition}</if>
<if test="entity.textContent != null and entity.textContent != ''"> and text_content = #{entity.textContent}</if>
<if test="entity.imageUrl != null and entity.imageUrl != ''"> and image_url = #{entity.imageUrl}</if>
<if test="entity.createdTime != null "> and created_time = #{entity.createdTime}</if>
<if test="entity.updatedTime != null "> and updated_time = #{entity.updatedTime}</if>
<if test="entity.createTime != null "> and create_time = #{entity.createTime}</if>
<if test="entity.updateTime != null "> and update_time = #{entity.updateTime}</if>
</where>
</select>
</mapper>

View File

@ -14,13 +14,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="remark" column="remark" />
<result property="delFlag" column="del_flag" />
<result property="creator" column="creator" />
<result property="createdTime" column="created_time" />
<result property="createTime" column="create_time" />
<result property="updater" column="updater" />
<result property="updatedTime" column="updated_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectCusTimeAxisVo">
select id, cus_code, busi_max_catg, busi_catg, contact_id, content, remark, del_flag, creator, created_time, updater, updated_time from cus_time_axis
select id, cus_code, busi_max_catg, busi_catg, contact_id, content, remark, del_flag, creator, create_time, updater, update_time from cus_time_axis
</sql>
<select id="queryListPage" parameterType="CusTimeAxis" resultMap="CusTimeAxisResult">
@ -32,8 +32,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="entity.contactId != null and entity.contactId != ''"> and contact_id = #{entity.contactId}</if>
<if test="entity.content != null and entity.content != ''"> and content = #{entity.content}</if>
<if test="entity.remark != null and entity.remark != ''"> and remark = #{entity.remark}</if>
<if test="entity.createdTime != null "> and created_time = #{entity.createdTime}</if>
<if test="entity.updatedTime != null "> and updated_time = #{entity.updatedTime}</if>
<if test="entity.createTime != null "> and create_time = #{entity.createTime}</if>
<if test="entity.updateTime != null "> and update_time = #{entity.updateTime}</if>
</where>
</select>
</mapper>

View File

@ -41,4 +41,12 @@ export default {
text-overflow: ellipsis;
display: inline-block; /* 确保宽度生效 */
}
::v-deep .el-drawer__header{
margin-bottom: 10px !important;
padding-bottom: 15px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); /* 轻微阴影,增强层次感 */
}
::v-deep .el-date-editor{
width: 100% !important;
}
</style>

View File

@ -1,5 +1,21 @@
import request from '@/utils/request'
// 获取客户编码
export function getCode() {
return request({
url: '/cus/main/generateCode',
method: 'get'
})
}
// 校验编码是否重复
export function checkCode(query) {
return request({
url: '/cus/main/checkCode',
method: 'get',
params: query
})
}
// 查询客户信息列表
export function listMain(query) {
return request({

View File

@ -0,0 +1,566 @@
<template>
<el-drawer
:title="title"
:visible.sync="open"
:size="650"
direction="rtl"
:before-close="cancel">
<div class="dl-drawer-box">
<el-form ref="form" :model="formData" :rules="rules" label-width="80px">
<!-- 1. 主要信息区块 -->
<div id="main-info" class="content-section">
<div class="section-box">
<div class="section-title">主要信息</div>
<el-switch
v-model="onlyRequired.mainInfo"
active-text="只显示必填项"
class="required-switch"
></el-switch>
</div>
<!-- 必填项 -->
<el-row>
<el-col :span="12">
<el-form-item label="客户名称" prop="fullName" label-width="100px">
<el-input v-model="formData.mainInfo.fullName" placeholder="客户名称">
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户编码" prop="cusCode" label-width="100px">
<el-input v-model="formData.mainInfo.cusCode" placeholder="请输入客户编码">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12" v-if="!onlyRequired.mainInfo">
<el-form-item label="客户简称" prop="shortName" label-width="100px">
<el-input v-model="formData.mainInfo.shortName" placeholder="客户简称">
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户类型" prop="cusType" label-width="100px">
<el-select style="width: 100%" v-model="formData.mainInfo.cusType" filterable placeholder="客户类型" clearable>
<el-option
v-for="dict in dict.type.cus_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 其他非必填项-->
<div v-if="!onlyRequired.mainInfo">
<el-row>
<el-col :span="12">
<el-form-item label="国家/地区" label-width="100px">
<el-select style="width: 100%" v-model="formData.mainInfo.country" filterable placeholder="国家/地区" clearable>
<el-option
v-for="dict in countryList"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="时区" label-width="100px">
<el-select style="width: 100%" v-model="formData.mainInfo.zoneName" filterable placeholder="时区" clearable>
<el-option
v-for="dict in timeZoneList"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="主营产品" label-width="100px">
<!-- collapse-tags-->
<el-select style="width: 100%" v-model="formData.mainInfo.mainProds" multiple collapse-tags filterable placeholder="主营产品" clearable>
<el-option
v-for="dict in dict.type.cus_main_product"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="企业网站" label-width="100px">
<el-input v-model="formData.mainInfo.siteUrl" placeholder="企业网站">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注" label-width="100px">
<el-input type="textarea" v-model="formData.mainInfo.remark" placeholder="备注">
</el-input>
</el-form-item>
</el-col>
</el-row>
</div>
</div>
<div id="contact" class="content-section">
<div class="section-box">
<div class="section-title">联系人<span style="font-weight: normal">({{formData.contact.length}})</span></div>
<el-switch
v-model="onlyRequired.contact"
active-text="只显示必填项"
class="required-switch"
></el-switch>
<div class="section-right">
<el-button size="mini" type="primary" icon="el-icon-circle-plus-outline" circle @click="addNewContact"></el-button>
<el-button size="mini" type="danger" icon="el-icon-delete" circle @click="delContactBatch"></el-button>
</div>
</div>
<el-card class="box-card" v-for="(contact,index) in formData.contact" :class="{'choose-contact':-1!=chooseContactIndexs.indexOf(index)}" style="margin-bottom: 10px">
<!-- 左上角多选 -->
<div class="dl-checkbox-box">
<el-checkbox v-model="-1!=chooseContactIndexs.indexOf(index)" @change="chooseContact($event,index)"></el-checkbox>
</div>
<!-- 右下角删除 -->
<div class="dl-del-box">
<i class="el-icon-delete" @click="delContact(index)"></i>
</div>
<!-- 右上角默认选中 -->
<div class="corner-tag" :class="{'corner-tag-default':formData.contact[index].ifDefault,
'corner-tag-normal':!formData.contact[index].ifDefault}" @click="chooseDefault(index)">默认</div>
<el-row>
<el-col :span="12">
<el-form-item label="姓名"
:prop="'contact.' + index + '.name'"
:rules="[{ required: true, message: '请输入联系人姓名', trigger: 'blur' }]">
<el-input v-model="formData.contact[index].name" placeholder="请输入联系人姓名"></el-input>
</el-form-item>
</el-col>
<el-col :span="12" v-if="!onlyRequired.contact">
<el-form-item label="称呼">
<el-input v-model="formData.contact[index].nickName" placeholder="请输入联系人称呼"></el-input>
</el-form-item>
</el-col>
</el-row>
<div v-if="!onlyRequired.contact">
<el-row>
<el-col :span="12">
<el-form-item label="性别">
<el-radio-group v-model="formData.contact[index].sex">
<el-radio
v-for="dict in dict.type.sys_user_sex"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生日">
<el-date-picker
v-model="formData.contact[index].birthday"
type="date"
placeholder="选择生日">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="联系地址">
<el-input v-model="formData.contact[index].contactAddress" placeholder="请输入联系地址"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="邮箱">
<el-input v-model="formData.contact[index].email" placeholder="请输入邮箱"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row >
<el-col :span="12">
<el-form-item label="手机">
<el-input v-model="formData.contact[index].telephone" placeholder="请输入手机">
<el-select v-model="formData.contact[index].telephonePre" slot="prepend" placeholder="区号">
<el-option key="+86" label="+86" value="+86">中国,+86</el-option>
<el-option key="+12" label="+12" value="+12">阿拉伯联合酋长国 | THE UNITED ARAB EMIRATES + 971</el-option>
<el-option key="+34" label="+34" value="+34">中国,+34</el-option>
</el-select>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="WhatsApp">
<template #label>
<el-tooltip content="WhatsApp" placement="top" effect="dark">
<span class="ellipsis-label">WhatsApp</span>
</el-tooltip>
</template>
<el-input v-model="formData.contact[index].whatsApp" placeholder="请输入WhatsApp">
<el-select v-model="formData.contact[index].whatsAppPre" slot="prepend" placeholder="区号">
<el-option key="+86" label="+86" value="+86">中国,+86</el-option>
<el-option key="+12" label="+12" value="+12">阿拉伯联合酋长国 | THE UNITED ARAB EMIRATES + 971</el-option>
<el-option key="+34" label="+34" value="+34">中国,+34</el-option>
</el-select>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="微信">
<el-input v-model="formData.contact[index].wechat" placeholder="请输入微信"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="QQ">
<el-input v-model="formData.contact[index].qq" placeholder="请输入QQ"></el-input>
</el-form-item>
</el-col>
</el-row>
</div>
</el-card>
<el-empty v-if="formData.contact.length==0" description="暂无数据"></el-empty>
</div>
<!-- 7. 附件区块 -->
<div id="attachment" class="content-section">
<div class="section-box">
<div class="section-title">附件</div>
</div>
<el-row>
<el-col :span="24">
<el-form-item label="附件">
<file-upload v-model="formData.files"/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
</div>
<div class="dl-drawer-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-drawer>
</template>
<script>
import { getCode, addMain } from "@/api/cus/main";
export default {
name: 'drawForm',
dicts: ['cus_main_product', 'cus_label', 'cus_type','sys_user_sex','cus_from','cus_level','cus_busi_type','cus_follow_step'],
data() {
return {
//
title: "快速新建客户",
//
open: false,
//
chooseContactIndexs: [],
//
onlyRequired: {
mainInfo: false,
contact: false,
},
//
formData: {
mainInfo: {
cusCode: '',
fullName: '',
cusType: '',
country: '',
shortName: '',
zoneName: '',
mainProds: "",
siteUrl: '',
remark: "",
files: ""
},
contact: [
{
name: '',
ifDefault: true,
nickName: '',
sex: '1',
birthday: '',
contactAddress: '',
email: '',
telephone: '',
telephonePre: '',
whatsApp: '',
whatsAppPre: '',
wechat: '',
qq: '',
}
]
},
//
//
countryList: [],
//
timeZoneList: [],
//
rules: {
cusCode: [
{ required: true, message: '请输入客户编码', trigger: 'blur' }
],
fullName: [
{ required: true, message: '请输入客户名称', trigger: 'blur' }
],
cusType: [
{ required: true, message: '请选择客户类型', trigger: 'blur' }
],
'contact': [
{
type: 'array',
required: true,
message: '请至少添加一个联系人',
trigger: 'change'
}
]
}
};
},
methods: {
/**
* 新增联系人
*/
addNewContact(){
this.formData.contact.push({
name: '',
ifDefault: false,
nickName: '',
sex: '0',
birthday: '',
contactAddress: '',
email: '',
telephone: '',
telephonePre: '',
whatsApp: '',
whatsAppPre: '',
wechat: '',
qq: '',
})
},
/**
* 选中默认的联系人
*/
chooseDefault(index){
this.$nextTick(()=>{
this.formData.contact.forEach((item,thisIndex) => {
item.ifDefault = thisIndex==index
})
})
console.log(this.formData.contact)
},
/**
* 批量删除联系人
*/
delContactBatch(){
if(this.chooseContactIndexs.length==0){
this.$message({
message: '请至少选择一个联系人',
type: 'warning'
});
}else{
this.formData.contact = this.formData.contact.filter((item,index) => {
return !this.chooseContactIndexs.includes(index)
})
this.chooseContactIndexs = []
}
},
/**
* 删除联系人
* @param index
*/
delContact(index){
this.formData.contact = this.formData.contact.filter((item,thisIndex) => {
return thisIndex!=index
})
this.chooseContactIndexs = this.chooseContactIndexs.filter((item,thisIndex) => {
return thisIndex!=index
})
},
/**
* 选择联系人
* @param val
* @param index
*/
chooseContact(val,index){
if(val){
//
this.chooseContactIndexs.push(index)
}else{
this.chooseContactIndexs.splice(this.chooseContactIndexs.indexOf(index),1)
}
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.formData = {
mainInfo: {
cusCode: '',
fullName: '',
cusType: '',
country: '',
shortName: '',
zoneName: '',
mainProds: "",
siteUrl: '',
remark: "",
files: ""
},
contact: [
{
name: '',
ifDefault: true,
nickName: '',
sex: '1',
birthday: '',
contactAddress: '',
email: '',
telephone: '',
telephonePre: '',
whatsApp: '',
whatsAppPre: '',
wechat: '',
qq: '',
}
]
};
this.resetForm("formData");
},
/** 提交按钮 */
submitForm() {
this.$refs["formData"].validate(valid => {
if (valid) {
}
})
},
}
}
</script>
<style scoped>
/* 内容区块样式 */
.content-section {
background-color: #ffffff;
border-radius: 8px; /* 圆角优化,更美观 */
padding: 5px 20px;
margin-bottom: 15px; /* 区块之间间距 */
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); /* 轻微阴影,增强层次感 */
}
/* 区块标题样式 */
.section-box {
margin: 8px 0 16px 0;
display: flex;
align-items: center;
border-bottom: 1px solid #f0f0f0;
padding-bottom: 8px;
}
.section-title {
font-weight: bold;
font-size: 16px;
color: #333333;
padding: 0 20px 0 10px;
}
.section-title::before {
content: "";
width: 3px;
height: 12px;
background: #1890ff;
border-radius: 2px;
margin-left: 0;
margin-right: 8px;
display: inline-block;
}
.section-right{
flex: 1;
text-align: right;
}
.dl-drawer-box{
position: relative;
padding-bottom: 40px;
height: 100%;
overflow-y: scroll;
}
.dl-drawer-footer{
z-index: 999;
background-color: white;
border-top: 1px solid #DCDFE6;;
position: absolute;
bottom: 0;
width: 100%;
padding: 10px;
height: 60px;
display: flex;
align-items: end;
justify-content: end;
}
::v-deep .el-select .el-input {
min-width: 60px;
}
::v-deep .el-select .el-input__inner{
padding: 5px !important;
}
::v-deep .input-with-select .el-input-group__prepend {
background-color: #fff;
}
.choose-contact{
border: 1px solid #1366ff !important;
}
.box-card{
position: relative;
border: 1px solid transparent;
}
::v-deep .el-card__body{
padding: 15px 20px 0 20px;
}
.dl-checkbox-box{
position: absolute;
left: 5px;
top: 5px;
}
.dl-del-box{
cursor: pointer;
position: absolute;
right: 5px;
bottom: 5px;
}
/* 角标样式:定位、旋转、外观 */
.corner-tag {
cursor: pointer;
position: absolute;
top: 8px;
right: 8px;
transform: translate(50%, -50%) rotate(45deg); /* 关键:定位到右上角并倾斜 */
font-size: 12px;
padding: 10px 18px 5px 18px;
border-radius: 3px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); /* 可选:添加阴影增强立体感 */
}
.corner-tag-default{
background-color: #1890ff; /* 蓝色背景,可自定义 */
color: white;
}
.corner-tag-normal{
background-color: rgba(187, 178, 178, 0.05); /* 蓝色背景,可自定义 */
color: #DCDFE6;
}
</style>

View File

@ -42,6 +42,16 @@
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAddQuick"
v-hasPermi="['cus:main:add']"
>快速新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
@ -143,87 +153,18 @@
/>
<!-- 添加或修改客户信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="客户标签(多个英文逗号隔开)" prop="cusLabels">
<el-select v-model="form.cusLabels" placeholder="请选择客户标签(多个英文逗号隔开)">
<el-option
v-for="dict in dict.type.cus_label"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="客户代码" prop="cusCode">
<el-input v-model="form.cusCode" placeholder="请输入客户代码" />
</el-form-item>
<el-form-item label="客户名称" prop="fullName">
<el-input v-model="form.fullName" placeholder="请输入客户名称" />
</el-form-item>
<el-form-item label="客户简称" prop="shortName">
<el-input v-model="form.shortName" placeholder="请输入客户简称" />
</el-form-item>
<el-form-item label="客户类型" prop="cusType">
<el-select v-model="form.cusType" placeholder="请选择客户类型">
<el-option
v-for="dict in dict.type.cus_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="主营产品(多个英文逗号隔开)" prop="mainProds">
<el-select v-model="form.mainProds" placeholder="请选择主营产品(多个英文逗号隔开)">
<el-option
v-for="dict in dict.type.cus_main_product"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="企业网站" prop="siteUrl">
<el-input v-model="form.siteUrl" placeholder="请输入企业网站" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="附件" prop="files">
<file-upload v-model="form.files"/>
</el-form-item>
<el-form-item label="创建时间" prop="createdTime">
<el-date-picker clearable
v-model="form.createdTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择创建时间">
</el-date-picker>
</el-form-item>
<el-form-item label="更新时间" prop="updatedTime">
<el-date-picker clearable
v-model="form.updatedTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择更新时间">
</el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<draw-form ref="drawForm"></draw-form>
</div>
</template>
<script>
import { listMain, getMain, delMain, addMain, updateMain } from "@/api/cus/main";
import DrawForm from './drawForm'
export default {
name: "Main",
dicts: ['cus_main_product', 'cus_label', 'cus_type'],
components: { DrawForm },
dicts: ['cus_main_product', 'cus_label', 'cus_type','sys_user_sex','cus_from','cus_level','cus_busi_type','cus_follow_step'],
data() {
return {
//
@ -241,7 +182,7 @@ export default {
//
mainList: [],
//
title: "",
title: "快速新建客户",
//
open: false,
//
@ -256,31 +197,69 @@ export default {
country: null,
mainProds: null,
},
//
chooseContactIndexs: [],
//
onlyRequired: {
mainInfo: false,
contact: false,
},
//
form: {},
formData: {
mainInfo: {
cusCode: '',
fullName: '',
cusType: '',
country: '',
shortName: '',
zoneName: '',
mainProds: "",
siteUrl: '',
remark: "",
files: ""
},
contact: [
{
name: '',
ifDefault: true,
nickName: '',
sex: '1',
birthday: '',
contactAddress: '',
email: '',
telephone: '',
telephonePre: '',
whatsApp: '',
whatsAppPre: '',
wechat: '',
qq: '',
}
]
},
//
//
countryList: [],
//
timeZoneList: [],
//
rules: {
cusCode: [
{ required: true, message: "客户代码不能为空", trigger: "blur" }
{ required: true, message: '请输入客户编码', trigger: 'blur' }
],
fullName: [
{ required: true, message: "客户名称不能为空", trigger: "blur" }
],
shortName: [
{ required: true, message: "客户简称不能为空", trigger: "blur" }
{ required: true, message: '请输入客户名称', trigger: 'blur' }
],
cusType: [
{ required: true, message: "客户类型不能为空", trigger: "change" }
],
country: [
{ required: true, message: "国家/地区不能为空", trigger: "change" }
],
zoneName: [
{ required: true, message: "时区不能为空", trigger: "change" }
],
mainProds: [
{ required: true, message: "主营产品(多个英文逗号隔开)不能为空", trigger: "change" }
{ required: true, message: '请选择客户类型', trigger: 'blur' }
],
'contact': [
{
type: 'array',
required: true,
message: '请至少添加一个联系人',
trigger: 'change'
}
]
}
};
},
@ -288,6 +267,7 @@ export default {
this.getList();
},
methods: {
/** 查询客户信息列表 */
getList() {
this.loading = true;
@ -297,34 +277,6 @@ export default {
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
cusLabels: null,
cusCode: null,
fullName: null,
shortName: null,
cusType: null,
country: null,
zoneName: null,
mainProds: null,
siteUrl: null,
remark: null,
files: null,
delFlag: null,
creator: null,
createdTime: null,
updater: null,
updatedTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
@ -345,6 +297,10 @@ export default {
handleAdd() {
this.$router.push({path:'/cus/newForm'})
},
/** 快速新增按钮操作 */
handleAddQuick() {
this.$refs.drawForm.open = true
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
@ -394,3 +350,5 @@ export default {
}
};
</script>

View File

@ -536,7 +536,7 @@ function debounce(fn, delay = 100) {
}, delay)
}
}
import { getCode, addMain } from "@/api/cus/main";
//
import { mapGetters } from 'vuex'