简化新建直播间的程序,分为3小步完成新建;修正营销人员验证的逻辑,解决可能绑错人的问题
5个文件已添加
8个文件已修改
986 ■■■■ 已修改文件
WebRoot/shopping/image/LiveCoverImg.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/miniapp/service/MaLiveIfc.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/miniapp/service/MaLiveImpl.java 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/action/api/LiveRoomVideo.java 533 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/action/jiazhuang/PanicBuyingLive.java 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/action/jiazhuang/PanicBuyingLiveGoods.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/action/jiazhuang/task/PanicBuyingTask.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/entity/CreateLiveRoomParameterStep1Entity.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/entity/CreateLiveRoomParameterStep2Entity.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/entity/CreateLiveRoomParameterStep3Entity.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/entity/CreateLiveRoomResultEntity.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/service/panicBuying/PanicBuyingImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/service/panicBuying/PanicBuyingSellerImpl.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/shopping/image/LiveCoverImg.jpg
src/com/yc/sdk/miniapp/service/MaLiveIfc.java
@@ -9,6 +9,9 @@
import com.yc.sdk.miniapp.entity.LiveRoomEntity;
import com.yc.sdk.miniapp.entity.LiveRoomEntity.RoomInfo;
import com.yc.sdk.miniapp.entity.LiveRoomImageEntity;
import com.yc.sdk.shopping.entity.CreateLiveRoomParameterStep1Entity;
import com.yc.sdk.shopping.entity.CreateLiveRoomParameterStep2Entity;
import com.yc.sdk.shopping.entity.CreateLiveRoomParameterStep3Entity;
import com.yc.sdk.shopping.entity.GoodsSortInRoomPamaraterEntity;
import com.yc.sdk.shopping.entity.LiveSubscribeUserEntity;
@@ -431,4 +434,25 @@
     * @return
     */
    public Integer deleteGoods(Long goodsId);
    /**
     * 新版小程序,新建直播间第1步
     * @param createLiveRoomParameterStep1Entity
     * @return
     */
    public String createRoomStep1(CreateLiveRoomParameterStep1Entity createLiveRoomParameterStep1Entity);
    /**
     * 新版小程序,新建直播间第2步
     * @param createLiveRoomParameterStep2Entity
     * @return
     */
    public Integer createRoomStep2(CreateLiveRoomParameterStep2Entity createLiveRoomParameterStep2Entity);
    /**
     * 新版小程序,新建直播间第3步
     * @param createLiveRoomParameterStep3Entity
     * @return
     */
    public Integer createRoomStep3(CreateLiveRoomParameterStep3Entity createLiveRoomParameterStep3Entity);
}
src/com/yc/sdk/miniapp/service/MaLiveImpl.java
@@ -17,6 +17,9 @@
import com.yc.sdk.miniapp.entity.LiveReplayVideoEntity.ReplayVideoEntity;
import com.yc.sdk.miniapp.entity.LiveRoomEntity;
import com.yc.sdk.miniapp.entity.LiveRoomEntity.RoomInfo;
import com.yc.sdk.shopping.entity.CreateLiveRoomParameterStep1Entity;
import com.yc.sdk.shopping.entity.CreateLiveRoomParameterStep2Entity;
import com.yc.sdk.shopping.entity.CreateLiveRoomParameterStep3Entity;
import com.yc.sdk.shopping.entity.GoodsSortInRoomEntity;
import com.yc.sdk.shopping.entity.GoodsSortInRoomPamaraterEntity;
import com.yc.sdk.shopping.entity.LiveSubscribeUserEntity;
@@ -879,9 +882,143 @@
                 
    }
    
    @Override
    public String createRoomStep1(CreateLiveRoomParameterStep1Entity createLiveRoomParameterStep1Entity) {
        String sql = " set nocount on ; \n"
                + " declare @DocCode varchar(20) = ?,@Type int = ?,@RoomName varchar(80) = ? \n"
                + " declare @AnchorName varchar(50) = ?,@AnchorWechat varchar(200) =?,@SubAnchorWechat varchar(200) =?\n"
                + " declare @ScreenType int = ?,@UserCode varchar(50) = ?, @UserName varchar(50) = ?,@ShopCcCode varchar(50) = ? \n"
                + " declare @isShowBannerPhotoOnHomePage int = 0 ,@OpenId varchar(200) = ? \n"
                + " declare @ShareImgUnid varchar(50) = ?,@FeedsImgUnid varchar(50) = ?,@CoverImgUnid varchar(50) = ? \n"
                + " declare @Today datetime = convert(varchar(10),getdate(),120) \n"
                + " declare @FormId int = 710701, @DocStatus int = 0 ,@isFound int = 0 \n"
                + " declare @DefaultBrand varchar(50)  \n"
                + " select top 1 @DefaultBrand = DefaultBrand from _sys_LoginUser where UserCode = @UserCode \n"
                + " declare @PeriodId varchar(20),@CompanyId varchar(20),@CompanyName varchar(80),@CcCode varchar(20),@CcName varchar(50) \n"
                + " if isnull(@DocCode,'') <> '' \n"
                + " begin \n"
                + "    update a set Type=@Type,RoomName = @RoomName,AnchorName=@AnchorName,\n"
                + "       AnchorWechat=@AnchorWechat,SubAnchorWechat=@SubAnchorWechat,ScreenType=@ScreenType,ShopCcCode=@ShopCcCode, \n"
                + "       ModifyName = @UserName,ModifyDate = getdate(),Brand = @DefaultBrand,isShowBannerPhotoOnHomePage = @isShowBannerPhotoOnHomePage, \n"
                + "       ShareImgUnid = @ShareImgUnid,FeedsImgUnid = @FeedsImgUnid,CoverImgUnid = @CoverImgUnid \n"
                + "    from t710701 a where a.DocCode = @DocCode \n"
                + "    set @isFound = @@rowcount \n"
                + " end \n"
                + " if isnull(@isFound,0) = 0 \n"
                + " begin \n"
                + "    select @CcCode = CcCode,@CompanyId = CompanyId,@CompanyName=CompanyName,@UserName = UserName \n"
                + "    from _sys_loginuser a where usercode = @UserCode \n"
                + "    select @DocStatus = PreDocStatus from gform where formid = 710701 \n"
                + "    select @PeriodId = dbo.GetPeriodID(@FormId,@CompanyID,@Today) \n"
                + "    exec sp_newdoccode @FormId,@UserCode,@DocCode output \n"
                + "    insert into t710701(DocCode,FormId,DocDate,CompanyID,CompanyName,DocStatus,EnterCode,EnterName,\n"
                + "        EnterDate,ModifyName,ModifyDate,CcCode,CcName,PeriodId, \n"
                + "        Type,RoomId,RoomName,AnchorName,AnchorWechat,SubAnchorWechat,\n"
                + "        ScreenType,ShopCcCode,Brand,isShowBannerPhotoOnHomePage,OpenId, \n"
                + "        ShareImgUnid ,FeedsImgUnid ,CoverImgUnid) \n"
                + "    values(@DocCode,@FormId,@Today,@CompanyID,@CompanyName,@DocStatus,@UserCode,@UserName,\n"
                + "        getdate(),@UserName,getdate(),@CcCode,@CcName,@PeriodId ,\n"
                + "        @Type,null,@RoomName,@StartTime,@EndTime,@AnchorName,@AnchorWechat,@SubAnchorWechat, \n"
                + "        @ScreenType,@ShopCcCode,@DefaultBrand,@isShowBannerPhotoOnHomePage,@OpenId , \n"
                + "        @ShareImgUnid ,@FeedsImgUnid ,@CoverImgUnid ) \n"
                + " end \n"
                + " exec p710701Save @DocCode = @DocCode \n"
                + " select @DocCode as DocCode \n" ;
        try {
            Map<String, Object> map = this.jdbcTemplate.queryForMap(sql, new Object[]{
                    createLiveRoomParameterStep1Entity.getDocCode(),createLiveRoomParameterStep1Entity.getType(),createLiveRoomParameterStep1Entity.getName(),
                    createLiveRoomParameterStep1Entity.getAnchorName(),createLiveRoomParameterStep1Entity.getAnchorWechat(),
                    createLiveRoomParameterStep1Entity.getSubAnchorWechat(),
                    createLiveRoomParameterStep1Entity.getScreenType(),createLiveRoomParameterStep1Entity.getUserCode(),
                    createLiveRoomParameterStep1Entity.getUserName(),createLiveRoomParameterStep1Entity.getShopCcCode(),
                    createLiveRoomParameterStep1Entity.getOpenId(),createLiveRoomParameterStep1Entity.getShareImgUnid(),
                    createLiveRoomParameterStep1Entity.getFeedsImgUnid(),createLiveRoomParameterStep1Entity.getCoverImgUnid()
            }) ;
            String docCode = null ;
            if (map != null) {
                docCode= (String)map.get("DocCode") ;
            }
            return docCode;
        }catch(DataAccessException e){
            if (e  instanceof EmptyResultDataAccessException) {
                return null ;
            } else {
                throw e ;
            }
        }catch(Exception e){
            throw e ;
        }
    }
    
    @Override
    public Integer createRoomStep2(CreateLiveRoomParameterStep2Entity createLiveRoomParameterStep2Entity) {
        String sql = " set nocount on ; \n"
                + " declare @DocCode varchar(20) = ?,@isCloseComment int =?,@isCloseLike int =?,@isCloseShare int = ? \n"
                + " declare @isCloseReplay int = ?,@isCloseKf int = ?,@isCloseGoods int =?,@isFeedsPublic int = ? \n"
                + " declare @myrowcount int \n"
                + " update a set isCloseComment=@isCloseComment,isCloseLike = @isCloseLike,isCloseShare=@isCloseShare, \n"
                + "     isCloseReplay=@isCloseReplay,isCloseKf=@isCloseKf,isCloseGoods=@isCloseGoods,isFeedsPublic = @isFeedsPublic \n"
                + " from t710701 a where a.DocCode = @DocCode \n"
                + " select @myrowcount = @@rowcount \n"
                + " exec p710701Save @DocCode = @DocCode \n"
                + " select @myrowcount \n";
        try {
            return  this.jdbcTemplate.queryForObject(sql, new Object[]{
                    createLiveRoomParameterStep2Entity.getDocCode(),
                    createLiveRoomParameterStep2Entity.getCloseComment(),
                    createLiveRoomParameterStep2Entity.getCloseLike(),
                    createLiveRoomParameterStep2Entity.getCloseShare(),
                    createLiveRoomParameterStep2Entity.getCloseReplay(),
                    createLiveRoomParameterStep2Entity.getCloseKf(),
                    createLiveRoomParameterStep2Entity.getCloseGoods(),
                    createLiveRoomParameterStep2Entity.getIsFeedsPublic()
            },Integer.class) ;
        }catch(DataAccessException e){
            if (e  instanceof EmptyResultDataAccessException) {
                return null ;
            } else {
                throw e ;
            }
        }catch(Exception e){
            throw e ;
        }
    }
    @Override
    public Integer createRoomStep3(CreateLiveRoomParameterStep3Entity createLiveRoomParameterStep3Entity) {
        String sql = " set nocount on ; \n"
                + " declare @DocCode varchar(20) = ?,@StartTime DateTime = ?,@EndTime datetime = ? \n"
                + " declare @myrowcount int \n"
                + " update a set StartTime = @StartTime,EndTime = @EndTime \n"
                + " from t710701 a where a.DocCode = @DocCode \n"
                + " select @myrowcount = @@rowcount \n"
                + " exec p710701Save @DocCode = @DocCode \n"
                + " select @myrowcount \n";
        try {
            return  this.jdbcTemplate.queryForObject(sql, new Object[]{
                    createLiveRoomParameterStep3Entity.getDocCode(),
                    createLiveRoomParameterStep3Entity.getStartDateTime(),
                    createLiveRoomParameterStep3Entity.getEndDateTime()
            },Integer.class) ;
        }catch(DataAccessException e){
            if (e  instanceof EmptyResultDataAccessException) {
                return null ;
            } else {
                throw e ;
            }
        }catch(Exception e){
            throw e ;
        }
    }
    @Override
    public Integer saveAttachment(String docCode,String fieldId,String unid,Integer seq) {
        String sql = " set nocount on ; \n"
                + " declare @DocCode varchar(20) = ?,@FieldId varchar(50) = ?,@Unid varchar(50) = ?,@Seq int = ? \n"
src/com/yc/sdk/shopping/action/api/LiveRoomVideo.java
@@ -50,6 +50,7 @@
import com.yc.sdk.miniapp.entity.LiveAssistantEntity.AssistantItemEntity;
import com.yc.sdk.miniapp.service.MaLiveIfc;
import com.yc.sdk.shopping.action.jiazhuang.PanicBuyingLive;
import com.yc.sdk.shopping.entity.CreateLiveRoomResultEntity;
import com.yc.sdk.shopping.entity.GoodsSortInRoomPamaraterEntity;
import com.yc.sdk.shopping.entity.ImageEntity;
import com.yc.sdk.shopping.entity.LiveSubscribeUserEntity;
@@ -238,6 +239,255 @@
        }
    }
    
    /**
     * 创建直播间
     * @param dataSourceEntity
     * @param docCode
     * @param request
     * @return
     * @throws Exception
     */
    public static CreateLiveRoomResultEntity CreateLiveRoom(DataSourceEntity dataSourceEntity,String docCode,HttpServletRequest request) throws Exception {
        //Logger log = LoggerFactory.getLogger(LiveRoomVideo.getClass());
        MaLiveIfc maLiveIfc = (MaLiveIfc)FactoryBean.getBean("MaLiveImpl");
        ShoppingImageDataIfc  imgData = (ShoppingImageDataIfc)FactoryBean.getBean("ShoppingImageDataImpl");
        SettingIfc  settingIfc = (SettingIfc)FactoryBean.getBean("SettingImpl");
        SettingEntity settingEntity = null;
        try {
            SpObserver.setDBtoInstance("_"+dataSourceEntity.getDbId());//切换数据源
            settingEntity = settingIfc.getSettingEntity() ;
            LiveRoomEntity liveRoomEntity = maLiveIfc.getLiveRoom(docCode) ;
            if (liveRoomEntity == null || liveRoomEntity.getRoomInfo()==null||liveRoomEntity.getRoomInfo().size() == 0) {
                throw new Exception("当前直播间不存在[" + docCode + "]") ;
            }
            RoomInfo roomInfo = liveRoomEntity.getRoomInfo().get(0) ;
            if (roomInfo==null) {
                throw new Exception("当前直播间不存在[" + docCode + "]") ;
            }
            if (roomInfo.getName()==null||"".equals(roomInfo.getName())) {
                throw new Exception("必须填写[直播间标题]") ;
            }
            if (roomInfo.getShareImgUnid()==null||"".equals(roomInfo.getShareImgUnid())) {
                throw new Exception("必须上传[分享卡片封图]图片") ;
            }
            if (roomInfo.getStartDateTime()==null) {
                throw new Exception("必须填写[开播时间]") ;
            }
            if (roomInfo.getEndDateTime()==null) {
                throw new Exception("必须填写[下播时间]") ;
            }
            Date now = new Date();
            //10分钟
            if (roomInfo.getStartDateTime().getTime() - (1000L*60L*10L) < now.getTime()) {
                throw new Exception("[开播时间]必须在当前时间10分钟后进行") ;
            }
            //180天
            if (roomInfo.getStartDateTime().getTime()  > now.getTime() + (1000L*60L*60L*24L*180L) ) {
                throw new Exception("[开播时间]不能在 6 个月后进行") ;
            }
            //30分钟
            if (roomInfo.getEndDateTime().getTime() - roomInfo.getStartDateTime().getTime() < (1000L*60L*30L)  ) {
                throw new Exception("[开播时间]和[下播时间]间隔不得短于30分钟") ;
            }
            //24小时
            if (roomInfo.getEndDateTime().getTime() - roomInfo.getStartDateTime().getTime() >  (1000L*60L*60L*24L)) {
                throw new Exception("[开播时间]和[下播时间]不得超过24小时") ;
            }
            if (roomInfo.getAnchorName()==null||"".equals(roomInfo.getAnchorName())) {
                throw new Exception("必须填写[主播昵称]") ;
            }
            if (roomInfo.getAnchorWechat()==null||"".equals(roomInfo.getAnchorWechat())) {
                throw new Exception("必须填写[主播微信号]") ;
            }
            if (roomInfo.getType()==null) {
                throw new Exception("必须选择[直播间类型 : 推流 或 手机直播]") ;
            }
            //小程序服务
            WxOpenService wxOpenService = MpServiceInit.getWxOpenService();
            WxOpenMaService wxOpenMaService = wxOpenService.getWxOpenComponentService().getWxMaServiceByAppid(dataSourceEntity.getMiniAppId()) ;
            WxMediaUploadResult wxMediaUploadResult  = null ;
            ImageEntity image = null ;
            //获取需要上传的图片
            image = imgData.getImageFile(roomInfo.getShareImgUnid().replaceAll(";",SettingKey.NAVSPLIT),null,null,true,request ,null,null);
            if (image == null) {
                throw new Exception("当前直播间[" + roomInfo.getName() + "]的[分享卡片封面]图不存在") ;
            }
            //上传分享图
            try {
                wxMediaUploadResult = wxOpenMaService.getMediaService().uploadMedia( "image",  image.getFile()) ;
                roomInfo.setShareImgMedialId(wxMediaUploadResult.getMediaId());  //上传分享图
            }catch (Exception e) {
                throw e ;
            }finally {
                if (image != null && image.getFile().exists()&&image.getFile().isFile()) {
                    //log.info("del>>"+image.getFile().getAbsolutePath());
                    image.getFile().delete();
                }
                image = null ;
            }
            //上传购物直播频道封面图 [官方收录封面] , 如果没有上传此图,则直接使用【分享卡片封面】图代替
            if (roomInfo.getFeedsImgUnid()==null||"".equals(roomInfo.getFeedsImgUnid())) {
                roomInfo.setFeedsImgUnid(roomInfo.getShareImgUnid());
            }
            //获取需要上传的图片
            image = imgData.getImageFile(roomInfo.getFeedsImgUnid().replaceAll(";",SettingKey.NAVSPLIT),null,null,true,request ,null,null);
            if (image == null) {
                throw new Exception("当前直播间[" + roomInfo.getName() + "]的[官方收录封面]图不存在") ;
            }
            //上传购物直播频道封面图[官方收录封面]
            try {
                wxMediaUploadResult = wxOpenMaService.getMediaService().uploadMedia( "image",  image.getFile()) ;
                roomInfo.setFeedsImgMedialId(wxMediaUploadResult.getMediaId());  //上传购物直播频道封面图[官方收录封面]
            }catch (Exception e) {
                throw e ;
            }finally {
                if (image != null && image.getFile().exists()&&image.getFile().isFile()) {
                    //log.info("del>>"+image.getFile().getAbsolutePath());
                    image.getFile().delete();
                }
                image = null ;
            }
            //上传背景图,如果用户没有上传背景图,则使用缺省背景图,路径:WebRoot/shopping/image/LiveCoverImg.jpg
            if (roomInfo.getCoverImgUnid() == null|| "".equals(roomInfo.getCoverImgUnid())) {
                //获取需要上传的图片
                if (image == null) {
                    image = new ImageEntity();
                }
                String rootPath = request.getSession().getServletContext().getRealPath("/");  //结尾有分隔符 /
                image.setFile(new File( rootPath +  "shopping" + File.separator +"image" + File.separator + "LiveCoverImg.jpg"));
            }else {
                //获取需要上传的图片(使用用户自己上传的背景图)
                image = imgData.getImageFile(roomInfo.getCoverImgUnid().replaceAll(";",SettingKey.NAVSPLIT),null,null,true,request ,null,null);
                if (image == null) {
                    throw new Exception("当前直播间[" + roomInfo.getName() + "]的[背景墙]图不存在") ;
                }
            }
            //上传背景图
            try {
                wxMediaUploadResult = wxOpenMaService.getMediaService().uploadMedia( "image",  image.getFile()) ;
                roomInfo.setCoverImgMedialId(wxMediaUploadResult.getMediaId());  //上传背景图
            }catch (Exception e) {
                throw e ;
            }finally {
                if (image != null && image.getFile().exists()&&image.getFile().isFile()) {
                    //log.info("del>>"+image.getFile().getAbsolutePath());
                    image.getFile().delete();
                }
                image = null ;
            }
            String qrCodeUrl = "";
            Integer roomId = null;
            if (roomInfo.getRoomId()!=null&&roomInfo.getRoomId().intValue()!=0) {
                //编辑直播间
                wxOpenMaService.getLiveService().editRoom(liveRoomEntity);
                roomId = roomInfo.getRoomId() ;
            }else {
                //新建直播间
                CreateRoomResultEntity createRoomResultEntity = wxOpenMaService.getLiveService().createRoom(liveRoomEntity);
                if (createRoomResultEntity != null) {
                    //保存直播间 房号 roomid
                    roomId = createRoomResultEntity.getRoomId();
                    qrCodeUrl = createRoomResultEntity.getQrCodeUrl();
                    maLiveIfc.saveRoomIdByRoomDocCode( docCode, roomId,qrCodeUrl,null);
                }
            }
            CreateLiveRoomResultEntity createLiveRoomResultEntity = new CreateLiveRoomResultEntity();
            createLiveRoomResultEntity.setRoomId(roomId);  //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
            createLiveRoomResultEntity.setQrCodeUrl(qrCodeUrl);  //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
            createLiveRoomResultEntity.setQrCodeUrlUnid("");  //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
            createLiveRoomResultEntity.setDocCode(docCode);
            createLiveRoomResultEntity.setState("success");
            return createLiveRoomResultEntity;
        }catch (WxErrorException e) {
            try {
                //主播未实名认证时报错: {"errmsg":"anchorWechat has no realName, please open the codeUrl and scan the code for certification rid: 5f48c536-4599b327-375338e9","qrcode_url":"https://res.wx.qq.com/op_res/BbVNeczA1XudfjVqCVoKgfuWe7e3aUhokktRVOqf_F0IqS6kYR--atCpVNUUC3zr","errcode":300036}
                //主播副号微信号未实名认证,错误代码:300039, 错误信息:subAnchorWechat has no realName, please open the codeUrl and scan the code for certification rid: 5f5c97aa-10a2c5f8-36ab8cc7,微信原始报文:{"errmsg":"subAnchorWechat has no realName, please open the codeUrl and scan the code for certification rid: 5f5c97aa-10a2c5f8-36ab8cc7","qrcode_url":"https://res.wx.qq.com/op_res/BbVNeczA1XudfjVqCVoKgfuWe7e3aUhokktRVOqf_F0IqS6kYR--atCpVNUUC3zr","errcode":300039}
                if (e.getError().getErrorCode() == 300036 || e.getError().getErrorCode() == 300039) {
                    JsonObject jsonElement = new JsonParser().parse(e.getError().getJson()).getAsJsonObject();
                    String qrCodeUrl =  jsonElement.get("qrcode_url")!=null?jsonElement.get("qrcode_url").getAsString():"";
                    String filePathFile = System.getProperty("java.io.tmpdir")+File.separator ;
                    String fileName = filePathFile + RandomString.getRandomString(6) +".jpg";
                    File newFile =    AvatarFile.getAvatarFile (qrCodeUrl,fileName,filePathFile) ;  //获取微信图像 File 对象
                    String qrCodeUrlUnid = qrCodeUrl;
                    String unidString = null,unid = null;
                    Integer seq = null;
                    LiveRoomEntity liveRoomEntity = maLiveIfc.getLiveRoom(docCode) ;
                    if (liveRoomEntity!= null && liveRoomEntity.getRoomInfo()!=null&& liveRoomEntity.getRoomInfo().size()>0) {
                        unidString = liveRoomEntity.getRoomInfo().get(0).getQrCodeUrlUnid() ;
                        if (unidString !=null) {
                            String unids[] = unidString.split(";") ;
                            if (unids!=null && unidString.length() > 0) {
                                unid = unids[0] ;
                                if (unids.length > 1) {
                                    seq = Integer.valueOf(unids[1]) ;
                                }
                            }
                        }
                    }
                    AttachmentEntity attachmentEntity = new AttachmentEntity() ;
                    attachmentEntity.setDoccode(docCode) ;
                    attachmentEntity.setRowId(docCode) ;
                    attachmentEntity.setFormId(710701) ;
                    attachmentEntity.setUnid(unid) ;
                    attachmentEntity.setSeq(seq) ;
                    attachmentEntity.setFieldId("QrCodeUrlUnid");
                    attachmentEntity.setPhysicalFile(newFile.getName());
                    attachmentEntity.setOriginalFileName(newFile.getName());
                    AttachmentIfc attachmentIfc = (AttachmentIfc) FactoryBean.getBean("AttachmentImpl");
                    //保存附件
                    AttachmentWhereEntity attachmentWhereEntity = attachmentIfc.saveAttachment( attachmentEntity , newFile,"2") ;
                    if (attachmentWhereEntity!=null) {
                        maLiveIfc.saveRoomIdByRoomDocCode( docCode, null,qrCodeUrl,attachmentWhereEntity.getUnid()+";"+ attachmentWhereEntity.getSeq());   //保存实名认证的链接
                        qrCodeUrlUnid = imgData.getImageUrl( attachmentWhereEntity.getUnid()+";"+ attachmentWhereEntity.getSeq(), settingEntity.getImageProductWidth(),
                                settingEntity.getImageProductHeight(), settingEntity.isShowProductOrgImage(),
                                settingEntity.isFromCached(), request);
                    }
                    CreateLiveRoomResultEntity createLiveRoomResultEntity = new CreateLiveRoomResultEntity();
                    createLiveRoomResultEntity.setRoomId(null);  //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
                    createLiveRoomResultEntity.setQrCodeUrl(qrCodeUrl);  //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
                    createLiveRoomResultEntity.setQrCodeUrlUnid(qrCodeUrlUnid);  //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
                    createLiveRoomResultEntity.setDocCode(docCode);
                    createLiveRoomResultEntity.setState("failed");
                    return createLiveRoomResultEntity;
                }else {
                    throw e ;
                }
            } catch (Exception e2) {
                throw e ;
            }
        }catch (Exception e) {
            throw e ;
        }finally {
            SpObserver.setDBtoInstance();
        }
    }
    /**
     * 保存小程序提交过来的新建直播间信息,第二步
     * @param request
@@ -289,286 +539,23 @@
                this.printJson(response, json.toString());
                return ;
            }
            liveRoomEntity = null;
            
            //执行创建直播间的过程
            liveRoomEntity =  maLiveIfc.getLiveRoom(docCode) ;
            if (liveRoomEntity == null || liveRoomEntity.getRoomInfo()==null||liveRoomEntity.getRoomInfo().size() == 0) {
                errJson.addProperty("warning","当前直播间不存在[" + docCode + "]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            RoomInfo roomInfo = liveRoomEntity.getRoomInfo().get(0) ;
            if (roomInfo==null) {
                errJson.addProperty("warning","当前直播间不存在[" + docCode + "]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            if (roomInfo.getName()==null||"".equals(roomInfo.getName())) {
                errJson.addProperty("warning","必须填写[直播间标题]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            if (roomInfo.getCoverImgUnid()==null||"".equals(roomInfo.getCoverImgUnid())) {
                errJson.addProperty("warning","必须上传[背景图]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            if (roomInfo.getStartDateTime()==null) {
                errJson.addProperty("warning","必须填写[开播时间]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            if (roomInfo.getEndDateTime()==null) {
                errJson.addProperty("warning","必须填写[下播时间]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            Date now = new Date();
            //10分钟
            if (roomInfo.getStartDateTime().getTime() - (1000L*60L*10L) < now.getTime()) {
                errJson.addProperty("warning","[开播时间]必须在当前时间10分钟后进行");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            //180天
            if (roomInfo.getStartDateTime().getTime()  > now.getTime() + (1000L*60L*60L*24L*180L) ) {
                errJson.addProperty("warning","[开播时间]不能在 6 个月后进行");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            //30分钟
            if (roomInfo.getEndDateTime().getTime() - roomInfo.getStartDateTime().getTime() < (1000L*60L*30L)  ) {
                errJson.addProperty("warning","[开播时间]和[下播时间]间隔不得短于30分钟");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            //24小时
            if (roomInfo.getEndDateTime().getTime() - roomInfo.getStartDateTime().getTime() >  (1000L*60L*60L*24L)) {
                errJson.addProperty("warning","[开播时间]和[下播时间]不得超过24小时");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            if (roomInfo.getAnchorName()==null||"".equals(roomInfo.getAnchorName())) {
                errJson.addProperty("warning","必须填写[主播昵称]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            if (roomInfo.getAnchorWechat()==null||"".equals(roomInfo.getAnchorWechat())) {
                errJson.addProperty("warning","必须填写[主播微信号]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            if (roomInfo.getShareImgUnid()==null||"".equals(roomInfo.getShareImgUnid())) {
                errJson.addProperty("warning","必须上传[分享图]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            if (roomInfo.getFeedsImgUnid()==null||"".equals(roomInfo.getFeedsImgUnid())) {
                errJson.addProperty("warning","必须上传[购物直播频道封面图]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            if (roomInfo.getType()==null) {
                errJson.addProperty("warning","必须选择[直播间类型 : 推流 或 手机直播]");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            //小程序服务
            WxOpenService wxOpenService = MpServiceInit.getWxOpenService();
            WxOpenMaService wxOpenMaService = wxOpenService.getWxOpenComponentService().getWxMaServiceByAppid(dataSourceEntity.getMiniAppId()) ;
            WxMediaUploadResult wxMediaUploadResult  = null ;
            ImageEntity image = null ;
            //上传背景图
            image = shoppingImageDataIfc.getImageFile(roomInfo.getCoverImgUnid().replaceAll(";",SettingKey.NAVSPLIT),null,null,true,request ,null,null);
            if (image == null) {
                errJson.addProperty("warning","当前直播间[" + roomInfo.getName() + "]的[背景图]不存在");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            //创建直播间
            CreateLiveRoomResultEntity createLiveRoomResultEntity = CreateLiveRoom( dataSourceEntity, docCode, request);
            try {
                wxMediaUploadResult = wxOpenMaService.getMediaService().uploadMedia( "image",  image.getFile()) ;
                roomInfo.setCoverImgMedialId(wxMediaUploadResult.getMediaId());  //上传背景图
            }catch (Exception e) {
                throw e ;
            }finally {
                if (image != null && image.getFile().exists()&&image.getFile().isFile()) {
                    log.info("del>>"+image.getFile().getAbsolutePath());
                    image.getFile().delete();
                }
                image = null ;
            }
            //上传分享图
            image = shoppingImageDataIfc.getImageFile(roomInfo.getShareImgUnid().replaceAll(";",SettingKey.NAVSPLIT),null,null,true,request ,null,null);
            if (image == null) {
                errJson.addProperty("warning","当前直播间[" + roomInfo.getName() + "]的[分享图]不存在");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            try {
                wxMediaUploadResult = wxOpenMaService.getMediaService().uploadMedia( "image",  image.getFile()) ;
                roomInfo.setShareImgMedialId(wxMediaUploadResult.getMediaId());  //上传分享图
            }catch (Exception e) {
                throw e ;
            }finally {
                if (image != null && image.getFile().exists()&&image.getFile().isFile()) {
                    log.info("del>>"+image.getFile().getAbsolutePath());
                    image.getFile().delete();
                }
                image = null ;
            }
            //上传购物直播频道封面图
            image = shoppingImageDataIfc.getImageFile(roomInfo.getFeedsImgUnid().replaceAll(";",SettingKey.NAVSPLIT),null,null,true,request ,null,null);
            if (image == null) {
                errJson.addProperty("warning","当前直播间[" + roomInfo.getName() + "]的[购物直播频道封面图]不存在");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            //上传购物直播频道封面图
            try {
                wxMediaUploadResult = wxOpenMaService.getMediaService().uploadMedia( "image",  image.getFile()) ;
                roomInfo.setFeedsImgMedialId(wxMediaUploadResult.getMediaId());  //上传购物直播频道封面图
            }catch (Exception e) {
                throw e ;
            }finally {
                if (image != null && image.getFile().exists()&&image.getFile().isFile()) {
                    log.info("del>>"+image.getFile().getAbsolutePath());
                    image.getFile().delete();
                }
                image = null ;
            }
            String qrCodeUrl = "";
            Integer roomId = null;
            if (roomInfo.getRoomId()!=null&&roomInfo.getRoomId().intValue()!=0) {
                //编辑直播间
                wxOpenMaService.getLiveService().editRoom(liveRoomEntity);
                roomId = roomInfo.getRoomId() ;
            }else {
                //新建直播间
                CreateRoomResultEntity createRoomResultEntity = wxOpenMaService.getLiveService().createRoom(liveRoomEntity);
                if (createRoomResultEntity != null) {
                    //保存直播间 房号 roomid
                    roomId = createRoomResultEntity.getRoomId();
                    qrCodeUrl = createRoomResultEntity.getQrCodeUrl();
                    maLiveIfc.saveRoomIdByRoomDocCode( docCode, roomId,qrCodeUrl,null);
                }
            }
            json.addProperty("RoomId", roomId);    //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
            json.addProperty("QrCodeUrl", qrCodeUrl);    //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
            json.addProperty("RoomId", createLiveRoomResultEntity.getRoomId());    //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
            json.addProperty("QrCodeUrl", createLiveRoomResultEntity.getQrCodeUrl());    //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
            json.addProperty(SettingKey.DOCCODE, docCode);    
            json.addProperty("state", "success");    
            this.printJson(response, json.toString());
            return ;
        }catch (WxErrorException e) {
            try {
                //主播未实名认证时报错: {"errmsg":"anchorWechat has no realName, please open the codeUrl and scan the code for certification rid: 5f48c536-4599b327-375338e9","qrcode_url":"https://res.wx.qq.com/op_res/BbVNeczA1XudfjVqCVoKgfuWe7e3aUhokktRVOqf_F0IqS6kYR--atCpVNUUC3zr","errcode":300036}
                //主播副号微信号未实名认证,错误代码:300039, 错误信息:subAnchorWechat has no realName, please open the codeUrl and scan the code for certification rid: 5f5c97aa-10a2c5f8-36ab8cc7,微信原始报文:{"errmsg":"subAnchorWechat has no realName, please open the codeUrl and scan the code for certification rid: 5f5c97aa-10a2c5f8-36ab8cc7","qrcode_url":"https://res.wx.qq.com/op_res/BbVNeczA1XudfjVqCVoKgfuWe7e3aUhokktRVOqf_F0IqS6kYR--atCpVNUUC3zr","errcode":300039}
                if (e.getError().getErrorCode() == 300036 || e.getError().getErrorCode() == 300039) {
                    JsonObject jsonElement = new JsonParser().parse(e.getError().getJson()).getAsJsonObject();
                    String qrCodeUrl =  jsonElement.get("qrcode_url")!=null?jsonElement.get("qrcode_url").getAsString():"";
                    String filePathFile = System.getProperty("java.io.tmpdir")+File.separator ;
                    String fileName = filePathFile + RandomString.getRandomString(6) +".jpg";
                    File newFile =    AvatarFile.getAvatarFile (qrCodeUrl,fileName,filePathFile) ;  //获取微信图像 File 对象
                    String qrCodeUrlUnid = qrCodeUrl;
                    String unidString = null,unid = null;
                    Integer seq = null;
                    LiveRoomEntity liveRoomEntity = maLiveIfc.getLiveRoom(docCode) ;
                    if (liveRoomEntity!= null && liveRoomEntity.getRoomInfo()!=null&& liveRoomEntity.getRoomInfo().size()>0) {
                        unidString = liveRoomEntity.getRoomInfo().get(0).getQrCodeUrlUnid() ;
                        if (unidString !=null) {
                            String unids[] = unidString.split(";") ;
                            if (unids!=null && unidString.length() > 0) {
                                unid = unids[0] ;
                                if (unids.length > 1) {
                                    seq = Integer.valueOf(unids[1]) ;
                                }
                            }
                        }
                    }
                    AttachmentEntity attachmentEntity = new AttachmentEntity() ;
                    attachmentEntity.setDoccode(docCode) ;
                    attachmentEntity.setRowId(docCode) ;
                    attachmentEntity.setFormId(710701) ;
                    attachmentEntity.setUnid(unid) ;
                    attachmentEntity.setSeq(seq) ;
                    attachmentEntity.setFieldId("QrCodeUrlUnid");
                    attachmentEntity.setPhysicalFile(newFile.getName());
                    attachmentEntity.setOriginalFileName(newFile.getName());
                    AttachmentIfc attachmentIfc = (AttachmentIfc) FactoryBean.getBean("AttachmentImpl");
                    //保存附件
                    AttachmentWhereEntity attachmentWhereEntity = attachmentIfc.saveAttachment( attachmentEntity , newFile,"2") ;
                    if (attachmentWhereEntity!=null) {
                        maLiveIfc.saveRoomIdByRoomDocCode( docCode, null,qrCodeUrl,attachmentWhereEntity.getUnid()+";"+ attachmentWhereEntity.getSeq());   //保存实名认证的链接
                        qrCodeUrlUnid = imgData.getImageUrl( attachmentWhereEntity.getUnid()+";"+ attachmentWhereEntity.getSeq(), settingEntity.getImageProductWidth(),
                                settingEntity.getImageProductHeight(), settingEntity.isShowProductOrgImage(),
                                settingEntity.isFromCached(), request);
                    }
                    json.addProperty("RoomId", "");    //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
                    json.addProperty("QrCodeUrl", qrCodeUrl);    //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
                    json.addProperty("QrCodeUrlUnid", qrCodeUrlUnid);    //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
                    json.addProperty(SettingKey.DOCCODE, docCode);
                    json.addProperty("state", "failed");
                    this.printJson(response, json.toString());
                    return ;
                }else {
                    this.logger.error(e.getMessage(), e);
                    e.printStackTrace();
                    errJson.addProperty("warning",(e.getCause()!=null?e.getCause().getMessage(): e.getMessage())+"【/shopping/live/saveRoomStep2.do】");
                    json.add("error", errJson);
                    this.printJson(response, json.toString());
                    return ;
                }
            } catch (Exception e2) {
                this.logger.error(e.getMessage(), e2);
                e.printStackTrace();
                errJson.addProperty("warning",(e2.getCause()!=null?e2.getCause().getMessage(): e2.getMessage())+"【/shopping/live/saveRoomStep2.do】");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            this.logger.error(e.getMessage(), e);
            e.printStackTrace();
            errJson.addProperty("warning",(e.getCause()!=null?e.getCause().getMessage(): e.getMessage())+"【/shopping/live/saveRoomStep2.do】");
            json.add("error", errJson);
            this.printJson(response, json.toString());
            return ;
            
        }catch (Exception e) {
            this.logger.error(e.getMessage(), e);
src/com/yc/sdk/shopping/action/jiazhuang/PanicBuyingLive.java
@@ -1,6 +1,8 @@
package com.yc.sdk.shopping.action.jiazhuang;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@@ -15,6 +17,7 @@
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import com.google.gson.JsonArray;
@@ -30,6 +33,10 @@
import com.yc.sdk.miniapp.service.MaLiveIfc;
import com.yc.sdk.shopping.action.api.LiveRoomVideo;
import com.yc.sdk.shopping.action.api.ShopCcCode;
import com.yc.sdk.shopping.entity.CreateLiveRoomParameterStep1Entity;
import com.yc.sdk.shopping.entity.CreateLiveRoomParameterStep2Entity;
import com.yc.sdk.shopping.entity.CreateLiveRoomParameterStep3Entity;
import com.yc.sdk.shopping.entity.CreateLiveRoomResultEntity;
import com.yc.sdk.shopping.entity.PanicBuyingEntity;
import com.yc.sdk.shopping.entity.SettingEntity;
import com.yc.sdk.shopping.entity.ShopCcCodeEntity;
@@ -525,4 +532,184 @@
        jsonItem.addProperty("SubscribeTimes", roomInfo.getSubscribeTimes());   //直播间订阅次数
        return jsonItem;
    }
    /**
     * 保存小程序提交过来的新建直播间信息 , 第一步
     * @param request
     * @param response
     */
    @RequestMapping("/saveRoomStep1.do")
    public void saveRoomStep1(@RequestBody CreateLiveRoomParameterStep1Entity createLiveRoomParameterStep1Entity, HttpServletRequest request, HttpServletResponse response) {
        HttpSession session=request.getSession();
        JsonObject json = new JsonObject();
        JsonObject errJson = new JsonObject();
        String userCode = (String) session.getAttribute(SessionKey.HRCODE) ;
        String userName = (String) session.getAttribute(SessionKey.HRNAME) ;
        String openId = (session.getAttribute(SessionKey.WEIXIN_OPENID) == null ? "": (String) session.getAttribute(SessionKey.WEIXIN_OPENID));
        if (createLiveRoomParameterStep1Entity.getName() == null||"".equals(createLiveRoomParameterStep1Entity.getName())) {
            errJson.addProperty("warning","必须传递直播间名字 name 【最短3个汉字,最长17个汉字】");
            json.add("error", errJson);
            this.printJson(response, json.toString());
            return ;
        }
        if (createLiveRoomParameterStep1Entity.getAnchorName() == null||"".equals(createLiveRoomParameterStep1Entity.getAnchorName())) {
            errJson.addProperty("warning","必须传递主播昵称 anchorName 【最短2个汉字,最长15个汉字】");
            json.add("error", errJson);
            this.printJson(response, json.toString());
            return ;
        }
        if (createLiveRoomParameterStep1Entity.getAnchorWechat() == null||"".equals(createLiveRoomParameterStep1Entity.getAnchorWechat())) {
            errJson.addProperty("warning","必须传递主播微信号 anchorWechat 【如果未实名认证,需要先前往“小程序直播”小程序进行实名验证】");
            json.add("error", errJson);
            this.printJson(response, json.toString());
            return ;
        }
        if (createLiveRoomParameterStep1Entity.getShareImgUnid() == null||"".equals(createLiveRoomParameterStep1Entity.getShareImgUnid())) {
            errJson.addProperty("warning","必须上传分享卡片封面 ShareImgUnid 字段");
            json.add("error", errJson);
            this.printJson(response, json.toString());
            return ;
        }
        try {
            DataSourceEntity dataSourceEntity = MultiDataSource.getDataSourceMap( request) ;
            SpObserver.setDBtoInstance("_"+dataSourceEntity.getDbId());//切换数据源
            SettingEntity settingEntity = settingIfc.getSettingEntity() ;
            //取网店 shopcccode
            ShopCcCodeEntity shopCcCodeEntity = ShopCcCode.getShopCcCode(settingEntity,request);
            createLiveRoomParameterStep1Entity.setShopCcCode(shopCcCodeEntity.getShopCcCode());
            createLiveRoomParameterStep1Entity.setOpenId(openId);
            createLiveRoomParameterStep1Entity.setUserCode(userCode);
            createLiveRoomParameterStep1Entity.setUserName(userName);
            String newDocCode = maLiveIfc.createRoomStep1(createLiveRoomParameterStep1Entity);
            json.addProperty(SettingKey.DOCCODE, newDocCode);
            json.addProperty("state", "success");
            this.printJson(response, json.toString());
            return ;
        }catch (Exception e) {
            this.logger.error(e.getMessage(), e);
            e.printStackTrace();
            errJson.addProperty("warning",(e.getCause()!=null?e.getCause().getMessage(): e.getMessage())+"【/shopping/panicBuyingLive/saveRoomStep1.do】");
            json.add("error", errJson);
            this.printJson(response, json.toString());
            return ;
        }finally {
            SpObserver.setDBtoInstance();
        }
    }
    /**
     * 保存小程序提交过来的新建直播间信息 , 第二步
     * @param request
     * @param response
     */
    @RequestMapping("/saveRoomStep2.do")
    public void saveRoomStep2(@RequestBody CreateLiveRoomParameterStep2Entity createLiveRoomParameterStep2Entity, HttpServletRequest request, HttpServletResponse response) {
        //HttpSession session=request.getSession();
        JsonObject json = new JsonObject();
        JsonObject errJson = new JsonObject();
        try {
            DataSourceEntity dataSourceEntity = MultiDataSource.getDataSourceMap( request) ;
            SpObserver.setDBtoInstance("_"+dataSourceEntity.getDbId());//切换数据源
            maLiveIfc.createRoomStep2(createLiveRoomParameterStep2Entity);
            json.addProperty(SettingKey.DOCCODE, createLiveRoomParameterStep2Entity.getDocCode());
            json.addProperty("state", "success");
            this.printJson(response, json.toString());
            return ;
        }catch (Exception e) {
            this.logger.error(e.getMessage(), e);
            e.printStackTrace();
            errJson.addProperty("warning",(e.getCause()!=null?e.getCause().getMessage(): e.getMessage())+"【/shopping/panicBuyingLive/saveRoomStep2.do】");
            json.add("error", errJson);
            this.printJson(response, json.toString());
            return ;
        }finally {
            SpObserver.setDBtoInstance();
        }
    }
    /**
     * 保存小程序提交过来的新建直播间信息 , 第三步
     * @param request
     * @param response
     */
    @RequestMapping("/saveRoomStep3.do")
    public void saveRoomStep3(@RequestBody CreateLiveRoomParameterStep3Entity createLiveRoomParameterStep3Entity, HttpServletRequest request, HttpServletResponse response) {
        //HttpSession session=request.getSession();
        JsonObject json = new JsonObject();
        JsonObject errJson = new JsonObject();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            DataSourceEntity dataSourceEntity = MultiDataSource.getDataSourceMap( request) ;
            SpObserver.setDBtoInstance("_"+dataSourceEntity.getDbId());//切换数据源
            if (createLiveRoomParameterStep3Entity.getStartTime() == null||"".equals(createLiveRoomParameterStep3Entity.getStartTime())) {
                errJson.addProperty("warning","必须传递直播计划开始时间 startTime ,格式:yyyy-MM-dd HH:mm:ss");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            if (createLiveRoomParameterStep3Entity.getEndTime() == null||"".equals(createLiveRoomParameterStep3Entity.getEndTime())) {
                errJson.addProperty("warning","必须传递直播计划结束时间 endTime ,格式:yyyy-MM-dd HH:mm:ss");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            Date startDateTime = null,endDateTime = null;
            try {
                startDateTime = sdf.parse(createLiveRoomParameterStep3Entity.getStartTime()) ;
            } catch (ParseException e) {
                errJson.addProperty("warning","直播计划开始时间 startTime 不能转换为日期类型,请检查日期格式是否符合:yyyy-MM-dd HH:mm:ss ");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            try {
                endDateTime = sdf.parse(createLiveRoomParameterStep3Entity.getEndTime()) ;
            } catch (ParseException e) {
                errJson.addProperty("warning","直播计划开始时间 endTime 不能转换为日期类型,请检查日期格式是否符合:yyyy-MM-dd HH:mm:ss ");
                json.add("error", errJson);
                this.printJson(response, json.toString());
                return ;
            }
            createLiveRoomParameterStep3Entity.setStartDateTime(startDateTime);
            createLiveRoomParameterStep3Entity.setEndDateTime(endDateTime);
            maLiveIfc.createRoomStep3(createLiveRoomParameterStep3Entity);
            //创建直播间
            CreateLiveRoomResultEntity createLiveRoomResultEntity = LiveRoomVideo.CreateLiveRoom( dataSourceEntity, createLiveRoomParameterStep3Entity.getDocCode(), request);
            json.addProperty("RoomId", createLiveRoomResultEntity.getRoomId());    //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
            json.addProperty("QrCodeUrl", createLiveRoomResultEntity.getQrCodeUrl());    //当主播微信号没有在 “小程序直播“ 小程序实名认证 返回该字段
            json.addProperty(SettingKey.DOCCODE, createLiveRoomParameterStep3Entity.getDocCode());
            json.addProperty("state", createLiveRoomResultEntity.getState());
            this.printJson(response, json.toString());
            return ;
        }catch (Exception e) {
            this.logger.error(e.getMessage(), e);
            e.printStackTrace();
            errJson.addProperty("warning",(e.getCause()!=null?e.getCause().getMessage(): e.getMessage())+"【/shopping/panicBuyingLive/saveRoomStep3.do】");
            json.add("error", errJson);
            this.printJson(response, json.toString());
            return ;
        }finally {
            SpObserver.setDBtoInstance();
        }
    }
}
src/com/yc/sdk/shopping/action/jiazhuang/PanicBuyingLiveGoods.java
@@ -11,6 +11,7 @@
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.firebirdsql.jdbc.parser.JaybirdSqlParser.nullValue_return;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.dao.DataAccessException;
@@ -360,6 +361,12 @@
                if (inputStream != null ) {
                    inputStream.close();
                }
                if (file!=null  && file.exists()) {
                    file.delete();
                }
                if (newFile!=null  && newFile.exists()) {
                    newFile.delete();
                }
            }
            // 结束处理图片
            
src/com/yc/sdk/shopping/action/jiazhuang/task/PanicBuyingTask.java
@@ -87,7 +87,7 @@
            
          //每1天更新一次 删除活动结束n天后商品库中的商品
            String cron = "10 0 0 * * ?";   //每天0:0:10执行
            //String cron = "10 0/2 * * * ?";   //test
            //String cron = "10 0/2 * * * ?";   //test , 每2分钟执行一次
            ScheduledFuture<?> future = threadPoolTaskScheduler.schedule(new DeleteExpiredGoodsTask(), new CronTrigger(cron));
            PanicBuyingTask.task.put("DeleteExpiredGoodsTask", future);
            threadPoolTaskScheduler.execute(new DeleteExpiredGoodsTask()) ;
src/com/yc/sdk/shopping/entity/CreateLiveRoomParameterStep1Entity.java
New file
@@ -0,0 +1,21 @@
package com.yc.sdk.shopping.entity;
import lombok.Data;
@Data
public class CreateLiveRoomParameterStep1Entity {
    private String docCode ; //直播间单号,新建时为空值,编辑时必须有值
    private String name ;  //直播间名字,最短3个汉字,最长17个汉字,1个汉字相当于2个字符
    private String anchorName ;  //主播昵称,最短2个汉字,最长15个汉字,1个汉字相当于2个字符
    private String anchorWechat ;  //主播微信号,如果未实名认证,需要先前往“小程序直播”小程序进行实名验证, 小程序二维码链接:https://res.wx.qq.com/op_res/BbVNeczA1XudfjVqCVoKgfuWe7e3aUhokktRVOqf_F0IqS6kYR--atCpVNUUC3zr
    private String subAnchorWechat ;  //主播副号微信号,如果未实名认证,需要先前往“小程序直播”小程序进行实名验证, 小程序二维码链接:https://res.wx.qq.com/op_res/BbVNeczA1XudfjVqCVoKgfuWe7e3aUhokktRVOqf_F0IqS6kYR--atCpVNUUC3zr
    private String shareImgUnid ; //分享卡片封面图片
    private String feedsImgUnid;  //官方收录封面图片
    private String coverImgUnid;  //背景墙图片
    private Integer type = 0 ; //直播间类型 : 1 推流,0 手机直播
    private Integer screenType = 0 ; //横屏、竖屏 screenType 【1:横屏,0:竖屏】
    private String shopCcCode ; //网店
    private String userCode ; //用户ID
    private String userName ; //用户名称
    private String openId ; //用户 openid
}
src/com/yc/sdk/shopping/entity/CreateLiveRoomParameterStep2Entity.java
New file
@@ -0,0 +1,15 @@
package com.yc.sdk.shopping.entity;
import lombok.Data;
@Data
public class CreateLiveRoomParameterStep2Entity {
    private String docCode ;  //直播间单号,新建时为空值,编辑时必须有值,如:LIVRM200902002
    private Integer closeComment = 0; //是否关闭评论 【0:开启,1:关闭】(若关闭,观众端将隐藏评论入口,直播开始后不允许开启)
    private Integer closeLike = 0 ; //是否关闭点赞 【0:开启,1:关闭】(若关闭,观众端将隐藏点赞按钮,直播开始后不允许开启)
    private Integer closeShare = 0 ;  //是否关闭分享 【0:开启,1:关闭】默认开启分享(直播开始后不允许修改)
    private Integer closeReplay = 0 ; //是否关闭回放 【0:开启,1:关闭】默认关闭回放(直播开始后允许开启)
    private Integer closeKf = 1 ; //是否关闭客服 【0:开启,1:关闭】 默认关闭客服(直播开始后允许开启)
    private Integer closeGoods = 0 ; //是否关闭货架 【0:开启,1:关闭】(若关闭,观众端将隐藏商品货架,直播开始后不允许开启)
    private Integer isFeedsPublic = 1 ; //是否开启官方收录 【1: 开启,0:关闭】,默认开启收录
}
src/com/yc/sdk/shopping/entity/CreateLiveRoomParameterStep3Entity.java
New file
@@ -0,0 +1,14 @@
package com.yc.sdk.shopping.entity;
import java.util.Date;
import lombok.Data;
@Data
public class CreateLiveRoomParameterStep3Entity {
    private String docCode ;
    private Date startDateTime;
    private Date endDateTime ;
    private String startTime ;   //直播开始时间,如: 2021-05-08 16:00:00
    private String endTime;   //直播结束时间,如: 2021-05-08 21:30:00
}
src/com/yc/sdk/shopping/entity/CreateLiveRoomResultEntity.java
New file
@@ -0,0 +1,12 @@
package com.yc.sdk.shopping.entity;
import lombok.Data;
@Data
public class CreateLiveRoomResultEntity {
    private String docCode ;   //直播单号
    private Integer roomId ;   //直播房间号
    private String qrCodeUrl ; //主播认证URL
    private String qrCodeUrlUnid ; //主播认证Unid
    private String state = "success" ;  //是否创建成功
}
src/com/yc/sdk/shopping/service/panicBuying/PanicBuyingImpl.java
@@ -146,7 +146,7 @@
                + "     DATEDIFF(second,getdate(),a.EffectiveEndDate) as EffectiveEndDateBalance,\n"
                + "        a.Quantity,a.RestrictBuyingQuantity,a.FreeId,c.FreeName,c.isRequiredAddress,a.TransCosts,a.Description,a.Images,a.ImagesUrl,a.RefCode, \n"
                + "     a.FirstPublishDate,a.FirstPublishUserCode,a.FirstPublishUserName,a.LastPublishDate,a.LastPublishUserCode,a.LastPublishUserName,a.PublishTimes, \n"
                + "     case when a.LastPublishDate >= a.ModifyDate then 0 else 1 end as PublishStatus,a.VisiteTimes,a.SharedTimes,a.OrderTimes,a.GroupBuyingStatus \n"
                + "     case when a.LastPublishDate >= a.ModifyDate then 0 else 1 end as PublishStatus,a.VisiteTimes,a.SharedTimes,a.OrderTimes,a.GroupBuyingStatus,a.isGoodsInLive \n"
                + " from t710802H a \n"
                + " left join t110601 b on a.CcCode = b.CcCode \n"
                + " left join t714034 c on a.FreeId = c.FreeId \n"
@@ -186,7 +186,7 @@
                + "     DATEDIFF(second,getdate(),a.EffectiveEndDate) as EffectiveEndDateBalance,\n"
                + "        a.Quantity,a.RestrictBuyingQuantity,a.FreeId,c.FreeName,c.isRequiredAddress,a.TransCosts,a.Description,a.Images,a.ImagesUrl,a.RefCode, \n"
                + "     a.FirstPublishDate,a.FirstPublishUserCode,a.FirstPublishUserName,a.LastPublishDate,a.LastPublishUserCode,a.LastPublishUserName,a.PublishTimes, \n"
                + "     case when a.LastPublishDate >= a.ModifyDate then 0 else 1 end as PublishStatus,a.VisiteTimes,a.SharedTimes,a.OrderTimes,a.GroupBuyingStatus \n"
                + "     case when a.LastPublishDate >= a.ModifyDate then 0 else 1 end as PublishStatus,a.VisiteTimes,a.SharedTimes,a.OrderTimes,a.GroupBuyingStatus,a.isGoodsInLive \n"
                + " from t710802H a \n"
                + " left join t110601 b on a.CcCode = b.CcCode \n"
                + " left join t714034 c on a.FreeId = c.FreeId \n"
@@ -225,7 +225,7 @@
                + "     DATEDIFF(second,getdate(),a.EffectiveEndDate) as EffectiveEndDateBalance,\n"
                + "        a.Quantity,a.RestrictBuyingQuantity,a.FreeId,c.FreeName,c.isRequiredAddress,a.TransCosts,a.Description,a.Images,a.ImagesUrl,a.RefCode, \n"
                + "     a.FirstPublishDate,a.FirstPublishUserCode,a.FirstPublishUserName,a.LastPublishDate,a.LastPublishUserCode,a.LastPublishUserName,a.PublishTimes, \n"
                + "     case when a.LastPublishDate >= a.ModifyDate then 0 else 1 end as PublishStatus,a.VisiteTimes,a.SharedTimes,a.OrderTimes,a.GroupBuyingStatus \n"
                + "     case when a.LastPublishDate >= a.ModifyDate then 0 else 1 end as PublishStatus,a.VisiteTimes,a.SharedTimes,a.OrderTimes,a.GroupBuyingStatus,a.isGoodsInLive \n"
                + " from t710802H a \n"
                + " left join t110601 b on a.CcCode = b.CcCode \n"
                + " left join t714034 c on a.FreeId = c.FreeId \n"
@@ -521,7 +521,7 @@
                + "     case when a.LastPublishDate >= a.ModifyDate then 0 else 1 end as PublishStatus,a.VisiteTimes,a.SharedTimes,a.OrderTimes, \n"
                + "     @TodayVisiteTimes as TodayVisiteTimes,@TodaySharedTimes as TodaySharedTimes,@TodayOrderTimes as TodayOrderTimes , \n"
                + "     d.SellerCount , d.SellerCheckedCount , isnull(d.SellerCount,0) -  isnull(d.SellerCheckedCount,0) as SellerCheckedBalance, \n"
                + "     @SellerUnCheckedNames as SellerUnCheckedNames \n"
                + "     @SellerUnCheckedNames as SellerUnCheckedNames,a.isGoodsInLive \n"
                + " from t710802H a \n"
                + " left join t110601 b on a.CcCode = b.CcCode \n"
                + " left join t714034 c on a.FreeId = c.FreeId \n"
src/com/yc/sdk/shopping/service/panicBuying/PanicBuyingSellerImpl.java
@@ -156,7 +156,8 @@
        String sql = " set nocount on \n"
                + " declare @DocCode varchar(20) = ?,@SellerOpenId varchar(200) = ? \n"
                + " declare @OpenId varchar(200) \n"
                + " declare @SellerNickName nvarchar(400),@SellerWeiXinAvatarUnid varchar(50),@SellerTelephone varchar(50) \n"
                + " declare @SellerNickName nvarchar(400),@SellerWeiXinAvatarUnid varchar(50),@SellerTelephone varchar(50),@SellerOpenId2 varchar(200) \n"
                + " declare @SellerId int \n"
                + " select @SellerNickName =a.NickName,@SellerWeiXinAvatarUnid =a.WeiXinAvatarUnid,@SellerTelephone = a.Tel \n"
                + " from t730102 a where a.OpenId = @SellerOpenId \n"
                + " if isnull(@SellerNickName,'') = '' \n"
@@ -170,12 +171,23 @@
                + "     return \n"
                + " end \n"
                + " select @OpenId = OpenId from t710802H a where a.DocCode = @DocCode \n"
                + " update a set SellerOpenId = @SellerOpenId, SellerNickName = @SellerNickName,SellerWeiXinAvatarUnid = @SellerWeiXinAvatarUnid \n"
                + " from t710801 a where a.OpenId = @OpenId and isnull(a.SellerOpenId,'') = '' \n"
                + " update a set SellerOpenId = @SellerOpenId,SellerNickName = @SellerNickName,SellerWeiXinAvatarUnid = @SellerWeiXinAvatarUnid \n"
                + " from t710802D a \n"
                + " where isnull(a.SellerOpenId,'') = '' \n"
                + " and exists(select 1 from t710801 b where a.SellerId = b.SellerId and b.SellerOpenId = @SellerOpenId ) \n"
                + " select top 1 @SellerId = a.SellerId,@SellerOpenId2 = a.SellerOpenId \n"
                + " from t710801 a \n"
                + " where a.OpenId = @OpenId and a.Telephone = @Telephone  \n"
                + " if @@rowcount = 0 \n"
                + " begin \n"
                + "     raiserror('您不是营销人员,无需验证[请检查本人微信绑定的电话与营销人员列表中的电话号码是否一致]',16,1) \n"
                + "     return \n"
                + " end \n"
                + " if isnull(@SellerOpenId2,'') <> isnull(@SellerOpenId2,'') or isnull(@SellerOpenId2,'') = '' \n"
                + " begin \n"
                + "    update a set SellerOpenId = @SellerOpenId, SellerNickName = @SellerNickName,SellerWeiXinAvatarUnid = @SellerWeiXinAvatarUnid \n"
                + "    from t710801 a where a.SellerId = @SellerId  \n"
                + "    update a set SellerOpenId = @SellerOpenId,SellerNickName = @SellerNickName,SellerWeiXinAvatarUnid = @SellerWeiXinAvatarUnid \n"
                + "    from t710802D a \n"
                + "    where isnull(a.SellerOpenId,'') = '' \n"
                + "    and exists(select 1 from t710801 b where a.SellerId = b.SellerId and b.SellerId = @SellerId ) \n"
                + " end \n"
                + " select @@rowcount \n";
        Integer ret = null;
        try {