wuwen 5 лет назад
Родитель
Сommit
8090d0c581
24 измененных файлов с 1313 добавлено и 83 удалено
  1. 150 53
      src/main/java/com/ssj/bean/sys/fx/domain/Merchant.java
  2. 13 0
      src/main/java/com/ssj/bean/weixin/sales/domain/LibOrderDetails.java
  3. 3 0
      src/main/java/com/ssj/dao/weixin/library/dao/ILibJoinQueryDao.java
  4. 48 0
      src/main/java/com/ssj/dao/weixin/library/dao/impl/LibJoinQueryDaoImpl.java
  5. 3 0
      src/main/java/com/ssj/dao/weixin/sales/dao/LibSalesPriceDao.java
  6. 4 0
      src/main/java/com/ssj/dao/weixin/sales/dao/LibVipServiceDao.java
  7. 3 0
      src/main/java/com/ssj/service/weixin/library/service/ILibJoinService.java
  8. 11 0
      src/main/java/com/ssj/service/weixin/library/service/impl/LibJoinServiceImpl.java
  9. 1 0
      src/main/java/com/ssj/service/weixin/order/service/OrderService.java
  10. 77 0
      src/main/java/com/ssj/service/weixin/order/service/impl/OrderServiceImpl.java
  11. 1 0
      src/main/java/com/ssj/service/weixin/sales/service/LibOrderDetailsService.java
  12. 8 5
      src/main/java/com/ssj/service/weixin/sales/service/LibSalesPriceService.java
  13. 9 0
      src/main/java/com/ssj/service/weixin/sales/service/LibVipServiceService.java
  14. 108 20
      src/main/java/com/ssj/service/weixin/sales/service/impl/LibOrderDetailsServiceImpl.java
  15. 4 0
      src/main/java/com/ssj/service/weixin/sales/service/impl/LibSalesPriceServiceImpl.java
  16. 110 0
      src/main/java/com/ssj/service/weixin/sales/service/impl/LibVipServiceServiceImpl.java
  17. 27 0
      src/main/java/com/ssj/weixin/library/controller/LibVipController.java
  18. 84 3
      src/main/java/com/ssj/weixin/payment/controller/PaymentController.java
  19. 8 0
      src/main/java/com/ssj/weixin/sales/controller/LibOrderDetailsController.java
  20. 2 2
      src/main/resources/templates/weixin/story/explainForm.html
  21. 79 0
      src/main/resources/templates/weixin/vip/service.html
  22. 57 0
      src/main/resources/templates/weixin/vip/serviceBuyOk.html
  23. 199 0
      src/main/resources/templates/weixin/vip/serviceLocation.html
  24. 304 0
      src/main/resources/templates/weixin/vip/serviceVipBuy.html

+ 150 - 53
src/main/java/com/ssj/bean/sys/fx/domain/Merchant.java

@@ -1,92 +1,118 @@
 package com.ssj.bean.sys.fx.domain;
 
-import com.ssj.bean.common.framework.core.domain.BaseEntity;
-import com.ssj.bean.weixin.libmy.domain.TbLibJoin;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
 import org.hibernate.annotations.Fetch;
 import org.hibernate.annotations.FetchMode;
 import org.hibernate.annotations.NotFound;
 import org.hibernate.annotations.NotFoundAction;
 
-import javax.persistence.*;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import com.ssj.bean.common.framework.core.domain.BaseEntity;
+import com.ssj.bean.weixin.libmy.domain.TbLibJoin;
 
 @Entity
 @Table(name = "fx_merchant")
 public class Merchant extends BaseEntity {
+	
+    private static final long serialVersionUID = 1L;
+    
+    private String posCode;
+    
+    private String orgCode;
 
-	private static final long serialVersionUID = 1L;
-
-	private String posCode;
-
-	private String orgCode;
-
-	private String  manageUserId;
-
-	private String parentPosCode;
-
-	private Integer type;
-
-	private Integer level;
-
-	private String unitName;
+    private String  manageUserId;
 
-	private String legalPerson;
+    private String parentPosCode;
 
-	private String phone;
+    private Integer type;
 
-	private String deputyName;
+    private Integer level;
 
-	private String deputyPhone;
+    private String unitName;
 
-	private Integer status;
+    private String legalPerson;
 
-	private String location;
+    private String phone;
 
-	private String remarks;
+    private String deputyName;
 
-	private Date createTime;
+    private String deputyPhone;
 
-	private Double price;
+    private Integer status;
 
-	private Double hardwarePrice;
+    private String location;
 
-	private String saleLoginName;
+    private String remarks;
+    
+    private Date createTime;
+    
+    private Double price;
+    
+    private Double hardwarePrice;
+    
+    private String saleLoginName;
 
 	private Double outPrice;
-
+	
 	private String libId;
-
+	
 	private TbLibJoin libJoin;
-
+	
 	private Integer portNum;
-
+	
 	private Integer libService;
-
+	
 	private Integer platformService;
-
+	
 	private Integer signService;
-
+	
 	private Integer hardwareService;
-
+	
 	private Date signTime;
-
+	
 	private Date endSignTime;
-
+	
 	private Date curSummaryTime;
 
 	private Date nextSummaryTime;
-
+	
 	private Integer curIsSummary;
-
+	
 	private String address;
-
+	
 	private Integer signType;
-
+	
+	private Integer mealType;
+	
+	private Date startActiveTime;
+	
+	private Date activeTime;
+	
+	private Date endActiveTime;
+	
+	private Date computeTime;
+	
+	private String signerPerson;
+	
+	private String contractNo;
+	
+	private Date contractTime;
+	
+	private Integer posType;
+	
 	@Transient
 	private List<Merchant> subMerchants=new ArrayList<Merchant>();
-
+	
 	public String getSaleLoginName() {
 		return saleLoginName;
 	}
@@ -275,7 +301,7 @@ public class Merchant extends BaseEntity {
 	public void setEndSignTime(Date endSignTime) {
 		this.endSignTime = endSignTime;
 	}
-
+	
 	public Integer getPortNum() {
 		return portNum;
 	}
@@ -300,10 +326,8 @@ public class Merchant extends BaseEntity {
 		this.curSummaryTime = curSummaryTime;
 	}
 
-	@OneToOne(cascade = { CascadeType.PERSIST}, fetch=FetchType.EAGER)
-	@JoinColumn(name="libId",updatable =false,insertable =false)
-	@NotFound(action=NotFoundAction.IGNORE)
-	@Fetch(FetchMode.SELECT)
+	@OneToOne(fetch=FetchType.LAZY)
+	@JoinColumn(name="libId",updatable =false,insertable =false,nullable=true)
 	public TbLibJoin getLibJoin() {
 		return libJoin;
 	}
@@ -327,7 +351,7 @@ public class Merchant extends BaseEntity {
 	public void setSignService(Integer signService) {
 		this.signService = signService;
 	}
-
+	
 	@Transient
 	public List<Merchant> getSubMerchants() {
 		return subMerchants;
@@ -369,4 +393,77 @@ public class Merchant extends BaseEntity {
 		this.signType = signType;
 	}
 
+	public Integer getMealType() {
+		return mealType;
+	}
+
+	public void setMealType(Integer mealType) {
+		this.mealType = mealType;
+	}
+
+	public Date getActiveTime() {
+		return activeTime;
+	}
+
+	public void setActiveTime(Date activeTime) {
+		this.activeTime = activeTime;
+	}
+
+	public Date getComputeTime() {
+		return computeTime;
+	}
+
+	public void setComputeTime(Date computeTime) {
+		this.computeTime = computeTime;
+	}
+
+	public Date getStartActiveTime() {
+		return startActiveTime;
+	}
+
+	public void setStartActiveTime(Date startActiveTime) {
+		this.startActiveTime = startActiveTime;
+	}
+
+
+	public Date getEndActiveTime() {
+		return endActiveTime;
+	}
+
+	public void setEndActiveTime(Date endActiveTime) {
+		this.endActiveTime = endActiveTime;
+	}
+
+	public String getSignerPerson() {
+		return signerPerson;
+	}
+
+	public void setSignerPerson(String signerPerson) {
+		this.signerPerson = signerPerson;
+	}
+
+	public String getContractNo() {
+		return contractNo;
+	}
+
+	public void setContractNo(String contractNo) {
+		this.contractNo = contractNo;
+	}
+
+	public Date getContractTime() {
+		return contractTime;
+	}
+
+	public void setContractTime(Date contractTime) {
+		this.contractTime = contractTime;
+	}
+
+	public Integer getPosType() {
+		return posType;
+	}
+
+	public void setPosType(Integer posType) {
+		this.posType = posType;
+	}
+
 }

+ 13 - 0
src/main/java/com/ssj/bean/weixin/sales/domain/LibOrderDetails.java

@@ -136,6 +136,12 @@ public class LibOrderDetails  extends BaseEntity{
 	 * 联系方式
 	 */
 	private String phone;
+	
+	/**
+	 * 家长角色
+	 */
+	private String parentRole;
+	
 	/**
 	 * 学校
 	 */
@@ -368,6 +374,13 @@ public class LibOrderDetails  extends BaseEntity{
 		this.phone = phone;
 	}
 	@Transient
+	public String getParentRole() {
+		return parentRole;
+	}
+	public void setParentRole(String parentRole) {
+		this.parentRole = parentRole;
+	}
+	@Transient
 	public String getSchool() {
 		return school;
 	}

+ 3 - 0
src/main/java/com/ssj/dao/weixin/library/dao/ILibJoinQueryDao.java

@@ -30,6 +30,8 @@ public interface ILibJoinQueryDao {
 	 
 	 public List<Map<String, Object>> getLocationJoin(String league_lat, String league_lng,Integer type);
 	 
+	 public List<Map<String, Object>> getLocationMerchant(String league_lat, String league_lng,Integer type);
+	 
 	  public List<Map<String, Object>> getPositionArea(String league_lat, String league_lng,Integer type,String schoolName);
 	 
 	 public Page<Map<String, Object>>  getLocationArea(Map<String, Object> searchParams, Pageable pageable);
@@ -37,6 +39,7 @@ public interface ILibJoinQueryDao {
 	 public Page<Map<String, Object>>  getLocationJoinService(Map<String, Object> searchParams, Pageable pageable);
 	 
 	 public List<Map<String, Object>> getNoLocationJoin(Integer type);
+	 public List<Map<String, Object>> getNoLocationMerchant(Integer type);
 	 public Page<Map<String, Object>> growthRecordList(Map<String, Object> params, Pageable pageable);
 	 
 	

+ 48 - 0
src/main/java/com/ssj/dao/weixin/library/dao/impl/LibJoinQueryDaoImpl.java

@@ -280,6 +280,45 @@ public class LibJoinQueryDaoImpl implements ILibJoinQueryDao{
 		queryParams.add(type);
 		return dao.findMap(sql, queryParams.toArray());
 	}
+	
+	
+	
+	@Override
+	public List<Map<String, Object>> getLocationMerchant(String league_lat, String league_lng,Integer type) {
+		String sql ="SELECT\n" +
+				 "	t.* , ROUND(\n" +
+				 "		6378.138 * 2 * ASIN(\n" +
+				 "			SQRT(\n" +
+				 "				POW(\n" +
+				 "					SIN(\n" +
+				 "						(\n" +
+				 "							? * PI() / 180 - league_lat * PI() / 180\n" +
+				 "						) / 2\n" +
+				 "					),\n" +
+				 "					2\n" +
+				 "				) + COS(? * PI() / 180) * COS(league_lat * PI() / 180) * POW(\n" +
+				 "					SIN(\n" +
+				 "						(\n" +
+				 "							? * PI() / 180 - league_lng * PI() / 180\n" +
+				 "						) / 2\n" +
+				 "					),\n" +
+				 "					2\n" +
+				 "				)\n" +
+				 "			)\n" +
+				 "		)\n" +
+				 "	,2) AS juli\n" +
+				 "FROM\n" +
+				 "	tb_lib_join t LEFT JOIN fx_merchant m ON t.id=m.lib_id where t.type >=? AND m.id is NOT NULL \n" +
+				 "ORDER BY\n" +
+				 "	juli ASC";
+		List<Object> queryParams = new ArrayList<Object>();
+		queryParams.add(league_lat);
+		queryParams.add(league_lat);
+		queryParams.add(league_lng);
+		queryParams.add(type);
+		return dao.findMap(sql, queryParams.toArray());
+	}
+	
 
 	@Override
 	public List<Map<String, Object>> getNoLocationJoin(Integer type) {
@@ -288,6 +327,15 @@ public class LibJoinQueryDaoImpl implements ILibJoinQueryDao{
 		queryParams.add(type);
 		return dao.findMap(sql, queryParams.toArray());
 	}
+	
+	@Override
+	public List<Map<String, Object>> getNoLocationMerchant(Integer type) {
+		String sql ="SELECT * from  tb_lib_join LEFT JOIN fx_merchant m ON t.id=m.lib_id where t.type >=? AND m.id is NOT NULL  ";
+		List<Object> queryParams = new ArrayList<Object>();
+		queryParams.add(type);
+		return dao.findMap(sql, queryParams.toArray());
+	}
+	
 
 	@Override
 	public	List<Map<String, Object>> countLibVipNum(){

+ 3 - 0
src/main/java/com/ssj/dao/weixin/sales/dao/LibSalesPriceDao.java

@@ -42,6 +42,9 @@ public interface LibSalesPriceDao  extends JpaRepository<LibSalesPrice, String>{
 	 public List<LibSalesPrice> findByLibId(String libId);
 	 
 	LibSalesPrice findByLibIdAndSpeciesAndType(String libId,String species ,String type);
+	
+	@Query(nativeQuery = true, value = " select *  from   tb_lib_sales_price  where lib_id is null and species=?1  ORDER BY species asc,type asc ")
+	List<LibSalesPrice> findByLibIdAndSpeciesAndType(String species);
 
 	List<LibSalesPrice> findByLibIdAndSpecies(String libId, String species);
 

+ 4 - 0
src/main/java/com/ssj/dao/weixin/sales/dao/LibVipServiceDao.java

@@ -326,4 +326,8 @@ public interface LibVipServiceDao extends JpaRepository<LibVipService, String> {
 			" and to_days(end_time) >= to_days(now()) \n" +
 			" ORDER BY species,service_sort,correct_type,start_time limit 1;")
 	LibVipService findCorrectTypeByVipId(String vipId);
+	
+    @Query(nativeQuery = true, value = "select * from tb_lib_vip_service where vip_id=?1 and lib_id=?2 and species=?3 and type=?4 limit 1")
+	LibVipService findTopByVipIdAndLibIdAndSpeciesAndTypeOrderByCreateTimeDesc(String vipId, String LibId, String species, String type);
+	
 }

+ 3 - 0
src/main/java/com/ssj/service/weixin/library/service/ILibJoinService.java

@@ -43,6 +43,8 @@ public interface ILibJoinService extends BaseService<TbLibJoin, String> {
 
 	  
 	  public List<Map<String, Object>> getLocationJoin(String league_lat, String league_lng,Integer type);
+	  
+	  public List<Map<String, Object>> getLocationMerchant(String league_lat, String league_lng,Integer type);
 	  /**
 	   * 根据定位查询图书馆,带分页
 	  * @param searchParams
@@ -66,6 +68,7 @@ public interface ILibJoinService extends BaseService<TbLibJoin, String> {
 	   */
 	  public Page<Map<String, Object>>  getLocationArea(Map<String, Object> searchParams, Pageable pageable);
 	  public List<Map<String, Object>> getNoLocationJoin(Integer type);
+	  public List<Map<String, Object>> getNoLocationMerchant(Integer type);
 	  
 	  
 	  public List<TbLibJoin> getLibJoinByCode(List<String> orgCode);

+ 11 - 0
src/main/java/com/ssj/service/weixin/library/service/impl/LibJoinServiceImpl.java

@@ -137,6 +137,12 @@ public class LibJoinServiceImpl extends BaseServiceImpl<TbLibJoin, String> imple
 	public List<Map<String, Object>> getLocationJoin(String league_lat, String league_lng,Integer type) {
 		return libJoinQueryDao.getLocationJoin(league_lat, league_lng,type);
 	}
+	
+	@Override
+	public List<Map<String, Object>> getLocationMerchant(String league_lat, String league_lng,Integer type) {
+		return libJoinQueryDao.getLocationMerchant(league_lat, league_lng,type);
+	}
+
 	@Override
 	 public Page<Map<String, Object>>  getLocationArea(Map<String, Object> searchParams, Pageable pageable){
 		return libJoinQueryDao.getLocationArea(searchParams, pageable);
@@ -291,4 +297,9 @@ public class LibJoinServiceImpl extends BaseServiceImpl<TbLibJoin, String> imple
 		libBorrowedServiceService.insertBorrowedService(lib.getId(),lib.getLibtype());
 
 	}
+
+	@Override
+	public List<Map<String, Object>> getNoLocationMerchant(Integer type) {
+		return libJoinQueryDao.getNoLocationMerchant(type);
+	}
 }

+ 1 - 0
src/main/java/com/ssj/service/weixin/order/service/OrderService.java

@@ -97,5 +97,6 @@ public interface OrderService extends BaseService<Order, String>{
 	 
 	 public Map<String, Object>  payInfo(User user,String total_fee,String pay_type);
 	 public Map<String, Object>  payVIP(User user,LibOrderDetails libOrderDetails);
+	 public Map<String, Object> payService(User user, LibOrderDetails libOrderDetails);
 	 public ResponseEntity  refund(String orderId,BigDecimal refund_fee,String  userId);
 }

+ 77 - 0
src/main/java/com/ssj/service/weixin/order/service/impl/OrderServiceImpl.java

@@ -431,4 +431,81 @@ public class OrderServiceImpl extends BaseServiceImpl<Order, String> implements
 		
 	}
 	
+	
+	@Override
+	public Map<String, Object> payService(User user, LibOrderDetails libOrderDetails) {
+        String desc = "私塾家-小塾学伴缴费";
+        
+     	String libId = libOrderDetails.getLibId();
+		TbLibJoin libJoin =joinService.getById(libId);
+		libOrderDetails.setLibtype(libJoin.getLibtype());//设置订单的模式
+		libOrderDetails.setUserId(user.getId());
+		
+		logger.info("===私塾家-小塾学伴缴费fee:"+libOrderDetails.getPrice());
+		
+		SortedMap<Object,Object> params = new TreeMap<Object,Object>();
+		Map<String, Object> data = new HashMap<String, Object>();
+		String orderNo = OrderUtil.getOrderCode();//生成订单号
+		
+		OrderHelper orderHelper = new OrderHelper();
+		String url =(String) SystemResourceLocator.getValue("sys_url")+"/weixin/payment/pay_vip_callback.html";
+		try {
+			//请求微信统一下单接口,获取最重要的prepay_id.
+			Map<String,Object> map = orderHelper.reqestOrder(user.getAccount(),libOrderDetails.getPrice().multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString(),orderNo,desc,url);
+			String prepay_id = (String) map.get("prepay_id");
+			logger.info("===微信统一下单接口返回的prepay_id:"+prepay_id);
+			//微信统一下单接口返回后,生成订单保存到数据库
+			Order o = new Order();
+			o.setOrderMoney(libOrderDetails.getPrice());
+			o.setOrderNo(orderNo);
+			o.setOrderStatus(0);
+			o.setPrepayId(prepay_id);
+			o.setCreateTime(new Date());
+			o.setUserId(user.getId());
+			o.setPayBy(1);//1 H5支付
+			o.setIsClosed(0);
+			o.setOrderType(4);
+			o=this.save(o);
+			libOrderDetails.setCreateTime(new Date());
+			libOrderDetails.setOrderId(o.getId());
+			libOrderDetails.setOrderNo(orderNo);
+			tokenManager.set(orderNo, libOrderDetails,7 * 24 * 3600);//存放redis
+			logger.info("==发起支付=orderNo-"+orderNo+"(libOrderDetails)"+JSON.toJSONString(libOrderDetails));
+			//页面发起支付接口需要的参数:appId,timeStamp,nonceStr,package,signType,paySign
+			String appId = ConfigUtil.APPID;
+			String nonceStr = CommonUtil.CreateNoncestr();
+			String timeStamp = Long.toString(System.currentTimeMillis());
+			String singType = ConfigUtil.SIGN_TYPE;
+			String package_ = "prepay_id="+prepay_id;
+			
+			//组织map去sign签名
+			params.put("appId", appId);
+			params.put("nonceStr", nonceStr);
+			params.put("package", "prepay_id="+prepay_id);
+			params.put("signType",singType);
+			params.put("timeStamp", timeStamp);//最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
+			 data.put("orderNo", orderNo);//向页面传入订单ID
+			//logger.info("===组织支付接口所需的sign签名:"+params);
+			String paySign =  PayCommonUtil.createSign("UTF-8", params,ConfigUtil.PAYKEY);//paySign的生成规则和Sign的生成规则一致
+			
+			//将参数传到页面,组织发起支付
+			data.put("appId", appId);
+			data.put("timeStamp",timeStamp);
+			data.put("nonceStr", nonceStr);
+			data.put("package", package_);
+			data.put("signType", singType);
+			data.put("paySign", paySign);//paySign的生成规则和Sign的生成规则一致
+			
+			data.put("packageValue", package_);//这里用packageValue是预防package是关键字在js获取值出错   
+			//data.put("sendUrl", ConfigUtil.PAY_SUCCESS_URL); //付款成功后跳转的页面
+			
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+		return data;
+	}
+	
+	
+	
 }

+ 1 - 0
src/main/java/com/ssj/service/weixin/sales/service/LibOrderDetailsService.java

@@ -237,6 +237,7 @@ public interface LibOrderDetailsService extends BaseService<LibOrderDetails, Str
 	* @void
 	 */
 	public void saveOrderDetails(LibOrderDetails  libOrderDetails);
+	public void saveServiceOrderDetails(LibOrderDetails  libOrderDetails);
 	public void saveOrderDetailsOneTwoOne(LibOrderDetails  libOrderDetails);
 	/**
 	 * 保存特色课(代付)

+ 8 - 5
src/main/java/com/ssj/service/weixin/sales/service/LibSalesPriceService.java

@@ -1,14 +1,15 @@
 package com.ssj.service.weixin.sales.service;
 
-import com.ssj.bean.weixin.sales.domain.LibSalesPrice;
-import com.ssj.framework.core.common.service.BaseService;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-
 import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+import com.ssj.bean.weixin.sales.domain.LibSalesPrice;
+import com.ssj.framework.core.common.service.BaseService;
+
 
 /** 
  * @author  ZhangCaibao 
@@ -32,5 +33,7 @@ public interface LibSalesPriceService extends BaseService<LibSalesPrice, String>
 	 public List<LibSalesPrice> findByLibId(String libId);
 	 
 	 public LibSalesPrice findByLibIdAndSpeciesAndType(String libId,String species ,String type);
+	 
+	 public List<LibSalesPrice> findByLibIdAndSpeciesAndType(String species);
 
 }

+ 9 - 0
src/main/java/com/ssj/service/weixin/sales/service/LibVipServiceService.java

@@ -634,4 +634,13 @@ public interface LibVipServiceService extends BaseService<LibVipService, String>
 	 * @param vipIdList
 	 */
 	void clearServiceCache(String libId, List<String> vipIdList);
+	
+	
+	
+	void insertLibServiceByType(String vipId, String libId, Date endDate, int signType);
+	    
+	void insertLibCorrectServiceByType(String vipId, String libId, Date endDate, int signType);
+	
+	LibVipService findTopByVipIdAndLibIdAndSpeciesAndTypeOrderByCreateTimeDesc(String vipId, String LibId, String species, String type);
+	
 }

+ 108 - 20
src/main/java/com/ssj/service/weixin/sales/service/impl/LibOrderDetailsServiceImpl.java

@@ -1,5 +1,30 @@
 package com.ssj.service.weixin.sales.service.impl;
 
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
 import com.alibaba.fastjson.JSON;
 import com.ssj.bean.sys.codeexchange.CodeExchange;
 import com.ssj.bean.weixin.card.domain.LibCardDetail;
@@ -18,8 +43,10 @@ import com.ssj.framework.basic.utils.DateHelper;
 import com.ssj.framework.core.common.service.BaseServiceImpl;
 import com.ssj.framework.core.security.manager.TokenManager;
 import com.ssj.framework.core.util.Constant;
+import com.ssj.framework.core.util.PasswordUtil;
 import com.ssj.framework.core.util.StringUtil;
 import com.ssj.framework.core.util.SystemResourceLocator;
+import com.ssj.framework.idworker.IdWorker;
 import com.ssj.framework.weixin.util.DateUtil;
 import com.ssj.service.sys.codeexchange.CodeExchangeService;
 import com.ssj.service.weixin.card.service.ILibCardService;
@@ -27,27 +54,12 @@ import com.ssj.service.weixin.library.service.IBookManagerService;
 import com.ssj.service.weixin.library.service.ILibJoinService;
 import com.ssj.service.weixin.library.service.ILibVipService;
 import com.ssj.service.weixin.push.service.PushTemplateService;
-import com.ssj.service.weixin.sales.service.*;
+import com.ssj.service.weixin.sales.service.LibCourseService;
+import com.ssj.service.weixin.sales.service.LibOrderDetailsService;
+import com.ssj.service.weixin.sales.service.LibStaffingService;
+import com.ssj.service.weixin.sales.service.LibVipCodeService;
+import com.ssj.service.weixin.sales.service.LibVipServiceService;
 import com.ssj.service.weixin.user.service.UserService;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.repository.PagingAndSortingRepository;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.lang.reflect.InvocationTargetException;
-import java.math.BigDecimal;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 
 /** 
@@ -1462,4 +1474,80 @@ public class LibOrderDetailsServiceImpl extends BaseServiceImpl<LibOrderDetails,
 			tokenManager.set(Constant.EXITED_STUDENT_PREFIX + newLibId, newLibExitedStudentIdList);
 		}
 	}
+	
+	
+	
+	@Override
+	@Transactional
+	public void saveServiceOrderDetails(LibOrderDetails libOrderDetails) {
+		logger.info("小塾学伴缴费,添加订单--"+DateHelper.getDateTime(libOrderDetails.getCreateTime()));
+		User user =userService.getById(libOrderDetails.getUserId());
+		TbLibJoin libJoin=joinService.getById(libOrderDetails.getLibId());
+		
+		libOrderDetails.setOrderStatus(1);//支付成功
+		
+		Integer number = libOrderDetails.getNumber();
+		
+		LibVip libVip=vipService.findByUserIdAndChildName(libOrderDetails.getUserId(), libOrderDetails.getChildName());
+		if(libVip==null) {
+			User studentUser=new User();
+			studentUser.setId(IdWorker.generateId());
+			studentUser.setUserName(libOrderDetails.getChildName());
+			studentUser.setCreateTime(new Date());
+			studentUser.setPassword("123456");
+			studentUser.setPwdSalt(PasswordUtil.generateSalt());
+			studentUser.setPassword(PasswordUtil.initPassword(studentUser.getPassword(), studentUser.getPwdSalt()));
+			studentUser=userService.save(studentUser);
+			
+			libVip=new LibVip();
+			libVip.setChildType(0);
+			libVip.setUserId(user.getId());
+			libVip.setParentName(libOrderDetails.getParentName());
+			libVip.setChildName(libOrderDetails.getChildName());
+			libVip.setPhone(libOrderDetails.getPhone());
+			libVip.setSchool(libOrderDetails.getSchool());
+			libVip.setParentRole(libOrderDetails.getParentRole());
+			libVip.setGrade(libOrderDetails.getGrade());
+			libVip.setLibId(libOrderDetails.getLibId());
+			libVip.setStat("1");
+			libVip.setChildUserId(studentUser.getId());
+			libVip.setCreateTime(new Date());
+			libVip=vipService.save(libVip);
+		}
+		
+		try {
+			Date startTime=new Date();
+			
+			LibVipService libVipService = libVipServiceService.findTopByVipIdAndLibIdAndSpeciesAndTypeOrderByCreateTimeDesc(libVip.getId(), libJoin.getId(), "S003", "C025");
+			if(libVipService!=null) {
+				//有效的
+				if(libVipService.getStat()==1 ) {
+					if(libVipService.getEndTime().getTime()>new Date().getTime()) {
+						startTime=libVipService.getEndTime();
+					}
+				}
+			}
+			
+			libOrderDetails.setStartTime(startTime);
+			
+			if("C022".equals(libOrderDetails.getPriceType())){
+				libOrderDetails.setEndTime(DateHelper.getMonthDate(startTime, number));
+			}
+			this.save(libOrderDetails);
+			
+			//给学生增加一个默认的永久校区批改服务
+			libVipServiceService.insertLibServiceByType(libVip.getId(), libJoin.getId(), libOrderDetails.getEndTime(), libJoin.getSignType());
+            
+			logger.info("小塾学伴缴费支付成功后,添加销售订单"+libOrderDetails.getId());
+			
+			tokenManager.createServiceCount("ZUOYB_SERVICE_"+libVip.getId()+"_"+libOrderDetails.getLibId(), "1");	
+
+		}catch(Exception e){
+			e.printStackTrace();
+			logger.error("保存购卡信息异常");
+		}
+		
+	}
+	
+	
 }

+ 4 - 0
src/main/java/com/ssj/service/weixin/sales/service/impl/LibSalesPriceServiceImpl.java

@@ -72,5 +72,9 @@ public class LibSalesPriceServiceImpl extends BaseServiceImpl<LibSalesPrice, Str
 			String species, String type) {
 		return libSalesPriceDao.findByLibIdAndSpeciesAndType(libId, species, type);
 	}
+	@Override
+	public List<LibSalesPrice> findByLibIdAndSpeciesAndType(String species) {
+		return libSalesPriceDao.findByLibIdAndSpeciesAndType(species);
+	}
 
 }

+ 110 - 0
src/main/java/com/ssj/service/weixin/sales/service/impl/LibVipServiceServiceImpl.java

@@ -3,6 +3,7 @@ package com.ssj.service.weixin.sales.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.ssj.alipay.utils.AlipayOrderHelper;
 import com.ssj.bean.curator.TbVacationLimit;
+import com.ssj.bean.sys.fx.domain.Merchant;
 import com.ssj.bean.sys.give.GiveRecord;
 import com.ssj.bean.weixin.libmy.domain.LibVip;
 import com.ssj.bean.weixin.libmy.domain.TbLibJoin;
@@ -28,6 +29,7 @@ import com.ssj.service.conch.common.dto.ServiceRecordDto;
 import com.ssj.service.conch.common.request.PayVipBatchReq;
 import com.ssj.service.conch.curator.service.v1.IVacationLimitService;
 import com.ssj.service.conch.parents.v2.dto.ServiceRecordV1Dto;
+import com.ssj.service.sys.fx.service.MerchantService;
 import com.ssj.service.sys.give.GiveRecordService;
 import com.ssj.service.weixin.library.service.IBookManagerService;
 import com.ssj.service.weixin.library.service.ILibJoinService;
@@ -101,6 +103,8 @@ public class LibVipServiceServiceImpl extends BaseServiceImpl<LibVipService, Str
 	private IVacationLimitService vacationLimitService;
 	@Autowired
 	private GiveRecordService giveRecordService;
+	@Autowired
+	private MerchantService merchantService;
 	@Override
 	public PagingAndSortingRepository<LibVipService, String> getDao() {
 		return libVipServiceDao;
@@ -1683,5 +1687,111 @@ public class LibVipServiceServiceImpl extends BaseServiceImpl<LibVipService, Str
 		});
 	}
 
+	
+	@Override
+    public void insertLibServiceByType(String vipId, String libId, Date endDate, int signType) {
+        if (signType > 0) {
+            //新套餐,需要给校区服务和批改服务两个,结束时间保持一致
+            //查询这个馆下有没有有效的服务
+            //2021-02-07 深圳吴老师学校商户只给平台批改服务
+            Merchant merchant = merchantService.getMerchantByLibId(libId);
+            if(Objects.isNull(merchant) || merchant.getPosType()!=3){
+				this.insertLibCorrectService(vipId, libId, endDate);
+			}
+            this.insertLibService(vipId, libId, endDate);
+        } else {
+            //老套餐,只需要给指定的校区服务
+            this.insertLibService(vipId, libId, DateUtil.parse_yyyyMMdd("9999-01-01"));
+        }
+    }
+
+    @Override
+    public void insertLibCorrectServiceByType(String vipId, String libId, Date endDate, int signType) {
+        if (signType > 0) {
+            //新套餐,给的这个服务需要和校区服务保持一致的结束时间
+            //查询这个馆下有没有有效的服务
+            this.insertLibCorrectService(vipId, libId, endDate);
+        } else {
+            //老套餐,直接给永久服务
+            this.insertLibCorrectService(vipId, libId, DateUtil.parse_yyyyMMdd("9999-01-01"));
+        }
+    }
+    
+
+    /**
+     * 新增校区批改服务
+     *
+     * @param vipId
+     * @param libId
+     * @param endDate
+     */
+    void insertLibCorrectService(String vipId, String libId, Date endDate) {
+        Date now = new Date();
+        //之前的校区批改服务
+        LibVipService libVipService = libVipServiceDao.findTopByVipIdAndLibIdAndSpeciesAndTypeOrderByCreateTimeDesc(vipId, libId, "S003", "C025");
+        if (libVipService == null) {
+            libVipService = new LibVipService();
+            libVipService.setVipId(vipId);
+            libVipService.setLibId(libId);
+            libVipService.setStartTime(now);
+            libVipService.setEndTime(endDate);
+            libVipService.setStat(1);
+            libVipService.setSpecies("S003");
+            libVipService.setType("C025");
+            libVipService.setCreateTime(now);
+            //为校区批改服务
+            libVipService.setCorrectType(5);
+            //排所有服务优先级第4
+            libVipService.setServiceSort(4);
+            this.save(libVipService);
+        } else {
+            libVipService.setEndTime(endDate);
+            libVipService.setStat(1);
+            this.save(libVipService);
+        }
+    }
+
+    /**
+     * 新加校区服务
+     *
+     * @param vipId
+     * @param libId
+     * @param endDate
+     */
+    void insertLibService(String vipId, String libId, Date endDate) {
+        Date now = new Date();
+        //之前的校区服务
+        LibVipService libVipService = libVipServiceDao.findTopByVipIdAndLibIdAndSpeciesAndTypeOrderByCreateTimeDesc(vipId, libId, "S003", "C024");
+        if (libVipService == null) {
+            libVipService = new LibVipService();
+            libVipService.setVipId(vipId);
+            libVipService.setLibId(libId);
+            libVipService.setStartTime(now);
+            libVipService.setEndTime(endDate);
+            libVipService.setSpecies("S003");
+            libVipService.setType("C024");
+            libVipService.setCreateTime(now);
+            //为校区服务
+            libVipService.setCorrectType(2);
+            //排所有服务优先级第3
+            libVipService.setServiceSort(3);
+            this.save(libVipService);
+        }else {
+	    	libVipService.setEndTime(endDate);
+	        libVipService.setStat(1);
+	        this.save(libVipService);
+        }
+
+    }
+
+	@Override
+	public LibVipService findTopByVipIdAndLibIdAndSpeciesAndTypeOrderByCreateTimeDesc(String vipId, String LibId,String species, String type) {
+		return this.findTopByVipIdAndLibIdAndSpeciesAndTypeOrderByCreateTimeDesc(vipId, LibId, species, type);
+	}
+
+
+    
+	
+
 
 }

+ 27 - 0
src/main/java/com/ssj/weixin/library/controller/LibVipController.java

@@ -899,6 +899,16 @@ public class LibVipController extends BaseController {
 		response.success(data,"获取成功");
 		return response;
 	}
+	@RequestMapping(value="/getLocationMerchantData" ,method=RequestMethod.POST)
+	@ResponseBody
+	public ResponseEntity getLocationMerchantData(Model model,String  league_lat ,String league_lng,Integer type){
+		ResponseEntity response = new ResponseEntity();
+		Map<String, Object> data = new  HashMap<String, Object>();
+		data.put("list", joinService.getLocationMerchant(league_lat, league_lng,type));
+		response.success(data,"获取成功");
+		return response;
+	}
+	
 	@RequestMapping(value="/getNoLocationData" ,method=RequestMethod.POST)
 	@ResponseBody
 	public ResponseEntity getNoLocationData(Model model,Integer type){
@@ -908,12 +918,29 @@ public class LibVipController extends BaseController {
 		response.success(data,"获取成功");
 		return response;
 	}
+	
+	@RequestMapping(value="/getNoLocationMerchantData" ,method=RequestMethod.POST)
+	@ResponseBody
+	public ResponseEntity getNoLocationMerchantData(Model model,Integer type){
+		ResponseEntity response = new ResponseEntity();
+		Map<String, Object> data = new  HashMap<String, Object>();
+		data.put("list", joinService.getNoLocationMerchant(type));
+		response.success(data,"获取成功");
+		return response;
+	}
+	
 	@RequestMapping("/location_{vipId}/{type}")
 	public String location(Model model,@PathVariable String vipId,@PathVariable int type){
 		model.addAttribute("vipId", vipId);
 		model.addAttribute("type", type);
 		return "weixin/vip/location";
 	}
+	
+	@RequestMapping("/serviceLocation")
+	public String serviceLocation(Model model){
+		return "weixin/vip/serviceLocation";
+	}
+	
 	@RequestMapping("/locationArea_{vipId}/{libId}/{type}")
 	public String locationArea(Model model,@PathVariable String vipId,@PathVariable String libId,@PathVariable int type,
 							   String vipCode,String day,String ctype,String schoolName){

+ 84 - 3
src/main/java/com/ssj/weixin/payment/controller/PaymentController.java

@@ -57,9 +57,7 @@ public class PaymentController extends BaseController {
 	
 	@Autowired
 	private OrderService orderService;
-
-
-
+	
 	@Autowired
 	private SortService sortService;
 	
@@ -280,6 +278,10 @@ public class PaymentController extends BaseController {
 									}else if("S007".equals(priceSpecies)){
 										//通讯服务
 										libOrderDetailsService.saveCommuOrderDetails(libOrderDetails);
+									}else if("S008".equals(priceSpecies)){
+										//小塾学伴缴费
+										libOrderDetailsService.saveServiceOrderDetails(libOrderDetails);
+									
 									} else if ("S003".equals(priceSpecies) && "newZybMethod".equals(libOrderDetails.getIsType())) {
 										//作业吧服务(NEW)  saveZybOrderDetails
 										libOrderDetailsService.saveBatchZybOrderDetails(libOrderDetails);
@@ -1116,6 +1118,85 @@ public class PaymentController extends BaseController {
 		return "/weixin/vip/vipbuybatch";
 	}
 
+	
+	/**
+	 * 小塾学伴
+	* @return
+	* 创建人:wuwne 
+	* 2017年12月1日14:17:04
+	* @String
+	 */
+	@RequestMapping("/service")
+	public String service(Model model){
+		return "weixin/vip/service";
+	}
+	
+	
+	/**
+	* C端家长支付购买小塾学伴
+	* @param model
+	* @param libId
+	* @return
+	*   创建人:wuwen 
+	* 2021年2月20日10:32:47
+	* @String
+	*/
+	@RequestMapping("/serviceVipBuy_{libId}")
+	public String serviceVipBuy(Model model,@PathVariable String libId){
+		
+		//通用的收费标准,150/月
+		List<LibSalesPrice> specieList=libSalesPriceService.findByLibIdAndSpeciesAndType("S008");
+		
+		User user=UserUtil.getUser(request);
+		TbLibJoin tbLibJoin=joinService.getById(libId);
+		
+		model.addAttribute("grade", sortService.getParamValByCode("grade"));//年级
+		model.addAttribute("libId", libId);
+		model.addAttribute("user", user);
+		model.addAttribute("tbLibJoin", tbLibJoin);
+		
+		model.addAttribute("specieList", specieList);
+
+		return "weixin/vip/serviceVipBuy";
+	}
+	
+	
+	@ResponseBody
+	@RequestMapping(value = "/payService", method = RequestMethod.POST)
+	public ResponseEntity payService(LibOrderDetails libOrderDetails) {
+		ResponseEntity responseEntity = new ResponseEntity();
+		User user = UserUtil.getUser(request);
+	
+		//单价乘以数量,计算出总价
+		LibSalesPrice libSalesPrice=libSalesPriceService.getById(libOrderDetails.getSalesPriceId());
+		libOrderDetails.setPrice(libSalesPrice.getPrice().multiply(new BigDecimal(libOrderDetails.getNumber())));
+		
+		if(libOrderDetails.getPrice().compareTo(new BigDecimal(0))<=0){
+			responseEntity.failure("金额为0,不能发起支付"); 
+			return responseEntity;
+		}
+		
+		libOrderDetails.setPriceSpecies(libSalesPrice.getSpecies());
+		libOrderDetails.setPriceType(libSalesPrice.getType());
+		
+		try{
+			Map<String, Object> data = orderService.payService(user, libOrderDetails);
+			String userAgent = request.getHeader("user-agent");
+			char agent = userAgent.charAt(userAgent.indexOf("MicroMessenger")+15);
+			data.put("agent", new String(new char[]{agent}));//微信版本号,用于前面提到的判断用户手机微信的版本是否是5.0以上版本。
+			logger.info("===发起支付接口数据准备成功:"+data);
+			
+			responseEntity.success(data, "发起支付接口数据准备成功");
+			
+		} catch (Exception e) {
+			e.printStackTrace();
+			responseEntity.failure(ResponseConstant.CODE_000, "服务器发生异常,请稍后重试");
+		}
+		return responseEntity;
+	}
+	
+	
+	
 
 
 }

+ 8 - 0
src/main/java/com/ssj/weixin/sales/controller/LibOrderDetailsController.java

@@ -727,4 +727,12 @@ public class LibOrderDetailsController extends BaseController{
 		
 	}
 	
+	
+	@RequestMapping("/serviceBuyOk_{orderNo}")
+	public String serviceBuyOk(Model model,@PathVariable String orderNo,String cardName){
+		return "weixin/vip/serviceBuyOk";
+	}
+	
+	
+	
 }

+ 2 - 2
src/main/resources/templates/weixin/story/explainForm.html

@@ -3,7 +3,7 @@
 	<head>
 		<meta charset="UTF-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;">
-		<title>小塾学伴,学习效果看得见</title>
+		<title>小塾学伴 · AI智慧教育系统</title>
 		<link rel="stylesheet" th:href="@{/static/story/css/explain.css}">
 	</head>
 	<body>
@@ -15,7 +15,7 @@
 			<div class="section-li">
 				<div id="" class="section-li-header">
 					<div id="" class="section-li-one">小塾学伴</div>
-					<div id="" class="section-li-two">学习效果看得见!</div>
+					<div id="" class="section-li-two">AI智慧教育系统</div>
 					<div id="" class="section-li-three">
 						<img th:src="@{/static/story/img/form_bg.png}" >
 					</div>

+ 79 - 0
src/main/resources/templates/weixin/vip/service.html

@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+<title>定位校区</title>
+<link href="style/jquery-weui.css" th:href="@{/static/style/jquery-weui.css(version=${#dates.format(#calendars.createNow(),'yyyyMMdd')})}" rel="stylesheet"/>
+<script th:include="weixin/common/includeJS_CSS" th:remove="tag" ></script>
+<link href="style/vipcard.css" th:href="@{/static/style/vipcard.css(version=${#dates.format(#calendars.createNow(),'yyyyMMdd')})}" rel="stylesheet"/>
+</head>
+
+<script type="text/javascript">
+$(function(){
+	jssdk();
+});
+function  jssdk(){
+	 $.ajax({
+		 url : "[[${sysUrl}]]/weixin/question/wxjssdk",
+         type : 'post',
+         dataType : 'json',
+         contentType : "application/x-www-form-urlencoded; charset=utf-8",
+         data : {
+             'url' : location.href.split('#')[0]
+         },
+         success : function(data) {
+        	 if(data && data.code == 999){
+             wx.config({
+                 debug : false,
+                 appId : data.data.appId,
+                 timestamp : data.data.timestamp,
+                 nonceStr : data.data.noncestr,
+                 signature : data.data.signature,
+                 jsApiList : [ 
+					        'getLocation',
+					        'openLocation',
+					        'onMenuShareAppMessage',  
+							'onMenuShareTimeline'
+                              ]
+             });
+             var title="私塾家-社区化教育共享平台";
+             var imgUrl='[[${imgUrl}]]/images/sharingschool.jpg';
+             var desc ="为孩子找个好老师-阅读辅导,一站解决,第三空间,伴我成长,家长社群,认知共享,微校结对,家教无忧!";	  
+             var link = "[[${sysUrl}]]/wechat/index.html";
+             var curl="[[${sysUrl}]]/weixin/payment/serviceVipBuy_#LIBID#.html";
+	             wx.ready(function () {
+	    			      wx.getLocation({
+		            		    type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
+		            		    success: function (res) {
+		            		        var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
+		            		        var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
+		            		        var params ={'league_lat':latitude,'league_lng':longitude,'type': '1' };
+		            		        var url ="[[${sysUrl}]]/weixin/libVip/getLocationMerchantData";
+		            		        $.post(url,params,function(data){
+			               				 if (data.code == 999) {
+			               					var obj=data.data.list;
+			               					var libId=obj[0].id;
+			               					curl=curl.replace("#LIBID#", libId);
+			               					window.location.href=curl;
+			               				 }
+			               			});
+		            		    },
+		            		    cancel: function (res) {
+		            		        $.toast('用户拒绝授权获取地理位置',"cancel");
+		            		        libId='149a7b0b-6bcd-45e0-8e99-845193396759';  //私塾家雅居乐家庭图书馆GZ200
+		            		        curl=curl.replace("#LIBID#", libId);
+		            		        window.location.href=curl;
+		            		    }
+		            		});
+	    			  });
+	             
+                wx.error(function (res) {
+            	    $.toast(res.errMsg,"cancel");
+            	  });
+        		 
+        	 }
+         }
+	   });
+	
+}
+</script>
+</html>

+ 57 - 0
src/main/resources/templates/weixin/vip/serviceBuyOk.html

@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+<title>会员卡购买</title>
+<script th:include="weixin/common/includeJS_CSS" th:remove="tag" ></script>
+
+<style type="text/css">
+	.sfkbox .tiptxt h3 {
+	    margin-bottom: 10px;
+	}
+	
+	.sfkbox .txt{
+		text-align: center;
+    	font-size: 12px;
+	}
+	
+	.sfkbox .txt img{
+		margin: 10px auto;
+	}
+
+
+</style>
+
+
+</head>
+<body>
+		<div class="mui-content">
+			<div class="sfkbox">
+				<div class="panel">
+					<div class="tiptxt">
+						<img th:src="${imgUrl}+'/images/Group 9.png'" />
+						<h3>请扫描二维码</h3>
+						<h3>下载小塾学伴app</h3>
+					</div>
+				</div>
+				<div class="panel panelshodow">
+					<div class="txt" >
+						<p >
+							<img  src="https://www.sharingschool.com/img/hover-icon%20(4).ba432094.png">
+						</p>
+						下载后直接用填写的手机号即可登录
+					</div>
+				</div>
+
+				<div class="panel">
+					<a href="javascript:void(0);" id="save" class="btn-blue">关闭</a>
+				</div>
+			</div>
+		</div>
+	</body>
+<script type="text/javascript">
+$('#save').on('click',function(){
+	WeixinJSBridge.call('closeWindow');
+});
+</script>	
+<script th:include="weixin/vip/vipjssdk" th:remove="tag"></script> 
+</html>	

+ 199 - 0
src/main/resources/templates/weixin/vip/serviceLocation.html

@@ -0,0 +1,199 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+<title>定位校区</title>
+<link href="style/jquery-weui.css" th:href="@{/static/style/jquery-weui.css(version=${#dates.format(#calendars.createNow(),'yyyyMMdd')})}" rel="stylesheet"/>
+<script th:include="weixin/common/includeJS_CSS" th:remove="tag" ></script>
+<link href="style/vipcard.css" th:href="@{/static/style/vipcard.css(version=${#dates.format(#calendars.createNow(),'yyyyMMdd')})}" rel="stylesheet"/>
+</head>
+<body class="bg_f2">
+	<!--内容-->
+	<div class="mui-content">
+		<div class="locationbox" id="locationbox" style="display: none">
+			<div class="Ttitle divdiv"><i class="iconfont">&#xe673;</i>定位地址</div>
+			<div class="panel divdiv">
+				<div class="list" id="locationlist">
+					
+				</div>
+			</div>
+			<div class="Ttitle"><i class="iconfont">&#xe669;</i>附近地址</div>
+			<div class="panel" id="list">
+			</div>
+		</div>
+	</div>
+</body>
+<script id="list_tpl" type="text/html">
+{{# if(d.list!=null && d.list.length > 0){ }}
+{{# for(var i = 0, len = d.list.length; i < len; i++){ }}
+       <div class="list divlist" data-id="{{=d.list[i].id}}">
+					<div class="dc_flex">
+						<div class="dc_hd">{{d.list[i].league_name}}</div>
+                        {{# if (d.list[i].juli !=null && d.list[i].juli !='' ) { }}
+						    <div class="dc_time">{{d.list[i].juli}}km</div>
+                         {{# } }}
+					</div>
+					<div class="addr">地址:{{d.list[i].league_address}}</div>
+	  </div>
+{{# } }}
+{{# } }}
+</script>
+<script id="locationbox_list_tpl" type="text/html">
+{{# if(d.list!=null && d.list.length > 0){ }}
+{{# for(var i = 0, len = d.list.length; i < len; i++){ }}
+    {{# if ( i==0 ) { }}
+       <div class="list divlist" data-id="{{=d.list[i].id}}">
+					<div class="dc_flex">
+						<div class="dc_hd">{{d.list[i].league_name}}</div>
+                        {{# if (d.list[i].juli !=null && d.list[i].juli !='' ) { }}
+						    <div class="dc_time">{{d.list[i].juli}}km</div>
+                         {{# } }}
+					</div>
+					<div class="addr">地址:{{d.list[i].league_address}}</div>
+	  </div>
+	{{# } }}
+{{# } }}
+{{# } }}
+</script>
+<script type="text/javascript">
+	mui("body").on('tap','div.divlist',function(){
+		var id = this.getAttribute('data-id');
+	    var openUrl =  '[[${sysUrl}]]/weixin/payment/serviceVipBuy_'+id+'.html';
+	  	mui.openWindow({
+ 			url:openUrl,
+ 			id: 'vipCard',
+ 		    waiting:{
+ 		      title:'正在加载...'//等待对话框上显示的提示内容
+ 		    }
+ 		}); 
+	}); 
+
+</script>
+<script type="text/javascript">
+$(function(){
+	jssdk();
+});
+function  jssdk(){
+	 $.ajax({
+		 url : "[[${sysUrl}]]/weixin/question/wxjssdk",
+         type : 'post',
+         dataType : 'json',
+         contentType : "application/x-www-form-urlencoded; charset=utf-8",
+         data : {
+             'url' : location.href.split('#')[0]
+         },
+         success : function(data) {
+        	 if(data && data.code == 999){
+             wx.config({
+                 debug : false,
+                 appId : data.data.appId,
+                 timestamp : data.data.timestamp,
+                 nonceStr : data.data.noncestr,
+                 signature : data.data.signature,
+                 jsApiList : [ 
+					        'getLocation',
+					        'openLocation',
+					        'onMenuShareAppMessage',  
+							'onMenuShareTimeline'
+                              ]
+             });
+             var title="私塾家-社区化教育共享平台";
+             var imgUrl='[[${imgUrl}]]/images/sharingschool.jpg';
+             var desc ="为孩子找个好老师-阅读辅导,一站解决,第三空间,伴我成长,家长社群,认知共享,微校结对,家教无忧!";	  
+             var link = "[[${sysUrl}]]/wechat/index.html";
+	             wx.ready(function () {
+	    			 // 2. 分享接口
+	    			    // 2.1 监听“分享给朋友”,按钮点击、自定义分享内容及分享结果接口
+	    			      wx.onMenuShareAppMessage({
+	    			    	    title: title,
+		    			        desc: desc,
+		    			        link:link,
+		    			        imgUrl: imgUrl,
+	    			        
+	    			        trigger: function (res) {
+	    			          // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
+	    			        },
+	    			        success: function (res) {
+	    			        	
+	    			        },
+	    			        cancel: function (res) {
+	    			        	
+	    			        },
+	    			        fail: function (res) {
+	    			          alert(JSON.stringify(res));
+	    			        }
+	    			      });
+	    			      
+
+	    			    // 2.2 监听“分享到朋友圈”按钮点击、自定义分享内容及分享结果接口
+	    			      wx.onMenuShareTimeline({
+	    			    	title: title,
+		    			    link:link,
+		    			    imgUrl: imgUrl,		
+	    			        trigger: function (res) {
+	    			          // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
+	    			        },
+	    			        success: function (res) {
+	    			        	
+	    			        },
+	    			        cancel: function (res) {
+	    			        	
+	    			        },
+	    			        fail: function (res) {
+	    			          $.toast(JSON.stringify(res),"cancel");
+	    			        }
+	    			      });
+	    			    
+	    			    
+	    			      wx.getLocation({
+		            		    type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
+		            		    success: function (res) {
+		            		        var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
+		            		        var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
+		            		        var params ={'league_lat':latitude,'league_lng':longitude,'type': '1' };
+		            		        var url ="[[${sysUrl}]]/weixin/libVip/getLocationMerchantData";
+		            		        $.post(url,params,function(data){
+			               				 if (data.code == 999) {
+			               					var table = document.getElementById("list");
+			               					var locationlist = document.getElementById("locationlist");
+			     					 		var listTpl = document.getElementById("list_tpl").innerHTML;
+			     					 		var locationboxListTpl = document.getElementById("locationbox_list_tpl").innerHTML;
+			               					laytpl(listTpl).render(data.data, function(html){
+			 									table.innerHTML = html;
+			 								});
+			               					laytpl(locationboxListTpl).render(data.data, function(html){
+			               						locationlist.innerHTML = html;
+			 								});
+			               					$('#locationbox').show();
+			               				 }
+			               			});
+		            		    },
+		            		    cancel: function (res) {
+		            		        $.toast('用户拒绝授权获取地理位置',"cancel");
+		            		        var url ="[[${sysUrl}]]/weixin/libVip/getNoLocationMerchantData";
+		            		        var params ={'type': '1' };
+		            		        $.post(url,params,function(data){
+			               				 if (data.code == 999) {
+			               					var table = document.getElementById("list");
+			               					var listTpl = document.getElementById("list_tpl").innerHTML;
+			               					laytpl(listTpl).render(data.data, function(html){
+			 									table.innerHTML = html;
+			 								});
+			               					$('#locationbox').show();
+			               					$('.divdiv').hide();
+			               				 }
+			               			});
+		            		    }
+		            		});
+	    			  });
+	             
+                wx.error(function (res) {
+            	    $.toast(res.errMsg,"cancel");
+            	  });
+        		 
+        	 }
+         }
+	   });
+	
+}
+</script>
+</html>

+ 304 - 0
src/main/resources/templates/weixin/vip/serviceVipBuy.html

@@ -0,0 +1,304 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+<title>小塾学伴会员购买</title>
+<link href="style/jquery-weui.css" th:href="@{/static/style/jquery-weui.css(version=${#dates.format(#calendars.createNow(),'yyyyMMdd')})}" rel="stylesheet"/>
+<script th:include="weixin/common/includeJS_CSS" th:remove="tag" ></script>
+<link href="style/vipcard.css" th:href="@{/static/style/vipcard.css(version=${#dates.format(#calendars.createNow(),'yyyyMMdd')})}" rel="stylesheet"/>
+<script src="js/jquery-weui.js" th:src="@{/static/js/jquery-weui.js}"></script>
+
+<style type="text/css">
+	.lineform input{
+		width: 192px;
+	}
+	.lineform select{
+		width: 192px;
+	}
+</style>
+
+</head>
+<body class="bg_f2">
+	<!--内容-->
+	<div class="mui-content">
+		<div class="vipcard">
+			<a class="dc_flex btnweizhi" th:href="@{/weixin/libVip/serviceLocation.html}">
+				<div><i class="iconfont">&#xe663;</i></div>
+				<div class="dc_hd" th:text="${tbLibJoin.leagueName}"></div>
+				<div><i class="iconfont">&#xe619;</i></div>
+			</a>
+			<div class="panel">
+				<div class="Ttitle">
+					<i>1</i>填写会员信息
+				</div>
+				<div class="lineform">
+					<div class="dc_flex">
+						<div class="type">孩子姓名</div>
+						<div class="dc_hd"><input type="text" name="childName" id="childName" placeholder="请输入小孩姓名"/></div>
+					</div>
+				</div>
+				<div class="lineform">
+					<div class="dc_flex">
+						<div class="type">所读年级</div>
+						<div class="dc_hd" >
+							<select name="grade" id="grade" style="height: 40px;    width: 192px;">
+								<option th:value="${list.name}" th:each="list:${grade}" th:text="${list.name}">学前</option>
+							</select>
+						</div>
+					</div>
+				</div>
+				<div class="lineform">
+					<div class="dc_flex">
+						<div class="type">家长姓名</div>
+						<div class="dc_hd"><input type="text" name="parentName" id="parentName" placeholder="请输入家长姓名"/></div>
+					</div>
+				</div>
+<!-- 				<div class="lineform"> -->
+<!-- 					<div class="dc_flex"> -->
+<!-- 						<div class="type">手机号码</div> -->
+<!-- 						<div class="dc_hd"><input type="tel" name="phone" id="phone" placeholder="请输入家长手机号码"/></div> -->
+<!-- 					</div> -->
+<!-- 				</div> -->
+				<div class="lineform">
+					<div class="dc_flex">
+						<div class="type">家长角色</div>
+						<div class="dc_hd">
+							<select name="parentRole" id="parentRole" style="height: 40px;">
+								<option value="爸爸" text="爸爸">爸爸</option>
+								<option value="妈妈" text="妈妈">妈妈</option>
+								<option value="爷爷" text="爷爷">爷爷</option>
+								<option value="奶奶" text="奶奶">奶奶</option>
+								<option value="外公" text="外公">外公</option>
+								<option value="外婆" text="外婆">外婆</option>
+								<option value="其他" text="其他">其他</option>
+							</select>
+						</div>
+					</div>
+				</div>
+
+				<div class="lineform">
+					<div class="dc_flex">
+						<div class="type">所读学校</div>
+						<div class="dc_hd"><input class="wsinput" type="text" placeholder="请输入所读学校" id="school" name="school" value=""/></div>
+					</div>
+				</div>
+			</div>
+			
+			<div class="panel">
+				<div class="Ttitle">
+					<i>2</i>选择购买月份
+				</div>
+				<div class="dc_flex vip2typeselect " th:each="specie:${specieList}">
+					<div class="dc_hd " th:classappend="${specieStat.first} ? 'active' " th:data-id="${specie.id}" th:data-species="${specie.species}"  th:data-type="${specie.type}" th:data-price="${specie.price}"   th:data-name="${specie.name}" ><i class="icon-vip-xz"></i>[[${specie.name}]]</div>
+					<div class="mui-numbox" data-numbox-min="1" data-numbox-max=""  >
+						<button class="mui-btn mui-btn-numbox-minus" type="button" disabled="">-</button>
+						<input class="mui-input-numbox" type="number" value="1" style="color: #000;">
+						<button class="mui-btn mui-btn-numbox-plus" type="button">+</button>
+					</div>
+				</div>
+
+			</div>
+			<div class="panelbttom">
+				<div class="txt-tiaokuan" id="txt-tiaokuan" >我已阅读并同意该<a >《私塾家小塾学伴会员购买条款》</a></div>
+				
+				<a href="javascript:save();" id="save"  style="margin: 0px;" class="btn-blue">支付</a>
+			</div>
+			<div class="js_dialog" id="iosDialog1">
+	            <div class="dc-mask"></div>
+	            <div class="dc-dialog dc-dialog_gmxy">
+	            	<div class="Top_close"><a href="javascript:;"></a></div>
+	            	<div class="txtbox">
+	            	<div class="title">用户服务协议</div>
+                <div class="txt" th:if="${tbLibJoin.libtype  eq 1}">
+                
+					<p>一、外借书及阅读指导会员卡使用须知</p >
+					<p>1、会员卡仅限会员本人使用,不得外借(父母可凭会员卡陪读及代办图书外借);</p >
+					<p>2、凭卡可到私塾家家庭图书馆外借图书,并可预约到馆阅读,但不承诺有位(具体规则参看《私塾家家庭图书馆馆内阅读与图书外借制度》);</p >
+					<p>3、本卡使用有效期由系统根据会员卡类别进行设定,在系统设定有效期范围内使用有效;</p >
+					<p>4、图书借阅期限为20天,逾期不还将不能再借新书,同时馆方保留收取滞纳金的权利;</p >
+					<p>5、如图书遭借阅者折叠、涂画、破损或丢失,借阅者须购置新书或按原价赔偿给本馆;</p >
+					<p>6、如不慎遗失本卡,补办新卡须交工本费10元;</p >
+					<p>7、会员卡一经办理,不能退费;</p >
+					<p>8、本须知最终解释权归私塾家家庭图书馆所有。</p >
+					<br>
+					<p>二、学习导师陪护式同伴督导VIP专席卡使用须知</p >
+					<p>1. 为提高学习效率,同伴作业督导VIP专席卡最小计时单位是2小时(周一至周五);</p >
+					<p>2. 每次预约均不少于10次,且每周平均不少于5次</p >
+					<p>3. 专席专段专属,预约但未实到不予补段;</p >
+					<p>4. 鼓励同伴学习、互助共进,鼓励家长到馆,共同陪护;</p >
+					<p>5. 配备学习导师管理学生作业,但不提供巩固提升辅导;</p >
+					<p>6. VIP专席卡一经办理,不能退费且使用有效期不超过1年;</p >
+					<p>7. 本须知最终解释权归私塾家家庭图书馆所有。</p >
+					<br>
+					               </div>
+					               <div class="txt" th:if="${tbLibJoin.libtype  ne 1}">
+					<p>一、外借书及阅读指导会员卡使用须知</p >
+					<p>1、会员卡仅限会员本人使用,不得外借(父母可凭会员卡陪读及代办图书外借);</p >
+					<p>2、凭卡可到私塾家共享图书馆外借图书,但不承诺到馆阅读有位;</p >
+					<p>3、本卡使用有效期由系统根据会员卡类别进行设定,在系统设定有效期范围内使用有效;</p >
+					<p>4、图书借阅期限为7天,每次最多可借阅2本,逾期不还将不能再借新书,同时馆方保留收取滞纳金的权利;</p >
+					<p>5、如图书遭借阅者折叠、涂画、破损或丢失,借阅者须购置新书或按原价赔偿给本馆;</p >
+					<p>6、本卡一经办理不予退费,如有遗失,请告知馆内老师进行补办;</p >
+					<p>7、本须知最终解释权归私塾家共享图书馆所有。</p >
+					<br>
+					<p>二、学习导师陪护式同伴督导VIP专席卡使用须知</p >
+					<p>1. 为提高学习效率,同伴作业督导VIP专席卡最小计时单位是2小时(周一至周五);</p >
+					<p>2. 每次预约均不少于10次,且每周平均不少于5次</p >
+					<p>3. 专席专段专属,预约但未实到不予补段;</p >
+					<p>4. 鼓励同伴学习、互助共进,鼓励家长到馆,共同陪护;</p >
+					<p>5. 配备学习导师管理学生作业,但不提供巩固提升辅导;</p >
+					<p>6. VIP专席卡一经办理,不能退费且使用有效期不超过1年;</p >
+					<p>7. 本须知最终解释权归私塾家家庭图书馆所有。</p >
+					<br>
+
+               </div>
+	            	</div>
+	            </div>
+	        </div>
+		</div>
+	</div>
+    <script type="text/javascript">
+		
+		mui("div.panel").on('tap','.vip2typeselect .dc_hd',function(){
+			$(this).addClass('active').siblings().removeClass('active');
+			$('.viptypeshow .list').removeClass('active');
+			var code = this.getAttribute('data-code');
+			$('.viptypeshow').find('.list , .otherbox').css('display','none');
+			$('.viptypeshow').find("."+code).css('display','block');
+			$('.viptypeshow').find("."+code).eq(0).css('margin-top','0px');
+			$('.viptypeshow').find("."+code).eq(0).addClass('active');
+			
+		});
+		mui("div.viptypeshow").on('tap','.list',function(){
+			$(this).addClass('active').siblings().removeClass('active');
+	   });
+		mui('.mui-content').on('tap','#save',function(){document.location.href=this.href;});
+		mui('.mui-content').on('tap','.btnweizhi',function(){document.location.href=this.href;});
+		
+		mui("div.panelbttom").on('tap','.txt-tiaokuan',function(){
+			$(this).toggleClass('active');
+		});
+		mui("div.panelbttom").on('tap','.txt-tiaokuan a',function(){
+			$('.js_dialog').show('fast');
+		});
+		mui("body").on('tap','.dc-mask, .Top_close',function(){
+			$('.js_dialog').hide('fast');
+		});
+		
+		function save(){
+			var b = $("#txt-tiaokuan").hasClass("active");
+			if(!b){
+				 $.toast("请勾选同意购卡条款","cancel");
+				 return false;
+			}
+			
+			var type =$('div.vip2typeselect').find('.active').data('type');
+			if(type == undefined || type ==''){
+				 $.toast("请选择购买类型","cancel");
+				 return false;
+			}
+			
+			var number =$('div.vip2typeselect').find('.active').parent().find('.mui-input-numbox').val();
+			if(number == undefined || number =='' || number<=0){
+				 $.toast("请选择购买月份","cancel");
+				 return false;
+			}
+			
+			var childName = $('#childName').val();
+			if(childName == undefined || childName ==''){
+				 $.toast("请填写孩子姓名","cancel");
+				 return false;
+			}
+			
+			var grade = $('#grade').val();
+			if(grade == undefined || grade ==''){
+				 $.toast("请选择所读年级","cancel");
+				 return false;
+			}
+			
+			var parentName = $('#parentName').val();
+			if(parentName == undefined || parentName ==''){
+				 $.toast("请输入家长姓名","cancel");
+				 return false;
+			}
+			
+			var phone = $('#phone').val();
+			if(phone == undefined || phone ==''){
+				 $.toast("请输入手机号码","cancel");
+				 return false;
+			}
+			
+			var parentRole = $('#parentRole').val();
+			if(parentRole == undefined || parentRole ==''){
+				 $.toast("请选择家长角色","cancel");
+				 return false;
+			}
+			
+			var school = $('#school').val();
+			if(school == undefined || school ==''){
+				 $.toast("请输入所读学校","cancel");
+				 return false;
+			}
+			
+			var know = '家长小塾学伴缴费';
+			var details="小塾学伴月费";
+			var price =$('div.vip2typeselect').find('.active').data('price');
+			var salesPriceId =$('div.vip2typeselect').find('.active').data('id');
+		   
+		   	$('#save').attr('href','javascript:void(0);');
+		   	$.ajax({
+				 url :  "[[${sysUrl}]]/weixin/payment/payService", 
+		         type : 'post',
+		         data : {
+		        	 'salesPriceId':salesPriceId,//购买类型id
+		        	 'number':number,//数量
+       				 'libId' :'[[${libId}]]',
+       				 'know' : know,
+       				 'details' : details,
+       				 
+       				 'childName' : childName,
+       				 'grade' : grade,
+       				 'parentName' : parentName,
+       				 'phone' : phone,
+       				 'parentRole' : parentRole,
+       				 'school' : school,
+       				 
+       				 'isBuy':1,
+       				 'vipStatus':1
+		         },
+				dataType: 'json',
+				success: function(data){
+					 if(data && data.code == 999){
+						 var payInfo = eval(data.data); //数组  
+							var orderNo=payInfo.orderNo;
+							        WeixinJSBridge.invoke('getBrandWCPayRequest',{  
+					                "appId" : payInfo.appId,                  //公众号名称,由商户传入  
+					                "timeStamp": payInfo.timeStamp,          //时间戳,自 1970 年以来的秒数  
+					                "nonceStr" : payInfo.nonceStr,         //随机串  
+					                "package" : payInfo.packageValue,      //商品包信息
+					                "signType" : payInfo.signType,        //微信签名方式'MD5'
+					                "paySign" : payInfo.paySign           //微信签名  
+					                },function(res){       
+					                	if(res.err_msg == "get_brand_wcpay_request:ok" ) {   
+					                		var jumpUrl ='[[${sysUrl}]]/weixin/libOrder/serviceBuyOk_'+orderNo+'.html';
+							    	    	location.replace(jumpUrl);
+										    event.returnValue=false;
+				               			    return false;
+						               		
+					                  	}else{  
+					                		 $('#save').attr('href','javascript:save();');
+					                    }  		
+					            });     
+			    	}else{
+			    		 $.toast("数据加载失败,请稍后再试!","cancel");
+			    		 $('#save').attr('href','javascript:save();');
+			    	}  
+				},
+				error: function(XMLHttpRequest,textStatus,errorThrown) {
+		            $.toast("网络或系统故障,请稍后再试!","cancel");
+		        }
+			});
+		}	
+</script>
+<script th:include="weixin/vip/vipjssdk" th:remove="tag"></script> 
+</body>
+</html>