瀏覽代碼

企微聊天小程序消息处理

Long 1 周之前
父節點
當前提交
f065bc6ef5

+ 24 - 0
fs-company/src/main/java/com/fs/qw/QwMsgController.java

@@ -1,6 +1,7 @@
 package com.fs.qw;
 
 import com.fs.common.annotation.Log;
+import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
@@ -12,6 +13,7 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.core.security.LoginUser;
 import com.fs.core.web.service.TokenService;
+import com.fs.course.param.FsCourseLinkMiniParam;
 import com.fs.course.param.FsCourseListBySidebarParam;
 import com.fs.course.service.IFsUserCourseService;
 import com.fs.course.service.IFsUserCourseVideoService;
@@ -42,6 +44,7 @@ import org.springframework.web.bind.annotation.*;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * 企微聊天记录Controller
@@ -263,4 +266,25 @@ public class QwMsgController extends BaseController
         PageInfo<FsCourseVideoListBySidebarVO> result = new PageInfo<>(videoListBySidebar);
         return R.ok().put("data", result);
     }
+
+    /**
+     * 创建 发客户小程序
+     */
+    @RepeatSubmit
+    @PostMapping("/createMiniLink")
+    public R createMiniLink(@RequestBody FsCourseLinkMiniParam param) {
+
+        if (Objects.isNull(param.getCourseId())){
+            return R.error("课程id不能为空");
+        }
+        if (Objects.isNull(param.getVideoId())){
+            return R.error("视频id不能为空");
+        }
+
+        if (Objects.isNull(param.getExtId())){
+            return R.error("客户id不能为空");
+        }
+
+        return fsUserCourseVideoService.createMiniLink(param);
+    }
 }

+ 34 - 1
fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java

@@ -237,7 +237,10 @@ public class QwMsgController {
                 else if (wxWorkMessageDTO.getMsgtype() == 104){
                     processEmotionDynamicMessage(wxWorkMessageDTO, wxWorkMsgResp, id, userId, sendType);
                 }
-
+                // 小程序消息
+                else if (wxWorkMessageDTO.getMsgtype() == 78) {
+                    processMiniAppMessage(serverId, wxWorkMessageDTO, wxWorkMsgResp, id, userId, sendType);
+                }
                 break;
 
         }
@@ -248,6 +251,36 @@ public class QwMsgController {
         return map;
     }
 
+    /**
+     * 小程序消息处理
+     * @param serverId          服务器ID
+     * @param wxWorkMessageDTO  消息DTO
+     * @param wxWorkMsgResp     回调信息对象
+     * @param id                企微用户ID
+     * @param userId            消息发送者ID
+     * @param sendType          发送者类型 1客户 2销售
+     */
+    private void processMiniAppMessage(Long serverId, WxWorkMessageDTO wxWorkMessageDTO, WxWorkMsgResp wxWorkMsgResp, Long id, Long userId, int sendType) {
+        System.out.println(wxWorkMsgResp.getJson());
+        String thumbName = IdUtils.fastSimpleUUID() + ".jpg";
+        WxWorkResponseDTO<String> fileUrlResp =
+                aiHookService.getFileUrl(wxWorkMsgResp.getUuid(), wxWorkMessageDTO.getThumbFileId(), wxWorkMessageDTO.getThumbAESKey(), 3, thumbName, wxWorkMessageDTO.getSize(), serverId);
+        if (fileUrlResp.getErrcode() != 0) {
+            log.warn("获取图片地址失败: {}", fileUrlResp.getErrmsg());
+            return;
+        }
+
+        JSONObject json = new JSONObject();
+        json.put("appid", wxWorkMessageDTO.getAppid());
+        json.put("pagepath", wxWorkMessageDTO.getPagepath());
+        json.put("title", wxWorkMessageDTO.getTitle());
+        json.put("thumbnail", fileUrlResp.getData());
+
+        // 保存聊天消息
+        QwMessageListVO message = aiHookService.saveQwMsg(id, userId, json.toString(), wxWorkMsgResp.getUuid(), sendType, wxWorkMsgResp.getJson(), 5);
+        QwImSocket.broadcast(message);
+    }
+
     /**
      * 处理文本消息
      * @param id                企微用户ID

+ 24 - 0
fs-service-system/src/main/java/com/fs/course/param/FsCourseLinkMiniParam.java

@@ -0,0 +1,24 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+@Data
+public class FsCourseLinkMiniParam {
+    /**
+     * 小节ID
+     */
+    private Long videoId;
+    /**
+     * 课程ID
+     */
+    private Long courseId;
+    /**
+     * 视频标题
+     */
+    private String title;
+    /**
+    * 外部联系人主键
+    */
+    private Long extId;
+
+}

+ 2 - 0
fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java

@@ -160,4 +160,6 @@ public interface IFsUserCourseVideoService
     List<OptionsVO> selectVideoListByMap(Map<String, Object> params);
 
     List<FsCourseVideoListBySidebarVO> getFsCourseVideoListBySidebar(FsCourseListBySidebarParam param);
+
+    R createMiniLink(FsCourseLinkMiniParam param);
 }

+ 137 - 0
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -3,6 +3,7 @@ package com.fs.course.service.impl;
 import cn.hutool.core.util.NumberUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.core.domain.R;
@@ -29,10 +30,12 @@ import com.fs.course.vo.FsUserCourseVideoVO;
 import com.fs.course.vo.newfs.*;
 import com.fs.his.param.WxSendRedPacketParam;
 import com.fs.his.vo.OptionsVO;
+import com.fs.qw.domain.QwCompany;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwUserMapper;
+import com.fs.qw.service.IQwCompanyService;
 import com.fs.qwApi.Result.QwAddContactWayResult;
 import com.fs.qwApi.param.QwAddContactWayParam;
 import com.fs.qwApi.service.QwApiService;
@@ -49,6 +52,7 @@ import com.fs.store.service.IFsStorePaymentService;
 import com.fs.store.service.IFsUserService;
 import com.fs.store.service.cache.IFsUserCourseCacheService;
 import com.fs.system.service.ISysConfigService;
+import com.fs.voice.utils.StringUtil;
 import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.Logger;
@@ -61,11 +65,14 @@ import org.springframework.transaction.annotation.Transactional;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
 
+import static com.fs.course.utils.LinkUtil.generateRandomStringWithLock;
+
 /**
  * 课堂视频Service业务层处理
  *
@@ -77,6 +84,11 @@ import java.util.stream.Collectors;
 public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 {
     private static final Logger logger = LoggerFactory.getLogger(FsUserCourseVideoServiceImpl.class);
+
+    private static final String miniappRealLink = "/pages_course/video.html?course=";
+    private static final String REAL_LINK_PREFIX = "/courseH5/pages/course/learning?course=";
+    private static final String SHORT_LINK_PREFIX = "/courseH5/pages/course/learning?s=";
+
     @Autowired
     private FsUserCourseVideoMapper fsUserCourseVideoMapper;
     @Autowired
@@ -153,6 +165,12 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     private FsUserCompanyUserMapper fsUserCompanyUserMapper;
     @Autowired
     private IFsUserCourseCacheService fsUserCourseCacheService;
+    @Autowired
+    private IQwCompanyService qwCompanyService;
+    @Autowired
+    private FsCourseWatchLogMapper fsCourseWatchLogMapper;
+    @Autowired
+    private FsCourseLinkMapper fsCourseLinkMapper;
 
     /**
      * 查询课堂视频
@@ -1198,6 +1216,125 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         return fsUserCourseVideoMapper.getFsCourseVideoListBySidebar(param);
     }
 
+    @Override
+    public R createMiniLink(FsCourseLinkMiniParam param) {
+        QwExternalContact qwExternalContact = qwExternalContactMapper.selectById(param.getExtId());
+        if (Objects.isNull(qwExternalContact)) {
+            return R.error("客户不存在");
+        }
+        QwUser qwUser = qwUserMapper.selectById(qwExternalContact.getQwUserId());
+        if (Objects.isNull(qwUser) || Objects.isNull(qwUser.getCompanyId()) || Objects.isNull(qwUser.getCompanyUserId())){
+            return R.error("员工未绑定 销售公司 或 销售 请先绑定");
+        }
+
+        QwCompany qwCompany = qwCompanyService.selectQwCompanyByCorpId(qwUser.getCorpId());
+        if (Objects.isNull(qwCompany)) {
+            return R.error().put("msg","企业不存在,请联系管理员");
+        }
+
+        //看课记录
+        addWatchLogIfNeeded(param.getVideoId(), param.getCourseId(), qwExternalContact.getFsUserId(), qwUser, qwExternalContact.getId());
+
+        //生成小程序链接
+        String linkByMiniApp = createLinkByMiniApp(new Date(), param.getCourseId(), param.getVideoId(), qwUser, qwExternalContact.getId(),2,null);
+
+        JSONObject news = new JSONObject(true);
+        news.put("miniprogramAppid", qwCompany.getMiniAppId());
+        news.put("miniprogramTitle", param.getTitle());
+        news.put("miniprogramPicUrl", "https://cos.his.cdwjyyh.com/fs/20250523/9c8af5735d784847818cada7fa776a7b.jpg");
+        news.put("miniprogramPage", linkByMiniApp);
+
+        return R.ok().put("data",news);
+    }
+
+    private String createLinkByMiniApp(Date sendTime, Long courseId, Long videoId,
+                                       QwUser qwUser, Long externalId,int type,String domainName) {
+        FsCourseLink link = new FsCourseLink();
+        link.setCompanyId(qwUser.getCompanyId());
+        link.setQwUserId(String.valueOf(qwUser.getId()));
+        link.setCompanyUserId(qwUser.getCompanyUserId());
+        link.setVideoId(videoId);
+        link.setCorpId(qwUser.getCorpId());
+        link.setCourseId(courseId);
+        link.setQwExternalId(externalId);
+
+        if (type == 1) {
+            link.setLinkType(0);
+        }else {
+            link.setLinkType(3);
+        }
+
+        String randomString = generateRandomStringWithLock();
+        if (StringUtil.strIsNullOrEmpty(randomString)){
+            link.setLink(UUID.randomUUID().toString().replace("-", ""));
+        }else {
+            link.setLink(randomString);
+        }
+
+        link.setCreateTime(sendTime);
+
+        FsCourseRealLink courseMap = new FsCourseRealLink();
+        BeanUtils.copyProperties(link,courseMap);
+
+        String courseJson = JSON.toJSONString(courseMap);
+
+        String realLinkFull;
+
+        if (type == 1) {
+            realLinkFull = REAL_LINK_PREFIX + courseJson;
+        }else {
+            realLinkFull = miniappRealLink + courseJson;
+        }
+
+        link.setRealLink(realLinkFull);
+
+        // 使用 Java 8 时间 API 计算过期时间
+        LocalDateTime sendDateTime = sendTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+        LocalDateTime expireDateTime = sendDateTime.plusDays(0);
+        expireDateTime = expireDateTime.toLocalDate().atTime(23, 59, 59);
+        Date updateTime = Date.from(expireDateTime.atZone(ZoneId.systemDefault()).toInstant());
+        link.setUpdateTime(updateTime);
+
+        //存短链-
+        fsCourseLinkMapper.insertFsCourseLink(link);
+
+        if (type==1){
+            return domainName + SHORT_LINK_PREFIX + link.getLink();
+        }else {
+            return link.getRealLink();
+        }
+    }
+
+    // 插入观看记录
+    private void addWatchLogIfNeeded(Long videoId, Long courseId,
+                                     Long fsUserId, QwUser qwUser,Long externalId) {
+
+        try {
+            FsCourseWatchLog watchLog = new FsCourseWatchLog();
+            watchLog.setVideoId(videoId);
+            watchLog.setQwExternalContactId(externalId);
+            watchLog.setSendType(2);
+            watchLog.setQwUserId(String.valueOf(qwUser.getId()));
+            watchLog.setDuration(0L);
+            watchLog.setCourseId(courseId);
+            watchLog.setCompanyUserId(qwUser.getCompanyUserId());
+            watchLog.setCompanyId(qwUser.getCompanyId());
+            watchLog.setCreateTime(new Date());
+            watchLog.setUpdateTime(new Date());
+            watchLog.setLogType(3);
+
+            if (fsUserId == null) {
+                fsUserId=0L;
+            }
+            watchLog.setUserId(fsUserId);
+
+            //存看课记录
+            fsCourseWatchLogMapper.insertOrUpdateFsCourseWatchLog(watchLog);
+        }catch (Exception e){
+            logger.error("一键群发失败-插入观看记录失败:"+e.getMessage());
+        }
+    }
+
     //会员-更新心跳时间
     public void updateHeartbeatWx(FsUserCourseVideoUParam param) {
         String redisKey = "h5wxuser:watch:heartbeat:" + param.getUserId() + ":" + param.getVideoId() + ":" + param.getCompanyUserId();

+ 1 - 1
fs-service-system/src/main/java/com/fs/fastGpt/service/AiHookService.java

@@ -28,7 +28,7 @@ public interface AiHookService {
      * @param uuid     UUID
      * @param sendType 发送者类型 1用户 2客服
      * @param json     消息json
-     * @param msgType  消息类型 1文本 2图片 3动态表情 4语音
+     * @param msgType  消息类型 1文本 2图片 3动态表情 4语音 5小程序
      */
     QwMessageListVO saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType, String json, int msgType);
 

+ 2 - 0
fs-service-system/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java

@@ -1351,6 +1351,8 @@ public class AiHookServiceImpl implements AiHookService {
             type = "emotionDynamic";
         } else if (msgType == 4) {
             type = "voice";
+        } else if (msgType == 5) {
+            type = "miniprogram";
         }
         listVO.setType(type);
         listVO.setStatus("succeed");

+ 3 - 0
fs-service-system/src/main/java/com/fs/qw/domain/QwCompany.java

@@ -77,4 +77,7 @@ public class QwCompany extends BaseEntity
     private String msgSecret;
 
     private String msgPrivateKey;
+
+    /** 小程序ID */
+    private String miniAppId;
 }

+ 1 - 1
fs-service-system/src/main/java/com/fs/qw/param/QwMsgSendParam.java

@@ -9,6 +9,6 @@ public class QwMsgSendParam implements Serializable {
     private Long sessionId;
     private String content;//内容
     private String appKey;
-    // 消息类型 1文本 2图片
+    // 消息类型 1文本 2图片 3动态表情 4语音 5小程序
     private Integer msgType;
 }

+ 44 - 0
fs-service-system/src/main/java/com/fs/qw/service/impl/QwMsgServiceImpl.java

@@ -2,6 +2,7 @@ package com.fs.qw.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.http.HttpRequest;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -335,6 +336,43 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
                 return R.error(imgMsgResp.getErrmsg());
             }
             msgJson = JSONObject.toJSONString(imgMsgDTO);
+        }
+        // 小程序
+        else if (param.getMsgType() == 5) {
+            JSONObject json = JSON.parseObject(param.getContent());
+            String appid = json.getString("appid");
+            String page = json.getString("pagepath");
+            String title = json.getString("title");
+            String thumbnail = json.getString("thumbnail");
+
+            // 上传cdn
+            WxCdnUploadImgLinkDTO linkDTO = new WxCdnUploadImgLinkDTO();
+            linkDTO.setUuid(uuid);
+            linkDTO.setUrl(thumbnail);
+            WxWorkResponseDTO<WxCdnUploadImgLinkResp> imgLinkResp = wxWorkService.cdnUploadImgLink(linkDTO, serverId);
+            if (imgLinkResp.getErrcode() != 0) {
+                return R.error(imgLinkResp.getErrmsg());
+            }
+            WxCdnUploadImgLinkResp data = imgLinkResp.getData();
+
+            // 发送小程序消息
+            WxWorkSendAppMsgDTO appMsgDTO = new WxWorkSendAppMsgDTO();
+            appMsgDTO.setUuid(uuid);
+            appMsgDTO.setSendUserid(sendUserId);
+            appMsgDTO.setTitle(title);
+            appMsgDTO.setPagepath(page);
+            appMsgDTO.setAppid(appid);
+            appMsgDTO.setCdnkey(data.getCdn_key());
+            appMsgDTO.setMd5(data.getThumb_file_md5());
+            appMsgDTO.setAeskey(data.getAes_key());
+            appMsgDTO.setFileSize(data.getThumb_file_size());
+            appMsgDTO.setIsRoom(false);
+            WxWorkResponseDTO<WxWorkSendAppMsgRespDTO> appMsgResp = wxWorkService.SendAppMsg(appMsgDTO, serverId);
+            if (appMsgResp.getErrcode() != 0) {
+                return R.error(appMsgResp.getErrmsg());
+            }
+
+            msgJson = param.getContent();
         } else {
             return R.error("暂不支持的消息类型");
         }
@@ -368,6 +406,8 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
             type = "image";
         } else if (param.getMsgType() == 3) {
             type = "emotionDynamic";
+        } else if (param.getMsgType() == 5) {
+            type = "miniprogram";
         }
         listVO.setType(type);
         listVO.setStatus("succeed");
@@ -450,6 +490,8 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
                 listVO.setType("emotionDynamic");
             } else if (qwMsg.getMsgType() == 4) {
                 listVO.setType("voice");
+            } else if (qwMsg.getMsgType() == 5) {
+                listVO.setType("miniprogram");
             }
             listVO.setMsgId(qwMsg.getMsgId());
             listVO.setLastContent(qwMsgs.get(0).getContent());
@@ -486,6 +528,8 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
                 type = "emotionDynamic";
             } else if (record.getMsgType() == 4) {
                 type = "voice";
+            } else if (record.getMsgType() == 5) {
+                type = "miniprogram";
             }
             listVO.setType(type);
             listVO.setStatus("succeed");

+ 9 - 0
fs-service-system/src/main/java/com/fs/wxwork/dto/WxWorkMessageDTO.java

@@ -33,4 +33,13 @@ public class WxWorkMessageDTO {
     // 语音
     private String voice_id;
     private Integer voice_size;
+
+    // 小程序
+    private String appid;
+    private String thumbFileId;
+    private String thumbMD5;
+    private String thumbAESKey;
+    private Integer size;
+    private String title;
+    private String pagepath;
 }

+ 1 - 1
fs-service-system/src/main/java/com/fs/wxwork/service/WxWorkService.java

@@ -36,7 +36,7 @@ public interface WxWorkService {
      * @param param 参数
      * @return QwWorkResponseDTO
      */
-    WxWorkSendAppMsgRespDTO SendAppMsg(WxWorkSendAppMsgDTO param,Long serverId);
+    WxWorkResponseDTO<WxWorkSendAppMsgRespDTO> SendAppMsg(WxWorkSendAppMsgDTO param,Long serverId);
 
     /**
      * 发送链接消息

+ 2 - 2
fs-service-system/src/main/java/com/fs/wxwork/service/WxWorkServiceImpl.java

@@ -66,9 +66,9 @@ public class WxWorkServiceImpl implements WxWorkService {
     }
 
     @Override
-    public WxWorkSendAppMsgRespDTO SendAppMsg(WxWorkSendAppMsgDTO param,Long serverId) {
+    public WxWorkResponseDTO<WxWorkSendAppMsgRespDTO> SendAppMsg(WxWorkSendAppMsgDTO param,Long serverId) {
         String url = getUrl(serverId) + "/SendAppMsg";
-        return WxWorkHttpUtil.postWithType(url, param, new TypeReference<WxWorkSendAppMsgRespDTO>() {
+        return WxWorkHttpUtil.postWithType(url, param, new TypeReference<WxWorkResponseDTO<WxWorkSendAppMsgRespDTO>>() {
         });
     }
 

+ 6 - 1
fs-service-system/src/main/resources/mapper/qw/QwCompanyMapper.xml

@@ -26,10 +26,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="updateTime"    column="update_time"    />
         <result property="createBy"    column="create_by"    />
         <result property="isBuy"    column="is_buy"    />
+        <result property="miniAppId"    column="mini_app_id"    />
     </resultMap>
 
     <sql id="selectQwCompanyVo">
-        select id, corp_id, corp_name, open_secret, open_corp_id, server_agent_id, server_book_corp_id, server_book_secret, token, encoding_aes_key, provider_secret, realm_name_url, notify_url, chat_toolbar, chat_toolbar_oauth, company_ids, status, create_time, update_time, create_by,is_buy from qw_company
+        select id, corp_id, corp_name, open_secret, open_corp_id, server_agent_id, server_book_corp_id, server_book_secret, token, encoding_aes_key, provider_secret, realm_name_url, notify_url, chat_toolbar, chat_toolbar_oauth, company_ids, status, create_time, update_time, create_by,is_buy, mini_app_id from qw_company
     </sql>
 
     <select id="selectQwCompanyList" parameterType="QwCompany" resultMap="QwCompanyResult">
@@ -52,6 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyIds != null  and companyIds != ''"> and company_ids = #{companyIds}</if>
             <if test="status != null "> and status = #{status}</if>
             <if test="isBuy != null "> and isBuy = #{isBuy}</if>
+            <if test="miniAppId != null "> and mini_app_id = #{miniAppId}</if>
         </where>
     </select>
     
@@ -89,6 +91,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateTime != null">update_time,</if>
             <if test="createBy != null">create_by,</if>
             <if test="isBuy != null">is_buy,</if>
+            <if test="miniAppId != null">mini_app_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="corpId != null">#{corpId},</if>
@@ -111,6 +114,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateTime != null">#{updateTime},</if>
             <if test="createBy != null">#{createBy},</if>
             <if test="isBuy != null">#{isBuy},</if>
+            <if test="miniAppId != null">#{miniAppId},</if>
          </trim>
     </insert>
 
@@ -137,6 +141,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateTime != null">update_time = #{updateTime},</if>
             <if test="createBy != null">create_by = #{createBy},</if>
             <if test="isBuy != null">is_buy = #{isBuy},</if>
+            <if test="miniAppId != null">mini_app_id = #{miniAppId},</if>
         </trim>
         where id = #{id}
     </update>