| | |
| | | package com.yeshi.fanli.controller.client.lijin; |
| | | |
| | | import com.google.gson.Gson; |
| | | import com.ks.lijin.exception.LiJinAmountException; |
| | | import com.ks.lijin.exception.LiJinException; |
| | | import com.ks.lijin.exception.LiJinGoodsException; |
| | | import com.ks.lijin.exception.LiJinUserException; |
| | | import com.ks.lijin.pojo.DO.LiJinExpendRecord; |
| | | import com.ks.lijin.pojo.DTO.MoneyInfo; |
| | | import com.ks.vip.pojo.Enums.VIPEnum; |
| | | import com.yeshi.common.entity.taobao.TaoBaoShop; |
| | | import com.yeshi.common.entity.taobao.TaoKeAppInfo; |
| | | import com.yeshi.common.vo.ClientTextStyleVO; |
| | |
| | | import com.yeshi.fanli.dto.pdd.PDDGoodsDetail; |
| | | import com.yeshi.fanli.dto.suning.SuningGoodsInfo; |
| | | import com.yeshi.fanli.dto.vip.goods.VIPGoodsInfo; |
| | | import com.yeshi.fanli.entity.SystemEnum; |
| | | import com.yeshi.fanli.entity.SystemPIDInfo; |
| | | import com.yeshi.fanli.entity.accept.AcceptData; |
| | | import com.yeshi.fanli.entity.bus.user.ShamUser; |
| | | import com.yeshi.fanli.entity.bus.user.UserInfo; |
| | | import com.yeshi.fanli.entity.goods.CollectionGoodsV2; |
| | | import com.yeshi.fanli.entity.jd.JDGoods; |
| | | import com.yeshi.fanli.exception.goods.CommonGoodsException; |
| | | import com.yeshi.fanli.exception.goods.ScanHistoryException; |
| | | import com.yeshi.fanli.exception.pdd.PDDApiException; |
| | | import com.yeshi.fanli.exception.taobao.TaobaoGoodsDownException; |
| | | import com.yeshi.fanli.lijin.manager.GoodsLijinMnager; |
| | | import com.yeshi.fanli.lijin.manager.UserLijinMnager; |
| | | import com.yeshi.fanli.lijin.manager.UserLijinSendManager; |
| | | import com.yeshi.fanli.log.vo.UserGoodsScanLog; |
| | | import com.yeshi.fanli.service.inter.goods.CollectionGoodsV2Service; |
| | | import com.yeshi.fanli.service.inter.goods.ScanHistoryV2Service; |
| | | import com.yeshi.fanli.service.inter.order.OrderHongBaoMoneyComputeService; |
| | | import com.yeshi.fanli.service.inter.pdd.PDDAuthService; |
| | | import com.yeshi.fanli.service.inter.taobao.TaoBaoGoodsUpdateService; |
| | | import com.yeshi.fanli.service.inter.taobao.TaoBaoShopService; |
| | | import com.yeshi.fanli.service.inter.user.ShamUserService; |
| | | import com.yeshi.fanli.util.Constant; |
| | | import com.yeshi.fanli.util.StringUtil; |
| | | import com.yeshi.fanli.util.TaoBaoConstant; |
| | | import com.yeshi.fanli.util.ThreadUtil; |
| | | import com.yeshi.fanli.service.inter.user.UserInfoService; |
| | | import com.yeshi.fanli.service.manger.PIDManager; |
| | | import com.yeshi.fanli.util.*; |
| | | import com.yeshi.fanli.util.cache.TaoBaoGoodsCacheUtil; |
| | | import com.yeshi.fanli.util.factory.goods.GoodsDetailVOFactory; |
| | | import com.yeshi.fanli.util.factory.goods.GoodsDetailVOLijinFactory; |
| | | import com.yeshi.fanli.util.factory.goods.ShopInfoVOFactory; |
| | | import com.yeshi.fanli.util.jd.JDApiUtil; |
| | |
| | | import com.yeshi.fanli.util.vipshop.VipShopApiUtil; |
| | | import com.yeshi.fanli.lijin.vo.GoodsDetailVO; |
| | | import com.yeshi.goods.facade.entity.taobao.TaoBaoGoodsBrief; |
| | | import net.sf.json.JSONObject; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.yeshi.utils.JsonUtil; |
| | |
| | | import java.io.PrintWriter; |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | @Controller |
| | | @RequestMapping("api/lijin/goods") |
| | | public class GoodsControllerLijin { |
| | | Logger userGoodsScanLogger = LoggerFactory.getLogger("userGoodsScanLog"); |
| | | |
| | | |
| | | |
| | | |
| | | @Resource |
| | | private TaoBaoGoodsCacheUtil taoBaoGoodsCacheUtil; |
| | |
| | | @Resource |
| | | private TaoBaoShopService taoBaoShopService; |
| | | |
| | | @Resource |
| | | private GoodsLijinMnager goodsLijinMnager; |
| | | |
| | | |
| | | @Resource |
| | | private UserLijinMnager userLijinMnager; |
| | | |
| | | @Resource |
| | | private UserLijinSendManager userLijinSendManager; |
| | | |
| | | @Resource |
| | | private PIDManager pidManager; |
| | | @Resource |
| | | private ScanHistoryV2Service scanHistoryV2Service; |
| | | |
| | | @Resource |
| | | private UserInfoService userInfoService; |
| | | |
| | | @Resource |
| | | private OrderHongBaoMoneyComputeService orderHongBaoMoneyComputeService; |
| | | |
| | | |
| | | /** |
| | | * 获取商品详情 |
| | | * |
| | |
| | | * @param from |
| | | * @return |
| | | */ |
| | | |
| | | @RequestMapping("getGoodsDetail") |
| | | public void getGoodsDetail(AcceptData acceptData, int goodsType, String goodsId, Long uid, String from, PrintWriter out) { |
| | | GoodsDetailVO goodsDetailVO = new GoodsDetailVO(); |
| | | GoodsDetailVO.GoodsExtraVO extraVO = new GoodsDetailVO.GoodsExtraVO(); |
| | | GoodsMoneyConfigParamsDTO paramsDTO = new GoodsMoneyConfigParamsDTO(); |
| | | paramsDTO.setFanLiRate(new BigDecimal("60")); |
| | | GoodsMoneyConfigParamsDTO paramsDTO = orderHongBaoMoneyComputeService.getShowComputeRate(acceptData.getPlatform(), |
| | | acceptData.getVersion(), acceptData.getSystem()); |
| | | |
| | | paramsDTO.setFanLiRate(goodsLijinMnager.getFanLiRate(uid)); |
| | | // 领券人列表 |
| | | List<ShamUser> listCouponUser = new ArrayList<>(); |
| | | Long goodsIdSuning = null; |
| | | switch (goodsType) { |
| | | case Constant |
| | | .SOURCE_TYPE_TAOBAO: |
| | | TaoBaoGoodsBrief goods = getTaoBaoGoods(Long.parseLong(goodsId)); |
| | | |
| | | if (uid != null) { |
| | | ThreadUtil.run(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | //小于10块自动发放奖金 |
| | | userLijinSendManager.autoSendLijin(uid, new BigDecimal(10)); |
| | | } |
| | | }); |
| | | |
| | | } |
| | | |
| | | TaoBaoGoodsBrief goods = getTaoBaoGoods(goodsId); |
| | | |
| | | //加载资金信息 |
| | | com.yeshi.fanli.vo.goods.GoodsDetailVO goodsDetailVO1 = GoodsDetailVOFactory.convertTaoBao(goods, paramsDTO); |
| | | goodsDetailVO1 = goodsLijinMnager.loadTBMoneyInfo(acceptData.getSystem(), uid, goods, goodsDetailVO1, true); |
| | | |
| | | goodsDetailVO.setGoods(GoodsDetailVOLijinFactory.convertTaoBao(goods, paramsDTO)); |
| | | //重置资金信息 |
| | | goodsDetailVO.getGoods().setMoneyInfo(goodsDetailVO1.getMoneyInfo()); |
| | | |
| | | |
| | | GoodsDetailVOLijinFactory.fillRights(goodsDetailVO.getGoods()); |
| | | |
| | | // 店铺信息 |
| | | TaoBaoShop shop = taoBaoShopService.getTaoBaoShop(goods.getId(), goods.getSellerId()); |
| | | TaoBaoShop shop = taoBaoShopService.getTaoBaoShop(goods.getAuctionId(), goods.getSellerId()); |
| | | if (shop != null) { |
| | | String shopLink = shop.getShopLink(); |
| | | if (StringUtil.isNullOrEmpty(shopLink)) { |
| | |
| | | goodsDetailVO.getGoods().setShopInfo(ShopInfoVOFactory.convertTaoBaoShop(shop)); |
| | | } |
| | | |
| | | extraVO.setDetailUrl("http://apph5.banliapp.com/apppage/goods_img.html?id=" + goodsId); |
| | | |
| | | extraVO.setDetailUrl("http://apph5.banliapp.com/apppage/goods_img_tb.html?id=" + goodsId); |
| | | ThreadUtil.run(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | try { |
| | | scanHistoryV2Service.addScanHistory(uid, acceptData.getDevice(), goods); |
| | | } catch (CommonGoodsException e) { |
| | | e.printStackTrace(); |
| | | } catch (ScanHistoryException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | }); |
| | | break; |
| | | |
| | | case Constant |
| | |
| | | JDGoods jdGoods = getJDGoods(Long.parseLong(goodsId)); |
| | | goodsDetailVO.setGoods(GoodsDetailVOLijinFactory.convertJDGoods(jdGoods, paramsDTO)); |
| | | extraVO.setDetailUrl("https://in.m.jd.com/product/jieshao/video/" + goodsId + ".html"); |
| | | |
| | | ThreadUtil.run(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | try { |
| | | scanHistoryV2Service.addJDScanHistory(uid, acceptData.getDevice(), jdGoods); |
| | | } catch (CommonGoodsException e) { |
| | | e.printStackTrace(); |
| | | } catch (ScanHistoryException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | }); |
| | | break; |
| | | |
| | | case Constant |
| | | .SOURCE_TYPE_PDD: |
| | | PDDGoodsDetail pddGoodsDetail = getPDDGoods(Long.parseLong(goodsId), uid); |
| | | PDDGoodsDetail pddGoodsDetail = getPDDGoods(acceptData.getSystem(), Long.parseLong(goodsId), uid); |
| | | goodsDetailVO.setGoods(GoodsDetailVOLijinFactory.convertPDDGoods(pddGoodsDetail, paramsDTO)); |
| | | extraVO.setDetailUrl("http://apph5.banliapp.com/apppage/goods_img_pdd.html?id=" + goodsId); |
| | | ThreadUtil.run(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | try { |
| | | scanHistoryV2Service.addPDDScanHistory(uid, acceptData.getDevice(), pddGoodsDetail); |
| | | } catch (CommonGoodsException e) { |
| | | e.printStackTrace(); |
| | | } catch (ScanHistoryException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | }); |
| | | break; |
| | | |
| | | case Constant |
| | | .SOURCE_TYPE_VIP: |
| | | VIPGoodsInfo vipGoodsInfo = VipShopApiUtil.getGoodsDetail(goodsId); |
| | | goodsDetailVO.setGoods(GoodsDetailVOLijinFactory.convertVIPGoods(vipGoodsInfo, paramsDTO)); |
| | | ThreadUtil.run(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | try { |
| | | scanHistoryV2Service.addVIPScanHistory(uid, acceptData.getDevice(), vipGoodsInfo); |
| | | } catch (CommonGoodsException e) { |
| | | e.printStackTrace(); |
| | | } catch (ScanHistoryException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | }); |
| | | break; |
| | | |
| | | case Constant |
| | | .SOURCE_TYPE_SUNING: |
| | | String[] ids = SuningUtil.getGoodsIdDetail(goodsId); |
| | | SuningGoodsInfo suningGoodsInfo = SuningApiUtil.getGoodsDetail(ids[1], ids[0]); |
| | | goodsIdSuning = Long.parseLong(suningGoodsInfo.getCommodityInfo().getCommodityCode()); |
| | | |
| | | goodsDetailVO.setGoods(GoodsDetailVOLijinFactory.convertSuningGoods(suningGoodsInfo, paramsDTO)); |
| | | extraVO.setDetailUrl("http://apph5.banliapp.com/apppage/goods_img_suning.html?id=" |
| | | + suningGoodsInfo.getCommodityInfo().getCommodityCode() + "&supplierCode=" |
| | | + suningGoodsInfo.getCommodityInfo().getSupplierCode()); |
| | | |
| | | ThreadUtil.run(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | try { |
| | | scanHistoryV2Service.addSuningScanHistory(uid, acceptData.getDevice(), suningGoodsInfo); |
| | | } catch (CommonGoodsException e) { |
| | | e.printStackTrace(); |
| | | } catch (ScanHistoryException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | break; |
| | | } |
| | | |
| | | ThreadUtil.run(new Runnable() { |
| | | |
| | | |
| | | @Override |
| | | public void run() { |
| | | try { |
| | | userGoodsScanLogger.info("{}", new Gson().toJson(UserGoodsScanLog.UserGoodsScanLogFactory.create(goodsDetailVO.getGoods(), uid, acceptData.getUtdid(), acceptData.getDevice()))); |
| | | }catch(Exception e){ |
| | | |
| | | } |
| | | } |
| | | }); |
| | | |
| | | |
| | | //是否收藏 |
| | | extraVO.setCollected(false); |
| | | if (uid != null) { |
| | | CollectionGoodsV2 collectionGoodsV2 = collectionGoodsV2Service.findByUidAndAuctionId(uid, Long.parseLong(goodsDetailVO.getGoods().getGoodsId()), goodsType); |
| | | CollectionGoodsV2 collectionGoodsV2 = collectionGoodsV2Service.findByUidAndAuctionId(uid, goodsType == Constant.SOURCE_TYPE_SUNING ? goodsIdSuning+"" : goodsDetailVO.getGoods().getGoodsId(), goodsType); |
| | | if (collectionGoodsV2 != null) { |
| | | extraVO.setCollected(true); |
| | | } |
| | |
| | | extraVO.setBuyValid(true); |
| | | extraVO.setListCouponUser(listCouponUser); |
| | | goodsDetailVO.setExtra(extraVO); |
| | | loadLijinInfo(goodsDetailVO.getGoods()); |
| | | |
| | | |
| | | loadLijinInfo(uid, acceptData.getSystem(), goodsDetailVO); |
| | | //清除临时信息 |
| | | goodsDetailVO.getGoods().setTempCoupon(null); |
| | | if (goodsDetailVO.getGoods().getLabels() == null) |
| | | goodsDetailVO.getGoods().setLabels(new ArrayList<>()); |
| | | goodsDetailVO.getGoods().getLabels().add(new ClientTextStyleVO("天猫", "#FF2C4A")); |
| | | goodsDetailVO.getGoods().getLabels().add(0, new ClientTextStyleVO(ShopUtil.getShopTypeName(goodsDetailVO.getGoods().getShopType()), "#FF2C4A")); |
| | | out.print(JsonUtil.loadTrueResult(new Gson().toJson(goodsDetailVO))); |
| | | } |
| | | |
| | | @RequestMapping("buyWithLijin") |
| | | public void buyWithLijin(AcceptData acceptData, int goodsType, String goodsId, String lijinId, Long uid, String from, PrintWriter out) { |
| | | String[] lijinTypes = lijinId.split("#"); |
| | | String lijinType = lijinTypes[0]; |
| | | if (lijinType.equalsIgnoreCase(GoodsDetailVO.GoodsHongBaoListVO.TYPE_LIJIN_LINK)) { |
| | | //礼金链接 |
| | | //TODO 获取链接 |
| | | } else { |
| | | //商品本身礼金 |
| | | //获取用户注册时间 |
| | | UserInfo user = userInfoService.getUserByIdWithMybatis(uid); |
| | | |
| | | try { |
| | | userLijinSendManager.autoSendLijin(uid, new BigDecimal(10)); |
| | | userLijinSendManager.autoRecieveLijin(acceptData.getSystem(), acceptData.getDevice(), uid); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | |
| | | try { |
| | | LiJinExpendRecord record = goodsLijinMnager.createTBLijin(goodsId, uid, new Date(user.getCreatetime())); |
| | | String sendUrl = record.getSendUrl(); |
| | | if (StringUtil.isNullOrEmpty(sendUrl)) { |
| | | out.print(JsonUtil.loadFalseResult("礼金创建失败")); |
| | | return; |
| | | } |
| | | |
| | | JSONObject data = new JSONObject(); |
| | | JSONObject link = new JSONObject(); |
| | | link.put("clickUrl", sendUrl); |
| | | data.put("type", 1); |
| | | data.put("link", link); |
| | | data.put("native", true); |
| | | data.put("userLevel", userLijinMnager.getUserLevelInfo(uid, acceptData.getSystem())); |
| | | //获取今日的剩余次数 |
| | | try { |
| | | int leftCount = goodsLijinMnager.getTodayLeftCount(uid, new Date(user.getCreatetime())); |
| | | data.put("todayLeftCount", "立减机会:-1次 今日剩余:" + leftCount + "次"); |
| | | } catch (Exception e) { |
| | | } |
| | | out.print(JsonUtil.loadTrueResult(data)); |
| | | } catch (LiJinException e) { |
| | | out.print(JsonUtil.loadFalseResult(e.getMsg())); |
| | | return; |
| | | } catch (LiJinGoodsException e) { |
| | | out.print(JsonUtil.loadFalseResult(e.getMsg())); |
| | | return; |
| | | } catch (LiJinAmountException e) { |
| | | out.print(JsonUtil.loadFalseResult(e.getMsg())); |
| | | return; |
| | | } catch (LiJinUserException e) { |
| | | if (e.getCode() == LiJinUserException.CODE_USER_BALANCE_NOT_ENOUGH) { |
| | | //TODO 余额不足 |
| | | } |
| | | out.print(JsonUtil.loadFalseResult(2001, "今日领取红包次数超限")); |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 加载礼金信息 |
| | | * |
| | | * @param goodsInfoVO |
| | | * @param goodsDetailVO |
| | | */ |
| | | private void loadLijinInfo(GoodsDetailVO.GoodsInfoVO goodsInfoVO) { |
| | | //虚拟数据 |
| | | List<BigDecimal> lijinList = new ArrayList<>(); |
| | | lijinList.add(new BigDecimal("1")); |
| | | lijinList.add(new BigDecimal("2")); |
| | | lijinList.add(new BigDecimal("2.5")); |
| | | |
| | | GoodsDetailVO.GoodsHongBaoListVO.UserLevelVO userLevelVO = new GoodsDetailVO.GoodsHongBaoListVO.UserLevelVO(); |
| | | userLevelVO.setVipRank(1); |
| | | userLevelVO.setDesc("升级为铂金会员红包可提高100%"); |
| | | userLevelVO.setLink("http://www.baidu.com"); |
| | | |
| | | if (goodsInfoVO.getPriceList() == null) { |
| | | goodsInfoVO.setPriceList(new ArrayList<>()); |
| | | } |
| | | |
| | | goodsInfoVO.getPriceList().get(0).setUserLevel(userLevelVO); |
| | | |
| | | for (BigDecimal money : lijinList) { |
| | | GoodsDetailVO.GoodsHongBaoListVO price = new GoodsDetailVO.GoodsHongBaoListVO(); |
| | | price.setType(2); |
| | | price.setSubMoney("¥" + money); |
| | | price.setUserLevel(userLevelVO); |
| | | |
| | | //最终价格计算=券后价-礼金 |
| | | price.setFinalMoney("¥" + goodsInfoVO.getCouponPrice().subtract(money).toString()); |
| | | |
| | | List<GoodsDetailVO.GoodsHongBaoListVO.PriceInfo> priceInfos = new ArrayList<>(); |
| | | |
| | | priceInfos.add(new GoodsDetailVO.GoodsHongBaoListVO.PriceInfo("原价", goodsInfoVO.getZkPrice())); |
| | | |
| | | if (goodsInfoVO.getTempCoupon() != null) { |
| | | priceInfos.add(new GoodsDetailVO.GoodsHongBaoListVO.PriceInfo("优惠券", "-¥" + MoneyBigDecimalUtil.getWithNoZera(goodsInfoVO.getTempCoupon().getAmount()).toString())); |
| | | } |
| | | |
| | | priceInfos.add(new GoodsDetailVO.GoodsHongBaoListVO.PriceInfo("首单礼金", "-¥1")); |
| | | |
| | | priceInfos.add(new GoodsDetailVO.GoodsHongBaoListVO.PriceInfo("礼金", "-" + "¥" + money)); |
| | | price.setPriceDetails(priceInfos); |
| | | goodsInfoVO.getPriceList().add(0, price); |
| | | } |
| | | |
| | | //计算最大的礼金面额 |
| | | goodsInfoVO.getMoneyInfo().setHongBaoMoney("¥3"); |
| | | private void loadLijinInfo(Long uid, SystemEnum system, GoodsDetailVO goodsDetailVO) { |
| | | VIPEnum vipRank = userLijinMnager.getVIPRank(uid); |
| | | GoodsDetailVO.GoodsHongBaoListVO.UserLevelVO userLevelVO = goodsLijinMnager.getUserLevel(system, vipRank, true); |
| | | //返利UserLevel |
| | | if (goodsDetailVO.getGoods().getPriceList() != null && goodsDetailVO.getGoods().getPriceList().size() > 0) |
| | | goodsDetailVO.getGoods().getPriceList().get(0).setUserLevel(userLevelVO); |
| | | //礼金UserLevel |
| | | userLevelVO = goodsLijinMnager.getUserLevel(system, vipRank, false); |
| | | goodsLijinMnager.loadLijinInfo(vipRank, goodsDetailVO, userLevelVO); |
| | | } |
| | | |
| | | |
| | | private TaoBaoGoodsBrief getTaoBaoGoods(Long id) { |
| | | private TaoBaoGoodsBrief getTaoBaoGoods(String id) { |
| | | try { |
| | | TaoBaoGoodsBrief goods = taoBaoGoodsCacheUtil.getCommonTaoBaoGoodsInfo(id); |
| | | if (goods != null) { |
| | |
| | | return jdGoods; |
| | | } |
| | | |
| | | private PDDGoodsDetail getPDDGoods(Long id, Long uid) { |
| | | private PDDGoodsDetail getPDDGoods(SystemEnum system, Long id, Long uid) { |
| | | String pid = pidManager.getPidCache(system, Constant.SOURCE_TYPE_PDD, SystemPIDInfo.PidType.fanli); |
| | | PDDGoodsDetail pddGoods = null; |
| | | try { |
| | | pddGoods = PinDuoDuoApiUtil.getGoodsDetail(id, PinDuoDuoApiUtil.PID_FANLI, pddAuthService.getFanliCustomParams(uid)); |
| | | pddGoods = PinDuoDuoApiUtil.getGoodsDetail(id, pid, pddAuthService.getFanliCustomParams(uid)); |
| | | } catch (PDDApiException e) { |
| | | e.printStackTrace(); |
| | | if (e.getCode() == PDDApiException.CODE_NOT_AUTH) { |
| | | try { |
| | | pddGoods = PinDuoDuoApiUtil.getGoodsDetail(id, PinDuoDuoApiUtil.PID_FANLI, Constant.PDD_SEARCH_CUSTOMER_PARAMS); |
| | | pddGoods = PinDuoDuoApiUtil.getGoodsDetail(id, pid, Constant.PDD_SEARCH_CUSTOMER_PARAMS); |
| | | } catch (PDDApiException e1) { |
| | | } |
| | | } |