xiaoyong931011
2022-05-16 781fb421fdda4aff90394777b31aea7664cc6e23
Merge branch 'score_shop' of http://120.27.238.55:7000/r/beauty-erp into score_shop

 Conflicts:
 zq-erp/src/main/resources/mybatis/mapper/hive/SysBeauticianStateDao.xml
2 files renamed
27 files modified
6 files added
890 ■■■■ changed files
zq-erp/pom.xml 5 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/beauty/followup/dao/SysFollowupDao.java 12 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/beauty/followup/entry/SysFollowup.java 6 ●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/beauty/followup/service/SysFollowupService.java 89 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/app/action/ApiCommonAction.java 5 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/app/action/ApiFollowupAction.java 62 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/app/authority/AppAuthorityManager.java 11 ●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/common/authority/DefaultAuthorityManager.java 15 ●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/common/bean/SysCacheValue.java 39 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/common/dao/SysCacheValueDao.java 14 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/common/init/LocalCache.java 185 ●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/common/init/UserCacheManager.java 6 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/common/interceptor/ApiUserLoginInterceptor.java 3 ●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/common/interceptor/HostInterceptor.java 3 ●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/common/tools/LocationUtil.java 9 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/hive/action/FollowuController.java 40 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/hive/action/ProjUseController.java 6 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/hive/action/ServiceRecordController.java 2 ●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/hive/dao/ShoppingGoodsDao.java 2 ●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/hive/dao/SysShopInfoDao.java 3 ●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/hive/dao/SysVipAlbumDao.java 11 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/hive/dto/FollowuListDto.java 36 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/hive/service/imp/ShoppingGoodsServiceImpl.java 31 ●●●● patch | view | raw | blame | history
zq-erp/src/main/java/com/matrix/system/shopXcx/api/action/YuyueAction.java 8 ●●●● patch | view | raw | blame | history
zq-erp/src/main/resources/config/application-local.properties 9 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/resources/config/application.properties 2 ●●● patch | view | raw | blame | history
zq-erp/src/main/resources/mybatis/mapper/hive/ShoppingGoodsDao.xml 2 ●●● patch | view | raw | blame | history
zq-erp/src/main/resources/mybatis/mapper/hive/SysBeauticianStateDao.xml 1 ●●●● patch | view | raw | blame | history
zq-erp/src/main/resources/mybatis/mapper/hive/SysFollowupDao.xml 30 ●●●● patch | view | raw | blame | history
zq-erp/src/main/resources/mybatis/mapper/hive/SysShopInfoDao.xml 7 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/resources/templates/views/admin/hive-erp/vip/vipInfo-list.html 2 ●●● patch | view | raw | blame | history
zq-erp/src/main/resources/templates/views/admin/hive/products/shoppinggoods-zb-list.html 20 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/resources/templates/views/admin/hive/vip/followu-list.html 206 ●●●●● patch | view | raw | blame | history
zq-erp/src/main/resources/templates/views/admin/hive/vip/vipInfo-list.html 2 ●●● patch | view | raw | blame | history
zq-erp/src/test/java/com/matrix/LocalCacheTest.java 6 ●●●●● patch | view | raw | blame | history
zq-erp/pom.xml
@@ -100,6 +100,11 @@
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
zq-erp/src/main/java/com/matrix/beauty/followup/dao/SysFollowupDao.java
File was renamed from zq-erp/src/main/java/com/matrix/system/hive/dao/SysFollowupDao.java
@@ -1,11 +1,13 @@
package com.matrix.system.hive.dao;
package com.matrix.beauty.followup.dao;
import com.matrix.beauty.followup.entry.SysFollowup;
import com.matrix.core.pojo.PaginationVO;
import com.matrix.system.app.dto.FollowupListDto;
import com.matrix.system.hive.dto.FollowuListDto;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
import com.matrix.core.pojo.PaginationVO;
import com.matrix.system.hive.bean.SysFollowup;
/**
 * @description 跟进
@@ -15,7 +17,7 @@
public interface SysFollowupDao{
    public int insert(@Param("item") SysFollowup sysFollowup);
       public int batchInsert(@Param("list") List<SysFollowup> sysFollowupList);
       
    public int updateByMap(Map<String, Object> modifyMap);
@@ -41,4 +43,6 @@
    void updateZan(@Param("id")Long id, @Param("zans")String zans);
    List<SysFollowup> selectByAppDto(FollowupListDto followupListDto);
    List<SysFollowup> findVipFollowuByPage(FollowuListDto followuListDto);
}
zq-erp/src/main/java/com/matrix/beauty/followup/entry/SysFollowup.java
File was renamed from zq-erp/src/main/java/com/matrix/system/hive/bean/SysFollowup.java
@@ -1,13 +1,13 @@
package com.matrix.system.hive.bean;
package com.matrix.beauty.followup.entry;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.matrix.core.pojo.EntityDTO;
import com.matrix.core.anotations.Extend;
import com.matrix.core.tools.DateUtil;
import com.matrix.system.common.bean.EntityDTOExt;
import com.matrix.system.common.bean.SysUsers;
import com.matrix.system.hive.bean.SysFollowupComment;
import com.matrix.system.hive.bean.SysVipAlbum;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.util.Date;
zq-erp/src/main/java/com/matrix/beauty/followup/service/SysFollowupService.java
New file
@@ -0,0 +1,89 @@
package com.matrix.beauty.followup.service;
import com.matrix.beauty.followup.dao.SysFollowupDao;
import com.matrix.beauty.followup.entry.SysFollowup;
import com.matrix.core.constance.MatrixConstance;
import com.matrix.core.tools.StringUtils;
import com.matrix.core.tools.WebUtil;
import com.matrix.system.common.bean.SysUsers;
import com.matrix.system.hive.bean.SysBeauticianState;
import com.matrix.system.hive.bean.SysOrderItem;
import com.matrix.system.hive.bean.SysVipAlbum;
import com.matrix.system.hive.dao.SysBeauticianStateDao;
import com.matrix.system.hive.dao.SysOrderItemDao;
import com.matrix.system.hive.dao.SysVipAlbumDao;
import com.matrix.system.hive.dto.FollowuListDto;
import com.matrix.system.hive.plugin.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SysFollowupService {
    @Autowired
    SysFollowupDao followupDao;
    @Autowired
    SysOrderItemDao orderItemDao;
    @Autowired
    private SysVipAlbumDao vipAlbumDao;
    @Autowired
    private SysBeauticianStateDao beauticianStateDao;
    public void save(SysFollowup followup){
        SysUsers user = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY);
        followup.setCreateBy(user.getSuName());
        followup.setUpdateBy(user.getSuName());
        followup.setStaffId(user.getSuId());
        followup.setCompanyId(user.getCompanyId());
        followup.setShopId(user.getShopId());
        //处理订单摘要
        if(followup.getOrderId()!=null){
            List<SysOrderItem> sysOrderItems = orderItemDao.selectByOrderId(followup.getOrderId());
            String abs="";
            if(sysOrderItems.size()>1){
                abs= sysOrderItems.get(0).getShoppingGoods().getName()+"等"+sysOrderItems.size()+"件商品";
            }else{
                abs= sysOrderItems.get(0).getShoppingGoods().getName();
            }
            followup.setOrderAbstract(abs);
        }
        //服务单摘要
        if(followup.getServiceId()!=null){
            List<SysBeauticianState> sysBeauticianStates = beauticianStateDao.selectBySerIds(followup.getServiceId());
            String abs="";
            if(sysBeauticianStates.size()>1){
                abs= sysBeauticianStates.get(0).getProjInfo().getName()+"等"+sysBeauticianStates.size()+"项服务";
            }else{
                abs= sysBeauticianStates.get(0).getProjInfo().getName();
            }
            followup.setOrderAbstract(abs);
        }
        followupDao.insert(followup);
        //插入图片
        List<SysVipAlbum> albums=followup.getAlbums();
        if(CollectionUtils.isNotEmpty(albums)){
            for (SysVipAlbum vipAlbum:albums){
                if(StringUtils.isNotBlank(vipAlbum.getImg())){
                    vipAlbum.setCreateBy(user.getSuName());
                    vipAlbum.setUpdateBy(user.getSuName());
                    vipAlbum.setSource(SysVipAlbum.SOURCE_FOLLOW);
                    vipAlbum.setVipId(followup.getVipId());
                    vipAlbum.setSourceId(followup.getId());
                    vipAlbumDao.insert(vipAlbum);
                }
            }
        }
    }
    public List<SysFollowup> findVipFollowuByPage(FollowuListDto followuListDto) {
        //todo 等订单改造版本合并后用验证工具加参数校验
      return   followupDao.findVipFollowuByPage(followuListDto);
    }
}
zq-erp/src/main/java/com/matrix/system/app/action/ApiCommonAction.java
@@ -2,6 +2,7 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.TypeReference;
import com.matrix.component.tools.HttpCurlUtil;
import com.matrix.core.pojo.AjaxResult;
import com.matrix.core.tools.*;
@@ -194,7 +195,7 @@
            return AjaxResult.buildFailInstance("该手机号不存在");
        }
        String codeExist = LocalCache.get(smsCodeDto.getTelphone());
        String codeExist = LocalCache.get(smsCodeDto.getTelphone(),new TypeReference<String>(){});
        if (StringUtils.isNotBlank(codeExist)) {
            return AjaxResult.buildFailInstance("请勿重复发送验证码");
        }
@@ -215,7 +216,7 @@
            return AjaxResult.buildFailInstance("该手机号不存在");
        }
        String code = LocalCache.get(pwdResetDto.getTelphone());
        String code = LocalCache.get(pwdResetDto.getTelphone(),new TypeReference<String>(){});
        if (StringUtils.isBlank(code)) {
            return AjaxResult.buildFailInstance("验证码已失效,请重新发送");
        }
zq-erp/src/main/java/com/matrix/system/app/action/ApiFollowupAction.java
@@ -1,5 +1,8 @@
package com.matrix.system.app.action;
import com.matrix.beauty.followup.dao.SysFollowupDao;
import com.matrix.beauty.followup.entry.SysFollowup;
import com.matrix.beauty.followup.service.SysFollowupService;
import com.matrix.core.constance.MatrixConstance;
import com.matrix.core.pojo.AjaxResult;
import com.matrix.core.tools.StringUtils;
@@ -7,7 +10,6 @@
import com.matrix.system.app.dto.*;
import com.matrix.system.common.bean.SysUsers;
import com.matrix.system.common.tools.DataAuthUtil;
import com.matrix.system.hive.action.util.QueryUtil;
import com.matrix.system.hive.bean.*;
import com.matrix.system.hive.dao.*;
import com.matrix.system.hive.plugin.util.CollectionUtils;
@@ -35,21 +37,11 @@
    private SysFollowupDao followupDao;
    @Autowired
    private SysVipAlbumDao vipAlbumDao;
    @Autowired
    private SysVipInfoDao vipInfoDao;
    @Autowired
    private SysFollowupCommentDao followupCommentDao;
    @Autowired
    private SysOrderItemDao orderItemDao;
    @Autowired
    private SysBeauticianStateDao beauticianStateDao;
    private SysFollowupService followupService;
    @ApiOperation(value = "新增跟进记录", notes = "新增跟进记录")
@@ -58,51 +50,7 @@
    })
    @PostMapping(value = "/addFollowup")
    public AjaxResult addFollowup(@RequestBody @Validated SysFollowup followup) {
        SysUsers user = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY);
        followup.setCreateBy(user.getSuName());
        followup.setUpdateBy(user.getSuName());
        followup.setStaffId(user.getSuId());
        followup.setCompanyId(user.getCompanyId());
        followup.setShopId(user.getShopId());
        //处理订单摘要
        if(followup.getOrderId()!=null){
            List<SysOrderItem> sysOrderItems = orderItemDao.selectByOrderId(followup.getOrderId());
            String abs="";
            if(sysOrderItems.size()>1){
                abs= sysOrderItems.get(0).getShoppingGoods().getName()+"等"+sysOrderItems.size()+"件商品";
            }else{
                abs= sysOrderItems.get(0).getShoppingGoods().getName();
            }
           followup.setOrderAbstract(abs);
        }
        //服务单摘要
        if(followup.getServiceId()!=null){
            List<SysBeauticianState> sysBeauticianStates = beauticianStateDao.selectBySerIds(followup.getServiceId());
            String abs="";
            if(sysBeauticianStates.size()>1){
                abs= sysBeauticianStates.get(0).getProjInfo().getName()+"等"+sysBeauticianStates.size()+"项服务";
            }else{
                abs= sysBeauticianStates.get(0).getProjInfo().getName();
            }
            followup.setOrderAbstract(abs);
        }
        followupDao.insert(followup);
        //插入图片
        List<SysVipAlbum> albums=followup.getAlbums();
        if(CollectionUtils.isNotEmpty(albums)){
            for (SysVipAlbum vipAlbum:albums){
                if(StringUtils.isNotBlank(vipAlbum.getImg())){
                    vipAlbum.setCreateBy(user.getSuName());
                    vipAlbum.setUpdateBy(user.getSuName());
                    vipAlbum.setSource(SysVipAlbum.SOURCE_FOLLOW);
                    vipAlbum.setVipId(followup.getVipId());
                    vipAlbum.setSourceId(followup.getId());
                    vipAlbumDao.insert(vipAlbum);
                }
            }
        }
        followupService.save(followup);
        return AjaxResult.buildSuccessInstance("保存成功");
    }
zq-erp/src/main/java/com/matrix/system/app/authority/AppAuthorityManager.java
@@ -1,6 +1,9 @@
package com.matrix.system.app.authority;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.matrix.core.constance.MatrixConstance;
import com.matrix.core.pojo.AjaxResult;
import com.matrix.core.tools.StringUtils;
@@ -98,12 +101,10 @@
        String redisKey = USER_POWER_REDISKEY_APP + SecureUtil.md5(user.getSuId()+"");
        Map<String, Object> cachePowerMap = LocalCache.get(redisKey);
        Map<String, Object> cachePowerMap = LocalCache.get(redisKey,new TypeReference<Map<String,Object>>(){});
        if (Objects.nonNull(cachePowerMap)) {
            userFunction = (Map<String, SysFunction>) cachePowerMap.get(USERFUNCTION);
            userUrlMapping = (List<String>) cachePowerMap.get(USER_URL_MAPPING);
            userFunction = JSONObject.parseObject(JSON.toJSONString( cachePowerMap.get(USERFUNCTION)), new TypeReference<Map<String, SysFunction>>(){});
            userUrlMapping =JSONObject.parseObject(JSON.toJSONString( cachePowerMap.get(USER_URL_MAPPING)) , new TypeReference<List<String>>(){});
        } else {
            // 获取用户所有权限
zq-erp/src/main/java/com/matrix/system/common/authority/DefaultAuthorityManager.java
@@ -1,6 +1,9 @@
package com.matrix.system.common.authority;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.matrix.core.constance.MatrixConstance;
import com.matrix.core.pojo.AjaxResult;
import com.matrix.core.tools.StringUtils;
@@ -13,6 +16,7 @@
import com.matrix.system.common.init.LocalCache;
import com.matrix.system.common.service.SysFunctionService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -151,15 +155,12 @@
        SysUsers sysUser = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY);
        String redisKey = USER_POWER_REDISKEY_PC + SecureUtil.md5(sysUser.getSuId() + "");
        Map<String, Object> cachePowerMap = LocalCache.get(redisKey);
        Map<String, Object> cachePowerMap = LocalCache.get(redisKey,new TypeReference<Map<String,Object>>(){});
        if (Objects.nonNull(cachePowerMap)) {
            userFunction = (Map<String, SysFunction>) cachePowerMap.get(USERFUNCTION);
            menuFunction = (List<SysFunction>) cachePowerMap.get(MENUSFUNCTION);
            userUrlMapping = (List<String>) cachePowerMap.get(USER_URL_MAPPING);
            userFunction = JSONObject.parseObject(JSON.toJSONString( cachePowerMap.get(USERFUNCTION)), new TypeReference<Map<String, SysFunction>>(){});
            menuFunction = JSONObject.parseObject(JSON.toJSONString( cachePowerMap.get(MENUSFUNCTION)) ,new TypeReference<List<SysFunction>>(){});
            userUrlMapping =JSONObject.parseObject(JSON.toJSONString( cachePowerMap.get(USER_URL_MAPPING)) , new TypeReference<List<String>>(){});
        } else {
            // 获取用户所有权限
zq-erp/src/main/java/com/matrix/system/common/bean/SysCacheValue.java
New file
@@ -0,0 +1,39 @@
package com.matrix.system.common.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
/**
 * 缓存对象
 */
@Data
public class SysCacheValue {
    @TableId(type= IdType.AUTO)
    private Long id;
    /**
     * 缓存key
     */
    private String cacheKey;
    /**
     * 过期时间,0 表示不过期,单位毫秒
     */
    private Long timeOut ;
    /**
     * 缓存值
     */
    private String cacheValue;
    /**
     * 类型名称
     */
    private String className;
    /**
     * 缓存创建时间
     */
    private Long createTime;
}
zq-erp/src/main/java/com/matrix/system/common/dao/SysCacheValueDao.java
New file
@@ -0,0 +1,14 @@
package com.matrix.system.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.matrix.system.common.bean.SysCacheValue;
import com.matrix.system.fenxiao.entity.ShopSalemanSettlement;
/**
 * @description 缓存对象
 * @author jyy
 * @date 2021-03-10 15:22
 */
public interface SysCacheValueDao extends BaseMapper<SysCacheValue> {
}
zq-erp/src/main/java/com/matrix/system/common/init/LocalCache.java
@@ -1,26 +1,64 @@
package com.matrix.system.common.init;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.matrix.core.tools.LogUtil;
import com.matrix.core.tools.StringUtils;
import com.matrix.system.common.bean.SysCacheValue;
import com.matrix.system.common.dao.SysCacheValueDao;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
public class LocalCache {
@Component
public class LocalCache implements ApplicationRunner {
    /*
     * 清理线程运行状态 0 未启动,1 已启动
     */
    private static int CLEAR_THREAD_STATUS = 0;
    private static ConcurrentMap<String, Value> localCache = new ConcurrentHashMap(60);
    private static ConcurrentMap<String, CacheValue> localCache = new ConcurrentHashMap(60);
    private static ConcurrentLinkedQueue<Long> deadCache = new ConcurrentLinkedQueue<>();
    @Autowired
    private SysCacheValueDao sysCacheValueDao;
    @Override
    public void run(ApplicationArguments args) {
        //初始化缓存
        List<SysCacheValue> sysCacheValues = sysCacheValueDao.selectByMap(null);
        if(CollUtil.isNotEmpty(sysCacheValues)){
            LogUtil.debug("初始化缓存");
            localCache.putAll(buildValues(sysCacheValues));
        }
        startClearThread();
        startSaveStoreThread();
    }
    private Map<String,CacheValue> buildValues(List<SysCacheValue> sysCacheValues) {
        Map<String,CacheValue> storeCache=new HashMap<>();
        sysCacheValues.forEach(e->{
            CacheValue cacheValue=new CacheValue();
            BeanUtil.copyProperties(e,cacheValue);
            storeCache.put(cacheValue.getCacheKey(),cacheValue);
        });
        return storeCache;
    }
    /**
     * 根据key匹配多个缓存值
@@ -33,8 +71,8 @@
        return localCache.entrySet().stream()
                .filter(item -> StringUtils.isMatch(key, item.getKey()))
                .map(Map.Entry::getValue)
                .filter(item -> Objects.nonNull(item.value))
                .collect(Collectors.toMap(Value::getKey, item -> (T) item.value));
                .filter(item -> Objects.nonNull(item.cacheValue))
                .collect(Collectors.toMap(CacheValue::getCacheKey, item -> JSONObject.parseObject(item.cacheValue, new TypeReference<T>(){})));
    }
    /**
@@ -43,11 +81,26 @@
     * @param key
     * @param <T>
     * @return
     */
     *//*
    public static <T> T get(String key) {
        Value value = localCache.get(key);
        CacheValue value = localCache.get(key);
        if (Objects.nonNull(value)) {
            return (T) value.value;
            return JSONObject.parseObject(value.cacheValue, new TypeReference<T>(){});
        }
        return null;
    }
*/
    /**
     * 获取本地缓存,如果需要转换为List,Map类型的具体泛型使用本方法
     * @param key
     * @param typeReference
     * @param <T>
     * @return
     */
    public static <T> T get(String key,TypeReference typeReference) {
        CacheValue value = localCache.get(key);
        if (Objects.nonNull(value)) {
            return (T)JSONObject.parseObject(value.cacheValue, typeReference);
        }
        return null;
    }
@@ -60,9 +113,10 @@
     * @return
     */
    public static <T> T remove(String key) {
        Value value = localCache.remove(key);
        CacheValue value = localCache.get(key);
        if (Objects.nonNull(value)) {
            return (T) value.value;
            deadCache.add(value.getId());
            return (T) value.cacheValue;
        }
        return null;
    }
@@ -75,10 +129,10 @@
     */
    public static int batchRemove(String key) {
        int count = 0;
        Set<Map.Entry<String, Value>> entries = localCache.entrySet();
        Iterator<Map.Entry<String, Value>> iterator = entries.iterator();
        Set<Map.Entry<String, CacheValue>> entries = localCache.entrySet();
        Iterator<Map.Entry<String, CacheValue>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Value> next = iterator.next();
            Map.Entry<String, CacheValue> next = iterator.next();
            if (StringUtils.isMatch(key, next.getKey())) {
                remove(next.getKey());
                count++;
@@ -110,25 +164,26 @@
        if (null != localCache.put(key, buildValue(key, value, timeOut))) {
            LogUtil.debug("覆盖原有缓存{}", key);
        }
        startClearThread();
    }
    /**
     * 重置缓存失效时间
     *
     * @param key
     */
    public static void resetExpire(String key) {
        Objects.requireNonNull(key);
        Value value = localCache.get(key);
        if(Objects.nonNull(value)){
            value.getCreateTime().set(System.currentTimeMillis());
        CacheValue value = localCache.get(key);
        if (Objects.nonNull(value)) {
            value.setCreateTime(System.currentTimeMillis());
        }
    }
    /**
     * 清理过期对象
     */
    private synchronized static void startClearThread() {
    private synchronized void startClearThread() {
        if (CLEAR_THREAD_STATUS == 0) {
            ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
                    .setNameFormat("demo-pool-%d").build();
@@ -139,10 +194,10 @@
                CLEAR_THREAD_STATUS = 1;
                while (true) {
                    try {
                        Set<Map.Entry<String, Value>> entries = localCache.entrySet();
                        Iterator<Map.Entry<String, Value>> iterator = entries.iterator();
                        Set<Map.Entry<String, CacheValue>> entries = localCache.entrySet();
                        Iterator<Map.Entry<String, CacheValue>> iterator = entries.iterator();
                        while (iterator.hasNext()) {
                            Map.Entry<String, Value> next = iterator.next();
                            Map.Entry<String, CacheValue> next = iterator.next();
                            if (next.getValue().timeOut == 0) {
                                continue;
@@ -150,9 +205,14 @@
                            boolean isTimeOut = (System.currentTimeMillis() - next.getValue().getCreateTime().longValue()) > next.getValue().timeOut;
                            if (isTimeOut) {
                                Value removed = localCache.remove(next.getKey());
                                LogUtil.debug("清除过期对象:{}", removed.value);
                                CacheValue removed = remove(next.getKey());
                                LogUtil.debug("清除过期对象:{}", removed.cacheValue);
                            }
                        }
                        if(CollUtil.isNotEmpty(deadCache)){
                            LogUtil.debug("删除数据库中的缓存:{}",deadCache);
                            sysCacheValueDao.deleteBatchIds(deadCache);
                            deadCache.clear();
                        }
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
@@ -166,49 +226,94 @@
        }
    }
    /**
     * 缓存对象写入磁盘
     */
    private synchronized void startSaveStoreThread() {
    private static Value buildValue(String key, Object value) {
            ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
                    .setNameFormat("startSaveStoreThread-pool-%d").build();
            ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>(1), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
            singleThreadPool.execute(() -> {
                try {
                    while (true){
                        Collection<CacheValue> values = localCache.values();
                        List<CacheValue> notSavedList = values.stream().filter(v -> !v.saved).collect(Collectors.toList());
                        if(CollUtil.isNotEmpty(notSavedList)){
                            List<String> collect = notSavedList.stream().map(e -> e.getCacheKey()).collect(Collectors.toList());
                            sysCacheValueDao.delete(new LambdaQueryWrapper<SysCacheValue>().in(SysCacheValue::getCacheKey,collect));
                            notSavedList.forEach(e->{
                                e.setSaved(true);
                                SysCacheValue sysCacheValue = buildSysCacheValue(e);
                                sysCacheValueDao.insert(sysCacheValue);
                                e.setId(sysCacheValue.getId());
                                LogUtil.debug("持久化缓存对象:{}",e.getCacheKey());
                            });
                        }
                        Thread.sleep(1000);
                    }
                } catch (Exception e) {
                    LogUtil.error("存储缓存对象线程异常停止", e);
                }
            });
    }
    private SysCacheValue buildSysCacheValue(CacheValue e) {
        SysCacheValue cacheValue=new SysCacheValue();
        BeanUtil.copyProperties(e,cacheValue);
        return  cacheValue;
    }
    private static CacheValue buildValue(String key, Object value) {
        return buildValue(key, value, 0);
    }
    private static Value buildValue(String key, Object value, long timeOut) {
        Value instances = new Value();
        instances.createTime = new AtomicLong(System.currentTimeMillis());
        instances.key = key;
        instances.value = value;
    private static CacheValue buildValue(String key, Object value, long timeOut) {
        CacheValue instances = new CacheValue();
        instances.createTime = System.currentTimeMillis();
        instances.cacheKey = key;
        instances.cacheValue = JSON.toJSONString(value);
        instances.timeOut = timeOut;
        return instances;
    }
    /**
     * 缓存对象
     */
    @Data
    static class Value {
    static class CacheValue {
        private Long id ;
        /**
         * 过期时间,0 表示不过期,单位毫秒
         */
        private long timeOut = 0;
        private Long timeOut = 0L;
        /**
         * 缓存key
         */
        private String key;
        private String cacheKey;
        /**
         * 缓存值
         */
        private Object value;
        private String cacheValue;
        /**
         * 缓存创建时间
         */
        private AtomicLong createTime;
        private Long createTime;
        private boolean saved=false;
        private boolean live=true;
    }
zq-erp/src/main/java/com/matrix/system/common/init/UserCacheManager.java
@@ -7,11 +7,13 @@
 */
package com.matrix.system.common.init;
import com.alibaba.fastjson.TypeReference;
import com.matrix.core.constance.SystemErrorCode;
import com.matrix.core.exception.GlobleException;
import com.matrix.core.tools.StringUtils;
import com.matrix.core.tools.UUIDUtil;
import com.matrix.core.tools.WebUtil;
import com.matrix.system.common.bean.SysUsers;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@@ -44,7 +46,7 @@
    public boolean isUserLogin() {
        String token = getUserToken();
        if (StringUtils.isNotBlank(token)) {
            return LocalCache.get(token) != null;
            return LocalCache.get(token,new TypeReference<String>(){}) != null;
        } else {
            return false;
        }
@@ -92,7 +94,7 @@
    public <T> T getLoginUser() {
        String userToken = getUserToken();
        if (userToken != null) {
            T user = LocalCache.get(userToken);
            T user = LocalCache.get(userToken,new TypeReference<SysUsers>(){});
            if (Objects.nonNull(user)) {
                //重新设置key过期时间
                LocalCache.resetExpire(userToken);
zq-erp/src/main/java/com/matrix/system/common/interceptor/ApiUserLoginInterceptor.java
@@ -1,6 +1,7 @@
package com.matrix.system.common.interceptor;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.matrix.core.constance.MatrixConstance;
import com.matrix.core.pojo.AjaxResult;
@@ -61,7 +62,7 @@
            return false;
        }
        SysUsers sysUsers = LocalCache.get(token);
        SysUsers sysUsers = LocalCache.get(token,new TypeReference<SysUsers>(){});
        if (Objects.isNull(sysUsers)) {
            ajaxResult.setInfo("login time out");
            response.getWriter().write(new ObjectMapper().writeValueAsString(ajaxResult));
zq-erp/src/main/java/com/matrix/system/common/interceptor/HostInterceptor.java
@@ -1,5 +1,6 @@
package com.matrix.system.common.interceptor;
import com.alibaba.fastjson.TypeReference;
import com.matrix.core.tools.LogUtil;
import com.matrix.core.tools.StringUtils;
import com.matrix.core.tools.WebUtil;
@@ -47,7 +48,7 @@
            return false;
        }
        Map<String, SysCompany> companyMap = LocalCache.get("companyMap");
        Map<String, SysCompany> companyMap = LocalCache.get("companyMap",new TypeReference<Map<String, SysCompany>>(){});
        SysCompany company=companyMap.get(host);
        if(Objects.nonNull(company)){
            // 查到公司后存到sesssion中
zq-erp/src/main/java/com/matrix/system/common/tools/LocationUtil.java
@@ -1,5 +1,7 @@
package com.matrix.system.common.tools;
import java.math.BigDecimal;
public class LocationUtil {
    private static final double EARTH_RADIUS = 6378.137;
@@ -17,7 +19,7 @@
     *  shopX 店铺位置经度
     *  shopY  店铺位置纬度
     */
    public static double getDistance(double locX, double locY, double shopX, double shopY) {
    public static BigDecimal getDistance(double locX, double locY, double shopX, double shopY) {
        double a, b, d, sa2, sb2;
        locY = rad(locY);
        shopY = rad(shopY);
@@ -29,12 +31,13 @@
        d = 2   * EARTH_RADIUS
                * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(locY)
                * Math.cos(shopY) * sb2 * sb2));
        return d;
        return BigDecimal.valueOf(d);
    }
    public static void main(String[] args) {
        // 112.886891,28.222562,114.061937,22.626003  -- 634093.3209722887
        // 113.930692,22.939454 -- 597367.3546527711
        System.out.println(getDistance(112.886891d, 28.222562d, 113.930692, 22.939454));
//        System.out.println(getDistance(112.886891d, 28.222562d, 113.930692, 22.939454));
        System.out.println(BigDecimal.ONE.compareTo(BigDecimal.ZERO)>0);
    }
}
zq-erp/src/main/java/com/matrix/system/hive/action/FollowuController.java
New file
@@ -0,0 +1,40 @@
package com.matrix.system.hive.action;
import com.matrix.beauty.followup.entry.SysFollowup;
import com.matrix.beauty.followup.service.SysFollowupService;
import com.matrix.core.constance.MatrixConstance;
import com.matrix.core.pojo.AjaxResult;
import com.matrix.core.tools.WebUtil;
import com.matrix.system.common.bean.SysUsers;
import com.matrix.system.hive.dto.FollowuListDto;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
 * @description 跟进记录
 */
@RestController
@RequestMapping(value = "admin/followu")
public class FollowuController extends BaseController{
    @Resource
    private SysFollowupService followupService;
    /**
     * 显示所有的会员卡等级信息
     */
    @RequestMapping(value = "/showList")
    public  AjaxResult showList(@RequestBody @Validated FollowuListDto followuListDto) {
        SysUsers users = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY);
        followuListDto.setCompanyId(users.getCompanyId());
        followuListDto.setSelfStaff(users.getSuId());
        List<SysFollowup> list= followupService.findVipFollowuByPage(followuListDto);
        return  AjaxResult.buildSuccessInstance(list);
    }
}
zq-erp/src/main/java/com/matrix/system/hive/action/ProjUseController.java
@@ -1,5 +1,6 @@
package com.matrix.system.hive.action;
import cn.hutool.core.util.StrUtil;
import com.matrix.core.constance.MatrixConstance;
import com.matrix.core.exception.GlobleException;
import com.matrix.core.pojo.AjaxResult;
@@ -19,6 +20,7 @@
import com.matrix.system.hive.service.MoneyCardUseService;
import com.matrix.system.hive.service.SysProjUseService;
import com.matrix.system.hive.service.SysProjuseFreezeService;
import jodd.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
@@ -328,7 +330,7 @@
        Object tel = objects.get(1);
        if (tel != null) {
            String telStr = tel.toString();
            SysVipInfo vipInfo = vipInfoDao.selectByPhone(telStr,sysUsers.getCompanyId());
            SysVipInfo vipInfo = vipInfoDao.selectByPhone(StrUtil.trim(telStr),sysUsers.getCompanyId());
            if (vipInfo == null) {
                vipInfo = new SysVipInfo();
                vipInfo.setShopId(sysUsers.getShopId());
@@ -385,7 +387,7 @@
        Object tel = objects.get(1);
        if (tel != null) {
            String telStr = tel.toString();
            SysVipInfo vipInfo = vipInfoDao.selectByPhone(telStr,sysUsers.getCompanyId());
            SysVipInfo vipInfo = vipInfoDao.selectByPhone(StrUtil.trim(telStr),sysUsers.getCompanyId());
            if (vipInfo == null) {
                vipInfo = new SysVipInfo();
                vipInfo.setShopId(sysUsers.getShopId());
zq-erp/src/main/java/com/matrix/system/hive/action/ServiceRecordController.java
@@ -32,7 +32,7 @@
    @RequestMapping(value = "/showAllList")
    public @ResponseBody
    AjaxResult showAllList(ServiceRecord serviceRecord, PaginationVO pageVo) {
    AjaxResult  showAllList(ServiceRecord serviceRecord, PaginationVO pageVo) {
        if (!getMe().getShopRole().equals(Dictionary.FLAG_YES_Y)) {
            serviceRecord.setShopId(getMe().getShopId());
zq-erp/src/main/java/com/matrix/system/hive/dao/ShoppingGoodsDao.java
@@ -90,7 +90,7 @@
    int selectShopppingGoodsAipTotal(@Param("record") ShoppingGoodsListDto shoppingGoodsListDto);
    public List<ShoppingGoods> selectByIds(@Param("ids")List<Integer> ids);
    public List<ShoppingGoods> selectByIds(@Param("ids")List<Long> ids);
    int updateInvalidProduct();
}
zq-erp/src/main/java/com/matrix/system/hive/dao/SysShopInfoDao.java
@@ -30,7 +30,8 @@
    public int  selectTotalRecord(@Param("record") SysShopInfo sysShopInfo);
    
    public SysShopInfo  selectById(Long id);
    public SysShopInfo selectByShopName(@Param("shopName") String shopName);
    public List<SysShopInfo> selectShopInfo(Long companyId);
zq-erp/src/main/java/com/matrix/system/hive/dao/SysVipAlbumDao.java
@@ -1,10 +1,13 @@
package com.matrix.system.hive.dao;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
import com.matrix.beauty.followup.entry.SysFollowup;
import com.matrix.core.pojo.PaginationVO;
import com.matrix.system.hive.bean.SysVipAlbum;
import com.matrix.system.hive.dto.FollowuListDto;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * @description 客户相册
@@ -38,5 +41,5 @@
    public SysVipAlbum  selectById(Long id);
    
    public SysVipAlbum  selectForUpdate(Long id);
}
zq-erp/src/main/java/com/matrix/system/hive/dto/FollowuListDto.java
New file
@@ -0,0 +1,36 @@
package com.matrix.system.hive.dto;
import com.matrix.core.pojo.PaginationDto;
import lombok.Data;
import javax.validation.constraints.NotNull;
/** 查询客户跟进记录
 * @author jyy
 * @date 2021-01-27
 **/
@Data
public class FollowuListDto extends PaginationDto {
    /**
     * 客户id
     */
    @NotNull
    private Long vipId;
    /**
     * 员工id
     */
    private Long staffId;
    /**
     * 当前查询人
     */
    private Long selfStaff;
    /**
     * 公司id
     */
    private Long companyId;
}
zq-erp/src/main/java/com/matrix/system/hive/service/imp/ShoppingGoodsServiceImpl.java
@@ -1,5 +1,6 @@
package com.matrix.system.hive.service.imp;
import cn.hutool.core.collection.CollUtil;
import com.matrix.core.constance.MatrixConstance;
import com.matrix.core.exception.GlobleException;
import com.matrix.core.pojo.PaginationVO;
@@ -33,6 +34,8 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -59,16 +62,11 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int add(ShoppingGoods shoppingGoods) {
        SysUsers sysUsers = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY);
        SysShopInfo shopInfo = shopInfoDao.selectById(sysUsers.getShopId());
        if(shopInfo.getShopType()==SysShopInfo.SHOP_TYPE_ZONGBU){
@@ -78,10 +76,14 @@
        }
        shoppingGoods.setShopId(sysUsers.getShopId());
        // 校验去重
        if (serviceUtil.addCheckRepeatTowColumn("shopping_goods",
                "code", shoppingGoods.getCode(),
                "company_id", shoppingGoods.getCompanyId())) {
        //去重查询
        ShoppingGoods queryGoods=new ShoppingGoods();
        queryGoods.setCompanyId(shoppingGoods.getCompanyId());
        queryGoods.setCode(shoppingGoods.getCode());
        queryGoods.setIsDel(ShoppingGoods.NORMAL);
        List<ShoppingGoods>  oldGoods=shoppingGoodsDao.selectByModel(queryGoods);
        if(CollUtil.isNotEmpty(oldGoods)){
            throw new GlobleException("编号" + shoppingGoods.getCode() + "重复");
        }
@@ -242,6 +244,17 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int remove(List<Long> list) {
        SysUsers user = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY);
        SysShopInfo zbShop = shopInfoDao.selectZbShop(user.getCompanyId());
        //非总部员工只能删除自己门店的产品
        if(user.getShopId()!=zbShop.getId()){
            //校验是否可以删除
            List<ShoppingGoods> dataList = shoppingGoodsDao.selectByIds(list);
            List<ShoppingGoods> collect = dataList.stream().filter(goods -> !Objects.equals(user.getShopId(), goods.getShopId())).collect(Collectors.toList());
            if(CollUtil.isNotEmpty(collect)){
                throw new GlobleException("非总部员工只能删除自己门店的产品");
            }
        }
        return shoppingGoodsDao.deleteByIds(list);
    }
zq-erp/src/main/java/com/matrix/system/shopXcx/api/action/YuyueAction.java
@@ -122,7 +122,7 @@
            return new AjaxResult(AjaxResult.STATUS_SUCCESS, shopList);
        }
        Double distance = null;
        BigDecimal distance = null;
        SysShopInfo nearestShop = null;
        AjaxResult ajaxResult = new AjaxResult("200", shopList);
@@ -130,9 +130,9 @@
            for (SysShopInfo shopInfo : shopList) {
                Double shopX = Double.parseDouble(shopInfo.getLongitude());
                Double shopY = Double.parseDouble(shopInfo.getLatitude());
                Double disResult = LocationUtil.getDistance(Double.parseDouble(locX), Double.parseDouble(locY), shopX, shopY);
                shopInfo.setDistance(new BigDecimal(disResult).setScale(1, BigDecimal.ROUND_HALF_UP));
                if (distance == null || distance > disResult) {
                BigDecimal disResult = LocationUtil.getDistance(Double.parseDouble(locX), Double.parseDouble(locY), shopX, shopY);
                shopInfo.setDistance(disResult);
                if (distance == null || distance.compareTo(disResult)>0) {
                    distance = disResult;
                    nearestShop = shopInfo;
                }
zq-erp/src/main/resources/config/application-local.properties
@@ -1,8 +1,8 @@
#数据库链接
spring.datasource.username=ct_test
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://120.27.238.55:3306/hive_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&allowMultiQueries=true&transformedBitIsBoolean=true&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/md_test_local?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&allowMultiQueries=true&transformedBitIsBoolean=true&serverTimezone=GMT%2B8
#是否启用debug模式
@@ -15,6 +15,9 @@
#文件保存地址
file_storage_path= D:\\webresources\\uploadeFile\\
local.cache.path= D:\\webresources\\uploadeFile\\
#微信支付调试开关
wx_pay_debug_onoff = false
zq-erp/src/main/resources/config/application.properties
@@ -1,5 +1,5 @@
spring.profiles.active=meidu
spring.profiles.active=alpha
evn=dev
server.port=8080
zq-erp/src/main/resources/mybatis/mapper/hive/ShoppingGoodsDao.xml
@@ -897,7 +897,7 @@
        t.id=cate_id)
        cate_name
        from shopping_goods a
        where code=#{code}
        where a.code=#{code}  and a.is_del=1
    </select>
    <!-- 根据id查询 -->
zq-erp/src/main/resources/mybatis/mapper/hive/SysBeauticianStateDao.xml
@@ -333,6 +333,7 @@
        and a.STAFF_ID = #{suId} ]]>
        and  a.STATE !='预约取消'
        and  a.STATE !='待确认'
        and  a.STATE !='服务单结束'
        and  a.STATE !='待预约' and (c.IS_DELETE is null or c.IS_DELETE = '')
        order by a.BEGIN_TIME asc
zq-erp/src/main/resources/mybatis/mapper/hive/SysFollowupDao.xml
@@ -2,9 +2,9 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.matrix.system.hive.dao.SysFollowupDao" >
<mapper namespace="com.matrix.beauty.followup.dao.SysFollowupDao" >
    <!-- 定义SysFollowup 的复杂关联map -->
    <resultMap type="com.matrix.system.hive.bean.SysFollowup" id="SysFollowupMap">
    <resultMap type="com.matrix.beauty.followup.entry.SysFollowup" id="SysFollowupMap">
        <id property="id" column="id" />
        <result property="createBy" column="create_by" />
        <result property="createTime" column="create_time" />
@@ -40,7 +40,7 @@
    </select>
    
    <!-- 定义SysFollowup 的简单map  ,本map不添加其他的关联属性 -->
    <resultMap type="com.matrix.system.hive.bean.SysFollowup" id="SysFollowupSimpleMap">
    <resultMap type="com.matrix.beauty.followup.entry.SysFollowup" id="SysFollowupSimpleMap">
        <id property="id" column="id" />
        <result property="createBy" column="create_by" />
        <result property="createTime" column="create_time" />
@@ -142,9 +142,9 @@
        </if>
         
    </sql>
    <!--  插入方法   -->
    <insert id="insert" parameterType="com.matrix.system.hive.bean.SysFollowup"
    <insert id="insert" parameterType="com.matrix.beauty.followup.entry.SysFollowup"
        useGeneratedKeys="true" keyProperty="item.id">
        INSERT INTO sys_followup (
             <include refid="columns"></include>
@@ -275,7 +275,7 @@
    </delete>
    
    <!-- 根据对象删除-->
    <delete id="deleteByModel" parameterType="com.matrix.system.hive.bean.SysFollowup">
    <delete id="deleteByModel" parameterType="com.matrix.beauty.followup.entry.SysFollowup">
        DELETE FROM sys_followup
        <where>
        <include refid="where_sql" ></include>
@@ -401,5 +401,23 @@
          limit ${offset},${limit}
    </select>
<select id="findVipFollowuByPage" resultMap="SysFollowupMap">
        select a.*,
         b.su_photo as staffPhoto,
         b.su_name as staffName,
         c.vip_name as vipName
         from sys_followup  a
         left join  sys_users b on a.staff_id= b.su_id
         left join  sys_vip_info c on a.vip_id=c.id
        <where>
            and a.company_id=#{companyId}
            and (visible=1 or ( visible!=1 and a.staff_id=#{selfStaff}))
            <if test="vipId!=null">
                and    a.vip_id = #{vipId}
            </if>
        </where>
        order by a.create_time desc
          limit ${offset},${limit}
    </select>
</mapper>
zq-erp/src/main/resources/mybatis/mapper/hive/SysShopInfoDao.xml
@@ -310,5 +310,12 @@
    <select id="selectZbShop" resultMap="SysShopInfoMap">
        select * from sys_shop_info where shop_type=1 and company_id=#{companyId}
    </select>
    <select id="selectByIds" resultType="com.matrix.system.hive.bean.SysShopInfo">
        select * from sys_shop_info where  ID in
        <foreach collection="list" index="index" item="item" open="("
                 separator="," close=")">
            #{item}
        </foreach>
    </select>
</mapper>
zq-erp/src/main/resources/templates/views/admin/hive-erp/vip/vipInfo-list.html
@@ -193,7 +193,7 @@
            title : "会员跟进记录",
            area :  MUI.SIZE_M,
            maxmin : true,
            content : [ basePath+'/admin/serviceRecord/toServicefollowListForZd?id=' + id ]
            content : [ basePath+'/admin/redirect/hive/vip/followu-list?vipId=' + id ]
        });
    }
zq-erp/src/main/resources/templates/views/admin/hive/products/shoppinggoods-zb-list.html
@@ -17,17 +17,11 @@
<body class=" container-fluid">
<div class="pd-10">
    <div class="row" >
        <a th:href="@{/admin/redirect/hive/products/shoppinggoods-zb-list}" class="btn btn-info " type="button"></i>总部产品</a>
        <a th:href="@{/admin/redirect/hive/products/shoppinggoods-md-list}" class="btn btn-default " type="button"></i>本店产品</a>
    </div>
    <!-- 搜索框部分start -->
    <div class="row form-head">
        <form class="form-inline" id="serchform">
            <input autocomplete="off"   type="hidden" name="salePlatform" value="线下">
            <input autocomplete="off"   type="hidden" name="headquarters" value="1">
            <div class="form-group mr-20">
                <label for="name">商品名称</label>
                <input   class="form-control " name="name" id="name">
@@ -83,6 +77,15 @@
                </select>
            </div>
            <div class="form-group mr-20">
                <label for=" ">是否总部产品</label>
                <select class="form-control" name="headquarters" id=" ">
                    <option value=''>--请选择--</option>
                    <option value='1'>是</option>
                    <option value='2'>否</option>
                </select>
            </div>
            <div class="form-group mr-20">
                <label>商品创建日期</label>
@@ -103,6 +106,9 @@
    <div class="row mt-10">
        <div id="option-bar">
            <button matrix:btn="shoppinggoods1-add"  onclick="openEdit()" type="button" class="btn btn-info btn-sm"><i class="fa fa-eye" ></i> 查看</button>
            <button  matrix:btn="shoppinggoods1-add"  onclick="openAdd()" type="button" class="btn btn-info btn-sm"><i class="fa fa-plus" ></i>  新增</button>
            <button matrix:btn="shoppinggoods1-edit"  onclick="openEdit()" type="button" class="btn btn-info btn-sm"><i class="fa fa-edit" ></i> 编辑</button>
            <button matrix:btn="shoppinggoods1-dels" onclick="myGrid.delItems()" type="button" class="btn btn-danger btn-sm"><i class="fa fa-trash" ></i>批量删除</button>
            <button matrix:btn="shoppinggoods1-add" onclick="exportExcel()" type="button" class="btn btn-default btn-sm"><i class="fa fa-download"></i>导出 </button>
        </div>
        <!-- 数据表格部分 -->
@@ -120,7 +126,7 @@
                <th data-field="isPresent">是否赠送</th>
                <th data-field="goodType" data-sortable="true">类型</th>
                <th data-field="cateName" >分类</th>
                <th data-field="achieveRuleName" >业绩规则</th>
                <th data-field="shopName"   >创建门店</th>
                <th data-field="createTime"  data-sortable="true" data-formatter="MGrid.getTime">创建时间</th>
            </tr>
            </thead>
zq-erp/src/main/resources/templates/views/admin/hive/vip/followu-list.html
New file
@@ -0,0 +1,206 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org" xmlns:matrix="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8">
    <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
    <meta name="renderer" content="webkit|ie-comp|ie-stand">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
    <meta http-equiv="Cache-Control" content="no-siteapp"/>
    <LINK rel="Bookmark" href="../images/favicon.ico">
    <!-- 本框架基本脚本和样式 -->
    <script type="text/javascript" th:src="@{/js/systools/MBaseVue.js}"></script>
    <link rel="stylesheet" th:href="@{/plugin/element-ui/index.css}">
    <link th:href="@{/css/styleOne/style.min.css}" rel="stylesheet" type="text/css"/>
    <title></title>
    <style>
        .panel-body{
            overflow: hidden;
        }
        .buttonPanel{
            background: #ffffff;
            padding: 10px 10px ;
            margin: 0px 0px 10px 0px;
        }
        .rowPanel{
            background: #ffffff;
            padding: 0px 10px ;
            padding-top: 10px;
            margin: 0px 0px 10px 0px;
        }
        .paginationStyle{
            background: #ffffff;
            padding: 10px 10px;
            margin: 0px 0px 10px 0px;
            text-align: right;
        }
    </style>
</head>
<body>
<div class="panel-body" id="app">
    <el-row class="table-style"  >
        <el-table id="proj" :data="table.rows"  :height="height" stripe @sort-change="sortChange">
            <el-table-column
                    prop="vipName"
                    label="客户名称"
                    width="180">
            </el-table-column>
            <el-table-column
                    prop="staffName"
                    label="员工名称">
            </el-table-column>
            <el-table-column
                    prop="orderAbstract"
                    label="订单摘要信息"
                    show-overflow-tooltip
                    width="240">
            </el-table-column>
            <el-table-column
                    prop="content"
                    label="跟进内容"
                    show-overflow-tooltip
                    width="340">
            </el-table-column>
            <el-table-column
                    prop="createTime"
                    label="填写时间"
                    width="180">
            </el-table-column>
            <el-table-column
                    prop="nextNotifyTime"
                    label="下次跟进时间">
            </el-table-column>
            <el-table-column label="效果图片">
                <template slot-scope="scope">
                    <el-image
                            style="width: 100px; height: 100px"
                            :src="scope.row.showImg"
                            :preview-src-list="scope.row.imgList">
                    </el-image>
                </template>
            </el-table-column>
        </el-table>
    </el-row>
    <el-row class="paginationStyle"  >
        <el-pagination background
                       @size-change="changePageSize"
                       @current-change="changeCurrentPage"
                       :current-page="table.currentPage"
                       :page-sizes="[10, 20, 30, 50]"
                       :page-size="table.pageSize"
                       layout="total, sizes, prev, pager, next, jumper"
                       :total="table.total">
        </el-pagination>
    </el-row>
</div>
</body>
<script type="text/javascript" th:src="@{/js/plugin/jquery-2.1.4.min.js}"></script>
<script type="text/javascript" th:src="@{/js/plugin/jquery.query.js}"></script>
<script type="text/javascript" th:src="@{/plugin/layer/layer.js}"></script>
<script type="text/javascript" th:src="@{/js/systools/AjaxProxyVue.js}"></script>
<script type="text/javascript" th:src="@{/js/plugin/vue.js}"></script>
<script type="text/javascript" th:src="@{/plugin/element-ui/index.js}"></script>
<script type="text/javascript" th:src="@{/plugin/moment.min.js}"></script>
<script type="text/javascript" th:inline="javascript">
    var vipId = $.query.get('vipId');
    var vue = new Vue({
        el: '#app',
        data: {
            table:{
                rows:[],
                total:0,
                pageSize:10,
                currentPage:1,
            },
            form:{
                vipId:vipId,
                order:'',
                sort:''
            },
            height:'calc(100vh - 240px)',
        },
        created: function () {
            let _this=this;
           this.loadData();
            window.addEventListener("keydown", this.keydown);
        },
        methods: {
            changePageSize(val) {
                this.table.pageSize = val;
                this.loadData();
            },
            changeCurrentPage(val) {
                this.table.currentPage = val;
                this.loadData();
            },
            resetForm(formName) {
                this.$refs[formName].resetFields();
            },
            sortChange:function (column){
                if(column.order){
                    if(column.order.indexOf("desc")){
                        this.form.order="desc";
                    }else{
                        this.form.order="asc";
                    }
                    this.form.sort=column.prop;
                    this.loadData();
                }
            },
            loadData:function(){
                let _this = this;
                let data=_this.getRequestParam();
                data.limit=_this.table.pageSize;
                data.offset=_this.table.pageSize*(_this.table.currentPage-1);
                AjaxProxy.requst({
                    app: _this,
                    data:data,
                    url: basePath + '/admin/followu/showList',
                    callback: function (data) {
                        data.rows.forEach(e=>{
                           e.showImg= e.albums[0].img;
                           e.imgList=[];
                           e.albums.forEach(album=>{
                               e.imgList.push(album.img);
                           })
                        })
                        _this.table.rows = data.rows;
                        _this.table.total=data.total;
                    }
                });
            },
            getRequestParam(){
                let _this = this;
                return   {
                    vipId:_this.form.vipId,
                    order:_this.form.order,
                    sort:_this.form.sort
                }
            },
            search:function(){
                this.table.currentPage=1;
                this.loadData();
            },
            keydown(evt){
                if(evt.keyCode==13) {
                    this.search();
                }
            },
        }
    });
</script>
</body>
</html>
zq-erp/src/main/resources/templates/views/admin/hive/vip/vipInfo-list.html
@@ -315,7 +315,7 @@
            title : "会员跟进记录",
            area :  MUI.SIZE_M,
            maxmin : true,
            content : [ basePath+'/admin/serviceRecord/toServicefollowList?id=' + id ]
            content : [ basePath+'/admin/redirect/hive/vip/followu-list?vipId=' + id ]
        });
    }
    function createDateDictionary() {
zq-erp/src/test/java/com/matrix/LocalCacheTest.java
@@ -7,6 +7,8 @@
 */
package com.matrix;
import com.alibaba.fastjson.TypeReference;
import com.matrix.system.common.bean.SysUsers;
import com.matrix.system.common.init.LocalCache;
import org.junit.Assert;
import org.junit.Test;
@@ -27,9 +29,9 @@
    public void testNoticeTask() throws IOException, InterruptedException {
        LocalCache.save("name","jyy",1000*3);
        System.out.println("放入对象");
        Assert.assertNotNull(LocalCache.get("name"));
        Assert.assertNotNull(LocalCache.get("name",new TypeReference<SysUsers>(){}));
        Thread.sleep(1000*5);
        Assert.assertNull(LocalCache.get("name"));
        Assert.assertNull(LocalCache.get("name",new TypeReference<SysUsers>(){}));
    }
}