浏览代码

Merge branch 'mfyx_2.0' of http://8.136.199.33:3000/hongze/hongze_cygx

xingzai 10 月之前
父节点
当前提交
4f5056f0b2

+ 1 - 0
go.mod

@@ -17,6 +17,7 @@ require (
 	github.com/rdlucklib/rdluck_tools v1.0.3
 	github.com/satori/go.uuid v1.2.0 // indirect
 	github.com/tealeg/xlsx v1.0.5
+	github.com/wechatpay-apiv3/wechatpay-go v0.2.18 // indirect
 	golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
 	golang.org/x/sys v0.6.0 // indirect
 	golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect

+ 10 - 0
go.sum

@@ -9,6 +9,7 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
+github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@@ -390,6 +391,8 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3
 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -397,6 +400,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
 github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
 github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
@@ -405,6 +411,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1
 github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/wechatpay-apiv3/wechatpay-go v0.2.18 h1:vj5tvSmnEIz3ZsnFNNUzg+3Z46xgNMJbrO4aD4wP15w=
+github.com/wechatpay-apiv3/wechatpay-go v0.2.18/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q=
 github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/ylywyn/jpush-api-go-client v0.0.0-20190906031852-8c4466c6e369/go.mod h1:Nv7wKD2/bCdKUFNKcJRa99a+1+aSLlCRJFriFYdjz/I=
@@ -634,6 +642,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

+ 16 - 0
models/db.go

@@ -2,6 +2,7 @@ package models
 
 import (
 	_ "github.com/go-sql-driver/mysql"
+	"hongze/hongze_cygx/models/order"
 	"hongze/hongze_cygx/utils"
 	"time"
 
@@ -190,8 +191,23 @@ func init() {
 		new(CygxTimelineLog),
 		new(CygxActivitySpecialPermissionPoints),
 	)
+
+	initOrder() // 订单模块
+
 	// 记录ORM查询日志
 	orm.Debug = true
 	orm.DebugLog = orm.NewLog(utils.BinLog)
 
 }
+
+// initOrder 买方研选订单模块
+func initOrder() {
+	orm.RegisterModel(
+		new(order.CygxOrder),             //订单表
+		new(order.CygxOrderAction),       //订单操表
+		new(order.CygxOrderUserCard),     //用户持卡表
+		new(order.CygxOrderUserCardLog),  //用户持卡日志表
+		new(order.CygxOrderPayment),      //支付记录表
+		new(order.CygxOrderVirtualAsset), //用户虚拟资产表(所购买的单篇报告,活动等)
+	)
+}

+ 188 - 0
models/order/order.go

@@ -0,0 +1,188 @@
+package order
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxOrderResp struct {
+	OrderId          int       `orm:"column(order_id);pk";comment:"订单id"`
+	OrderCode        string    `comment:"订单编号"`
+	OutTradeCode     string    `comment:"外部交易号"`
+	PaymentType      int       `comment:"支付类型。取值范围:1微信支付,2支付宝支付。"`
+	GoodsName        string    `comment:"商品名称"`
+	GoodsId          int       `comment:"商品ID"`
+	BuyerInvoice     string    `comment:"买家发票信息"`
+	GoodsMoney       float64   `comment:"商品总价"`
+	OrderMoney       float64   `comment:"订单总价"`
+	Point            int       `comment:"订单消耗积分"`
+	PointMoney       float64   `comment:"订单消耗积分抵多少钱"`
+	PayMoney         float64   `comment:"订单实付金额"`
+	RefundMoney      float64   `comment:"订单退款金额"`
+	OrderStatus      int       `comment:"订单状态,0:已取消、1:待支付、2:已支付、3:已退款"`
+	PayTime          time.Time `comment:"订单付款时间"`
+	SourceId         int       `comment:"来源ID"`
+	Source           string    `comment:"来源\n报告 :article\n活动 :activity"`
+	SourceTitle      string    `comment:"来源名称,活动或者报告标题"`
+	UserId           int       `comment:"用户ID"`
+	Mobile           string    `comment:"手机号"`
+	Email            string    `comment:"邮箱"`
+	CompanyId        int       `comment:"公司ID"`
+	CompanyName      string    `comment:"公司名称"`
+	RealName         string    `comment:"用户实际名称"`
+	SellerName       string    `comment:"所属销售"`
+	CreateTime       time.Time `comment:"创建时间"`
+	ModifyTime       time.Time `comment:"修改时间"`
+	RegisterPlatform int       `comment:"来源 1小程序,2:网页"`
+	StartDate        time.Time `comment:"开始时间"`
+	EndDate          time.Time `comment:"结束时间"`
+}
+
+// 订单表
+type CygxOrder struct {
+	OrderId          int       `orm:"column(order_id);pk";comment:"订单id"`
+	OrderCode        string    `comment:"订单编号"`
+	OutTradeNo       string    `comment:"【商户订单号】 商户系统内部订单号"`
+	OutTradeCode     string    `comment:"外部交易号"`
+	PaymentType      int       `comment:"支付类型。取值范围:1微信支付,2支付宝支付。"`
+	TradeType        string    `comment:"交易类型,枚举值:JSAPI:公众号支付 、 NATIVE:扫码支付 、 App:App支付 、 MICROPAY:付款码支付 、 MWEB:H5支付 、 FACEPAY:刷脸支付"`
+	GoodsName        string    `comment:"商品名称"`
+	GoodsId          int       `comment:"商品ID"`
+	BuyerInvoice     string    `comment:"买家发票信息"`
+	GoodsMoney       float64   `comment:"商品总价"`
+	OrderMoney       float64   `comment:"订单总价"`
+	Point            int       `comment:"订单消耗积分"`
+	PointMoney       float64   `comment:"订单消耗积分抵多少钱"`
+	PayMoney         float64   `comment:"订单实付金额"`
+	RefundTime       time.Time `comment:"订单退款时间"`
+	RefundMoney      float64   `comment:"订单退款金额"`
+	OrderStatus      int       `comment:"订单状态,0:已取消、1:待支付、2:已支付、3:已退款"`
+	PayTime          time.Time `comment:"订单付款时间"`
+	SourceId         int       `comment:"来源ID"`
+	Source           string    `comment:"来源\n报告 :article\n活动 :activity"`
+	SourceTitle      string    `comment:"来源名称,活动或者报告标题"`
+	UserId           int       `comment:"用户ID"`
+	Mobile           string    `comment:"手机号"`
+	Email            string    `comment:"邮箱"`
+	CompanyId        int       `comment:"公司ID"`
+	CompanyName      string    `comment:"公司名称"`
+	RealName         string    `comment:"用户实际名称"`
+	SellerName       string    `comment:"所属销售"`
+	SellerId         int       `comment:"所属销售Id"`
+	CreateTime       time.Time `comment:"创建时间"`
+	ModifyTime       time.Time `comment:"修改时间"`
+	RegisterPlatform int       `comment:"来源 1小程序,2:网页"`
+	OrderType        int       `comment:"订单类型,1:畅读卡订单,2:单场付费订单"`
+	StartDate        time.Time `comment:"开始时间"`
+	EndDate          time.Time `comment:"结束时间"`
+}
+
+// 订单操作表
+type CygxOrderAction struct {
+	ActionId         int64     `orm:"column(action_id);pk"` // 动作id
+	Action           string    // 动作内容
+	OrderStatus      int       // 订单状态,0:已取消、1:待支付、2:已支付、3:已退款
+	OrderStatusText  string    // 订单状态名称
+	OrderCode        string    // 订单编号
+	UserId           int       // 用户ID
+	Mobile           string    // 手机号
+	Email            string    // 邮箱
+	CompanyId        int       // 公司ID
+	CompanyName      string    // 公司名称
+	RealName         string    // 用户实际名称
+	SellerName       string    // 所属销售
+	CreateTime       time.Time // 创建时间
+	ModifyTime       time.Time // 修改时间
+	RegisterPlatform int       // 来源 1小程序,2:网页
+	AdminId          int       // 管理员ID
+	AdminName        string    // 管理员姓名
+}
+
+func GetCygxOrderList(condition string, pars []interface{}, startSize, pageSize int) (items []*CygxOrder, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *
+			FROM
+			cygx_order
+			WHERE 1 = 1 ` + condition
+	sql += ` LIMIT ?,?  `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+func GetCygxOrderDetailList(condition string, pars []interface{}) (items []*CygxOrder, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT *
+			FROM
+			cygx_order
+			WHERE 1 = 1 ` + condition
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// 自动取消订单
+func CancelCygxOrder(item *CygxOrder) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+	itemOrderAction := new(CygxOrderAction)
+	itemOrderAction.Action = "超时自动取消订单"
+	itemOrderAction.OrderStatus = 0
+	itemOrderAction.OrderStatusText = "已取消"
+	itemOrderAction.OrderCode = item.OrderCode
+	itemOrderAction.UserId = item.UserId
+	itemOrderAction.Mobile = item.Mobile
+	itemOrderAction.Email = item.Email
+	itemOrderAction.CompanyId = item.CompanyId
+	itemOrderAction.CompanyName = item.CompanyName
+	itemOrderAction.RealName = item.RealName
+	itemOrderAction.SellerName = item.SellerName
+	itemOrderAction.CreateTime = time.Now()
+	itemOrderAction.ModifyTime = time.Now()
+	itemOrderAction.RegisterPlatform = item.RegisterPlatform
+
+	_, err = o.Insert(itemOrderAction) // 写入订单操作信息
+	if err != nil {
+		return
+	}
+
+	updateParams := make(map[string]interface{})
+	updateParams["OrderStatus"] = 0
+	updateParams["ModifyTime"] = item.ModifyTime
+	ptrStructOrTableName := "cygx_order"
+	whereParam := map[string]interface{}{"order_code": item.OrderCode}
+	qs := o.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range whereParam {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err = qs.Update(updateParams)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// 根据订单编号获取订单详情
+func GetCygxOrderDetailByOrderCode(orderCode string) (item *CygxOrder, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_order WHERE order_code = ? `
+	err = o.Raw(sql, orderCode).QueryRow(&item)
+	return
+}
+
+// 根据订单编号获取订单详情
+func GetCygxOrderDetailByOutTradeNo(outTradeNo string) (item *CygxOrder, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_order WHERE out_trade_no = ? `
+	err = o.Raw(sql, outTradeNo).QueryRow(&item)
+	return
+}

+ 25 - 0
models/order/order_payment.go

@@ -0,0 +1,25 @@
+package order
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxOrderPayment struct {
+	OrderPaymentID int       `orm:"column(order_payment_id);pk";comment:"订单支付ID"`
+	OrderCode      string    `comment:"订单编号"`
+	OutTradeCode   string    `comment:"外部交易号退款使用"`
+	PayBody        string    `comment:"订单支付简介"`
+	PayDetail      string    `comment:"订单支付详情"`
+	PayMoney       float64   `comment:"支付金额"`
+	PayStatus      string    `comment:"支付状态"`
+	CreateTime     time.Time `comment:"创建时间"`
+	PaymentType    int       `comment:"支付类型。取值范围:1微信支付,2支付宝支付。"`
+}
+
+// 添加
+func AddCygxOrderPayment(item *CygxOrderPayment) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item) //回调支付信息
+	return
+}

+ 258 - 0
models/order/order_user_card.go

@@ -0,0 +1,258 @@
+package order
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// 用户持卡表 CygxOrderUserCard 结构体对应 cygx_order_user_card 数据表
+type CygxOrderUserCard struct {
+	UserCardId       int       `orm:"column(user_card_id);pk";comment:"订单id"`
+	OrderCode        string    `comment:"订单编号"`
+	UserId           int       `comment:"用户ID"`
+	Mobile           string    `comment:"手机号"`
+	Email            string    `comment:"邮箱"`
+	CompanyId        int       `comment:"公司ID"`
+	CompanyName      string    `comment:"公司名称"`
+	RealName         string    `comment:"用户实际名称"`
+	SellerName       string    `comment:"所属销售"`
+	CreateTime       time.Time `comment:"创建时间"`
+	ModifyTime       time.Time `comment:"修改时间"`
+	RegisterPlatform int       `comment:"来源"`
+	CardType         string    `comment:"会员卡类型"`
+	StartDate        time.Time `comment:"开始时间"`
+	EndDate          time.Time `comment:"结束时间"`
+	IsSuspend        int       `comment:"是否暂停"`
+}
+
+// 用户持卡日志表 CygxOrderUserCardLog 结构体对应 cygx_order_user_card_log 数据表
+type CygxOrderUserCardLog struct {
+	UserCardId       int       `orm:"column(user_card_log_id);pk";comment:"订单id"`
+	OrderCode        string    `comment:"订单编号"`
+	UserId           int       `comment:"用户ID"`
+	Mobile           string    `comment:"手机号"`
+	Email            string    `comment:"邮箱"`
+	CompanyId        int       `comment:"公司ID"`
+	CompanyName      string    `comment:"公司名称"`
+	RealName         string    `comment:"用户实际名称"`
+	SellerName       string    `comment:"所属销售"`
+	CreateTime       time.Time `comment:"创建时间"`
+	ModifyTime       time.Time `comment:"修改时间"`
+	RegisterPlatform int       `comment:"来源"`
+	CardType         string    `comment:"会员卡类型"`
+	StartDate        time.Time `comment:"开始时间"`
+	EndDate          time.Time `comment:"结束时间"`
+	IsSuspend        int       `comment:"是否暂停"`
+}
+
+// 添加
+func AddCygxOrderUserCard(item *CygxOrderUserCard, itemOrder *CygxOrder) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+
+	itemOrderAction := new(CygxOrderAction)
+
+	switch itemOrder.TradeType {
+	case "JSAPI":
+		itemOrderAction.Action = "公众号支付"
+	case "NATIVE":
+		itemOrderAction.Action = "扫码支付"
+	case "App":
+		itemOrderAction.Action = "App支付"
+	case "MICROPAY":
+		itemOrderAction.Action = "付款码支付"
+	case "MWEB":
+		itemOrderAction.Action = "H5支付"
+	case "FACEPAY":
+		itemOrderAction.Action = "刷脸支付"
+	}
+	itemOrderAction.OrderStatus = 2
+	itemOrderAction.OrderStatusText = "已支付"
+	itemOrderAction.OrderCode = item.OrderCode
+	itemOrderAction.UserId = item.UserId
+	itemOrderAction.Mobile = item.Mobile
+	itemOrderAction.Email = item.Email
+	itemOrderAction.CompanyId = item.CompanyId
+	itemOrderAction.CompanyName = item.CompanyName
+	itemOrderAction.RealName = item.RealName
+	itemOrderAction.SellerName = item.SellerName
+	itemOrderAction.CreateTime = time.Now()
+	itemOrderAction.ModifyTime = time.Now()
+	itemOrderAction.RegisterPlatform = item.RegisterPlatform
+
+	updateParams := make(map[string]interface{})
+	updateParams["PayTime"] = itemOrder.PayTime
+	updateParams["PayMoney"] = itemOrder.PayMoney
+	updateParams["OrderStatus"] = itemOrder.OrderStatus
+	updateParams["OutTradeCode"] = itemOrder.OutTradeCode
+	updateParams["ModifyTime"] = item.ModifyTime
+	updateParams["StartDate"] = item.StartDate
+	updateParams["EndDate"] = item.EndDate
+	updateParams["PaymentType"] = 1
+	updateParams["TradeType"] = itemOrder.TradeType
+	ptrStructOrTableName := "cygx_order"
+	whereParam := map[string]interface{}{"order_code": itemOrder.OrderCode}
+	qs := o.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range whereParam {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err = qs.Update(updateParams) // 修改订单状态
+	if err != nil {
+		return
+	}
+
+	_, err = o.Insert(itemOrderAction) // 写入订单操作信息
+	if err != nil {
+		return
+	}
+
+	sql := ` DELETE FROM cygx_order_user_card  WHERE mobile=? ` // 删除原有的持卡信息
+	_, err = o.Raw(sql, item.Mobile).Exec()
+	if err != nil {
+		return
+	}
+
+	itemLog := new(CygxOrderUserCardLog)
+	itemLog.OrderCode = item.OrderCode
+	itemLog.UserId = item.UserId
+	itemLog.Mobile = item.Mobile
+	itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.RealName = item.RealName
+	itemLog.SellerName = item.SellerName
+	itemLog.CreateTime = time.Now()
+	itemLog.ModifyTime = time.Now()
+	itemLog.RegisterPlatform = item.RegisterPlatform
+	itemLog.CardType = item.CardType
+	itemLog.StartDate = item.StartDate
+	itemLog.EndDate = item.EndDate
+	itemLog.IsSuspend = item.IsSuspend
+
+	_, err = o.Insert(item) //写入用户持卡表
+	if err != nil {
+		return
+	}
+
+	_, err = o.Insert(itemLog) // 写入用户持卡日志表
+	if err != nil {
+		return
+	}
+	return
+}
+
+// 根据订单编号获取用户持卡详情
+func GetCygxOrderUserCardDetailByOrderCode(orderCode string) (item *CygxOrderUserCard, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_order_user_card WHERE order_code = ? `
+	err = o.Raw(sql, orderCode).QueryRow(&item)
+	return
+}
+
+// 根据手机号获取用户持卡详情
+func GetCygxOrderUserCardDetailByMobile(mobile string) (item *CygxOrderUserCard, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM cygx_order_user_card WHERE mobile = ? `
+	err = o.Raw(sql, mobile).QueryRow(&item)
+	return
+}
+
+// 获取数量
+func GetCygxOrderUserCardCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := ` SELECT COUNT(1) AS  count  FROM cygx_order_user_card WHERE   1= 1  ` + condition
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 删除
+func RemoveCygxOrderUserCard(item *CygxOrderUserCard, itemOrder *CygxOrder) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+
+	itemOrderAction := new(CygxOrderAction)
+
+	itemOrderAction.Action = "退款成功"
+	itemOrderAction.OrderStatus = 3
+	itemOrderAction.OrderStatusText = "已退款"
+	itemOrderAction.OrderCode = item.OrderCode
+	itemOrderAction.UserId = item.UserId
+	itemOrderAction.Mobile = item.Mobile
+	itemOrderAction.Email = item.Email
+	itemOrderAction.CompanyId = item.CompanyId
+	itemOrderAction.CompanyName = item.CompanyName
+	itemOrderAction.RealName = item.RealName
+	itemOrderAction.SellerName = item.SellerName
+	itemOrderAction.CreateTime = time.Now()
+	itemOrderAction.ModifyTime = time.Now()
+	itemOrderAction.RegisterPlatform = item.RegisterPlatform
+
+	updateParams := make(map[string]interface{})
+	updateParams["OrderStatus"] = itemOrder.OrderStatus
+	updateParams["ModifyTime"] = item.ModifyTime
+	ptrStructOrTableName := "cygx_order"
+	whereParam := map[string]interface{}{"order_code": itemOrder.OrderCode}
+	qs := o.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range whereParam {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err = qs.Update(updateParams) // 修改订单状态
+	if err != nil {
+		return
+	}
+
+	_, err = o.Insert(itemOrderAction) // 写入订单操作信息
+	if err != nil {
+		return
+	}
+
+	//sql := ` DELETE FROM cygx_order_user_card  WHERE mobile=? ` // 删除原有的持卡信息 (退款之后不删除相关权益权限)
+	//_, err = o.Raw(sql, item.Mobile).Exec()
+	//if err != nil {
+	//	return
+	//}
+
+	itemLog := new(CygxOrderUserCardLog)
+	itemLog.OrderCode = item.OrderCode
+	itemLog.UserId = item.UserId
+	itemLog.Mobile = item.Mobile
+	itemLog.Email = item.Email
+	itemLog.CompanyId = item.CompanyId
+	itemLog.CompanyName = item.CompanyName
+	itemLog.RealName = item.RealName
+	itemLog.SellerName = item.SellerName
+	itemLog.CreateTime = time.Now()
+	itemLog.ModifyTime = time.Now()
+	itemLog.RegisterPlatform = item.RegisterPlatform
+	itemLog.CardType = item.CardType
+	itemLog.StartDate = item.StartDate
+	itemLog.EndDate = item.EndDate
+	itemLog.IsSuspend = 1
+
+	_, err = o.Insert(itemLog) // 写入用户持卡日志表
+	if err != nil {
+		return
+	}
+	return
+}

+ 171 - 0
models/order/order_virtual_asset.go

@@ -0,0 +1,171 @@
+package order
+
+//用户虚拟资产表
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_cygx/utils"
+	"time"
+)
+
+type CygxOrderVirtualAsset struct {
+	OrderVirtualAssetsId int       `orm:"column(order_virtual_assets_id);pk";comment:"订单支付ID"`
+	OrderCode            string    `comment:"订单编号"`
+	UserId               int       `comment:"用户ID"`
+	Mobile               string    `comment:"手机号"`
+	Email                string    `comment:"邮箱"`
+	CompanyId            int       `comment:"公司ID"`
+	CompanyName          string    `comment:"公司名称"`
+	RealName             string    `comment:"用户实际名称"`
+	SellerName           string    `comment:"所属销售"`
+	CreateTime           time.Time `comment:"创建时间"`
+	ModifyTime           time.Time `comment:"修改时间"`
+	SourceId             int       `comment:"来源ID"`
+	Source               string    `comment:"来源\n报告 :article\n活动 :activity"`
+}
+
+// 添加
+func AddCygxOrderVirtualAsset(item *CygxOrderVirtualAsset, itemOrder *CygxOrder) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+
+	itemOrderAction := new(CygxOrderAction)
+
+	switch itemOrder.TradeType {
+	case "JSAPI":
+		itemOrderAction.Action = "公众号支付"
+	case "NATIVE":
+		itemOrderAction.Action = "扫码支付"
+	case "App":
+		itemOrderAction.Action = "App支付"
+	case "MICROPAY":
+		itemOrderAction.Action = "付款码支付"
+	case "MWEB":
+		itemOrderAction.Action = "H5支付"
+	case "FACEPAY":
+		itemOrderAction.Action = "刷脸支付"
+	}
+	itemOrderAction.OrderStatus = 2
+	itemOrderAction.OrderStatusText = "已支付"
+	itemOrderAction.OrderCode = item.OrderCode
+	itemOrderAction.UserId = item.UserId
+	itemOrderAction.Mobile = item.Mobile
+	itemOrderAction.Email = item.Email
+	itemOrderAction.CompanyId = item.CompanyId
+	itemOrderAction.CompanyName = item.CompanyName
+	itemOrderAction.RealName = item.RealName
+	itemOrderAction.SellerName = item.SellerName
+	itemOrderAction.CreateTime = time.Now()
+	itemOrderAction.ModifyTime = time.Now()
+	itemOrderAction.RegisterPlatform = utils.REGISTER_PLATFORM
+
+	updateParams := make(map[string]interface{})
+	updateParams["PayTime"] = itemOrder.PayTime
+	updateParams["PayMoney"] = itemOrder.PayMoney
+	updateParams["OrderStatus"] = itemOrder.OrderStatus
+	updateParams["OutTradeCode"] = itemOrder.OutTradeCode
+	updateParams["ModifyTime"] = item.ModifyTime
+	updateParams["PaymentType"] = 1
+	updateParams["TradeType"] = itemOrder.TradeType
+	ptrStructOrTableName := "cygx_order"
+	whereParam := map[string]interface{}{"order_code": itemOrder.OrderCode}
+	qs := o.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range whereParam {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err = qs.Update(updateParams) // 修改订单状态
+	if err != nil {
+		return
+	}
+
+	_, err = o.Insert(itemOrderAction) // 写入订单操作信息
+	if err != nil {
+		return
+	}
+
+	_, err = o.Insert(item) //写入用户用户虚拟资产表
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// 获取数量
+func GetCygxOrderVirtualAssetdCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sqlCount := ` SELECT COUNT(1) AS  count  FROM cygx_order_virtual_asset WHERE   1= 1  ` + condition
+	err = o.Raw(sqlCount, pars).QueryRow(&count)
+	return
+}
+
+// 移除用户活动权限记录
+func RemoveCygxOrderVirtualAsset(item *CygxOrderVirtualAsset, itemOrder *CygxOrder) (err error) {
+	o, err := orm.NewOrm().Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		fmt.Println(err)
+		if err == nil {
+			o.Commit()
+		} else {
+			o.Rollback()
+		}
+	}()
+
+	itemOrderAction := new(CygxOrderAction)
+
+	itemOrderAction.Action = "退款成功"
+	itemOrderAction.OrderStatus = 3
+	itemOrderAction.OrderStatusText = "已退款"
+	itemOrderAction.OrderCode = item.OrderCode
+	itemOrderAction.UserId = item.UserId
+	itemOrderAction.Mobile = item.Mobile
+	itemOrderAction.Email = item.Email
+	itemOrderAction.CompanyId = item.CompanyId
+	itemOrderAction.CompanyName = item.CompanyName
+	itemOrderAction.RealName = item.RealName
+	itemOrderAction.SellerName = item.SellerName
+	itemOrderAction.CreateTime = time.Now()
+	itemOrderAction.ModifyTime = time.Now()
+	itemOrderAction.RegisterPlatform = utils.REGISTER_PLATFORM
+
+	updateParams := make(map[string]interface{})
+	updateParams["OrderStatus"] = itemOrder.OrderStatus
+	updateParams["ModifyTime"] = item.ModifyTime
+	ptrStructOrTableName := "cygx_order"
+	whereParam := map[string]interface{}{"order_code": itemOrder.OrderCode}
+	qs := o.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range whereParam {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err = qs.Update(updateParams) // 修改订单状态
+	if err != nil {
+		return
+	}
+
+	_, err = o.Insert(itemOrderAction) // 写入订单操作信息
+	if err != nil {
+		return
+	}
+
+	//sql := ` DELETE FROM cygx_order_virtual_asset  WHERE order_code =? ` // 删除原有的持卡信息  (退款之后不删除相关权益权限)
+	//_, err = o.Raw(sql, item.OrderCode).Exec()
+	//if err != nil {
+	//	return
+	//}
+
+	return
+}

+ 42 - 0
models/order/user_business_card.go

@@ -0,0 +1,42 @@
+package order
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+	//"time"
+)
+
+type CygxUserBusinessCard struct {
+	Id               int    `orm:"column(id);pk"`
+	BusinessCardUrl  string `description:"名片地址"`
+	UserId           int    `description:"用户ID"`
+	RealName         string `description:"用户实际名称"`
+	Mobile           string `description:"手机号"`
+	CompanyName      string `description:"公司名称"`
+	CreateTime       time.Time
+	ModifyTime       time.Time `description:"修改时间"`
+	RegisterPlatform int       `description:"来源"`
+	InviteName       string    `description:"邀请人"`
+}
+
+type CygxUserBusinessCardReq struct {
+	BusinessCardUrl string `description:"名片地址"`
+	RealName        string `description:"用户实际名称"`
+	Mobile          string `description:"手机号"`
+	CompanyName     string `description:"公司名称"`
+	InviteName      string `description:"邀请人"`
+}
+
+func GetCygxUserBusinessCardCount(userId int) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) AS count FROM cygx_user_business_card WHERE user_id=?  `
+	err = o.Raw(sql, userId).QueryRow(&count)
+	return
+}
+
+// 新增
+func AddCygxUserBusinessCard(item *CygxUserBusinessCard) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}

+ 9 - 0
services/activity_points.go

@@ -195,6 +195,11 @@ func YanXuanActivityPointsBillSignupAddReduce(log models.YanXuanActivityPointsRe
 	activityId := log.ActivityId
 	userId := log.UserId
 
+	activtyPayTotal := GetCygxOrderVirtualAssetdCountTotal(userId, activityId) // 单场付费活动不处理扣点明细
+	if activtyPayTotal > 0 {
+		return
+	}
+
 	//获取活动是否扣点以及扣点规则明细
 	activityPointsSetDetail, e := models.GetCygxActivityPointsSetDetail(activityId)
 	if e != nil && e.Error() != utils.ErrNoRow() {
@@ -295,6 +300,10 @@ func YanXuanActivityPointsBillSignupCancelReduce(log models.YanXuanActivityPoint
 	activityId := log.ActivityId
 	userId := log.UserId
 
+	activtyPayTotal := GetCygxOrderVirtualAssetdCountTotal(userId, activityId) // 单场付费活动不处理扣点明细
+	if activtyPayTotal > 0 {
+		return
+	}
 	//获取活动是否扣点以及扣点规则明细
 	activityPointsSetDetail, e := models.GetCygxActivityPointsSetDetail(activityId)
 	if e != nil && e.Error() != utils.ErrNoRow() {

+ 496 - 0
services/order.go

@@ -0,0 +1,496 @@
+package services
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"hongze/hongze_cygx/models"
+	"hongze/hongze_cygx/models/order"
+	"hongze/hongze_cygx/utils"
+	"time"
+)
+
+// CancelCygxOrder 关闭到期个人用户研选权限
+func CancelCygxOrder(cont context.Context) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("自动取消十分钟之内没有付款的的订单 CancelCygxOrder ,err:", err.Error()), 2)
+		}
+	}()
+	var condition string
+	var pars []interface{}
+	endTime := time.Now().Add(-10 * time.Minute)
+	condition = ` AND order_status = 1   AND create_time < ?   `
+	pars = append(pars, endTime)
+	orderList, e := order.GetCygxOrderList(condition, pars, 0, 999)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetCygxOrderList, Err: " + e.Error())
+		return
+	}
+	fmt.Println(len(orderList))
+	if len(orderList) == 0 {
+		return
+	}
+	//订单量不大,先这么写吧
+	for _, v := range orderList {
+		fmt.Println(v.OrderCode)
+		e = order.CancelCygxOrder(v)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			err = errors.New("CancelCygxOrder, Err: " + e.Error())
+			return
+		}
+	}
+	return
+}
+
+//func init() {
+//	HandleOrderRefundHandleask()
+//}
+
+// GetQueryOrderByOutTradeNoTask 定时任务主动获取订单支付状态
+func GetQueryOrderByOutTradeNoTask(cont context.Context) (err error) {
+	//func GetQueryOrderByOutTradeNoTask() (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("自动取消十分钟之内没有付款的的订单 CancelCygxOrder ,err:", err.Error()), 2)
+		}
+	}()
+	var condition string
+	var pars []interface{}
+	endTime := time.Now().Add(-10 * time.Minute)
+	condition = ` AND order_status = 1   AND create_time >  ?   ` //获取十分钟之内待支付的订单
+	pars = append(pars, endTime)
+	orderList, e := order.GetCygxOrderList(condition, pars, 0, 999)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetCygxOrderList, Err: " + e.Error())
+		return
+	}
+
+	if len(orderList) == 0 {
+		return
+	}
+	//订单量不大,先这么写吧
+	for _, v := range orderList {
+		tradeState, statusCode, itemResp := GetQueryOrderByOutTradeNo(v.OutTradeNo)
+		if tradeState == "SUCCESS" && statusCode == 200 {
+			go HandleOrderHandle(itemResp)
+		}
+	}
+	return
+}
+
+// 手动处理支付订单回调
+func HandleOrderHandle(itemCallback *Transaction) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("手动处理支付订单回调失败 HandleOrderHandle, err:", err.Error()), 2)
+		}
+	}()
+	outTradeNo := itemCallback.OutTradeNo
+	orderDetail, e := order.GetCygxOrderDetailByOutTradeNo(outTradeNo)
+	if e != nil {
+		err = errors.New("GetCygxOrderDetailByOrderCode, Err: " + e.Error())
+		return
+	}
+
+	go AddCygxOrderPayment(itemCallback) // 记录支付交易信息
+
+	if itemCallback.TradeState != "SUCCESS" { // 回调显示支付不成功,模版消息推送
+		if e != nil {
+			err = errors.New("支付失败,  outTradeNo: " + outTradeNo)
+			return
+		}
+	}
+	//修改过状态的不再二次处理
+	if orderDetail.OrderStatus == 2 {
+		return
+	}
+
+	itemOrder := new(order.CygxOrder)
+	itemOrder.OrderCode = orderDetail.OrderCode
+	itemOrder.PayTime = itemCallback.SuccessTime
+	itemOrder.PayMoney = float64(float64(itemCallback.Amount.PayerTotal) / 100) // 金额分转换处理
+	itemOrder.OrderStatus = 2
+	itemOrder.OutTradeCode = itemCallback.TransactionId
+	itemOrder.TradeType = itemCallback.TradeType
+
+	//文章处理逻辑  	OrderType        int       `comment:"订单类型,1:畅读卡订单,2:单场付费订单"`
+	if orderDetail.OrderType == 1 {
+		itemUserCard := new(order.CygxOrderUserCard)
+		itemUserCard.OrderCode = orderDetail.OrderCode
+		itemUserCard.UserId = orderDetail.UserId
+		itemUserCard.Mobile = orderDetail.Mobile
+		itemUserCard.Email = orderDetail.Email
+		itemUserCard.CompanyId = orderDetail.CompanyId
+		itemUserCard.CompanyName = orderDetail.CompanyName
+		itemUserCard.RealName = orderDetail.RealName
+		itemUserCard.SellerName = orderDetail.SellerName
+		itemUserCard.CreateTime = time.Now()
+		itemUserCard.ModifyTime = time.Now()
+		itemUserCard.RegisterPlatform = orderDetail.RegisterPlatform
+
+		if orderDetail.GoodsId == 1 {
+			itemUserCard.StartDate = itemOrder.PayTime
+			itemUserCard.EndDate = itemOrder.PayTime.AddDate(0, 0, 1)
+			itemUserCard.CardType = "日卡"
+		} else {
+			now := time.Now()
+			itemUserCard.StartDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
+			itemUserCard.EndDate = itemUserCard.StartDate.AddDate(0, 1, 0)
+			itemUserCard.CardType = "月卡"
+		}
+		e = order.AddCygxOrderUserCard(itemUserCard, itemOrder)
+		if e != nil {
+			err = errors.New("AddCygxOrderUserCard, Err: " + e.Error())
+			return
+		}
+	} else if orderDetail.OrderType == 2 {
+		//如果是活动,把单场付费信息的活动写入 用户虚拟资产表
+		itemOrderVirtualAsset := new(order.CygxOrderVirtualAsset)
+		itemOrderVirtualAsset.OrderCode = orderDetail.OrderCode
+		itemOrderVirtualAsset.UserId = orderDetail.UserId
+		itemOrderVirtualAsset.Mobile = orderDetail.Mobile
+		itemOrderVirtualAsset.Email = orderDetail.Email
+		itemOrderVirtualAsset.CompanyId = orderDetail.CompanyId
+		itemOrderVirtualAsset.CompanyName = orderDetail.CompanyName
+		itemOrderVirtualAsset.RealName = orderDetail.RealName
+		itemOrderVirtualAsset.SellerName = orderDetail.SellerName
+		itemOrderVirtualAsset.Source = orderDetail.Source
+		itemOrderVirtualAsset.SourceId = orderDetail.SourceId
+		itemOrderVirtualAsset.CreateTime = time.Now()
+		itemOrderVirtualAsset.ModifyTime = time.Now()
+		e = order.AddCygxOrderVirtualAsset(itemOrderVirtualAsset, itemOrder)
+		if e != nil {
+			err = errors.New("AddCygxOrderVirtualAsset, Err: " + e.Error())
+			return
+		}
+	}
+	if orderDetail.Source == utils.CYGX_OBJ_ACTIVITY {
+		go AddActivitySignupByWechatPay(orderDetail.SourceId, orderDetail.UserId) //微信付款成功自动添加报名
+	}
+	go CancelOtherOrder(orderDetail) //付款成功之后自动取消其他相同的订单
+
+	return
+}
+
+// 添加操作记录
+func AddCygxOrderPayment(itemCallback *Transaction) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("处理订单回调信息失败 HandleOrderHandle, err:", err.Error()), 2)
+		}
+	}()
+	itemPay := new(order.CygxOrderPayment)
+	itemPay.OrderCode = itemCallback.OutTradeNo
+	itemPay.OutTradeCode = itemCallback.TransactionId
+	itemPay.PayBody = itemCallback.TradeStateDesc
+	jsonData, _ := json.Marshal(itemCallback)
+	itemPay.PayDetail = string(jsonData)
+	itemPay.PayMoney = float64(float64(itemCallback.Amount.PayerTotal) / 100) // 金额分转换处理
+	itemPay.PayStatus = itemCallback.TradeState
+	itemPay.CreateTime = time.Now()
+	itemPay.PaymentType = 1
+	e := order.AddCygxOrderPayment(itemPay)
+	if e != nil {
+		err = errors.New("AddCygxOrderPayment, Err: " + e.Error())
+		return
+	}
+	return
+}
+
+// 定时任务处理退款回调
+func HandleOrderRefundHandleask(cont context.Context) (err error) {
+	//func HandleOrderRefundHandleask() (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("自动取消十分钟之内没有付款的的订单 CancelCygxOrder ,err:", err.Error()), 2)
+		}
+	}()
+	var condition string
+	var pars []interface{}
+	//endTime := time.Now().Add(-10 * time.Minute)
+	condition = ` AND order_status = 4    ` //获取十分钟之内待支付的订单
+	//pars = append(pars, endTime)
+	orderList, e := order.GetCygxOrderList(condition, pars, 0, 999)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetCygxOrderList, Err: " + e.Error())
+		return
+	}
+	fmt.Println(len(orderList))
+	if len(orderList) == 0 {
+		return
+	}
+	//订单量不大,先这么写吧
+	for _, v := range orderList {
+		tradeState, statusCode, itemResp := GetQueryOrderByOutTradeNo(v.OutTradeNo)
+		if tradeState == "REFUND" && statusCode == 200 {
+			go HandleOrderRefundHandle(itemResp)
+		}
+	}
+	return
+}
+
+// 处理退款订单回调
+func HandleOrderRefundHandle(itemCallback *Transaction) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("处理退款订单回调信息失败 HandleOrderRefundHandle, err:", err.Error()), 2)
+		}
+	}()
+	outTradeNo := itemCallback.OutTradeNo
+	orderDetail, e := order.GetCygxOrderDetailByOrderCode(outTradeNo)
+	if e != nil {
+		err = errors.New("GetCygxOrderDetailByOrderCode, Err: " + e.Error())
+		return
+	}
+
+	//go AddCygxOrderPayment(itemCallback) // 记录支付交易信息
+
+	//修改过状态的不再二次处理
+	if orderDetail.OrderStatus == 3 {
+		return
+	}
+
+	itemOrder := new(order.CygxOrder)
+	itemOrder.OrderCode = orderDetail.OrderCode
+	itemOrder.RefundTime = itemCallback.SuccessTime
+	itemOrder.RefundMoney = float64(float64(itemCallback.Amount.PayerTotal) / 100) // 金额分转换处理
+	itemOrder.OrderStatus = 3
+
+	//文章处理逻辑  	OrderType        int       `comment:"订单类型,1:畅读卡订单,2:单场付费订单"`
+	if orderDetail.OrderType == 1 {
+		itemUserCard := new(order.CygxOrderUserCard)
+		itemUserCard.OrderCode = orderDetail.OrderCode
+		itemUserCard.UserId = orderDetail.UserId
+		itemUserCard.Mobile = orderDetail.Mobile
+		itemUserCard.Email = orderDetail.Email
+		itemUserCard.CompanyId = orderDetail.CompanyId
+		itemUserCard.CompanyName = orderDetail.CompanyName
+		itemUserCard.RealName = orderDetail.RealName
+		itemUserCard.SellerName = orderDetail.SellerName
+		itemUserCard.CreateTime = time.Now()
+		itemUserCard.ModifyTime = time.Now()
+		itemUserCard.RegisterPlatform = orderDetail.RegisterPlatform
+
+		if orderDetail.GoodsId == 1 {
+			itemUserCard.CardType = "日卡"
+		} else {
+			itemUserCard.CardType = "月卡"
+		}
+		e = order.RemoveCygxOrderUserCard(itemUserCard, itemOrder) // 移除用户
+		if e != nil {
+			err = errors.New("RemoveCygxOrderUserCard, Err: " + e.Error())
+			return
+		}
+	} else if orderDetail.OrderType == 2 {
+		//如果是活动,把单场付费信息的活动写入 用户虚拟资产表
+		itemOrderVirtualAsset := new(order.CygxOrderVirtualAsset)
+		itemOrderVirtualAsset.OrderCode = orderDetail.OrderCode
+		itemOrderVirtualAsset.UserId = orderDetail.UserId
+		itemOrderVirtualAsset.Mobile = orderDetail.Mobile
+		itemOrderVirtualAsset.Email = orderDetail.Email
+		itemOrderVirtualAsset.CompanyId = orderDetail.CompanyId
+		itemOrderVirtualAsset.CompanyName = orderDetail.CompanyName
+		itemOrderVirtualAsset.RealName = orderDetail.RealName
+		itemOrderVirtualAsset.SellerName = orderDetail.SellerName
+		itemOrderVirtualAsset.Source = orderDetail.Source
+		itemOrderVirtualAsset.SourceId = orderDetail.SourceId
+		itemOrderVirtualAsset.CreateTime = time.Now()
+		itemOrderVirtualAsset.ModifyTime = time.Now()
+		e = order.RemoveCygxOrderVirtualAsset(itemOrderVirtualAsset, itemOrder)
+		if e != nil {
+			err = errors.New("AddCygxOrderVirtualAsset, Err: " + e.Error())
+			return
+		}
+	}
+	//if orderDetail.Source == utils.CYGX_OBJ_ACTIVITY {
+	//	go CancelActivitySignupByWechatPay(orderDetail.SourceId, orderDetail.UserId) //微信退款成功自动取消报名
+	//}
+	return
+}
+
+// 微信付款成功自动添加报名
+func AddActivitySignupByWechatPay(activityId, userId int) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("微信付款成功自动添加报名失败 AddActivitySignupByWechatPay, err:", err.Error(), "activityId:", activityId, "userId:", userId), 2)
+		}
+	}()
+	activityInfo, e := models.GetAddActivityInfoById(activityId)
+	if e != nil {
+		err = errors.New("GetAddActivityInfoById, Err: " + e.Error())
+		return
+	}
+	var userPointsNum float64
+	if activityInfo.IsResearchPoints {
+		//获取活动对用户要扣的点
+		userPointsNum, e = models.GetCygxActivityPointsSetUserNum(activityInfo.ActivityId)
+		if e != nil {
+			err = errors.New("GetCygxActivityPointsSetUserNum, Err: " + e.Error())
+			return
+		}
+	}
+
+	//专家线下沙龙与买方线下交流、扣点的公司调研电话会自动报名
+	if activityInfo.ActivityTypeId != 5 && activityInfo.ActivityTypeId != 8 && userPointsNum == 0 {
+		return
+	}
+
+	user, e := models.GetWxUserItemByUserId(userId)
+	if e != nil {
+		err = errors.New("GetWxUserItemByUserId, Err: " + e.Error())
+		return
+	}
+	var sellerName string
+	sellerName, e = models.GetCompanySellerName(user.CompanyId)
+	if e != nil {
+		err = errors.New("GetCompanySellerName, Err: " + e.Error())
+		return
+	}
+
+	item := new(models.CygxActivitySignup)
+	totalMySuccess, e := models.GetActivitySignupCount(userId, activityId)
+	if e != nil {
+		err = errors.New("AddActivitySignup, Err: " + e.Error())
+		return
+	}
+	if totalMySuccess > 0 { //已报名这个活动
+		return
+	}
+	item.UserId = userId
+	item.RealName = user.RealName
+	item.SellerName = sellerName
+	item.ActivityId = activityId
+	item.CreateTime = time.Now()
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.CompanyId = user.CompanyId
+	item.CompanyName = user.CompanyName
+	item.SignupType = 3
+	item.FailType = 0
+	item.DoFailType = 0
+	item.OutboundMobile = user.Mobile
+	if user.OutboundMobile != "" {
+		item.OutboundMobile = user.OutboundMobile
+		if user.OutboundCountryCode == "" {
+			item.CountryCode = "86"
+		} else {
+			item.CountryCode = user.OutboundCountryCode
+		}
+	} else {
+		item.OutboundMobile = user.Mobile
+		if user.CountryCode == "" {
+			item.CountryCode = "86"
+		} else {
+			item.CountryCode = user.CountryCode
+		}
+	}
+	_, e = models.AddActivitySignup(item)
+	if e != nil {
+		err = errors.New("AddActivitySignup, Err: " + e.Error())
+		return
+	}
+	fmt.Println("报名成功")
+	go ActivityUserRemind(user, activityInfo, 4)
+
+	return
+}
+
+// 微信退款成功自动取消报名
+func CancelActivitySignupByWechatPay(activityId, userId int) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("微信退款成功自动取消报名失败 CancelActivitySignupByWechatPay, err:", err.Error(), "activityId:", activityId, "userId:", userId), 2)
+		}
+	}()
+	activityInfo, e := models.GetAddActivityInfoById(activityId)
+	if e != nil {
+		err = errors.New("GetAddActivityInfoById, Err: " + e.Error())
+		return
+	}
+
+	user, e := models.GetWxUserItemByUserId(userId)
+	if e != nil {
+		err = errors.New("GetWxUserItemByUserId, Err: " + e.Error())
+		return
+	}
+
+	item := new(models.CygxActivitySignup)
+	item.UserId = userId
+	item.ActivityId = activityId
+	item.CreateTime = time.Now()
+	item.Mobile = user.Mobile
+	item.Email = user.Email
+	item.CompanyId = user.CompanyId
+	item.CompanyName = user.CompanyName
+	resp := new(models.SignupStatus)
+	resp.ActivityId = activityId
+	_, e = models.CancelActivitySignup(item)
+	if e != nil {
+		err = errors.New("CancelActivitySignup, Err: " + e.Error())
+		return
+	}
+
+	// 如果是买方研选下的专家沙龙,同时推给内容组四人
+	if activityInfo.ActivityTypeId == 5 {
+		go SendActivitieCancelSignTemplateMsg(user, activityInfo)
+	}
+	go SendResearchActivitiesTemplateMsg(user, activityInfo, "取消报名") //公司线下调研活动客户报名后给建会人,所属销售推送模板信息
+
+	return
+}
+
+// 付款成功之后自动取消其他相同的订单
+func CancelOtherOrder(item *order.CygxOrder) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("付款成功之后自动取消其他相同的订单失败 CancelOtherOrder, err:", err.Error(), "order_id:", item.OrderId), 2)
+		}
+	}()
+
+	var condition string
+	var pars []interface{}
+	userId := item.UserId
+
+	//判断是日卡月卡还是单场付费活动
+	if item.GoodsId == 1 || item.GoodsId == 2 {
+		condition += ` AND user_id  = ?  AND  goods_id IN (1,2)  AND  order_id  != ? AND  order_status = 1  `
+		pars = append(pars, userId, item.OrderId)
+	} else {
+		condition += ` AND user_id  = ?  AND  source_id = ?   AND  source = ?  AND  order_id  != ? AND  order_status = 1  `
+		pars = append(pars, userId, item.SourceId, item.Source, item.OrderId)
+	}
+
+	listOrder, e := order.GetCygxOrderDetailList(condition, pars) // 这里就一条数据
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("GetCygxOrderDetailList, Err: " + e.Error())
+		return
+	}
+	if len(listOrder) == 0 {
+		err = nil
+		return
+	}
+	for _, v := range listOrder {
+		e = order.CancelCygxOrder(v)
+		if e != nil {
+			return
+		}
+	}
+	return
+}

+ 9 - 0
services/task.go

@@ -142,6 +142,15 @@ func Task() {
 
 		sendMfyxActivityBeginMsg := task.NewTask("sendMfyxActivityBeginMsg", "0 */5 6-23 * * *", SendMfyxActivityBeginMsg) //会议前60分钟的提醒
 		task.AddTask("sendMfyxActivityBeginMsg", sendMfyxActivityBeginMsg)
+
+		cancelCygxOrder := task.NewTask("CancelCygxOrder", "0 */1 * * * *", CancelCygxOrder)
+		task.AddTask("十分钟内未付款的订单自动取消", cancelCygxOrder) //十分钟内未付款的订单自动取消
+
+		getQueryOrderByOutTradeNoTask := task.NewTask("getQueryOrderByOutTradeNoTask", "0 */1 * * * *", GetQueryOrderByOutTradeNoTask)
+		task.AddTask("定时任务主动获取订单支付状态", getQueryOrderByOutTradeNoTask) //定时任务主动获取订单支付状态
+
+		handleOrderRefundHandleask := task.NewTask("HandleOrderRefundHandleask", "0 */1 * * * *", HandleOrderRefundHandleask)
+		task.AddTask("定时任务处理退款回调", handleOrderRefundHandleask) //定时任务处理退款回调
 	}
 
 	//if utils.RunMode != "release" {

+ 23 - 0
services/user_yanxuan_permission.go

@@ -5,6 +5,7 @@ import (
 	"errors"
 	"fmt"
 	"hongze/hongze_cygx/models"
+	"hongze/hongze_cygx/models/order"
 	"hongze/hongze_cygx/utils"
 )
 
@@ -41,3 +42,25 @@ func UpdateCygxUserYanxuanPermissionToClose(cont context.Context) (err error) {
 	}
 	return
 }
+
+// 判断用户是购买了单场付费活动
+func GetCygxOrderVirtualAssetdCountTotal(userId, activityId int) (total int) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg(fmt.Sprint("判断用户是购买了单场付费活动失败 GetCygxOrderUserCardTotal userId:", userId, "activityId:", activityId, ",err:", err.Error()), 2)
+		}
+	}()
+	var condition string
+	var pars []interface{}
+	condition += ` AND user_id  =   ?  AND source  = 'activity'  AND  source_id =  ? `
+	pars = append(pars, userId, activityId)
+
+	total, e := order.GetCygxOrderVirtualAssetdCount(condition, pars)
+	if e != nil {
+		err = errors.New("GetCygxOrderVirtualAssetdCount, Err: " + e.Error())
+		return
+	}
+	return
+}

+ 165 - 0
services/wx_pay.go

@@ -0,0 +1,165 @@
+package services
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"github.com/wechatpay-apiv3/wechatpay-go/core"
+	"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
+	"hongze/hongze_cygx/utils"
+	"time"
+)
+
+//const (
+//	MchPKFileName              = "../hongze_mfyx/utils/cert/apiclient_key.pem"
+//	Mchid                      = "1624495680"
+//	MchCertificateSerialNumber = "5ED2719CFAE5205763034AD80BF4B8A33533C418"
+//	MchAPIv3Key                = "W1tbnzQrzQ7yRRNuQCIHjis8dgdasKVX"
+//)
+
+//// 微信商户建立连接
+//func getWechatClient() (context.Context, *core.Client, error) {
+//	var err error
+//	defer func() {
+//		if err != nil {
+//			fmt.Println("err", err)
+//			go utils.SendAlarmMsg(fmt.Sprint("微信商户建立连接失败 getWechatClient, err:", err.Error()), 2)
+//		}
+//	}()
+//	// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
+//	mchPrivateKey, err := payUtils.LoadPrivateKeyWithPath(MchPKFileName)
+//	if err != nil {
+//		log.Print("load merchant private key error")
+//		return nil, nil, err
+//	}
+//	ctx := context.Background()
+//	// 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力
+//	opts := []core.ClientOption{
+//		option.WithWechatPayAutoAuthCipher(Mchid, MchCertificateSerialNumber, mchPrivateKey, MchAPIv3Key),
+//	}
+//	client, err := core.NewClient(ctx, opts...)
+//	if err != nil {
+//		log.Printf("new wechat pay client err:%s", err)
+//		return nil, nil, err
+//	}
+//	return ctx, client, nil
+//}
+
+//func init() {
+//	GetQueryOrderByOutTradeNo("OD202404081631545174")
+//}
+
+// 根据订单号查询订单状态失败
+func GetQueryOrderByOutTradeNo(outTradeNo string) (tradeState string, statusCode int, itemResp *Transaction) {
+	var err error
+	defer func() {
+		if err != nil {
+			fmt.Println("err", err)
+			go utils.SendAlarmMsg(fmt.Sprint("根据订单号查询订单状态失败 GetQueryOrderByOutTradeNo, err:", err.Error(), "outTradeNo", outTradeNo), 2)
+		}
+	}()
+	//ctx, client, err := getWechatClient()
+	//if err != nil {
+	//	log.Printf("getWechatClientt err:%s", err)
+	//	return
+	//}
+	ctx := context.Background()
+	svc := jsapi.JsapiApiService{Client: utils.WechatCertClient}
+	resp, result, err := svc.QueryOrderByOutTradeNo(ctx,
+		jsapi.QueryOrderByOutTradeNoRequest{
+			OutTradeNo: core.String(outTradeNo),
+			Mchid:      core.String(utils.Mchid),
+		},
+	)
+	statusCode = result.Response.StatusCode
+	//fmt.Println(statusCode)
+	//订单状态码不存在直接返回
+	if statusCode == 404 {
+		err = nil
+		return
+	}
+	tradeState = *resp.TradeState
+	data, err := json.Marshal(resp)
+	if err != nil {
+		return
+	}
+	jsonstr := string(data)
+	//item := new(Transaction)
+	if err = json.Unmarshal([]byte(jsonstr), &itemResp); err != nil {
+		return
+	}
+	//itemResp = item
+	//fmt.Println(itemResp)
+	//fmt.Println(tradeState)
+	//fmt.Println(itemResp.TransactionId)
+	return
+}
+
+// Transaction
+type Transaction struct {
+	Amount          TransactionAmount `json:"amount,omitempty"`
+	Appid           string            `json:"appid,omitempty"`
+	Attach          string            `json:"attach,omitempty"`
+	BankType        string            `json:"bank_type,omitempty"`
+	Mchid           string            `json:"mchid,omitempty"`
+	OutTradeNo      string            `json:"out_trade_no,omitempty"`
+	Payer           TransactionPayer  `json:"payer,omitempty"`
+	PromotionDetail []PromotionDetail `json:"promotion_detail,omitempty"`
+	SuccessTime     time.Time         `json:"success_time,omitempty"`
+	TradeState      string            `json:"trade_state,omitempty"`
+	TradeStateDesc  string            `json:"trade_state_desc,omitempty"`
+	TradeType       string            `json:"trade_type,omitempty"`
+	TransactionId   string            `json:"transaction_id,omitempty"`
+}
+
+// TransactionAmount
+type TransactionAmount struct {
+	Currency      string `json:"currency,omitempty"`
+	PayerCurrency string `json:"payer_currency,omitempty"`
+	PayerTotal    int64  `json:"payer_total,omitempty"`
+	Total         int64  `json:"total,omitempty"`
+}
+
+// TransactionPayer
+type TransactionPayer struct {
+	Openid string `json:"openid,omitempty"`
+}
+
+// PromotionDetail
+type PromotionDetail struct {
+	// 券ID
+	CouponId *string `json:"coupon_id,omitempty"`
+	// 优惠名称
+	Name *string `json:"name,omitempty"`
+	// GLOBAL:全场代金券;SINGLE:单品优惠
+	Scope *string `json:"scope,omitempty"`
+	// CASH:充值;NOCASH:预充值。
+	Type *string `json:"type,omitempty"`
+	// 优惠券面额
+	Amount *int64 `json:"amount,omitempty"`
+	// 活动ID,批次ID
+	StockId *string `json:"stock_id,omitempty"`
+	// 单位为分
+	WechatpayContribute *int64 `json:"wechatpay_contribute,omitempty"`
+	// 单位为分
+	MerchantContribute *int64 `json:"merchant_contribute,omitempty"`
+	// 单位为分
+	OtherContribute *int64 `json:"other_contribute,omitempty"`
+	// CNY:人民币,境内商户号仅支持人民币。
+	Currency    *string                `json:"currency,omitempty"`
+	GoodsDetail []PromotionGoodsDetail `json:"goods_detail,omitempty"`
+}
+
+// PromotionGoodsDetail
+type PromotionGoodsDetail struct {
+	// 商品编码
+	GoodsId *string `json:"goods_id"`
+	// 商品数量
+	Quantity *int64 `json:"quantity"`
+	// 商品价格
+	UnitPrice *int64 `json:"unit_price"`
+	// 商品优惠金额
+	DiscountAmount *int64 `json:"discount_amount"`
+	// 商品备注
+	GoodsRemark *string `json:"goods_remark,omitempty"`
+}

+ 54 - 0
utils/wechat_cert.go

@@ -0,0 +1,54 @@
+package utils
+
+import (
+	"context"
+	"fmt"
+	"github.com/wechatpay-apiv3/wechatpay-go/core"
+	"github.com/wechatpay-apiv3/wechatpay-go/core/option"
+	payUtils "github.com/wechatpay-apiv3/wechatpay-go/utils"
+	"os"
+)
+
+var WechatCertClient *core.Client
+
+const (
+	//MchPKFileName = "../hongze_mfyx/utils/cert/apiclient_key.pem"
+	MchPKFileName              = "/home/code/wechat_cert/cygx/apiclient_key.pem"
+	Mchid                      = "1624495680"
+	MchCertificateSerialNumber = "5ED2719CFAE5205763034AD80BF4B8A33533C418"
+	MchAPIv3Key                = "W1tbnzQrzQ7yRRNuQCIHjis8dgdasKVX"
+)
+
+// 微信商户建立连接
+func init() {
+	if RunMode != "release" {
+		_, err := os.Stat(MchPKFileName) // 判断证书路径是否存在,非生产环境不做判断。
+		if err != nil {
+			//fmt.Println(err)
+			go SendAlarmMsg("微信商户链接失败 os.Stat"+err.Error(), 2)
+			FileLog.Info("WechatCertClient err:" + err.Error())
+			err = nil
+			return
+		}
+	}
+
+	// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
+	mchPrivateKey, err := payUtils.LoadPrivateKeyWithPath(MchPKFileName)
+	if err != nil {
+		fmt.Println(err)
+		go SendAlarmMsg("微信商户链接失败 LoadPrivateKeyWithPath"+err.Error(), 2)
+	}
+	ctx := context.Background()
+	// 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力
+	opts := []core.ClientOption{
+		option.WithWechatPayAutoAuthCipher(Mchid, MchCertificateSerialNumber, mchPrivateKey, MchAPIv3Key),
+	}
+
+	client, err := core.NewClient(ctx, opts...)
+	if err != nil {
+		fmt.Println(err)
+		go SendAlarmMsg("微信商户链接失败 NewClient"+err.Error(), 2)
+	}
+	WechatCertClient = client
+	return
+}