Commit 4bf1f194 by zhangjiec

1. 增加部分接口

parent 0829c0f2
set GOOS=linux
swag init
go build -o dcGoServer1 -ldflags "-w -s" main.go
\ No newline at end of file
......@@ -5,7 +5,7 @@ import (
"time"
)
/*********************************************************全国行政区域**/
// ProvinceMap /*********************************************************全国行政区域**/------------------------OK
var ProvinceMap []DistrictStruct // 省份列表[]District
var CityMap sync.Map // 城市列表map[uint32][]District //省份ID作为KEY
var CountyMap sync.Map // 区县列表map[uint32][]District //城市ID作为KEY
......@@ -15,14 +15,21 @@ type DistrictStruct struct {
Initial string `json:"initial" example:"S"`
}
/******************************************************区域(校区)**/
// CountyAreaMap /******************************************************************区县学校列表**/
var CountyAreaMap sync.Map //map[uint32][[]uint32] 区县ID作为KEY,[]area_id 作为Value
// TestAreaMap /******************************************************************测试校区列表**/
// AreaMap /******************************************************区域(校区)**/
var AreaMap sync.Map //area_id 作为KEY AreaStruct 作为VALUE
type AreaStruct struct { // AreaStruct 区域信息缓存,通过区域ID查出,后续再加支付信息
Name string
Loc []uint32
CountyID uint32
Status uint8 //校区状态 0 不展示 1展示 2测试校区
CreatAt time.Time
Name string
Longitude uint32
Latitude uint32
CountyID uint32
AreaService []uint32
Status uint8 //校区状态 0 不展示 1展示 2测试校区
// CreatAt time.Time
}
/*********************************************************代理商**/
......@@ -46,7 +53,7 @@ type AreaServiceStruct struct { //
ServiceID uint8 //服务项目 1公话 2定位 3饮水 4POS .........
OperatorID uint32 //运营商ID
Name string //服务名字(例宿舍135栋饮水)name
Status uint8 //状态 0无服务1暂停10正式11测试
Status uint8 //状态 0无内容1正式2测试3暂停4暂未开放
}
/*---------------------------------------------------------------*/
......@@ -55,7 +62,7 @@ type AreaServiceStruct struct { //
var adminMap sync.Map //后台管理用户 LoginAccount(string) 作为KEY
type AdminStruct struct {
Password [16]byte
tokenCreatTime int64
tokenCreatTime int64 // 初始化为0,则已有的token还有效
Name string
upAdminID uint32
//Phone string
......@@ -73,38 +80,41 @@ type RoleAuthStruct struct {
MenuRole map[uint32][]uint32 // 菜单、按钮权限
}
/***************************************************微信用户(家长)**/
var wechatCustomerMap sync.Map //微信的WechatUnionID(string)作为KEY
/***************************************************微信用户(家长)**/ //------------------------OK
var WechatCustomerUnionIDToIDMAP sync.Map // UnionID作为KEY(string),微信用户ID作为VALUE(uint32)
var WechatCustomerMap sync.Map // 微信的WechatUserID(uint32)作为KEY
type WechatCustomerStruct struct {
tokenCreatTime uint32
testRole uint8 // 测试用户(可看到测试校区)
wePhone string //
nickname string //微信昵称
masterCardUserID []uint32 //自己创建的学生用户
slaveCardUserID []uint32 //被邀请查看的学生用户
TokenCreatTime int64
TestRole bool // 测试用户(可看到测试校区)
WePhone string // 手机号
Nickname string // 微信昵称
AvatarURL string // 头像链接
MasterCardUserID []uint32 // 自己创建的学生用户
SlaveCardUserID []uint32 // 被邀请查看的学生用户
}
/****************************************************************/
/***************************************************卡用户(学生、教师、职工)**/
var cardUserMap sync.Map //卡用户 CardUserID卡用户ID(uint32) 作为KEY 纯卡用户可以不绑定微信
var CardUserMap sync.Map //卡用户 CardUserID卡用户ID(uint32) 作为KEY 纯卡用户可以不绑定微信
type CardUserType struct {
MasterWechatUnionID string
SlaveWechatUnionID []string
ShareCode string
Role uint8 //角色0学生,1教师,2职工,default0
AreaID uint32
Name string
Sex bool //false女 true男
MasterWechatUserID uint32
SlaveWechatUserID []uint32
Role uint8 //角色0学生,1教师,2职工,default0
AreaID uint32
Name string
Sex uint8 //0,无信息,1女,2男
// Birthday
Grade uint8
Class uint8
StudentNo string
Grade int8
Class int8
StuNum string
PhoneAreaServiceID uint32
LocationAreaServiceID uint32
WaterAreaServiceID uint32
PosAreaServiceID uint32
Recharge bool //是否充过值
//PhoneAreaServiceID uint32
//LocationAreaServiceID uint32
//WaterAreaServiceID uint32
//PosAreaServiceID uint32
SimCardID string
LocationCardID uint32
......@@ -140,40 +150,7 @@ type FamilyOnePerson struct {
/*---------------------------------------------------------------*/
///********************************************************Sim卡信息(允许一卡多校区使用)**/
//var simInfoMap sync.Map //card_id 作为KEY
//type SimInfoStruct struct {
// Status int8 //0没得这个数据 1 正常使用 其他各种异常
// MonthTalkMinutes uint16
// MonthPackageMinutes uint16
// AreaFamilyNum []sync.Map //area_id为KEY , []familyOnePerson 为 VALUE
//}
//type FamilyOnePerson struct {
// Phone string
// Nickname string
//}
///*---------------------------------------------------------------*/
///*******************************************************定位设备**/
//var phone20DeviceMap sync.Map //device_id 作为KEY DeviceStruct 作为VALUE
//type Phone20DeviceStruct struct {
// AreaID int32
// AllowCallTime uint8 //允许通话时长,255表示不限制时长
// Status bool
//}
///*---------------------------------------------------------------*/
//
//
///*******************************************************饮水设备**/
//var phone20DeviceMap sync.Map //device_id 作为KEY DeviceStruct 作为VALUE
//type Phone20DeviceStruct struct {
// AreaID int32
// AllowCallTime uint8 //允许通话时长,255表示不限制时长
// Status bool
//}
///*---------------------------------------------------------------*/
/***************************************************卡用户(学生、教师、职工)**/
/***************************************************卡用户动态**/
var cardUserTrendMap sync.Map //卡用户 CardUserID卡用户ID(uint32) 作为KEY,[]CardUserTrendType作为VALUE
type CardUserTrendType struct {
ServiceType uint8 //服务项目 UI图标及颜色等
......@@ -186,11 +163,12 @@ type CardUserTrendType struct {
func Init() {
initBCityMaps() // 初始化行政区域省市区缓存
initAreaMap()
initAreaMapAndCountyAreaMap()
initWechatCustomerMap()
initCardUserMap()
//initAdminMap()
//initOperatorMap()
//initWechatCustomerMap()
//initCardUserMap()
//initAreaServiceMap()
//initPhone20DeviceMap()
//initSimFamilyNumMap()
......
package cache
import (
"dc_golang_server_1/dbmodel"
"dc_golang_server_1/logger"
"fmt"
"go.uber.org/zap"
"log"
"time"
)
//id integer NOT NULL DEFAULT nextval('b_area_id_seq'::regclass),
//county_id integer,
//name character varying(32) COLLATE pg_catalog."default",
//longitude integer,
//latitude integer,
//status smallint,
//creator_id integer,
//updater_id integer,
//create_at timestamp without time zone,
//update_at timestamp without time zone,
//CONSTRAINT b_area_pkey PRIMARY KEY (id),
//CONSTRAINT b_area_uniq1 UNIQUE (name)
func initAreaMapAndCountyAreaMap() {
fmt.Println(time.Now(), "cache: initAreaMap begin")
var areaID uint32
var temp AreaStruct
rows, err := dbmodel.PgDb.Query("SELECT id,county_id,name,longitude,latitude,status FROM b_area") //
defer rows.Close()
if err != nil {
log.Panicln("SelectAreaToMap rows", err)
}
for rows.Next() {
err = rows.Scan(&areaID, &temp.CountyID, &temp.Name, &temp.Longitude, &temp.Latitude, &temp.Status)
if err != nil {
log.Panicln("SelectAreaToMap rows.Scan", err)
}
fmt.Println(areaID, temp)
AreaMap.Store(areaID, temp)
if temp.CountyID != 0 {
var areaIDList []uint32
if v, ok := CountyAreaMap.Load(temp.CountyID); ok {
areaIDList, _ = v.([]uint32)
}
areaIDList = append(areaIDList, areaID)
CountyAreaMap.Store(temp.CountyID, areaIDList)
fmt.Println(temp.CountyID, areaIDList)
}
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
log.Panicln(time.Now(), "initAreaMap rows.Err()", err)
}
fmt.Println(time.Now(), "cache: initAreaMap OK")
}
func GetAreaMapName(areaID uint32, test bool) string {
if v, ok := AreaMap.Load(areaID); ok {
if data, ok := v.(AreaStruct); ok {
if data.Status == 1 || (data.Status == 2 && test) {
return data.Name
}
} else {
AreaMap.Delete(areaID)
logger.Log.Error("AreaMap 类型断言错误",
zap.String("Src", "GetAreaMapName"),
zap.Uint32("areaID", areaID))
}
} else {
logger.Log.Error("AreaMap 没数据",
zap.String("Src", "GetAreaMapName"),
zap.Uint32("areaID", areaID))
}
// todo 查库
return ""
}
func GetAreaMapInfo(areaID uint32, info *AreaStruct) bool {
if v, ok := AreaMap.Load(areaID); ok {
if *info, ok = v.(AreaStruct); ok {
return true
} else {
AreaMap.Delete(areaID)
logger.Log.Error("AreaMap 类型断言错误",
zap.String("Src", "GetAreaMapInfo"),
zap.Uint32("areaID", areaID))
return false
}
} else {
logger.Log.Error("AreaMap 没数据",
zap.String("Src", "GetAreaMapInfo"),
zap.Uint32("areaID", areaID))
}
// todo 查库
return false
}
......@@ -36,10 +36,17 @@ func initAreaServiceMap() {
}
}
func GetAreaServiceInfo(areaServiceID uint32) AreaServiceStruct {
func GetAreaServiceInfo(areaServiceID uint32) (areaServiceInfo AreaServiceStruct) {
if info, ok := areaServiceMap.Load(areaServiceID); ok { //map有
if v, ok2 := info.(AreaServiceStruct); ok2 { //类型断言正确
return v //,true
if areaServiceInfo, ok = info.(AreaServiceStruct); ok { //类型断言正确
if areaServiceInfo.Status == 0 {
areaServiceMap.Delete(areaServiceID)
logger.Log.Error("areaServiceMap areaServiceInfo.Status == 0",
zap.Uint32("areaServiceID", areaServiceID),
zap.String("src", "GetAreaServiceInfo"))
} else {
return areaServiceInfo
}
} else { //类型断言失败
areaServiceMap.Delete(areaServiceID)
logger.Log.Error("areaServiceMap 类型断言错误",
......@@ -47,26 +54,26 @@ func GetAreaServiceInfo(areaServiceID uint32) AreaServiceStruct {
zap.String("src", "GetAreaServiceInfo"))
}
}
var temp AreaServiceStruct
var err error
for i := 0; i < 100; i++ {
for i := 0; i < 10; i++ {
err = dbmodel.PgDb.QueryRow("SELECT name,status FROM b_area WHERE id=$1",
areaServiceID).Scan(&temp.Name, &temp.Status) //todo
areaServiceID).Scan(&areaServiceInfo.Name, &areaServiceInfo.Status) //todo
if err != nil {
fmt.Println("GetAreaInfo SELECT:", i, err)
time.Sleep(3 * time.Millisecond)
continue
}
areaServiceMap.Store(areaServiceID, temp)
areaServiceMap.Store(areaServiceID, areaServiceInfo)
logger.Log.Error("数据库有而缓存没有 areaServiceMap",
zap.Uint32("areaServiceID", areaServiceID),
zap.Error(err),
zap.String("src", "GetAreaServiceInfo"))
return temp //,true
return
}
logger.Log.Error("GetAreaServiceInfo SELECT operator_id,status FROM b_area WHERE id=$1", //todo
zap.Uint32("areaServiceID", areaServiceID),
zap.Error(err),
zap.String("src", "GetAreaServiceInfo"))
return temp //,false
return
}
package cache
import (
"dc_golang_server_1/dbmodel"
"fmt"
"log"
"time"
)
func initAreaMap() {
fmt.Println(time.Now(), "cache: initAreaMap begin")
var areaID uint32
var temp AreaStruct
rows, err := dbmodel.PgDb.Query("SELECT id,county_id,name,location,status,create_at FROM b_area") //
defer rows.Close()
if err != nil {
log.Panicln("SelectAreaToMap rows", err)
}
var test2 string
for rows.Next() {
err = rows.Scan(&areaID, &temp.CountyID, &temp.Name, &test2, &temp.Status, &temp.CreatAt) //todo 它娘的location这个POINT取不来,咋个是string哦
if err != nil {
log.Panicln("SelectAreaToMap rows.Scan", err)
}
AreaMap.Store(areaID, temp)
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
log.Panicln(time.Now(), "initAreaMap rows.Err()", err)
}
fmt.Println(time.Now(), "cache: initAreaMap OK")
}
......@@ -11,21 +11,13 @@ import (
)
// 初始化行政区域缓存
//var ProvinceMap []District // 省份列表[]District
//var CityMap sync.Map // 城市列表map[uint32][]District //省份ID作为KEY
//var CountyMap sync.Map // 区县列表map[uint32][]District //城市ID作为KEY
//type DistrictStruct struct {
// Id uint32 `json:"id" example:"1"`
// Name string `json:"name" example:"四川省"`
// Initial string `json:"initial" example:"S"`
//}
func initBCityMaps() {
fmt.Println(time.Now(), "cache: initBCityMaps begin")
go func() bool {
ProvinceMap = []DistrictStruct{} //先清空原来的缓存
var temp DistrictStruct
rows, err := dbmodel.PgDb.Query("SELECT id,name,initial FROM b_city WHERE level=1 ORDER BY sort")
rows, err := dbmodel.PgDb.Query("SELECT id,name,initial FROM b_city WHERE level=1 ORDER BY initial,sort")
defer rows.Close()
if err != nil {
log.Panicln("ProvinceMap SELECT b_city rows", err)
......@@ -58,7 +50,7 @@ func selectToDistrictMap(level uint8, tempMap *sync.Map) bool {
var parentID uint32
var temp DistrictStruct
rows, err := dbmodel.PgDb.Query("SELECT id,name,parent_id,initial FROM b_city WHERE level=$1 ORDER BY sort", level)
rows, err := dbmodel.PgDb.Query("SELECT id,name,parent_id,initial FROM b_city WHERE level=$1 ORDER BY initial,sort", level)
defer rows.Close()
if err != nil {
log.Panicln("SELECT b_city rows", err, level)
......
......@@ -10,32 +10,33 @@ import (
)
//id integer NOT NULL DEFAULT nextval('u_card_user_id_seq'::regclass),
//role smallint DEFAULT 0,
//role smallint 角色:0学生,1教师,2职工
//name character varying(16) COLLATE pg_catalog."default",
//sex boolean,
//sex smallint,
//area_id integer,
//grade smallint,
//class smallint,
//student_num character varying(32) COLLATE pg_catalog."default",
//create_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
//update_at timestamp without time zone
//first_topup_at timestamp without time zone,
func initCardUserMap() {
fmt.Println(time.Now(), "cache: initCardUserMap begin")
var cardUserID uint32
var temp CardUserType
rows, err := dbmodel.PgDb.Query("SELECT id,role,name,sex,area_id,grade,class,student_num,we_uid,share_code FROM u_card_user") //
rows, err := dbmodel.PgDb.Query("SELECT id,role,name,sex,area_id,grade,class,student_num,first_topup_at is not null FROM u_card_user") //
defer rows.Close()
if err != nil {
log.Panicln("Select u_card_user To Map rows", err)
}
for rows.Next() {
err = rows.Scan(&cardUserID, &temp.Role, &temp.Name, &temp.Sex, &temp.AreaID, &temp.Grade, &temp.Class, &temp.StudentNo, &temp.MasterWechatUnionID, &temp.ShareCode)
err = rows.Scan(&cardUserID, &temp.Role, &temp.Name, &temp.Sex, &temp.AreaID, &temp.Grade, &temp.Class, &temp.StuNum, &temp.Recharge)
if err != nil {
log.Panicln("SelectAreaToMap rows.Scan", err)
log.Panicln("initCardUserMap rows.Scan", err)
}
AreaMap.Store(cardUserID, temp)
fmt.Println(cardUserID, temp)
CardUserMap.Store(cardUserID, temp)
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
......@@ -47,24 +48,21 @@ func initCardUserMap() {
fmt.Println(time.Now(), "cache: initCardUserMap OK")
}
func CreatNewCardUser(newUser CardUserType) {
}
func GetCardUserInfo(cardUserID uint32) CardUserType {
if s, ok := cardUserMap.Load(cardUserID); ok { // map有
func GetCardUserInfo(cardUserID uint32) (CardUserType, bool) {
if s, ok := CardUserMap.Load(cardUserID); ok { // map有
if v, ok4 := s.(CardUserType); ok4 { //类型断言正确
return v
return v, true
} else { //类型断言失败
cardUserMap.Delete(cardUserID)
logger.Log.Error("cardUserMap 类型断言错误",
CardUserMap.Delete(cardUserID)
logger.Log.Error("CardUserMap 类型断言错误",
zap.Uint32("cardUserID", cardUserID),
zap.String("src", "GetCardUserInfo"))
}
} else {
// todo logger
}
var temp CardUserType
//
//// todo 再去查一盘库
return temp
// todo 再去查一盘库
return temp, false
}
package cache
import (
"dc_golang_server_1/logger"
"go.uber.org/zap"
)
func GetCountyAreaMap(countyID uint32) ([]uint32, bool) {
var data []uint32
if v, ok := CountyAreaMap.Load(countyID); ok {
if data, ok = v.([]uint32); ok {
return data, true
} else {
logger.Log.Error("CountyAreaMap 类型断言错误",
zap.String("Src", "GetCountyAreaMap"),
zap.Uint32("countyID", countyID))
}
}
logger.Log.Error("CountyAreaMap 没数据",
zap.String("Src", "GetCountyAreaMap"),
zap.Uint32("countyID", countyID))
return data, false
}
package cache
import (
"dc_golang_server_1/dbmodel"
"dc_golang_server_1/logger"
"fmt"
"go.uber.org/zap"
"log"
"strings"
"time"
)
func initWechatCustomerMap() {
fmt.Println(time.Now(), "cache: initWechatCustomerMap begin")
var weUserID uint32
var unionID string
var temp WechatCustomerStruct
// 1. 查u_we_customer表获得基础数据
rows, err := dbmodel.PgDb.Query("SELECT id,unionid,phone,nickname,avatarurl,test_role FROM u_we_customer") //
// defer rows.Close()
if err != nil {
rows.Close()
log.Panicln("SelectWechatCustomerMap rows", err)
}
for rows.Next() {
err = rows.Scan(&weUserID, &unionID, &temp.WePhone, &temp.Nickname, &temp.AvatarURL, &temp.TestRole)
if err != nil {
rows.Close()
log.Panicln("SelectWechatCustomerMap rows.Scan", err)
}
if len(unionID) > 0 {
WechatCustomerUnionIDToIDMAP.Store(unionID, weUserID)
WechatCustomerMap.Store(weUserID, temp)
}
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
rows.Close()
log.Panicln(time.Now(), "initWechatCustomerMap rows.Err()", err)
}
rows.Close()
// 2. 查家长学生对应关系表u_we_card_user表,获得绑定的学生数据
rows, err = dbmodel.PgDb.Query("SELECT we_user_id,card_user_id,master FROM u_we_card_user order by create_at") //
defer rows.Close()
if err != nil {
log.Panicln("Select u_we_card_user rows", err)
}
var cUserID uint32
var master bool
for rows.Next() {
err = rows.Scan(&weUserID, &cUserID, &master)
if err != nil {
log.Panicln("Select u_we_card_user rows.Scan", err)
}
if master {
if v, ok := WechatCustomerMap.Load(weUserID); ok {
if value, ok := v.(WechatCustomerStruct); ok {
value.MasterCardUserID = append(value.MasterCardUserID, cUserID)
WechatCustomerMap.Store(weUserID, value)
} else {
logger.Log.Error("u_we_card_user 表中的 we_user_id,在wechatCustomerMap类型断言错误",
zap.Uint32("weUserID", weUserID),
zap.Uint32("cUserID", cUserID),
zap.Bool("master", master),
zap.String("src", "initWechatCustomerMap"))
}
} else {
logger.Log.Error("u_we_card_user 表中的 we_user_id,在u_we_customer表中没有",
zap.Uint32("weUserID", weUserID),
zap.Uint32("cUserID", cUserID),
zap.Bool("master", master),
zap.String("src", "initWechatCustomerMap"))
}
} else {
if v, ok := WechatCustomerMap.Load(weUserID); ok {
if value, ok := v.(WechatCustomerStruct); ok {
value.SlaveCardUserID = append(value.SlaveCardUserID, cUserID)
WechatCustomerMap.Store(weUserID, value)
} else {
logger.Log.Error("u_we_card_user 表中的 we_user_id,在wechatCustomerMap类型断言错误",
zap.Uint32("weUserID", weUserID),
zap.Uint32("cUserID", cUserID),
zap.Bool("master", master),
zap.String("src", "initWechatCustomerMap"))
}
} else {
logger.Log.Error("u_we_card_user 表中的 we_user_id,在u_we_customer表中没有",
zap.Uint32("weUserID", weUserID),
zap.Uint32("cUserID", cUserID),
zap.Bool("master", master),
zap.String("src", "initWechatCustomerMap"))
}
}
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
log.Panicln(time.Now(), "Select u_we_card_user rows.Err()", err)
}
fmt.Println(time.Now(), "cache: initWechatCustomerMap OK")
}
func GetWechatCustomerTokenCreatTime(weUserID uint32) int64 {
var data WechatCustomerStruct
if v, ok := WechatCustomerMap.Load(weUserID); ok {
if data, ok = v.(WechatCustomerStruct); ok {
return data.TokenCreatTime //正常情况
} else {
logger.Log.Error("WechatCustomerMap 类型断言错误",
zap.String("Src", "GetWechatCustomerTokenCreatTime"),
zap.Uint32("userID", weUserID))
}
} else {
logger.Log.Error("WechatCustomerMap 没数据",
zap.String("Src", "GetWechatCustomerTokenCreatTime"),
zap.Uint32("userID", weUserID))
}
return 0x7fffffffffffffff //没有这个用户
}
func GetWechatCustomerTestRole(userID uint32) (bool, bool) {
var data WechatCustomerStruct
if v, ok := WechatCustomerMap.Load(userID); ok {
if data, ok = v.(WechatCustomerStruct); ok {
return data.TestRole, true //正常情况
} else {
logger.Log.Error("WechatCustomerMap 类型断言错误",
zap.String("Src", "GetWechatCustomerTestRole"),
zap.Uint32("userID", userID))
}
} else {
logger.Log.Error("WechatCustomerMap 没数据",
zap.String("Src", "GetWechatCustomerTestRole"),
zap.Uint32("userID", userID))
}
if selectDBWechatCustomerByUserIDToCache(userID, &data) {
return data.TestRole, true
}
return false, false
}
func GetWechatCustomerCardUserID(unionID string) []uint32 {
return nil
func GetWechatCustomerUserIDByUnionID(unionID string) uint32 {
if v, ok := WechatCustomerUnionIDToIDMAP.Load(unionID); ok {
if userID, ok := v.(uint32); ok {
return userID
}
}
return 0
}
func GetWechatCustomerTokenCreatTime(unionID string) int64 {
return 0x7fffffffffffffff
func GetWechatCustomerInfoAndCanUpdateTokenTime(weUserID uint32, newTime int64) (WechatCustomerStruct, bool) {
var data WechatCustomerStruct
if v, ok := WechatCustomerMap.Load(weUserID); ok {
if data, ok = v.(WechatCustomerStruct); ok {
if newTime != 0 {
data.TokenCreatTime = newTime
WechatCustomerMap.Store(weUserID, data)
}
return data, true //正常的话就该这里
} else {
logger.Log.Error("WechatCustomerMap 类型断言错误",
zap.String("Src", "GetWechatCustomerInfo"),
zap.Uint32("weUserID", weUserID))
// todoN 考虑查一遍库
}
} else {
logger.Log.Error("WechatCustomerMap 没数据",
zap.String("Src", "GetWechatCustomerInfo"),
zap.Uint32("weUserID", weUserID))
}
data.TokenCreatTime = newTime
if selectDBWechatCustomerByUserIDToCache(weUserID, &data) {
return data, true
}
return data, false
}
func SetWechatCustomerTokenCreatTime(unionID string, newTime int64) bool {
func InsertWechatCustomerMap(unionID string, userInfo *WechatCustomerStruct) uint32 {
var err error
//var res sql.Result
var id uint32
for i := 0; i < 10; i++ {
err = dbmodel.PgDb.QueryRow("INSERT INTO u_we_customer(unionid)VALUES($1)RETURNING id", unionID).Scan(&id)
if err == nil {
WechatCustomerUnionIDToIDMAP.Store(unionID, id)
WechatCustomerMap.Store(id, *userInfo)
fmt.Println(id, unionID, *userInfo)
return id // 这里是完全正常的情况
}
if strings.Contains(err.Error(), "duplicate key value") {
logger.Log.Error("InsertWechatCustomerMap unionID Err",
zap.Error(err))
return selectDBWechatCustomerByUnionIDToCache(unionID, userInfo)
}
fmt.Println("InsertWechatCustomerMap Err:", i, unionID, err)
time.Sleep(10 * time.Millisecond)
}
logger.Log.Error("InsertDevCommandErr Err",
zap.Error(err))
return 0
}
func selectDBWechatCustomerByUserIDToCache(userID uint32, userInfo *WechatCustomerStruct) bool {
var unionID string
// 1. 查u_we_customer表获得基础数据
err := dbmodel.PgDb.QueryRow("SELECT unionid,phone,nickname,avatarurl,test_role FROM u_we_customer WHERE id=$1", userID).Scan(
&unionID,
&userInfo.WePhone,
&userInfo.Nickname,
&userInfo.AvatarURL,
&userInfo.TestRole)
if err != nil {
logger.Log.Error("selectDBWechatCustomerByUserIDToCache 错误",
zap.Uint32("userID", userID),
zap.Error(err))
return false
}
// 2. 查u_we_card_user表,获得绑定的学生数据
rows, err := dbmodel.PgDb.Query("SELECT card_user_id,master FROM u_we_card_user WHERE we_user_id=$1 order by create_at", userID)
defer rows.Close()
if err != nil {
logger.Log.Error("selectDBWechatCustomerByUserIDToCache rows 错误",
zap.Uint32("userID", userID),
zap.Error(err))
return false
}
var cUserID uint32
var master bool
userInfo.MasterCardUserID = userInfo.MasterCardUserID[0:0]
userInfo.SlaveCardUserID = userInfo.SlaveCardUserID[0:0]
for rows.Next() {
err = rows.Scan(&cUserID, &master)
if err != nil {
logger.Log.Error("selectDBWechatCustomerByUserIDToCache rows.Scan",
zap.Uint32("userID", userID),
zap.Error(err))
continue
}
if master {
userInfo.MasterCardUserID = append(userInfo.MasterCardUserID, cUserID)
} else {
userInfo.SlaveCardUserID = append(userInfo.SlaveCardUserID, cUserID)
}
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
logger.Log.Error("selectDBWechatCustomerByUserIDToCache rows.Err()",
zap.Uint32("userID", userID),
zap.Error(err))
}
WechatCustomerUnionIDToIDMAP.Store(unionID, userID)
WechatCustomerMap.Store(userID, *userInfo)
return true
}
func selectDBWechatCustomerByUnionIDToCache(unionID string, userInfo *WechatCustomerStruct) (userID uint32) { //返回userID
// 1. 查u_we_customer表获得基础数据
err := dbmodel.PgDb.QueryRow("SELECT id,phone,nickname,avatarurl,test_role FROM u_we_customer WHERE unionid=$1", unionID).Scan(
&userID,
&userInfo.WePhone,
&userInfo.Nickname,
&userInfo.AvatarURL,
&userInfo.TestRole)
if err != nil {
logger.Log.Error("selectDBWechatCustomerByUnionIDToCache 错误",
zap.String("unionID", unionID),
zap.Error(err))
return
}
// 2. 查u_we_card_user表,获得绑定的学生数据
rows, err := dbmodel.PgDb.Query("SELECT card_user_id,master FROM u_we_card_user WHERE we_user_id=$1 order by create_at", userID)
defer rows.Close()
if err != nil {
logger.Log.Error("selectDBWechatCustomerByUnionIDToCache rows 错误",
zap.Uint32("userID", userID),
zap.Error(err))
fmt.Println(err)
return
}
var cUserID uint32
var master bool
userInfo.MasterCardUserID = userInfo.MasterCardUserID[0:0]
userInfo.SlaveCardUserID = userInfo.SlaveCardUserID[0:0]
for rows.Next() {
err = rows.Scan(&cUserID, &master)
if err != nil {
logger.Log.Error("selectDBWechatCustomerByUnionIDToCache rows.Scan",
zap.Uint32("userID", userID),
zap.Error(err))
continue
}
if master {
userInfo.MasterCardUserID = append(userInfo.MasterCardUserID, cUserID)
} else {
userInfo.SlaveCardUserID = append(userInfo.SlaveCardUserID, cUserID)
}
}
// 处理完毕后,需要判断一次遍历过程中是否有错误产生
if err = rows.Err(); err != nil {
logger.Log.Error("selectDBWechatCustomerByUnionIDToCache rows.Err()",
zap.Uint32("userID", userID),
zap.Error(err))
}
WechatCustomerUnionIDToIDMAP.Store(unionID, userID)
WechatCustomerMap.Store(userID, *userInfo)
return
}
// InsertNewStudentIDToWechatCustomerMap 缓存定制方法:微信用户增加/绑定卡用户
func InsertNewStudentIDToWechatCustomerMap(weUserID uint32, cardUserID uint32, master bool) bool {
var data WechatCustomerStruct
if v, ok := WechatCustomerMap.Load(weUserID); ok {
if data, ok = v.(WechatCustomerStruct); ok {
if master {
data.MasterCardUserID = append(data.MasterCardUserID, cardUserID)
} else {
data.SlaveCardUserID = append(data.SlaveCardUserID, cardUserID)
}
WechatCustomerMap.Store(weUserID, data)
return true //正常的话就该这里
} else {
logger.Log.Error("WechatCustomerMap 类型断言错误",
zap.String("Src", "InsertNewStudentIDToWechatCustomerMap"),
zap.Uint32("weUserID", weUserID))
// todoN 考虑查一遍库
}
} else {
logger.Log.Error("WechatCustomerMap 没数据",
zap.String("Src", "InsertNewStudentIDToWechatCustomerMap"),
zap.Uint32("weUserID", weUserID))
}
if selectDBWechatCustomerByUserIDToCache(weUserID, &data) {
return true
}
return false
}
......@@ -7,13 +7,13 @@ import (
)
var PgDb *sql.DB
var stmtUpdateWechatUserLogin *sql.Stmt // 微信登录时间和登录次数更新
var stmtInsertDevHexCommandRecord *sql.Stmt
var stmtInsertDevConnectRecord *sql.Stmt
var stmtInsertDevHexResetRecord *sql.Stmt
// var stmtInsertUCallRecordAndUpdateUSimInfo *sql.Stmt //用事务处理
var stmtInsertUserCardUser *sql.Stmt
func InitDb() {
var err error
// fmt.Println("DBDSN",config.DbDSN)
......@@ -44,17 +44,32 @@ func InitDb() {
////if err != nil {
//// panic("建立stmtUserCallRecord失败:" + err.Error())
////}
//stmtInsertUserCardUser, err = PgDb.Prepare("INSERT INTO u_card_user VALUES($1,$2,$3,$4,$5,$6,$7,$8)")
//if err != nil {
// panic("建立stmtUserCardUser失败:" + err.Error())
//}
// 微信登录时间和登录次数更新
stmtUpdateWechatUserLogin, err = PgDb.Prepare("UPDATE u_we_customer SET login_at=$1,login_count=login_count+1 WHERE id=$2")
if err != nil {
panic("建立stmtUpdateWechatUserLogin失败:" + err.Error())
}
}
func CloseDb() {
_ = stmtInsertDevHexCommandRecord.Close()
_ = stmtInsertDevConnectRecord.Close()
_ = stmtInsertDevHexResetRecord.Close()
//_ = stmtInsertUCallRecordAndUpdateUSimInfo.Close()
_ = stmtInsertUserCardUser.Close()
if stmtUpdateWechatUserLogin != nil { // 微信登录时间和登录次数更新
_ = stmtUpdateWechatUserLogin.Close()
}
if stmtInsertDevHexCommandRecord != nil {
_ = stmtInsertDevHexCommandRecord.Close()
}
if stmtInsertDevConnectRecord != nil {
_ = stmtInsertDevConnectRecord.Close()
}
if stmtInsertDevHexResetRecord != nil {
_ = stmtInsertDevHexResetRecord.Close()
}
//if stmtInsertUCallRecordAndUpdateUSimInfo != nil {
// _ = stmtInsertUCallRecordAndUpdateUSimInfo.Close()
//}
//_ = stmtInsertUserCardUser.Close()
_ = PgDb.Close()
}
......@@ -49,7 +49,7 @@ type TableUserCallRecord struct {
func clearTransaction(tx *sql.Tx) {
err := tx.Rollback()
if err != sql.ErrTxDone && err != nil {
logger.Log.Panic("InsertUCallRecordAndUpdateUSimInfo clearTransaction",
logger.Log.Error("clearTransaction",
zap.Error(err))
}
}
......
package dbmodel
import "time"
import (
"dc_golang_server_1/logger"
"go.uber.org/zap"
)
//CREATE TABLE IF NOT EXISTS public.u_card_user
//(
//id integer NOT NULL DEFAULT nextval('u_card_user_id_seq'::regclass),
//customer_id integer,
//area_id integer,
//name character varying(32) COLLATE pg_catalog."default",
//role smallint 角色:0学生,1教师,2职工
//name character varying(16) COLLATE pg_catalog."default",
//sex smallint,
//birthday date,
//area_id integer,
//grade smallint,
//class smallint,
//student_no character varying(32) COLLATE pg_catalog."default",
//create_at timestamp without time zone,
//update_at timestamp without time zone,
//CONSTRAINT u_card_user_pkey PRIMARY KEY (id)
//)
type TableUserCardUser struct {
Id int32 //integer NOT NULL DEFAULT nextval('u_card_user_id_seq'::regclass),
CustomerId int32 //integer,
AreaId int32 //integer,
Name string //character varying(32) COLLATE pg_catalog."default",
Sex int8 //smallint,
Birthday time.Time
Grade int8 //smallint,
Class int8 //smallint,
StudentNo string //character varying(32) COLLATE pg_catalog."default",
CreateAt time.Time //timestamp without time zone,
UpdateAt time.Time //timestamp without time zone,
//student_num character varying(32) COLLATE pg_catalog."default",
//create_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
//first_topup_at timestamp without time zone,
type InsertTableUserCardUser struct {
Role uint8 `swaggerignore:"true"` // 后台添加选填,学生名字,角色:0学生,1教师,2职工
Name string `json:"name" example:"汤圆"` // 必填,学生名字,maxLen=16
AreaID uint32 `json:"areaID" example:"1"` // 必填,校区ID
Grade int8 `json:"grade"` // 必填,"1~9对应一年级~九年级,10~12对应高一~高三"
Sex uint8 `json:"sex,omitempty"` // 选填,1女2男
Class int8 `json:"class,omitempty"` // 选填,班级,number
StuNum string `json:"stuNum,omitempty"` // 选填,学号,字符串,maxLen=32
}
func InsertUserCardUser(insertData TableUserCardUser) int8 {
_, err := stmtInsertUserCardUser.Exec(
insertData.CustomerId,
insertData.AreaId,
// InsertUserCardUserAndUserWeCardUser 事务处理两张表
func InsertUserCardUserAndUserWeCardUser(insertData InsertTableUserCardUser, weUserID uint32) (cardUserID uint32) {
tx, err := PgDb.Begin()
if err != nil {
logger.Log.Error("InsertUCallRecordAndUpdateUSimInfo PgDb.Begin():",
zap.Error(err))
return
}
defer clearTransaction(tx)
err = tx.QueryRow("INSERT INTO u_card_user(role,name,sex,area_id,grade,class,student_num)VALUES($1,$2,$3,$4,$5,$6,$7)RETURNING id",
insertData.Role,
insertData.Name,
insertData.Sex,
insertData.Birthday,
insertData.AreaID,
insertData.Grade,
insertData.Class,
insertData.StudentNo,
)
if err == nil {
insertData.StuNum,
).Scan(&cardUserID)
if err != nil {
logger.Log.Error("InsertUserCardUserAndUserWeCardUser INSERT u_card_user:",
zap.Error(err))
return
}
_, err = tx.Exec("INSERT INTO u_we_card_user(we_user_id,card_user_id,master)VALUES($1,$2,true)", weUserID, cardUserID)
if err != nil {
logger.Log.Error("InsertUserCardUserAndUserWeCardUser INSERT u_we_card_user:",
zap.Error(err))
return 0
}
return 1 //1
if err = tx.Commit(); err != nil {
logger.Log.Error("InsertUserCardUserAndUserWeCardUser Commit:",
zap.Error(err))
return 0
}
return
}
......@@ -23,6 +23,45 @@ var doc = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/ad/area": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "目前仅用于填充数据,暂未做权限校验",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"管理后台"
],
"summary": "创建一个学校",
"parameters": [
{
"description": "学校信息",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dbmodel.TableBaseArea"
}
}
],
"responses": {
"0": {
"description": "",
"schema": {
"type": "integer"
}
}
}
}
},
"/base/city/{provinceID}": {
"get": {
"security": [
......@@ -34,7 +73,7 @@ var doc = `{
"tags": [
"公用接口"
],
"summary": "通过省份ID获取城市列表",
"summary": "通过省份ID获取城市列表 [complete]",
"parameters": [
{
"type": "integer",
......@@ -68,7 +107,7 @@ var doc = `{
"tags": [
"公用接口"
],
"summary": "通过城市ID获取区县列表",
"summary": "通过城市ID获取区县列表 [complete]",
"parameters": [
{
"type": "integer",
......@@ -102,7 +141,7 @@ var doc = `{
"tags": [
"公用接口"
],
"summary": "根据区县ID获取学校列表",
"summary": "根据区县ID获取学校列表 [complete]",
"parameters": [
{
"type": "integer",
......@@ -119,7 +158,7 @@ var doc = `{
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/v1.countyAreaRes"
"$ref": "#/definitions/api_public.countyAreaRes"
}
}
}
......@@ -137,7 +176,7 @@ var doc = `{
"tags": [
"公用接口"
],
"summary": "根据经纬度获取附近20所学校列表",
"summary": "根据经纬度获取附近20所学校列表 [can test]",
"parameters": [
{
"type": "integer",
......@@ -162,7 +201,7 @@ var doc = `{
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/v1.locationAreaRes"
"$ref": "#/definitions/api_public.locationAreaRes"
}
}
}
......@@ -180,7 +219,7 @@ var doc = `{
"tags": [
"公用接口"
],
"summary": "获取全国省份列表",
"summary": "获取全国省份列表 [complete]",
"responses": {
"0": {
"description": "按首字母排序好的列表,可直接用作展示",
......@@ -208,7 +247,7 @@ var doc = `{
"tags": [
"家长微信"
],
"summary": "获取学生副家长列表及邀请码内容(仅主家长有权限)",
"summary": "获取学生副家长列表(仅主家长有权限)",
"parameters": [
{
"type": "integer",
......@@ -220,9 +259,12 @@ var doc = `{
],
"responses": {
"0": {
"description": "副家长信息列表及邀请码",
"description": "副家长信息列表",
"schema": {
"$ref": "#/definitions/v1.getBindCardUserRes"
"type": "array",
"items": {
"$ref": "#/definitions/api_we.slaveWeUserRes"
}
}
}
}
......@@ -271,7 +313,7 @@ var doc = `{
"tags": [
"家长微信"
],
"summary": "副家长绑定学生",
"summary": "通过邀请码绑定学生",
"parameters": [
{
"type": "string",
......@@ -285,7 +327,83 @@ var doc = `{
"0": {
"description": "学生信息",
"schema": {
"$ref": "#/definitions/v1.bindCardUserRes"
"$ref": "#/definitions/api_we.bindCardUserRes"
}
},
"30": {
"description": "邀请码无效"
},
"31": {
"description": "邀请码已过期"
}
}
}
},
"/we/callrecord/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "传学生ID至后台,后台返回通话记录列表",
"produces": [
"application/json"
],
"tags": [
"家长微信"
],
"summary": "查询通话记录",
"parameters": [
{
"type": "integer",
"description": "学生ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "页数",
"name": "pnum",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "页条数",
"name": "psize",
"in": "query",
"required": true
},
{
"type": "string",
"description": "起始时间 2020-10-10 10:00:00",
"name": "start",
"in": "query"
},
{
"type": "string",
"description": "结束时间 2030-10-10 10:00:00",
"name": "end",
"in": "query"
},
{
"type": "boolean",
"default": false,
"description": "是否升序",
"name": "asc",
"in": "query"
}
],
"responses": {
"0": {
"description": "通话记录列表",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api_we.getCallRecordRes"
}
}
}
}
......@@ -434,7 +552,7 @@ var doc = `{
"tags": [
"家长微信"
],
"summary": "创建一个学生",
"summary": "创建一个学生 [complete]",
"parameters": [
{
"description": "学生信息",
......@@ -442,7 +560,7 @@ var doc = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1.weCreateCardUserReq"
"$ref": "#/definitions/dbmodel.InsertTableUserCardUser"
}
}
],
......@@ -450,7 +568,7 @@ var doc = `{
"0": {
"description": "",
"schema": {
"$ref": "#/definitions/v1.creatCardUserRes"
"$ref": "#/definitions/api_we.creatCardUserRes"
}
}
}
......@@ -488,7 +606,7 @@ var doc = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1.PutCardUserReq"
"$ref": "#/definitions/api_we.PutCardUserReq"
}
}
],
......@@ -528,21 +646,24 @@ var doc = `{
}
}
},
"/we/cardusershareoff/{id}": {
"/we/familynum": {
"put": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "传学生ID至后台,后台返回成功失败",
"description": "修改亲情号接口",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"家长微信"
],
"summary": "关闭邀请码开关(仅主家长有权限)",
"summary": "修改亲情号",
"parameters": [
{
"type": "integer",
......@@ -550,6 +671,22 @@ var doc = `{
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "电话号码",
"name": "phone",
"in": "query",
"required": true
},
{
"description": "亲情号内容",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api_we.familyNumStruct"
}
}
],
"responses": {
......@@ -557,23 +694,65 @@ var doc = `{
"description": ""
}
}
}
},
"/we/cardusershareon/{id}": {
"put": {
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "传学生ID至后台,后台返回成功失败",
"description": "家长绑定亲情号接口",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"家长微信"
],
"summary": "添加亲情号",
"parameters": [
{
"type": "integer",
"description": "学生ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "亲情号内容",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api_we.familyNumStruct"
}
}
],
"responses": {
"0": {
"description": ""
}
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "删除亲情号接口",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"家长微信"
],
"summary": "打开邀请码开关(仅主家长有权限)",
"summary": "删除亲情号",
"parameters": [
{
"type": "integer",
......@@ -581,6 +760,13 @@ var doc = `{
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "电话号码",
"name": "phone",
"in": "query",
"required": true
}
],
"responses": {
......@@ -592,25 +778,27 @@ var doc = `{
},
"/we/login/{code}": {
"post": {
"description": "微信code传至后台,后台返回token,token有效时长:24小时",
"description": "微信code传至后台,后台返回token,token有效时长:48小时",
"tags": [
"家长微信"
],
"summary": "登录",
"summary": "登录 [complete]",
"parameters": [
{
"type": "string",
"description": "用户微信的code",
"name": "code",
"in": "path",
"required": true
"description": "登录信息",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api_we.weLoginReq"
}
}
],
"responses": {
"0": {
"description": "",
"schema": {
"$ref": "#/definitions/v1.weLoginRes"
"$ref": "#/definitions/api_we.weLoginRes"
}
}
}
......@@ -644,7 +832,48 @@ var doc = `{
"0": {
"description": "公话卡状态信息",
"schema": {
"$ref": "#/definitions/v1.getPhoneCardStatusRes"
"$ref": "#/definitions/api_we.getPhoneCardStatusRes"
}
}
}
}
},
"/we/sharecode/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "主家长生成邀请码,有效时长可选1分钟~60分钟",
"produces": [
"application/json"
],
"tags": [
"家长微信"
],
"summary": "获取邀请码(仅主家长有权限)",
"parameters": [
{
"type": "integer",
"description": "学生ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 60,
"description": "有效时长,1~60分钟,不填则为60分钟",
"name": "time",
"in": "query"
}
],
"responses": {
"0": {
"description": "邀请码内容",
"schema": {
"type": "string"
}
}
}
......@@ -674,9 +903,9 @@ var doc = `{
"required": true
},
{
"type": "string",
"description": "副家长微信UnionID",
"name": "unionid",
"type": "integer",
"description": "副家长微信weUserID",
"name": "weUserID",
"in": "query",
"required": true
}
......@@ -688,27 +917,32 @@ var doc = `{
}
}
},
"/we/trend/:id": {
"/we/trend/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "微信学生首页,获取近20条用户最新动态",
"tags": [
"public"
"家长微信"
],
"summary": "微信学生首页,获取近20条用户最新动态",
"parameters": [
{
"type": "string",
"description": "请示参数code",
"name": "code",
"type": "integer",
"description": "学生ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "{\"code\": 200, \"token\": string}",
"description": "学生动态信息",
"schema": {
"type": "string"
"$ref": "#/definitions/api_we.wechatCardUsersTrendType"
}
}
}
......@@ -716,24 +950,37 @@ var doc = `{
}
},
"definitions": {
"cache.DistrictStruct": {
"api_public.countyAreaRes": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"initial": {
"name": {
"type": "string",
"example": "S"
"example": "海科学校"
}
}
},
"api_public.locationAreaRes": {
"type": "object",
"properties": {
"district": {
"type": "string",
"example": "四川省成都市温江区"
},
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "四川省"
"example": "海科学校"
}
}
},
"v1.PutCardUserReq": {
"api_we.PutCardUserReq": {
"type": "object",
"properties": {
"class": {
......@@ -759,19 +1006,20 @@ var doc = `{
}
}
},
"v1.bindCardUserRes": {
"api_we.WeMasterLoginResUserInfoStruct": {
"type": "object",
"properties": {
"area": {
"description": "区域名字",
"type": "string",
"example": "四川省成都市温江区实验中学"
"example": "温江实验中学"
},
"class": {
"description": "0无意义",
"type": "integer"
},
"grade": {
"description": "\"1~9对应一年级~九年级,10~12对应高一~高三\"",
"description": "0无意义 \"1~9对应一年级~九年级,10~12对应高一~高三\"",
"type": "integer"
},
"id": {
......@@ -797,34 +1045,94 @@ var doc = `{
]
},
"sex": {
"description": "0女 1男",
"description": "0无意义 1女 2男",
"type": "integer"
},
"stuNum": {
"description": "\"\"无意义",
"type": "string"
},
"topUp": {
"description": "是否已充值(已充值则不能删除,未充值可以删除)",
"type": "boolean"
}
}
},
"v1.countyAreaRes": {
"api_we.WeSlaveLoginResUserInfoStruct": {
"type": "object",
"properties": {
"area": {
"description": "区域名字",
"type": "string",
"example": "温江实验中学"
},
"class": {
"description": "0无意义",
"type": "integer"
},
"grade": {
"description": "0无意义 \"1~9对应一年级~九年级,10~12对应高一~高三\"",
"type": "integer"
},
"id": {
"type": "integer",
"example": 1
"description": "学生ID",
"type": "integer"
},
"name": {
"type": "string",
"example": "海科学校"
"type": "string"
},
"service": {
"description": "对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)",
"type": "array",
"items": {
"type": "integer"
},
"example": [
1,
2,
2,
0,
0,
0
]
},
"sex": {
"description": "0无意义 1女 2男",
"type": "integer"
},
"stuNum": {
"description": "\"\"无意义",
"type": "string"
}
}
},
"v1.creatCardUserRes": {
"api_we.bindCardUserRes": {
"type": "object",
"properties": {
"area": {
"description": "区域名字",
"type": "string",
"example": "四川省成都市温江区实验中学"
},
"class": {
"type": "integer"
},
"grade": {
"description": "\"1~9对应一年级~九年级,10~12对应高一~高三\"",
"type": "integer"
},
"id": {
"description": "新创建的学生ID",
"description": "学生ID",
"type": "integer"
},
"master": {
"description": "true:本来就是主家长,false:已成功绑定成副家长",
"type": "boolean",
"example": false
},
"name": {
"type": "string"
},
"service": {
"description": "对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)",
"type": "array",
......@@ -839,26 +1147,73 @@ var doc = `{
0,
0
]
},
"sex": {
"description": "0女 1男",
"type": "integer"
},
"stuNum": {
"type": "string"
}
}
},
"v1.getBindCardUserRes": {
"api_we.creatCardUserRes": {
"type": "object",
"properties": {
"shareCode": {
"description": "学生的邀请码,长度固定16,若为空,则表示邀请码开关关闭",
"type": "string"
"id": {
"description": "新创建的学生ID",
"type": "integer"
},
"weUser": {
"description": "副家长微信信息列表",
"service": {
"description": "对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)",
"type": "array",
"items": {
"$ref": "#/definitions/v1.slaveWeUserRes"
}
"type": "integer"
},
"example": [
1,
2,
2,
2,
2,
2
]
}
}
},
"api_we.familyNumStruct": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "string"
}
}
},
"api_we.getCallRecordRes": {
"type": "object",
"properties": {
"nickname": {
"description": "昵称",
"type": "string"
},
"number": {
"description": "被叫号码",
"type": "string"
},
"startAt": {
"description": "通话开始时间",
"type": "string"
},
"time": {
"description": "通话时长,单位(分钟)",
"type": "integer"
}
}
},
"v1.getPhoneCardStatusRes": {
"api_we.getPhoneCardStatusRes": {
"type": "object",
"properties": {
"changeable": {
......@@ -873,15 +1228,7 @@ var doc = `{
"description": "亲情号列表",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "string"
}
}
"$ref": "#/definitions/api_we.familyNumStruct"
}
},
"monthMin": {
......@@ -902,45 +1249,114 @@ var doc = `{
}
}
},
"v1.locationAreaRes": {
"api_we.slaveWeUserRes": {
"type": "object",
"properties": {
"district": {
"type": "string",
"example": "四川省成都市温江区"
"avatarURL": {
"description": "头像URL",
"type": "string"
},
"id": {
"type": "integer",
"example": 1
"createAt": {
"description": "绑定时间",
"type": "string"
},
"name": {
"nickname": {
"description": "微信昵称",
"type": "string"
},
"phone": {
"description": "手机号",
"type": "string"
},
"weUserID": {
"description": "微信UnionID",
"type": "integer"
}
}
},
"api_we.weLoginReq": {
"type": "object",
"properties": {
"code": {
"description": "必填,登录要用的微信code",
"type": "string",
"example": "海科学校"
"example": "codeTest1"
},
"token": {
"description": "选填,如果有旧的token,也带过来",
"type": "string"
}
}
},
"v1.slaveWeUserRes": {
"api_we.weLoginRes": {
"type": "object",
"properties": {
"avatarURL": {
"description": "头像URL",
"master": {
"description": "自己创建的学生列表(主家长)",
"type": "array",
"items": {
"$ref": "#/definitions/api_we.WeMasterLoginResUserInfoStruct"
}
},
"slave": {
"description": "添加的学生列表(副家长)",
"type": "array",
"items": {
"$ref": "#/definitions/api_we.WeSlaveLoginResUserInfoStruct"
}
},
"token": {
"type": "string"
},
"createAt": {
"description": "绑定时间",
"weInfo": {
"description": "是否已获取到微信用户信息",
"type": "boolean"
},
"wePhone": {
"description": "是否已获取到微信电话",
"type": "boolean"
}
}
},
"api_we.wechatCardUsersTrendType": {
"type": "object",
"properties": {
"content": {
"description": "显示在第二行",
"type": "string"
},
"nickname": {
"description": "微信昵称",
"service": {
"description": "服务项目 1公话2定位3饮水4卡消费5洗浴6洗衣机 决定UI图标及颜色等",
"type": "integer"
},
"time": {
"description": "显示在第三行",
"type": "string"
},
"unionID": {
"description": "微信UnionID",
"title": {
"description": "显示在第一行",
"type": "string"
}
}
},
"v1.weCreateCardUserReq": {
"cache.DistrictStruct": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"initial": {
"type": "string",
"example": "S"
},
"name": {
"type": "string",
"example": "四川省"
}
}
},
"dbmodel.InsertTableUserCardUser": {
"type": "object",
"properties": {
"areaID": {
......@@ -962,7 +1378,7 @@ var doc = `{
"example": "汤圆"
},
"sex": {
"description": "选填,0女1男",
"description": "选填,1女2男",
"type": "integer"
},
"stuNum": {
......@@ -971,123 +1387,38 @@ var doc = `{
}
}
},
"v1.weLoginRes": {
"dbmodel.TableBaseArea": {
"type": "object",
"properties": {
"master": {
"description": "自己创建的学生列表(主家长)",
"type": "array",
"items": {
"type": "object",
"properties": {
"area": {
"description": "区域名字",
"type": "string",
"example": "四川省成都市温江区实验中学"
},
"class": {
"type": "integer"
},
"grade": {
"description": "\"1~9对应一年级~九年级,10~12对应高一~高三\"",
"type": "integer"
},
"id": {
"description": "学生ID",
"type": "integer"
},
"name": {
"type": "string"
},
"service": {
"description": "对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)",
"type": "array",
"items": {
"type": "integer"
},
"example": [
1,
2,
2,
0,
0,
0
]
},
"sex": {
"description": "0女 1男",
"type": "integer"
},
"stuNum": {
"type": "string"
},
"topUp": {
"description": "是否已充值(已充值则不能删除,未充值可以删除)",
"type": "boolean"
}
}
}
"county_id": {
"description": "必填,所属区县ID",
"type": "integer",
"example": 2725
},
"slave": {
"description": "添加的学生列表(副家长)",
"type": "array",
"items": {
"type": "object",
"properties": {
"area": {
"description": "区域名字",
"type": "string",
"example": "四川省成都市温江区实验中学"
},
"class": {
"type": "integer"
},
"grade": {
"description": "\"1~9对应一年级~九年级,10~12对应高一~高三\"",
"type": "integer"
},
"id": {
"description": "学生ID",
"type": "integer"
},
"name": {
"type": "string"
},
"service": {
"description": "对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)",
"type": "array",
"items": {
"type": "integer"
},
"example": [
1,
2,
2,
0,
0,
0
]
},
"sex": {
"description": "0女 1男",
"type": "integer"
},
"stuNum": {
"type": "string"
}
}
}
"creator_id": {
"description": "测试用,以后不传这个字段",
"type": "integer",
"example": 1
},
"token": {
"type": "string"
"latitude": {
"description": "必填,纬度",
"type": "integer",
"example": 30000000
},
"weInfo": {
"description": "是否已获取到微信用户信息",
"type": "boolean"
"longitude": {
"description": "必填,经度",
"type": "integer",
"example": 103000000
},
"wePhone": {
"description": "是否已获取到微信电话",
"type": "boolean"
"name": {
"description": "必填,名字",
"type": "string",
"example": "多彩温江校区"
},
"status": {
"description": "必填,是否测试校区,0预留 1正示 2测试校区",
"type": "integer",
"example": 1
}
}
}
......
......@@ -8,6 +8,45 @@
},
"basePath": "/",
"paths": {
"/ad/area": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "目前仅用于填充数据,暂未做权限校验",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"管理后台"
],
"summary": "创建一个学校",
"parameters": [
{
"description": "学校信息",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dbmodel.TableBaseArea"
}
}
],
"responses": {
"0": {
"description": "",
"schema": {
"type": "integer"
}
}
}
}
},
"/base/city/{provinceID}": {
"get": {
"security": [
......@@ -19,7 +58,7 @@
"tags": [
"公用接口"
],
"summary": "通过省份ID获取城市列表",
"summary": "通过省份ID获取城市列表 [complete]",
"parameters": [
{
"type": "integer",
......@@ -53,7 +92,7 @@
"tags": [
"公用接口"
],
"summary": "通过城市ID获取区县列表",
"summary": "通过城市ID获取区县列表 [complete]",
"parameters": [
{
"type": "integer",
......@@ -87,7 +126,7 @@
"tags": [
"公用接口"
],
"summary": "根据区县ID获取学校列表",
"summary": "根据区县ID获取学校列表 [complete]",
"parameters": [
{
"type": "integer",
......@@ -104,7 +143,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/v1.countyAreaRes"
"$ref": "#/definitions/api_public.countyAreaRes"
}
}
}
......@@ -122,7 +161,7 @@
"tags": [
"公用接口"
],
"summary": "根据经纬度获取附近20所学校列表",
"summary": "根据经纬度获取附近20所学校列表 [can test]",
"parameters": [
{
"type": "integer",
......@@ -147,7 +186,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/v1.locationAreaRes"
"$ref": "#/definitions/api_public.locationAreaRes"
}
}
}
......@@ -165,7 +204,7 @@
"tags": [
"公用接口"
],
"summary": "获取全国省份列表",
"summary": "获取全国省份列表 [complete]",
"responses": {
"0": {
"description": "按首字母排序好的列表,可直接用作展示",
......@@ -193,7 +232,7 @@
"tags": [
"家长微信"
],
"summary": "获取学生副家长列表及邀请码内容(仅主家长有权限)",
"summary": "获取学生副家长列表(仅主家长有权限)",
"parameters": [
{
"type": "integer",
......@@ -205,9 +244,12 @@
],
"responses": {
"0": {
"description": "副家长信息列表及邀请码",
"description": "副家长信息列表",
"schema": {
"$ref": "#/definitions/v1.getBindCardUserRes"
"type": "array",
"items": {
"$ref": "#/definitions/api_we.slaveWeUserRes"
}
}
}
}
......@@ -256,7 +298,7 @@
"tags": [
"家长微信"
],
"summary": "副家长绑定学生",
"summary": "通过邀请码绑定学生",
"parameters": [
{
"type": "string",
......@@ -270,7 +312,83 @@
"0": {
"description": "学生信息",
"schema": {
"$ref": "#/definitions/v1.bindCardUserRes"
"$ref": "#/definitions/api_we.bindCardUserRes"
}
},
"30": {
"description": "邀请码无效"
},
"31": {
"description": "邀请码已过期"
}
}
}
},
"/we/callrecord/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "传学生ID至后台,后台返回通话记录列表",
"produces": [
"application/json"
],
"tags": [
"家长微信"
],
"summary": "查询通话记录",
"parameters": [
{
"type": "integer",
"description": "学生ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "页数",
"name": "pnum",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "页条数",
"name": "psize",
"in": "query",
"required": true
},
{
"type": "string",
"description": "起始时间 2020-10-10 10:00:00",
"name": "start",
"in": "query"
},
{
"type": "string",
"description": "结束时间 2030-10-10 10:00:00",
"name": "end",
"in": "query"
},
{
"type": "boolean",
"default": false,
"description": "是否升序",
"name": "asc",
"in": "query"
}
],
"responses": {
"0": {
"description": "通话记录列表",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api_we.getCallRecordRes"
}
}
}
}
......@@ -419,7 +537,7 @@
"tags": [
"家长微信"
],
"summary": "创建一个学生",
"summary": "创建一个学生 [complete]",
"parameters": [
{
"description": "学生信息",
......@@ -427,7 +545,7 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1.weCreateCardUserReq"
"$ref": "#/definitions/dbmodel.InsertTableUserCardUser"
}
}
],
......@@ -435,7 +553,7 @@
"0": {
"description": "",
"schema": {
"$ref": "#/definitions/v1.creatCardUserRes"
"$ref": "#/definitions/api_we.creatCardUserRes"
}
}
}
......@@ -473,7 +591,7 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1.PutCardUserReq"
"$ref": "#/definitions/api_we.PutCardUserReq"
}
}
],
......@@ -513,21 +631,24 @@
}
}
},
"/we/cardusershareoff/{id}": {
"/we/familynum": {
"put": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "传学生ID至后台,后台返回成功失败",
"description": "修改亲情号接口",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"家长微信"
],
"summary": "关闭邀请码开关(仅主家长有权限)",
"summary": "修改亲情号",
"parameters": [
{
"type": "integer",
......@@ -535,6 +656,22 @@
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "电话号码",
"name": "phone",
"in": "query",
"required": true
},
{
"description": "亲情号内容",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api_we.familyNumStruct"
}
}
],
"responses": {
......@@ -542,23 +679,65 @@
"description": ""
}
}
}
},
"/we/cardusershareon/{id}": {
"put": {
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "传学生ID至后台,后台返回成功失败",
"description": "家长绑定亲情号接口",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"家长微信"
],
"summary": "添加亲情号",
"parameters": [
{
"type": "integer",
"description": "学生ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "亲情号内容",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api_we.familyNumStruct"
}
}
],
"responses": {
"0": {
"description": ""
}
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "删除亲情号接口",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"家长微信"
],
"summary": "打开邀请码开关(仅主家长有权限)",
"summary": "删除亲情号",
"parameters": [
{
"type": "integer",
......@@ -566,6 +745,13 @@
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "电话号码",
"name": "phone",
"in": "query",
"required": true
}
],
"responses": {
......@@ -577,25 +763,27 @@
},
"/we/login/{code}": {
"post": {
"description": "微信code传至后台,后台返回token,token有效时长:24小时",
"description": "微信code传至后台,后台返回token,token有效时长:48小时",
"tags": [
"家长微信"
],
"summary": "登录",
"summary": "登录 [complete]",
"parameters": [
{
"type": "string",
"description": "用户微信的code",
"name": "code",
"in": "path",
"required": true
"description": "登录信息",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api_we.weLoginReq"
}
}
],
"responses": {
"0": {
"description": "",
"schema": {
"$ref": "#/definitions/v1.weLoginRes"
"$ref": "#/definitions/api_we.weLoginRes"
}
}
}
......@@ -629,7 +817,48 @@
"0": {
"description": "公话卡状态信息",
"schema": {
"$ref": "#/definitions/v1.getPhoneCardStatusRes"
"$ref": "#/definitions/api_we.getPhoneCardStatusRes"
}
}
}
}
},
"/we/sharecode/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "主家长生成邀请码,有效时长可选1分钟~60分钟",
"produces": [
"application/json"
],
"tags": [
"家长微信"
],
"summary": "获取邀请码(仅主家长有权限)",
"parameters": [
{
"type": "integer",
"description": "学生ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 60,
"description": "有效时长,1~60分钟,不填则为60分钟",
"name": "time",
"in": "query"
}
],
"responses": {
"0": {
"description": "邀请码内容",
"schema": {
"type": "string"
}
}
}
......@@ -659,9 +888,9 @@
"required": true
},
{
"type": "string",
"description": "副家长微信UnionID",
"name": "unionid",
"type": "integer",
"description": "副家长微信weUserID",
"name": "weUserID",
"in": "query",
"required": true
}
......@@ -673,27 +902,32 @@
}
}
},
"/we/trend/:id": {
"/we/trend/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "微信学生首页,获取近20条用户最新动态",
"tags": [
"public"
"家长微信"
],
"summary": "微信学生首页,获取近20条用户最新动态",
"parameters": [
{
"type": "string",
"description": "请示参数code",
"name": "code",
"type": "integer",
"description": "学生ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "{\"code\": 200, \"token\": string}",
"description": "学生动态信息",
"schema": {
"type": "string"
"$ref": "#/definitions/api_we.wechatCardUsersTrendType"
}
}
}
......@@ -701,24 +935,37 @@
}
},
"definitions": {
"cache.DistrictStruct": {
"api_public.countyAreaRes": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"initial": {
"name": {
"type": "string",
"example": "S"
"example": "海科学校"
}
}
},
"api_public.locationAreaRes": {
"type": "object",
"properties": {
"district": {
"type": "string",
"example": "四川省成都市温江区"
},
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "四川省"
"example": "海科学校"
}
}
},
"v1.PutCardUserReq": {
"api_we.PutCardUserReq": {
"type": "object",
"properties": {
"class": {
......@@ -744,19 +991,20 @@
}
}
},
"v1.bindCardUserRes": {
"api_we.WeMasterLoginResUserInfoStruct": {
"type": "object",
"properties": {
"area": {
"description": "区域名字",
"type": "string",
"example": "四川省成都市温江区实验中学"
"example": "温江实验中学"
},
"class": {
"description": "0无意义",
"type": "integer"
},
"grade": {
"description": "\"1~9对应一年级~九年级,10~12对应高一~高三\"",
"description": "0无意义 \"1~9对应一年级~九年级,10~12对应高一~高三\"",
"type": "integer"
},
"id": {
......@@ -782,34 +1030,94 @@
]
},
"sex": {
"description": "0女 1男",
"description": "0无意义 1女 2男",
"type": "integer"
},
"stuNum": {
"description": "\"\"无意义",
"type": "string"
},
"topUp": {
"description": "是否已充值(已充值则不能删除,未充值可以删除)",
"type": "boolean"
}
}
},
"v1.countyAreaRes": {
"api_we.WeSlaveLoginResUserInfoStruct": {
"type": "object",
"properties": {
"area": {
"description": "区域名字",
"type": "string",
"example": "温江实验中学"
},
"class": {
"description": "0无意义",
"type": "integer"
},
"grade": {
"description": "0无意义 \"1~9对应一年级~九年级,10~12对应高一~高三\"",
"type": "integer"
},
"id": {
"type": "integer",
"example": 1
"description": "学生ID",
"type": "integer"
},
"name": {
"type": "string",
"example": "海科学校"
"type": "string"
},
"service": {
"description": "对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)",
"type": "array",
"items": {
"type": "integer"
},
"example": [
1,
2,
2,
0,
0,
0
]
},
"sex": {
"description": "0无意义 1女 2男",
"type": "integer"
},
"stuNum": {
"description": "\"\"无意义",
"type": "string"
}
}
},
"v1.creatCardUserRes": {
"api_we.bindCardUserRes": {
"type": "object",
"properties": {
"area": {
"description": "区域名字",
"type": "string",
"example": "四川省成都市温江区实验中学"
},
"class": {
"type": "integer"
},
"grade": {
"description": "\"1~9对应一年级~九年级,10~12对应高一~高三\"",
"type": "integer"
},
"id": {
"description": "新创建的学生ID",
"description": "学生ID",
"type": "integer"
},
"master": {
"description": "true:本来就是主家长,false:已成功绑定成副家长",
"type": "boolean",
"example": false
},
"name": {
"type": "string"
},
"service": {
"description": "对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)",
"type": "array",
......@@ -824,26 +1132,73 @@
0,
0
]
},
"sex": {
"description": "0女 1男",
"type": "integer"
},
"stuNum": {
"type": "string"
}
}
},
"v1.getBindCardUserRes": {
"api_we.creatCardUserRes": {
"type": "object",
"properties": {
"shareCode": {
"description": "学生的邀请码,长度固定16,若为空,则表示邀请码开关关闭",
"type": "string"
"id": {
"description": "新创建的学生ID",
"type": "integer"
},
"weUser": {
"description": "副家长微信信息列表",
"service": {
"description": "对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)",
"type": "array",
"items": {
"$ref": "#/definitions/v1.slaveWeUserRes"
}
"type": "integer"
},
"example": [
1,
2,
2,
2,
2,
2
]
}
}
},
"api_we.familyNumStruct": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "string"
}
}
},
"api_we.getCallRecordRes": {
"type": "object",
"properties": {
"nickname": {
"description": "昵称",
"type": "string"
},
"number": {
"description": "被叫号码",
"type": "string"
},
"startAt": {
"description": "通话开始时间",
"type": "string"
},
"time": {
"description": "通话时长,单位(分钟)",
"type": "integer"
}
}
},
"v1.getPhoneCardStatusRes": {
"api_we.getPhoneCardStatusRes": {
"type": "object",
"properties": {
"changeable": {
......@@ -858,15 +1213,7 @@
"description": "亲情号列表",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "string"
}
}
"$ref": "#/definitions/api_we.familyNumStruct"
}
},
"monthMin": {
......@@ -887,45 +1234,114 @@
}
}
},
"v1.locationAreaRes": {
"api_we.slaveWeUserRes": {
"type": "object",
"properties": {
"district": {
"type": "string",
"example": "四川省成都市温江区"
"avatarURL": {
"description": "头像URL",
"type": "string"
},
"id": {
"type": "integer",
"example": 1
"createAt": {
"description": "绑定时间",
"type": "string"
},
"name": {
"nickname": {
"description": "微信昵称",
"type": "string"
},
"phone": {
"description": "手机号",
"type": "string"
},
"weUserID": {
"description": "微信UnionID",
"type": "integer"
}
}
},
"api_we.weLoginReq": {
"type": "object",
"properties": {
"code": {
"description": "必填,登录要用的微信code",
"type": "string",
"example": "海科学校"
"example": "codeTest1"
},
"token": {
"description": "选填,如果有旧的token,也带过来",
"type": "string"
}
}
},
"v1.slaveWeUserRes": {
"api_we.weLoginRes": {
"type": "object",
"properties": {
"avatarURL": {
"description": "头像URL",
"master": {
"description": "自己创建的学生列表(主家长)",
"type": "array",
"items": {
"$ref": "#/definitions/api_we.WeMasterLoginResUserInfoStruct"
}
},
"slave": {
"description": "添加的学生列表(副家长)",
"type": "array",
"items": {
"$ref": "#/definitions/api_we.WeSlaveLoginResUserInfoStruct"
}
},
"token": {
"type": "string"
},
"createAt": {
"description": "绑定时间",
"weInfo": {
"description": "是否已获取到微信用户信息",
"type": "boolean"
},
"wePhone": {
"description": "是否已获取到微信电话",
"type": "boolean"
}
}
},
"api_we.wechatCardUsersTrendType": {
"type": "object",
"properties": {
"content": {
"description": "显示在第二行",
"type": "string"
},
"nickname": {
"description": "微信昵称",
"service": {
"description": "服务项目 1公话2定位3饮水4卡消费5洗浴6洗衣机 决定UI图标及颜色等",
"type": "integer"
},
"time": {
"description": "显示在第三行",
"type": "string"
},
"unionID": {
"description": "微信UnionID",
"title": {
"description": "显示在第一行",
"type": "string"
}
}
},
"v1.weCreateCardUserReq": {
"cache.DistrictStruct": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"initial": {
"type": "string",
"example": "S"
},
"name": {
"type": "string",
"example": "四川省"
}
}
},
"dbmodel.InsertTableUserCardUser": {
"type": "object",
"properties": {
"areaID": {
......@@ -947,7 +1363,7 @@
"example": "汤圆"
},
"sex": {
"description": "选填,0女1男",
"description": "选填,1女2男",
"type": "integer"
},
"stuNum": {
......@@ -956,123 +1372,38 @@
}
}
},
"v1.weLoginRes": {
"dbmodel.TableBaseArea": {
"type": "object",
"properties": {
"master": {
"description": "自己创建的学生列表(主家长)",
"type": "array",
"items": {
"type": "object",
"properties": {
"area": {
"description": "区域名字",
"type": "string",
"example": "四川省成都市温江区实验中学"
},
"class": {
"type": "integer"
},
"grade": {
"description": "\"1~9对应一年级~九年级,10~12对应高一~高三\"",
"type": "integer"
},
"id": {
"description": "学生ID",
"type": "integer"
},
"name": {
"type": "string"
},
"service": {
"description": "对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)",
"type": "array",
"items": {
"type": "integer"
},
"example": [
1,
2,
2,
0,
0,
0
]
},
"sex": {
"description": "0女 1男",
"type": "integer"
},
"stuNum": {
"type": "string"
},
"topUp": {
"description": "是否已充值(已充值则不能删除,未充值可以删除)",
"type": "boolean"
}
}
}
"county_id": {
"description": "必填,所属区县ID",
"type": "integer",
"example": 2725
},
"slave": {
"description": "添加的学生列表(副家长)",
"type": "array",
"items": {
"type": "object",
"properties": {
"area": {
"description": "区域名字",
"type": "string",
"example": "四川省成都市温江区实验中学"
},
"class": {
"type": "integer"
},
"grade": {
"description": "\"1~9对应一年级~九年级,10~12对应高一~高三\"",
"type": "integer"
},
"id": {
"description": "学生ID",
"type": "integer"
},
"name": {
"type": "string"
},
"service": {
"description": "对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)",
"type": "array",
"items": {
"type": "integer"
},
"example": [
1,
2,
2,
0,
0,
0
]
},
"sex": {
"description": "0女 1男",
"type": "integer"
},
"stuNum": {
"type": "string"
}
}
}
"creator_id": {
"description": "测试用,以后不传这个字段",
"type": "integer",
"example": 1
},
"token": {
"type": "string"
"latitude": {
"description": "必填,纬度",
"type": "integer",
"example": 30000000
},
"weInfo": {
"description": "是否已获取到微信用户信息",
"type": "boolean"
"longitude": {
"description": "必填,经度",
"type": "integer",
"example": 103000000
},
"wePhone": {
"description": "是否已获取到微信电话",
"type": "boolean"
"name": {
"description": "必填,名字",
"type": "string",
"example": "多彩温江校区"
},
"status": {
"description": "必填,是否测试校区,0预留 1正示 2测试校区",
"type": "integer",
"example": 1
}
}
}
......
basePath: /
definitions:
cache.DistrictStruct:
api_public.countyAreaRes:
properties:
id:
example: 1
type: integer
initial:
example: S
name:
example: 海科学校
type: string
type: object
api_public.locationAreaRes:
properties:
district:
example: 四川省成都市温江区
type: string
id:
example: 1
type: integer
name:
example: 四川省
example: 海科学校
type: string
type: object
v1.PutCardUserReq:
api_we.PutCardUserReq:
properties:
class:
description: 选填,班级,number
......@@ -31,16 +40,17 @@ definitions:
description: 选填,学号,字符串,maxLen=32
type: string
type: object
v1.bindCardUserRes:
api_we.WeMasterLoginResUserInfoStruct:
properties:
area:
description: 区域名字
example: 四川省成都市温江区实验中学
example: 温江实验中学
type: string
class:
description: 0无意义
type: integer
grade:
description: '"1~9对应一年级~九年级,10~12对应高一~高三"'
description: 0无意义 "1~9对应一年级~九年级,10~12对应高一~高三"
type: integer
id:
description: 学生ID
......@@ -60,25 +70,71 @@ definitions:
type: integer
type: array
sex:
description: 0女 1
description: 0无意义 1女 2
type: integer
stuNum:
description: '""无意义'
type: string
topUp:
description: 是否已充值(已充值则不能删除,未充值可以删除)
type: boolean
type: object
v1.countyAreaRes:
api_we.WeSlaveLoginResUserInfoStruct:
properties:
area:
description: 区域名字
example: 温江实验中学
type: string
class:
description: 0无意义
type: integer
grade:
description: 0无意义 "1~9对应一年级~九年级,10~12对应高一~高三"
type: integer
id:
example: 1
description: 学生ID
type: integer
name:
example: 海科学校
type: string
service:
description: 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
example:
- 1
- 2
- 2
- 0
- 0
- 0
items:
type: integer
type: array
sex:
description: 0无意义 1女 2男
type: integer
stuNum:
description: '""无意义'
type: string
type: object
v1.creatCardUserRes:
api_we.bindCardUserRes:
properties:
area:
description: 区域名字
example: 四川省成都市温江区实验中学
type: string
class:
type: integer
grade:
description: '"1~9对应一年级~九年级,10~12对应高一~高三"'
type: integer
id:
description: 新创建的学生ID
description: 学生ID
type: integer
master:
description: true:本来就是主家长,false:已成功绑定成副家长
example: false
type: boolean
name:
type: string
service:
description: 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
example:
......@@ -91,19 +147,53 @@ definitions:
items:
type: integer
type: array
sex:
description: 0女 1男
type: integer
stuNum:
type: string
type: object
v1.getBindCardUserRes:
api_we.creatCardUserRes:
properties:
shareCode:
description: 学生的邀请码,长度固定16,若为空,则表示邀请码开关关闭
type: string
weUser:
description: 副家长微信信息列表
id:
description: 新创建的学生ID
type: integer
service:
description: 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
example:
- 1
- 2
- 2
- 2
- 2
- 2
items:
$ref: '#/definitions/v1.slaveWeUserRes'
type: integer
type: array
type: object
v1.getPhoneCardStatusRes:
api_we.familyNumStruct:
properties:
name:
type: string
phone:
type: string
type: object
api_we.getCallRecordRes:
properties:
nickname:
description: 昵称
type: string
number:
description: 被叫号码
type: string
startAt:
description: 通话开始时间
type: string
time:
description: 通话时长,单位(分钟)
type: integer
type: object
api_we.getPhoneCardStatusRes:
properties:
changeable:
description: 本月可修改亲情号次数
......@@ -114,12 +204,7 @@ definitions:
family:
description: 亲情号列表
items:
properties:
name:
type: string
phone:
type: string
type: object
$ref: '#/definitions/api_we.familyNumStruct'
type: array
monthMin:
description: 月套餐使用分钟数
......@@ -134,19 +219,7 @@ definitions:
description: 状态 0未绑定卡 1 正常使用 2 服务已到期 3 已挂失
type: integer
type: object
v1.locationAreaRes:
properties:
district:
example: 四川省成都市温江区
type: string
id:
example: 1
type: integer
name:
example: 海科学校
type: string
type: object
v1.slaveWeUserRes:
api_we.slaveWeUserRes:
properties:
avatarURL:
description: 头像URL
......@@ -157,11 +230,72 @@ definitions:
nickname:
description: 微信昵称
type: string
unionID:
phone:
description: 手机号
type: string
weUserID:
description: 微信UnionID
type: integer
type: object
api_we.weLoginReq:
properties:
code:
description: 必填,登录要用的微信code
example: codeTest1
type: string
token:
description: 选填,如果有旧的token,也带过来
type: string
type: object
api_we.weLoginRes:
properties:
master:
description: 自己创建的学生列表(主家长)
items:
$ref: '#/definitions/api_we.WeMasterLoginResUserInfoStruct'
type: array
slave:
description: 添加的学生列表(副家长)
items:
$ref: '#/definitions/api_we.WeSlaveLoginResUserInfoStruct'
type: array
token:
type: string
weInfo:
description: 是否已获取到微信用户信息
type: boolean
wePhone:
description: 是否已获取到微信电话
type: boolean
type: object
v1.weCreateCardUserReq:
api_we.wechatCardUsersTrendType:
properties:
content:
description: 显示在第二行
type: string
service:
description: 服务项目 1公话2定位3饮水4卡消费5洗浴6洗衣机 决定UI图标及颜色等
type: integer
time:
description: 显示在第三行
type: string
title:
description: 显示在第一行
type: string
type: object
cache.DistrictStruct:
properties:
id:
example: 1
type: integer
initial:
example: S
type: string
name:
example: 四川省
type: string
type: object
dbmodel.InsertTableUserCardUser:
properties:
areaID:
description: 必填,校区ID
......@@ -178,99 +312,38 @@ definitions:
example: 汤圆
type: string
sex:
description: 选填,0女1
description: 选填,1女2
type: integer
stuNum:
description: 选填,学号,字符串,maxLen=32
type: string
type: object
v1.weLoginRes:
dbmodel.TableBaseArea:
properties:
master:
description: 自己创建的学生列表(主家长)
items:
properties:
area:
description: 区域名字
example: 四川省成都市温江区实验中学
type: string
class:
type: integer
grade:
description: '"1~9对应一年级~九年级,10~12对应高一~高三"'
type: integer
id:
description: 学生ID
type: integer
name:
type: string
service:
description: 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
example:
- 1
- 2
- 2
- 0
- 0
- 0
items:
type: integer
type: array
sex:
description: 0女 1男
type: integer
stuNum:
type: string
topUp:
description: 是否已充值(已充值则不能删除,未充值可以删除)
type: boolean
type: object
type: array
slave:
description: 添加的学生列表(副家长)
items:
properties:
area:
description: 区域名字
example: 四川省成都市温江区实验中学
type: string
class:
type: integer
grade:
description: '"1~9对应一年级~九年级,10~12对应高一~高三"'
type: integer
id:
description: 学生ID
type: integer
name:
type: string
service:
description: 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
example:
- 1
- 2
- 2
- 0
- 0
- 0
items:
type: integer
type: array
sex:
description: 0女 1男
type: integer
stuNum:
type: string
type: object
type: array
token:
county_id:
description: 必填,所属区县ID
example: 2725
type: integer
creator_id:
description: 测试用,以后不传这个字段
example: 1
type: integer
latitude:
description: 必填,纬度
example: 30000000
type: integer
longitude:
description: 必填,经度
example: 103000000
type: integer
name:
description: 必填,名字
example: 多彩温江校区
type: string
weInfo:
description: 是否已获取到微信用户信息
type: boolean
wePhone:
description: 是否已获取到微信电话
type: boolean
status:
description: 必填,是否测试校区,0预留 1正示 2测试校区
example: 1
type: integer
type: object
info:
contact: {}
......@@ -278,6 +351,30 @@ info:
title: 多彩中小学一卡通系统
version: V0.0.1
paths:
/ad/area:
post:
consumes:
- application/json
description: 目前仅用于填充数据,暂未做权限校验
parameters:
- description: 学校信息
in: body
name: data
required: true
schema:
$ref: '#/definitions/dbmodel.TableBaseArea'
produces:
- application/json
responses:
"0":
description: ""
schema:
type: integer
security:
- ApiKeyAuth: []
summary: 创建一个学校
tags:
- 管理后台
/base/city/{provinceID}:
get:
description: 获取带首字母的城市列表
......@@ -296,7 +393,7 @@ paths:
type: array
security:
- ApiKeyAuth: []
summary: 通过省份ID获取城市列表
summary: 通过省份ID获取城市列表 [complete]
tags:
- 公用接口
/base/county/{cityID}:
......@@ -317,7 +414,7 @@ paths:
type: array
security:
- ApiKeyAuth: []
summary: 通过城市ID获取区县列表
summary: 通过城市ID获取区县列表 [complete]
tags:
- 公用接口
/base/countyarea/{countyID}:
......@@ -335,11 +432,11 @@ paths:
description: 排序好的学校列表,可直接用作展示
schema:
items:
$ref: '#/definitions/v1.countyAreaRes'
$ref: '#/definitions/api_public.countyAreaRes'
type: array
security:
- ApiKeyAuth: []
summary: 根据区县ID获取学校列表
summary: 根据区县ID获取学校列表 [complete]
tags:
- 公用接口
/base/locarea:
......@@ -363,11 +460,11 @@ paths:
description: 排序好的学校列表,可直接用作展示
schema:
items:
$ref: '#/definitions/v1.locationAreaRes'
$ref: '#/definitions/api_public.locationAreaRes'
type: array
security:
- ApiKeyAuth: []
summary: 根据经纬度获取附近20所学校列表
summary: 根据经纬度获取附近20所学校列表 [can test]
tags:
- 公用接口
/base/province:
......@@ -382,7 +479,7 @@ paths:
type: array
security:
- ApiKeyAuth: []
summary: 获取全国省份列表
summary: 获取全国省份列表 [complete]
tags:
- 公用接口
/we/bindcarduser/{id}:
......@@ -416,12 +513,14 @@ paths:
- application/json
responses:
"0":
description: 副家长信息列表及邀请码
description: 副家长信息列表
schema:
$ref: '#/definitions/v1.getBindCardUserRes'
items:
$ref: '#/definitions/api_we.slaveWeUserRes'
type: array
security:
- ApiKeyAuth: []
summary: 获取学生副家长列表及邀请码内容(仅主家长有权限)
summary: 获取学生副家长列表(仅主家长有权限)
tags:
- 家长微信
/we/bindcarduser/{share_code}:
......@@ -439,10 +538,60 @@ paths:
"0":
description: 学生信息
schema:
$ref: '#/definitions/v1.bindCardUserRes'
$ref: '#/definitions/api_we.bindCardUserRes'
"30":
description: 邀请码无效
"31":
description: 邀请码已过期
security:
- ApiKeyAuth: []
summary: 副家长绑定学生
summary: 通过邀请码绑定学生
tags:
- 家长微信
/we/callrecord/{id}:
get:
description: 传学生ID至后台,后台返回通话记录列表
parameters:
- description: 学生ID
in: path
name: id
required: true
type: integer
- description: 页数
in: query
name: pnum
required: true
type: integer
- description: 页条数
in: query
name: psize
required: true
type: integer
- description: 起始时间 2020-10-10 10:00:00
in: query
name: start
type: string
- description: 结束时间 2030-10-10 10:00:00
in: query
name: end
type: string
- default: false
description: 是否升序
in: query
name: asc
type: boolean
produces:
- application/json
responses:
"0":
description: 通话记录列表
schema:
items:
$ref: '#/definitions/api_we.getCallRecordRes'
type: array
security:
- ApiKeyAuth: []
summary: 查询通话记录
tags:
- 家长微信
/we/cardbind/{id}:
......@@ -537,17 +686,17 @@ paths:
name: data
required: true
schema:
$ref: '#/definitions/v1.weCreateCardUserReq'
$ref: '#/definitions/dbmodel.InsertTableUserCardUser'
produces:
- application/json
responses:
"0":
description: ""
schema:
$ref: '#/definitions/v1.creatCardUserRes'
$ref: '#/definitions/api_we.creatCardUserRes'
security:
- ApiKeyAuth: []
summary: 创建一个学生
summary: 创建一个学生 [complete]
tags:
- 家长微信
/we/carduser/{id}:
......@@ -584,7 +733,7 @@ paths:
name: data
required: true
schema:
$ref: '#/definitions/v1.PutCardUserReq'
$ref: '#/definitions/api_we.PutCardUserReq'
produces:
- application/json
responses:
......@@ -595,15 +744,22 @@ paths:
summary: 修改学生信息
tags:
- 家长微信
/we/cardusershareoff/{id}:
put:
description: 传学生ID至后台,后台返回成功失败
/we/familynum:
delete:
consumes:
- application/json
description: 删除亲情号接口
parameters:
- description: 学生ID
in: path
name: id
required: true
type: integer
- description: 电话号码
in: query
name: phone
required: true
type: string
produces:
- application/json
responses:
......@@ -611,18 +767,56 @@ paths:
description: ""
security:
- ApiKeyAuth: []
summary: 关闭邀请码开关(仅主家长有权限)
summary: 删除亲情号
tags:
- 家长微信
post:
consumes:
- application/json
description: 家长绑定亲情号接口
parameters:
- description: 学生ID
in: path
name: id
required: true
type: integer
- description: 亲情号内容
in: body
name: data
required: true
schema:
$ref: '#/definitions/api_we.familyNumStruct'
produces:
- application/json
responses:
"0":
description: ""
security:
- ApiKeyAuth: []
summary: 添加亲情号
tags:
- 家长微信
/we/cardusershareon/{id}:
put:
description: 传学生ID至后台,后台返回成功失败
consumes:
- application/json
description: 修改亲情号接口
parameters:
- description: 学生ID
in: path
name: id
required: true
type: integer
- description: 电话号码
in: query
name: phone
required: true
type: string
- description: 亲情号内容
in: body
name: data
required: true
schema:
$ref: '#/definitions/api_we.familyNumStruct'
produces:
- application/json
responses:
......@@ -630,24 +824,25 @@ paths:
description: ""
security:
- ApiKeyAuth: []
summary: 打开邀请码开关(仅主家长有权限)
summary: 修改亲情号
tags:
- 家长微信
/we/login/{code}:
post:
description: 微信code传至后台,后台返回token,token有效时长:24小时
description: 微信code传至后台,后台返回token,token有效时长:48小时
parameters:
- description: 用户微信的code
in: path
name: code
- description: 登录信息
in: body
name: data
required: true
type: string
schema:
$ref: '#/definitions/api_we.weLoginReq'
responses:
"0":
description: ""
schema:
$ref: '#/definitions/v1.weLoginRes'
summary: 登录
$ref: '#/definitions/api_we.weLoginRes'
summary: 登录 [complete]
tags:
- 家长微信
/we/phonecardstatus/{id}:
......@@ -665,12 +860,38 @@ paths:
"0":
description: 公话卡状态信息
schema:
$ref: '#/definitions/v1.getPhoneCardStatusRes'
$ref: '#/definitions/api_we.getPhoneCardStatusRes'
security:
- ApiKeyAuth: []
summary: 获取学生公话卡状态
tags:
- 家长微信
/we/sharecode/{id}:
get:
description: 主家长生成邀请码,有效时长可选1分钟~60分钟
parameters:
- description: 学生ID
in: path
name: id
required: true
type: integer
- default: 60
description: 有效时长,1~60分钟,不填则为60分钟
in: query
name: time
type: integer
produces:
- application/json
responses:
"0":
description: 邀请码内容
schema:
type: string
security:
- ApiKeyAuth: []
summary: 获取邀请码(仅主家长有权限)
tags:
- 家长微信
/we/slaveweuser/{id}:
delete:
description: 传学生ID和微信UnionID,后台返回成功失败
......@@ -680,11 +901,11 @@ paths:
name: id
required: true
type: integer
- description: 副家长微信UnionID
- description: 副家长微信weUserID
in: query
name: unionid
name: weUserID
required: true
type: string
type: integer
produces:
- application/json
responses:
......@@ -695,23 +916,25 @@ paths:
summary: 删除副家长(仅主家长有权限)
tags:
- 家长微信
/we/trend/:id:
/we/trend/{id}:
get:
description: 微信学生首页,获取近20条用户最新动态
parameters:
- description: 请示参数code
- description: 学生ID
in: path
name: code
name: id
required: true
type: string
type: integer
responses:
"200":
description: '{"code": 200, "token": string}'
description: 学生动态信息
schema:
type: string
$ref: '#/definitions/api_we.wechatCardUsersTrendType'
security:
- ApiKeyAuth: []
summary: 微信学生首页,获取近20条用户最新动态
tags:
- public
- 家长微信
securityDefinitions:
ApiKeyAuth:
in: header
......
{"level":"WARN","ts":"2021-10-07 16:08:55.565","msg":"","HostName":"DESKTOP-2789F62","Status":404,"SpendNanoS":0,"Ip":"127.0.0.1","Method":"GET","Path":"/swagger/","DataSize":18,"Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"}
{"level":"WARN","ts":"2021-10-07 16:09:16.983","msg":"","HostName":"DESKTOP-2789F62","Status":404,"SpendNanoS":0,"Ip":"127.0.0.1","Method":"GET","Path":"/favicon.ico","DataSize":0,"Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"}
{"level":"WARN","ts":"2021-10-09 14:42:58.848","msg":"","HostName":"DESKTOP-2789F62","Status":404,"SpendNanoS":0,"Ip":"127.0.0.1","Method":"GET","Path":"/","DataSize":0,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
{"level":"WARN","ts":"2021-10-09 14:42:59.535","msg":"","HostName":"DESKTOP-2789F62","Status":404,"SpendNanoS":0,"Ip":"127.0.0.1","Method":"GET","Path":"/favicon.ico","DataSize":0,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
{"level":"WARN","ts":"2021-10-10 00:17:49.872","msg":"","HostName":"DESKTOP-2789F62","Status":404,"SpendNanoS":0,"Ip":"127.0.0.1","Method":"GET","Path":"/","DataSize":0,"Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3875.400 QQBrowser/10.8.4492.400"}
{"level":"WARN","ts":"2021-10-13 15:03:27.882","msg":"","HostName":"DESKTOP-2789F62","Status":404,"SpendNanoS":0,"Ip":"127.0.0.1","Method":"DELETE","Path":"/we/carduser","DataSize":0,"Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"}
{"level":"WARN","ts":"2021-10-13 15:03:35.683","msg":"","HostName":"DESKTOP-2789F62","Status":404,"SpendNanoS":0,"Ip":"127.0.0.1","Method":"DELETE","Path":"/we/carduser","DataSize":0,"Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"}
{"level":"WARN","ts":"2021-10-13 16:18:48.126","msg":"","HostName":"DESKTOP-2789F62","Status":404,"SpendNanoS":0,"Ip":"127.0.0.1","Method":"POST","Path":"/we/bindcarduser","DataSize":0,"Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"}
{"level":"WARN","ts":"2021-10-13 16:18:55.598","msg":"","HostName":"DESKTOP-2789F62","Status":404,"SpendNanoS":0,"Ip":"127.0.0.1","Method":"POST","Path":"/we/bindcarduser","DataSize":0,"Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"}
......@@ -76,11 +76,16 @@ func Init() {
func HttpGinLog() gin.HandlerFunc { //logger *log.Log
return func(c *gin.Context) {
startTime := time.Now().UnixNano()
//defer func() {
// if r := recover();r!=nil{
// fmt.Println("recover",r)
// }
//}()
startTime := time.Now().UnixMicro()
c.Next()
// stopTime := time.Since(startTime)
// spendTime := stopTime.Nanoseconds()/1000000///fmt.Sprintf("%d ms", (stopTime.Nanoseconds()+500000)/1000000)
spendTime := time.Now().UnixNano() - startTime
spendTime := time.Now().UnixMicro() - startTime
hostName, err := os.Hostname()
if err != nil {
hostName = "unknown"
......
......@@ -6,9 +6,12 @@ import (
"dc_golang_server_1/dbmodel"
"dc_golang_server_1/devproduct/dcphone20"
"dc_golang_server_1/logger"
"dc_golang_server_1/web"
"dc_golang_server_1/web/router"
"fmt"
"os"
"os/signal"
"runtime"
"syscall"
"time"
)
......@@ -26,13 +29,22 @@ func main() { //
config.Init()
logger.Init()
go func() {
osc := make(chan os.Signal, 1)
signal.Notify(osc, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)
s := <-osc
dbmodel.CloseDb()
fmt.Println("程序退出:", s)
os.Exit(1)
}()
dbmodel.InitDb()
defer dbmodel.CloseDb()
// defer dbmodel.CloseDb()
cache.Init()
dcphone20.NewDCPhone20()
//dcdrinking60.NewDCDrinking60()
web.InitRouter()
router.InitRouter()
}
package tencent
import "errors"
func TencentCode2Session(code string) (string, error) {
var testTemp = map[string]string{
"codeTest1": "unionIDTest1",
"codeTest2": "unionIDTest2",
"codeTest3": "unionIDTest3",
"codeTest4": "unionIDTest4",
"codeTest5": "unionIDTest5",
"codeTest6": "unionIDTest6",
"codeTest7": "unionIDTest7",
"codeTest8": "unionIDTest8",
"codeTest9": "unionIDTest8",
}
if len(testTemp[code]) > 0 {
return testTemp[code], nil
} else {
return "", errors.New("code无效")
}
}
//func JsCode2session(code string) (responseData WxOAuth2ResponseData, err error) {
// var NAME = "微信授权"
// var name = NAME+"-code2Session"
// var url = "https://web.weixin.qq.com/sns/jscode2session?appid=${appId}&secret=${secret}&js_code=${code}&grant_type=authorization_code"
// baseWechatPayConfig := getBaseWechatPayConfig(appId)
// url = strings.ReplaceAll(url,"${appId}",baseWechatPayConfig.appId)
// url = strings.ReplaceAll(url,"${secret}",baseWechatPayConfig.secret)
// url = strings.ReplaceAll(url,"${code}",code)
// logger.Log.Debug(name,
// zap.String("url", url))
// request, err := http.NewRequest(http.MethodGet, url,nil)
// client := http.DefaultClient
// response, err := client.Do(request)
// if err != nil {
// return responseData, err
// }
// defer func() {
// response.Body.Close()
// }()
// bodyBytes, err := ioutil.ReadAll(response.Body)
// logger.Log.Debug(name,
// zap.String("url", url),
// zap.String("response", string(bodyBytes)))
// if err != nil {
// return responseData, err
// }
// if err = json.Unmarshal(bodyBytes, &responseData); err != nil {
// return responseData, err
// }
// if responseData.Errmsg != "" {
// return responseData, errors.New(responseData.Errmsg)
// }
// return responseData, nil
//}
......@@ -22,7 +22,6 @@ func TestHex2Cipher(t *testing.T) {
// fmt.Printf("%02X",test[j])
// j++
// }
// fmt.Println()
//}
var b [3]byte
for i := 10002; i <= 11001; i++ {
......
package v1
package api_public
import (
"dc_golang_server_1/cache"
"dc_golang_server_1/logger"
"dc_golang_server_1/web"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
"strconv"
)
// GetProvinceList 获取省份列表
// @Tags 公用接口
// @Summary 获取全国省份列表
// @Summary 获取全国省份列表 [complete]
// @Description 获取带首字母的省份列表
// @Product json
// @Success 0 {object} []cache.DistrictStruct "按首字母排序好的列表,可直接用作展示"
......@@ -17,14 +20,14 @@ import (
// @Security ApiKeyAuth
func GetProvinceList(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
"code": web.Success,
"data": cache.ProvinceMap,
})
}
// GetCityList 获取城市或区县列表
// GetCityList 获取城市列表
// @Tags 公用接口
// @Summary 通过省份ID获取城市列表
// @Summary 通过省份ID获取城市列表 [complete]
// @Description 获取带首字母的城市列表
// @Param provinceID path integer true "省份id"
// @Product json
......@@ -36,14 +39,14 @@ func GetCityList(c *gin.Context) {
v, _ := cache.CityMap.Load(uint32(para)) // 如果查不到就直接返回空data
// data, _ := v.([]cache.DistrictStruct)
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
"code": web.Success,
"data": v,
})
}
// GetCountyList 获取区县列表
// @Tags 公用接口
// @Summary 通过城市ID获取区县列表
// @Summary 通过城市ID获取区县列表 [complete]
// @Description 获取带首字母的城市列表
// @Param cityID path integer true "城市ID"
// @Product json
......@@ -62,12 +65,12 @@ func GetCountyList(c *gin.Context) {
type countyAreaRes struct {
Name string `json:"name" example:"海科学校"`
ID int `json:"id" example:"1"`
ID uint32 `json:"id" example:"1"`
}
// GetAreaByCounty 根据区县ID获取学校列表
// @Tags 公用接口
// @Summary 根据区县ID获取学校列表
// @Summary 根据区县ID获取学校列表 [complete]
// @Description 根据区县ID获取学校列表
// @Param countyID path integer true "区县id" default(2725)
// @Product json
......@@ -75,21 +78,55 @@ type countyAreaRes struct {
// @Router /base/countyarea/{countyID} [GET]
// @Security ApiKeyAuth
func GetAreaByCounty(c *gin.Context) {
para, _ := strconv.Atoi(c.Param("id")) //todo
countyID, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": web.ErrorReqParaFormat,
"message": web.CodeMsg[web.ErrorReqParaFormat],
})
return
}
userID, ok := c.Get("userID")
if ok == false {
logger.Log.Error("userID在Context里面居然没填对,遇到鬼了",
zap.String("Src", "GetAreaByCounty"),
zap.Int("countyID", countyID))
c.JSON(http.StatusOK, gin.H{
"code": web.ErrorSystemErr,
"message": web.CodeMsg[web.ErrorSystemErr],
})
return
}
testRole, ok := cache.GetWechatCustomerTestRole(userID.(uint32))
if ok == false {
c.JSON(http.StatusOK, gin.H{
"code": web.ErrorUserTokenWrong,
"message": web.CodeMsg[web.ErrorUserTokenWrong],
})
return
}
areaList, ok := cache.GetCountyAreaMap(uint32(countyID))
if ok == false {
c.JSON(http.StatusOK, gin.H{
"code": web.ErrorReqPara,
"message": web.CodeMsg[web.ErrorReqPara] + ",区县id=" + strconv.Itoa(countyID),
})
return
}
var data []countyAreaRes
if para == 2725 {
v, _ := cache.AreaMap.Load(uint32(1)) //
if a, ok := v.(cache.AreaStruct); ok { //类型断言正确
data = append(data, countyAreaRes{
a.Name,
1,
})
for _, areaID := range areaList {
name := cache.GetAreaMapName(areaID, testRole)
if len(name) > 0 {
data = append(data, countyAreaRes{name, areaID})
}
}
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
"code": web.Success,
"data": data,
})
}
......@@ -102,7 +139,7 @@ type locationAreaRes struct {
// GetAreaByLocation 根据经纬度获取附近学校列表
// @Tags 公用接口
// @Summary 根据经纬度获取附近20所学校列表
// @Summary 根据经纬度获取附近20所学校列表 [can test]
// @Description 根据经纬度获取附近20所学校列表
// @Param longitude query integer true "经度*1000000" default(103000000)
// @Param latitude query integer true "纬度*1000000" default(30000000)
......@@ -143,17 +180,17 @@ func GetAreaByLocation(c *gin.Context) {
}
var data []locationAreaRes
v, _ := cache.AreaMap.Load(uint32(1)) // todo 根据经纬度计算距离 还要看status 和 用户的权限
v, _ := cache.AreaMap.Load(uint32(14)) // todo 根据经纬度计算距离 还要看status 和 用户的权限
if a, ok := v.(cache.AreaStruct); ok { //类型断言正确
data = append(data, locationAreaRes{
a.Name,
"四川省成都市温江区",
1,
"温江区",
14,
})
}
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
"code": web.Success,
"data": data,
})
}
package api_we
import (
"dc_golang_server_1/web"
//"dc_golang_server_1/web"
"github.com/gin-gonic/gin"
"net/http"
"time"
)
// DeleteCardUser 主家长删除一个学生
// @Tags 家长微信
// @Summary 主家长删除一个学生
// @Description 传学生ID至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Success 0
// @Router /we/carduser/{id} [DELETE]
// @Security ApiKeyAuth
func DeleteCardUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
})
}
type bindCardUserRes struct {
Master bool `json:"master" example:"false"` //true:本来就是主家长,false:已成功绑定成副家长
ID uint32 `json:"id"` // 学生ID
Name string `json:"name"`
Sex uint8 `json:"sex"` // 0女 1男
Area string `json:"area" example:"四川省成都市温江区实验中学"` // 区域名字
Grade int8 `json:"grade"` // "1~9对应一年级~九年级,10~12对应高一~高三"
Class int8 `json:"class"`
StuNum string `json:"stuNum"`
Service []uint8 `json:"service" example:"1,2,2,0,0,0"` // 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
}
// BindCardUser 通过邀请码绑定学生
// @Tags 家长微信
// @Summary 通过邀请码绑定学生
// @Description 传学生的邀请码,后台返回学生信息
// @Produce json
// @Param share_code path string true "学生的邀请码"
// @Success 0 {object} bindCardUserRes "学生信息"
// @Failure 30 "邀请码无效"
// @Failure 31 "邀请码已过期"
// @Router /we/bindcarduser/{share_code} [POST]
// @Security ApiKeyAuth
func BindCardUser(c *gin.Context) {
res := bindCardUserRes{}
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
"data": res,
})
}
// DeleteBindCardUser 副家长解绑学生
// @Tags 家长微信
// @Summary 副家长解绑学生
// @Description 传学生ID至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Success 0
// @Router /we/bindcarduser/{id} [DELETE]
// @Security ApiKeyAuth
func DeleteBindCardUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
})
}
type wechatCardUsersTrendType struct {
ServiceType uint8 `json:"service"` //服务项目 1公话2定位3饮水4卡消费5洗浴6洗衣机 决定UI图标及颜色等
TrendName string `json:"title"` //显示在第一行
Content string `json:"content"` //显示在第二行
Time string `json:"time"` //显示在第三行
}
// GetCardUsersTrend 微信学生首页,获取近10条用户最新动态
// @Tags 家长微信
// @Summary 微信学生首页,获取近20条用户最新动态
// @Description 微信学生首页,获取近20条用户最新动态
// @Param id path integer true "学生ID"
// @Product json
// @Success 200 {object} wechatCardUsersTrendType "学生动态信息"
// @Router /we/trend/{id} [GET]
// @Security ApiKeyAuth
func GetCardUsersTrend(c *gin.Context) {
//id, _ := strconv.Atoi(c.Param("id"))
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
"data": [20]wechatCardUsersTrendType{},
})
}
type slaveWeUserRes struct {
// 微信UnionID
WeUserID uint32 `json:"weUserID"`
// 微信昵称
Nickname string `json:"nickname"`
// 头像URL
AvatarURL string `json:"avatarURL"`
// 手机号
Phone string `json:"phone"`
// 绑定时间
CreateAt time.Time `json:"createAt"`
}
//type getBindCardUserRes struct {
// // 副家长微信信息列表
// WeUser []slaveWeUserRes `json:"weUser"`
// // 学生的邀请码,长度固定16,若为空,则表示邀请码开关关闭
// ShareCode string `json:"shareCode"`
//}
// GetBindCardUser 获取学生副家长列表(仅主家长有权限)
// @Tags 家长微信
// @Summary 获取学生副家长列表(仅主家长有权限)
// @Description 传学生ID至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Success 0 {object} []slaveWeUserRes "副家长信息列表"
// @Router /we/bindcarduser/{id} [GET]
// @Security ApiKeyAuth
func GetBindCardUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
"data": []slaveWeUserRes{},
})
}
// CardUserShareCode 获取邀请码(仅主家长有权限)
// @Tags 家长微信
// @Summary 获取邀请码(仅主家长有权限)
// @Description 主家长生成邀请码,有效时长可选1分钟~60分钟
// @Produce json
// @Param id path integer true "学生ID"
// @Param time query integer false "有效时长,1~60分钟,不填则为60分钟" default(60)
// @Success 0 {object} string "邀请码内容"
// @Router /we/sharecode/{id} [GET]
// @Security ApiKeyAuth
func CardUserShareCode(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
"data": "todo",
})
}
//// PutCardUserShareOn 打开邀请码开关(仅主家长有权限)
//// @Tags 家长微信
//// @Summary 打开邀请码开关(仅主家长有权限)
//// @Description 传学生ID至后台,后台返回成功失败
//// @Produce json
//// @Param id path integer true "学生ID"
//// @Success 0
//// @Router /we/cardusershareon/{id} [PUT]
//// @Security ApiKeyAuth
//func PutCardUserShareOn(c *gin.Context) {
// c.JSON(http.StatusOK, gin.H{
// "code": web.Success,
// })
//}
//// PutCardUserShareOff 关闭邀请码开关(仅主家长有权限)
//// @Tags 家长微信
//// @Summary 关闭邀请码开关(仅主家长有权限)
//// @Description 传学生ID至后台,后台返回成功失败
//// @Produce json
//// @Param id path integer true "学生ID"
//// @Success 0
//// @Router /we/cardusershareoff/{id} [PUT]
//// @Security ApiKeyAuth
//func PutCardUserShareOff(c *gin.Context) {
// c.JSON(http.StatusOK, gin.H{
// "code": web.Success,
// })
//}
// DeleteSlaveWeUser 删除副家长(仅主家长有权限)
// @Tags 家长微信
// @Summary 删除副家长(仅主家长有权限)
// @Description 传学生ID和微信UnionID,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param weUserID query integer true "副家长微信weUserID"
// @Success 0
// @Router /we/slaveweuser/{id} [DELETE]
// @Security ApiKeyAuth
func DeleteSlaveWeUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
})
}
//// DeleteAllSlaveWeUser 清空所有副家长(仅主家长有权限)
//// @Tags 家长微信
//// @Summary 删除副家长(仅主家长有权限)
//// @Description 传学生ID和微信UnionID,后台返回成功失败
//// @Produce json
//// @Param id path integer true "学生ID"
//// @Param unionid query string true "副家长微信UnionID"
//// @Success 0
//// @Router /we/allslaveweuser/{id} [DELETE]
//// @Security ApiKeyAuth
//func DeleteAllSlaveWeUser(c *gin.Context) {
// c.JSON(http.StatusOK, gin.H{
// "code": web.Success,
// })
//}
type PutCardUserReq struct {
// 必填,学生名字,maxLen=16
Name string `json:"name" example:"汤圆"`
// 必填,"1~9对应一年级~九年级,10~12对应高一~高三"
Grade int8 `json:"grade"`
// 选填,0女1男
Sex uint8 `json:"sex,omitempty"`
// 选填,班级,number
Class int8 `json:"class,omitempty"`
// 选填,学号,字符串,maxLen=32
StudentNo string `json:"stuNum,omitempty"`
}
// PutCardUser 修改学生信息
// @Tags 家长微信
// @Summary 修改学生信息
// @Description 传学生id及新信息至后台,后台返回成功失败
// @Accept json
// @Produce json
// @Param id path integer true "学生ID"
// @Param data body PutCardUserReq true "学生信息"
// @Success 0
// @Router /we/carduser/{id} [PUT]
// @Security ApiKeyAuth
func PutCardUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
})
}
// CardLoss 卡挂失/解挂
// @Tags 家长微信
// @Summary 卡挂失/解挂
// @Description 传学生id及卡类型至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param loss query bool true "true挂失,false解挂"
// @Param type query integer true "卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)"
// @Success 0
// @Router /we/cardloss/{id} [PUT]
// @Security ApiKeyAuth
func CardLoss(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
})
}
// CardBind 绑定卡
// @Tags 家长微信
// @Summary 绑定卡
// @Description 传学生id及卡类型、卡号至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param code query string true "卡号"
// @Param type query integer true "卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)"
// @Success 0
// @Router /we/cardbind/{id} [PUT]
// @Security ApiKeyAuth
func CardBind(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
})
}
// DeleteCardBind 解绑卡
// @Tags 家长微信
// @Summary 解绑卡
// @Description 传学生id及卡类型至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param type query integer true "卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)"
// @Success 0
// @Router /we/cardbind/{id} [DELETE]
// @Security ApiKeyAuth
func DeleteCardBind(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
})
}
type familyNumStruct struct {
Phone string `json:"phone"`
Name string `json:"name"`
}
type getPhoneCardStatusRes struct {
Status uint8 `json:"status"` // 状态 0未绑定卡 1 正常使用 2 服务已到期 3 已挂失
SimID string `json:"simID"` // 卡号
ExpiryAt time.Time `json:"expiryAt"` // 到期时间
MonthMin uint16 `json:"monthMin"` // 月套餐使用分钟数
MonthPack uint16 `json:"monthPack"` // 月套餐分钟数
Changeable uint8 `json:"changeable"` // 本月可修改亲情号次数
Family []familyNumStruct `json:"family"` // 亲情号列表
}
// GetPhoneCardStatus 获取学生公话卡状态
// @Tags 家长微信
// @Summary 获取学生公话卡状态
// @Description 传学生ID至后台,后台返回卡信息
// @Produce json
// @Param id path integer true "学生ID"
// @Success 0 {object} getPhoneCardStatusRes "公话卡状态信息"
// @Router /we/phonecardstatus/{id} [GET]
// @Security ApiKeyAuth
func GetPhoneCardStatus(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
"data": getPhoneCardStatusRes{},
})
}
type getCallRecordRes struct {
// 被叫号码
CalledNumber string `json:"number"`
// 昵称
CalledNickname string `json:"nickname"`
// 通话开始时间
CallStartAt time.Time `json:"startAt"`
// 通话时长,单位(分钟)
TalkTime uint8 `json:"time"`
}
// GetCallRecord 查询通话记录
// @Tags 家长微信
// @Summary 查询通话记录
// @Description 传学生ID至后台,后台返回通话记录列表
// @Produce json
// @Param id path integer true "学生ID"
// @Param pnum query integer true "页数"
// @Param psize query integer true "页条数"
// @Param start query string false "起始时间 2020-10-10 10:00:00"
// @Param end query string false "结束时间 2030-10-10 10:00:00"
// @Param asc query bool false "是否升序" default(false)
// @Success 0 {object} []getCallRecordRes "通话记录列表"
// @Router /we/callrecord/{id} [GET]
// @Security ApiKeyAuth
func GetCallRecord(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
"data": [2]getCallRecordRes{},
})
}
// AddFamilyNum 添加亲情号
// @Tags 家长微信
// @Summary 添加亲情号
// @Description 家长绑定亲情号接口
// @Accept json
// @Produce json
// @Param id path integer true "学生ID"
// @Param data body familyNumStruct true "亲情号内容"
// @Success 0
// @Router /we/familynum [POST]
// @Security ApiKeyAuth
func AddFamilyNum(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
})
}
// PutFamilyNum 修改亲情号
// @Tags 家长微信
// @Summary 修改亲情号
// @Description 修改亲情号接口
// @Accept json
// @Produce json
// @Param id path integer true "学生ID"
// @Param phone query string true "电话号码"
// @Param data body familyNumStruct true "亲情号内容"
// @Success 0
// @Router /we/familynum [PUT]
// @Security ApiKeyAuth
func PutFamilyNum(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
})
}
// DeleteFamilyNum 删除亲情号
// @Tags 家长微信
// @Summary 删除亲情号
// @Description 删除亲情号接口
// @Accept json
// @Produce json
// @Param id path integer true "学生ID"
// @Param phone query string true "电话号码"
// @Success 0
// @Router /we/familynum [DELETE]
// @Security ApiKeyAuth
func DeleteFamilyNum(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": web.Success,
})
}
package web
const (
Success = 0
ErrorTokenExist = 1
ErrorTokenWrong = 2
ErrorTokenRunTime = 3
ErrorTokenExit = 4
ErrorUserRole = 5
ErrorSystemErr = 6
ErrorTencentErr = 7
ErrorReqParaFormat = 10
ErrorReqPara = 11
ErrorReqInsertDuplicate = 12
ErrorUserTokenWrong = 1001
ErrorWechatLogin = 1002
ErrorReq
//ERROR = 500
// code = 1000...用户模块的错误
//ERROR_USERNAME_USED = 1001
//ERROR_PASSWORD_WRONG = 1002
//ERROR_USER_NOT_EXIST = 1003
//ERROR_TOKEN_EXIST = 1004
//ERROR_TOKEN_RUNTIME = 1005
//ERROR_TOKEN_WRONG = 1006
//ERROR_TOKEN_TYPE_WRONG = 1007
//ERROR_USER_NO_RIGHT = 1008
// code = 2000...XXXXX模块的错误
// code = 3000...XXXXX模块的错误
)
var CodeMsg = map[uint16]string{
ErrorTokenExist: "token不存在",
ErrorTokenWrong: "非法token",
ErrorTokenRunTime: "token过期",
ErrorTokenExit: "token已退出登录",
ErrorUserRole: "用户没有权限",
ErrorSystemErr: "系统错误,请尝试重新登录(开发测试人员请联系开发人员)",
ErrorTencentErr: "微信服务器返回的错误:",
ErrorReqPara: "请求参数内容(取值)错误",
ErrorReqParaFormat: "请求参数格式错误",
ErrorReqInsertDuplicate: "内容重复,无法创建",
ErrorUserTokenWrong: "用户token错误,系统找不到用户信息,请重新登录",
ErrorWechatLogin: "微信登录错误:",
// Success: "OK",
// ERROR: "FAIL",
// ERROR_USERNAME_USED: "用户名已存在!",
// ERROR_PASSWORD_WRONG: "密码错误",
// ERROR_USER_NOT_EXIST: "用户不存在",
// ERROR_TOKEN_EXIST: "TOKEN不存在",
// ERROR_TOKEN_RUNTIME: "TOKEN已过期",
// ERROR_TOKEN_WRONG: "TOKEN不正确",
// ERROR_TOKEN_TYPE_WRONG: "TOKEN格式错误",
// ERROR_USER_NO_RIGHT: "用户没有权限",
}
......@@ -4,8 +4,8 @@ import (
"dc_golang_server_1/cache"
"dc_golang_server_1/util"
"github.com/gin-gonic/gin"
"math/rand"
"net/http"
"strings"
"time"
)
......@@ -13,105 +13,277 @@ const jeffWTKey = "jeffWT@666%b;'~+"
//const jeffWTTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
//type jeffWTInfo struct {
// //UID int32
// CreatTime int64
// ExpireTime uint32
// UserName string // 最长30字节
// Admin bool
//}
const tokenClearLen = 20
const tokenLen = 28
// 定义错误
//var (
// TokenExpired error = errors.New("Token已过期,请重新登录")
// TokenNotValidYet error = errors.New("Token无效,请重新登录")
// TokenMalformed error = errors.New("Token不正确,请重新登录")
// TokenInvalid error = errors.New("这不是一个token,请重新登录")
//)
type TokenResult struct {
CreatTime int64 //token创建时间
UserID uint32 //
ExpireTime uint32
UserType uint8 // 1微信家长 2后台用户 其余预留
CheckResult uint8
}
// CreateToken 生成token,duration单位秒,=0表示不限时长
func CreateToken(creatTime int64, userID uint32, userType uint8, duration uint32) string {
var expireTime uint32
if duration == 0 {
expireTime = 0xffffffff
} else {
expireTime = uint32(creatTime/1000000) + duration
}
var clear = make([]byte, tokenClearLen) //7字节创建时间 4字节结束时间 4字节有效时长 2字节CRC 3字节随机数预留
r := rand.New(rand.NewSource(time.Now().UnixNano()))
random := byte(r.Intn(256))
const tokenLen = 60
clear[0] = ^byte(userID>>24) - random
clear[1] = byte(expireTime>>16) - random
clear[2] = byte(userID>>16) + random + 166
clear[3] = ^byte(creatTime>>24) - random
clear[4] = byte(creatTime>>48) - random + 23
clear[5] = ^byte(expireTime >> 8)
clear[6] = byte(creatTime>>32) + random + 66
clear[7] = byte(expireTime>>24) + random + 99
clear[8] = byte(creatTime>>16) + random - 88
clear[9] = ^byte(userID)
clear[10] = byte(creatTime) - 69
clear[11] = byte(expireTime) + random + 27
clear[12] = byte(userID>>8) - random - 33
clear[13] = ^byte(creatTime>>40) - random - 28
clear[14] = byte(creatTime>>8) - random - 69
clear[15] = ^random + 0x5a
clear[16] = userType - random
clear[17] = 0x1a + random
util.GetCRC(clear, 18)
clear[18] = ^(clear[18] + random - 15)
clear[19] = ^clear[19] - random
// CreateToken 生成token,duration=0表示不限时长
func CreateToken(creatTime int64, userName string, admin bool, duration uint32) string {
expireTime := uint32(creatTime/1000000) + duration
return util.EncryptBytesToBase64URL(clear, jeffWTKey)
}
var clear = make([]byte, 44) //8字节创建时间 4字节结束时间 30字节userName 2字节CRC
func DecryptToken(token string) (clearStruct TokenResult) {
if len(token) != tokenLen {
// todo logger token长度错误
clearStruct.CheckResult = ErrorTokenExist
return
}
clear, err := util.DecryptBase64URLToBytes(token, jeffWTKey)
if err != nil {
// todo logger 有人在非法请求
clearStruct.CheckResult = ErrorTokenWrong
return
}
if len(clear) != tokenClearLen {
// todo logger 有人在非法请求
clearStruct.CheckResult = ErrorTokenWrong
return
}
//clear[15] = ^random + 0x5a
//clear[17] = 0x1a + random
//util.GetCRC(clear[:18], 18)
//clear[18] = ^(clear[18] + random - 15)
//clear[19] = ^clear[19] - random
random := clear[17] - 0x1a
if clear[15] != ^random+0x5a {
// todo logger 有人在非法请求
clearStruct.CheckResult = ErrorTokenWrong
return
}
clear[18] = ^clear[18] - random + 15
clear[19] = ^(clear[19] + random)
if util.CheckCRC(clear) == false {
// todo logger
clearStruct.CheckResult = ErrorTokenWrong
return
}
//r := rand.New(rand.NewSource(time.Now().UnixNano()))
if len(userName) > 30 {
return ""
//clear[11] = byte(expireTime) + random + 27
//clear[5] = ^byte(expireTime >> 8)
//clear[1] = byte(expireTime>>16) - random
//clear[7] = byte(expireTime>>24) + random + 99
clearStruct.ExpireTime = (uint32(clear[11] - 27 - random)) +
(uint32(^clear[5]) << 8) +
(uint32(clear[1]+random) << 16) +
(uint32(clear[7]-random-99) << 24)
if uint32(time.Now().Unix()) > clearStruct.ExpireTime { // 到期时间已经过了
clearStruct.CheckResult = ErrorTokenRunTime
return
}
random := byte(creatTime)
var str [30]byte
for i := 0; i < len(userName); i++ {
str[i] = userName[i] + (uint8(i) << 2) + random
//clear[10] = byte(creatTime) - 69
//clear[14] = byte(creatTime>>8) - random - 69
//clear[8] = byte(creatTime>>16) + random - 88
//clear[3] = ^byte(creatTime>>24) - random
//clear[6] = byte(creatTime>>32) + random + 66
//clear[13] = ^byte(creatTime>>40) - random - 28
//clear[4] = byte(creatTime >> 48) - random + 23
clearStruct.CreatTime = int64(clear[10]+69) +
(int64(clear[14]+69+random) << 8) +
(int64(clear[8]+88-random) << 16) +
(int64(^(clear[3] + random)) << 24) +
(int64(clear[6]-66-random) << 32) +
(int64(^(clear[13] + 28 + random)) << 40) +
(int64(clear[4]-23+random) << 48)
if time.Now().UnixMicro() < clearStruct.CreatTime { // 创建时间居然大于当前时间
// todo logger
clearStruct.CheckResult = ErrorTokenWrong
return
}
clear[0] = str[8]
clear[1] = str[25]
clear[2] = byte(expireTime) + random + 27
clear[3] = str[27]
clear[4] = str[15]
clear[5] = str[19]
clear[6] = str[11]
clear[7] = str[23]
clear[8] = str[6]
clear[9] = str[28]
clear[10] = byte(creatTime>>32) + random + 66
clear[11] = str[16]
clear[12] = ^random + 0x5a
clear[13] = str[17]
clear[14] = str[3]
clear[15] = str[21]
clear[16] = str[1]
clear[17] = byte(expireTime>>16) - random
clear[18] = str[0]
clear[19] = str[4]
clear[20] = ^byte(expireTime >> 8)
clear[21] = str[5]
clear[22] = byte(len(userName)) + random
clear[23] = str[7]
clear[24] = str[9]
clear[25] = str[10]
clear[26] = byte(expireTime>>24) + random + 99
clear[27] = str[12]
clear[28] = str[13]
clear[29] = str[14]
clear[30] = byte(creatTime >> 48)
if admin {
clear[30] |= 0x80
//clear[9] = ^byte(userID)
//clear[12] = byte(userID>>8) - random - 33
//clear[2] = byte(userID>>16) + random + 166
//clear[0] = ^byte(userID>>24) - random
clearStruct.UserID = uint32(^clear[9]) +
(uint32(clear[12]+33+random) << 8) +
(uint32(clear[2]-166-random) << 16) +
(uint32(^(clear[0] + random)) << 24)
clearStruct.UserType = clear[16] + random
if clearStruct.UserType != 1 && clearStruct.UserType != 2 {
// todo logger
clearStruct.CheckResult = ErrorTokenWrong
}
clear[31] = str[18]
clear[32] = str[20]
clear[33] = str[22]
clear[34] = str[2]
clear[35] = byte(creatTime>>16) + random - 88
clear[36] = ^byte(creatTime>>40) - random - 28
clear[37] = str[24]
clear[38] = str[26]
clear[39] = str[29]
clear[40] = ^byte(creatTime>>24) - random
clear[41] = byte(creatTime>>8) - random - 69
util.GetCRC(clear[:42], 42)
clear[42] = ^(clear[42] + random)
clear[43] = ^clear[43] - random
//if clearStruct.UserType == 2 {
// if clearStruct.CreatTime < cache.GetAdminTokenCreatTime(clearStruct.UserID) {
// clearStruct.CheckResult = errorTokenExit
// return
// }
//} else if clearStruct.UserType == 1 {
// if clearStruct.CreatTime < cache.GetWechatCustomerTokenCreatTime(clearStruct.UserID) {
// clearStruct.CheckResult = errorTokenExit
// return
// }
//}
return
}
return util.EncryptBytesToBase64URL(clear, jeffWTKey)
func CheckTokenExit(clearStruct *TokenResult) {
if clearStruct.UserType == 2 {
if clearStruct.CreatTime < cache.GetAdminTokenCreatTime(clearStruct.UserID) {
clearStruct.CheckResult = ErrorTokenExit
return
}
} else if clearStruct.UserType == 1 {
if clearStruct.CreatTime < cache.GetWechatCustomerTokenCreatTime(clearStruct.UserID) {
clearStruct.CheckResult = ErrorTokenExit
return
}
}
}
func JeffWTPublic() gin.HandlerFunc {
return func(c *gin.Context) {
clearStruct := DecryptToken(c.Request.Header.Get("token"))
if clearStruct.CheckResult == Success {
CheckTokenExit(&clearStruct)
}
if clearStruct.CheckResult != Success { //必须要这个判断,因为CheckTokenExit(&clearStruct)会改变
c.JSON(http.StatusOK, gin.H{
"status": clearStruct.CheckResult,
"message": CodeMsg[uint16(clearStruct.CheckResult)],
})
c.Abort()
return
}
c.Set("userID", clearStruct.UserID)
c.Next()
}
}
func JeffWTWechat() gin.HandlerFunc {
return func(c *gin.Context) {
clearStruct := DecryptToken(c.Request.Header.Get("token"))
if clearStruct.UserType != 1 {
c.JSON(http.StatusOK, gin.H{
"status": ErrorUserRole,
"message": CodeMsg[ErrorUserRole],
})
c.Abort()
return
}
if clearStruct.CheckResult == Success {
CheckTokenExit(&clearStruct)
}
if clearStruct.CheckResult != Success {
c.JSON(http.StatusOK, gin.H{
"status": clearStruct.CheckResult,
"message": CodeMsg[uint16(clearStruct.CheckResult)],
})
c.Abort()
return
}
c.Set("userID", clearStruct.UserID)
c.Next()
}
}
func JeffWTAdmin() gin.HandlerFunc {
return func(c *gin.Context) {
clearStruct := DecryptToken(c.Request.Header.Get("token"))
if clearStruct.UserType != 2 {
c.JSON(http.StatusOK, gin.H{
"status": ErrorUserRole,
"message": CodeMsg[ErrorUserRole],
})
c.Abort()
return
}
if clearStruct.CheckResult == Success {
CheckTokenExit(&clearStruct)
}
if clearStruct.CheckResult != Success {
c.JSON(http.StatusOK, gin.H{
"status": clearStruct.CheckResult,
"message": CodeMsg[uint16(clearStruct.CheckResult)],
})
c.Abort()
return
}
c.Set("userID", clearStruct.UserID)
c.Next()
}
}
//func CreateToken(creatTime int64, userName string, duration uint32) string {
// expireTime := uint32(creatTime/1000000) + duration
//package web
//
//import (
// "dc_golang_server_1/cache"
// "dc_golang_server_1/util"
// "github.com/gin-gonic/gin"
// "net/http"
// "time"
//)
//
//const jeffWTKey = "jeffWT@666%b;'~+"
//
////const jeffWTTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
//
//const tokenLen = 60
//
//type TokenResult struct {
// CreatTime int64 //token创建时间
// UserID string //
// Admin bool
// Duration uint32
//}
//
//// CreateToken 生成token,duration=0表示不限时长
//func CreateToken(t TokenResult) string {
// expireTime := uint32(t.CreatTime/1000000) + t.Duration
//
// var clear = make([]byte, 44) //8字节创建时间 4字节结束时间 30字节userName 2字节CRC
//
// //r := rand.New(rand.NewSource(time.Now().UnixNano()))
// if len(userName) > 30 {
// if len(t.UserID) > 30 {
// return ""
// }
// random := byte(creatTime)
// random := byte(t.CreatTime)
// var str [30]byte
// for i := 0; i < len(userName); i++ {
// str[i] = userName[i] + (uint8(i) << 2) + random
// for i := 0; i < len(t.UserID); i++ {
// str[i] = t.UserID[i] + (uint8(i) << 2) + random
// }
//
// clear[0] = str[8]
......@@ -124,7 +296,7 @@ func CreateToken(creatTime int64, userName string, admin bool, duration uint32)
// clear[7] = str[23]
// clear[8] = str[6]
// clear[9] = str[28]
// clear[10] = byte(creatTime>>32) + random + 66
// clear[10] = byte(t.CreatTime>>32) + random + 66
// clear[11] = str[16]
// clear[12] = ^random + 0x5a
// clear[13] = str[17]
......@@ -136,7 +308,7 @@ func CreateToken(creatTime int64, userName string, admin bool, duration uint32)
// clear[19] = str[4]
// clear[20] = ^byte(expireTime >> 8)
// clear[21] = str[5]
// clear[22] = byte(len(userName)) + random
// clear[22] = byte(len(t.UserID)) + random
// clear[23] = str[7]
// clear[24] = str[9]
// clear[25] = str[10]
......@@ -144,201 +316,218 @@ func CreateToken(creatTime int64, userName string, admin bool, duration uint32)
// clear[27] = str[12]
// clear[28] = str[13]
// clear[29] = str[14]
// clear[30] = byte(creatTime >> 48)
// clear[30] = byte(t.CreatTime >> 48)
// if t.Admin {
// clear[30] |= 0x80
// }
// clear[31] = str[18]
// clear[32] = str[20]
// clear[33] = str[22]
// clear[34] = str[2]
// clear[35] = byte(creatTime>>16) + random - 88
// clear[36] = ^byte(creatTime>>40) - random - 28
// clear[35] = byte(t.CreatTime>>16) + random - 88
// clear[36] = ^byte(t.CreatTime>>40) - random - 28
// clear[37] = str[24]
// clear[38] = str[26]
// clear[39] = str[29]
// clear[40] = ^byte(creatTime>>24) - random
// clear[41] = byte(creatTime>>8) - random - 69
// clear[40] = ^byte(t.CreatTime>>24) - random
// clear[41] = byte(t.CreatTime>>8) - random - 69
// util.GetCRC(clear[:42], 42)
// clear[42] = ^(clear[42] + random)
// clear[43] = ^clear[43] - random
//
// return util.EncryptBytesToBase64URL(clear, jeffWTKey)
//}
func CheckToken() gin.HandlerFunc {
return func(c *gin.Context) {
tokenHeader := c.Request.Header.Get("Authorization")
if tokenHeader == "" {
c.JSON(http.StatusOK, gin.H{
"status": 1004,
"message": "token不存在",
})
c.Abort()
return
}
checkToken := strings.Split(tokenHeader, " ")
if len(checkToken) == 0 {
c.JSON(http.StatusOK, gin.H{
"status": 1007,
"message": "TOKEN格式错误",
})
c.Abort()
return
}
if len(checkToken) != 2 || checkToken[0] != "Bearer" {
c.JSON(http.StatusOK, gin.H{
"status": 1007,
"message": "TOKEN格式错误",
})
c.Abort()
return
}
if len(checkToken[1]) != tokenLen {
// todo logger 有人在非法请求
c.JSON(http.StatusOK, gin.H{
"status": 1004,
"message": "token长度错误",
})
c.Abort()
return
}
clear, err := util.DecryptBase64URLToBytes(checkToken[1], jeffWTKey)
if err != nil {
// todo logger 有人在非法请求
c.JSON(http.StatusOK, gin.H{
"status": 1006,
"message": "TOKEN不正确",
})
c.Abort()
return //errors.New("TOKEN格式错误")//err
}
if len(clear) != 44 {
// todo logger
c.JSON(http.StatusOK, gin.H{
"status": 1006,
"message": "TOKEN不正确",
})
c.Abort()
return //errors.New("TOKEN格式错误")//err//return info,false //errors.New("TOKEN格式错误")//("明文长度错误")
}
random := clear[12] - 0x5a
clear[42] = ^clear[42] - random
clear[43] = ^(clear[43] + random)
if util.CheckCRC(clear) == false {
// todo logger
c.JSON(http.StatusOK, gin.H{
"status": 1006,
"message": "TOKEN不正确",
})
c.Abort()
return ////errors.New("TOKEN格式错误")//("明文校验错误")
}
userNameLen := clear[22] - random
if userNameLen < 1 || userNameLen > 30 {
// todo logger
c.JSON(http.StatusOK, gin.H{
"status": 1006,
"message": "TOKEN不正确",
})
c.Abort()
return ////errors.New("TOKEN格式错误")//("登录名长度错误")
}
var admin bool
if clear[30]&0x80 == 0x80 {
admin = true
clear[30] &= 0x7f
}
expireTime := (uint32(clear[2] - 27 - random)) +
(uint32(^clear[20]) << 8) +
(uint32(clear[17]+random) << 16) +
(uint32(clear[26]+random) << 24)
if expireTime > uint32(time.Now().Unix()) {
c.JSON(http.StatusOK, gin.H{
"status": 1005,
"message": "登录已过期",
})
c.Abort()
return
}
creatTime := int64(random) +
(int64(clear[41]+69+random) << 8) +
(int64(clear[35]+88-random) << 16) +
(int64(^(clear[40] + random)) << 24) +
(int64(clear[10]-66-random) << 32) +
(int64(^(clear[36] + 28 + random)) << 40) +
(int64(clear[30]-8-random) << 48)
if expireTime < uint32(creatTime/1000000) {
// todo logger
c.JSON(http.StatusOK, gin.H{
"status": 1006,
"message": "TOKEN不正确",
})
c.Abort()
return //
}
var str [30]byte
str[8] = clear[0]
str[25] = clear[1]
str[27] = clear[3]
str[15] = clear[4]
str[19] = clear[5]
str[11] = clear[6]
str[23] = clear[7]
str[6] = clear[8]
str[28] = clear[9]
str[16] = clear[11]
str[17] = clear[13]
str[3] = clear[14]
str[21] = clear[15]
str[1] = clear[16]
str[0] = clear[18]
str[4] = clear[19]
str[5] = clear[21]
str[7] = clear[23]
str[9] = clear[24]
str[10] = clear[25]
str[12] = clear[27]
str[13] = clear[28]
str[14] = clear[29]
str[18] = clear[31]
str[20] = clear[32]
str[22] = clear[33]
str[2] = clear[34]
str[24] = clear[37]
str[26] = clear[38]
str[29] = clear[39]
for i := uint8(0); i < userNameLen; i++ {
str[i] = str[i] - random - (i << 2)
}
userName := string(str[:userNameLen])
if admin {
// todo 查cache 已退出登录
} else {
// todo 查cache 已退出登录
cacheCreatTime := cache.GetWechatCustomerTokenCreatTime(userName)
if cacheCreatTime > creatTime { //如果缓存里面存的CreatTime比token里面的CreatTime要晚,则token已退出登录
// todo logger warn
c.JSON(http.StatusOK, gin.H{
"status": 1006,
"message": "用户已退出登录",
})
c.Abort()
return //
}
}
c.Set("username", userName)
c.Next()
}
}
//
//func CheckToken(token string)TokenResult{
// return TokenResult{}
//}
//
//func JeffWT() gin.HandlerFunc {
// return func(c *gin.Context) {
// //tokenHeader := c.Request.Header.Get("Authorization")
// //if tokenHeader == "" {
// // c.JSON(http.StatusOK, gin.H{
// // "status": 1004,
// // "message": "token不存在",
// // })
// // c.Abort()
// // return
// //}
// //
// //checkToken := strings.Split(tokenHeader, " ")
// //if len(checkToken) == 0 {
// // c.JSON(http.StatusOK, gin.H{
// // "status": 1007,
// // "message": "TOKEN格式错误",
// // })
// // c.Abort()
// // return
// //}
// //
// //if len(checkToken) != 2 || checkToken[0] != "Bearer" {
// // c.JSON(http.StatusOK, gin.H{
// // "status": 1007,
// // "message": "TOKEN格式错误",
// // })
// // c.Abort()
// // return
// //}
// //
// //if len(checkToken[1]) != tokenLen {
// // // todoN logger 有人在非法请求
// // c.JSON(http.StatusOK, gin.H{
// // "status": 1004,
// // "message": "token长度错误",
// // })
// // c.Abort()
// // return
// //}
// tokenHeader := c.Request.Header.Get("token")
// if len(tokenHeader) != tokenLen {
// // todo logger 有人在非法请求
// c.JSON(http.StatusOK, gin.H{
// "code": 1004,
// "message": "token长度错误",
// })
// c.Abort()
// return
// }
//
// clear, err := util.DecryptBase64URLToBytes(tokenHeader, jeffWTKey)
// if err != nil {
// // todo logger 有人在非法请求
// c.JSON(http.StatusOK, gin.H{
// "code": 1006,
// "message": "TOKEN不正确",
// })
// c.Abort()
// return //errors.New("TOKEN格式错误")//err
// }
// if len(clear) != 44 {
// // todo logger
// c.JSON(http.StatusOK, gin.H{
// "code": 1006,
// "message": "TOKEN不正确",
// })
// c.Abort()
// return //errors.New("TOKEN格式错误")//err//return info,false //errors.New("TOKEN格式错误")//("明文长度错误")
// }
//
// random := clear[12] - 0x5a
// clear[42] = ^clear[42] - random
// clear[43] = ^(clear[43] + random)
// if util.CheckCRC(clear) == false {
// // todo logger
// c.JSON(http.StatusOK, gin.H{
// "code": 1006,
// "message": "TOKEN不正确",
// })
// c.Abort()
// return ////errors.New("TOKEN格式错误")//("明文校验错误")
// }
//
// userNameLen := clear[22] - random
// if userNameLen < 1 || userNameLen > 30 {
// // todo logger
// c.JSON(http.StatusOK, gin.H{
// "code": 1006,
// "message": "TOKEN不正确",
// })
// c.Abort()
// return ////errors.New("TOKEN格式错误")//("登录名长度错误")
// }
//
// var admin bool
// if clear[30]&0x80 == 0x80 {
// admin = true
// clear[30] &= 0x7f
// }
//
// expireTime := (uint32(clear[2] - 27 - random)) +
// (uint32(^clear[20]) << 8) +
// (uint32(clear[17]+random) << 16) +
// (uint32(clear[26]+random) << 24)
// if expireTime > uint32(time.Now().Unix()) {
// c.JSON(http.StatusOK, gin.H{
// "code": 1005,
// "message": "登录已过期",
// })
// c.Abort()
// return
// }
// creatTime := int64(random) +
// (int64(clear[41]+69+random) << 8) +
// (int64(clear[35]+88-random) << 16) +
// (int64(^(clear[40] + random)) << 24) +
// (int64(clear[10]-66-random) << 32) +
// (int64(^(clear[36] + 28 + random)) << 40) +
// (int64(clear[30]-8-random) << 48)
//
// if expireTime < uint32(creatTime/1000000) {
// // todo logger
// c.JSON(http.StatusOK, gin.H{
// "code": 1006,
// "message": "TOKEN不正确",
// })
// c.Abort()
// return //
// }
//
// var str [30]byte
//
// str[8] = clear[0]
// str[25] = clear[1]
// str[27] = clear[3]
// str[15] = clear[4]
// str[19] = clear[5]
// str[11] = clear[6]
// str[23] = clear[7]
// str[6] = clear[8]
// str[28] = clear[9]
// str[16] = clear[11]
// str[17] = clear[13]
// str[3] = clear[14]
// str[21] = clear[15]
// str[1] = clear[16]
// str[0] = clear[18]
// str[4] = clear[19]
// str[5] = clear[21]
// str[7] = clear[23]
// str[9] = clear[24]
// str[10] = clear[25]
// str[12] = clear[27]
// str[13] = clear[28]
// str[14] = clear[29]
// str[18] = clear[31]
// str[20] = clear[32]
// str[22] = clear[33]
// str[2] = clear[34]
// str[24] = clear[37]
// str[26] = clear[38]
// str[29] = clear[39]
//
// for i := uint8(0); i < userNameLen; i++ {
// str[i] = str[i] - random - (i << 2)
// }
// userName := string(str[:userNameLen])
//
// if admin {
// // todo 查cache 已退出登录
// } else {
// // todo 查cache 已退出登录
// cacheCreatTime := cache.GetWechatCustomerTokenCreatTime(userName)
// if cacheCreatTime > creatTime { //如果缓存里面存的CreatTime比token里面的CreatTime要晚,则token已退出登录
// // todo logger warn
// c.JSON(http.StatusOK, gin.H{
// "code": 1006,
// "message": "用户已退出登录",
// })
// c.Abort()
// return //
// }
// }
//
// c.Set("userID", userName)
// c.Next()
// }
//}
1. 查卡用户信息
1)小程序:通过微信UNIONID(token),查家长绑定的所有的 //查缓存
2) 后台:通过校区服务ID,查这一堆校区的,并提供筛选条件 //查库
一、管理后台接口
1. 后台用户登录
传:LoginAccount、Password、验证码
用LoginAccount,获得AdminStruct,成功就更新 tokenCreatTime
成功则进入首页
成功回:token,Name, 菜单按钮权限,首页展示内容(后面做统计内容,现在先全为空) AdminStruct RoleAuthStruct
1基础数据
1. 获取区域列表
区域ID 省市区县 区域名字 经纬度 状态 创建时间
2. 服务商列表
列表-总记录
服务商ID 省市区县 服务商名字 法人 法人电话 联系人 联系人电话
3. 收款账户信息列表
4. 获取校区服务列表
(省市区) (服务类型) (区域名称) (运营状态) (服务商 名字) 【搜索-固定有】【新增-根据权限】
列表-总记录290条:
区域服务id,省市区县,区域服务名字,区域名字,负责人,负责人电话,状态, 服务商名字,创建时间,服务项目, [编辑][详情][收款信息 收款账户列表比例 -充值/代扣]充值项配置
2订单数据
1. 充值订单
2. 消费订单
3. 通话清单
4. 通行记录
3用户数据
1. 微信用户数据
2. 卡用户数据
模板下载(电话卡、定位卡、) 导入模板
4设备管理
1. 设备列表
模板下载(不同设备类型模板不同) 导入模板
2. 设备状态
3. 设备参数
4. 电话卡
5. 设备告警信息
5系统管理
1. 系统用户
2. 角色管理
-- 3. 菜单管理
6缴费(预留: 服务费/话费)
二、用户小程序接口
1. 登录:获取用户code->appid+appsecret+code获取session_key+openid等,生成token
2.
\ No newline at end of file
package web
import (
"dc_golang_server_1/config"
_ "dc_golang_server_1/docs"
"dc_golang_server_1/logger"
v1 "dc_golang_server_1/web/v1"
"fmt"
"github.com/gin-gonic/gin"
"github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
"time"
)
func InitRouter() { //*gin.Engine{
gin.SetMode(config.HttpServerMode)
r := gin.New()
r.Use(logger.HttpGinLog(), gin.Recovery())
r.Use(Cors()) //全局跨域 局部跨域的话在路由组里面去添加
//r.Use(CheckToken()) //jwt 还是在对应需要token的路由组添加
fmt.Println("swagger", config.HttpServerSwagger)
if config.HttpServerSwagger {
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}
base := r.Group("base/")
// base.Use(CheckToken())
{
base.GET("province", v1.GetProvinceList)
base.GET("city/:id", v1.GetCityList)
base.GET("county/:id", v1.GetCountyList)
base.GET("locarea", v1.GetAreaByLocation)
base.GET("countyarea/:id", v1.GetAreaByCounty)
}
r.POST("we/login/:code", v1.WeLogin)
wechat := r.Group("we/")
// wechat.Use(CheckToken())
{ // 需要token的
wechat.POST("carduser", v1.CreateCardUser) //创建学生
wechat.DELETE("carduser/:id", v1.DeleteCardUser) //删除学生
wechat.POST("bindcarduser/:share_code", v1.BindCardUser) //副家长绑定学生
wechat.DELETE("bindcarduser/:id", v1.DeleteBindCardUser) //副家长解绑学生
wechat.GET("trend/:id", v1.GetCardUsersTrend) //获取学生最新动态
wechat.GET("bindcarduser/:id", v1.GetBindCardUser) //获取学生副家长列表及邀请码内容(仅主家长有权限)
wechat.PUT("cardusershareon/:id", v1.PutCardUserShareOn) //打开邀请码开关(仅主家长有权限)
wechat.PUT("cardusershareoff/:id", v1.PutCardUserShareOff) //关闭邀请码开关(仅主家长有权限)
wechat.DELETE("slaveweuser", v1.DeleteSlaveWeUser) //删除副家长(仅主家长有权限)
wechat.PUT("carduser/:id", v1.PutCardUser) //修改学生信息
wechat.PUT("cardloss/:id", v1.CardLoss) //卡挂失/解挂
wechat.PUT("cardbind/:id", v1.CardBind) //绑定卡
wechat.DELETE("cardbind/:id", v1.DeleteCardBind) //解绑卡
wechat.GET("phonecardstatus/:id", v1.GetPhoneCardStatus) //获取学生公话卡状态
//wechat.GET("callrecord/:id",v1.GetCallRecord) // 查询通话记录
//添加亲情号
//修改亲情号
//删除亲情号
//缴费
//查询缴费记录
//获取学生定位卡状态
//查询通行记录
//缴费
//查询缴费记录
}
//router := r.Group("web/")
{
//router.POST()
}
fmt.Println(time.Now(), "server is running")
err := r.Run(config.HttpServerPort)
if err != nil {
panic(err)
}
}
package router
import (
"dc_golang_server_1/config"
_ "dc_golang_server_1/docs"
"dc_golang_server_1/logger"
"dc_golang_server_1/web"
"dc_golang_server_1/web/api_admin"
"dc_golang_server_1/web/api_public"
"dc_golang_server_1/web/api_we"
"fmt"
"github.com/gin-gonic/gin"
"github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
"time"
)
func InitRouter() { //*gin.Engine{
gin.SetMode(config.HttpServerMode)
r := gin.New()
r.Use(logger.HttpGinLog(), gin.Recovery())
r.Use(web.Cors()) //全局跨域 局部跨域的话在路由组里面去添加
//r.Use(CheckToken()) //jwt 还是在对应需要token的路由组添加
if config.HttpServerSwagger {
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}
base := r.Group("base/")
base.Use(web.JeffWTPublic())
{
base.GET("province", api_public.GetProvinceList)
base.GET("city/:id", api_public.GetCityList)
base.GET("county/:id", api_public.GetCountyList)
base.GET("locarea", api_public.GetAreaByLocation)
base.GET("countyarea/:id", api_public.GetAreaByCounty)
}
r.POST("we/login/:code", api_we.WeLogin)
wechat := r.Group("we/")
wechat.Use(web.JeffWTWechat())
{ // 需要token的
wechat.POST("carduser", api_we.CreateCardUser) //创建学生
wechat.DELETE("carduser/:id", api_we.DeleteCardUser) //删除学生
wechat.GET("trend/:id", api_we.GetCardUsersTrend) //获取学生最新动态
wechat.GET("bindcarduser/:id", api_we.GetBindCardUser) //获取学生副家长列表(仅主家长有权限)
wechat.GET("sharecode/id", api_we.CardUserShareCode) //获取邀请码(仅主家长有权限)
wechat.POST("bindcarduser/:share_code", api_we.BindCardUser) //副家长绑定学生
wechat.DELETE("bindcarduser/:id", api_we.DeleteBindCardUser) //副家长解绑学生
//wechat.PUT("cardusershareon/:id", api_we.PutCardUserShareOn) //打开邀请码开关(仅主家长有权限)
//wechat.PUT("cardusershareoff/:id", api_we.PutCardUserShareOff) //关闭邀请码开关(仅主家长有权限)
wechat.DELETE("slaveweuser", api_we.DeleteSlaveWeUser) //删除副家长(仅主家长有权限)
//wechat.DELETE("allslaveweuser", api_we.DeleteAllSlaveWeUser) //删除副家长(仅主家长有权限)
wechat.PUT("carduser/:id", api_we.PutCardUser) //修改学生信息
wechat.PUT("cardloss/:id", api_we.CardLoss) //卡挂失/解挂
wechat.PUT("cardbind/:id", api_we.CardBind) //绑定卡
wechat.DELETE("cardbind/:id", api_we.DeleteCardBind) //解绑卡
wechat.GET("phonecardstatus/:id", api_we.GetPhoneCardStatus) //获取学生公话卡状态
wechat.GET("callrecord/:id", api_we.GetCallRecord) // 查询通话记录
wechat.POST("familynum/:id", api_we.AddFamilyNum) //添加亲情号
wechat.PUT("familynum/:id", api_we.PutFamilyNum) //修改亲情号
wechat.DELETE("familynum/:id", api_we.DeleteFamilyNum) //删除亲情号
//缴费
//查询缴费记录
//获取学生定位卡状态
//查询通行记录
//缴费
//查询缴费记录
}
// r.POST("ad/login", api_we.AdminLogin)
admin := r.Group("ad/")
// admin.Use(web.JeffWTAdmin())
{
admin.POST("area", api_admin.CreateArea) // 新建一个学校
// admin.GET("cache", api_cache.GetCacheMap) // 获取缓存内容
}
fmt.Println(time.Now(), "server is running:swagger", config.HttpServerSwagger)
err := r.Run(config.HttpServerPort)
if err != nil {
panic(err)
}
}
package v1
import (
"dc_golang_server_1/cache"
"github.com/gin-gonic/gin"
"net/http"
)
// GetCardUsers 登录接口,返回Token及 微信首页获取卡用户信息列表
func GetCardUsers(c *gin.Context) {
cardUsersID := cache.GetWechatCustomerCardUserID(c.Param("username"))
cardUserInfos := make([]cache.CardUserType, len(cardUsersID))
for i, v := range cardUsersID {
cardUserInfos[i] = cache.GetCardUserInfo(v)
}
c.JSON(http.StatusOK, gin.H{
"status": 200,
// "total": 0,
"data": cardUserInfos,
"message": "OK",
})
}
var WechatCardUsersTrendType struct {
ServiceType uint8 `json:"service"` //服务项目 UI图标及颜色等
TrendName string `json:"title"` //显示在第一行
Content string `json:"content"` //显示在第二行
Time string `json:"time"` //显示在第三行
}
// GetCardUsersTrend 微信学生首页,获取近10条用户最新动态
// @Tags public
// @Summary 微信学生首页,获取近20条用户最新动态
// @Description 微信学生首页,获取近20条用户最新动态
// @Param code path string true "请示参数code"
// @Product json
// @Success 200 {object} string "{"code": 200, "token": string}"
// @Router /we/trend/:id [GET]
func GetCardUsersTrend(c *gin.Context) {
//id, _ := strconv.Atoi(c.Param("id"))
c.JSON(http.StatusOK, gin.H{
"status": 200,
"message": "OK",
})
}
package v1
const (
SUCCSE = 0
ERROR = 500
// code = 1000...用户模块的错误
ERROR_USERNAME_USED = 1001
ERROR_PASSWORD_WRONG = 1002
ERROR_USER_NOT_EXIST = 1003
ERROR_TOKEN_EXIST = 1004
ERROR_TOKEN_RUNTIME = 1005
ERROR_TOKEN_WRONG = 1006
ERROR_TOKEN_TYPE_WRONG = 1007
ERROR_USER_NO_RIGHT = 1008
// code = 2000...XXXXX模块的错误
// code = 3000...XXXXX模块的错误
)
//var codeMsg = map[int]string{
// SUCCSE: "OK",
// ERROR: "FAIL",
// ERROR_USERNAME_USED: "用户名已存在!",
// ERROR_PASSWORD_WRONG: "密码错误",
// ERROR_USER_NOT_EXIST: "用户不存在",
// ERROR_TOKEN_EXIST: "TOKEN不存在",
// ERROR_TOKEN_RUNTIME: "TOKEN已过期",
// ERROR_TOKEN_WRONG: "TOKEN不正确",
// ERROR_TOKEN_TYPE_WRONG: "TOKEN格式错误",
// ERROR_USER_NO_RIGHT: "用户没有权限",
//}
package v1
import (
"github.com/gin-gonic/gin"
"net/http"
"time"
)
type weLoginRes struct {
// 自己创建的学生列表(主家长)
Master []struct {
// 学生ID
ID uint32 `json:"id"`
Name string `json:"name"`
// 0女 1男
Sex uint8 `json:"sex"`
// 区域名字
Area string `json:"area" example:"四川省成都市温江区实验中学"`
// "1~9对应一年级~九年级,10~12对应高一~高三"
Grade int8 `json:"grade"`
Class int8 `json:"class"`
StuNum string `json:"stuNum"`
// 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
Service []uint8 `json:"service" example:"1,2,2,0,0,0"`
// 是否已充值(已充值则不能删除,未充值可以删除)
TopUp bool `json:"topUp"`
} `json:"master"`
// 添加的学生列表(副家长)
Slave []struct {
// 学生ID
ID uint32 `json:"id"`
Name string `json:"name"`
// 0女 1男
Sex uint8 `json:"sex"`
// 区域名字
Area string `json:"area" example:"四川省成都市温江区实验中学"`
// "1~9对应一年级~九年级,10~12对应高一~高三"
Grade int8 `json:"grade"`
Class int8 `json:"class"`
StuNum string `json:"stuNum"`
// 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
Service []uint8 `json:"service" example:"1,2,2,0,0,0"`
} `json:"slave"`
// 是否已获取到微信电话
WePhone bool `json:"wePhone"`
// 是否已获取到微信用户信息
WeInfo bool `json:"weInfo"`
Token string `json:"token"`
}
// WeLogin 微信登录
// @Tags 家长微信
// @Summary 登录
// @Description 微信code传至后台,后台返回token,token有效时长:24小时
// @Param code path string true "用户微信的code"
// @Product json
// @Success 0 {object} weLoginRes
// @Router /we/login/{code} [POST]
func WeLogin(c *gin.Context) {
code := c.Param("code")
var res weLoginRes
//todo 拿code去找腾讯要东西 生成token
res.Token = code
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
"data": res,
})
}
type weCreateCardUserReq struct {
// 必填,学生名字,maxLen=16
Name string `json:"name" example:"汤圆"`
// 必填,校区ID
AreaID uint32 `json:"areaID" example:"1"`
// 必填,"1~9对应一年级~九年级,10~12对应高一~高三"
Grade int8 `json:"grade"`
// 选填,0女1男
Sex uint8 `json:"sex,omitempty"`
// 选填,班级,number
Class int8 `json:"class,omitempty"`
// 选填,学号,字符串,maxLen=32
StudentNo string `json:"stuNum,omitempty"`
}
type creatCardUserRes struct {
// 新创建的学生ID
ID uint32 `json:"id"`
// 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
Service [6]uint8 `json:"service" example:"1,2,2,0,0,0"`
}
// CreateCardUser 创建一个学生
// @Tags 家长微信
// @Summary 创建一个学生
// @Description 传新建学生信息至后台,后台返回学生id,以及对应校区的service
// @Accept json
// @Produce json
// @Param data body weCreateCardUserReq true "学生信息"
// @Success 0 {object} creatCardUserRes
// @Router /we/carduser [POST]
// @Security ApiKeyAuth
func CreateCardUser(c *gin.Context) {
res := creatCardUserRes{
1,
[6]uint8{1, 2, 2, 0, 0, 0},
}
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
"data": res,
})
}
// DeleteCardUser 主家长删除一个学生
// @Tags 家长微信
// @Summary 主家长删除一个学生
// @Description 传学生ID至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Success 0
// @Router /we/carduser/{id} [DELETE]
// @Security ApiKeyAuth
func DeleteCardUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
})
}
type bindCardUserRes struct {
// 学生ID
ID uint32 `json:"id"`
Name string `json:"name"`
// 0女 1男
Sex uint8 `json:"sex"`
// 区域名字
Area string `json:"area" example:"四川省成都市温江区实验中学"`
// "1~9对应一年级~九年级,10~12对应高一~高三"
Grade int8 `json:"grade"`
Class int8 `json:"class"`
StuNum string `json:"stuNum"`
// 对应6个数字对应公话、定位、饮水、卡消费、洗浴、洗衣机图标(0不显示,1正常,2显示但提示校区暂未开通该服务)
Service []uint8 `json:"service" example:"1,2,2,0,0,0"`
}
// BindCardUser 副家长绑定学生
// @Tags 家长微信
// @Summary 副家长绑定学生
// @Description 传学生的邀请码,后台返回学生信息
// @Produce json
// @Param share_code path string true "学生的邀请码"
// @Success 0 {object} bindCardUserRes "学生信息"
// @Router /we/bindcarduser/{share_code} [POST]
// @Security ApiKeyAuth
func BindCardUser(c *gin.Context) {
res := bindCardUserRes{}
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
"data": res,
})
}
// DeleteBindCardUser 副家长解绑学生
// @Tags 家长微信
// @Summary 副家长解绑学生
// @Description 传学生ID至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Success 0
// @Router /we/bindcarduser/{id} [DELETE]
// @Security ApiKeyAuth
func DeleteBindCardUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
})
}
type slaveWeUserRes struct {
// 微信UnionID
UnionID string `json:"unionID"`
// 微信昵称
Nickname string `json:"nickname"`
// 头像URL
AvatarURL string `json:"avatarURL"`
// 绑定时间
CreateAt time.Time `json:"createAt"`
}
type getBindCardUserRes struct {
// 副家长微信信息列表
WeUser []slaveWeUserRes `json:"weUser"`
// 学生的邀请码,长度固定16,若为空,则表示邀请码开关关闭
ShareCode string `json:"shareCode"`
}
// GetBindCardUser 获取学生副家长列表及邀请码内容(仅主家长有权限)
// @Tags 家长微信
// @Summary 获取学生副家长列表及邀请码内容(仅主家长有权限)
// @Description 传学生ID至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Success 0 {object} getBindCardUserRes "副家长信息列表及邀请码"
// @Router /we/bindcarduser/{id} [GET]
// @Security ApiKeyAuth
func GetBindCardUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
"data": getBindCardUserRes{},
})
}
// PutCardUserShareOn 打开邀请码开关(仅主家长有权限)
// @Tags 家长微信
// @Summary 打开邀请码开关(仅主家长有权限)
// @Description 传学生ID至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Success 0
// @Router /we/cardusershareon/{id} [PUT]
// @Security ApiKeyAuth
func PutCardUserShareOn(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
})
}
// PutCardUserShareOff 关闭邀请码开关(仅主家长有权限)
// @Tags 家长微信
// @Summary 关闭邀请码开关(仅主家长有权限)
// @Description 传学生ID至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Success 0
// @Router /we/cardusershareoff/{id} [PUT]
// @Security ApiKeyAuth
func PutCardUserShareOff(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
})
}
// DeleteSlaveWeUser 删除副家长(仅主家长有权限)
// @Tags 家长微信
// @Summary 删除副家长(仅主家长有权限)
// @Description 传学生ID和微信UnionID,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param unionid query string true "副家长微信UnionID"
// @Success 0
// @Router /we/slaveweuser/{id} [DELETE]
// @Security ApiKeyAuth
func DeleteSlaveWeUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
})
}
type PutCardUserReq struct {
// 必填,学生名字,maxLen=16
Name string `json:"name" example:"汤圆"`
// 必填,"1~9对应一年级~九年级,10~12对应高一~高三"
Grade int8 `json:"grade"`
// 选填,0女1男
Sex uint8 `json:"sex,omitempty"`
// 选填,班级,number
Class int8 `json:"class,omitempty"`
// 选填,学号,字符串,maxLen=32
StudentNo string `json:"stuNum,omitempty"`
}
// PutCardUser 修改学生信息
// @Tags 家长微信
// @Summary 修改学生信息
// @Description 传学生id及新信息至后台,后台返回成功失败
// @Accept json
// @Produce json
// @Param id path integer true "学生ID"
// @Param data body PutCardUserReq true "学生信息"
// @Success 0
// @Router /we/carduser/{id} [PUT]
// @Security ApiKeyAuth
func PutCardUser(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
})
}
// CardLoss 卡挂失/解挂
// @Tags 家长微信
// @Summary 卡挂失/解挂
// @Description 传学生id及卡类型至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param loss query bool true "true挂失,false解挂"
// @Param type query integer true "卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)"
// @Success 0
// @Router /we/cardloss/{id} [PUT]
// @Security ApiKeyAuth
func CardLoss(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
})
}
// CardBind 绑定卡
// @Tags 家长微信
// @Summary 绑定卡
// @Description 传学生id及卡类型、卡号至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param code query string true "卡号"
// @Param type query integer true "卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)"
// @Success 0
// @Router /we/cardbind/{id} [PUT]
// @Security ApiKeyAuth
func CardBind(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
})
}
// DeleteCardBind 解绑卡
// @Tags 家长微信
// @Summary 解绑卡
// @Description 传学生id及卡类型至后台,后台返回成功失败
// @Produce json
// @Param id path integer true "学生ID"
// @Param type query integer true "卡类型:1电话卡,2定位卡,3IC卡(饮水、消费、洗浴、洗衣机均为IC卡,固任何一个服务的卡挂失状态改变,其余也跟随改变)"
// @Success 0
// @Router /we/cardbind/{id} [DELETE]
// @Security ApiKeyAuth
func DeleteCardBind(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
})
}
type getPhoneCardStatusRes struct {
// 状态 0未绑定卡 1 正常使用 2 服务已到期 3 已挂失
Status uint8 `json:"status"`
// 卡号
SimID string `json:"simID"`
// 到期时间
ExpiryAt time.Time `json:"expiryAt"`
// 月套餐使用分钟数
MonthMin uint16 `json:"monthMin"`
// 月套餐分钟数
MonthPack uint16 `json:"monthPack"`
// 本月可修改亲情号次数
Changeable uint8 `json:"changeable"`
// 亲情号列表
Family []struct {
Phone string `json:"phone"`
Name string `json:"name"`
} `json:"family"`
}
// GetPhoneCardStatus 获取学生公话卡状态
// @Tags 家长微信
// @Summary 获取学生公话卡状态
// @Description 传学生ID至后台,后台返回卡信息
// @Produce json
// @Param id path integer true "学生ID"
// @Success 0 {object} getPhoneCardStatusRes "公话卡状态信息"
// @Router /we/phonecardstatus/{id} [GET]
// @Security ApiKeyAuth
func GetPhoneCardStatus(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": SUCCSE,
"data": getPhoneCardStatusRes{},
})
}
type getCallRecordRes struct {
// 状态 0未绑定卡 1 正常使用 2 服务已到期 3 已挂失
Status uint8 `json:"status"`
// 卡号
SimID string `json:"simID"`
// 到期时间
ExpiryAt time.Time `json:"expiryAt"`
// 月套餐使用分钟数
MonthMin uint16 `json:"monthMin"`
// 月套餐分钟数
MonthPack uint16 `json:"monthPack"`
// 本月可修改亲情号次数
Changeable uint8 `json:"changeable"`
// 亲情号列表
Family []struct {
Phone string `json:"phone"`
Name string `json:"name"`
} `json:"family"`
}
//// GetCallRecord 查询通话记录
//// @Tags 家长微信
//// @Summary 查询通话记录
//// @Description 传学生ID至后台,后台返回通话记录列表
//// @Produce json
//// @Param id path integer true "学生ID"
//// @Param pnum query integer true "页数"
//// @Param psize query integer true "页条数"
//// @Param start quety string false "起始时间 2020-10-10 10:00:00"
//// @Param end quety string false "结束时间 2030-10-10 10:00:00"
//// @Param asc quety bool false "是否升序" default(false)
//// @Success 0 {object} []getPhoneCardStatusRes "通话记录列表"
//// @Router /we/callrecord/{id} [GET]
//// @Security ApiKeyAuth
//func GetCallRecord(c *gin.Context) {
// c.JSON(http.StatusOK, gin.H{
// "code": SUCCSE,
// "data": getPhoneCardStatusRes{},
// })
//}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment