Compare commits
42 Commits
d2ae9e258b
...
e3097efa24
| Author | SHA1 | Date |
|---|---|---|
|
|
e3097efa24 | |
|
|
e126b97031 | |
|
|
2ff4235310 | |
|
|
5d481e4ca8 | |
|
|
a52f8618da | |
|
|
f32444afe2 | |
|
|
6568cc0690 | |
|
|
ec91501a44 | |
|
|
95d164da1d | |
|
|
5f84186a64 | |
|
|
8bb537ff6a | |
|
|
c726d792bd | |
|
|
e50a565e80 | |
|
|
6fa0b3b8af | |
|
|
dd97565ce0 | |
|
|
c9341af4aa | |
|
|
67e974de0e | |
|
|
68cc3c14e6 | |
|
|
4d48f8fce3 | |
|
|
616b3bc99e | |
|
|
42d65797f3 | |
|
|
b55ac43bb9 | |
|
|
593bf8e46a | |
|
|
6ae64b443b | |
|
|
a1dc360fac | |
|
|
3a9efa6ff7 | |
|
|
9228429d63 | |
|
|
4f189f6e2f | |
|
|
c9bfe84484 | |
|
|
62187b9f96 | |
|
|
17110618a8 | |
|
|
2b8eaeedc1 | |
|
|
1e666ae8e5 | |
|
|
672496d34d | |
|
|
9b8dfe1646 | |
|
|
2342ce66b1 | |
|
|
e02ab6405d | |
|
|
7e231be804 | |
|
|
f70c80c40e | |
|
|
48e8dbb4d6 | |
|
|
10a63309ee | |
|
|
9e09eece6f |
|
|
@ -11,3 +11,4 @@ go.sum
|
||||||
pkg
|
pkg
|
||||||
test.go
|
test.go
|
||||||
.claude
|
.claude
|
||||||
|
opencode.json
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
FormTypeInput = "input" //文本输入框
|
|
||||||
FormTypeText = "text" //多行文本
|
|
||||||
FormTypeRadio = "radio" //单选框
|
|
||||||
FormTypeCheckbox = "checkbox" //多选框
|
|
||||||
FormTypeSwitch = "switch" //开关
|
|
||||||
FormTypeJson = "json" //JSON输入框
|
|
||||||
)
|
|
||||||
|
|
||||||
type FormOption struct {
|
|
||||||
Name string `json:"name"` //选项名称
|
|
||||||
Value string `json:"value"` //选项值
|
|
||||||
}
|
|
||||||
|
|
||||||
type Form struct {
|
|
||||||
Type string `json:"type"` //表单类型
|
|
||||||
Name string `json:"name"` //表单名称
|
|
||||||
Key string `json:"key"` //表单KEY
|
|
||||||
Value interface{} `json:"value"` //表单值
|
|
||||||
Default interface{} `json:"default"` //默认值
|
|
||||||
Disable bool `json:"disable,omitempty"` //是否禁用
|
|
||||||
Tips string `json:"tips"` //表单提示
|
|
||||||
Option []*FormOption `json:"option"` //表单选项,radio和checkbox需要
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFroms(tplConfig, saveConfig string) ([]*Form, error) {
|
|
||||||
var forms []*Form
|
|
||||||
err := json.Unmarshal([]byte(tplConfig), &forms)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var cfg map[string]interface{}
|
|
||||||
if strings.TrimSpace(saveConfig) != "" {
|
|
||||||
err = json.Unmarshal([]byte(saveConfig), &cfg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cfg == nil {
|
|
||||||
cfg = make(map[string]interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, form := range forms {
|
|
||||||
if _, ok := cfg[form.Key]; ok {
|
|
||||||
form.Value = cfg[form.Key]
|
|
||||||
} else {
|
|
||||||
form.Value = form.Default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return forms, err
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package enterprise
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"git.u8t.cn/open/goutil"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ApprovalProfitAmountTypeCost = "消耗"
|
||||||
|
ApprovalProfitAmountTypeProfit = "利润"
|
||||||
|
ApprovalProfitAmountTypeAward = "奖励"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ApprovalProfitCreate struct {
|
||||||
|
SpNo string `json:"sp_no"` //申请单号,相同的单号数据将会被替换
|
||||||
|
Month string `json:"month"` //业绩对应月份
|
||||||
|
Username string `json:"username"` //业绩对应责任人
|
||||||
|
AmountType string `json:"amount_type"` //业绩类型
|
||||||
|
Amount string `json:"amount"` //业绩金额 单位元
|
||||||
|
Description string `json:"description"` //业绩描述
|
||||||
|
AppId string `json:"app_id"` //业绩对应的业务ID
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApprovalProfit struct {
|
||||||
|
Enterprise
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApprovalProfit(baseUrl, token string) *ApprovalProfit {
|
||||||
|
return &ApprovalProfit{
|
||||||
|
Enterprise: Enterprise{
|
||||||
|
baseUrl: baseUrl,
|
||||||
|
token: token,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ApprovalProfit) Create(req *ApprovalProfitCreate) error {
|
||||||
|
var reqBody string
|
||||||
|
reqBody = goutil.EncodeJSON(req)
|
||||||
|
reqUrl := e.GetBaseUrl() + "/ext/approval/profit"
|
||||||
|
|
||||||
|
body, err := goutil.HttpPost(reqUrl, e.GetHeader(), []byte(reqBody))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
g := gjson.ParseBytes(body)
|
||||||
|
if g.Get("code").Int() != 0 {
|
||||||
|
return errors.New(string(body))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package enterprise
|
||||||
|
|
||||||
|
type Enterprise struct {
|
||||||
|
token string
|
||||||
|
baseUrl string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Enterprise) GetHeader() map[string]string {
|
||||||
|
return map[string]string{
|
||||||
|
"x-token": e.token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Enterprise) GetBaseUrl() string {
|
||||||
|
if e.baseUrl != "" {
|
||||||
|
return e.baseUrl
|
||||||
|
}
|
||||||
|
return "http://e.batiao8.com"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package enterprise
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"git.u8t.cn/open/goutil"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StaffTarget struct {
|
||||||
|
Enterprise
|
||||||
|
}
|
||||||
|
|
||||||
|
type StaffTargetCreate struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Month string `json:"month"`
|
||||||
|
Day string `json:"day"`
|
||||||
|
Score string `json:"score"`
|
||||||
|
Comment string `json:"comment"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStaffTarget(baseUrl, token string) *StaffTarget {
|
||||||
|
return &StaffTarget{
|
||||||
|
Enterprise: Enterprise{
|
||||||
|
baseUrl: baseUrl,
|
||||||
|
token: token,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *StaffTarget) Create(req *StaffTargetCreate) error {
|
||||||
|
reqUrl := e.GetBaseUrl() + "/ext/staff/target"
|
||||||
|
body, err := goutil.HttpPost(reqUrl, e.GetHeader(), []byte(goutil.EncodeJSON(req)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
g := gjson.ParseBytes(body)
|
||||||
|
if g.Get("code").Int() != 0 {
|
||||||
|
return errors.New(string(body))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
package enterprise
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.u8t.cn/open/goutil"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
corpId = 1000
|
||||||
|
)
|
||||||
|
|
||||||
|
type VerifyCode struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Timestamp string `json:"timestamp"`
|
||||||
|
}
|
||||||
|
type StaffInfo struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Realname string `json:"realname"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
}
|
||||||
|
type StaffUser struct {
|
||||||
|
Enterprise
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStaffUser(baseUrl, token string) *StaffUser {
|
||||||
|
return &StaffUser{
|
||||||
|
Enterprise: Enterprise{
|
||||||
|
baseUrl: baseUrl,
|
||||||
|
token: token,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *StaffUser) SendVerifyCode(username, scene string) (*VerifyCode, error) {
|
||||||
|
var reqBody string
|
||||||
|
reqBody = fmt.Sprintf(`{"username":"%s","scene":"%s"}`, username, scene)
|
||||||
|
reqUrl := e.GetBaseUrl() + "/ext/staff/verify/code"
|
||||||
|
|
||||||
|
body, err := goutil.HttpPost(reqUrl, e.GetHeader(), []byte(reqBody))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
g := gjson.ParseBytes(body)
|
||||||
|
if g.Get("code").Int() != 0 {
|
||||||
|
return nil, errors.New(string(body))
|
||||||
|
}
|
||||||
|
r := new(VerifyCode)
|
||||||
|
r.Timestamp = g.Get("data.timestamp").String()
|
||||||
|
r.Username = g.Get("data.username").String()
|
||||||
|
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *StaffUser) Login(username, timestamp, code string) (*StaffInfo, error) {
|
||||||
|
reqBody := fmt.Sprintf(`{"username":"%s","timestamp":"%s","code":"%s"}`, username, timestamp, code)
|
||||||
|
reqUrl := e.GetBaseUrl() + "/ext/staff/login"
|
||||||
|
body, err := goutil.HttpPost(reqUrl, e.GetHeader(), []byte(reqBody))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
g := gjson.ParseBytes(body)
|
||||||
|
if g.Get("code").Int() != 0 {
|
||||||
|
return nil, errors.New(string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(StaffInfo)
|
||||||
|
r.Realname = g.Get("data.realname").String()
|
||||||
|
r.Username = g.Get("data.username").String()
|
||||||
|
r.Phone = g.Get("data.phone").String()
|
||||||
|
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package erp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"git.u8t.cn/open/goutil"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ApprovalProfitAmountTypeCost = "消耗"
|
||||||
|
ApprovalProfitAmountTypeProfit = "利润"
|
||||||
|
ApprovalProfitAmountTypeAward = "奖励"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ApprovalProfitCreate struct {
|
||||||
|
BizNo string `json:"biz_no"` //申请单号,相同的单号数据将会被替换
|
||||||
|
Month string `json:"month"` //业绩对应月份
|
||||||
|
Username string `json:"username"` //业绩对应责任人
|
||||||
|
AmountType string `json:"amount_type"` //业绩类型
|
||||||
|
Amount string `json:"amount"` //业绩金额 单位元
|
||||||
|
Description string `json:"description"` //业绩描述
|
||||||
|
AppId string `json:"app_id"` //业绩对应的业务ID
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApprovalProfit struct {
|
||||||
|
Erp
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApprovalProfit(baseUrl, token string) *ApprovalProfit {
|
||||||
|
return &ApprovalProfit{
|
||||||
|
Erp: Erp{
|
||||||
|
baseUrl: baseUrl,
|
||||||
|
token: token,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ApprovalProfit) Create(req *ApprovalProfitCreate) error {
|
||||||
|
var reqBody string
|
||||||
|
reqBody = goutil.EncodeJSON(req)
|
||||||
|
reqUrl := e.GetBaseUrl() + "/ext/staff/profit"
|
||||||
|
|
||||||
|
body, err := goutil.HttpPost(reqUrl, e.GetHeader(), []byte(reqBody))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
g := gjson.ParseBytes(body)
|
||||||
|
if g.Get("code").Int() != 0 {
|
||||||
|
return errors.New(string(body))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package erp
|
||||||
|
|
||||||
|
type Erp struct {
|
||||||
|
token string
|
||||||
|
baseUrl string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Erp) GetHeader() map[string]string {
|
||||||
|
return map[string]string{
|
||||||
|
"x-token": e.token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Erp) GetBaseUrl() string {
|
||||||
|
if e.baseUrl != "" {
|
||||||
|
return e.baseUrl
|
||||||
|
}
|
||||||
|
return "http://eapi.batiao8.com"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package erp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"git.u8t.cn/open/goutil"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StaffScore struct {
|
||||||
|
Erp
|
||||||
|
}
|
||||||
|
|
||||||
|
type StaffScoreCreate struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Month string `json:"month"`
|
||||||
|
Day string `json:"day"`
|
||||||
|
Score string `json:"score"`
|
||||||
|
Comment string `json:"comment"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStaffScore(baseUrl, token string) *StaffScore {
|
||||||
|
return &StaffScore{
|
||||||
|
Erp: Erp{
|
||||||
|
baseUrl: baseUrl,
|
||||||
|
token: token,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *StaffScore) Create(req *StaffScoreCreate) error {
|
||||||
|
reqUrl := e.GetBaseUrl() + "/ext/staff/score"
|
||||||
|
body, err := goutil.HttpPost(reqUrl, e.GetHeader(), []byte(goutil.EncodeJSON(req)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
g := gjson.ParseBytes(body)
|
||||||
|
if g.Get("code").Int() != 0 {
|
||||||
|
return errors.New(string(body))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
package erp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.u8t.cn/open/goutil"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LoginTypePassword = "password"
|
||||||
|
LoginTypeVerify = "verify"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StaffCode struct {
|
||||||
|
Timestamp string `json:"timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginReq struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Timestamp string `json:"timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginRsp struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Realname string `json:"realname"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateReq struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StaffUser struct {
|
||||||
|
Erp
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStaffUser(baseUrl, token string) *StaffUser {
|
||||||
|
return &StaffUser{
|
||||||
|
Erp: Erp{
|
||||||
|
baseUrl: baseUrl,
|
||||||
|
token: token,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *StaffUser) SendCode(username, scene string) (*StaffCode, error) {
|
||||||
|
var reqBody string
|
||||||
|
reqBody = fmt.Sprintf(`{"username":"%s","scene":"%s"}`, username, scene)
|
||||||
|
reqUrl := e.GetBaseUrl() + "/ext/staff/user/code"
|
||||||
|
|
||||||
|
body, err := goutil.HttpPost(reqUrl, e.GetHeader(), []byte(reqBody))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
g := gjson.ParseBytes(body)
|
||||||
|
if g.Get("code").Int() != 0 {
|
||||||
|
return nil, errors.New(string(body))
|
||||||
|
}
|
||||||
|
r := new(StaffCode)
|
||||||
|
r.Timestamp = g.Get("data.timestamp").String()
|
||||||
|
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *StaffUser) Login(req *LoginReq) (*LoginRsp, error) {
|
||||||
|
|
||||||
|
var reqBody string
|
||||||
|
|
||||||
|
reqBody = fmt.Sprintf(`{"username":"%s","password":"%s", "timestamp":"%s","type":"%s"}`,
|
||||||
|
req.Username, req.Password, req.Timestamp, req.Type)
|
||||||
|
|
||||||
|
reqUrl := e.GetBaseUrl() + "/ext/staff/user/login"
|
||||||
|
body, err := goutil.HttpPost(reqUrl, e.GetHeader(), []byte(reqBody))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
g := gjson.ParseBytes(body)
|
||||||
|
if g.Get("code").Int() != 0 {
|
||||||
|
return nil, errors.New(string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(LoginRsp)
|
||||||
|
r.Realname = g.Get("data.realname").String()
|
||||||
|
r.Username = g.Get("data.username").String()
|
||||||
|
r.Phone = g.Get("data.phone").String()
|
||||||
|
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *StaffUser) Update(req *UpdateReq) error {
|
||||||
|
var reqBody string
|
||||||
|
|
||||||
|
reqBody = goutil.EncodeJSON(req)
|
||||||
|
|
||||||
|
reqUrl := e.GetBaseUrl() + "/ext/staff/user"
|
||||||
|
body, err := goutil.HttpPut(reqUrl, e.GetHeader(), []byte(reqBody))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
g := gjson.ParseBytes(body)
|
||||||
|
if g.Get("code").Int() != 0 {
|
||||||
|
return errors.New(g.Get("message").String())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
34
go.mod
34
go.mod
|
|
@ -1,9 +1,9 @@
|
||||||
module git.u8t.cn/open/gosdk
|
module git.u8t.cn/open/gosdk
|
||||||
|
|
||||||
go 1.25
|
go 1.25.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.u8t.cn/open/goutil v0.0.0-20251006031723-35e9c33cf3b5
|
git.u8t.cn/open/goutil v0.0.0-20260701172715-c0058361ddcc
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf
|
github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf
|
||||||
github.com/eclipse/paho.mqtt.golang v1.5.1
|
github.com/eclipse/paho.mqtt.golang v1.5.1
|
||||||
github.com/gin-gonic/gin v1.11.0
|
github.com/gin-gonic/gin v1.11.0
|
||||||
|
|
@ -12,13 +12,13 @@ require (
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c
|
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c
|
||||||
github.com/minio/minio-go v6.0.14+incompatible
|
github.com/minio/minio-go v6.0.14+incompatible
|
||||||
github.com/qiniu/go-sdk/v7 v7.25.4
|
github.com/qiniu/go-sdk/v7 v7.21.0
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.4
|
||||||
github.com/spf13/cast v1.10.0
|
github.com/spf13/cast v1.10.0
|
||||||
github.com/tidwall/gjson v1.18.0
|
github.com/tidwall/gjson v1.18.0
|
||||||
github.com/wechatpay-apiv3/wechatpay-go v0.2.21
|
github.com/wechatpay-apiv3/wechatpay-go v0.2.21
|
||||||
golang.org/x/crypto v0.47.0
|
golang.org/x/crypto v0.51.0
|
||||||
gorm.io/gorm v1.31.0
|
gorm.io/gorm v1.31.2
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
@ -29,7 +29,6 @@ require (
|
||||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||||
github.com/fogleman/gg v1.3.0 // indirect
|
github.com/fogleman/gg v1.3.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||||
github.com/gammazero/toposort v0.1.1 // indirect
|
|
||||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||||
github.com/go-ini/ini v1.67.0 // indirect
|
github.com/go-ini/ini v1.67.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
|
@ -45,29 +44,30 @@ require (
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
|
github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
github.com/nxadm/tail v1.4.8 // indirect
|
||||||
github.com/onsi/gomega v1.39.1 // indirect
|
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||||
github.com/quic-go/qpack v0.5.1 // indirect
|
github.com/quic-go/qpack v0.5.1 // indirect
|
||||||
github.com/quic-go/quic-go v0.54.0 // indirect
|
github.com/quic-go/quic-go v0.54.0 // indirect
|
||||||
|
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||||
github.com/speps/go-hashids v2.0.0+incompatible // indirect
|
github.com/speps/go-hashids v2.0.0+incompatible // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
github.com/tidwall/pretty v1.2.0 // indirect
|
github.com/tidwall/pretty v1.2.0 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||||
go.uber.org/mock v0.5.0 // indirect
|
go.uber.org/mock v0.5.0 // indirect
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
golang.org/x/arch v0.20.0 // indirect
|
golang.org/x/arch v0.20.0 // indirect
|
||||||
golang.org/x/image v0.31.0 // indirect
|
golang.org/x/image v0.43.0 // indirect
|
||||||
golang.org/x/mod v0.32.0 // indirect
|
golang.org/x/mod v0.36.0 // indirect
|
||||||
golang.org/x/net v0.49.0 // indirect
|
golang.org/x/net v0.54.0 // indirect
|
||||||
golang.org/x/sync v0.19.0 // indirect
|
golang.org/x/sync v0.21.0 // indirect
|
||||||
golang.org/x/sys v0.40.0 // indirect
|
golang.org/x/sys v0.46.0 // indirect
|
||||||
golang.org/x/text v0.33.0 // indirect
|
golang.org/x/text v0.38.0 // indirect
|
||||||
golang.org/x/tools v0.41.0 // indirect
|
golang.org/x/tools v0.45.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.9 // indirect
|
google.golang.org/protobuf v1.36.9 // indirect
|
||||||
modernc.org/fileutil v1.0.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.u8t.cn/open/gosdk/util"
|
"git.u8t.cn/open/gosdk/util"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"git.u8t.cn/open/goutil"
|
"git.u8t.cn/open/goutil"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
@ -78,7 +78,7 @@ func (g *GetuiSms) Token() string {
|
||||||
return g.token
|
return g.token
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GetuiSms) Send(phone string, data map[string]string) (interface{}, error) {
|
func (g *GetuiSms) Send(phone string, data string) (interface{}, error) {
|
||||||
|
|
||||||
reqUrl := "https://openapi-smsp.getui.com/v1/sps/push_sms_list"
|
reqUrl := "https://openapi-smsp.getui.com/v1/sps/push_sms_list"
|
||||||
params := make(map[string]interface{})
|
params := make(map[string]interface{})
|
||||||
|
|
@ -93,7 +93,7 @@ func (g *GetuiSms) Send(phone string, data map[string]string) (interface{}, erro
|
||||||
log.Errorf("http post [%s] error :%s", string(reqBody), err.Error())
|
log.Errorf("http post [%s] error :%s", string(reqBody), err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fmt.Println(string(reqBody), string(rspBody))
|
|
||||||
_, err = g.getResult(rspBody)
|
_, err = g.getResult(rspBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("get Result error :%s", err.Error())
|
log.Errorf("get Result error :%s", err.Error())
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,10 @@ type MessageRequest struct {
|
||||||
MediaID string `json:"media_id"`
|
MediaID string `json:"media_id"`
|
||||||
} `json:"image"`
|
} `json:"image"`
|
||||||
|
|
||||||
|
Voice struct {
|
||||||
|
MediaID string `json:"media_id"`
|
||||||
|
} `json:"voice"`
|
||||||
|
|
||||||
Video struct {
|
Video struct {
|
||||||
MediaID string `json:"media_id"`
|
MediaID string `json:"media_id"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
|
|
@ -235,6 +239,33 @@ func (a *App) SendImage(receiver []string, meidiaId string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) SendVoice(receiver []string, meidiaId string) error {
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s?access_token=%s", urlQiyeSend, a.GetToken())
|
||||||
|
req := new(MessageRequest)
|
||||||
|
req.MstType = "voice"
|
||||||
|
req.AgentId = a.config.Agent
|
||||||
|
req.ToUser = strings.Join(receiver, "|")
|
||||||
|
req.Voice.MediaID = meidiaId
|
||||||
|
|
||||||
|
data, _ := json.Marshal(req)
|
||||||
|
result, err := util.HttpPostJson(url, nil, data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var rsp BaseResponse
|
||||||
|
err = json.Unmarshal([]byte(result), &rsp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if rsp.ErrCode != 0 {
|
||||||
|
return fmt.Errorf("%d:%s", rsp.ErrCode, rsp.ErrMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) SendVideo(receiver []string, meidiaId, title, desc string) error {
|
func (a *App) SendVideo(receiver []string, meidiaId, title, desc string) error {
|
||||||
|
|
||||||
url := fmt.Sprintf("%s?access_token=%s", urlQiyeSend, a.GetToken())
|
url := fmt.Sprintf("%s?access_token=%s", urlQiyeSend, a.GetToken())
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,21 @@ type ApproveDetailRsp struct {
|
||||||
Info *ApproveDetail `json:"info"`
|
Info *ApproveDetail `json:"info"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VacationQuota struct {
|
||||||
|
Id uint32 `json:"id"`
|
||||||
|
AssignDuration uint32 `json:"assignduration"`
|
||||||
|
UsedDuration uint32 `json:"usedduration"`
|
||||||
|
LeftDuration uint32 `json:"leftduration"`
|
||||||
|
VacationName string `json:"vacationname"`
|
||||||
|
RealAssignDuration uint32 `json:"real_assignduration"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VacationQuotaRsp struct {
|
||||||
|
Errcode int `json:"errcode"`
|
||||||
|
Errmsg string `json:"errmsg"`
|
||||||
|
Lists []*VacationQuota `json:"lists"`
|
||||||
|
}
|
||||||
|
|
||||||
type AppApprove struct {
|
type AppApprove struct {
|
||||||
App
|
App
|
||||||
}
|
}
|
||||||
|
|
@ -165,6 +180,46 @@ func NewAppApprove(cfg *AppConfig) *AppApprove {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (q *AppApprove) GetVacationQuota(userid string) ([]*VacationQuota, error) {
|
||||||
|
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/oa/vacation/getuservacationquota?access_token=%s", q.GetToken())
|
||||||
|
reqParam := map[string]interface{}{
|
||||||
|
"userid": userid,
|
||||||
|
}
|
||||||
|
rspBody, err := util.HttpPostJson(reqUrl, nil, []byte(goutil.EncodeJSON(reqParam)))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if _, err := q.GetResult(rspBody); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var rsp VacationQuotaRsp
|
||||||
|
if err := json.Unmarshal(rspBody, &rsp); err != nil {
|
||||||
|
log.Errorf("get body[%s] json error :%s", string(rspBody), err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return rsp.Lists, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *AppApprove) SetVacationQuota(userid string, vacationId, leftDuration, timeAttr uint32, remarks string) error {
|
||||||
|
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/oa/vacation/setoneuserquota?access_token=%s", q.GetToken())
|
||||||
|
reqParam := map[string]interface{}{
|
||||||
|
"userid": userid,
|
||||||
|
"vacation_id": vacationId,
|
||||||
|
"leftduration": leftDuration,
|
||||||
|
"time_attr": timeAttr,
|
||||||
|
}
|
||||||
|
if remarks != "" {
|
||||||
|
reqParam["remarks"] = remarks
|
||||||
|
}
|
||||||
|
rspBody, err := util.HttpPostJson(reqUrl, nil, []byte(goutil.EncodeJSON(reqParam)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = q.GetResult(rspBody)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (q *AppApprove) GetDetail(spNo string) (*ApproveDetail, error) {
|
func (q *AppApprove) GetDetail(spNo string) (*ApproveDetail, error) {
|
||||||
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovaldetail?access_token=%s", q.GetToken())
|
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovaldetail?access_token=%s", q.GetToken())
|
||||||
reqParam := fmt.Sprintf(`{"sp_no":"%s"}`, spNo)
|
reqParam := fmt.Sprintf(`{"sp_no":"%s"}`, spNo)
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ type QiniuConfig struct {
|
||||||
|
|
||||||
type Qiniu struct {
|
type Qiniu struct {
|
||||||
config *QiniuConfig
|
config *QiniuConfig
|
||||||
|
domains []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewQiniu(cfg *QiniuConfig) Storage {
|
func NewQiniu(cfg *QiniuConfig) Storage {
|
||||||
|
|
@ -137,41 +138,25 @@ func (s *Qiniu) List(objectPrefix string) ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Qiniu) Get(objectName, fileName string) error {
|
func (s *Qiniu) Get(objectName, fileName string) error {
|
||||||
mac := qbox.NewMac(s.config.AK, s.config.SK)
|
s.loadDomains()
|
||||||
cfg := storage.Config{
|
if len(s.domains) <= 0 {
|
||||||
UseHTTPS: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
bucketManager := storage.NewBucketManager(mac, &cfg)
|
|
||||||
|
|
||||||
domains, err := bucketManager.ListBucketDomains(s.config.Bucket)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(domains) <= 0 {
|
|
||||||
return errors.New("bucket no domain")
|
return errors.New("bucket no domain")
|
||||||
}
|
}
|
||||||
url := fmt.Sprintf("http://%s/%s", domains[0].Domain, objectName)
|
url := fmt.Sprintf("http://%s/%s", s.domains[0], objectName)
|
||||||
return Download(url, fileName)
|
return Download(url, fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Qiniu) Url(objectName string, expire time.Duration, https ...bool) string {
|
func (s *Qiniu) Url(objectName string, expire time.Duration, https ...bool) string {
|
||||||
mac := qbox.NewMac(s.config.AK, s.config.SK)
|
mac := qbox.NewMac(s.config.AK, s.config.SK)
|
||||||
cfg := storage.Config{
|
|
||||||
UseHTTPS: false,
|
s.loadDomains()
|
||||||
|
if len(s.domains) <= 0 {
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
bucketManager := storage.NewBucketManager(mac, &cfg)
|
domain := "http://" + s.domains[0]
|
||||||
domains, err := bucketManager.ListBucketDomains(s.config.Bucket)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if len(domains) <= 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
domain := "http://" + domains[0].Domain
|
|
||||||
if len(https) > 0 && https[0] {
|
if len(https) > 0 && https[0] {
|
||||||
domain = "https://" + domains[0].Domain
|
domain = "https://" + s.domains[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
if expire == 0 {
|
if expire == 0 {
|
||||||
|
|
@ -218,6 +203,27 @@ func isQiniuNotFound(err error) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Qiniu) loadDomains() {
|
||||||
|
if len(s.domains) != 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mac := qbox.NewMac(s.config.AK, s.config.SK)
|
||||||
|
cfg := storage.Config{
|
||||||
|
UseHTTPS: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
bucketManager := storage.NewBucketManager(mac, &cfg)
|
||||||
|
domains, err := bucketManager.ListBucketDomains(s.config.Bucket)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.domains = make([]string, 0)
|
||||||
|
for _, domain := range domains {
|
||||||
|
s.domains = append(s.domains, domain.Domain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Qiniu) Fetch(url, objectName string, local ...bool) error {
|
func (s *Qiniu) Fetch(url, objectName string, local ...bool) error {
|
||||||
if len(local) > 0 && local[0] == true {
|
if len(local) > 0 && local[0] == true {
|
||||||
return s.fetchLocal(url, objectName)
|
return s.fetchLocal(url, objectName)
|
||||||
|
|
|
||||||
110
unify/message.go
110
unify/message.go
|
|
@ -3,8 +3,10 @@ package unify
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.u8t.cn/open/gosdk/util"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"git.u8t.cn/open/gosdk/util"
|
||||||
|
"git.u8t.cn/open/goutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
|
|
@ -24,8 +26,20 @@ func NewMessage(addreess string, token string, sender string) *Message {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) Send(receiver, content string) error {
|
func (m *Message) Clone(sender string) *Message {
|
||||||
reqUrl := fmt.Sprintf("%s/admin/message/send?sender=%s&receiver=%s&content=%s", m.address, m.sender, receiver, url.QueryEscape(content))
|
return &Message{
|
||||||
|
address: m.address,
|
||||||
|
token: m.token,
|
||||||
|
sender: sender,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) Send(args ...string) error {
|
||||||
|
return m.SendText(args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) SendMedia(receiver, mediaType, mediaId string) error {
|
||||||
|
reqUrl := fmt.Sprintf("%s/admin/message/send?sender=%s&receiver=%s&type=%s&content=%s", m.address, m.sender, receiver, mediaType, url.QueryEscape(mediaId))
|
||||||
body, err := util.HttpGet(reqUrl, map[string]string{
|
body, err := util.HttpGet(reqUrl, map[string]string{
|
||||||
"x-token": m.token,
|
"x-token": m.token,
|
||||||
})
|
})
|
||||||
|
|
@ -41,3 +55,93 @@ func (m *Message) Send(receiver, content string) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Message) SendText(args ...string) error {
|
||||||
|
var receiver, content, fingerprint, level, count string
|
||||||
|
if len(args) == 2 {
|
||||||
|
receiver, content = args[0], args[1]
|
||||||
|
} else if len(args) == 3 {
|
||||||
|
receiver, content, fingerprint = args[0], args[1], args[2]
|
||||||
|
} else if len(args) == 4 {
|
||||||
|
receiver, content, fingerprint, level = args[0], args[1], args[2], args[3]
|
||||||
|
} else if len(args) > 4 {
|
||||||
|
receiver, content, fingerprint, level, count = args[0], args[1], args[2], args[3], args[4]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build form data
|
||||||
|
formData := url.Values{}
|
||||||
|
formData.Set("sender", m.sender)
|
||||||
|
formData.Set("receiver", receiver)
|
||||||
|
formData.Set("type", "text")
|
||||||
|
formData.Set("fingerprint", fingerprint)
|
||||||
|
formData.Set("count", count)
|
||||||
|
formData.Set("level", level)
|
||||||
|
formData.Set("content", content)
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/admin/message/send", m.address)
|
||||||
|
body, err := util.HttpPostForm(reqUrl, map[string]string{
|
||||||
|
"x-token": m.token,
|
||||||
|
}, formData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var rsp util.Response
|
||||||
|
if err := json.Unmarshal(body, &rsp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if rsp.Code != 0 {
|
||||||
|
return fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) SendMail(receiver, title, content string) error {
|
||||||
|
|
||||||
|
// Build form data
|
||||||
|
formData := url.Values{}
|
||||||
|
formData.Set("sender", m.sender)
|
||||||
|
formData.Set("receiver", receiver)
|
||||||
|
formData.Set("type", "text")
|
||||||
|
formData.Set("title", title)
|
||||||
|
formData.Set("content", content)
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s/admin/message/send", m.address)
|
||||||
|
body, err := util.HttpPostForm(reqUrl, map[string]string{
|
||||||
|
"x-token": m.token,
|
||||||
|
}, formData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var rsp util.Response
|
||||||
|
if err := json.Unmarshal(body, &rsp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if rsp.Code != 0 {
|
||||||
|
return fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) SendTable(receiver string, table *goutil.TableData) error {
|
||||||
|
content := goutil.EncodeJSON(table)
|
||||||
|
reqUrl := fmt.Sprintf("%s/admin/message/send", m.address)
|
||||||
|
reqData := make(map[string]interface{})
|
||||||
|
reqData["type"] = "table"
|
||||||
|
reqData["content"] = content
|
||||||
|
reqData["receiver"] = receiver
|
||||||
|
reqData["sender"] = m.sender
|
||||||
|
|
||||||
|
body, err := util.HttpPostJson(reqUrl, map[string]string{"x-token": m.token},
|
||||||
|
[]byte(goutil.EncodeJSON(reqData)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var rsp util.Response
|
||||||
|
if err := json.Unmarshal(body, &rsp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if rsp.Code != 0 {
|
||||||
|
return fmt.Errorf("%d:%s", rsp.Code, rsp.Message)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,10 @@ import (
|
||||||
|
|
||||||
func TestMessage_Send(t *testing.T) {
|
func TestMessage_Send(t *testing.T) {
|
||||||
|
|
||||||
s := NewMessage("http://u.batiao8.com", "", "alarm")
|
s := NewMessage("http://u.batiao8.com", "c39e1c6e-38f7-422c-a7d1-9e05bf65596f", "batiao-report-mail")
|
||||||
|
|
||||||
mess := make([]string, 0)
|
mess := make([]string, 0)
|
||||||
mess = append(mess, "加发到")
|
mess = append(mess, `abcc`)
|
||||||
mess = append(mess, "asdfasdfadfa")
|
err := s.SendMail("jiangyong@batiao8.com", "测试", strings.Join(mess, "\n"))
|
||||||
mess = append(mess, "@3q452345~!@@#$$%^&*())")
|
|
||||||
err := s.Send("jiangyong", strings.Join(mess, "\n"))
|
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,13 @@ func NewPay(address string, token string) *Pay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Pay) Clone(token string) *Pay {
|
||||||
|
return &Pay{
|
||||||
|
address: p.address,
|
||||||
|
token: token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Pay) CreateOrder(order *CreateOrderReq) (map[string]interface{}, error) {
|
func (p *Pay) CreateOrder(order *CreateOrderReq) (map[string]interface{}, error) {
|
||||||
if order.PayType == "" {
|
if order.PayType == "" {
|
||||||
errors.New("payType is nil")
|
errors.New("payType is nil")
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ type TransferReq struct {
|
||||||
PayChannel string `json:"payChannel"`
|
PayChannel string `json:"payChannel"`
|
||||||
UserId string `json:"userId"`
|
UserId string `json:"userId"`
|
||||||
OutTradeNo string `json:"outTradeNo"`
|
OutTradeNo string `json:"outTradeNo"`
|
||||||
|
Extra map[string]interface{} `json:"extra"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommonResponse struct {
|
type CommonResponse struct {
|
||||||
|
|
|
||||||
23
util/http.go
23
util/http.go
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -72,6 +74,27 @@ func HttpPutJson(link string, header map[string]string, json []byte) ([]byte, er
|
||||||
return io.ReadAll(resp.Body)
|
return io.ReadAll(resp.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HttpPostForm(url string, headers map[string]string, data url.Values) ([]byte, error) {
|
||||||
|
req, err := http.NewRequest("POST", url, strings.NewReader(data.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
for k, v := range headers {
|
||||||
|
req.Header.Set(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
return io.ReadAll(resp.Body)
|
||||||
|
}
|
||||||
|
|
||||||
// Get 请求 link:请求url
|
// Get 请求 link:请求url
|
||||||
func HttpGet(link string, header map[string]string) ([]byte, error) {
|
func HttpGet(link string, header map[string]string) ([]byte, error) {
|
||||||
req, err := http.NewRequest("GET", link, nil)
|
req, err := http.NewRequest("GET", link, nil)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ const (
|
||||||
userPhoneNumberUrl string = "https://api.weixin.qq.com/wxa/business/getuserphonenumber"
|
userPhoneNumberUrl string = "https://api.weixin.qq.com/wxa/business/getuserphonenumber"
|
||||||
getWxACodeUnLimitUrl string = "https://api.weixin.qq.com/wxa/getwxacodeunlimit"
|
getWxACodeUnLimitUrl string = "https://api.weixin.qq.com/wxa/getwxacodeunlimit"
|
||||||
getWxScheme string = "https://api.weixin.qq.com/wxa/generatescheme"
|
getWxScheme string = "https://api.weixin.qq.com/wxa/generatescheme"
|
||||||
|
getWxUrlLink string = "https://api.weixin.qq.com/wxa/generate_urllink"
|
||||||
code2UserinfoUrl string = "https://api.weixin.qq.com/sns/userinfo"
|
code2UserinfoUrl string = "https://api.weixin.qq.com/sns/userinfo"
|
||||||
oaQrCodeCreateUrl string = "https://api.weixin.qq.com/cgi-bin/qrcode/create"
|
oaQrCodeCreateUrl string = "https://api.weixin.qq.com/cgi-bin/qrcode/create"
|
||||||
userInfoByOpenid string = "https://api.weixin.qq.com/cgi-bin/user/info"
|
userInfoByOpenid string = "https://api.weixin.qq.com/cgi-bin/user/info"
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,15 @@ package weixin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"cmp"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/spf13/cast"
|
|
||||||
"github.com/tidwall/gjson"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MpSdk struct {
|
type MpSdk struct {
|
||||||
|
|
@ -151,3 +153,58 @@ func (o *MpSdk) GetScheme(params map[string]interface{}) (string, error) {
|
||||||
}
|
}
|
||||||
return g.Get("openlink").String(), nil
|
return g.Get("openlink").String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *MpSdk) GetEncryptUrl(params map[string]any) (string, error) {
|
||||||
|
newParams := map[string]any{
|
||||||
|
"env_version": cmp.Or(cast.ToString(params["env_version"]), "release"),
|
||||||
|
}
|
||||||
|
if path := cast.ToString(params["path"]); path != "" {
|
||||||
|
newParams["path"] = path
|
||||||
|
}
|
||||||
|
if query := cast.ToString(params["query"]); query != "" {
|
||||||
|
newParams["query"] = query
|
||||||
|
}
|
||||||
|
|
||||||
|
_, hasExpireType := params["expire_type"]
|
||||||
|
_, hasExpireTime := params["expire_time"]
|
||||||
|
_, hasExpireInterval := params["expire_interval"]
|
||||||
|
if hasExpireType {
|
||||||
|
newParams["expire_type"] = cast.ToInt(params["expire_type"])
|
||||||
|
} else if hasExpireInterval {
|
||||||
|
newParams["expire_type"] = 1
|
||||||
|
} else if hasExpireTime {
|
||||||
|
newParams["expire_type"] = 0
|
||||||
|
}
|
||||||
|
if hasExpireTime {
|
||||||
|
newParams["expire_time"] = cast.ToInt64(params["expire_time"])
|
||||||
|
}
|
||||||
|
if hasExpireInterval {
|
||||||
|
newParams["expire_interval"] = cast.ToInt(params["expire_interval"])
|
||||||
|
}
|
||||||
|
|
||||||
|
marshal, err := json.Marshal(newParams)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
accessToken, err := o.getAccessToken()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("%s?access_token=%s", getWxUrlLink, accessToken)
|
||||||
|
res, err := http.Post(url, "application/json", bytes.NewBuffer(marshal))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
body, err := io.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
g := gjson.ParseBytes(body)
|
||||||
|
errcode := g.Get("errcode").Int()
|
||||||
|
if errcode != 0 {
|
||||||
|
return "", fmt.Errorf("%d:%s", errcode, g.Get("errmsg"))
|
||||||
|
}
|
||||||
|
return g.Get("url_link").String(), nil
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue