Compare commits

...

17 Commits

Author SHA1 Message Date
382696293@qq.com 635f8fb43a 数云接口对接,会员操作,积分变更操作 2 years ago
382696293@qq.com 678bbc11fe 获取 accessToken 日志输入json格式化 2 years ago
382696293@qq.com 5fb2b3a3eb 数云accessToken获取以及缓存 2 years ago
382696293@qq.com 4f35e32c3f 数云accessToken获取以及缓存 2 years ago
382696293@qq.com d39d966a90 数云accessToken获取以及缓存 2 years ago
382696293@qq.com a07eedcd68 数云accessToken获取以及缓存 2 years ago
382696293@qq.com 7045c196a7 用户仪器绑定记录顺序优化 2 years ago
382696293@qq.com cc5f905f78 非IOT仪器获取模式列表 2 years ago
382696293@qq.com 71fac463d1 换绑仪器 2 years ago
382696293@qq.com ef0c6bb21f 模式管理 2 years ago
382696293@qq.com 6a406137ba 根据序列号获取仪器信息 2 years ago
382696293@qq.com b396c7b79c 打卡记录 导出增加打卡时间 2 years ago
382696293@qq.com 4961816bf9 打卡记录 查看详情 2 years ago
382696293@qq.com 321cfdeb1a 打卡记录 批量操作 2 years ago
382696293@qq.com ccf2a20cf5 打卡记录 2 years ago
382696293@qq.com b11a409446 模式管理,自定义组合只在 WL200 允许选择 2 years ago
382696293@qq.com 9bd883feb7 仪器管理新增修改优化 2 years ago

@ -76,4 +76,18 @@ public class CacheConstants
* access_token
*/
public static final long WX_ACCESS_TOKEN_EXPIRATION = 100;
/**
* access_token Key
*/
public static final String SHUYUN_ACCESS_TOKEN_CACHE = "shuyun_access_token_cache";
/**
* access_token HKey
*/
public static final String SHUYUN_ACCESS_TOKEN_CACHE_VALUE = "value";
/**
* access_token HKey
*/
public static final String SHUYUN_ACCESS_TOKEN_CACHE_EXPIRY = "expiry";
}

@ -61,4 +61,9 @@ public class SecurityConstants
*
*/
public static final String ROLE_PERMISSION = "role_permission";
/**
*
*/
public static final String SHUYUN_REQUEST_TIME = "Gateway-Request-Time";
}

@ -5,6 +5,8 @@ import com.flossom.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.List;
/**
* wx_clock_log
*
@ -52,6 +54,8 @@ public class WxClockLog extends BaseEntity {
// 微信用户实体
private WxUserMember wxUserMember;
private List<WxClockImg> wxClockImgList;
public void setId(Long id) {
this.id = id;
}
@ -108,6 +112,14 @@ public class WxClockLog extends BaseEntity {
this.wxUserMember = wxUserMember;
}
public List<WxClockImg> getWxClockImgList() {
return wxClockImgList;
}
public void setWxClockImgList(List<WxClockImg> wxClockImgList) {
this.wxClockImgList = wxClockImgList;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)

@ -0,0 +1,136 @@
package com.flossom.common.core.domain.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.flossom.common.core.annotation.Excel;
import com.flossom.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.Date;
import java.util.List;
/**
* WxMemberClockLog
*
* @author flossom
* @date 2024-01-29
*/
public class WxMemberClockLog {
/**
*
*/
private Integer clockNum;
private String headimg;
private String nickname;
private Long userId;
private String mobile;
private String wecomTagListStr;
private String miniProgramTagListStr;
/* 用户注册时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date memberRegisterDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastClockTime;
private String instrumentName;
private String clockTime;
public Integer getClockNum() {
return clockNum;
}
public void setClockNum(Integer clockNum) {
this.clockNum = clockNum;
}
public String getHeadimg() {
return headimg;
}
public void setHeadimg(String headimg) {
this.headimg = headimg;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getWecomTagListStr() {
return wecomTagListStr;
}
public void setWecomTagListStr(String wecomTagListStr) {
this.wecomTagListStr = wecomTagListStr;
}
public String getMiniProgramTagListStr() {
return miniProgramTagListStr;
}
public void setMiniProgramTagListStr(String miniProgramTagListStr) {
this.miniProgramTagListStr = miniProgramTagListStr;
}
public Date getMemberRegisterDate() {
return memberRegisterDate;
}
public void setMemberRegisterDate(Date memberRegisterDate) {
this.memberRegisterDate = memberRegisterDate;
}
public Date getLastClockTime() {
return lastClockTime;
}
public void setLastClockTime(Date lastClockTime) {
this.lastClockTime = lastClockTime;
}
public String getInstrumentName() {
return instrumentName;
}
public void setInstrumentName(String instrumentName) {
this.instrumentName = instrumentName;
}
public String getClockTime() {
return clockTime;
}
public void setClockTime(String clockTime) {
this.clockTime = clockTime;
}
}

@ -0,0 +1,129 @@
package com.flossom.common.core.domain.export;
import com.flossom.common.core.annotation.Excel;
import java.time.LocalTime;
import java.util.Date;
/**
*
*
* @author flossom
* @date 2024-01-29
*/
public class WxClockLogExport {
@Excel(name = "会员昵称")
private String nickname;
@Excel(name = "用户编号")
private Long userId;
@Excel(name = "手机号")
private String mobile;
@Excel(name = "仪器名称")
private String instrumentName;
@Excel(name = "最新打卡时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date lastClockTime;
@Excel(name = "累计打卡时间")
private String clockTime;
@Excel(name = "小程序标签")
private String miniProgramTagListStr;
@Excel(name = "累计打卡天数")
private Integer clockNum;
@Excel(name = "外部标签")
private String wecomTagListStr;
@Excel(name = "用户注册时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date memberRegisterDate;
public WxClockLogExport() {
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getInstrumentName() {
return instrumentName;
}
public void setInstrumentName(String instrumentName) {
this.instrumentName = instrumentName;
}
public Date getLastClockTime() {
return lastClockTime;
}
public void setLastClockTime(Date lastClockTime) {
this.lastClockTime = lastClockTime;
}
public String getMiniProgramTagListStr() {
return miniProgramTagListStr;
}
public void setMiniProgramTagListStr(String miniProgramTagListStr) {
this.miniProgramTagListStr = miniProgramTagListStr;
}
public Integer getClockNum() {
return clockNum;
}
public void setClockNum(Integer clockNum) {
this.clockNum = clockNum;
}
public String getWecomTagListStr() {
return wecomTagListStr;
}
public void setWecomTagListStr(String wecomTagListStr) {
this.wecomTagListStr = wecomTagListStr;
}
public Date getMemberRegisterDate() {
return memberRegisterDate;
}
public void setMemberRegisterDate(Date memberRegisterDate) {
this.memberRegisterDate = memberRegisterDate;
}
public String getClockTime() {
return clockTime;
}
public void setClockTime(String clockTime) {
this.clockTime = clockTime;
}
}

@ -0,0 +1,155 @@
package com.flossom.common.core.domain.req;
import java.util.Date;
import java.util.List;
/**
*
*
* @author flossom
* @date 2024-01-29
*/
public class UserClockLogReq {
/**
* ','
*/
private String userIdList;
/**
*
*/
private String nickname;
/**
* ','
*/
private String mobile;
/**
* ID
*/
private List<Long> wecomTagList;
/**
* ID
*/
private List<Long> miniProgramTagList;
/**
*
*/
private List<Date> memberRegisterDateRange;
/**
*
*/
private List<Date> clockDateRange;
/**
*
*/
private List<Date> clockLastDateRange;
/**
*
*/
private Integer clockNumStart;
private Integer clockNumEnd;
private List<Long> queryUserIdList;
public UserClockLogReq() {
}
public String getUserIdList() {
return userIdList;
}
public void setUserIdList(String userIdList) {
this.userIdList = userIdList;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public List<Long> getWecomTagList() {
return wecomTagList;
}
public void setWecomTagList(List<Long> wecomTagList) {
this.wecomTagList = wecomTagList;
}
public List<Long> getMiniProgramTagList() {
return miniProgramTagList;
}
public void setMiniProgramTagList(List<Long> miniProgramTagList) {
this.miniProgramTagList = miniProgramTagList;
}
public List<Date> getMemberRegisterDateRange() {
return memberRegisterDateRange;
}
public void setMemberRegisterDateRange(List<Date> memberRegisterDateRange) {
this.memberRegisterDateRange = memberRegisterDateRange;
}
public List<Date> getClockDateRange() {
return clockDateRange;
}
public void setClockDateRange(List<Date> clockDateRange) {
this.clockDateRange = clockDateRange;
}
public List<Date> getClockLastDateRange() {
return clockLastDateRange;
}
public void setClockLastDateRange(List<Date> clockLastDateRange) {
this.clockLastDateRange = clockLastDateRange;
}
public List<Long> getQueryUserIdList() {
return queryUserIdList;
}
public void setQueryUserIdList(List<Long> queryUserIdList) {
this.queryUserIdList = queryUserIdList;
}
public Integer getClockNumStart() {
return clockNumStart;
}
public void setClockNumStart(Integer clockNumStart) {
this.clockNumStart = clockNumStart;
}
public Integer getClockNumEnd() {
return clockNumEnd;
}
public void setClockNumEnd(Integer clockNumEnd) {
this.clockNumEnd = clockNumEnd;
}
}

@ -0,0 +1,31 @@
package com.flossom.common.core.domain.req;
import java.util.ArrayList;
import java.util.List;
public class WxClockLogExportVm extends UserClockLogReq {
/**
*
*/
private List<String> exportFields = new ArrayList<>();
private List<Integer> idList = new ArrayList<>();
public List<String> getExportFields() {
return exportFields;
}
public void setExportFields(List<String> exportFields) {
this.exportFields = exportFields;
}
public List<Integer> getIdList() {
return idList;
}
public void setIdList(List<Integer> idList) {
this.idList = idList;
}
}

@ -0,0 +1,85 @@
package com.flossom.common.core.domain.shuyun;
/**
* api accessToken 1
*
*/
public class AccessToken {
/**
* isOverDue
*/
private String accessToken;
/**
* ID
*/
private String appId;
/**
* 0:1:
*/
private String authType;
/**
*
*
*/
private String authValue;
/**
* 0: 1:accessToken
*/
private Integer isOverDue;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAuthType() {
return authType;
}
public void setAuthType(String authType) {
this.authType = authType;
}
public String getAuthValue() {
return authValue;
}
public void setAuthValue(String authValue) {
this.authValue = authValue;
}
public Integer getIsOverDue() {
return isOverDue;
}
public void setIsOverDue(Integer isOverDue) {
this.isOverDue = isOverDue;
}
@Override
public String toString() {
return "AccessToken{" +
"accessToken='" + accessToken + '\'' +
", appId='" + appId + '\'' +
", authType='" + authType + '\'' +
", authValue='" + authValue + '\'' +
", isOverDue='" + isOverDue + '\'' +
'}';
}
}

@ -0,0 +1,174 @@
package com.flossom.common.core.domain.shuyun;
/**
*
*/
public class ShuYunMember {
/**
* ()
*/
private String id;
/**
* ()
*/
private String platCode;
/**
* 使IDID()
*/
private String shopId;
/**
* ()
*/
private String name;
/**
* ()
*/
private String mobile;
/**
* yyyy-MM-dd
*/
private String birthday;
/**
* F(); M()
*/
private String gender;
/**
* yyyy-MM-dd HH:mm:ss
*/
private String created;
/**
* ID
*/
private String guideId;
public ShuYunMember() {
}
/**
*
* @param id
* @param platCode
* @param shopId
* @param name
* @param mobile
*/
public ShuYunMember(String id, String platCode, String shopId, String name, String mobile) {
this.id = id;
this.platCode = platCode;
this.shopId = shopId;
this.name = name;
this.mobile = mobile;
}
/**
*
* @param id
* @param platCode
* @param shopId
*/
public ShuYunMember(String id, String platCode, String shopId) {
this.id = id;
this.platCode = platCode;
this.shopId = shopId;
}
public ShuYunMember(String id, String platCode, String shopId, String mobile) {
this.id = id;
this.platCode = platCode;
this.shopId = shopId;
this.mobile = mobile;
}
public ShuYunMember(String id, String platCode, String shopId, String name, String mobile, String birthday, String gender, String created, String guideId) {
this.id = id;
this.platCode = platCode;
this.shopId = shopId;
this.name = name;
this.mobile = mobile;
this.birthday = birthday;
this.gender = gender;
this.created = created;
this.guideId = guideId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPlatCode() {
return platCode;
}
public void setPlatCode(String platCode) {
this.platCode = platCode;
}
public String getShopId() {
return shopId;
}
public void setShopId(String shopId) {
this.shopId = shopId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getGuideId() {
return guideId;
}
public void setGuideId(String guideId) {
this.guideId = guideId;
}
}

@ -0,0 +1,183 @@
package com.flossom.common.core.domain.shuyun;
public class ShuYunPointChange {
/**
*
*/
private String id;
/**
*
*/
private String platCode;
/**
* 使IDID
*/
private String shopId;
/**
*
*/
private String sequence;
/**
*
* TRADE:
* REFUND:退
* SERVICE:
* CONSUME:
* EXPIRE:
* IMPORT:
* MALL:
* BRAND:
* OTHER
*/
private String source;
/**
*
*/
private Integer changePoint;
/**
* yyyy-MM-dd HH:mm:ss
*/
private String created;
/**
* yyyy-MM-dd HH:mm:ss
*/
private String expired;
/**
*
*/
private String operator;
/**
*
*/
private String desc;
public ShuYunPointChange() {
}
/**
*
*
* @param id
* @param platCode
* @param shopId
* @param sequence
* @param source
* @param changePoint
* @param created
* @param desc
*/
public ShuYunPointChange(String id, String platCode, String shopId, String sequence, String source, Integer changePoint, String created, String desc) {
this.id = id;
this.platCode = platCode;
this.shopId = shopId;
this.sequence = sequence;
this.source = source;
this.changePoint = changePoint;
this.created = created;
this.desc = desc;
}
public ShuYunPointChange(String id, String platCode, String shopId, String sequence, String source, Integer changePoint, String created, String expired, String operator, String desc) {
this.id = id;
this.platCode = platCode;
this.shopId = shopId;
this.sequence = sequence;
this.source = source;
this.changePoint = changePoint;
this.created = created;
this.expired = expired;
this.operator = operator;
this.desc = desc;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPlatCode() {
return platCode;
}
public void setPlatCode(String platCode) {
this.platCode = platCode;
}
public String getShopId() {
return shopId;
}
public void setShopId(String shopId) {
this.shopId = shopId;
}
public String getSequence() {
return sequence;
}
public void setSequence(String sequence) {
this.sequence = sequence;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public Integer getChangePoint() {
return changePoint;
}
public void setChangePoint(Integer changePoint) {
this.changePoint = changePoint;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getExpired() {
return expired;
}
public void setExpired(String expired) {
this.expired = expired;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}

@ -1,6 +1,8 @@
package com.flossom.common.core.mapper;
import com.flossom.common.core.domain.entity.WxClockLog;
import com.flossom.common.core.domain.entity.WxMemberClockLog;
import com.flossom.common.core.domain.req.UserClockLogReq;
import com.flossom.common.core.domain.ret.WxClockLogRet;
import java.util.List;
@ -63,4 +65,8 @@ public interface WxClockLogMapper {
Integer selectCountByUserId(WxClockLog queryClockLog);
List<WxClockLogRet> selectWxClockImgRetList(WxClockLog queryClockLog);
List<WxMemberClockLog> selectMemberClockLogList(UserClockLogReq userClockLogReq);
List<WxClockLog> detail(UserClockLogReq userClockLogReq);
}

@ -29,6 +29,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateTime" column="update_time" />
</resultMap>
<resultMap type="WxMemberClockLog" id="wxMemberClockLog">
<result property="userId" column="user_id" />
<result property="lastClockTime" column="last_clock_time"/>
<result property="clockNum" column="clock_num" />
<result property="instrumentName" column="instrument_name" />
<result property="clockTime" column="clock_time" />
</resultMap>
<resultMap type="WxClockLog" id="WxClockImgLogResult">
<result property="id" column="id" />
<result property="userId" column="user_id" />
<result property="instrumentId" column="instrument_id" />
<result property="instrumentName" column="instrument_name" />
<result property="clockContent" column="clock_content" />
<result property="status" column="status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<collection property="wxClockImgList" ofType="WxClockImg" >
<result property="id" column="img_id" />
<result property="userClockId" column="user_clock_id" />
<result property="clockImg" column="clock_img" />
</collection>
</resultMap>
<sql id="selectWxClockLogVo">
select id, user_id, instrument_id, instrument_name, clock_content, status, create_by, create_time, update_by, update_time from wx_clock_log
</sql>
@ -59,6 +85,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by create_time desc
</select>
<select id="detail" parameterType="WxClockLog" resultMap="WxClockImgLogResult">
SELECT
log.id, log.user_id, log.instrument_id, log.instrument_name, log.clock_content, log.status,
log.create_by, log.create_time, log.update_by, log.update_time, img.id as img_id,
img.user_clock_id as user_clock_id, img.clock_img as clock_img
FROM
wx_clock_log log
LEFT JOIN wx_clock_img img ON log.id = img.user_clock_id
<where>
<if test="userIdList != null "> and user_id = #{userIdList}</if>
<if test="clockDateRange != null and clockDateRange.size > 0">
and update_time &gt;= #{clockDateRange[0]}
</if>
<if test="clockDateRange != null and clockDateRange.size > 0">
and update_time &lt;= #{clockDateRange[1]}
</if>
</where>
order by update_time desc
</select>
<select id="selectWxClockLogById" parameterType="Long" resultMap="WxClockLogResult">
<include refid="selectWxClockLogVo"/>
where id = #{id}
@ -83,6 +129,49 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by create_time desc
</select>
<select id="selectMemberClockLogList" parameterType="userClockLogReq" resultMap="wxMemberClockLog">
SELECT
user_id,
MAX( update_time ) AS last_clock_time,
GROUP_CONCAT(instrument_name) AS instrument_name,
count( 1 ) AS clock_num,
GROUP_CONCAT( update_time ) AS clock_time
FROM
wx_clock_log
<where>
<if test="clockDateRange != null and clockDateRange.size > 0">
and update_time &gt;= #{clockDateRange[0]}
</if>
<if test="clockDateRange != null and clockDateRange.size > 0">
and update_time &lt;= #{clockDateRange[1]}
</if>
</where>
GROUP BY
user_id
<trim prefix="having" prefixOverrides="and">
<if test="queryUserIdList != null and queryUserIdList.size > 0">
and user_id in
<foreach item="item" collection="queryUserIdList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="clockLastDateRange != null and clockLastDateRange.size > 0">
and last_clock_time &gt;= #{clockLastDateRange[0]}
</if>
<if test="clockLastDateRange != null and clockLastDateRange.size > 0">
and last_clock_time &lt;= #{clockLastDateRange[1]}
</if>
<if test="clockNumStart != null">
and clock_num &gt;= #{clockNumStart}
</if>
<if test="clockNumEnd != null">
and clock_num &lt;= #{clockNumEnd}
</if>
</trim>
ORDER BY
last_clock_time DESC
</select>
<insert id="insertWxClockLog" parameterType="WxClockLog" useGeneratedKeys="true" keyProperty="id">
<selectKey keyProperty="id" resultType="Long" order="AFTER">
SELECT LAST_INSERT_ID()

@ -38,7 +38,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="bindingStatus != null "> and binding_status = #{bindingStatus}</if>
<if test="status != null "> and status = #{status}</if>
</where>
order by create_time desc
order by id desc
</select>
<select id="selectWxUserInstrumentLogById" parameterType="Long" resultMap="WxUserInstrumentLogResult">

@ -102,6 +102,14 @@
<scope>test</scope>
</dependency>
<!-- 数云SDK -->
<dependency>
<groupId>com.shuyun.open</groupId>
<artifactId>open-platform-sdk</artifactId>
<version>1.0.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/open-platform-sdk.jar</systemPath>
</dependency>
</dependencies>
<build>
@ -110,6 +118,10 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 将 resources 目录下的 第三方jar 打包到 自己的 jar 包中 -->
<includeSystemScope>true</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>

@ -139,6 +139,10 @@ public class WxInstrumentServiceImpl implements IWxInstrumentService {
logger.info("serial:{}, 序列号不存在", serial);
throw new ServiceReturnCodeException(InstrumentHttpCodeEnum.TWO_HUNDRED_AND_FIVE.getInfo(), InstrumentHttpCodeEnum.TWO_HUNDRED_AND_FIVE.getCode());
}
WxInstrument wxInstrument = wxInstrumentMapper.selectWxInstrumentById(wxInstrumentSerial.getInstrumentId());
if (wxInstrument != null) {
wxInstrumentSerial.setInstrumentName(wxInstrument.getName());
}
return wxInstrumentSerial;
}
@ -355,7 +359,8 @@ public class WxInstrumentServiceImpl implements IWxInstrumentService {
// 3.2、更新旧的序列号状态为已解绑
// 当后管解除了用户和仪器的绑定,状态变为已解绑,无需再次修改序列号的绑定状态
if (BindingStatusEnums.UN_BOUND.getCode() == wxUserInstrument.getBindingStatus()) {
logger.info("用户仪器绑定状态:{},需解绑的旧序列号:{}", wxUserInstrument.getBindingStatus(), wxUserInstrument.getSerial());
if (BindingStatusEnums.BINDED.getCode() == wxUserInstrument.getBindingStatus()) {
WxInstrumentSerial oldUpdate = new WxInstrumentSerial();
oldUpdate.setBindingStatus(BindingStatusEnums.UN_BOUND.getCode());
oldUpdate.setSerial(wxUserInstrument.getSerial());
@ -379,9 +384,11 @@ public class WxInstrumentServiceImpl implements IWxInstrumentService {
updateEntity.setUpdateBy(wxUserMember.getNickname());
updateEntity.setUpdateTime(DateUtils.getNowDate());
wxUserInstrumentMapper.updateWxUserInstrument(updateEntity);
// 3.5、用户仪器关联记录表
// 3.5、用户仪器关联操作日志表
// 当后管解除了用户和仪器的绑定,操作记录已记录,无需再次记录
if (BindingStatusEnums.UN_BOUND.getCode() == wxUserInstrument.getBindingStatus()) {
logger.info("旧序列号日志记录:用户仪器绑定状态:{}", wxUserInstrument.getBindingStatus());
if (BindingStatusEnums.BINDED.getCode() == wxUserInstrument.getBindingStatus()) {
WxUserInstrumentLog oldUserInstrumentLog = new WxUserInstrumentLog();
oldUserInstrumentLog.setUserInstrumentId(wxUserInstrument.getId());
oldUserInstrumentLog.setUserId(wxUserMember.getId());
@ -444,7 +451,10 @@ public class WxInstrumentServiceImpl implements IWxInstrumentService {
wxModeTag.setModeId(wxMode.getId());
List<WxModeTag> wxModeTagList = wxModeTagMapper.selectWxModeTagList(wxModeTag);
BeanUtils.copyProperties(wxMode, wxModeRet);
if(wxMode.getInstrumentType() == 2) {
// IOT仪器才可以设置模式时长
wxModeRet.setModeTime(LocalTime.of(0, wxMode.getModeTime()));
}
Boolean isLock = false;
if (wxModeTagList != null && wxModeTagList.size() > 0) {
List<Long> modeTagList = wxModeTagList.stream().map(WxModeTag::getTagId).collect(Collectors.toList());

@ -0,0 +1,73 @@
package com.flossom.miniProgram.utils.shuyun;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.flossom.common.core.constant.CacheConstants;
import com.flossom.common.core.utils.StringUtils;
import com.flossom.common.redis.service.RedisService;
import com.flossom.miniProgram.utils.HttpClientUtils;
import com.shuyun.open.sdk.bean.HttpMethod;
import com.shuyun.open.sdk.core.GateWayClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.Map;
/**
*
*/
@Component
public class ShuYunApiUtils {
protected final static Logger logger = LoggerFactory.getLogger(ShuYunApiUtils.class);
private static ShuYunConfig shuYunConfig;
private static RedisService redisService;
@Autowired
public void setShuYunConfig(ShuYunConfig shuYunConfig) {
ShuYunApiUtils.shuYunConfig = shuYunConfig;
}
@Autowired
public void setRedisService(RedisService redisService) {
ShuYunApiUtils.redisService = redisService;
}
public static void refreshAccessToken() throws Exception {
String url = "https://open-client.shuyun.com/client/callback/token/" + shuYunConfig.getAppid() + "/v2";
logger.info(url);
logger.info(HttpClientUtils.get(url));
}
public static String getAccessToken(String appid, String secret) throws Exception {
String accessToken = redisService.getCacheObject(CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE);
if (StringUtils.isBlank(accessToken)) {
Map<String, String> params = new LinkedHashMap<>();
params.put("platCode", "OFFLINE"); // 暂时固定
params.put("shopId", "9005"); // 暂时固定
params.put("id", "001");
params.put("mobile", "13500000001");
String requestBody = new ObjectMapper().writeValueAsString(params);
String result = GateWayClient.askGateWay(HttpMethod.POST,
shuYunConfig.getUrl(),
null,
requestBody,
shuYunConfig.getAppid(),
shuYunConfig.getSecurity(),
null,
"shuyun.loyalty.member.register");
}
return accessToken;
}
}

@ -0,0 +1,56 @@
package com.flossom.miniProgram.utils.shuyun;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author flossom
*/
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "shuyun")
public class ShuYunConfig {
/**
*
*/
private String url;
/**
* appid
*/
private String appid;
/**
* security
*/
private String security;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getSecurity() {
return security;
}
public void setSecurity(String security) {
this.security = security;
}
}

@ -0,0 +1,3 @@
http-pool.connect-timeout=60000
http-pool.connection-request-timeout=60000
http-pool.socket-timeout=60000

@ -99,6 +99,15 @@
<artifactId>javase</artifactId>
<version>3.5.1</version>
</dependency>
<!-- 数云SDK -->
<dependency>
<groupId>com.shuyun.open</groupId>
<artifactId>open-platform-sdk</artifactId>
<version>1.0.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/open-platform-sdk.jar</systemPath>
</dependency>
</dependencies>
<build>
@ -107,6 +116,10 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 将 resources 目录下的 第三方jar 打包到 自己的 jar 包中 -->
<includeSystemScope>true</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>

@ -0,0 +1,65 @@
package com.flossom.system.controller;
import com.alibaba.fastjson.JSON;
import com.flossom.common.core.constant.CacheConstants;
import com.flossom.common.core.domain.R;
import com.flossom.common.core.domain.shuyun.AccessToken;
import com.flossom.common.redis.service.RedisService;
import com.flossom.system.utils.shuyun.ShuYunConfig;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
/**
*
*/
@RestController
@RequestMapping("/shuyun")
public class ShuYunCallbackController {
protected final static Logger logger = LoggerFactory.getLogger(ShuYunCallbackController.class);
@Autowired
private ShuYunConfig shuYunConfig;
@Autowired
private RedisService redisService;
/**
* accessToken accessToken
*/
@PostMapping(value = "/accessToken")
public R accessToken(@RequestBody List<AccessToken> accessTokenList) {
logger.info("数云回调结果accessTokenList: {}", JSON.toJSONString(accessTokenList));
/**
* accessToken
*/
if (accessTokenList != null && accessTokenList.size() > 0) {
for (AccessToken accessToken : accessTokenList) {
if (accessToken.getIsOverDue() == 0 && StringUtils.equals(accessToken.getAuthValue(), shuYunConfig.getAuthValue())) {
logger.info("缓存数云accessToken{}", accessToken);
if (StringUtils.isNotBlank(accessToken.getAccessToken())) {
Map<String, Object> map = new HashMap<>();
map.put(CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE_VALUE, JSON.toJSONString(accessToken));
map.put(CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE_EXPIRY, LocalDateTime.now().plusDays(1).atZone(ZoneId.systemDefault()).toEpochSecond());
redisService.setCacheMap(CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE, map);
return R.ok("", "SUCCESS");
}
}
}
}
logger.error("缓存数云accessToken失败{}", accessTokenList);
return R.fail();
}
}

@ -1,9 +1,16 @@
package com.flossom.system.controller;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import java.util.stream.Collectors;
import com.flossom.common.core.domain.R;
import com.flossom.common.core.domain.entity.WxClockLog;
import com.flossom.common.core.domain.entity.WxMemberClockLog;
import com.flossom.common.core.domain.export.WxClockLogExport;
import com.flossom.common.core.domain.req.UserClockLogReq;
import com.flossom.common.core.domain.req.WxClockLogExportVm;
import com.flossom.common.core.exception.ServiceException;
import com.flossom.common.core.utils.poi.ExcelUtil;
import com.flossom.common.core.web.controller.BaseController;
import com.flossom.common.core.web.domain.AjaxResult;
@ -11,17 +18,14 @@ import com.flossom.common.core.web.page.TableDataInfo;
import com.flossom.common.log.annotation.Log;
import com.flossom.common.log.enums.BusinessType;
import com.flossom.common.security.annotation.RequiresPermissions;
import com.flossom.system.service.IWxUserMemberService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import com.flossom.system.service.IWxClockLogService;
import javax.servlet.http.HttpServletResponse;
/**
* Controller
*
@ -35,27 +39,27 @@ public class WxClockLogController extends BaseController {
@Autowired
private IWxClockLogService wxClockLogService;
@Autowired
private IWxUserMemberService wxUserMemberService;
/**
*
*/
@RequiresPermissions("system:clockLog:list")
@GetMapping("/list")
public TableDataInfo list(WxClockLog wxClockLog) {
startPage();
List<WxClockLog> list = wxClockLogService.selectWxClockLogList(wxClockLog);
public TableDataInfo list(UserClockLogReq userClockLogReq) {
List<WxMemberClockLog> list = wxClockLogService.selectWxClockLogList(userClockLogReq, true);
return getDataTable(list);
}
/**
*
*
*/
@RequiresPermissions("system:clockLog:export")
@Log(title = "用户打卡", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, WxClockLog wxClockLog) {
List<WxClockLog> list = wxClockLogService.selectWxClockLogList(wxClockLog);
ExcelUtil<WxClockLog> util = new ExcelUtil<WxClockLog>(WxClockLog.class);
util.exportExcel(response, list, "用户打卡数据");
@RequiresPermissions("system:clockLog:list")
@GetMapping("/detail")
public TableDataInfo detail(UserClockLogReq userClockLogReq) {
List<WxClockLog> list = wxClockLogService.detail(userClockLogReq);
return getDataTable(list);
}
/**
@ -96,4 +100,77 @@ public class WxClockLogController extends BaseController {
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(wxClockLogService.deleteWxClockLogByIds(ids));
}
/**
*
*/
@PostMapping("/allAddMiniProgramTag")
public R allAddMiniProgramTag(@RequestParam("tagIdList") List<Integer> tagIdList, @RequestBody UserClockLogReq userClockLogReq) {
if (tagIdList == null || tagIdList.size() == 0) {
logger.error("参数有误");
throw new ServiceException("参数有误");
}
List<WxMemberClockLog> list = wxClockLogService.selectWxClockLogList(userClockLogReq, true);
if (list != null && list.size() > 0) {
List<Integer> collect = list.stream().map(wxMemberClockLog -> wxMemberClockLog.getUserId().intValue()).collect(Collectors.toList());
wxUserMemberService.batchAddMiniProgramTag(tagIdList, collect);
}
return R.ok();
}
/**
*
*/
@PostMapping("/allDelMiniProgramTag")
public R allDelMiniProgramTag(@RequestParam("tagIdList") List<Integer> tagIdList, @RequestBody UserClockLogReq userClockLogReq) {
if (tagIdList == null || tagIdList.size() == 0) {
logger.error("参数有误");
throw new ServiceException("参数有误");
}
List<WxMemberClockLog> list = wxClockLogService.selectWxClockLogList(userClockLogReq, true);
if (list != null && list.size() > 0) {
List<Integer> collect = list.stream().map(wxMemberClockLog -> wxMemberClockLog.getUserId().intValue()).collect(Collectors.toList());
wxUserMemberService.batchDelMiniProgramTag(tagIdList, collect);
}
return R.ok();
}
/**
*
*/
@RequiresPermissions("system:nursingLog:export")
@PostMapping("/batchExport")
public void batchExport(HttpServletResponse response, WxClockLogExportVm wxClockLogExportVm) {
List<Integer> idList = wxClockLogExportVm.getIdList();
if (idList == null || idList.size() == 0) {
throw new ServiceException("请选择导出数据");
}
UserClockLogReq userClockLogReq = new UserClockLogReq();
userClockLogReq.setQueryUserIdList(wxClockLogExportVm.getIdList().stream().map(Integer::longValue).collect(Collectors.toList()));
List<WxMemberClockLog> list = wxClockLogService.selectWxClockLogList(userClockLogReq, false);
export(response, list, wxClockLogExportVm.getExportFields());
}
/**
*
*/
@RequiresPermissions("system:nursingLog:export")
@PostMapping("/allExport")
public void allExport(HttpServletResponse response, WxClockLogExportVm wxClockLogExportVm) {
List<WxMemberClockLog> list = wxClockLogService.selectWxClockLogList(wxClockLogExportVm, false);
export(response, list, wxClockLogExportVm.getExportFields());
}
private static void export(HttpServletResponse response, List<WxMemberClockLog> list, List<String> exportFields) {
List<WxClockLogExport> exportList = new ArrayList<>();
WxClockLogExport export;
for (WxMemberClockLog wxMemberClockLog : list) {
export = new WxClockLogExport();
BeanUtils.copyProperties(wxMemberClockLog, export);
exportList.add(export);
}
ExcelUtil<WxClockLogExport> util = new ExcelUtil(WxClockLogExport.class);
util.exportExcel(response, exportList, "打卡记录数据", exportFields);
}
}

@ -1,6 +1,8 @@
package com.flossom.system.service;
import com.flossom.common.core.domain.entity.WxClockLog;
import com.flossom.common.core.domain.entity.WxMemberClockLog;
import com.flossom.common.core.domain.req.UserClockLogReq;
import java.util.List;
@ -24,10 +26,10 @@ public interface IWxClockLogService {
/**
*
*
* @param wxClockLog
* @param userClockLogReq
* @return
*/
public List<WxClockLog> selectWxClockLogList(WxClockLog wxClockLog);
public List<WxMemberClockLog> selectWxClockLogList(UserClockLogReq userClockLogReq, boolean isPage);
/**
*
@ -60,4 +62,6 @@ public interface IWxClockLogService {
* @return
*/
public int deleteWxClockLogById(Long id);
List<WxClockLog> detail(UserClockLogReq userClockLogReq);
}

@ -1,10 +1,21 @@
package com.flossom.system.service.impl;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import com.flossom.common.core.domain.entity.WxClockLog;
import com.flossom.common.core.domain.entity.WxMemberClockLog;
import com.flossom.common.core.domain.entity.WxUserMember;
import com.flossom.common.core.domain.entity.WxUserTag;
import com.flossom.common.core.domain.req.UserClockLogReq;
import com.flossom.common.core.domain.req.WxUserMemberVm;
import com.flossom.common.core.enums.TagTypeStatusEnum;
import com.flossom.common.core.mapper.WxClockLogMapper;
import com.flossom.common.core.mapper.WxUserMemberMapper;
import com.flossom.common.core.mapper.WxUserTagMapper;
import com.flossom.common.core.utils.DateUtils;
import com.flossom.common.core.utils.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.flossom.system.service.IWxClockLogService;
@ -21,6 +32,15 @@ public class WxClockLogServiceImpl implements IWxClockLogService {
@Autowired
private WxClockLogMapper wxClockLogMapper;
@Autowired
private WxUserMemberMapper wxUserMemberMapper;
@Autowired
private WxUserTagMapper wxUserTagMapper;
/**
*
*
@ -35,12 +55,68 @@ public class WxClockLogServiceImpl implements IWxClockLogService {
/**
*
*
* @param wxClockLog
* @param userClockLogReq
* @return
*/
@Override
public List<WxClockLog> selectWxClockLogList(WxClockLog wxClockLog) {
return wxClockLogMapper.selectWxClockLogList(wxClockLog);
public List<WxMemberClockLog> selectWxClockLogList(UserClockLogReq userClockLogReq, boolean isPage) {
// 查询条件
WxUserMemberVm wxUserMemberVm = new WxUserMemberVm();
if (!(userClockLogReq.getUserIdList() == null && userClockLogReq.getNickname() == null
&& userClockLogReq.getMobile() == null && userClockLogReq.getMemberRegisterDateRange() == null
&& userClockLogReq.getWecomTagList() == null && userClockLogReq.getMiniProgramTagList() == null)) {
wxUserMemberVm.setId(userClockLogReq.getUserIdList());
wxUserMemberVm.setNickname(userClockLogReq.getNickname());
wxUserMemberVm.setMobile(userClockLogReq.getMobile());
if (userClockLogReq.getWecomTagList() != null && userClockLogReq.getWecomTagList().size() > 0) {
wxUserMemberVm.setWecomTags(userClockLogReq.getWecomTagList().stream().map(Long::intValue).collect(Collectors.toList()));
wxUserMemberVm.setWecomTagNum(userClockLogReq.getWecomTagList().size());
}
if (userClockLogReq.getMiniProgramTagList() != null && userClockLogReq.getMiniProgramTagList().size() > 0) {
wxUserMemberVm.setMiniProgramTags(userClockLogReq.getMiniProgramTagList().stream().map(Long::intValue).collect(Collectors.toList()));
wxUserMemberVm.setMiniProgramTagNum(userClockLogReq.getMiniProgramTagList().size());
}
if (userClockLogReq.getMemberRegisterDateRange() != null && userClockLogReq.getMemberRegisterDateRange().size() > 0) {
wxUserMemberVm.getParams().put("beginTime", userClockLogReq.getMemberRegisterDateRange().get(0));
wxUserMemberVm.getParams().put("endTime", userClockLogReq.getMemberRegisterDateRange().get(1));
}
List<WxUserMember> wxUserMemberList = wxUserMemberMapper.selectWxUserMemberListByVm(wxUserMemberVm);
if (wxUserMemberList != null && wxUserMemberList.size() > 0) {
userClockLogReq.setQueryUserIdList(wxUserMemberList.stream().map(WxUserMember::getId).collect(Collectors.toList()));
} else {
userClockLogReq.setQueryUserIdList(Arrays.asList(0L));
}
}
if(isPage) {
PageUtils.startPage();
}
List<WxMemberClockLog> wxClockLogList = wxClockLogMapper.selectMemberClockLogList(userClockLogReq);
wxClockLogList.forEach(wxMemberClockLog -> {
WxUserMember wxUserMember = wxUserMemberMapper.selectWxUserMemberById(wxMemberClockLog.getUserId());
if (wxUserMember != null) {
// 用户信息
wxMemberClockLog.setHeadimg(wxUserMember.getHeadimg());
wxMemberClockLog.setMobile(wxUserMember.getMobile());
wxMemberClockLog.setNickname(wxUserMember.getNickname());
wxMemberClockLog.setMemberRegisterDate(wxUserMember.getCreateTime());
// 查询标签
WxUserTag wxUserTag = new WxUserTag();
wxUserTag.setUserId(wxUserMember.getId());
wxUserTag.setType(TagTypeStatusEnum.MINI_PROGRAM.getCode());
List<WxUserTag> miniProgramTagList = wxUserTagMapper.selectWxUserTagList(wxUserTag);
if (miniProgramTagList != null && miniProgramTagList.size() > 0) {
wxMemberClockLog.setMiniProgramTagListStr(miniProgramTagList.stream().map(WxUserTag::getTagName).collect(Collectors.joining(",")));
}
wxUserTag.setType(TagTypeStatusEnum.ENTERPRISE_WECHAT.getCode());
List<WxUserTag> wecomTagList = wxUserTagMapper.selectWxUserTagList(wxUserTag);
if (wecomTagList != null && wecomTagList.size() > 0) {
wxMemberClockLog.setWecomTagListStr(wecomTagList.stream().map(WxUserTag::getTagName).collect(Collectors.joining(",")));
}
}
});
return wxClockLogList;
}
/**
@ -88,4 +164,11 @@ public class WxClockLogServiceImpl implements IWxClockLogService {
public int deleteWxClockLogById(Long id) {
return wxClockLogMapper.deleteWxClockLogById(id);
}
@Override
public List<WxClockLog> detail(UserClockLogReq userClockLogReq) {
return wxClockLogMapper.detail(userClockLogReq);
}
}

@ -75,9 +75,11 @@ public class WxNursingLogServiceImpl implements IWxNursingLogService {
wxUserMemberVm.setAreaId(userNursingLogReq.getAreaId());
if (userNursingLogReq.getWecomTagList() != null && userNursingLogReq.getWecomTagList().size() > 0) {
wxUserMemberVm.setWecomTags(userNursingLogReq.getWecomTagList().stream().map(Long::intValue).collect(Collectors.toList()));
wxUserMemberVm.setWecomTagNum(userNursingLogReq.getWecomTagList().size());
}
if (userNursingLogReq.getMiniProgramTagList() != null && userNursingLogReq.getMiniProgramTagList().size() > 0) {
wxUserMemberVm.setMiniProgramTags(userNursingLogReq.getMiniProgramTagList().stream().map(Long::intValue).collect(Collectors.toList()));
wxUserMemberVm.setMiniProgramTagNum(userNursingLogReq.getMiniProgramTagList().size());
}
List<WxUserMember> wxUserMemberList = wxUserMemberMapper.selectWxUserMemberListByVm(wxUserMemberVm);

@ -0,0 +1,394 @@
package com.flossom.system.utils;
import com.flossom.common.core.utils.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class HttpClientUtils {
private static final Logger log = LoggerFactory.getLogger(HttpClientUtils.class);
public static final int connTimeout = 10000;
public static final int readTimeout = 10000;
public static final String charset = "UTF-8";
private static HttpClient client = null;
static {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(128);
cm.setDefaultMaxPerRoute(128);
client = HttpClients.custom().setConnectionManager(cm).build();
}
public static String postJsonParameters(String url, String parameterStr) throws Exception {
return postJson(url, parameterStr, charset, connTimeout, readTimeout);
}
public static String postParameters(String url, String parameterStr) throws Exception {
return post(url, parameterStr, "application/x-www-form-urlencoded", charset, connTimeout, readTimeout);
}
public static String postParameters(String url, String parameterStr, String charset, Integer connTimeout, Integer readTimeout) throws ConnectTimeoutException, SocketTimeoutException, Exception {
return post(url, parameterStr, "application/x-www-form-urlencoded", charset, connTimeout, readTimeout);
}
public static String postParameters(String url, Map<String, String> params) throws ConnectTimeoutException,
SocketTimeoutException, Exception {
return postForm(url, params, null, connTimeout, readTimeout);
}
public static String postParameters(String url, Map<String, String> params, Integer connTimeout, Integer readTimeout) throws ConnectTimeoutException,
SocketTimeoutException, Exception {
return postForm(url, params, null, connTimeout, readTimeout);
}
public static String get(String url) throws Exception {
return get(url, charset, null, null);
}
public static String get(String url, String charset) throws Exception {
return get(url, charset, connTimeout, readTimeout);
}
public static String getParameters(String url, Map<String, String> params) throws Exception {
URIBuilder builder = new URIBuilder(url);
if (params != null) {
for (String key : params.keySet()) {
builder.addParameter(key, params.get(key));
}
}
URI uri = builder.build();
return get(uri.toString(), charset, null, null);
}
/**
* Post , 使.
*
* @param url
* @param body RequestBody
* @param charset
* @param connTimeout ,.
* @param readTimeout ,.
* @return ResponseBody, 使.
* @throws ConnectTimeoutException
* @throws SocketTimeoutException
* @throws Exception
*/
public static String postJson(String url, String body, String charset, Integer connTimeout, Integer readTimeout) throws Exception {
HttpClient client = null;
HttpPost post = new HttpPost(url);
String result = "";
try {
if (StringUtils.isNotBlank(body)) {
HttpEntity entity = new StringEntity(body, ContentType.APPLICATION_JSON);
post.setEntity(entity);
}
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
post.setConfig(customReqConf.build());
HttpResponse res;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(post);
} else {
// 执行 Http 请求.
client = HttpClientUtils.client;
res = client.execute(post);
}
result = EntityUtils.toString(res.getEntity(), charset);
} catch (Exception ex) {
log.error("HttpClient request error!", ex);
throw ex;
} finally {
post.releaseConnection();
if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
return result;
}
/**
* Post , 使.
*
* @param url
* @param body RequestBody
* @param mimeType application/xml "application/x-www-form-urlencoded" a=1&b=2&c=3
* @param charset
* @param connTimeout ,.
* @param readTimeout ,.
* @return ResponseBody, 使.
* @throws ConnectTimeoutException
* @throws SocketTimeoutException
* @throws Exception
*/
public static String post(String url, String body, String mimeType, String charset, Integer connTimeout, Integer readTimeout)
throws ConnectTimeoutException, SocketTimeoutException, Exception {
HttpClient client = null;
HttpPost post = new HttpPost(url);
String result = "";
try {
if (StringUtils.isNotBlank(body)) {
HttpEntity entity = new StringEntity(body, ContentType.create(mimeType, charset));
post.setEntity(entity);
}
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
post.setConfig(customReqConf.build());
HttpResponse res;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(post);
} else {
// 执行 Http 请求.
client = HttpClientUtils.client;
res = client.execute(post);
}
result = EntityUtils.toString(res.getEntity(), charset);
} catch (Exception ex) {
log.error("HttpClient request error!", ex);
throw ex;
} finally {
post.releaseConnection();
if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
return result;
}
/**
* form
*
* @param url
* @param params
* @param connTimeout
* @param readTimeout
* @return
* @throws ConnectTimeoutException
* @throws SocketTimeoutException
* @throws Exception
*/
public static String postForm(String url, Map<String, String> params, Map<String, String> headers, Integer connTimeout, Integer readTimeout) throws ConnectTimeoutException,
SocketTimeoutException, Exception {
HttpClient client = null;
HttpPost post = new HttpPost(url);
try {
if (params != null && !params.isEmpty()) {
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
Set<Entry<String, String>> entrySet = params.entrySet();
for (Entry<String, String> entry : entrySet) {
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
post.setEntity(entity);
}
if (headers != null && !headers.isEmpty()) {
for (Entry<String, String> entry : headers.entrySet()) {
post.addHeader(entry.getKey(), entry.getValue());
}
}
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
post.setConfig(customReqConf.build());
HttpResponse res = null;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(post);
} else {
// 执行 Http 请求.
client = HttpClientUtils.client;
res = client.execute(post);
}
return EntityUtils.toString(res.getEntity(), charset);
} catch (Exception ex) {
log.error("HttpClient request error!", ex);
throw ex;
} finally {
post.releaseConnection();
if (url.startsWith("https") && client != null
&& client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
}
/**
* GET
*
* @param url
* @param charset
* @param connTimeout ,.
* @param readTimeout ,.
* @return
* @throws ConnectTimeoutException
* @throws SocketTimeoutException
* @throws Exception
*/
public static String get(String url, String charset, Integer connTimeout, Integer readTimeout)
throws ConnectTimeoutException, SocketTimeoutException, Exception {
HttpClient client = null;
HttpGet get = new HttpGet(url);
String result = "";
try {
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
get.setConfig(customReqConf.build());
HttpResponse res = null;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(get);
} else {
// 执行 Http 请求.
client = HttpClientUtils.client;
res = client.execute(get);
}
result = EntityUtils.toString(res.getEntity(), charset);
} catch (Exception ex) {
log.error("HttpClient request error!", ex);
throw ex;
} finally {
get.releaseConnection();
if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
return result;
}
/**
* response charset
*
* @param ressponse
* @return
*/
@SuppressWarnings("unused")
private static String getCharsetFromResponse(HttpResponse ressponse) {
// Content-Type:text/html; charset=GBK
if (ressponse.getEntity() != null && ressponse.getEntity().getContentType() != null && ressponse.getEntity().getContentType().getValue() != null) {
String contentType = ressponse.getEntity().getContentType().getValue();
if (contentType.contains("charset=")) {
return contentType.substring(contentType.indexOf("charset=") + 8);
}
}
return null;
}
/**
* SSL
*
* @return
* @throws GeneralSecurityException
*/
private static CloseableHttpClient createSSLInsecureClient() throws GeneralSecurityException {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
@Override
public void verify(String host, SSLSocket ssl)
throws IOException {
}
@Override
public void verify(String host, X509Certificate cert)
throws SSLException {
}
@Override
public void verify(String host, String[] cns,
String[] subjectAlts) throws SSLException {
}
});
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (GeneralSecurityException e) {
throw e;
}
}
}

@ -0,0 +1,98 @@
package com.flossom.system.utils.shuyun;
/**
*
*/
public class ActionMethod {
/**
* token
*/
private String accessToken;
/**
*
*/
private String queryMember;
/**
*
*/
private String registerMember;
/**
*
*/
private String modifyMember;
/**
*
*/
private String modifyMemberMobile;
/**
*
*/
private String unbindMember;
/**
*
*/
private String pointChange;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getQueryMember() {
return queryMember;
}
public void setQueryMember(String queryMember) {
this.queryMember = queryMember;
}
public String getRegisterMember() {
return registerMember;
}
public void setRegisterMember(String registerMember) {
this.registerMember = registerMember;
}
public String getModifyMember() {
return modifyMember;
}
public void setModifyMember(String modifyMember) {
this.modifyMember = modifyMember;
}
public String getModifyMemberMobile() {
return modifyMemberMobile;
}
public void setModifyMemberMobile(String modifyMemberMobile) {
this.modifyMemberMobile = modifyMemberMobile;
}
public String getUnbindMember() {
return unbindMember;
}
public void setUnbindMember(String unbindMember) {
this.unbindMember = unbindMember;
}
public String getPointChange() {
return pointChange;
}
public void setPointChange(String pointChange) {
this.pointChange = pointChange;
}
}

@ -0,0 +1,194 @@
package com.flossom.system.utils.shuyun;
import com.alibaba.fastjson.JSON;
import com.flossom.common.core.constant.CacheConstants;
import com.flossom.common.core.domain.R;
import com.flossom.common.core.domain.shuyun.AccessToken;
import com.flossom.common.core.domain.shuyun.ShuYunMember;
import com.flossom.common.core.domain.shuyun.ShuYunPointChange;
import com.flossom.common.core.exception.ServiceException;
import com.flossom.common.redis.service.RedisService;
import com.flossom.system.utils.HttpClientUtils;
import com.shuyun.open.sdk.bean.HttpMethod;
import com.shuyun.open.sdk.core.GateWayClient;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;
/**
*
*/
@Component
public class ShuYunApiUtils {
protected final static Logger logger = LoggerFactory.getLogger(ShuYunApiUtils.class);
/**
*
*/
private static ShuYunConfig shuYunConfig;
private static RedisService redisService;
@Autowired
public void setShuYunConfig(ShuYunConfig shuYunConfig) {
ShuYunApiUtils.shuYunConfig = shuYunConfig;
}
@Autowired
public void setRedisService(RedisService redisService) {
ShuYunApiUtils.redisService = redisService;
}
/**
* accessToken accessToken
*/
public static String getAccessToken() {
Long expiryTime = redisService.getCacheMapValue(CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE, CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE_EXPIRY);
if (expiryTime == null || expiryTime == 0 || LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond() > expiryTime) {
String accessTokenUrl = StringUtils.replace(shuYunConfig.getActionMethod().getAccessToken(), "{appid}", shuYunConfig.getAppid());
logger.info("刷新accessToken地址{}", accessTokenUrl);
try {
String result = HttpClientUtils.get(accessTokenUrl);
logger.info("请求数云接口获取accessToken结果{}", result);
R r = JSON.parseObject(result, R.class);
if (r.getCode() != R.SUCCESS) {
logger.error("请求数云接口获取accessToken失败将直接使用旧的accessToken失败原因{}", result);
}
} catch (Exception e) {
logger.error("请求数云接口获取accessToken失败将直接使用旧的accessToken失败原因{}", e);
}
}
String accessTokenStr = redisService.getCacheMapValue(CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE, CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE_VALUE);
if (StringUtils.isNotBlank(accessTokenStr)) {
AccessToken accessToken = JSON.parseObject(accessTokenStr, AccessToken.class);
return accessToken.getAccessToken();
}
/**
* redis
*/
logger.error("从redis获取数云accessToken失败缓存中没有accessToken有可能是第一次调用");
throw new ServiceException("从redis获取数云accessToken失败缓存中没有accessToken有可能是第一次调用");
}
/**
*
*
* @param httpMethod
* @param requestParams geturl
* @param requestBody postput
* @param actionMethod
*/
public static R shuYunHttpRequest(HttpMethod httpMethod, Map requestParams, String requestBody, String actionMethod) throws ServiceException {
logger.info("数云接口请求地址:{}参数requestParams = {}、requestBody = {}", actionMethod, requestParams, requestBody);
String result = GateWayClient.askGateWay(
httpMethod,
shuYunConfig.getUrl(),
requestParams,
requestBody,
shuYunConfig.getAppid(),
shuYunConfig.getSecurity(),
getAccessToken(),
actionMethod);
logger.info("返回响应:{}", result);
R r = JSON.parseObject(result, R.class);
if (r.getCode() == 10000 || r.getCode() == 14000) {
return r;
} else {
logger.error("调用数云接口发生未知错误:{}", result);
throw new ServiceException("调用数云接口发生未知错误");
}
}
/**
*
*/
public static void registerMember(ShuYunMember member) {
try {
shuYunHttpRequest(HttpMethod.POST, null, JSON.toJSONString(member),
shuYunConfig.getActionMethod().getRegisterMember());
} catch (Exception e) {
logger.error("请求数云接口注册会员失败:{}", e);
throw new ServiceException("请求数云接口注册会员失败");
}
}
/**
*
*/
public static ShuYunMember queryMember(ShuYunMember member) {
try {
R r = shuYunHttpRequest(HttpMethod.POST, null, JSON.toJSONString(member),
shuYunConfig.getActionMethod().getQueryMember());
if (r.getCode() == 10000) {
return JSON.parseObject(r.getData().toString(), ShuYunMember.class);
}
return null;
} catch (Exception e) {
logger.error("请求数云接口-查询会员信息失败:{}", e);
throw new ServiceException("请求数云接口-查询会员信息失败");
}
}
/**
*
*
*/
public static void modifyMember(ShuYunMember member) {
try {
shuYunHttpRequest(HttpMethod.PUT, null, JSON.toJSONString(member),
shuYunConfig.getActionMethod().getModifyMember());
} catch (Exception e) {
logger.error("请求数云接口-修改会员信息(除手机号)失败:{}", e);
throw new ServiceException("请求数云接口-修改会员信息(除手机号)失败");
}
}
/**
*
*/
public static void modifyMemberMobile(ShuYunMember member) {
try {
shuYunHttpRequest(HttpMethod.PUT, null, JSON.toJSONString(member),
shuYunConfig.getActionMethod().getModifyMemberMobile());
} catch (Exception e) {
logger.error("请求数云接口-修改会员手机号失败:{}", e);
throw new ServiceException("请求数云接口-修改会员手机号失败");
}
}
/**
*
*/
public static void unbindMember(ShuYunMember member) {
try {
shuYunHttpRequest(HttpMethod.POST, null, JSON.toJSONString(member),
shuYunConfig.getActionMethod().getUnbindMember());
} catch (Exception e) {
logger.error("请求数云接口-解绑会员失败:{}", e);
throw new ServiceException("请求数云接口-解绑会员失败");
}
}
/**
*
*/
public static void pointChange(ShuYunPointChange shuYunPointChange) {
try {
shuYunHttpRequest(HttpMethod.POST, null, JSON.toJSONString(shuYunPointChange),
shuYunConfig.getActionMethod().getPointChange());
} catch (Exception e) {
logger.error("请求数云接口-会员积分变更失败:{}", e);
throw new ServiceException("请求数云接口-会员积分变更失败");
}
}
}

@ -0,0 +1,99 @@
package com.flossom.system.utils.shuyun;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author flossom
*/
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "shuyun")
public class ShuYunConfig {
/**
*
*/
private String url;
/**
* appid
*/
private String appid;
/**
* security
*/
private String security;
/**
*
*/
private String authValue;
private String platCode;
private String shopId;
private ActionMethod actionMethod;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getSecurity() {
return security;
}
public void setSecurity(String security) {
this.security = security;
}
public ActionMethod getActionMethod() {
return actionMethod;
}
public void setActionMethod(ActionMethod actionMethod) {
this.actionMethod = actionMethod;
}
public String getPlatCode() {
return platCode;
}
public void setPlatCode(String platCode) {
this.platCode = platCode;
}
public String getShopId() {
return shopId;
}
public void setShopId(String shopId) {
this.shopId = shopId;
}
public String getAuthValue() {
return authValue;
}
public void setAuthValue(String authValue) {
this.authValue = authValue;
}
}

@ -0,0 +1,3 @@
http-pool.connect-timeout=60000
http-pool.connection-request-timeout=60000
http-pool.socket-timeout=60000

@ -42,3 +42,29 @@ export function delClockLog(id) {
method: 'delete'
})
}
export function allAddMiniProgramTag(tagIdList, data) {
return request({
url: '/system/clockLog/allAddMiniProgramTag?tagIdList=' + tagIdList,
method: 'post',
data: data
})
}
// 全量删除小程序标签
export function allDelMiniProgramTag(tagIdList, data) {
return request({
url: '/system/clockLog/allDelMiniProgramTag?tagIdList=' + tagIdList,
method: 'post',
data: data
})
}
export function detail(query) {
return request({
url: '/system/clockLog/detail',
method: 'get',
params: query
})
}

@ -3,31 +3,32 @@
<el-collapse accordion style="margin-bottom: 10px" v-model="activeNames">
<el-collapse-item name="search">
<template slot="title">
<div class="margin-top" style="border-left: solid 2px #419eff;padding-left: 10px;font-size: 18px !important;color: #000;">
<div class="margin-top"
style="border-left: solid 2px #419eff;padding-left: 10px;font-size: 18px !important;color: #000;">
搜索
</div>
</template>
<div style="margin-top: 10px">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
<div style="display: flex">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
label-width="100px">
<el-popover
placement="top-start"
width="200"
trigger="click"
content="手机号码和用户编号,满足其中之一内容即可"
>
<el-form-item label="用户编号" prop="id" slot="reference">
<el-form-item label="用户编号" prop="userIdList" slot="reference">
<el-input
v-model="queryParams.id"
v-model="queryParams.userIdList"
placeholder="搜索多个请用英文逗号隔开"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-popover>
<el-form-item label="会员昵称" prop="userId">
<el-form-item label="会员昵称" prop="nickname">
<el-input
v-model="queryParams.userId"
v-model="queryParams.nickname"
placeholder="请输入单个会员昵称搜索"
clearable
@keyup.enter.native="handleQuery"
@ -47,74 +48,45 @@
/>
</el-form-item>
</el-popover>
<el-form-item label="仪器名称" prop="source">
<el-select
v-model="queryParams.instrumentIdArray"
placeholder="请选择类型"
multiple
:style="{ width: '100%' }"
clearable
<el-form-item label="打卡时间" prop="clockDateRange">
<el-date-picker
style="width: 360px"
v-model="queryParams.clockDateRange"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
value-format="yyyy-MM-dd HH:mm:ss"
end-placeholder="结束日期"
align="right"
>
<el-option
v-for="item in instrumentList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</div>
<div style="display: flex">
<el-form-item label="打卡时间" prop="startTime">
<el-date-picker clearable
v-model="queryParams.startTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm"
placeholder="请选择操作开始时间">
</el-date-picker>
</el-form-item>
<el-form-item prop="endTime">
<el-date-picker clearable
v-model="queryParams.endTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm"
placeholder="请选择操作结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="用户注册时间" prop="startTime">
<el-date-picker clearable
v-model="queryParams.startTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm"
placeholder="请选择操作开始时间">
</el-date-picker>
</el-form-item>
<el-form-item prop="endTime">
<el-date-picker clearable
v-model="queryParams.endTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm"
placeholder="请选择操作结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="最新打卡时间" prop="startTime">
<el-date-picker clearable
v-model="queryParams.startTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm"
placeholder="请选择操作开始时间">
<el-form-item label="用户注册时间" prop="memberRegisterDateRange">
<el-date-picker
style="width: 360px"
v-model="queryParams.memberRegisterDateRange"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
value-format="yyyy-MM-dd HH:mm:ss"
end-placeholder="结束日期"
align="right"
>
</el-date-picker>
</el-form-item>
<el-form-item prop="endTime">
<el-date-picker clearable
v-model="queryParams.endTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm"
placeholder="请选择操作结束时间">
<el-form-item label="最新打卡时间" prop="clockLastDateRange">
<el-date-picker
style="width: 360px"
v-model="queryParams.clockLastDateRange"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
value-format="yyyy-MM-dd HH:mm:ss"
end-placeholder="结束日期"
align="right"
>
</el-date-picker>
</el-form-item>
</div>
<div style="display: flex">
<el-popover
placement="top-start"
width="200"
@ -127,7 +99,7 @@
slot="reference"
>
<el-select
v-model="queryParams.wecomTags"
v-model="queryParams.wecomTagList"
multiple
placeholder="请选择"
>
@ -153,7 +125,7 @@
slot="reference"
>
<el-select
v-model="queryParams.miniProgramTags"
v-model="queryParams.miniProgramTagList"
multiple
placeholder="请选择"
>
@ -167,21 +139,21 @@
</el-select>
</el-form-item>
</el-popover>
<el-form-item label="打卡范围" prop="credit">
<el-form-item label="打卡范围" prop="clockNumStart">
<el-input-number
:min="0"
:precision="0"
v-model="queryParams.creditStart"
v-model="queryParams.clockNumStart"
@keyup.enter.native="handleQuery"
></el-input-number>
<el-input-number
:min="0"
:precision="0"
v-model="queryParams.creditEnd"
v-model="queryParams.clockNumEnd"
@keyup.enter.native="handleQuery"
></el-input-number>
<el-button icon="el-icon-close" circle ></el-button>
<el-button icon="el-icon-close" circle @click="clearClockNum"></el-button>
</el-form-item>
<el-form-item>
<el-button
@ -200,7 +172,6 @@
</el-button
>
</el-form-item>
</div>
</el-form>
</div>
</el-collapse-item>
@ -230,14 +201,7 @@
<el-option label="批量删除小程序标签" :value="2"></el-option>
<el-option label="全量添加小程序标签" :value="3"></el-option>
<el-option label="全量删除小程序标签" :value="4"></el-option>
<el-option label="批量加减积分" :value="5"></el-option>
<el-option label="全量加减积分" :value="6"></el-option>
<el-option label="批量发送话术" :value="7"></el-option>
<el-option label="全量发送话术" :value="8"></el-option>
<el-option label="批量备注" :value="9"></el-option>
<el-option label="全量备注" :value="10"></el-option>
<el-option label="注销账号" :value="11"></el-option>
<el-option label="导出数据" :value="12"></el-option>
<el-option label="导出批量数据" :value="12"></el-option>
<el-option label="导出全量数据" :value="13"></el-option>
</el-select>
</el-col>
@ -247,6 +211,7 @@
plain
icon="el-icon-warning"
size="mini"
@click="batchOperate()"
>确认
</el-button>
</el-col>
@ -258,19 +223,31 @@
<el-table v-loading="loading" :data="clockLogList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="头像" align="center" prop="userId" />
<el-table-column label="会员昵称" align="center" prop="userId" />
<el-table-column label="用户编号" align="center" prop="userId" />
<el-table-column label="手机号码" align="center" prop="userId" />
<el-table-column label="仪器名称" align="center" prop="userId" />
<el-table-column label="打卡记录" align="center" prop="userId" />
<el-table-column label="打卡天数" align="center" prop="instrumentId" />
<el-table-column label="最新打卡时间" align="center" prop="instrumentName" />
<el-table-column label="小程序标签" align="center" prop="clockContent" />
<el-table-column label="外部标签" align="center" prop="clockContent" />
<el-table-column label="用户注册时间" align="center" prop="clockContent" />
<el-table-column label="状态" align="center" prop="status" />
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="头像" align="center">
<template slot-scope="scope">
<el-avatar shape="circle" :size="50" :src="scope.row.headimg"/>
</template>
</el-table-column>
<el-table-column label="会员昵称" align="center" prop="nickname"/>
<el-table-column label="用户编号" align="center" prop="userId"/>
<el-table-column label="手机号码" align="center" prop="mobile"/>
<el-table-column label="打卡记录" align="center" prop="clockNum" min-width="100">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
@click="viewClockDetail(scope.row)"
>
{{ '查看详情(' + scope.row.clockNum + '' }}
</el-button>
</template>
</el-table-column>
<el-table-column label="打卡天数" align="center" prop="clockNum"/>
<el-table-column label="最新打卡时间" align="center" prop="lastClockTime"/>
<el-table-column label="小程序标签" align="center" prop="miniProgramTagListStr"/>
<el-table-column label="外部标签" align="center" prop="wecomTagListStr"/>
<el-table-column label="用户注册时间" align="center" prop="memberRegisterDate"/>
</el-table>
<pagination
@ -280,21 +257,133 @@
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 小程序标签批量操作 -->
<el-dialog :title="this.miniProgramForm.title" :visible.sync="this.miniProgramForm.batchMiniProgramVisible"
width="50%" :before-close="cancelMiniProgramDialog">
<el-form ref="miniProgramForm" :model="miniProgramForm" :rules="batchMiniProgramRules" label-width="150px">
<el-row>
<el-col :span="100">
<el-form-item label="小程序标签" prop="tagIdArray" label-width="100px">
<treeselect
v-model="miniProgramForm.tagIdArray"
:options="chatTagOptions"
:multiple="true"
:show-count="true"
placeholder="请选择小程序标签"
:disable-branch-nodes="true"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancelMiniProgramDialog(false)"> </el-button>
<el-button type="primary" @click="submitBatchOperate"> </el-button>
</div>
</el-dialog>
<!-- 导出字段选择弹窗 -->
<el-dialog title="自定义导出字段" :visible.sync="exportFieldsForm.exportFieldsVisible" width="50%"
:before-close="cancelExportFieldsDialog">
<el-form ref="form" label-width="150px">
<el-form-item label="全部字段" prop="allFields">
<el-switch v-model="allFields" @click.native="isExportAllFields()"/>
</el-form-item>
</el-form>
<el-form :inline="true" ref="form" :model="exportFieldList" label-width="150px">
<el-form-item label="会员昵称" prop="nickname">
<el-switch v-model="exportFieldList.nickname" active-value="nickname" :inactive-value="null"/>
</el-form-item>
<el-form-item label="用户编号 " prop="userId">
<el-switch v-model="exportFieldList.userId" active-value="userId" :inactive-value="null"/>
</el-form-item>
<el-form-item label="手机号 " prop="mobile">
<el-switch v-model="exportFieldList.mobile" active-value="mobile" :inactive-value="null"/>
</el-form-item>
<el-form-item label="累计打卡仪器名称 " prop="instrumentName">
<el-switch v-model="exportFieldList.instrumentName" active-value="instrumentName" :inactive-value="null"/>
</el-form-item>
<el-form-item label="最新打卡时间 " prop="lastClockTime">
<el-switch v-model="exportFieldList.lastClockTime" active-value="lastClockTime" :inactive-value="null"/>
</el-form-item>
<el-form-item label="累计打卡时间 " prop="clockTime">
<el-switch v-model="exportFieldList.clockTime" active-value="clockTime" :inactive-value="null"/>
</el-form-item>
<el-form-item label="小程序标签 " prop="miniProgramTagListStr">
<el-switch v-model="exportFieldList.miniProgramTagListStr" active-value="miniProgramTagListStr"
:inactive-value="null"/>
</el-form-item>
<el-form-item label="累计打卡天数 " prop="clockNum">
<el-switch v-model="exportFieldList.clockNum" active-value="clockNum" :inactive-value="null"/>
</el-form-item>
<el-form-item label="用户注册时间 " prop="memberRegisterDate">
<el-switch v-model="exportFieldList.memberRegisterDate" active-value="memberRegisterDate"
:inactive-value="null"/>
</el-form-item>
<el-form-item label="外部标签 " prop="wecomTagListStr">
<el-switch v-model="exportFieldList.wecomTagListStr" active-value="wecomTagListStr" :inactive-value="null"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancelExportFieldsDialog()"> </el-button>
<el-button type="primary" @click="submitBatchOperate"> </el-button>
</div>
</el-dialog>
<!-- 查看用户积分列表 -->
<el-dialog title="打卡记录" :visible.sync="userClockLogVisible" width="90%" :before-close="cancelUserClockLogDialog">
<template>
<el-table :data="userClockLogQuery.userClockLogList" :stripe="true" style="width: 100%">
<el-table-column type="index" width="50" label="序号" />
<el-table-column prop="instrumentName" label="仪器名称" width="300px" />
<el-table-column prop="wxClockImgList" label="打卡图片" width="100" style="display: flex">
<template slot-scope="scope">
<div v-for="(val, index) in scope.row.wxClockImgList" :key="index">
<el-image :src="val.clockImg" style="width: 60px;height: 80px" :preview-src-list="[val.clockImg]">
<div slot="placeholder" class="image-slot"><span class="dot"></span>
</div>
</el-image>
</div>
</template>
</el-table-column>
<el-table-column prop="clockContent" label="打卡心得" width="300" />
<el-table-column prop="updateTime" label="打卡时间" width="200" />
</el-table>
</template>
<pagination
v-show="userClockLogQuery.total > 0"
:total="userClockLogQuery.total"
:page.sync="userClockLogQuery.pageNum"
:limit.sync="userClockLogQuery.pageSize"
@pagination="getClockLogDetail"
/>
</el-dialog>
</div>
</template>
<script>
import { listClockLog, getClockLog, delClockLog, addClockLog, updateClockLog } from "@/api/system/clockLog";
import {
listClockLog, getClockLog, delClockLog, addClockLog, updateClockLog,
allAddMiniProgramTag, allDelMiniProgramTag, detail
} from "@/api/system/clockLog";
import {listInstrument} from "@/api/system/instrument";
import {
getMiniProgramTags,
getWecomTags,
getMiniProgramTags, batchAddMiniProgramTag, batchDelMiniProgramTag, getWecomTags,
} from '@/api/system/member'
import {tagTreeSelect} from "@/api/system/wechatTab";
import Treeselect from '@riophae/vue-treeselect';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
export default {
name: "ClockLog",
components: {Treeselect},
data() {
return {
batchOperateValue: '',
//
activeNames: ['search'],
//
@ -309,6 +398,7 @@ export default {
showSearch: true,
//
total: 0,
chatTagOptions: [],
//
clockLogList: [],
//
@ -325,17 +415,64 @@ export default {
queryParams: {
pageNum: 1,
pageSize: 10,
userIdList: null,
nickname: null,
mobile: null,
wecomTagList: null,
miniProgramTagList: null,
memberRegisterDateRange: null,
clockDateRange: null,
clockLastDateRange: null,
clockNumStart: undefined,
clockNumEnd: undefined,
},
//
batchOperateValue: null,
miniProgramForm: {
title: null,
batchMiniProgramVisible: false,
tagIdArray: [],
userIdList: [],
},
//
exportFieldsForm: {
idList: null,
exportFields: null,
exportFieldsVisible: false,
},
allFields: false,
exportFieldList: {
nickname: null,
userId: null,
instrumentId: null,
mobile: null,
clockNum: null,
lastClockTime: null,
miniProgramTagListStr: null,
wecomTagListStr: null,
memberRegisterDate: null,
instrumentName: null,
clockContent: null,
status: null,
clockTime: null,
},
//
userClockLogVisible: false,
userClockLogQuery: {
total: 0,
pageNum: 1,
pageSize: 10,
userClockLogList: null,
userIdList: null,
clockDateRange: null,
},
//
form: {},
//
rules: {
}
rules: {},
//
batchMiniProgramRules: {
tagIdArray: [
{required: true, message: '请选择小程序标签', trigger: 'change'},
],
},
};
},
created() {
@ -344,7 +481,7 @@ export default {
this.getTag();
},
methods: {
getTag(){
getTag() {
//
getMiniProgramTags().then((Response) => {
this.miniProgramTags = Response.data
@ -354,7 +491,7 @@ export default {
this.wecomTags = Response.data
})
},
queryInstrument(){
queryInstrument() {
listInstrument({}).then(response => {
this.instrumentList = response.rows;
});
@ -376,17 +513,18 @@ export default {
//
reset() {
this.form = {
id: null,
headimg: null,
nickname: null,
userId: null,
instrumentId: null,
instrumentName: null,
clockContent: null,
status: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
mobile: null,
clockNum: null,
lastClockTime: null,
miniProgramTagListStr: null,
wecomTagListStr: null,
memberRegisterDate: null,
};
this.queryParams.clockNumStart = undefined,
this.queryParams.clockNumEnd = undefined,
this.resetForm("form");
},
/** 搜索按钮操作 */
@ -402,7 +540,10 @@ export default {
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
let selectedUserIdList = selection.map(item => item.userId)
this.miniProgramForm.userIdList = selectedUserIdList;
this.exportFieldsForm.idList = selectedUserIdList;
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
@ -444,19 +585,259 @@ export default {
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除用户打卡编号为"' + ids + '"的数据项?').then(function() {
this.$modal.confirm('是否确认删除用户打卡编号为"' + ids + '"的数据项?').then(function () {
return delClockLog(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/clockLog/export', {
...this.queryParams
}, `clockLog_${new Date().getTime()}.xlsx`)
},
clearClockNum() {
this.queryParams.clockNumStart = undefined;
this.queryParams.clockNumEnd = undefined;
},
viewClockDetail(row) {
this.userClockLogQuery.userIdList = row.userId;
this.userClockLogQuery.clockDateRange = this.queryParams.clockDateRange
this.getClockLogDetail();
//
this.userClockLogVisible = true;
},
getClockLogDetail() {
detail(this.userClockLogQuery).then(response => {
this.userClockLogQuery.total = response.total;
this.userClockLogQuery.userClockLogList = response.rows;
});
},
/** 批量操作按钮,显示批量操作弹窗 */
batchOperate() {
if (this.batchOperateValue == null) {
this.$message({
message: '请选择要批量操作类型',
type: 'warning',
})
return;
} else {
/* 批量操作 小程序标签 */
if (this.batchOperateValue == 1 || this.batchOperateValue == 2) {
if (this.ids.length == 0) {
this.$message({
message: '请选择要操作的数据',
type: 'warning',
})
return
}
if (this.batchOperateValue == 1) {
this.miniProgramForm.title = '添加小程序标签'
}
if (this.batchOperateValue == 2) {
this.miniProgramForm.title = '删除小程序标签'
}
//
this.getDeptTree()
this.miniProgramForm.batchMiniProgramVisible = true
}
if (this.batchOperateValue == 3 || this.batchOperateValue == 4) {
if (this.batchOperateValue == 3) {
this.miniProgramForm.title = '添加小程序标签'
}
if (this.batchOperateValue == 4) {
this.miniProgramForm.title = '删除小程序标签'
}
//
this.getDeptTree()
this.miniProgramForm.batchMiniProgramVisible = true
}
/* 批量操作:导出数据 */
if (this.batchOperateValue == 12) {
if (this.ids.length == 0) {
this.$message({
message: '请选择要操作的数据',
type: 'warning',
})
return
}
this.exportFieldsForm.exportFieldsVisible = true
}
if (this.batchOperateValue == 13) {
this.exportFieldsForm.exportFieldsVisible = true
}
}
},
/** 查询部门下拉树结构 */
getDeptTree() {
tagTreeSelect({type: 1}).then((response) => {
this.chatTagOptions = response.data
})
},
//
cancelMiniProgramDialog(isClose) {
this.$refs.miniProgramForm.clearValidate();
this.miniProgramForm.tagIdArray = []
if (isClose) {
this.miniProgramForm.title = null
this.miniProgramForm.batchMiniProgramVisible = false
}
},
/* 批量操作提交按钮 */
submitBatchOperate() {
//
if (this.batchOperateValue == 1) {
this.$refs['miniProgramForm'].validate((valid) => {
if (valid) {
batchAddMiniProgramTag(
this.miniProgramForm.tagIdArray,
Array.from(new Set(this.miniProgramForm.userIdList))
).then((Response) => {
this.$modal.msgSuccess('批量添加小程序标签成功');
this.cancelMiniProgramDialog(true)
this.getList();
})
}
})
}
//
if (this.batchOperateValue == 2) {
this.$refs['miniProgramForm'].validate((valid) => {
if (valid) {
batchDelMiniProgramTag(
this.miniProgramForm.tagIdArray,
Array.from(new Set(this.miniProgramForm.userIdList))
).then((Response) => {
this.$modal.msgSuccess('批量删除小程序标签成功')
this.cancelMiniProgramDialog(true)
this.getList();
})
}
})
}
//
if (this.batchOperateValue == 3) {
this.$refs['miniProgramForm'].validate((valid) => {
if (valid) {
allAddMiniProgramTag(
this.miniProgramForm.tagIdArray,
this.queryParams
).then((Response) => {
this.$modal.msgSuccess('全量添加小程序标签成功')
this.cancelMiniProgramDialog(true)
this.getList();
})
}
})
}
//
if (this.batchOperateValue == 4) {
this.$refs['miniProgramForm'].validate((valid) => {
if (valid) {
allDelMiniProgramTag(
this.miniProgramForm.tagIdArray,
this.queryParams
).then((Response) => {
this.$modal.msgSuccess('全量删除小程序标签成功')
this.cancelMiniProgramDialog(true)
this.getList();
})
}
})
}
//
if (this.batchOperateValue == 12) {
let exportFields = Object.values(this.exportFieldList).filter(
(val) => val != null
)
if (exportFields.length == 0) {
this.$modal.msgError('请选择导出字段')
return
}
this.exportFieldsForm.exportFields = exportFields
this.download('/system/clockLog/batchExport', {
...this.exportFieldsForm,
},
`打卡记录数据_${new Date().getTime()}.xlsx`
)
this.cancelExportFieldsDialog()
}
if (this.batchOperateValue == 13) {
let exportFields = Object.values(this.exportFieldList).filter(
(val) => val != null
)
if (exportFields.length == 0) {
this.$modal.msgError('请选择导出字段')
return
}
this.download(
'/system/clockLog/allExport',
{
...Object.assign({}, this.queryParams, {
exportFields: exportFields,
}),
},
`打卡记录数据_${new Date().getTime()}.xlsx`
)
this.cancelExportFieldsDialog()
}
},
cancelExportFieldsDialog() {
this.allFields = false
this.exportFieldsForm.exportFieldsVisible = false
this.exportFieldList = {
nickname: null,
userId: null,
mobile: null,
clockNum: null,
lastClockTime: null,
miniProgramTagListStr: null,
wecomTagListStr: null,
memberRegisterDate: null,
instrumentName: null,
clockTime: null,
}
},
isExportAllFields() {
if (this.allFields) {
this.exportFieldList.nickname = "nickname";
this.exportFieldList.userId = "userId";
this.exportFieldList.mobile = "mobile";
this.exportFieldList.clockNum = "clockNum";
this.exportFieldList.lastClockTime = "lastClockTime";
this.exportFieldList.miniProgramTagListStr = "miniProgramTagListStr";
this.exportFieldList.wecomTagListStr = "wecomTagListStr";
this.exportFieldList.memberRegisterDate = "memberRegisterDate";
this.exportFieldList.instrumentName = "instrumentName";
this.exportFieldList.clockTime = "clockTime";
} else {
this.exportFieldList.nickname = null;
this.exportFieldList.userId = null;
this.exportFieldList.mobile = null;
this.exportFieldList.clockNum = null;
this.exportFieldList.lastClockTime = null;
this.exportFieldList.miniProgramTagListStr = null;
this.exportFieldList.wecomTagListStr = null;
this.exportFieldList.memberRegisterDate = null;
this.exportFieldList.instrumentName = null;
this.exportFieldList.clockTime = null;
}
},
cancelUserClockLogDialog() {
this.userClockLogVisible = false
this.userClockLogQuery = {
total: 0,
pageNum: 1,
pageSize: 10,
userClockLogList: null,
}
},
}
};
</script>

@ -2189,12 +2189,62 @@ export default {
},
/* 仪器类型切换 */
typeChange() {
// IOT
if (this.form.type == 1) {
/**
* 两个都有但需要根据仪器 仪器类型和仪器型号来查询数据
* 模式带new标识模式
*/
/**
* IOT 特有
* 仪器型号默认WL200
* 生成护理记录最短时间
*
* 蓝牙连接中图片
* 蓝牙连接中标题
* 蓝牙连接中文案
*
* 蓝牙连接失败图片
* 蓝牙连接失败标题
* 蓝牙连接失败文案
*
* 蓝牙连断开接图片
* 蓝牙断开连接标题
* 蓝牙断开连接文案
*
* we200蓝牙连接中图片(WL200仪器特有)
* we200蓝牙连接中标题(WL200仪器特有)
* we200蓝牙连接中文案(WL200仪器特有)
*
* IOT版本
* IOT升级数据文件
* IOT版本升级介绍
*
* we200IOT版本(WL200仪器特有)
* we200IOT升级数据文件(WL200仪器特有)
* we200IOT版本升级介绍(WL200仪器特有)
*/
// IOT WL200
if (this.form.type == 2) {
this.form.model = 'WL200';
}
/* 模式选项 */
//
this.form.modeIdsValue = [];
this.modeIdsOptions = [];
// new
this.form.newModeIdList = [];
this.newModeOptionList = [];
listAllMode({
instrumentType: this.form.type,
instrumentModel: this.form.model,
}).then((response) => {
if (response.code != 200) {
this.$message.error('模式获取失败')
}
this.mode.modeIdsOptions = response.data
})
//
this.form.model = null
this.form.nursingTime = null
this.form.iotVersion = null
this.form.iotUpgradeData = null
this.form.bluetoothConnecting = null
this.form.bluetoothConnectingTitle = null
this.form.bluetoothConnectingContent = null
@ -2204,23 +2254,10 @@ export default {
this.form.bluetoothClosed = null
this.form.bluetoothClosedTitle = null
this.form.bluetoothClosedContent = null
this.form.iotVersion = null
this.form.iotUpgradeData = null
this.form.iotVersionUpgrade = null
this.form.modeIdsValue = []
} else {
this.form.model = 'WL200'
this.form.modeIdsValue = []
}
/* 模式选项 */
this.mode.modeIdsOptions = []
listAllMode({
instrumentType: this.form.type,
instrumentModel: this.form.model,
}).then((response) => {
if (response.code != 200) {
this.$message.error('模式获取失败')
}
this.mode.modeIdsOptions = response.data
})
/* we200数据清空 */
this.form.we200IotVersion = null;
this.form.we200IotUpgradeData = null;
this.form.we200IotVersionUpgrade = null;
@ -2235,6 +2272,14 @@ export default {
modelChange() {
/* 模式选项 */
this.mode.modeIdsOptions = []
// new
//
this.form.modeIdsValue = [];
this.modeIdsOptions = [];
// new
this.form.newModeIdList = [];
this.newModeOptionList = [];
//
listAllMode({
instrumentType: this.form.type,
instrumentModel: this.form.model,
@ -2244,7 +2289,7 @@ export default {
}
this.mode.modeIdsOptions = response.data
})
/* 清空we200 对应的数据 */
this.form.we200IotVersion = null;
this.form.we200IotUpgradeData = null;
this.form.we200IotVersionUpgrade = null;

@ -200,7 +200,7 @@
</el-form-item>
</el-col>
<el-col :span ="12">
<el-form-item label="自定义组合" prop="isCustomMode" v-if="(form.modeType != 'MaskCustom'&&form.instrumentType==2)" label-width="100px">
<el-form-item label="自定义组合" prop="isCustomMode" v-if="(form.modeType != 'MaskCustom'&&form.instrumentType==2&&form.instrumentModel=='WL200')" label-width="100px">
<el-select v-model="form.isCustomMode">
<el-option label="是" :value="1"></el-option>
<el-option label="否" :value="0"></el-option>
@ -733,7 +733,7 @@ export default {
this.form.serviceData = this.serviceData;
let flag = false;
let serverImageFlag = false;
if (this.form.serviceData.length > 0) {
if (this.form.instrumentType == 2 && this.form.serviceData.length > 0) {
this.form.serviceData.forEach(data => {
if(data.startTimeArray == null || data.startTimeArray.length == 0) {
flag = true;
@ -754,15 +754,12 @@ export default {
}
})
} else {
this.$message.error("启动/暂停图片不能为空");
return;
}
if (flag) {
this.$message.error("护理时间范围不能为空");
return;
}
if (serverImageFlag) {
if (this.form.instrumentType == 2 && !serverImageFlag) {
this.$message.error("启动/暂停图片不能为空");
return;
}

Loading…
Cancel
Save