订单回调

This commit is contained in:
wuchao 2024-06-24 11:44:38 +08:00
parent ee7a93f73d
commit 046418534a
22 changed files with 472 additions and 42 deletions

39
Dockerfile Normal file
View File

@ -0,0 +1,39 @@
# 使用官方Go镜像作为构建环境
FROM golang:1.21.0 AS builder
# 设置环境变量的默认值
ENV SERVER=api
# 设置工作目录
WORKDIR /app
# 设置环境变量
ENV GOPROXY=https://goproxy.cn,direct
# 复制项目源码
COPY . .
# 安装snow-core
RUN go get github.com/qit-team/snow-core/kernel/server@v0.1.28
# 安装go模块依赖
RUN go mod tidy
# 编译Go应用程序生成静态链接的二进制文件
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o server main.go
# 创建最终镜像用于运行编译后的Go程序
FROM alpine
WORKDIR /app
# 将编译好的二进制文件从构建阶段复制到运行阶段
COPY --from=builder /app/server /app/server
COPY --from=builder /app/.env /app/.env
RUN chmod +x /app/server
# 暴露容器的端口
EXPOSE 443 8083 8082
# 设置容器启动时运行的命令
ENTRYPOINT ["/app/server", "-a", "api"]

View File

@ -28,6 +28,8 @@ const (
OrderProductNotExist = 1002
//兴业下单失败
XINYEOrderFAIL = 1003
//商品库存不足
ProductStockFAIL = 1004
//订单不允许退款
OrderNOTAuthREFUND = 2001
@ -62,6 +64,7 @@ var MsgZH = map[int]string{
OrderRefundUpdateFail: "订单更新失败",
OrderRefundFail: "退款失败",
YouChuOrderRefundFail: "邮储服务异常",
ProductStockFAIL: "库存不足",
}
var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH}

View File

@ -3,6 +3,7 @@ package front
import (
"github.com/ahmetb/go-linq/v3"
"github.com/gin-gonic/gin"
"net/http"
"qteam/app/constants/common"
"qteam/app/constants/errorcode"
"qteam/app/http/controllers"
@ -28,9 +29,9 @@ func OrderList(c *gin.Context) {
//userId := controllers.GetUserId(c)
userId := 1
code, orderList, count := services.OrderQueryService(userId, request)
var rsp []front.OrderQueryResponse
var rsp []front.OrderListResponse
if count > 0 {
linq.From(orderList).SelectT(func(in ordersmodel.Orders) (out front.OrderQueryResponse) {
linq.From(orderList).SelectT(func(in ordersmodel.OrdersProductsList) (out front.OrderListResponse) {
out.ResponseFromDb(in)
return out
}).ToSlice(&rsp)
@ -41,7 +42,8 @@ func OrderList(c *gin.Context) {
func OrderQuery(c *gin.Context) {
var request = controllers.GetRequest(c).(*front.OrderQueryRequest)
orderId, _ := strconv.Atoi(request.OrderId)
order := ordersmodel.Orders{Id: orderId}
order := ordersmodel.Orders{}
order.Id = orderId
var OrderQueryResponse front.OrderQueryResponse
has, err := services.OrderDetailService(&order)
if err != nil {
@ -79,13 +81,15 @@ func OrderQuery(c *gin.Context) {
func OrderRefund(c *gin.Context) {
var request = controllers.GetRequest(c).(*front.OrderQueryRequest)
//userId := controllers.GetUserId(c)
userId := 1
userId := controllers.GetUserId(c)
//userId := 1
OrderId, _ := strconv.Atoi(request.OrderId)
code := services.OrderRefundService(userId, OrderId)
controllers.HandCodeRes(c, nil, code)
}
func OrderNotify(c *gin.Context) {
var request = controllers.GetRequest(c).(*front.YouChuRequest)
response := services.OrderNotify(*request)
c.JSON(http.StatusOK, response)
}

View File

@ -0,0 +1,16 @@
package front
import (
"github.com/gin-gonic/gin"
"qteam/app/http/controllers"
"qteam/app/http/entities/front"
"qteam/app/services"
)
func ProductDetail(c *gin.Context) {
var request = controllers.GetRequest(c).(*front.ProductDetailRequest)
code, product := services.ProductDetail(*request)
var response = front.ProductDetailResponse{}
response.ResponseFromDb(product)
controllers.HandCodeRes(c, response, code)
}

View File

@ -15,6 +15,36 @@ type OrderQueryRequest struct {
type OrderListRequest struct {
PageRequest
State int `form:"state"`
}
type OrderListResponse struct {
Id int `json:"id"`
OrderNo string `json:"order_no"`
MainImage string `json:"main_image"`
UserId int `json:"user_id"`
UserName string `json:"user_name"`
Mobile string `json:"mobile"`
ProductId int `json:"product_id"`
ProductName string `json:"product_name"`
State int `json:"state"`
VoucherLink string `json:"voucher_link"`
CreateTime string `json:"create_time"`
}
func (p *OrderListResponse) ResponseFromDb(l ordersmodel.OrdersProductsList) {
p.Id = l.Id
p.OrderNo = l.OrderNo
p.MainImage = l.MainImage
p.UserId = l.UserId
p.UserName = l.UserName
p.Mobile = l.Mobile
p.ProductId = l.ProductId
p.ProductName = l.ProductName
p.State = l.State
p.VoucherLink = l.VoucherLink
p.CreateTime = l.CreateTime.Format("2006-01-02 15:04:05")
return
}
type OrderQueryResponse struct {

View File

@ -1 +1,28 @@
package front
import (
"qteam/app/models/productsmodel"
"qteam/app/utils"
)
type ProductDetailRequest struct {
ProductId int `form:"product_id" validate:"required"`
}
type ProductDetailResponse struct {
Id string `json:"id"`
Name string `json:"name"`
MainImage string `json:"main_image"`
Brand string `json:"brand"`
Stock string `json:"stock"`
ShowPrice string `json:"show_price"`
Price string `json:"price"`
CreateTime string `json:"create_time"`
Status string `json:"status"`
Description string `json:"description"`
}
func (this *ProductDetailResponse) ResponseFromDb(in productsmodel.Products) {
utils.EntityCopy(this, &in)
this.CreateTime = in.CreateTime.Format("2006-01-02 15:04:05")
}

View File

@ -4,6 +4,7 @@ import (
"qteam/app/models/brandmodel"
"qteam/app/models/productsmodel"
"qteam/config"
"strconv"
)
type VoucherListResponse struct {
@ -23,6 +24,7 @@ func (this *MilkList) ResponseFromDb(in brandmodel.Brand) {
}
type MilkVoucherList struct {
ProductId string `json:"ProductId"`
BrandFlag string `json:"brandFlag"`
VoucherTitle string `json:"voucherTitle"`
VoucherUrl string `json:"voucherUrl"`
@ -33,11 +35,17 @@ type MilkVoucherList struct {
}
func (this *MilkVoucherList) ResponseFromDb(in productsmodel.MilkProductsList) {
this.ProductId = in.Id
this.BrandFlag = in.Flag
this.VoucherTitle = in.Name
this.VoucherUrl = config.GetConf().YouChu.MilkUrl + "?voucher_id=" + in.Id
this.VoucherUrl = config.GetConf().YouChu.VoucherUrl + "?product_id=" + in.Id
this.VoucherIcon = in.MainImage
this.VoucherAmount = in.ShowPrice
this.VoucherOriginalPrice = in.Price
this.VoucherStatus = in.Status
stock, _ := strconv.Atoi(in.Stock)
if stock > 0 {
this.VoucherStatus = "1"
} else {
this.VoucherStatus = "0"
}
}

View File

@ -9,6 +9,26 @@ type YouChuRequest struct {
EncryptKey string `json:"encryptKey"`
}
type YouChuLoginRequest struct {
Body YouChuLoginBody `json:"body"`
Head YouChuRequestHeader `json:"head"`
}
type YouChuLoginResponse struct {
RespCode string `json:"respCode"` //000000-成功 069801-系统繁忙,请稍后重试 820007-未查询到客户号
RespMsg string `json:"respMsg"` //描 述 (失败时必填)
Phone string `json:"phone"`
IdtLastFour string `json:"idtLastFour"`
CustName string `json:"custName"`
CustFlag string `json:"custFlag"`
}
type YouChuLoginBody struct {
CustNo string `json:"custNo"`
ReqTransTime string `json:"reqTransTime"`
Code string `json:"code"`
}
type YouChuRequestBody struct {
Body YouChuOrderRequest `json:"body"`
Head YouChuRequestHeader `json:"head"`
@ -92,6 +112,22 @@ type RefundRequestData struct {
}
type YouChuOrderNotifyRequest struct {
TxnCode string `json:"txnCode"`
SourceId string `json:"sourceId"`
ReqDate string `json:"reqDate"`
ReqTraceId string `json:"reqTraceId"`
OrderNo string `json:"orderNo"`
TxnAmt string `json:"txnAmt"`
OrderSta string `json:"orderSta"` //03-支付成功 04-支付失败05-检查失败
MchtNo string `json:"mchtNo"`
TermId string `json:"termId"`
TxnFlag string `json:"txnFlag"` //01-消费 03-退货
TxnKind string `json:"txnKind"` //01-银行卡 02-微信 03-支付宝
}
type YouChuOrderNotifyResponse struct {
RespCode string `json:"respCode"` //000000 表示通知成功
RespMsg string `json:"respMsg"`
}
func (this *YouChuOrderRequest) ToMap() (resultMap map[string]interface{}) {

View File

@ -10,7 +10,10 @@ var FrontRequestMap = map[string]func() interface{}{
common.FRONT_API_V1 + "/VoucherList": func() interface{} { return new(struct{}) },
//联合登录
common.FRONT_API_V1 + "/UnionLogin": func() interface{} { return new(front.UnionLoginRequest) },
//商品详情
common.FRONT_API_V1 + "/product/detail": func() interface{} { return new(front.ProductDetailRequest) },
//订单回调
common.FRONT_API_V1 + "/order/notify": func() interface{} { return new(front.YouChuRequest) },
// 生成订单
common.FRONT_API_V1_Auth + "/order/create": func() interface{} { return new(front.OrderCreateRequest) },
//订单列表

View File

@ -52,8 +52,10 @@ func RegisterRoute(router *gin.Engine) {
v1.POST("/VoucherList", front.VoucherList)
// 联合登录
v1.POST("/UnionLogin", front.UnionLogin)
// 订单回调
v1.POST("/order/notify", front.OrderNotify)
//商品详情
v1.POST("/product/detail", front.ProductDetail)
//auth
auth := v1.Group("auth")

View File

@ -27,13 +27,18 @@ type Orders struct {
VoucherLink string `xorm:"'voucher_link' varchar(255)"`
RefundOrderNo string `xorm:"'refundOrderNo' varchar(255)"`
RefundOrderSta string `xorm:"'refundOrderSta' varchar(20)"`
RefundTime time.Time `xorm:"'create_time' datetime"`
RefundTime time.Time `xorm:"'refund_time' datetime"`
CreateTime time.Time `xorm:"'create_time' datetime"`
UpdateTime time.Time `xorm:"'update_time' datetime"`
ExchangeTime time.Time `xorm:"'exchange_time' datetime"`
Deleted time.Time `xorm:"'Deleted' datetime"`
}
type OrdersProductsList struct {
Orders `xorm:"extends"`
MainImage string `xorm:"'main_image' varchar(255)"`
}
// 表名
func (m *Orders) TableName() string {
return "Orders"

View File

@ -1,12 +1,15 @@
package services
import (
"encoding/json"
"qteam/app/constants/common"
"qteam/app/constants/errorcode"
"qteam/app/http/entities/front"
"qteam/app/models/ordersmodel"
"qteam/app/models/productsmodel"
"qteam/app/models/usersmodel"
"qteam/app/third/market"
"qteam/app/third/youchu"
"qteam/app/utils"
redis_util "qteam/app/utils/redis"
"qteam/config"
@ -46,6 +49,10 @@ func CreateOrderService(userId int, productId int) (code int, data front.InsertO
if !has {
return errorcode.OrderProductNotExist, data
}
stock, _ := strconv.Atoi(product.Stock)
if stock <= 0 {
return errorcode.ProductStockFAIL, data
}
var user usersmodel.Users
_, err = usersmodel.GetInstance().GetDb().Where("id =?", userId).Get(&user)
if err != nil {
@ -77,9 +84,15 @@ func CreateOrderService(userId int, productId int) (code int, data front.InsertO
return errorcode.Success, data
}
func OrderQueryService(userId int, OrderRequest *front.OrderListRequest) (code int, data []ordersmodel.Orders, count int64) {
func OrderQueryService(userId int, OrderRequest *front.OrderListRequest) (code int, data []ordersmodel.OrdersProductsList, count int64) {
repo := ordersmodel.GetInstance().GetDb()
count, err := repo.Where("user_id = ?", userId).
conn := builder.NewCond()
conn = conn.And(builder.Eq{"a.user_id": userId})
if OrderRequest.State != 0 {
conn = conn.And(builder.Eq{"a.state": OrderRequest.State})
}
count, err := repo.Where(conn).Alias("a").
Join("INNER", "Products b", "a.product_id = b.id").Select("a.*,b.main_image").
Desc("id").Limit(OrderRequest.PageSize, (OrderRequest.Page-1)*OrderRequest.PageSize).FindAndCount(&data)
code = handErr(err)
return
@ -126,7 +139,8 @@ func OrderRefundService(userId int, orderId int) (code int) {
return errorcode.SystemError
}
}
order := ordersmodel.Orders{Id: orderId, UserId: userId}
order := ordersmodel.Orders{}
order.Id = orderId
has, err := OrderDetailService(&order)
if err != nil || !has {
return errorcode.NotFound
@ -153,3 +167,62 @@ func OrderRefundService(userId int, orderId int) (code int) {
}
}
}
func OrderNotify(request front.YouChuRequest) (NotifyResponse front.YouChuOrderNotifyResponse) {
requestStr, _ := json.Marshal(request)
utils.Log(nil, "OrderNotify", string(requestStr))
response := youchu.DecryptResponse(string(requestStr))
var YouChuOrderNotifyRequest front.YouChuOrderNotifyRequest
err := json.Unmarshal([]byte(response), &YouChuOrderNotifyRequest)
if err != nil {
return front.YouChuOrderNotifyResponse{RespCode: "000001", RespMsg: "解析失败"}
}
utils.Log(nil, "YouChuOrderNotifyRequest", YouChuOrderNotifyRequest)
// 03-支付成功 04-支付失败 05-检查失败
if YouChuOrderNotifyRequest.OrderSta != "03" {
return front.YouChuOrderNotifyResponse{RespCode: "000002", RespMsg: "交易失败"}
} else {
//支付成功
utils.Log(nil, "OrderNotify-success", YouChuOrderNotifyRequest)
var orderDetail ordersmodel.Orders
var order ordersmodel.Orders
has, err := ordersmodel.GetInstance().GetDb().Where("state = ?", common.ORDER_STATUS_DEFAULT).Where("order_no = ?", YouChuOrderNotifyRequest.ReqTraceId).Get(&orderDetail)
if err != nil || !has {
return front.YouChuOrderNotifyResponse{RespCode: "000003", RespMsg: "订单不存在"}
}
var productDetail productsmodel.Products
has, err = productsmodel.GetInstance().GetDb().Where("id = ?", orderDetail.ProductId).Get(&productDetail)
if err != nil || !has {
return front.YouChuOrderNotifyResponse{RespCode: "000003", RespMsg: "商品不存在"}
}
//01-消费 03-退货
if YouChuOrderNotifyRequest.TxnFlag == "01" {
client := market.NewMarketClient(config.GetConf().OpenApiMarketConfig)
send, err := client.MarketSend(orderDetail.OrderNo, strconv.Itoa(orderDetail.VoucherId), "", "1")
utils.Log(nil, "OrderNotify-MarketSend", send)
if err != nil {
return front.YouChuOrderNotifyResponse{RespCode: "000004", RespMsg: "充值失败"}
}
order.OrgTxnSeq = YouChuOrderNotifyRequest.OrderNo
if send.ErrCode != "00" {
order.State = common.ORDER_STATUS_FAIL
} else {
order.State = common.ORDER_STATUS_FINISH
order.VoucherLink = send.Data.ShortUrl
Stock, _ := strconv.Atoi(productDetail.Stock)
productDetail.Stock = strconv.Itoa(Stock - 1)
}
} else {
//order.RefundOrderNo = YouChuOrderNotifyRequest.OrgTxnSeq
//order.RefundOrderSta = YouChuOrderNotifyRequest.OrderSta
return front.YouChuOrderNotifyResponse{RespCode: "000005", RespMsg: "订单标识错误"}
}
_, err = ordersmodel.GetInstance().GetDb().Where("order_no = ?", YouChuOrderNotifyRequest.ReqTraceId).Update(&order)
_, err = productsmodel.GetInstance().GetDb().Where("id = ?", orderDetail.ProductId).Update(&productDetail)
if err != nil {
utils.Log(nil, "OrderNotify-MarketSend", err.Error())
return front.YouChuOrderNotifyResponse{RespCode: "000004", RespMsg: "操作失败"}
}
}
return
}

View File

@ -1,6 +1,11 @@
package services
import "qteam/app/models/productsmodel"
import (
"qteam/app/constants/errorcode"
"qteam/app/http/entities/front"
"qteam/app/models/productsmodel"
"xorm.io/builder"
)
func MilkProductList() (code int, productList []productsmodel.MilkProductsList) {
err := productsmodel.GetInstance().GetDb().Alias("a").
@ -8,3 +13,16 @@ func MilkProductList() (code int, productList []productsmodel.MilkProductsList)
Where("a.status = ?", 1).Find(&productList)
return handErr(err), productList
}
func ProductDetail(request front.ProductDetailRequest) (code int, product productsmodel.Products) {
repo := productsmodel.GetInstance().GetDb()
conn := builder.NewCond()
if request.ProductId != 0 {
conn = conn.And(builder.Eq{"id": request.ProductId})
}
has, err := repo.Where(conn).Get(&product)
if !has {
return errorcode.NotFound, product
}
return handErr(err), product
}

View File

@ -12,8 +12,8 @@ import (
func YouChuLogin(req *front.UnionLoginRequest) (code int, login front.LoginResponse) {
client := youchu.NewYouChuClient(config.GetConf().YouChu)
YouChuResponse, err := client.Login(req.Code)
if err != nil {
Code, YouChuResponse := client.Login(req.Code)
if Code != errorcode.Success {
return
}
if YouChuResponse.RespCode == "000000" {

View File

@ -20,15 +20,6 @@ type YouChuSendRequest struct {
Code string `json:"code"`
}
type YouChuResponse struct {
RespCode string `json:"respCode"` //000000-成功 069801-系统繁忙,请稍后重试 820007-未查询到客户号
RespMsg string `json:"respMsg"` //描 述 (失败时必填)
Phone string `json:"phone"`
IdtLastFour string `json:"idtLastFour"`
CustName string `json:"custName"`
CustFlag string `json:"custFlag"`
}
func (this *YouChuSendRequest) toMap() (resultMap map[string]interface{}) {
// Marshal the struct to JSON, ignoring omitempty fields.
jsonBytes, err := json.Marshal(this)

View File

@ -19,24 +19,41 @@ func NewYouChuClient(cfg config.YouChuConfig) *YouChuClient {
}
}
func (this *YouChuClient) Login(code string) (res YouChuResponse, err error) {
func (this *YouChuClient) Login(code string) (Code int, response front.YouChuLoginResponse) {
partnerTxSriNo := time.Now().Format("20060102150405") + fmt.Sprintf("%10d", mrand.Intn(10000))
url := this.cfg.MerchantId + ".html?partnerTxSriNo=" + partnerTxSriNo
request := YouChuSendRequest{
CustNo: this.cfg.MerchantId,
ReqTransTime: time.Now().Format("20060102150405"),
request := front.YouChuLoginRequest{
Head: front.YouChuRequestHeader{
PartnerTxSriNo: partnerTxSriNo,
AccessType: "API",
Reserve: "",
Method: "crecard.getCustomerInfo",
Version: "1",
MerchantId: config.GetConf().YouChu.MerchantId,
AppID: config.GetConf().YouChu.AppID,
},
Body: front.YouChuLoginBody{
Code: code,
CustNo: "000000",
ReqTransTime: time.Now().Format("20060102150405"),
},
}
bytes, err := json.Marshal(request)
requestData := EncryptRequest(request)
bytes, err := json.Marshal(requestData)
if err != nil {
return res, err
return errorcode.SystemError, response
}
data, err := this.doPost(url, partnerTxSriNo, "crecard.getCustomerInfo", bytes)
post, err := this.doPost(url, partnerTxSriNo, "crecard.getCustomerInfo", bytes)
if err != nil {
return res, err
return errorcode.SystemError, response
}
err = json.Unmarshal(data, &res)
return
responseData := DecryptResponse(string(post))
utils.Log(nil, "YouChuLogin", responseData)
err = json.Unmarshal([]byte(responseData), &response)
if err != nil {
return errorcode.SystemError, response
}
return errorcode.Success, response
}
func (this *YouChuClient) OrderQuery(order ordersmodel.Orders) (code int, response front.YouChuOrderQueryResponse) {
@ -75,9 +92,10 @@ func (this *YouChuClient) OrderQuery(order ordersmodel.Orders) (code int, respon
if err != nil {
return errorcode.SystemError, response
}
err = json.Unmarshal(post, &response)
responseData := DecryptResponse(string(post))
err = json.Unmarshal([]byte(responseData), &response)
if err != nil {
return errorcode.SystemError, front.YouChuOrderQueryResponse{}
return errorcode.SystemError, response
}
return errorcode.Success, response
}
@ -121,7 +139,8 @@ func (this *YouChuClient) OrderRefund(order ordersmodel.Orders) (code int, respo
if err != nil {
return errorcode.YouChuOrderRefundFail, response
}
err = json.Unmarshal(post, &response)
responseData := DecryptResponse(string(post))
err = json.Unmarshal(post, &responseData)
if err != nil {
return errorcode.SystemError, front.YouChuOrderRefundResponse{}
}
@ -132,7 +151,7 @@ func EncryptRequest(request interface{}) (RequestData front.YouChuRequest) {
input, _ := json.Marshal(request)
MerchantId := config.GetConf().YouChu.MerchantId
PrivateKey := config.GetConf().Sm2.PrivateKey
PublicKey := config.GetConf().Sm2.PublicKey
PublicKey := config.GetConf().YouChu.SopPublicKey
encrypt, err := postbank.Encrypt(MerchantId, PrivateKey, PublicKey, string(input), "", true)
if err != nil {
return front.YouChuRequest{}
@ -143,3 +162,29 @@ func EncryptRequest(request interface{}) (RequestData front.YouChuRequest) {
}
return RequestData
}
func DecryptResponse(response string) (Rsponse string) {
MerchantId := config.GetConf().YouChu.MerchantId
PrivateKey := config.GetConf().Sm2.PrivateKey
PublicKey := config.GetConf().YouChu.SopPublicKey
encrypt, err := postbank.Decrypt(MerchantId, PrivateKey, PublicKey, response, true)
if err != nil {
return ""
}
var RsponseData map[string]string
err = json.Unmarshal([]byte(encrypt), &RsponseData)
if err != nil {
return ""
} else {
if RsponseData["body"] != "" {
Rsponse = RsponseData["body"]
}
}
utils.Log(nil, "DecryptResponse-body", Rsponse)
return Rsponse
}
type T struct {
Head string `json:"head"`
Body string `json:"body"`
}

View File

@ -42,7 +42,8 @@ type Config struct {
type YouChuConfig struct {
Host string
NotifyUrl string
MilkUrl string
MilkUrl string //奶茶专区跳转链接
VoucherUrl string //代金券链接
MerchantId string //合作方编号
MchtNo string //上单商户号
AppID string //appid

15
sh/create.sh Normal file
View File

@ -0,0 +1,15 @@
#!/bin/bash
IMAGE="msg:v1"
RPC_CONTAINER="msg"
RPC_PORT="9000"
API_PORT="8000"
V_REFLECT=""
docker build -t "${IMAGE}" . --no-cache
docker stop "${RPC_CONTAINER}"
docker rm "${RPC_CONTAINER}"
docker run -it -p "${RPC_PORT}:${RPC_PORT}" -p "${API_PORT}:${API_PORT}" --name "$RPC_CONTAINER" "${IMAGE}"

9
sh/startup.sh Normal file
View File

@ -0,0 +1,9 @@
#!/bin/bash
# supervisord
supervisord -c /etc/supervisord.conf

29
sh/supervisord.conf Normal file
View File

@ -0,0 +1,29 @@
; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /msgc/sh/supervisord_include/*.conf

View File

@ -0,0 +1,44 @@
[program:rpc]
directory=/msgc/cmd/rpc
# 执行的命令
command=/msgc/cmd/rpc/msgcenter
#在 supervisord 启动的时候也自动启动
autorstart=false
#程序异常退出后自动重启
autorestart=true
#启动 5 秒后没有异常退出,就当作已经正常启动了
startsecs=5
#启动失败自动重试次数,默认是 3
startretries=3
#把 stderr 重定向到 stdout默认 false
redirect_stderr=false
#stdout 日志文件大小,默认 50MB
stdout_logfile_maxbytes = 20MB
#stdout 日志文件备份数
stdout_logfile_backups = 20
#stdout 日志文件需要注意当指定目录不存在时无法正常启动所以需要手动创建目录supervisord 会自动创建日志文件)
stdout_logfile=/var/log/supervisor_swoole_http_out.log
stderr_logfile=/var/log/supervisor_swoole_http_err.log
[program:api]
directory=/msgc/cmd/api
# 执行的命令
command=/msgc/cmd/api/msgcenter
#在 supervisord 启动的时候也自动启动
autorstart=false
#程序异常退出后自动重启
autorestart=true
#启动 5 秒后没有异常退出,就当作已经正常启动了
startsecs=5
#启动失败自动重试次数,默认是 3
startretries=3
#把 stderr 重定向到 stdout默认 false
redirect_stderr=false
#stdout 日志文件大小,默认 50MB
stdout_logfile_maxbytes = 20MB
#stdout 日志文件备份数
stdout_logfile_backups = 20
#stdout 日志文件需要注意当指定目录不存在时无法正常启动所以需要手动创建目录supervisord 会自动创建日志文件)
stdout_logfile=/var/log/supervisor_swoole_http_out.log
stderr_logfile=/var/log/supervisor_swoole_http_err.log

32
start.sh Normal file
View File

@ -0,0 +1,32 @@
#!/bin/bash
# 检测 MySQL 容器是否在运行
if [ "$(docker ps -q -f name=mysql-container)" ] && [ "$(docker ps -q -f name=redis-container)" ]; then
echo "MySQL 容器已经在运行,退出脚本。"
exit
fi
# 下载 MySQL 8.0.33 镜像
docker pull mysql:8.0.33
# 下载 Redis Alpine 3.10 镜像
docker pull redis:alpine3.10
# 挂载 Redis 和 MySQL 配置目录以及数据存储目录到 /var/www 目录
mkdir -p /var/www/redis/config
mkdir -p /var/www/mysql/config
mkdir -p /var/www/mysql/data
# 启动 MySQL Docker 容器,并挂载配置目录和数据存储目录,设置 root 密码为 lansexiongdi@666并开启远程连接
# 在容器内部创建新的 MySQL 配置目录
docker run -d --name mysql-container -v /var/www/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=lansexiongdi@666 -e MYSQL_ROOT_HOST='%' -p 3306:3306 mysql:8.0.33
# 等待 MySQL 容器启动
echo "等待 MySQL 容器启动..."
# 给 MySQL 的 root 用户授权远程登录
docker exec -it mysql-container mysql -uroot -p lansexiongdi@666 -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'lansexiongdi@666';SET GLOBAL log_bin = 'mysql-bin'; FLUSH PRIVILEGES;"
# 启动 Redis Docker 容器,并挂载配置目录,设置密码为 lansexiongdi@666
docker run -d --name redis-container -v /var/www/redis/redis.conf:/etc/redis.conf -v /var/www/redis/data:/var/lib/redis -e REDIS_PASSWORD=lansexiongdi@666 -p 6379:6379 redis:alpine3.10
echo "MySQL 和 Redis 容器已启动,并配置目录已挂载到 /var/www 目录。MySQL root 用户已授权远程登录。"