qq_bot/handler/newbond/service.go

170 lines
4.2 KiB
Go

package newbond
import (
"database/sql"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"git.lxtend.com/qqbot/action"
"git.lxtend.com/qqbot/model"
"git.lxtend.com/qqbot/sqlite3"
"git.lxtend.com/qqbot/util"
)
func init() {
createNewBondListenGroupTableSQL := `
CREATE TABLE IF NOT EXISTS new_bond_listen_group (
group_id INT PRIMARY KEY
);
`
createNewBondInfoTableSQL := `CREATE TABLE BondData (
SecurityCode VARCHAR(10) NOT NULL,
SecuCode VARCHAR(15) NOT NULL,
TradeMarket VARCHAR(10) NOT NULL,
SecurityNameAbbr VARCHAR(50) NOT NULL,
PRIMARY KEY (SecurityCode)
);
`
sqlite3.TryCreateTable(createNewBondListenGroupTableSQL)
sqlite3.TryCreateTable(createNewBondInfoTableSQL)
go RoundCheckNewBond()
}
func GetBondsData() ([]BondData, error) {
url := "https://datacenter-web.eastmoney.com/api/data/v1/get?sortColumns=PUBLIC_START_DATE%2CSECURITY_CODE&sortTypes=-1%2C-1&pageSize=50&pageNumber=1&reportName=RPT_BOND_CB_LIST&columns=ALL&quoteColumns=f2~01~CONVERT_STOCK_CODE~CONVERT_STOCK_PRICE%2Cf235~10~SECURITY_CODE~TRANSFER_PRICE%2Cf236~10~SECURITY_CODE~TRANSFER_VALUE%2Cf2~10~SECURITY_CODE~CURRENT_BOND_PRICE%2Cf237~10~SECURITY_CODE~TRANSFER_PREMIUM_RATIO%2Cf239~10~SECURITY_CODE~RESALE_TRIG_PRICE%2Cf240~10~SECURITY_CODE~REDEEM_TRIG_PRICE%2Cf23~01~CONVERT_STOCK_CODE~PBV_RATIO&quoteType=0&source=WEB&client=WEB"
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("status code %d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var apiResponse BondResponse
err = json.Unmarshal(body, &apiResponse)
if err != nil {
return nil, err
}
return apiResponse.Result.Data, nil
}
func AddGroupListen(groupID int) error {
tx, err := sqlite3.GetTran()
if err != nil {
return err
}
defer tx.Rollback()
tx.Exec("INSERT INTO new_bond_listen_group (group_id) VALUES (?)", groupID)
if err := tx.Commit(); err != nil {
return err
}
return nil
}
func RemoveGroupListen(groupID int) error {
tx, err := sqlite3.GetTran()
if err != nil {
return err
}
defer tx.Rollback()
tx.Exec("DELETE FROM new_bond_listen_group WHERE group_id = ?", groupID)
if err := tx.Commit(); err != nil {
return err
}
return nil
}
func BondDataExists(securityCode string) (bool, error) {
db := sqlite3.GetDB()
var count int
if err := db.Get(&count, "SELECT COUNT(*) FROM BondData WHERE SecurityCode = ?", securityCode); err != nil {
return false, err
}
return count > 0, nil
}
func AddBondData(data BondData) error {
tx, err := sqlite3.GetTran()
if err != nil {
return err
}
defer tx.Rollback()
query := `INSERT INTO BondData (
SecurityCode, SecuCode, TradeMarket, SecurityNameAbbr
) VALUES (
:SecurityCode, :SecuCode, :TradeMarket, :SecurityNameAbbr
)`
_, err = tx.NamedExec(query, data)
if err != nil {
return err
}
if err := tx.Commit(); err != nil {
return err
}
return nil
}
func GetGroupListens() ([]int, error) {
db := sqlite3.GetDB()
var groupIDs []int
if err := db.Select(&groupIDs, "SELECT group_id FROM new_bond_listen_group"); err != nil && err != sql.ErrNoRows {
return nil, err
}
return groupIDs, nil
}
func RoundCheckNewBond() {
time.Sleep(5 * time.Second)
for !action.ActionManager.Started() {
time.Sleep(5 * time.Second)
}
// once := true
util.AddCycleTask("checkNewBond", 5*time.Minute, 5*time.Minute, func() {
bonds, err := GetBondsData()
if bonds == nil || err != nil {
fmt.Println("Error getting bonds data:", err)
return
}
groups, err := GetGroupListens()
if err != nil {
fmt.Println("Error getting group listens:", err)
return
}
for _, bond := range bonds {
exists, err := BondDataExists(bond.SecurityCode)
if err != nil {
fmt.Println("Error checking bond data exists:", err)
return
}
if !exists {
for _, group := range groups {
msg := model.Reply{
ReplyMsg: fmt.Sprintf("号外号外,%s开始申购了", bond.SecurityNameAbbr),
ReferOriginMsg: false,
FromMsg: model.Message{
GroupInfo: model.GroupInfo{
GroupId: int64(group),
},
},
}
action.ActionManager.SendMsg(msg)
}
}
AddBondData(bond)
}
})
}