feat: 从黄果 NET hgdjnet-server 9bfbafe 导入 HKDJ 官网后端

来源:hgdjnet-server 9bfbafe10d417deea959bd53117bc88a10e60a83
项目身份 HKDJ / JHA-216,独立官网仓库,Jenkins 守卫键 hkdjnet
测试目录 /server/hkdj_net,App/Web API 30331/30332

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-10-16 11:20:04 +08:00
co-authored by Claude Opus 4.7
parent 99a4854def
commit 85c0071fd8
653 changed files with 85000 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
package fengniao
import (
"crypto/sha1"
"errors"
"fmt"
"hkdj-web-server/pub/common/httputil"
"hkdj-web-server/pub/common/log"
"net/http"
)
type requestBody struct {
MercId string `json:"mercId"`
Secret string `json:"secret"`
TemplateId string `json:"templateId"`
Code string `json:"smsCode"`
Mobile string `json:"mobile"`
SignType string `json:"signType"` // 固定sha1
Sign string `json:"sign"` // 签名
}
type msg struct {
Status string `json:"status"`
TaskId string `json:"taskId"`
}
type responseBody struct {
Code int `json:"code"`
Msg msg `json:"msg"`
Err string `json:"err"`
}
type FengNiao struct {
Url string
MercId string
Secret string
Tmpl string
}
// Send 发送, 目前蜂鸟貌似只支持数字
func (f *FengNiao) Send(mobile string, code string) error {
content := fmt.Sprintf(f.Tmpl, code)
data := fmt.Sprintf("mercId=%s&templateId=%s&smsCode=%s&mobile=%s&secret=%s", f.MercId, f.Tmpl, code, mobile, f.Secret)
sha := sha1.New()
_, err := sha.Write([]byte(data))
if err != nil {
log.Error("fengniao send error", log.Any("mobile", mobile), log.Any("content", content), log.E(err))
return err
}
body := &requestBody{
MercId: f.MercId,
Secret: f.Secret,
TemplateId: f.Tmpl,
Code: code,
Mobile: mobile,
SignType: "sha1",
Sign: fmt.Sprintf("%x", sha.Sum(nil)),
}
rp := responseBody{}
statusCode, err := httputil.Client().POSTJsonWithJResp(&rp, f.Url, nil, body)
if err != nil {
log.Error("fengniao POSTJsonWithResp err", log.E(err))
return err
}
if statusCode != http.StatusOK {
log.Error("fengniao status code not 200")
return errors.New("fengniao statusCode not 200")
}
if rp.Code != 200 {
log.Error("fengniao code not 200", log.Any("errdesc", rp.Err))
err = errors.New(rp.Err)
}
return err
}
+50
View File
@@ -0,0 +1,50 @@
package sms
import (
"errors"
"hkdj-web-server/pub/common/sms/fengniao"
"os"
"strings"
)
type Provider = int
const (
tmplID1 = "6029f19a99fd8b404062e4d2" // 大陆
tmplID2 = "5f8412c39396d16f787e561b" // 非大陆
)
const (
FengNiao Provider = 1 //蜂鸟
YunPian Provider = 2 //云片
)
func sendByFengNiao(mobile string, code string) error {
if os.Getenv("HKDJNET_SMS_CN_SECRET") == "" || os.Getenv("HKDJNET_SMS_GLOBAL_SECRET") == "" {
return errors.New("SMS provider is not configured")
}
var tmplID string
if strings.HasPrefix(mobile, "+86") {
tmplID = tmplID1
return (&fengniao.FengNiao{
Url: "https://t9x6k.cc/api/sms/sendSms",
MercId: "10177",
Secret: os.Getenv("HKDJNET_SMS_CN_SECRET"),
Tmpl: tmplID,
}).Send(mobile, code)
} else {
tmplID = tmplID2
return (&fengniao.FengNiao{
Url: "https://t9x6k.cc/api/sms/sendSms",
MercId: "10228",
Secret: os.Getenv("HKDJNET_SMS_GLOBAL_SECRET"),
Tmpl: tmplID,
}).Send(mobile, code)
}
// return
}
// Send 发送短信
func Send(mobile string, code string) error {
return sendByFengNiao(mobile, code)
}