优化 下单页面,新增客户地址管理,新增查询条件构建工具类
This commit is contained in:
parent
018f89c050
commit
75aad6a93d
|
|
@ -367,6 +367,26 @@ public class FuncUtil extends StringUtils {
|
|||
public static List<String> toStrList(String str) {
|
||||
return Arrays.asList(toStrArray(str));
|
||||
}
|
||||
public static List<String> toStrListByArray(Object[] objects) {
|
||||
if(isEmpty(objects)){
|
||||
return null;
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
for (Object o : objects) {
|
||||
list.add(toStr(o,null));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
public static List<String> toStrListByCollection(Collection<Object> objects) {
|
||||
if(isEmpty(objects)){
|
||||
return null;
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
for (Object o : objects) {
|
||||
list.add(toStr(o,null));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<String> toStrList(String split, String str) {
|
||||
return Arrays.asList(toStrArray(split, str));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
package cn.hangtag.framework.common.util;
|
||||
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 安全使用值
|
||||
*
|
||||
* @author YuanFeng
|
||||
* @date 2024/5/16
|
||||
*/
|
||||
public class SafeUseUtil extends BeanUtil {
|
||||
// 缓存结果的 Map
|
||||
private static final Map<Object, Object> cache = new HashMap<>();
|
||||
private static final int CACHE_LIMIT = 1000; // 设置缓存大小限制
|
||||
|
||||
/**
|
||||
* Optional 的简单版
|
||||
* 安全使用值 对象中能取值则使用对象的值,否则返回默认值
|
||||
*
|
||||
* @param obj obj
|
||||
* @param extractor 提取器
|
||||
* @return {@link R }
|
||||
*/
|
||||
public static <T, R> R use(T obj, Function<T, R> extractor) {
|
||||
return use(obj, extractor, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全使用值 对象中能取值则使用对象的值,否则返回默认值
|
||||
*
|
||||
* @param obj obj
|
||||
* @param extractor 提取器
|
||||
* @param defaultValue 默认值
|
||||
* @return {@link R }
|
||||
*/
|
||||
public static <T, R> R use(T obj, Function<T, R> extractor, R defaultValue) {
|
||||
if (obj == null) return defaultValue;
|
||||
// 使用简单键,例如 obj 的哈希值
|
||||
Object key = generateCacheKey(obj, extractor,defaultValue);
|
||||
if (cache.containsKey(key)) {
|
||||
return (R) cache.get(key); // 从缓存中获取结果
|
||||
}
|
||||
R result = defaultValue;
|
||||
try {
|
||||
result = extractor.apply(obj);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
putCacheKey(key, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <R> void putCacheKey(Object key, R result) {
|
||||
if (cache.size() >= CACHE_LIMIT) {
|
||||
// 进行简单的缓存清理
|
||||
cache.clear();
|
||||
}
|
||||
cache.put(key, result); // 缓存结果
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全使用值 对象不为空 能取值并且不为空时 使用对象的中值,
|
||||
*
|
||||
* @param obj obj
|
||||
* @param extractor 提取器
|
||||
* @param defaultValue 默认值
|
||||
* @return {@link R }
|
||||
*/
|
||||
public static <T, R> R useNotEmpty(T obj, Function<T, R> extractor, R defaultValue) {
|
||||
if (isEmpty(obj)) return defaultValue;
|
||||
R result = use(obj, extractor, defaultValue);
|
||||
if (!isEmpty(result)) {
|
||||
return result;
|
||||
}
|
||||
return defaultValue; // 如果结果为空,返回默认值
|
||||
}
|
||||
public static boolean isEmpty(final Object object) {
|
||||
if (object == null) return true;
|
||||
if (object instanceof Collection) {
|
||||
return ((Collection<?>) object).isEmpty();
|
||||
} else if (object instanceof Map) {
|
||||
return ((Map<?,?>) object).isEmpty();
|
||||
} else if (object instanceof CharSequence) {
|
||||
return ((CharSequence) object).length() == 0;
|
||||
} else if (object.getClass().isArray()) {
|
||||
return Array.getLength(object) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 生成缓存键
|
||||
private static Object generateCacheKey(Object obj, Function<?, ?> extractor,Object val) {
|
||||
return Objects.hash(obj, extractor, val);
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// User2 user2 = new User2();
|
||||
//
|
||||
// user2.setName("yuanfeng");
|
||||
// Dept2 dept3 = new Dept2();
|
||||
// dept3.setName("parent");
|
||||
// Dept2 dept2 = new Dept2();
|
||||
// dept2.setParent(dept3);
|
||||
// dept2.setName("dept");
|
||||
// user2.setDept(dept2);
|
||||
// String name = use(use(use(user2, User2::getDept), Dept2::getParent),Dept2::getName);
|
||||
//
|
||||
// System.out.println(name);
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package cn.hangtag.framework.mybatis.build;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class FilterItem implements Serializable {
|
||||
|
||||
/**
|
||||
* 类型 = > >= < <= != in notIn like likeLef likeRight keyword
|
||||
* {@link QueryFilterTypeEnum}
|
||||
*/
|
||||
private String type = QueryFilterTypeEnum.EQ.getValue();
|
||||
|
||||
/**
|
||||
* 条件为 或关系
|
||||
*/
|
||||
private boolean or;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package cn.hangtag.framework.mybatis.build;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 过滤条件配置
|
||||
*
|
||||
* @author YuanFeng
|
||||
*/
|
||||
@Data
|
||||
public class FilterItemConfig implements Serializable {
|
||||
|
||||
// 排序字段 多个使用逗号分隔 name asc,createTime desc
|
||||
private String orderBy = ""; // 排序规则 name,createTime desc 这个默认使用 asc
|
||||
private String groupBy = ""; // 分组 name,createTime desc 这个默认使用 asc
|
||||
private Set<String> ignoreFields = new HashSet<>(); // 忽略字段 多个使用逗号分隔 如: userName,age
|
||||
private String dateFields = ""; //声明哪些是 日期字段 避免搜索错误 多个使用逗号分隔 如: createTime,updateTime
|
||||
private String defaultFilterType = QueryFilterTypeEnum.EQ.getValue();
|
||||
// 关键字搜索值,多个使用空格间隔 查询条件 where (name like %张% or name or like %李%) or (code like %张% or code or like %李%)
|
||||
private String keywordSearch; // 关键字搜索值,多个使用空格间隔 如: 张 李
|
||||
private String keywordFields; // 关键字段多个使用逗号 name,code
|
||||
private String easyOption = ""; // 简单配置 多个使用逗号号间隔; 如 name@like,age@> 条件 where like '%?%' and age > ?
|
||||
private Map<String, FilterItem> options; // 条件过滤配置
|
||||
|
||||
|
||||
|
||||
public Set<String> getIgnoreFieldsKeys() {
|
||||
if(ignoreFields == null){
|
||||
ignoreFields = new HashSet<>();
|
||||
}
|
||||
return ignoreFields;
|
||||
}
|
||||
public void setIgnoreFields(String config) {
|
||||
if(QueryConfigUtils.isNotEmpty(config)){
|
||||
List<String> strList = QueryConfigUtils.toStrList(config);
|
||||
getIgnoreFieldsKeys().addAll(strList);
|
||||
}
|
||||
}
|
||||
public String getIgnoreFields(){
|
||||
if(getIgnoreFieldsKeys().isEmpty()){
|
||||
return "";
|
||||
}
|
||||
return String.join(QueryConfigUtils.SPLIT_CHAR, getIgnoreFieldsKeys());
|
||||
}
|
||||
|
||||
public Map<String, FilterItem> getOptions() {
|
||||
if(options == null){
|
||||
options = new HashMap<>();
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
// @条件(QueryFilterTypeEnum) 多个使用逗号号间隔; 如 name@like,age@> 条件 where like '%?%' and age > ?
|
||||
public void setEasyOption(String options){
|
||||
if (QueryConfigUtils.isNotEmpty(options)) {
|
||||
String[] split = options.split(QueryConfigUtils.SPLIT_CHAR);
|
||||
for (String s : split) {
|
||||
if(QueryConfigUtils.isNotEmpty(s.trim())){
|
||||
String[] split1 = s.trim().split(QueryConfigUtils.SPLIT_CONDITIONS);
|
||||
FilterItem item = new FilterItem();
|
||||
// 简单模式设置条件为都为 and 模式
|
||||
item.setOr(false);
|
||||
item.setType(getDefaultFilterType());
|
||||
if(split1.length == 2){
|
||||
// 获取条件类型
|
||||
QueryFilterTypeEnum byValue = QueryFilterTypeEnum.getByValue(split1[1]);
|
||||
if(byValue != null){
|
||||
item.setType(byValue.getValue());
|
||||
}
|
||||
}
|
||||
if(QueryConfigUtils.isEmpty(getOptions().get(split1[0].trim()))){
|
||||
//没有配置时候才将 简单条件添加到配置中
|
||||
getOptions().put(split1[0].trim(), item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
package cn.hangtag.framework.mybatis.build;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 高性能有序Map
|
||||
*
|
||||
* @author YuanFeng
|
||||
* @date 2020/9/14
|
||||
*/
|
||||
public class HighPerformanceOrderedMap<K, V> extends AbstractMap<K, V> {
|
||||
private final Map<K, V> map; // 存储数据的 HashMap
|
||||
private final List<K> order; // 维护插入顺序的 List
|
||||
|
||||
// 构造函数
|
||||
public HighPerformanceOrderedMap() {
|
||||
this.map = new HashMap<>();
|
||||
this.order = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
Set<Entry<K, V>> entrySet = new LinkedHashSet<>();
|
||||
for (K key : order) {
|
||||
entrySet.add(new SimpleEntry<>(key, map.get(key)));
|
||||
}
|
||||
return entrySet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除第一
|
||||
*
|
||||
* @return {@link K }
|
||||
*/
|
||||
public K removeFirst(){
|
||||
if(!isEmpty()){
|
||||
K k = this.order.get(0);
|
||||
remove(k);
|
||||
return k;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public List<K> keyList(){
|
||||
return order;
|
||||
}
|
||||
@Override
|
||||
public Set<K> keySet(){
|
||||
return new LinkedHashSet<>(order);
|
||||
}
|
||||
@Override
|
||||
public List<V> values(){
|
||||
return new ArrayList<>(map.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(K key, V value) {
|
||||
if (!map.containsKey(key)) {
|
||||
order.add(key); // 只在新插入时添加顺序
|
||||
}
|
||||
return map.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(Object key) {
|
||||
if (map.containsKey(key)) {
|
||||
order.remove(key); // 移除顺序中的键
|
||||
}
|
||||
return map.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return map.containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
map.clear();
|
||||
order.clear();
|
||||
}
|
||||
|
||||
// 打印所有键值对
|
||||
public void printEntries() {
|
||||
for (K key : order) {
|
||||
System.out.println(key + ": " + map.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,446 @@
|
|||
package cn.hangtag.framework.mybatis.build;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* mybatisPlus 查询条件构建工具
|
||||
*
|
||||
* @author YuanFeng
|
||||
* @date 2023/5/14
|
||||
*/
|
||||
public class MybatisPlusUtil {
|
||||
|
||||
public static String[] defaultIgnoreFilters = {"pageNo", "pageSize", "PAGE_NO", "PAGE_SIZE", "PAGE_SIZE_NONE"};
|
||||
/**
|
||||
* 弱类型 生成非空值查询 指定转成的实体类型
|
||||
*
|
||||
* @param entity 实体
|
||||
* @param clazz clazz 返回QueryWrapper泛型的类型
|
||||
* @param ignoreField ignore字段
|
||||
* @return {@link QueryWrapper }<{@link T }>
|
||||
*/
|
||||
public static <T> QueryWrapper<T> buildQueryFor(Object entity,
|
||||
Class<T> clazz,
|
||||
String... ignoreField) {
|
||||
return buildQueryFor(null, entity, QueryFilterTypeEnum.EQ, clazz, ignoreField);
|
||||
}
|
||||
|
||||
/**
|
||||
* 弱类型 生成非空值查询 指定转成的实体类型
|
||||
*
|
||||
* @param conditions 条件 @条件(QueryFilterTypeEnum) 多个使用逗号号间隔; 如 name@like,age@> 条件 where like '%?%' and age > ?
|
||||
* @param entity 实体
|
||||
* @param typeEnum 类型列举 没有指定过滤类型时候的默认条件类型
|
||||
* @param clazz clazz 返回QueryWrapper泛型的类型
|
||||
* @param ignoreField ignore字段
|
||||
* @return {@link QueryWrapper }<{@link T }>
|
||||
*/
|
||||
public static <T> QueryWrapper<T> buildQueryFor(String conditions,
|
||||
Object entity,
|
||||
QueryFilterTypeEnum typeEnum,
|
||||
Class<T> clazz,
|
||||
String... ignoreField) {
|
||||
QueryFilterInfo queryFilterInfo = toFilter(conditions, entity, typeEnum, ignoreField);
|
||||
return parseQuery(queryFilterInfo, true, ignoreField);
|
||||
}
|
||||
|
||||
/**
|
||||
* 弱类型 实体转成查询条件
|
||||
* 实体可能是vo 但是查询 为 Db实体的时候使用
|
||||
*
|
||||
* @param conditions 条件 @条件(QueryFilterTypeEnum) 多个使用逗号号间隔; 如 name@like,age@> 条件 where like '%?%' and age > ?
|
||||
* @param entity 实体
|
||||
* @param clazz clazz 返回QueryWrapper泛型的类型
|
||||
* @param ignoreField ignore字段
|
||||
* @return {@link QueryWrapper }<{@link T }>
|
||||
*/
|
||||
public static <T> QueryWrapper<T> buildQueryFor(String conditions,
|
||||
Object entity,
|
||||
Class<T> clazz,
|
||||
String... ignoreField) {
|
||||
return buildQueryFor(conditions, entity, QueryFilterTypeEnum.EQ, clazz, ignoreField);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 弱类型 实体转成查询条件
|
||||
* 实体可能是vo 但是查询 为 Db 实体的时候使用
|
||||
*
|
||||
* @param entity 实体
|
||||
* @param typeEnum 类型列举 没有指定过滤类型时候的默认条件类型
|
||||
* @param clazz clazz 返回QueryWrapper泛型的类型
|
||||
* @param ignoreField ignore字段
|
||||
* @return {@link QueryWrapper }<{@link T }>
|
||||
*/
|
||||
public static <T> QueryWrapper<T> buildQueryFor(Object entity,
|
||||
QueryFilterTypeEnum typeEnum,
|
||||
Class<T> clazz,
|
||||
String... ignoreField) {
|
||||
return buildQueryFor(null, entity, typeEnum, clazz, ignoreField);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实体转成查询条件
|
||||
*
|
||||
* @param entity 实体
|
||||
* @param ignoreField ignore字段
|
||||
* @return {@link QueryWrapper }<{@link T }>
|
||||
*/
|
||||
public static <T> QueryWrapper<T> buildQuery(T entity, String... ignoreField) {
|
||||
return buildQuery(null, entity, QueryFilterTypeEnum.EQ, ignoreField);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实体转成查询条件
|
||||
*
|
||||
* @param conditions 条件
|
||||
* @param entity 实体
|
||||
* @param ignoreField ignore字段
|
||||
* @return {@link QueryWrapper }<{@link T }>
|
||||
*/
|
||||
public static <T> QueryWrapper<T> buildQuery(String conditions, T entity, String... ignoreField) {
|
||||
return buildQuery(conditions, entity, QueryFilterTypeEnum.EQ, ignoreField);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成非空值查询
|
||||
*
|
||||
* @param entity 实体
|
||||
* @param typeEnum 类型列举 没有指定过滤类型时候的默认条件类型
|
||||
* @param ignoreField ignore字段
|
||||
* @return {@link QueryWrapper }<{@link T }>
|
||||
*/
|
||||
public static <T> QueryWrapper<T> buildQuery(T entity, QueryFilterTypeEnum typeEnum, String... ignoreField) {
|
||||
return buildQuery(null, entity, typeEnum, ignoreField);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成非空值查询 根据泛型返回类型
|
||||
*
|
||||
* @param conditions 简单条件 @条件(QueryFilterTypeEnum) 多个使用逗号号间隔; 如 name@like,age@> 条件 where like '%?%' and age > ?
|
||||
* @param entity 实体
|
||||
* @param typeEnum 类型列举 没有指定过滤类型时候的默认条件类型
|
||||
* @param ignoreField ignore字段
|
||||
* @return {@link QueryWrapper }<{@link T }>
|
||||
*/
|
||||
public static <T> QueryWrapper<T> buildQuery(String conditions, T entity, QueryFilterTypeEnum typeEnum, String... ignoreField) {
|
||||
QueryFilterInfo<T> queryFilterInfo = toFilter(conditions, entity, typeEnum, ignoreField);
|
||||
QueryWrapper<T> queryWrapper = parseQuery(queryFilterInfo, true, ignoreField);
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
|
||||
public static <E> QueryFilterInfo<E> toFilter(E entity, QueryFilterTypeEnum typeEnum, String... ignoreField) {
|
||||
return toFilter(null, entity, typeEnum, ignoreField);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实体转成 过滤信息对象
|
||||
*
|
||||
* @param conditions 条件 name@like,age@>,code@= 简单配置 字段名称@条件
|
||||
* @param entity 实体
|
||||
* @param typeEnum 类型列举 没有指定过滤类型时候的默认条件类型
|
||||
* @param ignoreField ignore字段
|
||||
* @return {@link QueryFilterInfo }<{@link E }>
|
||||
*/
|
||||
public static <E> QueryFilterInfo<E> toFilter(String conditions, E entity, QueryFilterTypeEnum typeEnum, String... ignoreField) {
|
||||
Set<String> ignoreList = new HashSet<>();
|
||||
if (QueryConfigUtils.isNotEmpty(ignoreField)) {
|
||||
for (String ignoreColumn : ignoreField) {
|
||||
// 忽略字段 类中的字段转成下划线命名
|
||||
ignoreList.add(QueryConfigUtils.humpToLine(ignoreColumn));
|
||||
}
|
||||
}
|
||||
QueryFilterInfo<E> queryFilterInfo = new QueryFilterInfo<E>();
|
||||
queryFilterInfo.easyOptions(conditions);
|
||||
queryFilterInfo.setDefaultFilterType(typeEnum);
|
||||
queryFilterInfo.appendIgnoreFields(ignoreList);
|
||||
handlerEntityField(entity, queryFilterInfo, QueryConfigUtils.getDeclaredFields(entity.getClass()));
|
||||
// 处理父类
|
||||
Class<?> superclass = entity.getClass().getSuperclass();
|
||||
while (superclass != null) {
|
||||
handlerEntityField(entity, queryFilterInfo, QueryConfigUtils.getDeclaredFields(superclass));
|
||||
superclass = superclass.getSuperclass();
|
||||
}
|
||||
return queryFilterInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理实体字段 将 字段转成 查询条件
|
||||
*
|
||||
* @param entity 实体
|
||||
* @param queryFilterInfo 查询过滤器信息
|
||||
* @param declaredFields 声明字段
|
||||
*/
|
||||
private static <T> void handlerEntityField(T entity, QueryFilterInfo<T> queryFilterInfo, Field[] declaredFields) {
|
||||
|
||||
// 字段过滤条件类型
|
||||
Map<String, QueryFilterTypeEnum> filterMap = new HashMap<>();
|
||||
// 取出过滤条件类型
|
||||
Map<String, FilterItem> options = queryFilterInfo.getOptions();
|
||||
// 或者关系条件的字段集合
|
||||
Set<String> orKeys = new HashSet<>();
|
||||
if (QueryConfigUtils.isNotEmpty(options)) {
|
||||
Set<String> keySet = options.keySet();
|
||||
for (String s : keySet) {
|
||||
FilterItem item = options.get(s);
|
||||
|
||||
String type = item.getType();
|
||||
QueryFilterTypeEnum queryFilterTypeEnum = QueryFilterTypeEnum.getByValue(type);
|
||||
// 类中的字段转成下划线命名
|
||||
String field = QueryConfigUtils.humpToLine(s);
|
||||
if (queryFilterTypeEnum != null) {
|
||||
filterMap.put(field, queryFilterTypeEnum);
|
||||
} else {
|
||||
filterMap.put(field, QueryFilterTypeEnum.getByValue(queryFilterInfo.getDefaultFilterType()));
|
||||
}
|
||||
if (item.isOr()) {
|
||||
orKeys.add(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<String> ignoreList = queryFilterInfo.getIgnoreFieldsKeys();
|
||||
for (Field field : declaredFields) {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
//序列化 字段 属性为空不查询
|
||||
if (QueryConfigUtils.shouldSkipField(field, ignoreList)) {
|
||||
queryFilterInfo.appendIgnoreFields(ignoreList);
|
||||
continue;
|
||||
}
|
||||
String column = QueryConfigUtils.humpToLine(field.getName());
|
||||
//主键 注解TableId
|
||||
TableId tableId = field.getAnnotation(TableId.class);
|
||||
if (tableId != null && field.get(entity) != null) {
|
||||
//主键
|
||||
if (QueryConfigUtils.isNotEmpty(tableId.value())) {
|
||||
column = tableId.value();
|
||||
}
|
||||
} else {
|
||||
//数据库中字段名和实体类属性不一致 注解TableField
|
||||
TableField tableField = field.getAnnotation(TableField.class);
|
||||
if (tableField != null && !tableField.exist()) {
|
||||
// @TableField(exist = false) 不是表中内容 不形成查询条件
|
||||
if (QueryConfigUtils.isNotEmpty(tableField.value())) {
|
||||
column = tableField.value();
|
||||
}
|
||||
ignoreList.add(column);
|
||||
queryFilterInfo.appendIgnoreFields(ignoreList);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// 属性不为null 或 值在过滤条件中
|
||||
if (field.get(entity) != null) {
|
||||
Object inputVal = field.get(entity);
|
||||
Class<?> type = field.getType();
|
||||
Object val;
|
||||
|
||||
// 是否有指定的过滤条件
|
||||
QueryFilterTypeEnum filterTypeEnum = filterMap.get(column);
|
||||
if (filterTypeEnum == null) {
|
||||
filterTypeEnum = QueryFilterTypeEnum.getByValue(queryFilterInfo.getDefaultFilterType());
|
||||
}
|
||||
|
||||
if (QueryConfigUtils.isArr(inputVal)) {
|
||||
val = QueryConfigUtils.objToArray(inputVal, Object.class);
|
||||
} else if (QueryConfigUtils.isList(inputVal)) {
|
||||
val = QueryConfigUtils.objToArray(inputVal, Object.class);
|
||||
} else {
|
||||
val = TypeConverter.convertValue(inputVal, type);
|
||||
if (val == null) {
|
||||
// 没有转换成功
|
||||
val = inputVal.toString();
|
||||
}
|
||||
}
|
||||
queryFilterInfo.build(column, val, filterTypeEnum, orKeys.contains(column));
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解析为查询条件
|
||||
*
|
||||
* @param queryFilterInfo 查询过滤器信息
|
||||
* @param isToLine 是否转成 下划线命名
|
||||
* @param clazz clazz 返回QueryWrapper泛型的类型
|
||||
* @param ignoreField 忽略字段
|
||||
* @return {@link QueryWrapper }<{@link T }>
|
||||
*/
|
||||
public static <T> QueryWrapper<T> parseQuery(QueryFilterInfo queryFilterInfo, boolean isToLine, Class<T> clazz, String... ignoreField) {
|
||||
QueryWrapper<T> queryWrapper = parseQuery(queryFilterInfo, isToLine, ignoreField);
|
||||
return queryWrapper;
|
||||
}
|
||||
/**
|
||||
* 解析为查询条件
|
||||
*
|
||||
* @param filterInfo 查询过滤器信息
|
||||
* @param isToLine 是否转成 下划线命名
|
||||
* @param ignoreField 忽略字段
|
||||
* @return {@link QueryWrapper }<{@link T }>
|
||||
*/
|
||||
public static <T> QueryWrapper<T> parseQuery(QueryFilterInfo<T> filterInfo, boolean isToLine, String... ignoreField) {
|
||||
|
||||
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
|
||||
|
||||
queryWrapper.and((q) -> {
|
||||
q.eq("1", 1);
|
||||
});
|
||||
String keywordFields = filterInfo.getConfig().getKeywordFields();
|
||||
String keywordSearch = filterInfo.getConfig().getKeywordSearch();
|
||||
if (QueryConfigUtils.isEmpty(filterInfo)) {
|
||||
return queryWrapper;
|
||||
}
|
||||
Map<String, Object> filter = filterInfo.getFilter();
|
||||
Map<String, FilterItem> options = filterInfo.getOptions();
|
||||
String str = filterInfo.getConfig().getOrderBy();
|
||||
Set<String> ignoreFieldsKeys = filterInfo.getIgnoreFieldsKeys();
|
||||
if(QueryConfigUtils.isNotEmpty(ignoreField)){
|
||||
ignoreFieldsKeys.addAll(Arrays.asList(ignoreField));
|
||||
}
|
||||
Set<String> ignoreKeys = new HashSet<>();
|
||||
|
||||
for (String ignoreFieldsKey : ignoreFieldsKeys) {
|
||||
ignoreKeys.add(isToLine ? QueryConfigUtils.humpToLine(ignoreFieldsKey) : ignoreFieldsKey);
|
||||
}
|
||||
if (QueryConfigUtils.isNotEmpty(str)) {
|
||||
String[] split = str.split(QueryConfigUtils.SPLIT_CHAR);
|
||||
for (String s1 : split) {
|
||||
String[] s2 = s1.split(" ");
|
||||
String orderField = s2[0];
|
||||
if (isToLine) {
|
||||
orderField = QueryConfigUtils.humpToLine(orderField);
|
||||
}
|
||||
|
||||
// 说明字段不存在 或者不参与排序
|
||||
if (ignoreKeys.contains(orderField)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("desc".equalsIgnoreCase(QueryConfigUtils.toStr(s2[1],""))) {
|
||||
queryWrapper.orderByDesc(orderField);
|
||||
} else {
|
||||
queryWrapper.orderByAsc(orderField);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理关键字查询
|
||||
if (QueryConfigUtils.isNotEmpty(keywordSearch) && QueryConfigUtils.isNotEmpty(keywordFields)) {
|
||||
String finalKeywordSearch = keywordSearch.trim();
|
||||
if (QueryConfigUtils.isNotEmpty(finalKeywordSearch)) {
|
||||
String[] split = keywordFields.split(QueryConfigUtils.SPLIT_CHAR);
|
||||
queryWrapper.and((c) -> {
|
||||
for (String s : split) {
|
||||
s = isToLine ? QueryConfigUtils.humpToLine(s) : s;
|
||||
// 说明字段不存在 或者不参与搜索
|
||||
if (ignoreKeys.contains(s)) {
|
||||
continue;
|
||||
}
|
||||
// name like '%张%' or name like '%李%' or name like '%王%'
|
||||
// 多个关键字空格间隔
|
||||
String[] keyList = finalKeywordSearch.split(" ");
|
||||
for (String key : keyList) {
|
||||
c.or();
|
||||
// 关键字过滤 key
|
||||
c.like(s, key.trim());
|
||||
}
|
||||
c.or();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 条件查询
|
||||
if (QueryConfigUtils.isNotEmpty(filter)) {
|
||||
Set<String> keySet = options.keySet();
|
||||
Map<String, FilterItem> filterMap = new HashMap<>();
|
||||
for (String s : keySet) {
|
||||
// 处理驼峰字段
|
||||
filterMap.put(isToLine ? QueryConfigUtils.humpToLine(s) : s, options.get(s));
|
||||
}
|
||||
// 日期字段
|
||||
Set<String> dateSet = new HashSet<>();
|
||||
String dateFields = filterInfo.getConfig().getDateFields();
|
||||
if (QueryConfigUtils.isNotEmpty(dateFields)) {
|
||||
String[] split = dateFields.split(QueryConfigUtils.SPLIT_CHAR);
|
||||
for (String s : split) {
|
||||
if (QueryConfigUtils.isNotEmpty(s.trim())) {
|
||||
dateSet.add(isToLine ? QueryConfigUtils.humpToLine(s.trim()) : s.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
// 遍历过滤条件
|
||||
Set<String> fieldKey = filter.keySet();
|
||||
for (String objKey : fieldKey) {
|
||||
// 取出过滤的值
|
||||
Object value = filter.get(objKey);
|
||||
|
||||
if (QueryConfigUtils.skipData(value)) {
|
||||
// 跳过数据
|
||||
continue;
|
||||
}
|
||||
String field = isToLine ? QueryConfigUtils.humpToLine(objKey) : objKey;
|
||||
// 说明字段不存在 或者不参与条件查询
|
||||
if (ignoreKeys.contains(field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FilterItem item = filterMap.get(field);
|
||||
if (item == null) {
|
||||
//找不到指定的过滤类型 默认过滤类型
|
||||
item = new FilterItem();
|
||||
// 默认过滤类型
|
||||
item.setType(filterInfo.getDefaultFilterType());
|
||||
// 判断是否是数组
|
||||
if (QueryConfigUtils.isArr(value) || QueryConfigUtils.isList(value)) {
|
||||
item.setType(QueryFilterTypeEnum.BETWEEN.getValue());
|
||||
}
|
||||
item.setOr(false);
|
||||
}
|
||||
|
||||
// 判断是否是or
|
||||
if (item.isOr()) {
|
||||
queryWrapper.or();
|
||||
}
|
||||
QueryFilterTypeEnum byValue = QueryFilterTypeEnum.getByValue(item.getType());
|
||||
if(byValue == null){
|
||||
byValue = QueryFilterTypeEnum.EQ;
|
||||
}
|
||||
// 条件处理器
|
||||
queryWrapper = QueryConfigUtils.whereHandler(queryWrapper, byValue, dateSet, field, value);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 分组
|
||||
List<String> strList = QueryConfigUtils.toStrList(filterInfo.getConfig().getGroupBy());
|
||||
if (QueryConfigUtils.isNotEmpty(strList)) {
|
||||
List<String> strSet = new ArrayList<>();
|
||||
for (String s : strList) {
|
||||
String s1 = isToLine ? QueryConfigUtils.humpToLine(s) : s;
|
||||
if (ignoreKeys.contains(s1)) {
|
||||
continue;
|
||||
}
|
||||
strSet.add(s1);
|
||||
}
|
||||
if (QueryConfigUtils.isNotEmpty(strSet)) {
|
||||
queryWrapper.groupBy(strSet);
|
||||
}
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,474 @@
|
|||
package cn.hangtag.framework.mybatis.build;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.enums.DbTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.handler.*;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class QueryConfigUtils {
|
||||
|
||||
private static final Map<String, Function<Object, Boolean>> SKIP_HANDLER = new HashMap<>();
|
||||
|
||||
public static int MAX_LINE_CACHE = 100000;
|
||||
/**
|
||||
* 分隔符
|
||||
*/
|
||||
public static final String SPLIT_CHAR = ",";
|
||||
/**
|
||||
* 分裂条件
|
||||
*/
|
||||
public static final String SPLIT_CONDITIONS = "@";
|
||||
private static final Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");
|
||||
private static DbTypeEnum currentType = DbTypeEnum.MYSQL;
|
||||
|
||||
public static DbTypeEnum getDbType() {
|
||||
return currentType;
|
||||
}
|
||||
|
||||
public static void setDbType(String dbType) {
|
||||
currentType = DbTypeEnum.getDbType(dbType);
|
||||
}
|
||||
|
||||
|
||||
private static final ThreadLocal<String> LOCAL_HANDLER = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 注册一个跳过数据处理方法,名称为key
|
||||
*
|
||||
* @param name 名称
|
||||
* @param handler 处理程序
|
||||
*/
|
||||
public static void registerSkipHandler(String name, Function<Object, Boolean> handler) {
|
||||
SKIP_HANDLER.put(name, handler);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static {
|
||||
// 默认
|
||||
registerSkipHandler("null", (obj) -> {
|
||||
return obj == null || obj.equals("null");
|
||||
});
|
||||
|
||||
resetWrapperHandler();
|
||||
}
|
||||
|
||||
public static void resetWrapperHandler(){
|
||||
|
||||
registerWrapperHandler(new Between2Handler<>());
|
||||
registerWrapperHandler(new BetweenHandler<>());
|
||||
registerWrapperHandler(new EqHandler<>());
|
||||
registerWrapperHandler(new GeHandler<>());
|
||||
registerWrapperHandler(new InHandler<>());
|
||||
registerWrapperHandler(new InSetHandler<>());
|
||||
registerWrapperHandler(new KeywordHandler<>());
|
||||
registerWrapperHandler(new LeHandler<>());
|
||||
registerWrapperHandler(new LikeHandler<>());
|
||||
registerWrapperHandler(new LikeLeftHandler<>());
|
||||
registerWrapperHandler(new LikeRightHandler<>());
|
||||
registerWrapperHandler(new LtHandler<>());
|
||||
registerWrapperHandler(new NeHandler<>());
|
||||
registerWrapperHandler(new NotInHandler<>());
|
||||
registerWrapperHandler(new NotLikeHandler<>());
|
||||
|
||||
}
|
||||
|
||||
public static void registerWrapperHandler(WhereWrapper<?> whereWrapper) {
|
||||
WrapperHandler.registerWrapperHandler(whereWrapper);
|
||||
}
|
||||
/**
|
||||
* 使用跳过逻辑处理方法名称
|
||||
*
|
||||
* @param name 名称
|
||||
*/
|
||||
public static void useSkipHandler(String name) {
|
||||
// 线程绑定
|
||||
LOCAL_HANDLER.set(name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static Function<Object, Boolean> getSkipHandler(String name) {
|
||||
Function<Object, Boolean> function = null;
|
||||
if (name != null) {
|
||||
function = SKIP_HANDLER.get(name);
|
||||
}
|
||||
if (function == null) {
|
||||
// 使用默认
|
||||
return QueryConfigUtils::isEmpty;
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 sql 如 字段为 id1,id2,id3 , 条件如 为 id1
|
||||
* 使用 方法 queryWrapper.apply(MybatisPlusUtil.getIdsToApply(“user_ids"),id)
|
||||
*
|
||||
* @param columnName 列名
|
||||
* @return {@link String }
|
||||
*/
|
||||
public static String getIdsToApply(String columnName) {
|
||||
return getIdsToApply(getDbType(), columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取身份证申请
|
||||
*
|
||||
* @param dbType db类型
|
||||
* @param columnName 列名
|
||||
* @return {@link String }
|
||||
*/
|
||||
public static String getIdsToApply(DbTypeEnum dbType, String columnName) {
|
||||
switch (dbType) {
|
||||
case MYSQL:
|
||||
return "FIND_IN_SET ({0}, " + columnName + ")";
|
||||
case POSTGRE_SQL:
|
||||
return "'{0}' = ANY (string_to_array(" + columnName + ", ','))";
|
||||
default:
|
||||
return "FIND_IN_SET ({0}, " + columnName + ")";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成下线缓存
|
||||
*/
|
||||
private static final HighPerformanceOrderedMap<String, String> TO_LINE_CACHE = new HighPerformanceOrderedMap<>();
|
||||
|
||||
/**
|
||||
* 驼峰转下划线
|
||||
*
|
||||
* @param str str
|
||||
* @return {@link String}
|
||||
*/
|
||||
public static String humpToLine(String str) {
|
||||
if (isNotEmpty(str)) {
|
||||
String s = TO_LINE_CACHE.get(str);
|
||||
if (isNotEmpty(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
str = str.substring(0, 1).toLowerCase() + str.substring(1);
|
||||
Matcher matcher = HUMP_PATTERN.matcher(str);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
String string = sb.toString();
|
||||
TO_LINE_CACHE.put(str, string);
|
||||
if (TO_LINE_CACHE.size() > MAX_LINE_CACHE) {
|
||||
TO_LINE_CACHE.removeFirst();
|
||||
}
|
||||
return string;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转为骆驼
|
||||
*
|
||||
* @param s S
|
||||
* @return {@link String }
|
||||
*/
|
||||
public static String toCamelCase(String s) {
|
||||
if (isEmpty(s) || !s.contains("_")) {
|
||||
return s;
|
||||
}
|
||||
s = s.toLowerCase();
|
||||
StringBuilder sb = new StringBuilder(s.length());
|
||||
boolean upperCase = false;
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
|
||||
if (c == '_') {
|
||||
upperCase = true;
|
||||
} else if (upperCase) {
|
||||
sb.append(Character.toUpperCase(c));
|
||||
upperCase = false;
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean shouldSkipField(Field field, Set<String> ignoreList) {
|
||||
|
||||
if ("serialVersionUID".equals(field.getName())) return true;
|
||||
if (ignoreList.contains(humpToLine(field.getName()))) return true;
|
||||
|
||||
// 过滤字段 只写字段
|
||||
if (field.getAnnotation(JsonProperty.class) != null
|
||||
&& field.getAnnotation(JsonProperty.class).access() == JsonProperty.Access.WRITE_ONLY) {
|
||||
ignoreList.add(humpToLine(field.getName()));
|
||||
return true;
|
||||
}
|
||||
// 在序列化和反序列化时忽略的属性
|
||||
if (field.getAnnotation(JsonIgnore.class) != null) {
|
||||
ignoreList.add(humpToLine(field.getName()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final Map<Class<?>, Field[]> fieldCache = new HashMap<>();
|
||||
|
||||
public static Field[] getDeclaredFields(Class<?> clazz) {
|
||||
return fieldCache.computeIfAbsent(clazz, Class::getDeclaredFields);
|
||||
}
|
||||
|
||||
// 去除空白
|
||||
public static List<String> toStrList(String str) {
|
||||
if (isEmpty(str)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
String[] split = str.split(QueryConfigUtils.SPLIT_CHAR);
|
||||
return Arrays.stream(split).filter(s -> !isEmpty(s)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static String[] toStrArr(String str) {
|
||||
List<String> strList = toStrList(str);
|
||||
if (isEmpty(strList)) {
|
||||
return null;
|
||||
}
|
||||
return strList.toArray(new String[strList.size()]);
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(final Object object) {
|
||||
return !isEmpty(object);
|
||||
}
|
||||
|
||||
public static boolean isEmpty(final Object object) {
|
||||
if (object == null) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof CharSequence) {
|
||||
return ((CharSequence) object).length() == 0;
|
||||
}
|
||||
if (object.getClass().isArray()) {
|
||||
return Array.getLength(object) == 0;
|
||||
}
|
||||
if (object instanceof Collection<?>) {
|
||||
return ((Collection<?>) object).isEmpty();
|
||||
}
|
||||
if (object instanceof Map<?, ?>) {
|
||||
return ((Map<?, ?>) object).isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否支持日期搜索的类型 的关键字
|
||||
*
|
||||
* @param input 输入
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isDateValue(String input) {
|
||||
try {
|
||||
LocalDate.parse(input, DateTimeFormatter.ISO_LOCAL_DATE);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
Long.valueOf(input);
|
||||
return true;
|
||||
} catch (Exception e2) {
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String toStr(Object str) {
|
||||
return toStr(str, "");
|
||||
}
|
||||
|
||||
public static String toStr(Object str, String defaultValue) {
|
||||
return null != str ? str.toString() : defaultValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对象到数组
|
||||
*
|
||||
* @param obj obj
|
||||
* @param clazz clazz
|
||||
* @return {@link T[] }
|
||||
*/
|
||||
public static <T> T[] objToArray(Object obj, Class<T> clazz) {
|
||||
if (obj == null) {
|
||||
return (T[]) Array.newInstance(clazz, 0); // 返回空数组
|
||||
}
|
||||
|
||||
if (obj.getClass().isArray()) {
|
||||
return (T[]) obj; // 已经是数组,直接转换
|
||||
}
|
||||
|
||||
if (obj instanceof List<?>) {
|
||||
List<?> list = (List<?>) obj;
|
||||
// 使用传入的类型创建数组
|
||||
return list.toArray((T[]) Array.newInstance(clazz, list.size()));
|
||||
}
|
||||
|
||||
// 单个对象,转换为包含该对象的数组
|
||||
T[] array = (T[]) Array.newInstance(clazz, 1);
|
||||
array[0] = (T) obj;
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期格式
|
||||
*
|
||||
* @param localDateTime 当地日期时间
|
||||
* @return {@link String }
|
||||
*/
|
||||
public static String dateFormat(LocalDateTime localDateTime) {
|
||||
return DateUtil.format(localDateTime, "yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
/**
|
||||
* // 将对象转换为 List,支持泛型
|
||||
*
|
||||
* @param obj obj
|
||||
* @param clazz clazz
|
||||
* @return {@link List }<{@link T }>
|
||||
*/
|
||||
public static <T> List<T> objToList(Object obj, Class<T> clazz) {
|
||||
if (obj == null) {
|
||||
return new ArrayList<>(); // 返回空 List
|
||||
}
|
||||
|
||||
if (obj.getClass().isArray()) {
|
||||
// 数组转换为 List
|
||||
int length = Array.getLength(obj);
|
||||
List<T> list = new ArrayList<>(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
list.add((T) Array.get(obj, i));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
if (obj instanceof List<?>) {
|
||||
return new ArrayList<>((List<T>) obj); // 已经是 List,直接转换
|
||||
}
|
||||
|
||||
// 单个对象,转换为包含该对象的 List
|
||||
return new ArrayList<>(Collections.singletonList((T) obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象是否为数组类型
|
||||
*
|
||||
* @param obj obj
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isArr(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
// 检查是否为数组
|
||||
if (obj.getClass().isArray()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为List 类型的数据
|
||||
*
|
||||
* @param obj obj
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isList(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
// 检查是否为 List
|
||||
if (obj instanceof List) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串添加
|
||||
*
|
||||
* @param str str
|
||||
* @param field 领域
|
||||
* @return {@link String }
|
||||
*/
|
||||
public static String strAdd(String str, String... field) {
|
||||
if (QueryConfigUtils.isNotEmpty(field)) {
|
||||
for (String s : field) {
|
||||
if (QueryConfigUtils.isNotEmpty(s.trim())) {
|
||||
str += (s.trim() + QueryConfigUtils.SPLIT_CHAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串删除
|
||||
*
|
||||
* @param str str
|
||||
* @param keys 键
|
||||
* @return {@link String }
|
||||
*/
|
||||
public static String strRemove(String str, String... keys) {
|
||||
if (QueryConfigUtils.isNotEmpty(keys)) {
|
||||
String[] split = str.split(QueryConfigUtils.SPLIT_CHAR);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
List<String> strList = QueryConfigUtils.toStrList(String.join(QueryConfigUtils.SPLIT_CHAR, keys));
|
||||
for (int i = 0; i < split.length; i++) {
|
||||
if (strList.contains(split[i])) {
|
||||
continue;
|
||||
}
|
||||
builder.append(split[i]).append(QueryConfigUtils.SPLIT_CHAR);
|
||||
}
|
||||
str = builder.toString();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳过数据
|
||||
*
|
||||
* @param str str
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean skipData(Object str) {
|
||||
return getSkipHandler(LOCAL_HANDLER.get()).apply(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* where 条件处理
|
||||
*
|
||||
* @param value str
|
||||
* @return boolean
|
||||
*/
|
||||
public static <T> QueryWrapper<T> whereHandler(QueryWrapper<T> queryWrapper,
|
||||
QueryFilterTypeEnum type,
|
||||
Set<String> dateField,
|
||||
String filed,
|
||||
Object value) {
|
||||
return WrapperHandler.exeWrapperHandler(queryWrapper, type,dateField, filed, value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
package cn.hangtag.framework.mybatis.build;
|
||||
|
||||
|
||||
import cn.hangtag.framework.common.pojo.PageParam;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
/*
|
||||
|
||||
前端条件 条件
|
||||
where
|
||||
(userName like '%周%' or nickname like '%周%')
|
||||
and (age > 18)
|
||||
and (userName in ('陈海瑶', '冯雨馨')
|
||||
or nickname like '%杰%')
|
||||
{
|
||||
"pager": {
|
||||
"current": 1,
|
||||
"size": 10
|
||||
},
|
||||
"config": {
|
||||
"keywordSearch": "周",
|
||||
"keywordFields": "userName,nickname",
|
||||
"orderBy": "age desc;name asc",
|
||||
"options": {
|
||||
"age": {
|
||||
"type": ">",
|
||||
"or": false
|
||||
},
|
||||
"userName": {
|
||||
"type": "in",
|
||||
"or": false
|
||||
},
|
||||
"nickname": {
|
||||
"type": "like",
|
||||
"or": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"age": 18,
|
||||
"userName": [
|
||||
"陈海瑶",
|
||||
"冯雨馨"
|
||||
],
|
||||
"nickname": "杰"
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class QueryFilterInfo<T> implements Serializable {
|
||||
|
||||
private FilterItemConfig config; // 配置
|
||||
private PageParam pager = new PageParam(); // 分页
|
||||
// 查询条件
|
||||
private Map<String, Object> filter = new HighPerformanceOrderedMap<>();
|
||||
|
||||
|
||||
public FilterItemConfig getConfig() {
|
||||
if(config == null){
|
||||
config = new FilterItemConfig();
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
public String getDefaultFilterType() {
|
||||
return getConfig().getDefaultFilterType();
|
||||
}
|
||||
public Map<String, Object> getFilter() {
|
||||
if (filter == null) {
|
||||
filter = new HighPerformanceOrderedMap<>();
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
// @条件(QueryFilterTypeEnum) 多个使用逗号号间隔; 如 name@like,age@> 条件 where like '%?%' and age > ?
|
||||
public void easyOptions(String options){
|
||||
this.getConfig().setEasyOption(options);
|
||||
}
|
||||
public Map<String, FilterItem> getOptions() {
|
||||
return this.getConfig().getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立或
|
||||
*
|
||||
* @param field 字段
|
||||
* @param value 值
|
||||
* @param type 类型
|
||||
* @return {@link FilterItem }
|
||||
*/
|
||||
public FilterItem buildOr(String field, Object value, QueryFilterTypeEnum type) {
|
||||
return buildFilter(field, value, type, true);
|
||||
}
|
||||
public void appendKeywordFields(String ...field){
|
||||
QueryConfigUtils.strAdd(this.getConfig().getKeywordFields(),field);
|
||||
}
|
||||
|
||||
public void delKeywordFields(String... keys){
|
||||
QueryConfigUtils.strRemove(this.getConfig().getKeywordFields(), keys);
|
||||
}
|
||||
|
||||
public void appendDateFields(String ...field){
|
||||
QueryConfigUtils.strAdd(this.getConfig().getDateFields(),field);
|
||||
}
|
||||
|
||||
public void delDateFields(String... keys){
|
||||
QueryConfigUtils.strRemove(this.getConfig().getDateFields(),keys);
|
||||
}
|
||||
|
||||
public void appendGroupBy(String ...field){
|
||||
QueryConfigUtils.strAdd(this.getConfig().getGroupBy(),field);
|
||||
}
|
||||
|
||||
public void delGroupBy(String... keys){
|
||||
QueryConfigUtils.strRemove(this.getConfig().getGroupBy(),keys);
|
||||
}
|
||||
|
||||
public boolean containsIgnoredKeys(String key) {
|
||||
return this.getConfig().getIgnoreFields().contains(key);
|
||||
}
|
||||
|
||||
public Set<String> getIgnoreFieldsKeys(){
|
||||
return this.getConfig().getIgnoreFieldsKeys();
|
||||
}
|
||||
public void appendIgnoreFields(String ...field){
|
||||
Set<String> set = new HashSet<>();
|
||||
if(QueryConfigUtils.isNotEmpty(field)){
|
||||
set.addAll(Arrays.asList(field));
|
||||
}
|
||||
appendIgnoreFields(set);
|
||||
}
|
||||
public void setDefaultFilterType(QueryFilterTypeEnum type){
|
||||
this.getConfig().setDefaultFilterType(type.getValue());
|
||||
}
|
||||
public void appendIgnoreFields(Set<String> field){
|
||||
if(QueryConfigUtils.isNotEmpty(field)){
|
||||
for (String s : field) {
|
||||
if(QueryConfigUtils.isNotEmpty(s.trim())){
|
||||
this.getConfig().getIgnoreFieldsKeys().add(s.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void delIgnoreFields(String... keys){
|
||||
if(QueryConfigUtils.isNotEmpty(keys)){
|
||||
for (String key : keys) {
|
||||
this.getConfig().getIgnoreFieldsKeys().remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void appendOrderByDesc(String ...field){
|
||||
appendOrderBy("DESC",field);
|
||||
}
|
||||
|
||||
private void appendOrderBy(String type,String ...field){
|
||||
if(QueryConfigUtils.isNotEmpty(field)){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
List<String> strList = QueryConfigUtils.toStrList(this.getConfig().getOrderBy());
|
||||
for (String s : field) {
|
||||
if (QueryConfigUtils.isNotEmpty(s.trim())) {
|
||||
String key = s.trim() + " "+type;
|
||||
if(strList.contains(key)){
|
||||
strList.remove(key);
|
||||
}
|
||||
builder.append(s.trim()).append(" ").append(type).append(",");
|
||||
}
|
||||
}
|
||||
// 移除重复的排序
|
||||
StringBuilder res = new StringBuilder();
|
||||
for (String s : strList) {
|
||||
res.append(s).append(",");
|
||||
}
|
||||
String tmp = res.toString();
|
||||
tmp += builder.toString();
|
||||
this.getConfig().setOrderBy(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
public void appendOrderByAsc(String ...field){
|
||||
appendOrderBy("ASC",field);
|
||||
}
|
||||
public void delOrderBy(String... keys){
|
||||
QueryConfigUtils.strRemove(this.getConfig().getOrderBy(), keys);
|
||||
}
|
||||
/**
|
||||
* 构建
|
||||
*
|
||||
* @param field 字段
|
||||
* @param value 值
|
||||
* @param type 类型
|
||||
* @return {@link FilterItem }
|
||||
*/
|
||||
public FilterItem build(String field, Object value, QueryFilterTypeEnum type) {
|
||||
return build(field, value, type, false);
|
||||
}
|
||||
public FilterItem build(String field, Object value, QueryFilterTypeEnum type, boolean isOr) {
|
||||
return buildFilter(field, value, type, isOr);
|
||||
}
|
||||
|
||||
private FilterItem buildFilter(String field, Object value, QueryFilterTypeEnum type, boolean isOr) {
|
||||
filter.put(field, value);
|
||||
FilterItem item = new FilterItem();
|
||||
item.setOr(isOr);
|
||||
item.setType(type.getValue());
|
||||
this.getConfig().getOptions().put(field, item);
|
||||
return item;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
package cn.hangtag.framework.mybatis.build;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 类型 取值转换器
|
||||
*
|
||||
* @author YuanFeng
|
||||
* @date 2024/10/16
|
||||
*/
|
||||
public class TypeConverter {
|
||||
|
||||
// 用于存储类型和其对应的转换逻辑
|
||||
private static final Map<Class<?>, Function<Object, Object>> converters = new HashMap<>();
|
||||
|
||||
// 注册类型转换器
|
||||
public static <T> void registerConverter(Class<T> type, Function<T, Object> converter) {
|
||||
converters.put(type, (Function<Object, Object>) converter);
|
||||
}
|
||||
|
||||
// 根据类型进行转换
|
||||
public static Object convertValue(Object inputVal, Class<?> targetType) {
|
||||
Function<Object, Object> converter = converters.get(targetType);
|
||||
if (converter == null) {
|
||||
// 如果没有注册转换器,返回原始值
|
||||
return null;
|
||||
}
|
||||
// 如果有对应类型的转换器,执行转换
|
||||
return converter.apply(inputVal);
|
||||
}
|
||||
|
||||
static {
|
||||
rest();
|
||||
}
|
||||
public static void rest(){
|
||||
restLocalDateTime();
|
||||
restDate();
|
||||
restString();
|
||||
restLong();
|
||||
restDouble();
|
||||
restInteger();
|
||||
restBoolean();
|
||||
restBigDecimal();
|
||||
restBigInteger();
|
||||
}
|
||||
public static void restLocalDateTime(){
|
||||
// 注册LocalDate的转换器
|
||||
TypeConverter.registerConverter(LocalDateTime.class, inputVal -> {
|
||||
if (inputVal != null) {
|
||||
return QueryConfigUtils.dateFormat(inputVal);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
public static void restDate(){
|
||||
// 注册Date的转换器
|
||||
TypeConverter.registerConverter(Date.class, inputVal -> {
|
||||
if (inputVal != null) {
|
||||
return DateUtil.formatDate(inputVal);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
public static void restString(){
|
||||
// 注册字符的转换器
|
||||
TypeConverter.registerConverter(String.class, inputVal -> {
|
||||
return inputVal;
|
||||
});
|
||||
}
|
||||
public static void restLong(){
|
||||
TypeConverter.registerConverter(Long.class, inputVal -> {
|
||||
return inputVal;
|
||||
});
|
||||
}public static void restDouble(){
|
||||
TypeConverter.registerConverter(Double.class, inputVal -> {
|
||||
return inputVal;
|
||||
});
|
||||
}
|
||||
public static void restInteger(){
|
||||
TypeConverter.registerConverter(Integer.class, inputVal -> {
|
||||
return inputVal;
|
||||
});
|
||||
}public static void restBoolean(){
|
||||
TypeConverter.registerConverter(Boolean.class, inputVal -> {
|
||||
return inputVal;
|
||||
});
|
||||
}
|
||||
public static void restBigDecimal() {
|
||||
TypeConverter.registerConverter(BigDecimal.class, inputVal -> {
|
||||
if (inputVal != null) {
|
||||
return new BigDecimal(inputVal.toString()).toString();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public static void restBigInteger() {
|
||||
TypeConverter.registerConverter(BigInteger.class, inputVal -> {
|
||||
if (inputVal != null) {
|
||||
return new BigInteger(inputVal.toString());
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package cn.hangtag.framework.mybatis.build;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class WrapperHandler {
|
||||
|
||||
private static final Map<QueryFilterTypeEnum, WhereWrapper<?>> QUERY_WRAPPER_HANDLER = new HashMap<>();
|
||||
|
||||
public static void registerWrapperHandler(WhereWrapper<?> whereWrapper) {
|
||||
if(whereWrapper != null){
|
||||
QUERY_WRAPPER_HANDLER.put(whereWrapper.getType(), whereWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> QueryWrapper<T> exeWrapperHandler(QueryWrapper<T> queryWrapper,
|
||||
QueryFilterTypeEnum type,
|
||||
Set<String> dateField,
|
||||
String field, Object value) {
|
||||
if (queryWrapper == null) {
|
||||
queryWrapper = new QueryWrapper<>();
|
||||
}
|
||||
WhereWrapper<?> whereWrapper = QUERY_WRAPPER_HANDLER.get(type);
|
||||
WrapperInfo<T> wrapperInfo = new WrapperInfo<>(queryWrapper, field, value,dateField);
|
||||
if (whereWrapper == null) {
|
||||
//没有找到处理器 使用默认
|
||||
if (QueryConfigUtils.isArr(value)) {
|
||||
Object[] strings = QueryConfigUtils.objToArray(value, Object.class);
|
||||
if (QueryConfigUtils.isNotEmpty(strings)) {
|
||||
return queryWrapper.between(field, strings[0], strings[strings.length - 1]);
|
||||
}
|
||||
|
||||
}
|
||||
if (QueryConfigUtils.isList(value)) {
|
||||
List<Object> list = QueryConfigUtils.objToList(value, Object.class);
|
||||
if (QueryConfigUtils.isNotEmpty(list)) {
|
||||
return queryWrapper.between(field, list.get(0), list.get(list.size() - 1));
|
||||
}
|
||||
}
|
||||
return queryWrapper.eq(field, value);
|
||||
}
|
||||
// 执行
|
||||
return ((WhereWrapper<T>)whereWrapper).handler(wrapperInfo);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package cn.hangtag.framework.mybatis.build;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 包装信息
|
||||
*
|
||||
* @author YuanFeng
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class WrapperInfo<T> {
|
||||
|
||||
private QueryWrapper<T> queryWrapper;
|
||||
private String field;
|
||||
private Object value;
|
||||
private Set<String> dateFields;
|
||||
|
||||
public Set<String> getDateFields() {
|
||||
if (dateFields == null) {
|
||||
dateFields = new HashSet<>();
|
||||
}
|
||||
return dateFields;
|
||||
}
|
||||
|
||||
public QueryWrapper<T> getQueryWrapper() {
|
||||
if (queryWrapper == null) {
|
||||
queryWrapper = new QueryWrapper<>();
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package cn.hangtag.framework.mybatis.build.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DbTypeEnum {
|
||||
|
||||
MYSQL("mysql", "MySql数据库"),
|
||||
MARIADB("mariadb", "MariaDB数据库"),
|
||||
ORACLE("oracle", "Oracle11g及以下数据库(高版本推荐使用ORACLE_NEW)"),
|
||||
ORACLE_12C("oracle12c", "Oracle12c+数据库"),
|
||||
DB2("db2", "DB2数据库"),
|
||||
H2("h2", "H2数据库"),
|
||||
HSQL("hsql", "HSQL数据库"),
|
||||
SQLITE("sqlite", "SQLite数据库"),
|
||||
POSTGRE_SQL("postgresql", "Postgre数据库"),
|
||||
SQL_SERVER2005("sqlserver2005", "SQLServer2005数据库"),
|
||||
SQL_SERVER("sqlserver", "SQLServer数据库"),
|
||||
DM("dm", "达梦数据库"),
|
||||
XU_GU("xugu", "虚谷数据库"),
|
||||
KINGBASE_ES("kingbasees", "人大金仓数据库"),
|
||||
PHOENIX("phoenix", "Phoenix HBase数据库"),
|
||||
GAUSS("zenith", "Gauss 数据库"),
|
||||
CLICK_HOUSE("clickhouse", "clickhouse 数据库"),
|
||||
GBASE("gbase", "南大通用(华库)数据库"),
|
||||
GBASE_8S("gbase-8s", "南大通用数据库 GBase 8s"),
|
||||
GBASE8S_PG("gbase8s-pg", "南大通用数据库 GBase 8s兼容pg"),
|
||||
GBASE_8C("gbase8c", "南大通用数据库 GBase 8c"),
|
||||
SINODB("sinodb", "星瑞格数据库"),
|
||||
OSCAR("oscar", "神通数据库"),
|
||||
SYBASE("sybase", "Sybase ASE 数据库"),
|
||||
OCEAN_BASE("oceanbase", "OceanBase 数据库"),
|
||||
FIREBIRD("Firebird", "Firebird 数据库"),
|
||||
HIGH_GO("highgo", "瀚高数据库"),
|
||||
CUBRID("cubrid", "CUBRID数据库"),
|
||||
SUNDB("sundb", "SUNDB数据库"),
|
||||
SAP_HANA("hana", "SAP_HANA数据库"),
|
||||
IMPALA("impala", "impala数据库"),
|
||||
VERTICA("vertica", "vertica数据库"),
|
||||
XCloud("xcloud", "行云数据库"),
|
||||
REDSHIFT("redshift", "亚马逊redshift数据库"),
|
||||
OPENGAUSS("openGauss", "华为 opengauss 数据库"),
|
||||
TDENGINE("TDengine", "TDengine数据库"),
|
||||
INFORMIX("informix", "Informix数据库"),
|
||||
UXDB("uxdb", "优炫数据库"),
|
||||
LEALONE("lealone", "Lealone数据库"),
|
||||
TRINO("trino", "Trino数据库"),
|
||||
PRESTO("presto", "Presto数据库"),
|
||||
OTHER("other", "其他数据库");
|
||||
|
||||
private final String db;
|
||||
private final String desc;
|
||||
|
||||
public static DbTypeEnum getDbType(String dbType) {
|
||||
DbTypeEnum[] var1 = values();
|
||||
int var2 = var1.length;
|
||||
|
||||
for (int var3 = 0; var3 < var2; ++var3) {
|
||||
DbTypeEnum type = var1[var3];
|
||||
if (type.db.equalsIgnoreCase(dbType)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return OTHER;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package cn.hangtag.framework.mybatis.build.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum QueryFilterTypeEnum {
|
||||
|
||||
GT("大于", ">"),
|
||||
GE("大于等于", ">="),
|
||||
LT("小于", "<"),
|
||||
LE("小于等于", "<="),
|
||||
NE("不等于", "!="),
|
||||
EQ("等于", "="),
|
||||
IN("在...之内", "in"),
|
||||
NOTIN("不在...之内", "notIn"),
|
||||
BETWEEN("之间", "between"),
|
||||
BETWEEN2("之间", "><"),
|
||||
LIKE("模糊匹配", "like"),
|
||||
NOT_LIKE("模糊匹配", "notLike"),
|
||||
LIKE_LEFT("左模糊匹配", "likeLeft"),
|
||||
LIKE_RIGHT("右模糊匹配", "likeRight"),
|
||||
/**
|
||||
* 查询以逗号分隔的组合字段数据。
|
||||
* 使用条件:FIND_IN_SET({0}, columnName) 进行查询。
|
||||
* 示例:
|
||||
* - 字段值为:数据1: 123,234,345;数据2: 23,456;数据3: 123,567
|
||||
* - 当条件为 23 时,仅匹配包含 23 的数据,即数据2。
|
||||
*/
|
||||
IN_SET("查询以逗号分隔的组合字段数据", "inSet"),
|
||||
KEYWORD("关键字", "keyword")
|
||||
|
||||
;
|
||||
private final String msg;
|
||||
private final String value;
|
||||
public static QueryFilterTypeEnum getByValue(String value){
|
||||
if(value != null && !value.isEmpty()){
|
||||
for( QueryFilterTypeEnum enumItem: QueryFilterTypeEnum.values()) {
|
||||
if (enumItem.getValue().equalsIgnoreCase(value)) {
|
||||
return enumItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package cn.hangtag.framework.mybatis.build.where;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
public interface WhereWrapper<T> {
|
||||
QueryFilterTypeEnum getType();
|
||||
QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo);
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Between2Handler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.BETWEEN2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
if (QueryConfigUtils.isArr(wrapperInfo.getValue())) {
|
||||
Object[] strings = QueryConfigUtils.objToArray(wrapperInfo.getValue(), Object.class);
|
||||
wrapperInfo.getQueryWrapper().between(wrapperInfo.getField(), strings[0], strings[strings.length - 1]);
|
||||
} else if (QueryConfigUtils.isList(wrapperInfo.getValue())) {
|
||||
List<Object> list = QueryConfigUtils.objToList(wrapperInfo.getValue(), Object.class);
|
||||
wrapperInfo.getQueryWrapper().between(wrapperInfo.getField(), list.get(0), list.get(list.size() - 1));
|
||||
}
|
||||
return wrapperInfo.getQueryWrapper();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
public class BetweenHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.BETWEEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
if (QueryConfigUtils.isArr(wrapperInfo.getValue())) {
|
||||
Object[] strings = QueryConfigUtils.objToArray(wrapperInfo.getValue(), Object.class);
|
||||
wrapperInfo.getQueryWrapper().between(wrapperInfo.getField(), strings[0], strings[strings.length - 1]);
|
||||
} else if (QueryConfigUtils.isList(wrapperInfo.getValue())) {
|
||||
List<Object> list = QueryConfigUtils.objToList(wrapperInfo.getValue(), Object.class);
|
||||
wrapperInfo.getQueryWrapper().between(wrapperInfo.getField(), list.get(0), list.get(list.size() - 1));
|
||||
}
|
||||
return wrapperInfo.getQueryWrapper();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
public class EqHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.EQ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
return wrapperInfo.getQueryWrapper().eq(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
public class GeHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.GE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
return wrapperInfo.getQueryWrapper().ge(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
public class InHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.IN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
return wrapperInfo.getQueryWrapper().in(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
public class InSetHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.IN_SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
// 查询逗号组合数据
|
||||
String str2 = QueryConfigUtils.toStr(wrapperInfo.getValue());
|
||||
String[] arr = str2.split(QueryConfigUtils.SPLIT_CHAR);
|
||||
wrapperInfo.getQueryWrapper().and(w -> {
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
String s = arr[i];
|
||||
w.apply(QueryConfigUtils.getIdsToApply(wrapperInfo.getField()), s);
|
||||
if (i < arr.length - 1) {
|
||||
wrapperInfo.getQueryWrapper().or();
|
||||
}
|
||||
}
|
||||
});
|
||||
return wrapperInfo.getQueryWrapper();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class KeywordHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.KEYWORD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
String str1 = QueryConfigUtils.toStr(wrapperInfo.getValue());
|
||||
// 多个关键字 空格间隔 如 张三 李 条件 where (name like '%张%' or name like '%李%' )
|
||||
String[] arr2 = str1.split(" ");
|
||||
wrapperInfo.getQueryWrapper().and(w -> {
|
||||
for (int i = 0; i < arr2.length; i++) {
|
||||
String s = arr2[i];
|
||||
w.like(wrapperInfo.getField(), s);
|
||||
if (i < arr2.length - 1) {
|
||||
w.or();
|
||||
}
|
||||
}
|
||||
});
|
||||
return wrapperInfo.getQueryWrapper();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
public class LeHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.LE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
return wrapperInfo.getQueryWrapper().le(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LikeHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.LIKE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
if (wrapperInfo.getDateFields().contains(wrapperInfo.getField()) && !QueryConfigUtils.isDateValue(QueryConfigUtils.toStr(wrapperInfo.getValue()))) {
|
||||
//字段为日期 但是关键字的值 又不能支持 like 跳过条件
|
||||
// 设置一个不能的匹配的条件
|
||||
wrapperInfo.getQueryWrapper().eq("1", "2");
|
||||
} else {
|
||||
wrapperInfo.getQueryWrapper().like(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
return wrapperInfo.getQueryWrapper();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LikeLeftHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.LIKE_LEFT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
if (wrapperInfo.getDateFields().contains(wrapperInfo.getField()) && !QueryConfigUtils.isDateValue(QueryConfigUtils.toStr(wrapperInfo.getValue()))) {
|
||||
//字段为日期 但是关键字的值 又不能支持 like 跳过条件
|
||||
// 设置一个不能的匹配的条件
|
||||
wrapperInfo.getQueryWrapper().eq("1", "2");
|
||||
} else {
|
||||
wrapperInfo.getQueryWrapper().likeLeft(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
return wrapperInfo.getQueryWrapper();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LikeRightHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.LIKE_RIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
if (wrapperInfo.getDateFields().contains(wrapperInfo.getField()) && !QueryConfigUtils.isDateValue(QueryConfigUtils.toStr(wrapperInfo.getValue()))) {
|
||||
//字段为日期 但是关键字的值 又不能支持 like 跳过条件
|
||||
// 设置一个不能的匹配的条件
|
||||
wrapperInfo.getQueryWrapper().eq("1", "2");
|
||||
} else {
|
||||
wrapperInfo.getQueryWrapper().likeRight(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
return wrapperInfo.getQueryWrapper();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LtHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.LT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
return wrapperInfo.getQueryWrapper().lt(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
public class NeHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.NE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
return wrapperInfo.getQueryWrapper().ne(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NotInHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.NOTIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
return wrapperInfo.getQueryWrapper().notIn(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package cn.hangtag.framework.mybatis.build.where.handler;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hangtag.framework.mybatis.build.WrapperInfo;
|
||||
import cn.hangtag.framework.mybatis.build.enums.QueryFilterTypeEnum;
|
||||
import cn.hangtag.framework.mybatis.build.where.WhereWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NotLikeHandler<T> implements WhereWrapper<T> {
|
||||
@Override
|
||||
public QueryFilterTypeEnum getType() {
|
||||
return QueryFilterTypeEnum.NOT_LIKE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapper<T> handler(WrapperInfo<T> wrapperInfo) {
|
||||
if (wrapperInfo.getDateFields().contains(wrapperInfo.getField()) && !QueryConfigUtils.isDateValue(QueryConfigUtils.toStr(wrapperInfo.getValue()))) {
|
||||
//字段为日期 但是关键字的值 又不能支持 like 跳过条件
|
||||
// 设置一个不能的匹配的条件
|
||||
wrapperInfo.getQueryWrapper().eq("1", "2");
|
||||
} else {
|
||||
wrapperInfo.getQueryWrapper().notLike(wrapperInfo.getField(), wrapperInfo.getValue());
|
||||
}
|
||||
return wrapperInfo.getQueryWrapper();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package cn.hangtag.framework.mybatis.config;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryConfigUtils;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hangtag.framework.mybatis.core.handler.DefaultDBFieldHandler;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
|
|
@ -26,6 +27,7 @@ import org.springframework.core.env.ConfigurableEnvironment;
|
|||
lazyInitialization = "${mybatis.lazy-initialization:false}") // Mapper 懒加载,目前仅用于单元测试
|
||||
public class HangtagMybatisAutoConfiguration {
|
||||
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
|
||||
|
|
@ -43,6 +45,7 @@ public class HangtagMybatisAutoConfiguration {
|
|||
public IKeyGenerator keyGenerator(ConfigurableEnvironment environment) {
|
||||
DbType dbType = IdTypeEnvironmentPostProcessor.getDbType(environment);
|
||||
if (dbType != null) {
|
||||
QueryConfigUtils.setDbType(dbType.getDb());
|
||||
switch (dbType) {
|
||||
case POSTGRE_SQL:
|
||||
return new PostgreKeyGenerator();
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ public interface ErrorCodeConstants extends cn.hangtag.module.system.enums.Erro
|
|||
ErrorCode PRODUCT_INFO_NOT_EXISTS = new ErrorCode(3200, "产品资料 不存在");
|
||||
ErrorCode PRODUCT_PROCESS_NOT_EXISTS = new ErrorCode(3201, "产品工艺 不存在");
|
||||
ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(3300, "客户不存在");
|
||||
ErrorCode CUSTOMER_LOGIN_STATUS_DISABLE = new ErrorCode(3301, "客户已被禁用!请联系管理员");
|
||||
ErrorCode CUSTOMER_ADDRESS_NOT_EXISTS = new ErrorCode(3302, "地址信息数据 不存在");
|
||||
ErrorCode SHAPE_TEMPLATE_NOT_EXISTS = new ErrorCode(3400, "图形模板管理 不存在");
|
||||
ErrorCode DRAFT_DESIGN_DATA_NOT_EXISTS = new ErrorCode(3500, "稿件模板数据 不存在");
|
||||
ErrorCode SALE_ORDER_NOT_EXISTS = new ErrorCode(3600, "OMS销售订单不存在");
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@ public class BrandRespVO {
|
|||
@ExcelProperty("官网")
|
||||
private String website;
|
||||
|
||||
|
||||
@Schema(description = "品牌数量")
|
||||
@ExcelProperty("品牌数量")
|
||||
private Integer productCount;
|
||||
|
||||
@Schema(description = "语言标识 字典-language_locale")
|
||||
@ExcelProperty("语言标识 字典-language_locale")
|
||||
private String locale;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
package cn.hangtag.module.oms.controller.admin.customer.front;
|
||||
|
||||
import cn.hangtag.framework.common.pojo.CommonResult;
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
import cn.hangtag.framework.common.util.FuncUtil;
|
||||
import cn.hangtag.framework.common.util.object.BeanUtils;
|
||||
import cn.hangtag.framework.ip.core.Area;
|
||||
import cn.hangtag.framework.ip.core.utils.AreaUtils;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.AddressInfoVO;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.AddressInfoValidate;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.AddressReqVO;
|
||||
import cn.hangtag.module.oms.service.customer.CustomerAddressService;
|
||||
import cn.hangtag.module.oms.service.customer.CustomerService;
|
||||
import cn.hangtag.module.system.controller.app.ip.vo.AppAreaNodeRespVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.hangtag.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "前台 - 客户")
|
||||
@RestController
|
||||
@RequestMapping("/front/oms/address")
|
||||
@Validated
|
||||
@AllArgsConstructor
|
||||
public class AddressFrontController {
|
||||
private final CustomerService customerService;
|
||||
private final CustomerAddressService addressService;
|
||||
|
||||
@PostMapping("/submit")
|
||||
@Operation(summary = "更新品牌管理 ")
|
||||
// todo 权限
|
||||
public CommonResult<Long> submit(@Valid @RequestBody AddressInfoValidate info) {
|
||||
Long id = addressService.submit(info);
|
||||
return success(id);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(summary = "删除 ")
|
||||
@Parameter(name = "id", description = "主键id", required = true)
|
||||
public CommonResult<Boolean> delete(@PathVariable("id") Long id) {
|
||||
addressService.delById(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取明细 ")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<AddressInfoVO> getBrand(@PathVariable("id") Long id) {
|
||||
AddressInfoVO vo = addressService.getAddressInfo(id);
|
||||
return success(vo);
|
||||
}
|
||||
@PutMapping("/default/{id}")
|
||||
@Operation(summary = "获取明细 ")
|
||||
@Parameter(name = "id", description = "编号")
|
||||
public CommonResult<Boolean> setDefaultAddress(@PathVariable("id") Long id) {
|
||||
addressService.setDefaultAddress(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得品牌管理 分页")
|
||||
public CommonResult<PageResult<AddressInfoVO>> getBrandPage(@Valid AddressReqVO vo) {
|
||||
PageResult<AddressInfoVO> pageResult = addressService.queryPage(vo);
|
||||
return success(pageResult);
|
||||
}
|
||||
|
||||
@GetMapping("/area-tree/{type}")
|
||||
public CommonResult<List<AppAreaNodeRespVO>> getAreaTree(@PathVariable Integer type) {
|
||||
int anInt = FuncUtil.toInt(type, 0);
|
||||
Area area = AreaUtils.getArea(anInt == 1 ? 1 : 0);
|
||||
return success(BeanUtils.toBean(area.getChildren(), AppAreaNodeRespVO.class));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package cn.hangtag.module.oms.controller.admin.customer.front;
|
||||
|
||||
import cn.hangtag.framework.common.pojo.CommonResult;
|
||||
import cn.hangtag.framework.security.core.LoginUser;
|
||||
import cn.hangtag.framework.security.core.util.SecurityFrameworkUtils;
|
||||
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.CustomerInfoVO;
|
||||
import cn.hangtag.module.oms.service.customer.CustomerService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
import static cn.hangtag.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "前台 - 客户")
|
||||
@RestController
|
||||
@RequestMapping("/front/oms/customer")
|
||||
@Validated
|
||||
@AllArgsConstructor
|
||||
public class CustomerFrontController {
|
||||
private final CustomerService customerService;
|
||||
|
||||
@GetMapping("/info")
|
||||
@Operation(summary = "获得客户")
|
||||
public CommonResult<CustomerInfoVO> getCustomer() {
|
||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||
CustomerInfoVO vo = customerService.queryLoginCustomerInfo(loginUser.getId());
|
||||
return success(vo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package cn.hangtag.module.oms.controller.admin.customer.front.vo;
|
||||
|
||||
import cn.hangtag.framework.common.util.SafeUseUtil;
|
||||
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerAddressDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class AddressInfoVO implements Serializable {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 关联到客户的ID,外键指向客户表
|
||||
*/
|
||||
private Long customerId;
|
||||
/**
|
||||
* 收货人姓名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
private String phone;
|
||||
/**
|
||||
* 区/县
|
||||
*/
|
||||
private Integer areaId;
|
||||
/**
|
||||
* 详细地址
|
||||
*/
|
||||
private String address;
|
||||
/**
|
||||
* 是否为默认地址,0表示否,1表示是
|
||||
*/
|
||||
private Boolean isDefault;
|
||||
|
||||
public AddressInfoVO(CustomerAddressDO addressDO) {
|
||||
SafeUseUtil.copyProperties(addressDO,this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package cn.hangtag.module.oms.controller.admin.customer.front.vo;
|
||||
|
||||
import cn.hangtag.framework.common.util.SafeUseUtil;
|
||||
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerAddressDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 地址信息验证
|
||||
*
|
||||
* @author YuanFeng
|
||||
* @date 2024/10/15
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class AddressInfoValidate implements Serializable {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
private Long customerId;
|
||||
|
||||
@NotEmpty(message = "名称不能为空")
|
||||
@Length(min = 1, max = 64, message = "名称 name不能大于64个字符")
|
||||
private String name;
|
||||
|
||||
@NotEmpty(message = "联系电话 phone不能为空")
|
||||
private String phone;
|
||||
/**
|
||||
* 区/县
|
||||
*/
|
||||
@NotNull(message = "areaId 地区不能为空")
|
||||
private Integer areaId;
|
||||
/**
|
||||
* 详细地址
|
||||
*/
|
||||
@NotEmpty(message = "详细地址 不能为空")
|
||||
@Length(min = 1, max = 512, message = "详细地址 name不能大于512个字符")
|
||||
private String address;
|
||||
/**
|
||||
* 是否为默认地址,0表示否,1表示是
|
||||
*/
|
||||
private Boolean isDefault;
|
||||
|
||||
public Boolean getIsDefault() {
|
||||
if(this.isDefault == null){
|
||||
isDefault = false;
|
||||
}
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
public AddressInfoValidate(CustomerAddressDO addressDO) {
|
||||
SafeUseUtil.copyProperties(addressDO,this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package cn.hangtag.module.oms.controller.admin.customer.front.vo;
|
||||
|
||||
import cn.hangtag.framework.common.pojo.PageParam;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "前台 - 客户地址分页 ")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AddressReqVO extends PageParam {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 关联到客户的ID,外键指向客户表
|
||||
*/
|
||||
private Long customerId;
|
||||
/**
|
||||
* 收货人姓名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
private String phone;
|
||||
/**
|
||||
* 区/县
|
||||
*/
|
||||
private Integer areaId;
|
||||
/**
|
||||
* 详细地址
|
||||
*/
|
||||
private String address;
|
||||
/**
|
||||
* 是否为默认地址,0表示否,1表示是
|
||||
*/
|
||||
private Boolean isDefault;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package cn.hangtag.module.oms.controller.admin.customer.front.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "客户信息 VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class CustomerInfoVO implements Serializable {
|
||||
|
||||
@Schema(description = "ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "编码")
|
||||
private String number;
|
||||
|
||||
@Schema(description = "名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "公司")
|
||||
private String company;
|
||||
|
||||
@Schema(description = "类型")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "数据状态")
|
||||
private String status;
|
||||
/**
|
||||
* 公司地址
|
||||
*/
|
||||
private String companyAddress;
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
/**
|
||||
* 联系人
|
||||
*/
|
||||
private String contacts;
|
||||
/**
|
||||
* 联系人手机号
|
||||
*/
|
||||
private String phone;
|
||||
/**
|
||||
* 跟单员
|
||||
*/
|
||||
private String gdperson;
|
||||
/**
|
||||
* 销售员
|
||||
*/
|
||||
private String saleperson;
|
||||
|
||||
private String invoiceCode;
|
||||
|
||||
private String invoiceName;
|
||||
|
||||
private String invoiceAddress;
|
||||
|
||||
/**
|
||||
* 所属地区
|
||||
*/
|
||||
private List<AddressInfoVO> addressList;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remarks;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -59,4 +59,9 @@ public class DraftDesignDataRespVO {
|
|||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
||||
@Schema(description = "产品计数")
|
||||
@ExcelProperty("产品计数")
|
||||
private Integer productCount;
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package cn.hangtag.module.oms.controller.admin.productinfo;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryFilterInfo;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
|
@ -8,7 +9,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
import javax.validation.*;
|
||||
import javax.servlet.http.*;
|
||||
import java.util.*;
|
||||
|
|
@ -79,6 +79,15 @@ public class ProductInfoController {
|
|||
return success(BeanUtils.toBean(pageResult, ProductInfoRespVO.class));
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/query")
|
||||
@Operation(summary = "获得产品资料 分页")
|
||||
@PreAuthorize("@ss.hasPermission('oms:product-info:query')")
|
||||
public CommonResult<PageResult<ProductInfoRespVO>> queryPage(@RequestBody QueryFilterInfo<ProductInfoPageReqVO> queryFilterInfo) {
|
||||
PageResult<ProductInfoDO> pageResult = productInfoService.queryPage(queryFilterInfo);
|
||||
return success(BeanUtils.toBean(pageResult, ProductInfoRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出产品资料 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('oms:product-info:export')")
|
||||
|
|
|
|||
|
|
@ -1,64 +0,0 @@
|
|||
package cn.hangtag.module.oms.controller.admin.saleorder;
|
||||
|
||||
import cn.hangtag.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.hangtag.framework.common.pojo.CommonResult;
|
||||
import cn.hangtag.framework.common.pojo.PageParam;
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
import cn.hangtag.framework.common.util.number.NumberUtils;
|
||||
import cn.hangtag.framework.common.util.object.BeanUtils;
|
||||
import cn.hangtag.framework.excel.core.util.ExcelUtils;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.dto.CreateSaleOrderDTO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderPageReqVO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderRemarkReqVO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderRespVO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderSaveReqVO;
|
||||
import cn.hangtag.module.oms.convert.saleorder.SaleOrderConvert;
|
||||
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.saleorder.SaleOrderDO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO;
|
||||
import cn.hangtag.module.oms.service.customer.CustomerService;
|
||||
import cn.hangtag.module.oms.service.saleorder.SaleOrderService;
|
||||
import cn.hangtag.module.system.api.user.AdminUserApi;
|
||||
import cn.hangtag.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.hangtag.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.hangtag.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "销售订单")
|
||||
@RestController
|
||||
@RequestMapping("/front/oms/sale-order")
|
||||
@Validated
|
||||
public class SaleOrderFrontController {
|
||||
|
||||
@Resource
|
||||
private SaleOrderService saleOrderService;
|
||||
@Resource
|
||||
private CustomerService customerService;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
|
||||
@PostMapping("/placeOrder")
|
||||
@Operation(summary = "下单")
|
||||
public CommonResult<Long> placeOrder(@Valid @RequestBody CreateSaleOrderDTO dto) {
|
||||
return success(saleOrderService.placeOrder(dto));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package cn.hangtag.module.oms.controller.admin.saleorder.front;
|
||||
|
||||
import cn.hangtag.framework.common.pojo.CommonResult;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.front.dto.CreateSaleOrderDTO;
|
||||
import cn.hangtag.module.oms.service.customer.CustomerService;
|
||||
import cn.hangtag.module.oms.service.saleorder.SaleOrderService;
|
||||
import cn.hangtag.module.system.api.user.AdminUserApi;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.hangtag.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "销售订单")
|
||||
@RestController
|
||||
@RequestMapping("/front/oms/sale-order")
|
||||
@Validated
|
||||
public class SaleOrderFrontController {
|
||||
|
||||
@Resource
|
||||
private SaleOrderService saleOrderService;
|
||||
@Resource
|
||||
private CustomerService customerService;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
|
||||
@PostMapping("/placeOrder")
|
||||
@Operation(summary = "下单")
|
||||
public CommonResult<Long> placeOrder(@Valid @RequestBody CreateSaleOrderDTO dto) {
|
||||
return success(saleOrderService.placeOrder(dto));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
package cn.hangtag.module.oms.controller.admin.saleorder.dto;
|
||||
package cn.hangtag.module.oms.controller.admin.saleorder.front.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
|
|
@ -80,11 +79,24 @@ public class CreateSaleOrderDTO implements Serializable {
|
|||
*/
|
||||
private Long plansenddate;
|
||||
|
||||
/**
|
||||
* 交货地址
|
||||
*/
|
||||
private String deliveryAddress;
|
||||
|
||||
/**
|
||||
* 交货备注
|
||||
*/
|
||||
private String deliveryRemark;
|
||||
|
||||
|
||||
/**
|
||||
* 是否分批交货
|
||||
*/
|
||||
private Boolean isBatch;
|
||||
|
||||
|
||||
|
||||
private List<SaleOrderEntryItemDTO> saleOrderEntry;
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package cn.hangtag.module.oms.controller.admin.saleorder.dto;
|
||||
package cn.hangtag.module.oms.controller.admin.saleorder.front.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package cn.hangtag.module.oms.controller.admin.saleorder.dto;
|
||||
package cn.hangtag.module.oms.controller.admin.saleorder.front.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package cn.hangtag.module.oms.controller.admin.saleorder.dto;
|
||||
package cn.hangtag.module.oms.controller.admin.saleorder.front.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package cn.hangtag.module.oms.controller.admin.saleorder.dto;
|
||||
package cn.hangtag.module.oms.controller.admin.saleorder.front.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
package cn.hangtag.module.oms.dal.dataobject.brand;
|
||||
|
||||
import cn.hangtag.framework.common.util.FuncUtil;
|
||||
import cn.hangtag.module.oms.dal.dataobject.productinfo.ProductInfoDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
|
@ -62,4 +65,10 @@ public class BrandDO extends BaseDO {
|
|||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 产品计数
|
||||
*/
|
||||
private Integer productCount;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -66,4 +66,10 @@ public class DraftDesignDataDO extends BaseDO {
|
|||
*/
|
||||
private String propDefault;
|
||||
|
||||
|
||||
/**
|
||||
* 产品计数
|
||||
*/
|
||||
private Integer productCount;
|
||||
|
||||
}
|
||||
|
|
@ -1,16 +1,10 @@
|
|||
package cn.hangtag.module.oms.dal.dataobject.saleorder;
|
||||
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.dto.CreateSaleOrderDTO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.front.dto.CreateSaleOrderDTO;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
|
|
@ -100,6 +94,17 @@ public class SaleOrderDO extends BaseDO {
|
|||
* 发票名称
|
||||
*/
|
||||
private String invoiceName;
|
||||
|
||||
/**
|
||||
* 发票地址
|
||||
*/
|
||||
private String invoiceAddress;
|
||||
|
||||
/**
|
||||
* 发票备注
|
||||
*/
|
||||
private String invoiceRemarks;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
|
|
@ -108,10 +113,7 @@ public class SaleOrderDO extends BaseDO {
|
|||
* 货币
|
||||
*/
|
||||
private String currency;
|
||||
/**
|
||||
* 发票备注
|
||||
*/
|
||||
private String invoiceRemarks;
|
||||
|
||||
/**
|
||||
* 驳回原因
|
||||
*/
|
||||
|
|
@ -145,10 +147,7 @@ public class SaleOrderDO extends BaseDO {
|
|||
* 零售商单号
|
||||
*/
|
||||
private String retailerCode;
|
||||
/**
|
||||
* 发票地址
|
||||
*/
|
||||
private String invoiceAddress;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -161,7 +160,15 @@ public class SaleOrderDO extends BaseDO {
|
|||
*/
|
||||
private Boolean isBatch;
|
||||
|
||||
/**
|
||||
* 交货地址
|
||||
*/
|
||||
private String deliveryAddress;
|
||||
|
||||
/**
|
||||
* 交货备注
|
||||
*/
|
||||
private String deliveryRemark;
|
||||
|
||||
public SaleOrderDO(CreateSaleOrderDTO dto) {
|
||||
BeanUtil.copyProperties(dto, this,"bizdate","plansenddate");
|
||||
|
|
|
|||
|
|
@ -25,4 +25,5 @@ public interface CustomerAddressMapper extends BaseMapperX<CustomerAddressDO> {
|
|||
return delete(CustomerAddressDO::getCustomerId, customerId);
|
||||
}
|
||||
|
||||
int restDefaultAddress(Long customerId);
|
||||
}
|
||||
|
|
@ -2,10 +2,16 @@ package cn.hangtag.module.oms.dal.mysql.productinfo;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
import cn.hangtag.framework.common.pojo.PageParam;
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.MybatisPlusUtil;
|
||||
import cn.hangtag.framework.mybatis.build.QueryFilterInfo;
|
||||
import cn.hangtag.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.hangtag.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.hangtag.module.oms.dal.dataobject.productinfo.ProductInfoDO;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import cn.hangtag.module.oms.controller.admin.productinfo.vo.*;
|
||||
|
||||
|
|
@ -33,4 +39,16 @@ public interface ProductInfoMapper extends BaseMapperX<ProductInfoDO> {
|
|||
.orderByDesc(ProductInfoDO::getId));
|
||||
}
|
||||
|
||||
default PageResult<ProductInfoDO> selectPagePlus(QueryFilterInfo<ProductInfoPageReqVO> queryFilterInfo) {
|
||||
PageParam pager = queryFilterInfo.getPager();
|
||||
QueryWrapper<ProductInfoDO> queryWrapper = MybatisPlusUtil
|
||||
.parseQuery(queryFilterInfo, true,ProductInfoDO.class,
|
||||
"pageNo", "pageSize", "PAGE_NO", "PAGE_SIZE", "PAGE_SIZE_NONE");
|
||||
queryWrapper.orderByDesc("id");
|
||||
PageResult<ProductInfoDO> productInfoDOPageResult = selectPage(pager, queryWrapper);
|
||||
|
||||
return productInfoDOPageResult;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -69,4 +69,13 @@ public interface BrandService {
|
|||
* @return 品牌编号集合
|
||||
*/
|
||||
Set<Long> getCustomerBrandListByCustomerId(Collection<Long> customerIds);
|
||||
|
||||
|
||||
/**
|
||||
* 更新产品计数
|
||||
*
|
||||
* @param id ID 品牌id
|
||||
* @return {@link Integer }
|
||||
*/
|
||||
Integer updateProductCount(Long id);
|
||||
}
|
||||
|
|
@ -6,7 +6,9 @@ import cn.hangtag.framework.common.util.FuncUtil;
|
|||
import cn.hangtag.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.hangtag.module.oms.base.dal.dataobject.producttype.ProductTypeDO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.customerbrand.CustomerBrandDO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.productinfo.ProductInfoDO;
|
||||
import cn.hangtag.module.oms.dal.mysql.customerbrand.CustomerBrandMapper;
|
||||
import cn.hangtag.module.oms.dal.mysql.productinfo.ProductInfoMapper;
|
||||
import cn.hangtag.module.oms.enums.BrandErrorCodeConstants;
|
||||
import cn.hangtag.module.oms.serialnumber.CodingRulesUtils;
|
||||
import cn.hangtag.module.system.dal.dataobject.permission.MenuDO;
|
||||
|
|
@ -14,15 +16,19 @@ import cn.hangtag.module.system.dal.dataobject.permission.RoleMenuDO;
|
|||
import cn.hangtag.module.system.dal.mysql.permission.RoleMenuMapper;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.hangtag.module.oms.controller.admin.brand.vo.*;
|
||||
import cn.hangtag.module.oms.dal.dataobject.brand.BrandDO;
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
|
|
@ -43,21 +49,21 @@ import static java.util.Collections.singleton;
|
|||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class BrandServiceImpl implements BrandService {
|
||||
|
||||
@Resource
|
||||
private BrandMapper brandMapper;
|
||||
@Resource
|
||||
private CustomerBrandMapper customerBrandMapper;
|
||||
private final BrandMapper brandMapper;
|
||||
private final ProductInfoMapper productInfoMapper;
|
||||
private final CustomerBrandMapper customerBrandMapper;
|
||||
|
||||
@Override
|
||||
public Long createBrand(BrandSaveReqVO createReqVO) {
|
||||
// 插入
|
||||
BrandDO brand = BeanUtils.toBean(createReqVO, BrandDO.class);
|
||||
String code = brand.getCode();
|
||||
if(FuncUtil.isNotEmpty(code)){
|
||||
checkCode(brand.getId(),code);
|
||||
}else {
|
||||
if (FuncUtil.isNotEmpty(code)) {
|
||||
checkCode(brand.getId(), code);
|
||||
} else {
|
||||
brand.setCode(getNewCode());
|
||||
}
|
||||
brandMapper.insert(brand);
|
||||
|
|
@ -72,15 +78,30 @@ public class BrandServiceImpl implements BrandService {
|
|||
// 更新
|
||||
BrandDO updateObj = BeanUtils.toBean(updateReqVO, BrandDO.class);
|
||||
String code = updateObj.getCode();
|
||||
if(FuncUtil.isNotEmpty(code)){
|
||||
checkCode(updateObj.getId(),code);
|
||||
}else {
|
||||
if (FuncUtil.isNotEmpty(code)) {
|
||||
checkCode(updateObj.getId(), code);
|
||||
} else {
|
||||
updateObj.setCode(getNewCode());
|
||||
}
|
||||
|
||||
brandMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer updateProductCount(Long id) {
|
||||
LambdaQueryWrapper<ProductInfoDO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(ProductInfoDO::getBrandId, id);
|
||||
queryWrapper.eq(ProductInfoDO::getDeleted, 0);
|
||||
Long l = productInfoMapper.selectCount(queryWrapper);
|
||||
int count = FuncUtil.toInt(l, 0);
|
||||
// 更新数量
|
||||
BrandDO brandDO = new BrandDO();
|
||||
brandDO.setId(id);
|
||||
brandDO.setProductCount(count);
|
||||
brandMapper.updateById(brandDO);
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBrand(Long id) {
|
||||
// 校验存在
|
||||
|
|
@ -109,15 +130,15 @@ public class BrandServiceImpl implements BrandService {
|
|||
public String getNewCode() {
|
||||
String s = "";
|
||||
int count = 10;
|
||||
while (true){
|
||||
count --;
|
||||
while (true) {
|
||||
count--;
|
||||
try {
|
||||
s = CodingRulesUtils.generateCode(2L, false);
|
||||
checkCode(null,s);
|
||||
return s;
|
||||
}catch (ServiceException e){
|
||||
s = CodingRulesUtils.generateCode(2L, false);
|
||||
checkCode(null, s);
|
||||
return s;
|
||||
} catch (ServiceException e) {
|
||||
log.warn("重复或者下一个编码");
|
||||
if(count < 0){
|
||||
if (count < 0) {
|
||||
log.error("编码获取失败");
|
||||
return "";
|
||||
}
|
||||
|
|
@ -140,20 +161,20 @@ public class BrandServiceImpl implements BrandService {
|
|||
}
|
||||
|
||||
|
||||
private void checkCode(Long id,String code){
|
||||
if(FuncUtil.isNotEmpty(code)){
|
||||
private void checkCode(Long id, String code) {
|
||||
if (FuncUtil.isNotEmpty(code)) {
|
||||
LambdaQueryWrapper<BrandDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.select(BrandDO::getId,BrandDO::getCode, BaseDO::getDeleted);
|
||||
lambdaQueryWrapper.select(BrandDO::getId, BrandDO::getCode, BaseDO::getDeleted);
|
||||
lambdaQueryWrapper.eq(BrandDO::getCode, code);
|
||||
lambdaQueryWrapper.eq(BrandDO::getDeleted,false);
|
||||
lambdaQueryWrapper.eq(BrandDO::getDeleted, false);
|
||||
List<BrandDO> dos = brandMapper.selectList(lambdaQueryWrapper);
|
||||
if(FuncUtil.isEmpty(id) && FuncUtil.isNotEmpty(dos)){
|
||||
if (FuncUtil.isEmpty(id) && FuncUtil.isNotEmpty(dos)) {
|
||||
throw exception(GlobalErrorCodeConstants.DATA_DUPLICATE);
|
||||
}
|
||||
if (FuncUtil.isNotEmpty(id) && FuncUtil.isNotEmpty(dos)) {
|
||||
for (BrandDO aDo : dos) {
|
||||
// 出现重复并当前id 不一致
|
||||
if(!FuncUtil.equals(aDo.getId(), id)){
|
||||
if (!FuncUtil.equals(aDo.getId(), id)) {
|
||||
throw exception(GlobalErrorCodeConstants.DATA_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
package cn.hangtag.module.oms.service.customer;
|
||||
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.AddressInfoVO;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.AddressInfoValidate;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.AddressReqVO;
|
||||
|
||||
/**
|
||||
* 客户 Service 接口
|
||||
*
|
||||
* @author wwb
|
||||
*/
|
||||
public interface CustomerAddressService {
|
||||
|
||||
Long submit(AddressInfoValidate addressInfo);
|
||||
|
||||
void delById(Long id);
|
||||
|
||||
AddressInfoVO getAddressInfo(Long id);
|
||||
|
||||
/**
|
||||
* 查询页
|
||||
*
|
||||
* @param vo vo
|
||||
* @return {@link PageResult }<{@link AddressInfoVO }>
|
||||
*/
|
||||
PageResult<AddressInfoVO> queryPage(AddressReqVO vo);
|
||||
|
||||
/**
|
||||
* 设置默认地址
|
||||
*
|
||||
* @param id ID
|
||||
*/
|
||||
void setDefaultAddress(Long id);
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
package cn.hangtag.module.oms.service.customer;
|
||||
|
||||
import cn.hangtag.framework.common.exception.ServiceException;
|
||||
import cn.hangtag.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import cn.hangtag.framework.common.pojo.PageParam;
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
import cn.hangtag.framework.common.util.FuncUtil;
|
||||
import cn.hangtag.framework.common.util.SafeUseUtil;
|
||||
import cn.hangtag.framework.common.util.object.BeanUtils;
|
||||
import cn.hangtag.framework.common.util.validation.AssertUtil;
|
||||
import cn.hangtag.framework.mybatis.build.MybatisPlusUtil;
|
||||
import cn.hangtag.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.hangtag.framework.security.core.LoginUser;
|
||||
import cn.hangtag.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.AddressInfoVO;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.AddressInfoValidate;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.AddressReqVO;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.CustomerInfoVO;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.vo.CustomerPageReqVO;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.vo.CustomerSaveReqVO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerAddressDO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
|
||||
import cn.hangtag.module.oms.dal.mysql.customer.CustomerAddressMapper;
|
||||
import cn.hangtag.module.oms.dal.mysql.customer.CustomerMapper;
|
||||
import cn.hangtag.module.oms.serialnumber.CodingRulesUtils;
|
||||
import cn.hangtag.module.system.controller.admin.user.vo.user.UserSaveReqVO;
|
||||
import cn.hangtag.module.system.service.permission.PermissionService;
|
||||
import cn.hangtag.module.system.service.user.AdminUserService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.hangtag.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.hangtag.module.oms.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 客户 Service 实现类
|
||||
*
|
||||
* @author wwb
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class CustomerAddressServiceImpl implements CustomerAddressService {
|
||||
|
||||
private CustomerAddressMapper customerAddressMapper;
|
||||
private CustomerMapper customerMapper;
|
||||
private CustomerService customerService;
|
||||
|
||||
@Override
|
||||
public Long submit(AddressInfoValidate addressInfo) {
|
||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||
CustomerDO customerDO = customerService.getCanUseCustomer(loginUser.getId());
|
||||
// 客户档案可用
|
||||
CustomerAddressDO addressDO = new CustomerAddressDO();
|
||||
Long id = addressInfo.getId();
|
||||
SafeUseUtil.copyProperties(addressInfo, addressDO);
|
||||
addressDO.setCustomerId(customerDO.getId());
|
||||
if(FuncUtil.isEmpty(id)){
|
||||
customerAddressMapper.insert(addressDO);
|
||||
id = addressDO.getId();
|
||||
}else {
|
||||
customerAddressMapper.updateById(addressDO);
|
||||
}
|
||||
if(addressDO.getIsDefault()){
|
||||
setDefaultAddress(id);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delById(Long id) {
|
||||
CustomerAddressDO addressDO = customerAddressMapper.selectById(id);
|
||||
AssertUtil.isEmpty(addressDO, CUSTOMER_ADDRESS_NOT_EXISTS.getMsg());
|
||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||
CustomerDO customerDO = customerService.getCanUseCustomer(loginUser.getId());
|
||||
Long customerId = addressDO.getCustomerId();
|
||||
if(!FuncUtil.equals(customerDO, customerId)){
|
||||
// 删除非本客户档案
|
||||
throw exception(AUTH_USER_NOT_PERMISSION);
|
||||
}
|
||||
// 删除客户地址
|
||||
customerAddressMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddressInfoVO getAddressInfo(Long id) {
|
||||
CustomerAddressDO addressDO = customerAddressMapper.selectById(id);
|
||||
AssertUtil.isEmpty(addressDO, CUSTOMER_ADDRESS_NOT_EXISTS.getMsg());
|
||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||
CustomerDO customerDO = customerService.getCanUseCustomer(loginUser.getId());
|
||||
Long customerId = addressDO.getCustomerId();
|
||||
if(!FuncUtil.equals(customerDO.getId(), customerId)){
|
||||
// 非本客户档案
|
||||
throw exception(AUTH_USER_NOT_PERMISSION);
|
||||
}
|
||||
return new AddressInfoVO(addressDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<AddressInfoVO> queryPage(AddressReqVO vo) {
|
||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||
CustomerDO customerDO = customerService.getCanUseCustomer(loginUser.getId());
|
||||
PageParam pageParam = new PageParam();
|
||||
pageParam.setPageNo(vo.getPageNo());
|
||||
pageParam.setPageSize(vo.getPageSize());
|
||||
vo.setCustomerId(customerDO.getId());
|
||||
QueryWrapper<CustomerAddressDO> queryWrapper = MybatisPlusUtil.buildQueryFor("customerId@=,name@like,address@like,phone@like",
|
||||
vo,
|
||||
CustomerAddressDO.class, MybatisPlusUtil.defaultIgnoreFilters);
|
||||
|
||||
PageResult<CustomerAddressDO> result = customerAddressMapper.selectPage(pageParam, queryWrapper);
|
||||
List<CustomerAddressDO> list = result.getList();
|
||||
List<AddressInfoVO> addressInfos = new ArrayList<>();
|
||||
for (CustomerAddressDO addressDO : list) {
|
||||
addressInfos.add(new AddressInfoVO(addressDO));
|
||||
}
|
||||
PageResult<AddressInfoVO> result2 = new PageResult<>(addressInfos, result.getTotal());
|
||||
return result2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultAddress(Long id) {
|
||||
CustomerAddressDO addressDO = customerAddressMapper.selectById(id);
|
||||
AssertUtil.isEmpty(addressDO, CUSTOMER_ADDRESS_NOT_EXISTS.getMsg());
|
||||
Long customerId = addressDO.getCustomerId();
|
||||
customerAddressMapper.restDefaultAddress(customerId);
|
||||
CustomerAddressDO addressDO1 = new CustomerAddressDO();
|
||||
addressDO1.setId(id);
|
||||
addressDO1.setIsDefault(true);
|
||||
customerAddressMapper.updateById(addressDO1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,10 @@ package cn.hangtag.module.oms.service.customer;
|
|||
import java.util.*;
|
||||
import javax.validation.*;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.vo.*;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.CustomerInfoVO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerAddressDO;
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
import cn.hangtag.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 客户 Service 接口
|
||||
|
|
@ -65,4 +65,19 @@ public interface CustomerService {
|
|||
|
||||
CustomerDO getCustomerByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 前台 带出查询登录客户信息 包含地址
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return {@link CustomerInfoVO }
|
||||
*/
|
||||
CustomerInfoVO queryLoginCustomerInfo(Long userId);
|
||||
|
||||
/**
|
||||
* 获取可以使用客户
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return {@link CustomerDO }
|
||||
*/
|
||||
CustomerDO getCanUseCustomer(Long userId);
|
||||
}
|
||||
|
|
@ -3,13 +3,20 @@ package cn.hangtag.module.oms.service.customer;
|
|||
import cn.hangtag.framework.common.exception.ServiceException;
|
||||
import cn.hangtag.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import cn.hangtag.framework.common.util.FuncUtil;
|
||||
import cn.hangtag.framework.common.util.SafeUseUtil;
|
||||
import cn.hangtag.framework.common.util.validation.AssertUtil;
|
||||
import cn.hangtag.framework.mybatis.build.MybatisPlusUtil;
|
||||
import cn.hangtag.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.produceorder.ProduceOrderDO;
|
||||
import cn.hangtag.framework.security.core.LoginUser;
|
||||
import cn.hangtag.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.AddressInfoVO;
|
||||
import cn.hangtag.module.oms.controller.admin.customer.front.vo.CustomerInfoVO;
|
||||
import cn.hangtag.module.oms.serialnumber.CodingRulesUtils;
|
||||
import cn.hangtag.module.system.controller.admin.user.vo.user.UserSaveReqVO;
|
||||
import cn.hangtag.module.system.service.permission.PermissionService;
|
||||
import cn.hangtag.module.system.service.user.AdminUserService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
|
@ -23,7 +30,6 @@ import cn.hangtag.module.oms.controller.admin.customer.vo.*;
|
|||
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerAddressDO;
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
import cn.hangtag.framework.common.pojo.PageParam;
|
||||
import cn.hangtag.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.hangtag.module.oms.dal.mysql.customer.CustomerMapper;
|
||||
|
|
@ -172,6 +178,31 @@ public class CustomerServiceImpl implements CustomerService {
|
|||
return customerDO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomerInfoVO queryLoginCustomerInfo(Long userId) {
|
||||
CustomerDO customerDO = customerMapper.selectOne(CustomerDO::getUserId, userId);
|
||||
String status = customerDO.getStatus();
|
||||
if("0".equals(status)){
|
||||
throw exception(CUSTOMER_LOGIN_STATUS_DISABLE);
|
||||
}
|
||||
CustomerInfoVO infoVO = new CustomerInfoVO();
|
||||
SafeUseUtil.copyProperties(customerDO,infoVO);
|
||||
CustomerAddressDO addressDO = new CustomerAddressDO();
|
||||
addressDO.setCustomerId(customerDO.getId());
|
||||
addressDO.setDeleted(false);
|
||||
QueryWrapper<CustomerAddressDO> queryWrapper = MybatisPlusUtil.buildQuery(addressDO);
|
||||
queryWrapper.orderByDesc("is_default");
|
||||
List<CustomerAddressDO> list = customerAddressMapper.selectList(queryWrapper);
|
||||
List<AddressInfoVO> addressInfos = new ArrayList<>();
|
||||
for (CustomerAddressDO aDo : list) {
|
||||
AddressInfoVO infoVO1 = new AddressInfoVO(aDo);
|
||||
addressInfos.add(infoVO1);
|
||||
}
|
||||
infoVO.setAddressList(addressInfos);
|
||||
|
||||
return infoVO;
|
||||
}
|
||||
|
||||
private void createCustomerAddressList(Long customerId, List<CustomerAddressDO> list) {
|
||||
list.forEach(o -> o.setCustomerId(customerId));
|
||||
customerAddressMapper.insertBatch(list);
|
||||
|
|
@ -230,4 +261,23 @@ public class CustomerServiceImpl implements CustomerService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可以使用客户
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return {@link CustomerDO }
|
||||
*/
|
||||
@Override
|
||||
public CustomerDO getCanUseCustomer(Long userId) {
|
||||
LambdaQueryWrapper<CustomerDO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomerDO::getUserId, userId);
|
||||
queryWrapper.eq(CustomerDO::getDeleted, false);
|
||||
queryWrapper.orderByDesc(BaseDO::getCreateTime);
|
||||
CustomerDO customerDO = customerMapper.selectOne(queryWrapper,false);
|
||||
AssertUtil.isEmpty(customerDO,CUSTOMER_NOT_EXISTS.getMsg());
|
||||
String status = customerDO.getStatus();
|
||||
AssertUtil.isFalse(status.equals("1"), CUSTOMER_LOGIN_STATUS_DISABLE.getMsg());
|
||||
return customerDO;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -53,4 +53,12 @@ public interface DraftDesignDataService {
|
|||
PageResult<DraftDesignDataDO> getDraftDesignDataPage(DraftDesignDataPageReqVO pageReqVO);
|
||||
|
||||
String getNewCode();
|
||||
|
||||
/**
|
||||
* 更新产品计数
|
||||
*
|
||||
* @param id ID
|
||||
* @return {@link Integer }
|
||||
*/
|
||||
Boolean updateProductCount(String id);
|
||||
}
|
||||
|
|
@ -3,21 +3,23 @@ package cn.hangtag.module.oms.service.draftdesigndata;
|
|||
import cn.hangtag.framework.common.exception.ServiceException;
|
||||
import cn.hangtag.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import cn.hangtag.framework.common.util.FuncUtil;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.MybatisPlusUtil;
|
||||
import cn.hangtag.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.brand.BrandDO;
|
||||
import cn.hangtag.module.oms.dal.dataobject.productinfo.ProductInfoDO;
|
||||
import cn.hangtag.module.oms.dal.mysql.productinfo.ProductInfoMapper;
|
||||
import cn.hangtag.module.oms.serialnumber.CodingRulesUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import cn.hangtag.module.oms.controller.admin.draftdesigndata.vo.*;
|
||||
import cn.hangtag.module.oms.dal.dataobject.draftdesigndata.DraftDesignDataDO;
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
import cn.hangtag.framework.common.pojo.PageParam;
|
||||
import cn.hangtag.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.hangtag.module.oms.dal.mysql.draftdesigndata.DraftDesignDataMapper;
|
||||
|
|
@ -33,10 +35,11 @@ import static cn.hangtag.module.oms.enums.ErrorCodeConstants.*;
|
|||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class DraftDesignDataServiceImpl implements DraftDesignDataService {
|
||||
|
||||
@Resource
|
||||
private DraftDesignDataMapper draftDesignDataMapper;
|
||||
private final DraftDesignDataMapper draftDesignDataMapper;
|
||||
private final ProductInfoMapper productInfoMapper;
|
||||
|
||||
@Override
|
||||
public Long createDraftDesignData(DraftDesignDataSaveReqVO createReqVO) {
|
||||
|
|
@ -98,6 +101,27 @@ public class DraftDesignDataServiceImpl implements DraftDesignDataService {
|
|||
return draftDesignDataMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateProductCount(String id) {
|
||||
|
||||
List<Long> list = FuncUtil.toLongList(",", id);
|
||||
for (Long draftId : list) {
|
||||
ProductInfoDO productInfoDO = new ProductInfoDO();
|
||||
productInfoDO.setDraftDesignDataId(draftId.toString());
|
||||
QueryWrapper<ProductInfoDO> queryWrapper = MybatisPlusUtil.buildQuery("draft_design_data_id@inSet", productInfoDO);
|
||||
|
||||
|
||||
Long l = productInfoMapper.selectCount(queryWrapper);
|
||||
int count = FuncUtil.toInt(l, 0);
|
||||
// 更新数量
|
||||
DraftDesignDataDO designDataDO = new DraftDesignDataDO();
|
||||
designDataDO.setId(draftId);
|
||||
designDataDO.setProductCount(count);
|
||||
draftDesignDataMapper.updateById(designDataDO);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String getNewCode() {
|
||||
String s = "";
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package cn.hangtag.module.oms.service.productinfo;
|
||||
|
||||
import java.util.*;
|
||||
import javax.validation.*;
|
||||
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryFilterInfo;
|
||||
import cn.hangtag.module.oms.controller.admin.productinfo.vo.*;
|
||||
import cn.hangtag.module.oms.dal.dataobject.productinfo.ProductInfoDO;
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
import cn.hangtag.framework.common.pojo.PageParam;
|
||||
|
||||
/**
|
||||
* 产品资料 Service 接口
|
||||
|
|
@ -52,6 +53,8 @@ public interface ProductInfoService {
|
|||
*/
|
||||
PageResult<ProductInfoDO> getProductInfoPage(ProductInfoPageReqVO pageReqVO);
|
||||
|
||||
PageResult<ProductInfoDO> queryPage(QueryFilterInfo<ProductInfoPageReqVO> queryFilterInfo);
|
||||
|
||||
/**
|
||||
* 获取编码
|
||||
*
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package cn.hangtag.module.oms.service.productinfo;
|
|||
import cn.hangtag.framework.common.exception.ServiceException;
|
||||
import cn.hangtag.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import cn.hangtag.framework.common.util.FuncUtil;
|
||||
|
||||
import cn.hangtag.framework.mybatis.build.QueryFilterInfo;
|
||||
import cn.hangtag.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.hangtag.module.oms.base.dal.dataobject.producttype.ProductTypeDO;
|
||||
import cn.hangtag.module.oms.base.dal.mysql.producttype.ProductTypeMapper;
|
||||
|
|
@ -14,7 +16,11 @@ import cn.hangtag.module.oms.dal.dataobject.productprocess.ProductProcessDO;
|
|||
import cn.hangtag.module.oms.dal.mysql.brand.BrandMapper;
|
||||
import cn.hangtag.module.oms.dal.mysql.productprocess.ProductProcessMapper;
|
||||
import cn.hangtag.module.oms.serialnumber.CodingRulesUtils;
|
||||
import cn.hangtag.module.oms.service.brand.BrandService;
|
||||
import cn.hangtag.module.oms.service.draftdesigndata.DraftDesignDataService;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
|
@ -51,8 +57,11 @@ public class ProductInfoServiceImpl implements ProductInfoService {
|
|||
private final BrandMapper brandMapper;
|
||||
private final ProductTypeMapper productTypeMapper;
|
||||
private final ProductProcessMapper productProcessMapper;
|
||||
private final BrandService brandService;
|
||||
private final DraftDesignDataService draftDesignDataService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createProductInfo(ProductInfoSaveReqVO createReqVO) {
|
||||
// 插入
|
||||
ProductInfoDO productInfo = BeanUtils.toBean(createReqVO, ProductInfoDO.class);
|
||||
|
|
@ -77,13 +86,17 @@ public class ProductInfoServiceImpl implements ProductInfoService {
|
|||
}
|
||||
productProcessMapper.insertBatch(subList);
|
||||
}
|
||||
brandService.updateProductCount(productInfo.getBrandId());
|
||||
draftDesignDataService.updateProductCount(productInfo.getDraftDesignDataId());
|
||||
return productInfo.getId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateProductInfo(ProductInfoSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateProductInfoExists(updateReqVO.getId());
|
||||
ProductInfoDO productInfoDO = validateProductInfoExists(updateReqVO.getId());
|
||||
|
||||
String code = updateReqVO.getCode();
|
||||
if(FuncUtil.isNotEmpty(code)){
|
||||
|
|
@ -118,20 +131,35 @@ public class ProductInfoServiceImpl implements ProductInfoService {
|
|||
// 更新
|
||||
ProductInfoDO updateObj = BeanUtils.toBean(updateReqVO, ProductInfoDO.class);
|
||||
productInfoMapper.updateById(updateObj);
|
||||
if (!FuncUtil.equals(productInfoDO.getBrandId(),updateReqVO.getBrandId())) {
|
||||
// 产品的品牌发生变化时
|
||||
brandService.updateProductCount(updateReqVO.getBrandId());
|
||||
brandService.updateProductCount(productInfoDO.getBrandId());
|
||||
}
|
||||
if (!FuncUtil.equals(productInfoDO.getDraftDesignDataId(),updateReqVO.getDraftDesignDataId())) {
|
||||
// 产品的品牌发生变化时
|
||||
draftDesignDataService.updateProductCount(productInfoDO.getDraftDesignDataId());
|
||||
draftDesignDataService.updateProductCount(updateReqVO.getDraftDesignDataId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProductInfo(Long id) {
|
||||
// 校验存在
|
||||
validateProductInfoExists(id);
|
||||
ProductInfoDO productInfoDO = validateProductInfoExists(id);
|
||||
// 删除
|
||||
productInfoMapper.deleteById(id);
|
||||
brandService.updateProductCount(productInfoDO.getBrandId());
|
||||
draftDesignDataService.updateProductCount(productInfoDO.getDraftDesignDataId());
|
||||
}
|
||||
|
||||
private void validateProductInfoExists(Long id) {
|
||||
if (productInfoMapper.selectById(id) == null) {
|
||||
private ProductInfoDO validateProductInfoExists(Long id) {
|
||||
ProductInfoDO productInfoDO = productInfoMapper.selectById(id);
|
||||
if (productInfoDO == null) {
|
||||
throw exception(PRODUCT_INFO_NOT_EXISTS);
|
||||
}
|
||||
return productInfoDO;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -161,7 +189,30 @@ public class ProductInfoServiceImpl implements ProductInfoService {
|
|||
return productInfoDOPageResult;
|
||||
}
|
||||
|
||||
private void checkCode(Long id,String code){
|
||||
|
||||
@Override
|
||||
public PageResult<ProductInfoDO> queryPage(QueryFilterInfo<ProductInfoPageReqVO> queryFilterInfo) {
|
||||
PageResult<ProductInfoDO> productInfoDOPageResult = productInfoMapper.selectPagePlus(queryFilterInfo);
|
||||
List<ProductInfoDO> list = productInfoDOPageResult.getList();
|
||||
list.forEach(productInfoDO -> {
|
||||
if(FuncUtil.isNotEmpty(productInfoDO.getBrandId())){
|
||||
BrandDO brandDO = brandMapper.selectById(productInfoDO.getBrandId());
|
||||
if(FuncUtil.isNotEmpty(brandDO)){
|
||||
productInfoDO.setBrandName(brandDO.getName());
|
||||
}
|
||||
}
|
||||
if(FuncUtil.isNotEmpty(productInfoDO.getProductTypeId())){
|
||||
ProductTypeDO productTypeDO = productTypeMapper.selectById(productInfoDO.getProductTypeId());
|
||||
if(FuncUtil.isNotEmpty(productTypeDO)){
|
||||
productInfoDO.setProductTypeName(productTypeDO.getLabel());
|
||||
}
|
||||
}
|
||||
});
|
||||
productInfoDOPageResult.setList(list);
|
||||
return productInfoDOPageResult;
|
||||
}
|
||||
|
||||
private void checkCode(Long id, String code){
|
||||
if(FuncUtil.isNotEmpty(code)){
|
||||
LambdaQueryWrapper<ProductInfoDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.select(ProductInfoDO::getId,ProductInfoDO::getCode, BaseDO::getDeleted);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import javax.validation.*;
|
||||
|
||||
import cn.hangtag.module.oms.controller.admin.common.vo.DataComparisonRespVO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.dto.CreateSaleOrderDTO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.front.dto.CreateSaleOrderDTO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.vo.*;
|
||||
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderSummaryRespVO;
|
||||
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendReqVO;
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ import cn.hangtag.module.oms.common.utils.WKHtmlToPdfUtil;
|
|||
import cn.hangtag.module.oms.controller.admin.common.vo.DataComparisonRespVO;
|
||||
import cn.hangtag.module.oms.controller.admin.produceorder.vo.ProduceOrderSaveReqVO;
|
||||
import cn.hangtag.module.oms.controller.admin.product.vo.ProductPriceSaveReqVO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.dto.CreateSaleOrderDTO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.dto.SaleOrderEntryItemDTO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.dto.SaleOrderSkuDTO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.front.dto.CreateSaleOrderDTO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.front.dto.SaleOrderEntryItemDTO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.front.dto.SaleOrderSkuDTO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderPageReqVO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderRemarkReqVO;
|
||||
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderSaveReqVO;
|
||||
|
|
@ -52,8 +52,6 @@ import cn.hutool.core.date.DateUtil;
|
|||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.Snowflake;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
|
|
@ -66,7 +64,6 @@ import org.springframework.validation.annotation.Validated;
|
|||
import org.thymeleaf.TemplateEngine;
|
||||
import org.thymeleaf.context.Context;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.File;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.hangtag.module.oms.dal.mysql.customer.CustomerAddressMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
<update id="restDefaultAddress" parameterType="java.lang.Long">
|
||||
update oms_customer_address set is_default = 0 where customer_id = #{customerId}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -16,6 +16,7 @@ public interface ErrorCodeConstants {
|
|||
ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1_002_000_005, "未绑定账号,需要进行绑定");
|
||||
ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1_002_000_006, "Token 已经过期");
|
||||
ErrorCode AUTH_MOBILE_NOT_EXISTS = new ErrorCode(1_002_000_007, "手机号不存在");
|
||||
ErrorCode AUTH_USER_NOT_PERMISSION = new ErrorCode(1_002_000_008, "没有相关权限");
|
||||
|
||||
// ========== 菜单模块 1-002-001-000 ==========
|
||||
ErrorCode MENU_NAME_DUPLICATE = new ErrorCode(1_002_001_000, "已经存在该名字的菜单");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import request from '@/config/axios'
|
||||
import {data} from "autoprefixer";
|
||||
|
||||
// 产品资料 VO
|
||||
export interface ProductInfoVO {
|
||||
|
|
@ -26,6 +27,10 @@ export const ProductInfoApi = {
|
|||
getProductInfoPage: async (params: any) => {
|
||||
return await request.get({ url: `/oms/product-info/page`, params })
|
||||
},
|
||||
// 查询产品资料 分页
|
||||
queryPage: async (params: any) => {
|
||||
return await request.post({ url: `/oms/product-info/query`, data:{...params}})
|
||||
},
|
||||
|
||||
// 查询产品资料 详情
|
||||
getProductInfo: async (id: number) => {
|
||||
|
|
|
|||
|
|
@ -57,34 +57,37 @@
|
|||
v-loading="loading"
|
||||
:src="that.previewUrl"/>
|
||||
</div>
|
||||
|
||||
<div style="width: 100%" v-if="that.propOrderByList && that.propOrderByList.length > 0">
|
||||
<el-scrollbar height="600px">
|
||||
<el-form label-width="180px">
|
||||
<el-form-item label="风格主题" v-show="that.draftDesignList.length > 1">
|
||||
<div class="flex ml-3">
|
||||
<div>
|
||||
<el-select class="min-w-100" v-model="that.draftDesignId" @change="changeType">
|
||||
<el-option
|
||||
v-for="(item) in that.draftDesignList"
|
||||
:key="item.id"
|
||||
:label="item.label"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
<div class="flex flex-col">
|
||||
<div>
|
||||
<el-form label-width="180px">
|
||||
<el-form-item label="风格样式" v-show="that.draftDesignList.length > 1">
|
||||
<div class="flex ml-3">
|
||||
<div>
|
||||
<el-select class="min-w-100" v-model="that.draftDesignId" @change="changeType">
|
||||
<el-option
|
||||
v-for="(item) in that.draftDesignList"
|
||||
:key="item.id"
|
||||
:label="item.label"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
v-for="(tmp) in that.propOrderByList"
|
||||
:key="tmp.key"
|
||||
:label="getLabelName(that.propInfo[tmp.key])">
|
||||
<div
|
||||
v-if="that.propInfo[tmp.key].multiLanguage && that.propInfo[tmp.key].shape === ShapeType.vueTextCell">
|
||||
<div
|
||||
style="padding: 4px">
|
||||
<div style="display: flex;align-items: center;">
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div style="width: 100%" v-if="that.propOrderByList && that.propOrderByList.length > 0">
|
||||
<el-scrollbar height="600px">
|
||||
<el-form label-width="180px">
|
||||
<el-form-item
|
||||
v-for="(tmp) in that.propOrderByList"
|
||||
:key="tmp.key"
|
||||
:label="getLabelName(that.propInfo[tmp.key])">
|
||||
<div
|
||||
v-if="that.propInfo[tmp.key].multiLanguage && that.propInfo[tmp.key].shape === ShapeType.vueTextCell">
|
||||
<div
|
||||
style="padding: 4px">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<span>
|
||||
<i
|
||||
v-if="that.propInfo[tmp.key].canInput"
|
||||
|
|
@ -93,56 +96,56 @@
|
|||
<i v-else class="icon-lk_cell_add" style="font-size: 20px"> </i>
|
||||
</span>
|
||||
|
||||
<el-select-v2
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].showLabel"
|
||||
filterable
|
||||
:options="getIngredientInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeData(-1,tmp.key)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
/>
|
||||
<div v-if="that.propInfo[tmp.key].groupType === '1'">
|
||||
<div
|
||||
style="display: flex;align-items: center; margin-left: 10px; width: 220px">
|
||||
<el-row>
|
||||
<el-col span="4">
|
||||
<div>占比</div>
|
||||
</el-col>
|
||||
<el-col span="14">
|
||||
<el-input-number
|
||||
:min="-1" :max="100"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].ratio"
|
||||
@change="changeData(0,tmp.key)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col span="4">
|
||||
<div> %</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-select-v2
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].showLabel"
|
||||
filterable
|
||||
:options="getIngredientInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeData(-1,tmp.key)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
/>
|
||||
<div v-if="that.propInfo[tmp.key].groupType === '1'">
|
||||
<div
|
||||
style="display: flex;align-items: center; margin-left: 10px; width: 220px">
|
||||
<el-row>
|
||||
<el-col span="4">
|
||||
<div>占比</div>
|
||||
</el-col>
|
||||
<el-col span="14">
|
||||
<el-input-number
|
||||
:min="-1" :max="100"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].ratio"
|
||||
@change="changeData(0,tmp.key)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col span="4">
|
||||
<div> %</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div v-else-if="!that.propInfo[tmp.key].isCombo">
|
||||
<div
|
||||
v-for="(text,index) in that.propInfo[tmp.key].dataInfo"
|
||||
:key="index"
|
||||
style="padding: 4px">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<div v-else-if="!that.propInfo[tmp.key].isCombo">
|
||||
<div
|
||||
v-for="(text,index) in that.propInfo[tmp.key].dataInfo"
|
||||
:key="index"
|
||||
style="padding: 4px">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<span>
|
||||
<i
|
||||
v-if="that.propInfo[tmp.key].canInput"
|
||||
|
|
@ -150,111 +153,113 @@
|
|||
style="font-size: 20px"> </i>
|
||||
<i v-else class="icon-lk_cell_add" style="font-size: 20px"> </i>
|
||||
</span>
|
||||
<el-autocomplete
|
||||
v-if="that.propInfo[tmp.key].canInput"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].showLabel"
|
||||
:fetch-suggestions="querySearch"
|
||||
clearable
|
||||
class="inline-input w-50"
|
||||
placeholder="Please Input"
|
||||
@change="changeData"
|
||||
@select="changeData"
|
||||
/>
|
||||
<el-autocomplete
|
||||
v-if="that.propInfo[tmp.key].canInput"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].showLabel"
|
||||
:fetch-suggestions="querySearch"
|
||||
clearable
|
||||
class="inline-input w-50"
|
||||
placeholder="Please Input"
|
||||
@change="changeData"
|
||||
@select="changeData"
|
||||
/>
|
||||
|
||||
<el-select-v2
|
||||
v-else
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].showLabel"
|
||||
filterable
|
||||
:options="getIngredientInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeData(index,tmp.key)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
/>
|
||||
<div v-if="that.propInfo[tmp.key].groupType === '1'">
|
||||
<el-select-v2
|
||||
v-else
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].showLabel"
|
||||
filterable
|
||||
:options="getIngredientInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeData(index,tmp.key)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
/>
|
||||
<div v-if="that.propInfo[tmp.key].groupType === '1'">
|
||||
|
||||
<div
|
||||
style="display: flex;align-items: center; margin-left: 10px; width: 220px">
|
||||
<el-row>
|
||||
<el-col span="4">
|
||||
<div>占比</div>
|
||||
</el-col>
|
||||
<el-col span="14">
|
||||
<el-input-number
|
||||
:min="-1" :max="100"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].ratio"
|
||||
@change="changeData(index,tmp.key)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col span="4">
|
||||
<div> %</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div
|
||||
style="display: flex;align-items: center; margin-left: 10px; width: 220px">
|
||||
<el-row>
|
||||
<el-col span="4">
|
||||
<div>占比</div>
|
||||
</el-col>
|
||||
<el-col span="14">
|
||||
<el-input-number
|
||||
:min="-1" :max="100"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].ratio"
|
||||
@change="changeData(index,tmp.key)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col span="4">
|
||||
<div> %</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div v-else-if="that.propInfo[tmp.key].shape === ShapeType.vueShapeImage">
|
||||
<div
|
||||
v-for="(img,index) in that.propInfo[tmp.key].dataInfo"
|
||||
:key="index" style="display: flex">
|
||||
<div class="img-box" v-if="img.url">
|
||||
<div style="display: flex">
|
||||
<img :src="img.url" width="60px" height="60px"/>
|
||||
<el-select-v2
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].showLabel"
|
||||
filterable
|
||||
:options="washingInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeComboData(that.propInfo[tmp.key],that.propInfo[tmp.key].dataInfo[0].showLabel)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
>
|
||||
<template #default="{ item }">
|
||||
<div style="display: flex;">
|
||||
<img :src="item.url" width="30px" height="30px"/>
|
||||
<span>
|
||||
<div v-else-if="that.propInfo[tmp.key].shape === ShapeType.vueShapeImage">
|
||||
<div
|
||||
v-for="(img,index) in that.propInfo[tmp.key].dataInfo"
|
||||
:key="index" style="display: flex">
|
||||
<div class="img-box" v-if="img.url">
|
||||
<div style="display: flex">
|
||||
<img :src="img.url" width="60px" height="60px"/>
|
||||
<el-select-v2
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].showLabel"
|
||||
filterable
|
||||
:options="washingInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeComboData(that.propInfo[tmp.key],that.propInfo[tmp.key].dataInfo[0].showLabel)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
>
|
||||
<template #default="{ item }">
|
||||
<div style="display: flex;">
|
||||
<img :src="item.url" width="30px" height="30px"/>
|
||||
<span>
|
||||
{{ item.label }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-select-v2>
|
||||
</div>
|
||||
</template>
|
||||
</el-select-v2>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="img.label">
|
||||
<el-input v-model="img.label" disabled/>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="img.label">
|
||||
<el-input v-model="img.label" disabled/>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
|
@ -520,7 +525,7 @@ const previewByProductId = async (id: string | number, propData = {}, defDraftDe
|
|||
console.log("prodRes", prodRes)
|
||||
that.draftDesignList = JSON.parse(prodRes.draftDesignList, '[]')
|
||||
that.draftDesignId = defDraftDesignId || prodRes.draftDesignDataId
|
||||
await previewByDraftDesignId(that.draftDesignId, propData)
|
||||
await previewByDraftDesignId(that.draftDesignId.split(',')[0], propData)
|
||||
}
|
||||
}
|
||||
const loadConfig = (config: object, propData = {}) => {
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ const uploadInfo = async ()=>{
|
|||
}
|
||||
const addNew = async () => {
|
||||
for (let i = 0; i < fileList.value.length; i++) {
|
||||
const base64Info = await convertImageToBase64(fileList.value[i].url as string)
|
||||
// const base64Info = await convertImageToBase64(fileList.value[i].url as string)
|
||||
let info ={
|
||||
key: ShapeType.vueShapeImage,
|
||||
shape: ShapeType.vueShapeImage,
|
||||
|
|
@ -173,11 +173,11 @@ const addNew = async () => {
|
|||
shape: VueCellShapeType.Image,
|
||||
style: {
|
||||
shape:{
|
||||
href: base64Info,
|
||||
href: fileList.value[i].url,
|
||||
},
|
||||
}
|
||||
},
|
||||
icon: base64Info,
|
||||
icon: fileList.value[i].url,
|
||||
//@ts-ignore
|
||||
label: fileList.value[i].filename || '未命名图片',
|
||||
filterKeyword: function (){ return this.label }
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@
|
|||
>
|
||||
<template #title>
|
||||
<div>
|
||||
Setting
|
||||
页面配置
|
||||
</div>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-form>
|
||||
<div>
|
||||
<div>
|
||||
<el-form-item label="backgroundColor">
|
||||
<el-form-item label="背景颜色">
|
||||
<ColorPickerTool
|
||||
v-model="that.pageConfig.background.areaColor"
|
||||
:uuid="`background.areaColor`"
|
||||
|
|
@ -26,21 +26,21 @@
|
|||
</el-form-item>
|
||||
</div>
|
||||
<div>
|
||||
<div style="width: 150px;">
|
||||
<div>
|
||||
width
|
||||
<div style="width: 300px;">
|
||||
<div style="display: flex;align-items: center">
|
||||
<span style="padding: 4px">宽</span>
|
||||
<el-input-number
|
||||
v-model="that.pageConfig.editArea.width"
|
||||
@change="changePageConfig"/>
|
||||
@change="changePageConfig"/>mm
|
||||
</div>
|
||||
<div>
|
||||
height
|
||||
<div style="display: flex;align-items: center">
|
||||
<span style="padding: 4px">高</span>
|
||||
<el-input-number
|
||||
v-model="that.pageConfig.editArea.height"
|
||||
@change="changePageConfig"/>
|
||||
@change="changePageConfig"/>mm
|
||||
</div>
|
||||
<div>
|
||||
onLoadZoom
|
||||
<div style="display: flex;align-items: center">
|
||||
<div style="padding: 4px">加载缩放比</div>
|
||||
<el-input-number
|
||||
:min="0.1"
|
||||
:max="10"
|
||||
|
|
@ -132,7 +132,7 @@
|
|||
<div
|
||||
style="margin-left: 6px;display: flex;flex-wrap: wrap;align-items: center;height: 100%;max-width: 900px">
|
||||
<div>
|
||||
<el-button @click="that.showDialog = true" :title="Setting">Settings</el-button>
|
||||
<el-button @click="that.showDialog = true" title="页面设置">页面设置</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button @click="that.showOrderByDialog= true" :title="'属性排序'">
|
||||
|
|
@ -298,7 +298,7 @@
|
|||
:width="60"
|
||||
:effect="that.effect"
|
||||
trigger="hover"
|
||||
content="FillColor"
|
||||
content="填充颜色"
|
||||
>
|
||||
<template #reference>
|
||||
<div>
|
||||
|
|
@ -324,7 +324,7 @@
|
|||
:width="60"
|
||||
:effect="that.effect"
|
||||
trigger="hover"
|
||||
content="lineColor"
|
||||
content="边框颜色"
|
||||
>
|
||||
<template #reference>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -12,13 +12,12 @@
|
|||
transform-origin: left top;
|
||||
transform: scale(0.1); "
|
||||
:style="svgStyle"
|
||||
|
||||
>
|
||||
|
||||
<image
|
||||
:href="cellInfo.style.shape.href" x="0" y="0"
|
||||
:href="hrefBase64 || cellInfo.style.shape.href" x="0" y="0"
|
||||
style="width: 100%;height: 100%;"
|
||||
:stroke="cellInfo.style.shape.strokeColor"
|
||||
:stroke-width="cellInfo.style.shape.strokeWidth"
|
||||
:fill="cellInfo.style.shape.fillColor"
|
||||
:fill-opacity="cellInfo.style.shape.fillOpacity"
|
||||
:stroke-dasharray="cellInfo.style.shape.strokeDasharray"
|
||||
:stroke-dashoffset="cellInfo.style.shape.strokeDashoffset"
|
||||
|
|
@ -27,7 +26,6 @@
|
|||
:clip-path="cellInfo.style.shape.clipPath"
|
||||
:filter="cellInfo.style.shape.filter"
|
||||
/>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -60,11 +58,12 @@ export default defineComponent({
|
|||
svgStyle() {
|
||||
const res = {
|
||||
borderRadius: '',
|
||||
backgroundColor : this.cellInfo.style.shape.fillColor || "",
|
||||
width: `1000px`,
|
||||
height: `1000px`,
|
||||
transform: ''
|
||||
}
|
||||
const tmp = Math.min(this.sizeWInfo.width, this.sizeWInfo.height) - (this.cellInfo.style.shape.strokeWidth * 2)
|
||||
// const tmp = Math.min(this.sizeWInfo.width, this.sizeWInfo.height) - (this.cellInfo.style.shape.strokeWidth * 2)
|
||||
const w = (Math.max(this.sizeWInfo.width, 0)) / 1000;
|
||||
const h = (Math.max(this.sizeWInfo.height, 0)) / 1000;
|
||||
res.transform = `scaleX(${w}) scaleY(${h})`
|
||||
|
|
@ -108,7 +107,7 @@ export default defineComponent({
|
|||
y: 0, // 矩形左上角的 y 坐标
|
||||
rx: 0, // 矩形的圆角 x 半径
|
||||
ry: 0, // 矩形的圆角 y 半径
|
||||
fillColor: '#000000', // 填充颜色
|
||||
fillColor: '', // 填充颜色
|
||||
fillOpacity: '', // 填充颜色的不透明度
|
||||
href: '',
|
||||
hrefBase64: null,
|
||||
|
|
@ -116,8 +115,6 @@ export default defineComponent({
|
|||
strokeDashoffset: '', // 虚线起始偏移量
|
||||
strokeLinecap: undefined, // 线段末端的样式:"round" | "butt" | "square" | "inherit" | undefined
|
||||
strokeLinejoin: undefined, // 线段连接处的样式:"round" | "inherit" | "miter" | "bevel" | undefined
|
||||
strokeColor: '', // 描边颜色
|
||||
strokeWidth: 0, // 描边宽度
|
||||
strokeDasharray: '', // 虚线模式
|
||||
bottom: 0, // 元素的底部位置(用于定位)
|
||||
transform: '', // 应用到元素的变换(如平移、旋转、缩放)
|
||||
|
|
@ -246,8 +243,6 @@ export default defineComponent({
|
|||
strokeDashoffset: '', // 虚线起始偏移量
|
||||
strokeLinecap: undefined, // 线段末端的样式:"round" | "butt" | "square" | "inherit" | undefined
|
||||
strokeLinejoin: undefined, // 线段连接处的样式:"round" | "inherit" | "miter" | "bevel" | undefined
|
||||
strokeColor: '#000000', // 描边颜色
|
||||
strokeWidth: 0, // 描边宽度
|
||||
strokeDasharray: '', // 虚线模式
|
||||
bottom: 0, // 元素的底部位置(用于定位)
|
||||
transform: '', // 应用到元素的变换(如平移、旋转、缩放)
|
||||
|
|
@ -261,6 +256,7 @@ export default defineComponent({
|
|||
if(this.cellInfo.style.shape.href){
|
||||
convertImageToBase64(this.cellInfo.style.shape.href).then((res)=>{
|
||||
// @ts-ignore
|
||||
// 待优化 this.hrefBase64 = res
|
||||
this.cellInfo.style.shape.href = res
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
// filterConfig 格式name@like
|
||||
export const buildQuery = (params: object, options={}) => {
|
||||
const query = {
|
||||
"pager": {
|
||||
pageNo: params.pageNo || 1,
|
||||
pageSize: params.pageSize || 10
|
||||
},
|
||||
config:{
|
||||
"keywordSearch": "", // 搜索关键字 张三
|
||||
"keywordFields": "", // 搜索字段 name,code,summary
|
||||
"orderBy": "", // age desc;name asc
|
||||
...options,
|
||||
},
|
||||
"filter": {
|
||||
...params
|
||||
}
|
||||
}
|
||||
|
||||
console.log("@@@@",query)
|
||||
return query;
|
||||
}
|
||||
|
||||
|
|
@ -98,25 +98,70 @@
|
|||
<dict-tag :type="DICT_TYPE.BRAND_INDUSTRY_FIELD" :value="scope.row.brandField" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-hasPermi="['oms:product-info:create']"
|
||||
label="产品数量" align="center" prop="brandField">
|
||||
<template #default="scope">
|
||||
<router-link v-if="scope.row.productCount > 0"
|
||||
:to="'/base/product-info?brandId='+ scope.row.id">
|
||||
<el-button
|
||||
link
|
||||
type="primary">
|
||||
{{scope.row.productCount}}
|
||||
</el-button>
|
||||
</router-link>
|
||||
<router-link v-else :to="'/base/product-info?brandId='+scope.row.id+'&_add=1'">
|
||||
<el-button
|
||||
link
|
||||
type="primary">
|
||||
{{scope.row.productCount}}
|
||||
</el-button>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="官网" align="center" prop="website" />
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['oms:brand:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['oms:brand:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
<div class="flex">
|
||||
<div>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['oms:brand:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-hasPermi="['oms:product-info:create']">
|
||||
<router-link v-if="scope.row.productCount > 0 "
|
||||
|
||||
:to="'/base/product-info?brandId='+ scope.row.id">
|
||||
<el-button
|
||||
link
|
||||
type="primary">
|
||||
管理产品
|
||||
</el-button>
|
||||
</router-link>
|
||||
<router-link v-else :to="'/base/product-info?brandId='+scope.row.id+'&_add=1'">
|
||||
<el-button
|
||||
link
|
||||
type="primary">
|
||||
新增产品
|
||||
</el-button>
|
||||
</router-link>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['oms:brand:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
|
|||
|
|
@ -92,6 +92,20 @@
|
|||
<el-table-column label="id" align="center" prop="id" />
|
||||
<el-table-column label="编码" align="center" prop="code" width="200" />
|
||||
<el-table-column label="设计稿名称" align="center" prop="name" />
|
||||
<el-table-column
|
||||
v-hasPermi="['oms:product-info:create']"
|
||||
label="使用数量" align="center" prop="brandField">
|
||||
<template #default="scope">
|
||||
<router-link
|
||||
:to="'/base/product-info?draftDesignDataId='+ scope.row.id">
|
||||
<el-button
|
||||
link
|
||||
type="primary">
|
||||
{{scope.row.productCount}}
|
||||
</el-button>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="作者" align="center" prop="author" />
|
||||
<el-table-column label="启用状态" align="center" prop="enabled">
|
||||
<template #default="scope">
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.label" placeholder="请输入风格主色名称"/>
|
||||
<el-input name="auto_input@draftDesignList_label" autocomplete="on" clearable v-model="scope.row.label" placeholder="请输入风格主色名称"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark">
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.remark" placeholder="备注说明"/>
|
||||
<el-input clearable v-model="scope.row.remark" placeholder="备注说明"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
|
|
@ -251,6 +251,7 @@ import BrandDataListDialog from "@/components/Dialog/src/BrandDataListDialog/ind
|
|||
/** 产品资料 表单 */
|
||||
defineOptions({name: 'ProductInfoForm'})
|
||||
|
||||
const route = useRoute() // 路由
|
||||
const {t} = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
|
|
@ -275,7 +276,9 @@ const formData = ref({
|
|||
specSizeThk: 0,
|
||||
specMaterial: '',
|
||||
})
|
||||
|
||||
const that = reactive({
|
||||
brandId: undefined,
|
||||
draftDesignList: [{
|
||||
remark: '',
|
||||
label: '',
|
||||
|
|
@ -294,7 +297,7 @@ const that = reactive({
|
|||
const addRow = () => {
|
||||
that.draftDesignList.push({
|
||||
remark: '',
|
||||
label: '',
|
||||
label: '默认'+Math.random().toString(36).substring(2, 5),
|
||||
id: ''
|
||||
})
|
||||
}
|
||||
|
|
@ -356,6 +359,7 @@ const open = async (type: string, id?: number) => {
|
|||
type = type ? type : 'create'
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
that.brandId = route.query.brandId
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
|
|
@ -454,7 +458,7 @@ const submitForm = async () => {
|
|||
|
||||
data.draftDesignList = JSON.stringify(that.draftDesignList)
|
||||
// 作为默认的设计稿
|
||||
data.draftDesignDataId = ids[0];
|
||||
data.draftDesignDataId = ids.join(",");
|
||||
if (formType.value === 'create') {
|
||||
await ProductInfoApi.createProductInfo(data as ProductInfoVO)
|
||||
message.success(t('common.createSuccess'))
|
||||
|
|
@ -495,7 +499,7 @@ const resetForm = () => {
|
|||
code: undefined,
|
||||
name: undefined,
|
||||
cover: undefined,
|
||||
brandId: '',
|
||||
brandId: that.brandId || '',
|
||||
productTypeId: '',
|
||||
draftDesignDataId: undefined,
|
||||
draftDesignList: '',
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@
|
|||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="稿件" prop="remark">
|
||||
<DraftDesignDataListDialog v-model="queryParams.draftDesignDataId"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
|
|
@ -180,13 +183,14 @@ import download from '@/utils/download'
|
|||
import {ProductInfoApi, ProductInfoVO} from '@/api/oms/productinfo'
|
||||
import ProductInfoForm from './ProductInfoForm.vue'
|
||||
import {ProductTypeApi} from "@/api/base/producttype";
|
||||
import {buildQuery} from "@/utils/queryUtil";
|
||||
|
||||
/** 产品资料 列表 */
|
||||
defineOptions({name: 'ProductInfo'})
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const {t} = useI18n() // 国际化
|
||||
|
||||
const route = useRoute() // 路由
|
||||
const designPreviewDialogRef = ref()
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<ProductInfoVO[]>([]) // 列表的数据
|
||||
|
|
@ -205,6 +209,7 @@ const queryParams = reactive({
|
|||
details: undefined,
|
||||
createTime: [],
|
||||
})
|
||||
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
|
|
@ -212,7 +217,12 @@ const exportLoading = ref(false) // 导出的加载中
|
|||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await ProductInfoApi.getProductInfoPage(queryParams)
|
||||
const data = await ProductInfoApi.queryPage(buildQuery(queryParams,{
|
||||
easyOption: "create_time@between,name@like,code@like,draftDesignDataId@inSet",
|
||||
orderBy: 'create_time desc',
|
||||
ignoreField: "pageNo,pageSize"
|
||||
}))
|
||||
// const data = await ProductInfoApi.queryPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
|
|
@ -285,8 +295,20 @@ const init = async () => {
|
|||
})
|
||||
})
|
||||
}
|
||||
let first_load = true;
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
if(first_load){
|
||||
first_load = false;
|
||||
queryParams.brandId = route.query.brandId
|
||||
queryParams.draftDesignDataId = route.query.draftDesignDataId
|
||||
const tmp = route.query._add
|
||||
if(tmp == 1){
|
||||
// 删除 url的参数
|
||||
openForm('create')
|
||||
}
|
||||
}
|
||||
|
||||
getList();
|
||||
init();
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
import request from '@/config/axios'
|
||||
import {i18n} from "@/plugins/vueI18n";
|
||||
import {useAppStore} from "@/store/modules/app";
|
||||
const appStore = useAppStore()
|
||||
// 地址 API
|
||||
export const AddressApi = {
|
||||
|
||||
|
||||
// 获取当前用户的地址列表
|
||||
getCustomerAddressList: async (params: any) => {
|
||||
return await request.get({ url: `/front/oms/address/page`,params })
|
||||
},
|
||||
delAddress: async (id: number) => {
|
||||
return await request.delete({ url: `/front/oms/address/${id}` })
|
||||
},
|
||||
getAddressInfo: async (id: number) => {
|
||||
return await request.get({ url: `/front/oms/address/${id}`})
|
||||
},
|
||||
setDefaultAddress: async (id: number) => {
|
||||
return await request.put({ url: `/front/oms/address/default/${id}`})
|
||||
},
|
||||
// 提交表单数据
|
||||
submit: async (data: any) => {
|
||||
return await request.post({ url: `/front/oms/address/submit`, data })
|
||||
},
|
||||
getAreaTree: async () => {
|
||||
let type = 0;
|
||||
try {
|
||||
type = i18n.global.locale.value == "zh-CN" ? "1" : "0"
|
||||
}catch (e) {
|
||||
}
|
||||
return await request.get({ url: '/front/oms/address/area-tree/'+type })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -44,12 +44,18 @@ export const CustomerApi = {
|
|||
return await request.download({ url: `/oms/customer/export-excel`, params })
|
||||
},
|
||||
|
||||
// 查询当前登录客户
|
||||
getCustomerInfo: async () => {
|
||||
return await request.get({ url: `/front/oms/customer/info`})
|
||||
},
|
||||
// ==================== 子表(用户地址) ====================
|
||||
|
||||
// 获得用户地址列表
|
||||
getCustomerAddressListByCustomerId: async (customerId) => {
|
||||
return await request.get({ url: `/oms/customer/customer-address/list-by-customer-id?customerId=` + customerId })
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
<template>
|
||||
<Dialog :title="dialogTitle" append-to-body v-model="dialogVisible">
|
||||
<Form :disabled="disabled" ref="formRef" :schema="allSchemas.formSchema" :rules="rules" v-loading="formLoading" >
|
||||
<template #areaId="data">
|
||||
<div>
|
||||
<el-cascader
|
||||
v-model="data.areaId"
|
||||
:options="that.areaList"
|
||||
:props="defaultProps"
|
||||
class="w-1/1"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择城市"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<template #isDefault="data">
|
||||
<el-checkbox v-model="data.isDefault">默认</el-checkbox>
|
||||
</template>
|
||||
</Form>
|
||||
<template #footer>
|
||||
<el-button v-if="!disabled" @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { AddressApi } from '@/api/oms/customer/address'
|
||||
import { rules, allSchemas } from './config.data'
|
||||
import {defaultProps} from "@/utils/tree";
|
||||
import {UPDATE_ADDRESS} from "@/constants/EmitEventName";
|
||||
import {useEmitt} from "@/hooks/web/useEmitt";
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
const {emitter} = useEmitt();
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
const disabled = computed(() => {
|
||||
return formType.value !== 'create' && formType.value !== 'update'
|
||||
})
|
||||
const that = reactive({
|
||||
areaList: [],
|
||||
})
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
AddressApi.getAreaTree().then(res=>{
|
||||
that.areaList = res;
|
||||
})
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = await AddressApi.getAddressInfo(id)
|
||||
formRef.value.setValues(data)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
if (!formRef) return
|
||||
const valid = await formRef.value.getElFormRef().validate()
|
||||
if (!valid) return
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formRef.value.formModel
|
||||
await AddressApi.submit(data)
|
||||
message.success(t(data.id ? 'common.updateSuccess' :'common.createSuccess'))
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
emitter.emit(UPDATE_ADDRESS,{
|
||||
...data
|
||||
})
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import type { CrudSchema } from '@/hooks/web/useCrudSchemas'
|
||||
|
||||
// 表单校验
|
||||
export const rules = reactive({
|
||||
code: [required],
|
||||
name: [required],
|
||||
})
|
||||
|
||||
// CrudSchema https://doc.iocoder.cn/vue3/crud-schema/
|
||||
const crudSchemas = reactive<CrudSchema[]>([
|
||||
|
||||
{
|
||||
label: 'id',
|
||||
field: 'id',
|
||||
isForm: false,
|
||||
table: {
|
||||
show: false
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '名称',
|
||||
field: 'name',
|
||||
isSearch: true,
|
||||
},{
|
||||
label: '联系电话',
|
||||
field: 'phone',
|
||||
isSearch: true,
|
||||
},{
|
||||
label: '地区',
|
||||
field: 'areaId',
|
||||
table: {
|
||||
show: false
|
||||
},
|
||||
isSearch: false,
|
||||
},
|
||||
{
|
||||
label: '地址',
|
||||
field: 'address',
|
||||
isSearch: true,
|
||||
},
|
||||
{
|
||||
label: '默认地址',
|
||||
field: 'isDefault',
|
||||
isSearch: true,
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
width: '260px',
|
||||
label: '操作' ,
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
detail: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
])
|
||||
export const { allSchemas } = useCrudSchemas(crudSchemas)
|
||||
|
|
@ -0,0 +1,348 @@
|
|||
<template>
|
||||
<slot>
|
||||
<div>
|
||||
<el-input
|
||||
v-model="that.showValue"
|
||||
clearable
|
||||
:placeholder="props.placeholder"
|
||||
@clear="clearData"
|
||||
@click="viewDetails"
|
||||
>
|
||||
<template #append>
|
||||
<el-button @click.stop="openDialog">
|
||||
<Icon icon="ep:search"/>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</slot>
|
||||
{{tmp}}
|
||||
<Dialog
|
||||
:title="dialogTitle"
|
||||
width="80%"
|
||||
append-to-body
|
||||
v-model="that.visible"
|
||||
@close="updateVisible(false)">
|
||||
<div>
|
||||
<!-- 搜索工作栏 -->
|
||||
<ContentWrap>
|
||||
<Search
|
||||
:schema="allSchemas.searchSchema"
|
||||
:is-col="false"
|
||||
@search="setSearchParams"
|
||||
@reset="setSearchParams">
|
||||
<!-- 新增等操作按钮 -->
|
||||
<template #actionMore>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['oms:draft-design-data:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px"/>
|
||||
新增
|
||||
</el-button>
|
||||
</template>
|
||||
</Search>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<div class="flex justify-between items-center mb-10px">
|
||||
<div class="flex-1">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px"/>
|
||||
新增
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<Table
|
||||
:columns="allSchemas.tableColumns"
|
||||
:data="tableObject.tableList"
|
||||
:loading="tableObject.loading"
|
||||
:selection="true"
|
||||
ref="tableRef"
|
||||
@selection-change="selectionChange"
|
||||
:pagination="{
|
||||
total: tableObject.total
|
||||
}"
|
||||
v-model:pageSize="tableObject.pageSize"
|
||||
v-model:currentPage="tableObject.currentPage"
|
||||
>
|
||||
|
||||
<template #isDefault="{row}">
|
||||
<div>
|
||||
<div v-if="row.isDefault">
|
||||
{{t("size.default")}}
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="mini"
|
||||
@click="setDefault(row.id)">
|
||||
设为默认
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #action="{ row }">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', row.id)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(row.id)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</Table>
|
||||
</ContentWrap>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="updateVisible(false,true)">{{ t('common.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit">{{ t('common.ok') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</Dialog>
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<DataForm ref="formRef" @success="getList"/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="ProductInfoListDialog">
|
||||
import {allSchemas} from './config.data'
|
||||
import DataForm from './DataForm.vue'
|
||||
import {AddressApi} from "@/api/oms/customer/address";
|
||||
import {usePageLoading} from "@/hooks/web/usePageLoading";
|
||||
import {useEmitt} from "@/hooks/web/useEmitt";
|
||||
import {UPDATE_ADDRESS} from "@/constants/EmitEventName";
|
||||
|
||||
/** 稿件图片库 */
|
||||
defineOptions({name: 'AddressListDialog'})
|
||||
const emit = defineEmits(['update:modelValue', 'update:visible', 'submit']) // 定义 success 事件,用于操作成功后的回调
|
||||
const {t} = useI18n() // 国际化
|
||||
const {emitter} = useEmitt();
|
||||
const dialogTitle = ref('收货地址管理') // 弹窗的标题
|
||||
const pageLoading = usePageLoading();
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
dataKey: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'id'
|
||||
},
|
||||
showKey: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'name'
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '请选择'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '64px'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '64px'
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const that = reactive({
|
||||
inputVal: '',
|
||||
showValue: '',
|
||||
visible: false,
|
||||
areaList: [],
|
||||
})
|
||||
const setDefault = (id: number)=>{
|
||||
pageLoading.loadStart();
|
||||
AddressApi.setDefaultAddress(id).then(res=>{
|
||||
useMessage().success(t('common.success'))
|
||||
emitter.emit(UPDATE_ADDRESS,{
|
||||
id: id
|
||||
})
|
||||
getList();
|
||||
pageLoading.loadDone();
|
||||
})
|
||||
}
|
||||
const openDialog = () => {
|
||||
updateVisible(true);
|
||||
|
||||
}
|
||||
const viewDetails = () => {
|
||||
if (that.inputVal) {
|
||||
openForm("preview", that.inputVal.split(",")[0])
|
||||
} else {
|
||||
openDialog();
|
||||
}
|
||||
}
|
||||
// 用监听属性变化无其他意义
|
||||
const tmp = computed(()=>{
|
||||
setTimeout(()=>{
|
||||
that.inputVal = toStr(props.modelValue,that.inputVal)
|
||||
if (that.inputVal) {
|
||||
initInput();
|
||||
}
|
||||
},100)
|
||||
return ''
|
||||
},{
|
||||
deep: true
|
||||
})
|
||||
const toStr = (data: any) => {
|
||||
if (data !== null && data !== undefined) {
|
||||
return `${data}`
|
||||
}
|
||||
return data
|
||||
}
|
||||
let map = new Map();
|
||||
const initInput = async () => {
|
||||
const dataKey = that.inputVal + ',' + props.dataKey + ',' + props.showKey + ',' + props.multiple;
|
||||
if (map.has(dataKey)) {
|
||||
const data = map.get(dataKey)
|
||||
if (data) {
|
||||
that.inputVal = data.inputVal
|
||||
that.showValue = data.showValue
|
||||
console.log('缓存数据', data)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const ids = that.inputVal.split(",");
|
||||
|
||||
map.set(dataKey, {
|
||||
inputVal: that.inputVal,
|
||||
showValue: that.showValue
|
||||
})
|
||||
}
|
||||
watch(() => props.visible, (newVal) => {
|
||||
that.visible = newVal;
|
||||
})
|
||||
const clearData = () => {
|
||||
that.inputVal = '';
|
||||
that.showValue = '';
|
||||
updateValue();
|
||||
}
|
||||
const updateVisible = (visible: boolean, clearInput = false) => {
|
||||
that.visible = visible;
|
||||
if(that.visible){
|
||||
getList();
|
||||
}
|
||||
emit("update:visible", visible)
|
||||
if (clearInput) {
|
||||
clearData();
|
||||
}
|
||||
}
|
||||
|
||||
const submit = () => {
|
||||
updateValue();
|
||||
updateVisible(false)
|
||||
}
|
||||
const updateValue = () => {
|
||||
emit("update:modelValue", that.inputVal)
|
||||
}
|
||||
//
|
||||
const selectionChange = (row) => {
|
||||
if (row && row.length > 0) {
|
||||
if (props.multiple) {
|
||||
let valArr = [];
|
||||
let showArr = [];
|
||||
for (let i = 0; i < row.length; i++) {
|
||||
const tmp = row[i][props.dataKey || 'id']
|
||||
if(valArr.includes(tmp)){
|
||||
continue;
|
||||
}
|
||||
valArr.push( tmp)
|
||||
showArr.push(row[i][props.showKey || 'id'])
|
||||
}
|
||||
that.inputVal = valArr.join(',')
|
||||
that.showValue = showArr.join(',')
|
||||
} else {
|
||||
if (row.length > 1) {
|
||||
useMessage().warning('单选数据,已忽略其他')
|
||||
}
|
||||
that.showValue = row[row.length - 1][props.showKey || 'id']
|
||||
that.inputVal = row[row.length - 1][props.dataKey || 'id']
|
||||
}
|
||||
} else {
|
||||
that.inputVal = ''
|
||||
that.showValue = ''
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const {tableObject, tableMethods} = useTable({
|
||||
getListApi: AddressApi.getCustomerAddressList, // 分页接口
|
||||
delListApi: AddressApi.delAddress // 删除接口
|
||||
})
|
||||
// 获得表格的各种操作
|
||||
const {getList, setSearchParams} = tableMethods
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = (id: number) => {
|
||||
tableMethods.delList(id, false)
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
viewDetails
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
position: relative;
|
||||
|
||||
.el-input__inner {
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -57,34 +57,37 @@
|
|||
v-loading="loading"
|
||||
:src="that.previewUrl"/>
|
||||
</div>
|
||||
|
||||
<div style="width: 100%" v-if="that.propOrderByList && that.propOrderByList.length > 0">
|
||||
<el-scrollbar height="600px">
|
||||
<el-form label-width="180px">
|
||||
<el-form-item label="风格主题" v-show="that.draftDesignList.length > 1">
|
||||
<div class="flex ml-3">
|
||||
<div>
|
||||
<el-select class="min-w-100" v-model="that.draftDesignId" @change="changeType">
|
||||
<el-option
|
||||
v-for="(item) in that.draftDesignList"
|
||||
:key="item.id"
|
||||
:label="item.label"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
<div class="flex flex-col">
|
||||
<div>
|
||||
<el-form label-width="180px">
|
||||
<el-form-item label="风格样式" v-show="that.draftDesignList.length > 1">
|
||||
<div class="flex ml-3">
|
||||
<div>
|
||||
<el-select class="min-w-100" v-model="that.draftDesignId" @change="changeType">
|
||||
<el-option
|
||||
v-for="(item) in that.draftDesignList"
|
||||
:key="item.id"
|
||||
:label="item.label"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
v-for="(tmp) in that.propOrderByList"
|
||||
:key="tmp.key"
|
||||
:label="getLabelName(that.propInfo[tmp.key])">
|
||||
<div
|
||||
v-if="that.propInfo[tmp.key].multiLanguage && that.propInfo[tmp.key].shape === ShapeType.vueTextCell">
|
||||
<div
|
||||
style="padding: 4px">
|
||||
<div style="display: flex;align-items: center;">
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div style="width: 100%" v-if="that.propOrderByList && that.propOrderByList.length > 0">
|
||||
<el-scrollbar height="600px">
|
||||
<el-form label-width="180px">
|
||||
<el-form-item
|
||||
v-for="(tmp) in that.propOrderByList"
|
||||
:key="tmp.key"
|
||||
:label="getLabelName(that.propInfo[tmp.key])">
|
||||
<div
|
||||
v-if="that.propInfo[tmp.key].multiLanguage && that.propInfo[tmp.key].shape === ShapeType.vueTextCell">
|
||||
<div
|
||||
style="padding: 4px">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<span>
|
||||
<i
|
||||
v-if="that.propInfo[tmp.key].canInput"
|
||||
|
|
@ -93,56 +96,56 @@
|
|||
<i v-else class="icon-lk_cell_add" style="font-size: 20px"> </i>
|
||||
</span>
|
||||
|
||||
<el-select-v2
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].showLabel"
|
||||
filterable
|
||||
:options="getIngredientInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeData(-1,tmp.key)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
/>
|
||||
<div v-if="that.propInfo[tmp.key].groupType === '1'">
|
||||
<div
|
||||
style="display: flex;align-items: center; margin-left: 10px; width: 220px">
|
||||
<el-row>
|
||||
<el-col span="4">
|
||||
<div>占比</div>
|
||||
</el-col>
|
||||
<el-col span="14">
|
||||
<el-input-number
|
||||
:min="-1" :max="100"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].ratio"
|
||||
@change="changeData(0,tmp.key)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col span="4">
|
||||
<div> %</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-select-v2
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].showLabel"
|
||||
filterable
|
||||
:options="getIngredientInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeData(-1,tmp.key)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
/>
|
||||
<div v-if="that.propInfo[tmp.key].groupType === '1'">
|
||||
<div
|
||||
style="display: flex;align-items: center; margin-left: 10px; width: 220px">
|
||||
<el-row>
|
||||
<el-col span="4">
|
||||
<div>占比</div>
|
||||
</el-col>
|
||||
<el-col span="14">
|
||||
<el-input-number
|
||||
:min="-1" :max="100"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].ratio"
|
||||
@change="changeData(0,tmp.key)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col span="4">
|
||||
<div> %</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div v-else-if="!that.propInfo[tmp.key].isCombo">
|
||||
<div
|
||||
v-for="(text,index) in that.propInfo[tmp.key].dataInfo"
|
||||
:key="index"
|
||||
style="padding: 4px">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<div v-else-if="!that.propInfo[tmp.key].isCombo">
|
||||
<div
|
||||
v-for="(text,index) in that.propInfo[tmp.key].dataInfo"
|
||||
:key="index"
|
||||
style="padding: 4px">
|
||||
<div style="display: flex;align-items: center;">
|
||||
<span>
|
||||
<i
|
||||
v-if="that.propInfo[tmp.key].canInput"
|
||||
|
|
@ -150,111 +153,113 @@
|
|||
style="font-size: 20px"> </i>
|
||||
<i v-else class="icon-lk_cell_add" style="font-size: 20px"> </i>
|
||||
</span>
|
||||
<el-autocomplete
|
||||
v-if="that.propInfo[tmp.key].canInput"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].showLabel"
|
||||
:fetch-suggestions="querySearch"
|
||||
clearable
|
||||
class="inline-input w-50"
|
||||
placeholder="Please Input"
|
||||
@change="changeData"
|
||||
@select="changeData"
|
||||
/>
|
||||
<el-autocomplete
|
||||
v-if="that.propInfo[tmp.key].canInput"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].showLabel"
|
||||
:fetch-suggestions="querySearch"
|
||||
clearable
|
||||
class="inline-input w-50"
|
||||
placeholder="Please Input"
|
||||
@change="changeData"
|
||||
@select="changeData"
|
||||
/>
|
||||
|
||||
<el-select-v2
|
||||
v-else
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].showLabel"
|
||||
filterable
|
||||
:options="getIngredientInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeData(index,tmp.key)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
/>
|
||||
<div v-if="that.propInfo[tmp.key].groupType === '1'">
|
||||
<el-select-v2
|
||||
v-else
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].showLabel"
|
||||
filterable
|
||||
:options="getIngredientInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeData(index,tmp.key)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
/>
|
||||
<div v-if="that.propInfo[tmp.key].groupType === '1'">
|
||||
|
||||
<div
|
||||
style="display: flex;align-items: center; margin-left: 10px; width: 220px">
|
||||
<el-row>
|
||||
<el-col span="4">
|
||||
<div>占比</div>
|
||||
</el-col>
|
||||
<el-col span="14">
|
||||
<el-input-number
|
||||
:min="-1" :max="100"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].ratio"
|
||||
@change="changeData(index,tmp.key)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col span="4">
|
||||
<div> %</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div
|
||||
style="display: flex;align-items: center; margin-left: 10px; width: 220px">
|
||||
<el-row>
|
||||
<el-col span="4">
|
||||
<div>占比</div>
|
||||
</el-col>
|
||||
<el-col span="14">
|
||||
<el-input-number
|
||||
:min="-1" :max="100"
|
||||
v-model="that.propInfo[tmp.key].dataInfo[index].ratio"
|
||||
@change="changeData(index,tmp.key)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col span="4">
|
||||
<div> %</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div v-else-if="that.propInfo[tmp.key].shape === ShapeType.vueShapeImage">
|
||||
<div
|
||||
v-for="(img,index) in that.propInfo[tmp.key].dataInfo"
|
||||
:key="index" style="display: flex">
|
||||
<div class="img-box" v-if="img.url">
|
||||
<div style="display: flex">
|
||||
<img :src="img.url" width="60px" height="60px"/>
|
||||
<el-select-v2
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].showLabel"
|
||||
filterable
|
||||
:options="washingInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeComboData(that.propInfo[tmp.key],that.propInfo[tmp.key].dataInfo[0].showLabel)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
>
|
||||
<template #default="{ item }">
|
||||
<div style="display: flex;">
|
||||
<img :src="item.url" width="30px" height="30px"/>
|
||||
<span>
|
||||
<div v-else-if="that.propInfo[tmp.key].shape === ShapeType.vueShapeImage">
|
||||
<div
|
||||
v-for="(img,index) in that.propInfo[tmp.key].dataInfo"
|
||||
:key="index" style="display: flex">
|
||||
<div class="img-box" v-if="img.url">
|
||||
<div style="display: flex">
|
||||
<img :src="img.url" width="60px" height="60px"/>
|
||||
<el-select-v2
|
||||
v-model="that.propInfo[tmp.key].dataInfo[0].showLabel"
|
||||
filterable
|
||||
:options="washingInfoListByType(that.propInfo[tmp.key].groupType)"
|
||||
placeholder="Please select"
|
||||
@change="changeComboData(that.propInfo[tmp.key],that.propInfo[tmp.key].dataInfo[0].showLabel)"
|
||||
size="large"
|
||||
style="min-width: 280px;width: 100%"
|
||||
>
|
||||
<template #default="{ item }">
|
||||
<div style="display: flex;">
|
||||
<img :src="item.url" width="30px" height="30px"/>
|
||||
<span>
|
||||
{{ item.label }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-select-v2>
|
||||
</div>
|
||||
</template>
|
||||
</el-select-v2>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="img.label">
|
||||
<el-input v-model="img.label" disabled/>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="img.label">
|
||||
<el-input v-model="img.label" disabled/>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="deleteList(that.propInfo[tmp.key],index)">
|
||||
<i class="icon-lk_delete"> </i>
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="that.propInfo[tmp.key].canChange"
|
||||
@click="appendList(that.propInfo[tmp.key])">
|
||||
添加
|
||||
</el-button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
|
@ -520,7 +525,7 @@ const previewByProductId = async (id: string | number, propData = {}, defDraftDe
|
|||
console.log("prodRes", prodRes)
|
||||
that.draftDesignList = JSON.parse(prodRes.draftDesignList, '[]')
|
||||
that.draftDesignId = defDraftDesignId || prodRes.draftDesignDataId
|
||||
await previewByDraftDesignId(that.draftDesignId, propData)
|
||||
await previewByDraftDesignId(that.draftDesignId.split(',')[0], propData)
|
||||
}
|
||||
}
|
||||
const loadConfig = (config: object, propData = {}) => {
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ const uploadInfo = async ()=>{
|
|||
}
|
||||
const addNew = async () => {
|
||||
for (let i = 0; i < fileList.value.length; i++) {
|
||||
const base64Info = await convertImageToBase64(fileList.value[i].url as string)
|
||||
// const base64Info = await convertImageToBase64(fileList.value[i].url as string)
|
||||
let info ={
|
||||
key: ShapeType.vueShapeImage,
|
||||
shape: ShapeType.vueShapeImage,
|
||||
|
|
@ -173,11 +173,11 @@ const addNew = async () => {
|
|||
shape: VueCellShapeType.Image,
|
||||
style: {
|
||||
shape:{
|
||||
href: base64Info,
|
||||
href: fileList.value[i].url,
|
||||
},
|
||||
}
|
||||
},
|
||||
icon: base64Info,
|
||||
icon: fileList.value[i].url,
|
||||
//@ts-ignore
|
||||
label: fileList.value[i].filename || '未命名图片',
|
||||
filterKeyword: function (){ return this.label }
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@
|
|||
>
|
||||
<template #title>
|
||||
<div>
|
||||
Setting
|
||||
页面配置
|
||||
</div>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-form>
|
||||
<div>
|
||||
<div>
|
||||
<el-form-item label="backgroundColor">
|
||||
<el-form-item label="背景颜色">
|
||||
<ColorPickerTool
|
||||
v-model="that.pageConfig.background.areaColor"
|
||||
:uuid="`background.areaColor`"
|
||||
|
|
@ -26,21 +26,21 @@
|
|||
</el-form-item>
|
||||
</div>
|
||||
<div>
|
||||
<div style="width: 150px;">
|
||||
<div>
|
||||
width
|
||||
<div style="width: 300px;">
|
||||
<div style="display: flex;align-items: center">
|
||||
<span style="padding: 4px">宽</span>
|
||||
<el-input-number
|
||||
v-model="that.pageConfig.editArea.width"
|
||||
@change="changePageConfig"/>
|
||||
@change="changePageConfig"/>mm
|
||||
</div>
|
||||
<div>
|
||||
height
|
||||
<div style="display: flex;align-items: center">
|
||||
<span style="padding: 4px">高</span>
|
||||
<el-input-number
|
||||
v-model="that.pageConfig.editArea.height"
|
||||
@change="changePageConfig"/>
|
||||
@change="changePageConfig"/>mm
|
||||
</div>
|
||||
<div>
|
||||
onLoadZoom
|
||||
<div style="display: flex;align-items: center">
|
||||
<div style="padding: 4px">加载缩放比</div>
|
||||
<el-input-number
|
||||
:min="0.1"
|
||||
:max="10"
|
||||
|
|
@ -132,7 +132,7 @@
|
|||
<div
|
||||
style="margin-left: 6px;display: flex;flex-wrap: wrap;align-items: center;height: 100%;max-width: 900px">
|
||||
<div>
|
||||
<el-button @click="that.showDialog = true" :title="Setting">Settings</el-button>
|
||||
<el-button @click="that.showDialog = true" title="页面设置">页面设置</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button @click="that.showOrderByDialog= true" :title="'属性排序'">
|
||||
|
|
@ -298,7 +298,7 @@
|
|||
:width="60"
|
||||
:effect="that.effect"
|
||||
trigger="hover"
|
||||
content="FillColor"
|
||||
content="填充颜色"
|
||||
>
|
||||
<template #reference>
|
||||
<div>
|
||||
|
|
@ -324,7 +324,7 @@
|
|||
:width="60"
|
||||
:effect="that.effect"
|
||||
trigger="hover"
|
||||
content="lineColor"
|
||||
content="边框颜色"
|
||||
>
|
||||
<template #reference>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -12,13 +12,12 @@
|
|||
transform-origin: left top;
|
||||
transform: scale(0.1); "
|
||||
:style="svgStyle"
|
||||
|
||||
>
|
||||
|
||||
<image
|
||||
:href="cellInfo.style.shape.href" x="0" y="0"
|
||||
:href="hrefBase64 || cellInfo.style.shape.href" x="0" y="0"
|
||||
style="width: 100%;height: 100%;"
|
||||
:stroke="cellInfo.style.shape.strokeColor"
|
||||
:stroke-width="cellInfo.style.shape.strokeWidth"
|
||||
:fill="cellInfo.style.shape.fillColor"
|
||||
:fill-opacity="cellInfo.style.shape.fillOpacity"
|
||||
:stroke-dasharray="cellInfo.style.shape.strokeDasharray"
|
||||
:stroke-dashoffset="cellInfo.style.shape.strokeDashoffset"
|
||||
|
|
@ -27,7 +26,6 @@
|
|||
:clip-path="cellInfo.style.shape.clipPath"
|
||||
:filter="cellInfo.style.shape.filter"
|
||||
/>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -60,11 +58,12 @@ export default defineComponent({
|
|||
svgStyle() {
|
||||
const res = {
|
||||
borderRadius: '',
|
||||
backgroundColor : this.cellInfo.style.shape.fillColor || "",
|
||||
width: `1000px`,
|
||||
height: `1000px`,
|
||||
transform: ''
|
||||
}
|
||||
const tmp = Math.min(this.sizeWInfo.width, this.sizeWInfo.height) - (this.cellInfo.style.shape.strokeWidth * 2)
|
||||
// const tmp = Math.min(this.sizeWInfo.width, this.sizeWInfo.height) - (this.cellInfo.style.shape.strokeWidth * 2)
|
||||
const w = (Math.max(this.sizeWInfo.width, 0)) / 1000;
|
||||
const h = (Math.max(this.sizeWInfo.height, 0)) / 1000;
|
||||
res.transform = `scaleX(${w}) scaleY(${h})`
|
||||
|
|
@ -108,7 +107,7 @@ export default defineComponent({
|
|||
y: 0, // 矩形左上角的 y 坐标
|
||||
rx: 0, // 矩形的圆角 x 半径
|
||||
ry: 0, // 矩形的圆角 y 半径
|
||||
fillColor: '#000000', // 填充颜色
|
||||
fillColor: '', // 填充颜色
|
||||
fillOpacity: '', // 填充颜色的不透明度
|
||||
href: '',
|
||||
hrefBase64: null,
|
||||
|
|
@ -116,8 +115,6 @@ export default defineComponent({
|
|||
strokeDashoffset: '', // 虚线起始偏移量
|
||||
strokeLinecap: undefined, // 线段末端的样式:"round" | "butt" | "square" | "inherit" | undefined
|
||||
strokeLinejoin: undefined, // 线段连接处的样式:"round" | "inherit" | "miter" | "bevel" | undefined
|
||||
strokeColor: '', // 描边颜色
|
||||
strokeWidth: 0, // 描边宽度
|
||||
strokeDasharray: '', // 虚线模式
|
||||
bottom: 0, // 元素的底部位置(用于定位)
|
||||
transform: '', // 应用到元素的变换(如平移、旋转、缩放)
|
||||
|
|
@ -246,8 +243,6 @@ export default defineComponent({
|
|||
strokeDashoffset: '', // 虚线起始偏移量
|
||||
strokeLinecap: undefined, // 线段末端的样式:"round" | "butt" | "square" | "inherit" | undefined
|
||||
strokeLinejoin: undefined, // 线段连接处的样式:"round" | "inherit" | "miter" | "bevel" | undefined
|
||||
strokeColor: '#000000', // 描边颜色
|
||||
strokeWidth: 0, // 描边宽度
|
||||
strokeDasharray: '', // 虚线模式
|
||||
bottom: 0, // 元素的底部位置(用于定位)
|
||||
transform: '', // 应用到元素的变换(如平移、旋转、缩放)
|
||||
|
|
@ -261,6 +256,7 @@ export default defineComponent({
|
|||
if(this.cellInfo.style.shape.href){
|
||||
convertImageToBase64(this.cellInfo.style.shape.href).then((res)=>{
|
||||
// @ts-ignore
|
||||
// 待优化 this.hrefBase64 = res
|
||||
this.cellInfo.style.shape.href = res
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export default defineComponent({
|
|||
emits: ['update:pageSize', 'update:currentPage', 'register','selectionChange'],
|
||||
setup(props, { attrs, slots, emit, expose }) {
|
||||
const elTableRef = ref<ComponentRef<typeof ElTable>>()
|
||||
|
||||
console.log("slots",slots)
|
||||
// 注册
|
||||
onMounted(() => {
|
||||
const tableRef = unref(elTableRef)
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
|
||||
export const STEP0_FINISH:string = 'step0finish'
|
||||
export const UPDATE_ADDRESS:string = 'update_address'
|
||||
|
|
|
|||
|
|
@ -228,52 +228,123 @@
|
|||
</el-card>
|
||||
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="3">
|
||||
<template #title>
|
||||
<CardTitle title="发票信息"/>
|
||||
</template>
|
||||
<el-card>
|
||||
<el-row>
|
||||
<!-- 右上角:账户信息 -->
|
||||
<el-col :span="12" class="detail-info-item"
|
||||
style="padding-left: 0px; margin-top: 20px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="发票抬头" prop="invoiceCode">
|
||||
<el-input v-model="formData.invoiceCode" placeholder="请输入发票抬头"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="发票名称" prop="invoiceName">
|
||||
<el-input v-model="formData.invoiceName" placeholder="请输入发票名称"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="发票地址" prop="invoiceAddress">
|
||||
<el-input
|
||||
name="auto$input_so_invoiceAddress"
|
||||
autocomplete="on"
|
||||
v-model="formData.invoiceAddress"
|
||||
placeholder="请输入发票地址"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="发票备注" prop="invoiceRemarks">
|
||||
<el-input
|
||||
v-model="formData.invoiceRemarks"
|
||||
:autosize="{ minRows: 4, maxRows: 6 }"
|
||||
placeholder="请输入发票备注"
|
||||
type="textarea"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<div class="flex">
|
||||
<el-row>
|
||||
<el-col :span="12" :xs="24">
|
||||
<div>
|
||||
<el-card>
|
||||
<div class="flex items-center">
|
||||
<CardTitle title="发票信息"/>
|
||||
<div class="pl-8px" v-if="false">
|
||||
<el-button type="primary" link>管理发票信息</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-collapse-item>
|
||||
<el-row>
|
||||
<!-- 右上角:账户信息 -->
|
||||
<el-col :span="24" class="detail-info-item"
|
||||
style="padding-left: 0px; margin-top: 20px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="发票抬头" prop="invoiceCode">
|
||||
<el-input v-model="formData.invoiceCode" placeholder="请输入发票抬头"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="发票名称" prop="invoiceName">
|
||||
<el-input v-model="formData.invoiceName" placeholder="请输入发票名称"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="发票地址" prop="invoiceAddress">
|
||||
<el-input
|
||||
name="auto$input_so_invoiceAddress"
|
||||
autocomplete="on"
|
||||
v-model="formData.invoiceAddress"
|
||||
placeholder="请输入发票地址"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="发票备注" prop="invoiceRemarks">
|
||||
<el-input
|
||||
v-model="formData.invoiceRemarks"
|
||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||
placeholder="请输入发票备注"
|
||||
type="textarea"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12" :xs="24">
|
||||
<div>
|
||||
<el-card>
|
||||
<div class="flex items-center">
|
||||
<CardTitle title="收货信息"/>
|
||||
<div class="pl-8px">
|
||||
<AddressListDialog ref="addressRef">
|
||||
<el-button type="primary" link @click="editAddress">管理收货地址</el-button>
|
||||
</AddressListDialog>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<el-row>
|
||||
<!-- 右上角:账户信息 -->
|
||||
<el-col :span="24" class="detail-info-item"
|
||||
style="padding-left: 0px; margin-top: 20px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="送货公司">
|
||||
<el-select filterable
|
||||
placeholder="选择地址"
|
||||
v-model="that.addressId"
|
||||
@change="onChangeAddress">
|
||||
<el-option v-for="item in that.addressList" :label="item.name" :key="item.id" :value="item.id">
|
||||
<span>{{ item.name }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="详细地址">
|
||||
<el-input
|
||||
name="auto$input_deliveryAddress"
|
||||
autocomplete="on"
|
||||
clearable
|
||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||
v-model="formData.deliveryAddress"
|
||||
type="textarea"
|
||||
placeholder="请输入收货地址"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="送货备注" prop="invoiceRemarks">
|
||||
<el-input
|
||||
v-model="formData.deliveryRemark"
|
||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||
placeholder="请输入送货备注"
|
||||
clearable
|
||||
type="textarea"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
</el-collapse>
|
||||
|
||||
</div>
|
||||
|
|
@ -317,12 +388,13 @@
|
|||
<script lang="ts" setup>
|
||||
//@ts-nocheck
|
||||
import * as BrandApi from "@/api/oms/brand";
|
||||
import {AddressApi} from "@/api/oms/customer/address";
|
||||
import {CustomerApi} from "@/api/oms/customer";
|
||||
import {SaleOrderApi} from "@/api/oms/saleorder";
|
||||
|
||||
import OrderAddProductStep from "./components/OrderAddProductStep/index.vue";
|
||||
import {useEmitt} from "@/hooks/web/useEmitt";
|
||||
import {STEP0_FINISH} from "@/constants/EmitEventName";
|
||||
import {STEP0_FINISH, UPDATE_ADDRESS} from "@/constants/EmitEventName";
|
||||
import {formatDate} from "@/utils/formatTime";
|
||||
|
||||
// 计算当前时间之后指定天数的日期
|
||||
|
|
@ -346,20 +418,29 @@ const stepRef = ref(null);
|
|||
const formRef = ref() // 表单 Ref
|
||||
const selectedIndex = ref(-1)
|
||||
const stepIndex = ref(0)
|
||||
|
||||
const addressRef = ref(null);
|
||||
const editAddress = () => {
|
||||
addressRef.value.openDialog()
|
||||
}
|
||||
useEmitt({
|
||||
name: UPDATE_ADDRESS,
|
||||
callback: ()=>{
|
||||
getCustomerAddressList();
|
||||
},
|
||||
});
|
||||
const that = reactive({
|
||||
formLoading: false,
|
||||
addressList: [],
|
||||
addressId: null,
|
||||
tmpFormData: {
|
||||
inputEmail: '',
|
||||
emailList: [],
|
||||
planDate: calculateDateAfterDays(7),
|
||||
},
|
||||
})
|
||||
const customerData = ref()
|
||||
|
||||
const formData = ref({
|
||||
contactName: '',
|
||||
phone: '18122943211',
|
||||
phone: '',
|
||||
invoiceAddress: '',
|
||||
orderStatus: '',
|
||||
customerId: '',
|
||||
|
|
@ -379,6 +460,8 @@ const formData = ref({
|
|||
emails: '',
|
||||
bizdate: undefined,
|
||||
plansenddate: undefined,
|
||||
deliveryAddress: '',
|
||||
deliveryRemark: '',
|
||||
saleOrderEntry: [],
|
||||
})
|
||||
|
||||
|
|
@ -432,18 +515,6 @@ const generateContractCode = () => {
|
|||
return code;
|
||||
}
|
||||
|
||||
|
||||
/** 查询列表 */
|
||||
const getCustomer = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await CustomerApi.getCustomerPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
const backStep = async () => {
|
||||
stepIndex.value = stepIndex.value - 1;
|
||||
}
|
||||
|
|
@ -470,7 +541,14 @@ const nextStep = async () => {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
const onChangeAddress = (id)=>{
|
||||
console.log(id)
|
||||
for (let i = 0; i < that.addressList.length; i++) {
|
||||
if(that.addressList[i].id === id){
|
||||
formData.value.deliveryAddress = that.addressList[i].address
|
||||
}
|
||||
}
|
||||
}
|
||||
const addNewBill = () => {
|
||||
console.log("stepRef.value.getTableData()", stepRef.value.getTableData())
|
||||
// todo 校验
|
||||
|
|
@ -503,19 +581,32 @@ const brandList = ref<any[]>([]) // 品牌列表
|
|||
onMounted(async () => {
|
||||
// 获取品牌列表
|
||||
brandList.value = await BrandApi.getSimpleBrandList()
|
||||
customerData.value = await CustomerApi.getCustomer()
|
||||
if (customerData.value) {
|
||||
formData.value.customerId = customerData.value.id;
|
||||
formData.value.username = customerData.value.name;
|
||||
formData.value.company = customerData.value.company;
|
||||
const customerData = await CustomerApi.getCustomerInfo()
|
||||
if (customerData) {
|
||||
that.addressList = customerData.addressList;
|
||||
formData.value.customerId = customerData.id;
|
||||
formData.value.username = customerData.name;
|
||||
formData.value.company = customerData.company;
|
||||
formData.value.contactName = customerData.contacts;
|
||||
formData.value.phone = customerData.phone;
|
||||
if(!formData.value.deliveryAddress && that.addressList.length > 0){
|
||||
formData.value.deliveryAddress = that.addressList[0].address;
|
||||
that.addressId = that.addressList[0].id;
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
const getCustomerAddressList = async () => {
|
||||
const customerData = await CustomerApi.getCustomerInfo()
|
||||
if (customerData) {
|
||||
that.addressList = customerData.addressList;
|
||||
}
|
||||
}
|
||||
const resFrom = (init = {}) => {
|
||||
|
||||
formData.value = {
|
||||
contactName: '',
|
||||
phone: '18122943211',
|
||||
phone: '',
|
||||
invoiceAddress: '',
|
||||
orderStatus: '',
|
||||
customerId: '',
|
||||
|
|
@ -538,6 +629,18 @@ const resFrom = (init = {}) => {
|
|||
saleOrderEntry: [],
|
||||
...init
|
||||
}
|
||||
if (customerData && !init.id) {
|
||||
that.addressList = customerData.addressList;
|
||||
formData.value.customerId = customerData.id;
|
||||
formData.value.username = customerData.name;
|
||||
formData.value.company = customerData.company;
|
||||
formData.value.contactName = customerData.contacts;
|
||||
formData.value.phone = customerData.phone;
|
||||
formData.value.invoiceCode = customerData.invoiceCode;
|
||||
formData.value.invoiceName = customerData.invoiceName;
|
||||
formData.value.invoiceAddress = customerData.invoiceAddress;
|
||||
console.log("formData",formData)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue