Compare commits

..

5 Commits

@ -1,215 +0,0 @@
{
"id": 1416,
"type": "normal",
"title": "多规格123123",
"subtitle": "多规格",
"weigh": 0,
"category_ids": "46",
"image": "https://demo.shopro.top/uploads/20230821/00e97b4723771626fb44bdbf56d35a73.jpg",
"images": [
"https://demo.shopro.top/uploads/20230823/170a1630b9b3124e28feacd95646b453.png",
"https://demo.shopro.top/uploads/20230823/16f27aeea875d3ff395786ad48f2e38b.png",
"https://demo.shopro.top/uploads/20230821/00e97b4723771626fb44bdbf56d35a73.jpg"
],
"params": null,
"content": "\u003cp\u003e\u003cimg src=\"https://demo.shopro.top/uploads/20230821/00e97b4723771626fb44bdbf56d35a73.jpg\" style=\"width: 612px;\"\u003e\u003cimg src=\"https://demo.shopro.top/uploads/20230821/da48a8a2595d0efd619984ebd7e22bd9.jpg\" style=\"width: 612px;\"\u003e\u003cimg src=\"https://demo.shopro.top/uploads/20230819/8659310afe6e0f2680457c26da4f6d3d.jpg\" style=\"width: 612px;\"\u003e\u003cimg src=\"https://demo.shopro.top/uploads/20230819/655d7da134ea4669625007c65f934931.jpg\" style=\"width: 612px;\"\u003e\u003cimg src=\"https://demo.shopro.top/uploads/20230819/a6a57d00022b06e5b412dcfc6df06f1d.jpg\" style=\"width: 612px;\"\u003e\u003cimg src=\"https://demo.shopro.top/uploads/20230819/8a477ec231722200e268c722f87d95a3.jpg\" style=\"width: 612px;\"\u003e\u003cimg src=\"https://demo.shopro.top/uploads/20230818/18889719294b8c8bef913a3bbcc73e60.png\" style=\"width: 612px;\"\u003e\u003cimg src=\"https://demo.shopro.top/uploads/20230817/5aea7892240b08ee32e3b47c8b210053.png\" style=\"width: 500px;\"\u003e\u003cimg src=\"https://demo.shopro.top/uploads/20230816/f0238ed4eef0068f18f03699c4b8979c.png\" style=\"width: 612px;\"\u003e\u003cimg src=\"https://demo.shopro.top/uploads/20230815/f68d107a4c703780c900c049a65cd47c.jpeg\" style=\"width: 612px;\"\u003e\u003cbr\u003e\u003c/p\u003e",
"price": "11.00",
"original_price": "22.00",
"is_sku": 1,
"likes": 0,
"views": 623,
"sales": 0,
"show_sales": 0,
"total_sales": 4,
"service_ids": "28",
"dispatch_type": "express",
"dispatch_ids": "23",
"deletetime": null,
"activity": {
"id": 0,
"title": "",
"type": "",
"richtext_id": 0,
"richtext_title": "",
"starttime": 0,
"endtime": 0,
"rules": {
"activity_auto_close": "",
"fictitious_num": "",
"is_alone": "",
"is_fictitious": "",
"limit_buy": "",
"order_auto_close": "",
"team_card": "",
"team_num": "",
"valid_time": ""
},
"status_code": ""
},
"activity_type": "",
"buyers": null,
"sku_price": [
{
"id": 2365,
"goods_sku_ids": [
1676,
1679
],
"goods_id": 1416,
"weigh": 0,
"image": "https://demo.shopro.top/uploads/20230819/8659310afe6e0f2680457c26da4f6d3d.jpg",
"stock": 1,
"stock_warning": null,
"sales": 0,
"sn": "",
"weight": 0,
"price": "1.00",
"goods_sku_text": "红色,xl",
"status": "up",
"groupon_price": "",
"activity_type": "",
"activity_id": 0,
"item_goods_sku_price": {
"id": 0,
"activity_id": 0,
"sku_price_id": 0,
"goods_id": 0,
"stock": 0,
"sales": 0,
"price": "",
"status": ""
},
"goods_sku_id_arr": [
"1676",
"1679"
]
},
{
"id": 2366,
"goods_sku_ids": [
1677,
1679
],
"goods_id": 1416,
"weigh": 0,
"image": "",
"stock": 1,
"stock_warning": null,
"sales": 0,
"sn": "",
"weight": 0,
"price": "2.00",
"goods_sku_text": "绿色,xl",
"status": "up",
"groupon_price": "",
"activity_type": "",
"activity_id": 0,
"item_goods_sku_price": {
"id": 0,
"activity_id": 0,
"sku_price_id": 0,
"goods_id": 0,
"stock": 0,
"sales": 0,
"price": "",
"status": ""
},
"goods_sku_id_arr": [
"1677",
"1679"
]
},
{
"id": 2367,
"goods_sku_ids": [
1676,
1680
],
"goods_id": 1416,
"weigh": 0,
"image": "",
"stock": 1,
"stock_warning": null,
"sales": 0,
"sn": "",
"weight": 0,
"price": "3.00",
"goods_sku_text": "红色,m",
"status": "up",
"groupon_price": "",
"activity_type": "",
"activity_id": 0,
"item_goods_sku_price": {
"id": 0,
"activity_id": 0,
"sku_price_id": 0,
"goods_id": 0,
"stock": 0,
"sales": 0,
"price": "",
"status": ""
},
"goods_sku_id_arr": [
"1676",
"1680"
]
},
{
"id": 2368,
"goods_sku_ids": [
1677,
1680
],
"goods_id": 1416,
"weigh": 0,
"image": "",
"stock": 1,
"stock_warning": null,
"sales": 0,
"sn": "",
"weight": 0,
"price": "4.00",
"goods_sku_text": "绿色,m",
"status": "up",
"groupon_price": "",
"activity_type": "",
"activity_id": 0,
"item_goods_sku_price": {
"id": 0,
"activity_id": 0,
"sku_price_id": 0,
"goods_id": 0,
"stock": 0,
"sales": 0,
"price": "",
"status": ""
},
"goods_sku_id_arr": [
"1677",
"1680"
]
}
],
"stock": 1,
"activity_discounts": [
"",
""
],
"activity_discounts_types": "",
"activity_discounts_tags": [],
"favorite": null,
"dispatch_type_arr": [
"express"
],
"service": [
{
"id": 28,
"name": "免费包邮",
"image": "https://demo.shopro.top/uploads/20230710/f7f6bf60f2898f583bbe09acd221d9f1.png",
"description": "123"
}
],
"sku": null,
"coupons": null,
"groupon_price": ""
}

@ -1,226 +0,0 @@
{
"id": 1416,
"type": "normal",
"title": "多规格",
"subtitle": "多规格",
"weigh": 0,
"category_ids": "46",
"image": "https://demo.shopro.top/uploads/20230821/00e97b4723771626fb44bdbf56d35a73.jpg",
"images": [
"https://demo.shopro.top/uploads/20230823/170a1630b9b3124e28feacd95646b453.png",
"https://demo.shopro.top/uploads/20230823/16f27aeea875d3ff395786ad48f2e38b.png",
"https://demo.shopro.top/uploads/20230821/00e97b4723771626fb44bdbf56d35a73.jpg"
],
"params": [],
"content": "<p><img src=\"https://demo.shopro.top/uploads/20230821/00e97b4723771626fb44bdbf56d35a73.jpg\" style=\"width: 612px;\"><img src=\"https://demo.shopro.top/uploads/20230821/da48a8a2595d0efd619984ebd7e22bd9.jpg\" style=\"width: 612px;\"><img src=\"https://demo.shopro.top/uploads/20230819/8659310afe6e0f2680457c26da4f6d3d.jpg\" style=\"width: 612px;\"><img src=\"https://demo.shopro.top/uploads/20230819/655d7da134ea4669625007c65f934931.jpg\" style=\"width: 612px;\"><img src=\"https://demo.shopro.top/uploads/20230819/a6a57d00022b06e5b412dcfc6df06f1d.jpg\" style=\"width: 612px;\"><img src=\"https://demo.shopro.top/uploads/20230819/8a477ec231722200e268c722f87d95a3.jpg\" style=\"width: 612px;\"><img src=\"https://demo.shopro.top/uploads/20230818/18889719294b8c8bef913a3bbcc73e60.png\" style=\"width: 612px;\"><img src=\"https://demo.shopro.top/uploads/20230817/5aea7892240b08ee32e3b47c8b210053.png\" style=\"width: 500px;\"><img src=\"https://demo.shopro.top/uploads/20230816/f0238ed4eef0068f18f03699c4b8979c.png\" style=\"width: 612px;\"><img src=\"https://demo.shopro.top/uploads/20230815/f68d107a4c703780c900c049a65cd47c.jpeg\" style=\"width: 612px;\"><br></p>",
"price": "11",
"original_price": "22.00",
"is_sku": 1,
"likes": 0,
"views": 631,
"sales": 0,
"show_sales": 0,
"service_ids": "28",
"dispatch_type": "express",
"dispatch_ids": "23",
"deletetime": null,
"activity": null,
"activity_type": null,
"buyers": [],
"sku_price": [
{
"id": 2365,
"goods_sku_ids": "1676,1679",
"goods_id": 1416,
"weigh": 0,
"image": "https://demo.shopro.top/uploads/20230819/8659310afe6e0f2680457c26da4f6d3d.jpg",
"stock": 1,
"stock_warning": null,
"sales": 0,
"sn": "",
"weight": 0,
"price": "1.00",
"goods_sku_text": "红色,xl",
"status": "up",
"goods_sku_id_arr": [
"1676",
"1679"
]
},
{
"id": 2366,
"goods_sku_ids": "1677,1679",
"goods_id": 1416,
"weigh": 0,
"image": "",
"stock": 1,
"stock_warning": null,
"sales": 0,
"sn": "",
"weight": 0,
"price": "2.00",
"goods_sku_text": "绿色,xl",
"status": "up",
"goods_sku_id_arr": [
"1677",
"1679"
]
},
{
"id": 2367,
"goods_sku_ids": "1676,1680",
"goods_id": 1416,
"weigh": 0,
"image": "",
"stock": 1,
"stock_warning": null,
"sales": 0,
"sn": "",
"weight": 0,
"price": "3.00",
"goods_sku_text": "红色,m",
"status": "up",
"goods_sku_id_arr": [
"1676",
"1680"
]
},
{
"id": 2368,
"goods_sku_ids": "1677,1680",
"goods_id": 1416,
"weigh": 0,
"image": "",
"stock": 1,
"stock_warning": null,
"sales": 0,
"sn": "",
"weight": 0,
"price": "4.00",
"goods_sku_text": "绿色,m",
"status": "up",
"goods_sku_id_arr": [
"1677",
"1680"
]
}
],
"stock": 4,
"activity_discounts": [],
"activity_discounts_types": "",
"activity_discounts_tags": [],
"favorite": null,
"dispatch_type_arr": [
"express"
],
"service": [
{
"id": 28,
"name": "免费包邮",
"image": "https://demo.shopro.top/uploads/20230710/f7f6bf60f2898f583bbe09acd221d9f1.png",
"description": "123"
}
],
"sku": [
{
"id": 1675,
"name": "颜色",
"pid": 0,
"goods_id": 1416,
"weigh": 0,
"content": [
{
"id": 1676,
"name": "红色",
"pid": 1675,
"goods_id": 1416,
"weigh": 0
},
{
"id": 1677,
"name": "绿色",
"pid": 1675,
"goods_id": 1416,
"weigh": 0
}
]
},
{
"id": 1678,
"name": "尺码",
"pid": 0,
"goods_id": 1416,
"weigh": 0,
"content": [
{
"id": 1679,
"name": "xl",
"pid": 1678,
"goods_id": 1416,
"weigh": 0
},
{
"id": 1680,
"name": "m",
"pid": 1678,
"goods_id": 1416,
"weigh": 0
}
]
}
],
"coupons": [
{
"id": 35,
"name": "新人优惠券",
"type": "cash",
"goods_ids": "0",
"amount": "10.00",
"enough": "100.00",
"stock": 999760,
"limit": 1,
"gettime": {
"start": 1665849600,
"end": 1732896000
},
"usetime": {
"start": 1732896000,
"end": 1764345600
},
"description": "新人可领asdfasd",
"usetimestart": 1732896000,
"usetimeend": 1764345600,
"gettimestart": 1665849600,
"gettimeend": 1732896000,
"status_code": "can_get",
"status_name": "可以领取",
"user_coupons": []
},
{
"id": 83,
"name": "111",
"type": "cash",
"goods_ids": "0",
"amount": "5.00",
"enough": "10.00",
"stock": 99992,
"limit": 1,
"gettime": {
"start": 1699200000,
"end": 1703520000
},
"usetime": {
"start": 1699200000,
"end": 1703692800
},
"description": "1",
"usetimestart": 1699200000,
"usetimeend": 1703692800,
"gettimestart": 1699200000,
"gettimeend": 1703520000,
"status_code": "can_get",
"status_name": "可以领取",
"user_coupons": []
}
]
}

@ -0,0 +1,51 @@
case $3 in
"")
goarch="amd64"
releasePath="x86_64"
break
;;
"arm")
goarch="arm"
releasePath="arm"
break
;;
"arm64")
goarch="arm64"
releasePath="arm64"
break
;;
"loong64")
goarch="loong64"
releasePath="loong64"
break
;;
*)
echo '目标 ' $3 ' 无法编译'
exit
;;
esac
buildfile=$1
case $2 in
"linux") echo '交叉编译目标为linux+'$goarch
echo "CGO_ENABLED=0 GOOS=linux GOARCH="$goarch" go build "$1
CGO_ENABLED=0 GOOS=linux GOARCH=$goarch go build -o ./"${buildfile%%.*}-"$releasePath $1
break
;;
"windows") echo '交叉编译目标为windows+'$goarch
echo "CGO_ENABLED=0 GOOS=windows GOARCH="$goarch" go build "$1
CGO_ENABLED=0 GOOS=windows GOARCH=$goarch go build -o ././"${buildfile%%.*}-"$releasePath".exe" $1
break
;;
"darwin") echo '交叉编译目标为maxos+'$goarch
echo "CGO_ENABLED=0 GOOS=darwin GOARCH="$goarch" go build "$1
CGO_ENABLED=0 GOOS=darwin GOARCH=$goarch go build -o ./"${buildfile%%.*}-"$releasePath $1
break
;;
*) echo '参数不正确:'$goarch
break
;;
esac
echo '脚本执行结束...'

@ -0,0 +1,10 @@
[
{
"DbType":"mysql",
"IsMaster":true,
"Dsn":"root:Password1!@tcp(mysql-a.fanhaninfo.test:3306)/dev_digital?charset=utf8mb4",
"sqlMaxIdleConns":100,
"sqlMaxOpenConns":100,
"sqlLogLevel":2
}
]

@ -0,0 +1,10 @@
[
{
"DbType":"mysql",
"IsMaster":true,
"Dsn":"root:12345678@tcp(127.0.0.1:3306)/fushouxian?charset=utf8mb4",
"sqlMaxIdleConns":1,
"sqlMaxOpenConns":1,
"sqlLogLevel":2
}
]

@ -0,0 +1,5 @@
{
"rpa_url": "http://172.0.0.19:19005",
"username": "admin",
"password": "123"
}

@ -0,0 +1,7 @@
{
"Priority":100,
"ModuleName":"go",
"ServerUrls":[
"wss://shop.ruixininfo.com/websocket/jsonrpc"
]
}

@ -0,0 +1,108 @@
package main
import (
"fmt"
"log"
"net/http"
"os"
_ "src/init"
"github.com/towgo/towgo/dao/basedboperat"
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/lib/processmanager"
"github.com/towgo/towgo/lib/system"
"github.com/towgo/towgo/towgo"
)
var appName string = "fushouxian-server"
var appVersion string = "1.0.0"
var basePath = system.GetPathOfProgram()
func init() {
//初始化xorm数据库驱动
var dbconfig []xormDriver.DsnConfig
system.ScanConfigJson(basePath+"/config/dbconfig.json", &dbconfig)
xormDriver.New(dbconfig)
//设定默认orm引擎
err := basedboperat.SetOrmEngine("xorm")
if err != nil {
log.Print(err.Error())
}
}
func main() {
pm := processmanager.GetManager()
for k, v := range os.Args {
switch v {
case "start":
if k == 1 {
if pm.Start() {
log.Print("启动成功")
start()
return
} else {
log.Print("启动失败:" + pm.Error.Error())
return
}
}
case "restart":
if k == 1 {
if pm.ReStart() {
log.Print("重启成功")
start()
return
} else {
log.Print("重启失败:" + pm.Error.Error())
}
return
}
case "stop":
if k == 1 {
if pm.Stop() {
log.Print("程序停止成功")
} else {
log.Print("程序停止失败:程序没有运行")
}
return
}
case "version":
if k == 1 {
fmt.Print(appName + ":" + appVersion + "\n")
os.Exit(0)
}
return
}
}
log.Print("参数传递错误,有效参数如下:\n" + os.Args[0] + " start | stop | reload | stop")
}
func start() {
moduleClientInit()
conf := struct {
Serverport string `json:"serverport"`
}{}
system.ScanConfigJson(basePath+"/config/config.json", &conf)
http.HandleFunc("/jsonrpc", towgo.HttpHandller)
log.Print("http服务运行中:0.0.0.0:" + conf.Serverport + "\n")
http.ListenAndServe("0.0.0.0:"+conf.Serverport, nil)
}
func moduleClientInit() {
var node towgo.EdgeServerNodeConfig
system.ScanConfigJson(basePath+"config/togocdn.client.config.json", &node)
node.Methods = towgo.GetMethods()
node.ModuleName = appName
for _, v := range node.ServerUrls {
node.ServerUrl = v
client := towgo.NewEdgeServerNode(node)
client.Connect()
}
}

@ -1 +1 @@
{"pid":42691}
{"pid":36728}

@ -2,9 +2,9 @@
{
"DbType":"mysql",
"IsMaster":true,
"Dsn":"root:root@tcp(localhost:3306)/fushouxian?charset=utf8mb4",
"Dsn":"root:12345678@tcp(127.0.0.1:3306)/fushouxian?charset=utf8mb4",
"sqlMaxIdleConns":1,
"sqlMaxOpenConns":1,
"sqlLogLevel":1
"sqlLogLevel":2
}
]

@ -1,6 +1,6 @@
{
"Priority":100,
"ModuleName":"fushouxian-server",
"ModuleName":"go",
"ServerUrls":[
"wss://shop.ruixininfo.com/websocket/jsonrpc"
]

@ -1,13 +1,16 @@
package main
import (
"fmt"
"log"
"net/http"
"os"
_ "src/init"
"github.com/towgo/towgo/dao/basedboperat"
"github.com/towgo/towgo/dao/ormDriver/gormDriver"
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/lib/processmanager"
"github.com/towgo/towgo/lib/system"
"github.com/towgo/towgo/towgo"
)
@ -15,18 +18,17 @@ import (
var appName string = "fushouxian-server"
var appVersion string = "1.0.0"
// var basePath = system.GetPathOfProgram()
var basePath = "E:\\workfile\\FuShouXian-Backend\\apps\\fushouxian-server"
var basePath = system.GetPathOfProgram()
func init() {
//初始化xorm数据库驱动
var dbconfig []xormDriver.DsnConfig
system.ScanConfigJson(basePath+"\\config\\dbconfig.json", &dbconfig)
system.ScanConfigJson(basePath+"/config/dbconfig.json", &dbconfig)
xormDriver.New(dbconfig)
//初始化gorm数据库驱动
var gormdbconfig []gormDriver.DsnConfig
system.ScanConfigJson(basePath+"\\config\\dbconfig.json", &gormdbconfig)
system.ScanConfigJson(basePath+"/config/dbconfig.json", &gormdbconfig)
gormDriver.New(gormdbconfig)
//设定默认orm引擎
@ -37,7 +39,7 @@ func init() {
}
func main() {
/*pm := processmanager.GetManager()
pm := processmanager.GetManager()
for k, v := range os.Args {
switch v {
case "start":
@ -81,8 +83,7 @@ func main() {
}
}
log.Print("参数传递错误,有效参数如下:\n" + os.Args[0] + " start | stop | reload | stop")
*/
start()
}
func start() {
@ -92,7 +93,7 @@ func start() {
conf := struct {
Serverport string `json:"serverport"`
}{}
system.ScanConfigJson(basePath+"\\config\\config.json", &conf)
system.ScanConfigJson(basePath+"/config/config.json", &conf)
http.HandleFunc("/jsonrpc", towgo.HttpHandller)
@ -102,7 +103,7 @@ func start() {
func moduleClientInit() {
var node towgo.EdgeServerNodeConfig
system.ScanConfigJson(basePath+"\\config\\togocdn.client.config.json", &node)
system.ScanConfigJson(basePath+"config/togocdn.client.config.json", &node)
node.Methods = towgo.GetMethods()
node.ModuleName = appName
for _, v := range node.ServerUrls {

@ -2,7 +2,11 @@ module src
go 1.21.5
require github.com/towgo/towgo v0.0.0-20231224080502-c72f73646298
require (
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.825
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.825
github.com/towgo/towgo v0.0.0-20231224080502-c72f73646298
)
require (
github.com/go-sql-driver/mysql v1.7.1 // indirect

@ -215,6 +215,10 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.825 h1:ijG2TLksawrFMdBpfFa5N/HjBZLGRPwmCgg0JFfFl6E=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.825/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.825 h1:F6NQyLl7IscbIV1NcXshJeQVt8nMcS/Ock77aBhYI+k=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.825/go.mod h1:TtDf9a/E/BsheaNyTdYUD3ttvTUIYODO/4bYv6ZW9tY=
github.com/towgo/towgo v0.0.0-20231224080502-c72f73646298 h1:oYz9djtL9h+k2OBxsk7i8Emu233eYJJ5RpAGFua5fHA=
github.com/towgo/towgo v0.0.0-20231224080502-c72f73646298/go.mod h1:mNKhCpd9uCgi1yKphteeXR0S2ZyUJ8UDVPwJ4LKos3s=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

@ -0,0 +1,3 @@
package init
//import _ "src/module/category"

@ -1,12 +0,0 @@
package init
import _ "src/module/category"
import _ "src/module/coupon"
import _ "src/module/goods"
import _ "src/module/service"
import _ "src/module/skuPrice"
import _ "src/module/activity"
import _ "src/module/itemGoodsSkuPrice"
import _ "src/module/good_category_re"
import _ "src/module/sku"
import _ "src/module/address"

@ -0,0 +1,7 @@
package init
import "src/module/usercenter"
func init() {
usercenter.InitManageApi()
}

@ -1,28 +0,0 @@
package activity
func (Activity) TableName() string {
return "activity"
}
type Activity struct {
ID int `json:"id"` // 活动ID
Title string `json:"title"` // 活动标题
Type string `json:"type"` // 活动类型
RichtextID int `json:"richtext_id"` // 富文本ID
RichtextTitle string `json:"richtext_title"` // 富文本标题
StartTime int64 `json:"starttime"` // 活动开始时间
EndTime int64 `json:"endtime"` // 活动结束时间
Rules Rules `json:"rules" ` // 活动规则
StatusCode string `json:"status_code"` // 活动状态码
}
type Rules struct {
ActivityAutoClose string `json:"activity_auto_close"` // 活动自动关闭
FictitiousNum string `json:"fictitious_num"` // 虚拟号码
IsAlone string `json:"is_alone"` // 是否单独
IsFictitious string `json:"is_fictitious"` // 是否虚拟
LimitBuy string `json:"limit_buy"` // 限购
OrderAutoClose string `json:"order_auto_close"` // 订单自动关闭
TeamCard string `json:"team_card"` // 团购卡
TeamNum string `json:"team_num"` // 团购人数
ValidTime string `json:"valid_time"` // 有效时间
}

@ -1,12 +0,0 @@
package activity
import (
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/towgo"
)
func init() {
xormDriver.Sync2(new(Activity))
towgo.NewCRUDJsonrpcAPI("/activity", Activity{}, []Activity{}).RegAPI()
}

@ -1,34 +0,0 @@
package address
func (Address) TableName() string {
return "address"
}
func (Area) TableName() string {
return "area"
}
// Address 表示用户的地址信息
type Address struct {
ID int64 `json:"id"` // 地址的唯一标识符
IsDefault string `json:"is_default"` // 是否为默认地址1表示是0表示否
UserID int64 `json:"user_id"` // 关联用户的ID
Consignee string `json:"consignee"` // 收货人姓名
Phone string `json:"phone"` // 联系电话
ProvinceName string `json:"province_name"` // 省份名称
CityName string `json:"city_name"` // 城市名称
AreaName string `json:"area_name"` // 区域名称
Address string `json:"address"` // 详细地址
ProvinceID int64 `json:"province_id"` // 省份ID
CityID int64 `json:"city_id"` // 城市ID
AreaID int64 `json:"area_id"` // 区域ID
Latitude float64 `json:"latitude"` // 纬度
Longitude float64 `json:"longitude"` // 经度
}
// Area 表示地区信息
type Area struct {
Value int64 `json:"value"` // 地区值
Label string `json:"label"` // 地区标签
PID int64 `json:"pid"` // 上级地区的值
Level int64 `json:"level"` // 地区级别
}

@ -1,24 +0,0 @@
package address
import (
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/towgo"
)
func init() {
xormDriver.Sync2(new(Address), new(Area))
towgo.NewCRUDJsonrpcAPI("/address", Address{}, []Address{}).RegAPI()
towgo.NewCRUDJsonrpcAPI("/area", Area{}, []Area{}).RegAPI()
//towgo.SetFunc("/area", AreaInfo)
}
type AreaResult struct {
AreaData [][][]Area `json:"areaData"`
CityData [][]Area `json:"cityData"`
ProvinceData []Area `json:"provinceData"`
}
/*func AreaInfo(rpc towgo.JsonRpcConnection) {
}
*/

@ -9,58 +9,18 @@ func (Category) TableName() string {
}
type Category struct {
Id int64 `json:"id"`
Image string `json:"image"`
Description string `json:"description"`
Name string `json:"name"`
Type string `json:"type"`
Pid int64 `json:"pid"`
Weigh int64 `json:"weigh"`
Children []Category `json:"children" xorm:"-"`
Id int64 `json:"id"`
Type int64 `json:"type"`
Name string `json:"name"`
ParentId int64 `json:"parent_id"`
Children []Category `json:"children" xorm:"-"`
}
func (c *Category) AfterQuery(session basedboperat.DbTransactionSession) {
var cs []Category
cs = append(cs, Category{
Id: c.Id,
Image: c.Image,
Description: c.Description,
Name: c.Name,
Type: c.Type,
Pid: c.Pid,
Weigh: c.Weigh,
Children: c.Children,
})
var children []Category
var list basedboperat.List
list.Limit = -1
session.ListScan(&list, c, &children)
c.Children = children
children := findChildren(cs, session)
c.Id = children[0].Id
c.Image = children[0].Image
c.Description = children[0].Description
c.Name = children[0].Name
c.Type = children[0].Type
c.Pid = children[0].Pid
c.Weigh = children[0].Weigh
c.Children = children[0].Children
}
// 递归查询子集方法
func findChildren(categories []Category, session basedboperat.DbTransactionSession) []Category {
var result []Category
for _, category := range categories {
var children []Category
var list basedboperat.List
list.Limit = -1
list.Where = append(list.Where, basedboperat.Condition{
Field: "pid",
Operator: "=",
Value: category.Id,
})
session.ListScan(&list, &category, &children) // 传递切片的指针
category.Children = findChildren(children, session)
result = append(result, category)
}
return result
}

@ -8,8 +8,5 @@ import (
func init() {
xormDriver.Sync2(new(Category))
towgo.NewCRUDJsonrpcAPI("/category", Category{}, []Category{}).RegAPI()
towgo.SetFunc("/category/treeList", TreeList)
}
func TreeList(rpcConn towgo.JsonRpcConnection) {
}

@ -1,31 +0,0 @@
package comment
import "time"
func (Comment) TableName() string {
return "comment"
}
// Comment 用户评论结构体
type Comment struct {
ID int64 `json:"id"` // 评论ID
GoodsID int64 `json:"goods_id"` // 商品ID
OrderID int64 `json:"order_id"` // 订单ID
OrderItemID int64 `json:"order_item_id"` // 订单项ID
UserID int64 `json:"user_id"` // 用户ID
Level int64 `json:"level"` // 评级
Content string `json:"content"` // 评论内容
Images []string `json:"images"` // 评论图片列表
Status string `json:"status"` // 评论状态
AdminID int64 `json:"admin_id"` // 管理员ID
ReplyContent string `json:"reply_content"` // 回复内容
ReplyTime time.Time `json:"replytime"` // 回复时间
CreateTime int64 `json:"createtime"` // 创建时间
UpdateTime int64 `json:"updatetime"` // 更新时间
DeleteTime int64 `json:"deletetime"` // 删除时间
User struct {
ID int64 `json:"id"` // 用户ID
Nickname string `json:"nickname"` // 用户昵称
Avatar string `json:"avatar"` // 用户头像
} `json:"user" xorm:"-"` // 用户信息
}

@ -1,12 +0,0 @@
package comment
import (
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/towgo"
)
func init() {
xormDriver.Sync2(new(Comment))
towgo.NewCRUDJsonrpcAPI("/comment", Comment{}, []Comment{}).RegAPI()
}

@ -1,45 +0,0 @@
package goods
func (Coupon) TableName() string {
return "coupon"
}
// Coupon 结构体表示优惠券信息
type Coupon struct {
ID int64 `json:"id"` // 优惠券ID
Name string `json:"name"` // 优惠券名称
Type string `json:"type"` // 优惠券类型
GoodsIds string `json:"goods_ids"` // 关联商品ID
Amount string `json:"amount"` // 优惠金额
Enough string `json:"enough"` // 满足条件金额
Stock int64 `json:"stock"` // 库存
Limit int64 `json:"limit"` // 领取限制
Usetimestart int64 `json:"usetimestart"` // 可使用时间段开始
Usetimeend int64 `json:"usetimeend"` // 可使用时间段结束
Gettimestart int64 `json:"gettimestart"` // 可领取时间段开始
Gettimeend int64 `json:"gettimeend"` // 可领取时间段结束
Description string `json:"description"` // 优惠券描述
StatusCode string `json:"status_code"` // 优惠券状态代码
StatusName string `json:"status_name"` // 优惠券状态名称
GetTime TimeRange `json:"gettime" xorm:"-"` // 可领取时间段
UseTime TimeRange `json:"usetime" xorm:"-"` // 可使用时间段
UserCoupons []string `json:"user_coupons" xorm:"-"` // 用户优惠券列表
}
type TimeRange struct {
Start int64 `json:"start"` // 开始时间
End int64 `json:"end"` // 结束时间
}
func (coupon *Coupon) AfterQuery() error {
coupon.GetTime = TimeRange{
coupon.Gettimestart,
coupon.Gettimeend,
}
coupon.UseTime = TimeRange{
coupon.Usetimestart,
coupon.Usetimeend,
}
return nil
}

@ -1,12 +0,0 @@
package goods
import (
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/towgo"
)
func init() {
xormDriver.Sync2(new(Coupon))
towgo.NewCRUDJsonrpcAPI("/coupon", Coupon{}, []Coupon{}).RegAPI()
}

@ -1,12 +0,0 @@
package good_category_re
func (GoodCategoryRe) TableName() string {
return "good_category_re"
}
// GoodCategoryRe 结构体表示产品信息
type GoodCategoryRe struct {
Id int64 `json:"id"`
GoodsId int64 `json:"goodsId"`
CategoryId int64 `json:"categoryId"`
}

@ -1,12 +0,0 @@
package good_category_re
import (
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/towgo"
)
func init() {
xormDriver.Sync2(new(GoodCategoryRe))
towgo.NewCRUDJsonrpcAPI("/goodCategoryRe", GoodCategoryRe{}, []GoodCategoryRe{}).RegAPI()
}

@ -1,162 +0,0 @@
package goods
import (
"github.com/towgo/towgo/dao/basedboperat"
"log"
"src/module/activity"
coupon "src/module/coupon"
"src/module/good_category_re"
service "src/module/service"
"src/module/sku"
skuPrice "src/module/skuPrice"
"strconv"
"strings"
)
func (Goods) TableName() string {
return "goods"
}
// Goods 结构体表示产品信息
type Goods struct {
ID int64 `json:"id"` // 产品ID
Type string `json:"type"` // 产品类型
Title string `json:"title"` // 产品标题
Subtitle string `json:"subtitle"` // 产品副标题
Weigh int64 `json:"weigh"` // 产品权重
CategoryIds string `json:"category_ids" xorm:"-"` // 类别ID
Image string `json:"image"` // 产品图片
Images []string `json:"images"` // 产品图片数组
Params []Param `json:"params"` // 产品参数
Content string `json:"content"` // 产品内容
Price string `json:"price"` // 产品价格
OriginalPrice string `json:"original_price"` // 产品原价
IsSKU int64 `json:"is_sku"` // 是否有SKU
Likes int64 `json:"likes"` // 喜欢数
Views int64 `json:"views"` // 浏览数
Sales int64 `json:"sales"` // 销售数
ShowSales int64 `json:"show_sales"` // 展示销售数
TotalSales int64 `json:"total_sales"` // 总计销售额
ServiceIds string `json:"service_ids"` // 服务ID
DispatchType string `json:"dispatch_type"` // 派送类型
DispatchIds string `json:"dispatch_ids"` // 派送ID
DeleteTime interface{} `json:"deletetime"` // 删除时间
Activity activity.Activity `json:"activity" xorm:"-"` // 活动
ActivityType string `json:"activity_type"` // 活动类型
Buyers []string `json:"buyers" xorm:"-"` // 购买者列表
SKUPrice []skuPrice.SKUPrice `json:"sku_price" xorm:"-"` // SKU价格列表
Stock int64 `json:"stock"` // 库存
ActivityDiscounts []string `json:"activity_discounts"` // 活动折扣列表
ActivityDiscountsTypes string `json:"activity_discounts_types"` // 活动折扣类型
ActivityDiscountsTags []string `json:"activity_discounts_tags"` // 活动折扣标签
Favorite interface{} `json:"favorite"` // 收藏
DispatchTypeArr []string `json:"dispatch_type_arr"` // 派送类型数组
Service []service.Service `json:"service" xorm:"-"` // 服务列表
SKU []sku.SKU `json:"sku" xorm:"-"` // SKU列表
Coupons []coupon.Coupon `json:"coupons" xorm:"-"` // 优惠券列表
GrouponPrice string `json:"groupon_price"` // 团购价
}
type Param struct {
Title string `json:"title"`
Content string `json:"content"`
}
func (good *Goods) AfterQuery(session basedboperat.DbTransactionSession) error {
var skuPrices []skuPrice.SKUPrice
var skuPrice skuPrice.SKUPrice
var list basedboperat.List
list.Limit = -1
list.Where = append(list.Where, basedboperat.Condition{
Field: "goods_id",
Operator: "=",
Value: good.ID,
})
session.ListScan(&list, &skuPrice, &skuPrices) // 传递切片的指针
good.SKUPrice = skuPrices
if len(skuPrices) > 0 {
var a activity.Activity
for _, v := range skuPrices {
if v.ActivityId != 0 {
err := session.Get(&a, nil, "id = ?", v.ActivityId)
if err != nil {
log.Println("@", err)
return err
}
break
}
}
good.Activity = a
}
var serverList []service.Service
sIds := strings.Split(good.ServiceIds, ",")
for _, sId := range sIds {
var s service.Service
err := session.Get(&s, nil, "id = ?", sId)
if err != nil {
return err
}
serverList = append(serverList, s)
}
good.Service = serverList
var gcr good_category_re.GoodCategoryRe
var gcrs []good_category_re.GoodCategoryRe
var list2 basedboperat.List
list2.Limit = -1
list2.Where = append(list.Where, basedboperat.Condition{
Field: "goods_id",
Operator: "=",
Value: good.ID,
})
session.ListScan(&list2, &gcr, &gcrs) // 传递切片的指针
var tempIds []string
for _, v := range gcrs {
tempIds = append(tempIds, strconv.FormatInt(v.CategoryId, 10))
}
result := ""
if len(tempIds) > 1 {
result = strings.Join(tempIds, ",")
} else if len(tempIds) == 1 {
result = tempIds[0]
}
good.CategoryIds = result
var skus []sku.SKU
var skud sku.SKU
var listSku basedboperat.List
listSku.Limit = -1
listSku.Where = append(listSku.Where, basedboperat.Condition{
Field: "goods_id",
Operator: "=",
Value: good.ID,
})
listSku.Where = append(listSku.Where, basedboperat.Condition{
Field: "pid",
Operator: "=",
Value: 0,
})
session.ListScan(&listSku, &skud, &skus)
good.SKU = skus
/* var cs []coupon.Coupon
var c coupon.Coupon
var list2 basedboperat.List
list2.Limit = -1
list2.Where = append(list.Where, basedboperat.Condition{
Field: "goods_ids",
Operator: "like",
Value: "%" + strconv.FormatInt(good.ID, 10) + "%",
})
list2.Or = append(list.Where, basedboperat.Condition{
Field: "goods_ids",
Operator: "like",
Value: "%" + strconv.FormatInt(good.ID, 10) + "%",
})
session.ListScan(&list, &sku, &skus)*/
return nil
}

@ -1,108 +0,0 @@
package goods
import (
"github.com/towgo/towgo/dao/basedboperat"
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/towgo"
"log"
"src/module/good_category_re"
)
func init() {
xormDriver.Sync2(new(Goods))
towgo.NewCRUDJsonrpcAPI("/goods", Goods{}, []Goods{}).RegAPI()
towgo.SetFunc("/goods/list2", List2)
}
type List2Params struct {
CategoryId interface{} `json:"category_id"`
Keywords string `json:"keywords"`
Page int64 `json:"page"`
}
func List2(rpcConn towgo.JsonRpcConnection) {
var params List2Params
err := rpcConn.ReadParams(&params)
if err != nil {
log.Println(err)
return
}
var good Goods
var goods []Goods
var gcr good_category_re.GoodCategoryRe
var gcrs []good_category_re.GoodCategoryRe
var listGcr basedboperat.List
listGcr.Limit = 10
var listGood basedboperat.List
listGood.Limit = 10
if params.CategoryId != 0 {
listGcr.Where = append(listGcr.Where, basedboperat.Condition{
Field: "category_id",
Operator: "=",
Value: params.CategoryId,
})
}
if params.CategoryId != "0" {
listGcr.Where = append(listGcr.Where, basedboperat.Condition{
Field: "category_id",
Operator: "=",
Value: params.CategoryId,
})
}
if params.Keywords != "" {
listGood.Like = make(map[string][]interface{})
listGood.Like["title"] = []interface{}{"%" + params.Keywords + "%"}
}
basedboperat.ListScan(&listGcr, &gcr, &gcrs)
//basedboperat.ListScan(&listGood, &good, &goods)
sql := "select * from " + good.TableName() + " where title like '%" + params.Keywords + "%'"
err = basedboperat.SqlQueryScan(&goods, sql)
if err != nil {
log.Println(err)
//rpcConn.WriteError(500, err.Error())
//return
}
sql = "select count(id) as `count` from " + good.TableName()
var m []map[string]interface{}
err = basedboperat.SqlQueryScan(&m, sql)
if err != nil {
log.Println(err)
}
count := int64(m[0]["count"].(float64))
mapGcrs := make(map[int64]int64)
for _, v := range gcrs {
mapGcrs[v.GoodsId] = v.CategoryId
}
var resultGoods []Goods
for _, v := range goods {
if mapGcrs[v.ID] != 0 {
resultGoods = append(resultGoods, v)
}
}
type data struct {
ResultGoods []Goods `json:"resultGoods"`
CurrentPage int64 `json:"current_Page"`
LastPage int64 `json:"last_page"`
PerPage int64 `json:"per_page"`
Total int64 `json:"total"`
}
var lastPage int64
if count%10 == 0 {
lastPage = count / 10
} else {
lastPage = count/10 + 1
}
d := data{
ResultGoods: resultGoods,
CurrentPage: params.Page,
LastPage: lastPage,
PerPage: 10,
Total: count,
}
rpcConn.WriteResult(d)
}

@ -1,17 +0,0 @@
package itemGoodsSkuPrice
func (ItemGoodsSkuPrice) TableName() string {
return "item_goods_sku_price"
}
// ItemGoodsSkuPrice 结构体表示商品 SKU 的价格信息中的具体项
type ItemGoodsSkuPrice struct {
ID int64 `json:"id"` // 唯一标识
ActivityID int64 `json:"activity_id"` // 活动的唯一标识
SkuPriceID int64 `json:"sku_price_id"` // SKU 价格的唯一标识
GoodsID int64 `json:"goods_id"` // 商品的唯一标识
Stock int64 `json:"stock"` // 库存
Sales int64 `json:"sales"` // 销量
Price string `json:"price"` // 价格
Status string `json:"status"` // 状态
}

@ -1,12 +0,0 @@
package itemGoodsSkuPrice
import (
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/towgo"
)
func init() {
xormDriver.Sync2(new(ItemGoodsSkuPrice))
towgo.NewCRUDJsonrpcAPI("/itemGoodsSkuPrice", ItemGoodsSkuPrice{}, []ItemGoodsSkuPrice{}).RegAPI()
}

@ -1,104 +0,0 @@
package order
func (Order) TableName() string {
return "order"
}
// Order 表示订单信息
type Order struct {
ID int64 `json:"id"` // 订单ID
Type string `json:"type"` // 订单类型
OrderSN string `json:"order_sn"` // 订单编号
UserID int64 `json:"user_id"` // 用户ID
ActivityType string `json:"activity_type"` // 活动类型
GoodsAmount string `json:"goods_amount"` // 商品金额
DispatchAmount string `json:"dispatch_amount"` // 配送费用
Phone string `json:"phone"` // 联系电话
Consignee string `json:"consignee"` // 收货人
ProvinceName string `json:"province_name"` // 省份名称
CityName string `json:"city_name"` // 城市名称
AreaName string `json:"area_name"` // 区域名称
Address string `json:"address"` // 收货地址
ProvinceID int64 `json:"province_id"` // 省份ID
CityID int64 `json:"city_id"` // 城市ID
AreaID int64 `json:"area_id"` // 区域ID
Status int64 `json:"status"` // 订单状态
InvoiceStatus string `json:"invoice_status"` // 发票状态
Memo string `json:"memo"` // 备注
Remark string `json:"remark"` // 备注
TotalAmount string `json:"total_amount"` // 订单总金额
ScoreAmount int64 `json:"score_amount"` // 积分金额
TotalFee string `json:"total_fee"` // 总费用
LastTotalFee string `json:"last_total_fee"` // 最终总费用
DiscountFee string `json:"discount_fee"` // 折扣金额
CouponFee string `json:"coupon_fee"` // 优惠券金额
ActivityDiscountMoney string `json:"activity_discount_money"` // 活动折扣金额
DispatchDiscountMoney string `json:"dispatch_discount_money"` // 配送折扣金额
PayFee string `json:"pay_fee"` // 支付费用
ScoreFee int64 `json:"score_fee"` // 积分费用
GoodsOriginalAmount string `json:"goods_original_amount"` // 商品原始金额
CouponsID int64 `json:"coupons_id"` // 优惠券ID
TransactionID string `json:"transaction_id"` // 交易ID
PaymentJSON string `json:"payment_json"` // 支付信息JSON
PayType string `json:"pay_type"` // 支付类型
Paytime int64 `json:"paytime"` // 支付时间
Ext string `json:"ext"` // 扩展信息
Platform string `json:"platform"` // 平台
Createtime int64 `json:"createtime"` // 创建时间
Item []OrderItem `json:"item"` // 订单项列表
StatusCode string `json:"status_code"` // 状态编码
StatusName string `json:"status_name"` // 状态名称
StatusDesc string `json:"status_desc"` // 状态描述
Btns []string `json:"btns"` // 按钮列表
ExtArr []ExtArr `json:"ext_arr"` // 扩展信息数组
}
type ExtArr struct {
BuyType string `json:"buy_type"`
GrouponId int64 `json:"groupon_id"`
ExpiredTime int64 `json:"expired_time"`
}
// OrderItem 表示订单项信息
type OrderItem struct {
ID int64 `json:"id"` // 订单项ID
UserID int64 `json:"user_id"` // 用户ID
OrderID int64 `json:"order_id"` // 订单ID
GoodsID int64 `json:"goods_id"` // 商品ID
GoodsType string `json:"goods_type"` // 商品类型
GoodsSkuPriceID int64 `json:"goods_sku_price_id"` // 商品SKU价格ID
ActivityID int64 `json:"activity_id"` // 活动ID
ActivityType string `json:"activity_type"` // 活动类型
ItemGoodsSkuPriceID int64 `json:"item_goods_sku_price_id"` // 订单项商品SKU价格ID
GoodsSkuText string `json:"goods_sku_text"` // 商品SKU文本
GoodsTitle string `json:"goods_title"` // 商品标题
GoodsImage string `json:"goods_image"` // 商品图片
GoodsOriginalPrice string `json:"goods_original_price"` // 商品原始价格
DiscountFee string `json:"discount_fee"` // 折扣金额
GoodsPrice string `json:"goods_price"` // 商品价格
GoodsNum int64 `json:"goods_num"` // 商品数量
GoodsWeight int64 `json:"goods_weight"` // 商品重量
PayPrice string `json:"pay_price"` // 支付价格
DispatchStatus int64 `json:"dispatch_status"` // 配送状态
DispatchFee string `json:"dispatch_fee"` // 配送费用
DispatchType string `json:"dispatch_type"` // 配送类型
DispatchID int64 `json:"dispatch_id"` // 配送ID
StoreID int64 `json:"store_id"` // 店铺ID
AftersaleStatus int64 `json:"aftersale_status"` // 售后状态
CommentStatus int64 `json:"comment_status"` // 评论状态
RefundStatus int64 `json:"refund_status"` // 退款状态
RefundFee string `json:"refund_fee"` // 退款费用
RefundMsg string `json:"refund_msg"` // 退款消息
ExpressName string `json:"express_name"` // 快递公司名称
ExpressCode string `json:"express_code"` // 快递公司代码
ExpressNo string `json:"express_no"` // 快递单号
Ext string `json:"ext"` // 扩展信息
Createtime int64 `json:"createtime"` // 创建时间
Updatetime int64 `json:"updatetime"` // 更新时间
StatusCode string `json:"status_code"` // 状态编码
StatusName string `json:"status_name"` // 状态名称
StatusDesc string `json:"status_desc"` // 状态描述
Btns []string `json:"btns"` // 按钮列表
ExtArr []ExtArr `json:"ext_arr"` // 扩展信息数组
StatusText string `json:"status_text"` // 状态文本
}

@ -1,13 +0,0 @@
package goods
func (Service) TableName() string {
return "service"
}
// Service 结构体表示服务信息
type Service struct {
ID int64 `json:"id"` // 服务ID
Name string `json:"name"` // 服务名称
Image string `json:"image"` // 服务图片
Description string `json:"description"` // 服务描述
}

@ -1,12 +0,0 @@
package goods
import (
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/towgo"
)
func init() {
xormDriver.Sync2(new(Service))
towgo.NewCRUDJsonrpcAPI("/service", Service{}, []Service{}).RegAPI()
}

@ -1,35 +0,0 @@
package sku
import "github.com/towgo/towgo/dao/basedboperat"
func (SKU) TableName() string {
return "sku"
}
// SKU 表示SKU属性
type SKU struct {
ID int64 `json:"id"` // SKU的唯一标识符
Name string `json:"name"` // SKU的名称
PID int64 `json:"pid"` // 父ID表示SKU属性
GoodsID int64 `json:"goods_id"` // 关联商品的ID
Weigh int64 `json:"weigh"` // SKU的权重
Content []SKU `json:"content" xorm:"-"` // SKU内容列表
}
func (sku *SKU) AfterQuery(session basedboperat.DbTransactionSession) error {
var qSku SKU
var qSkus []SKU
var listSkus basedboperat.List
listSkus.Limit = -1
listSkus.Where = append(listSkus.Where, basedboperat.Condition{
Field: "pid",
Operator: "=",
Value: sku.ID,
})
session.ListScan(&listSkus, &qSku, &qSkus)
sku.Content = qSkus
return nil
}

@ -1,12 +0,0 @@
package sku
import (
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/towgo"
)
func init() {
xormDriver.Sync2(new(SKU))
towgo.NewCRUDJsonrpcAPI("/sku", SKU{}, []SKU{}).RegAPI()
}

@ -1,48 +0,0 @@
package goods
import (
"github.com/towgo/towgo/dao/basedboperat"
"src/module/itemGoodsSkuPrice"
"strconv"
)
func (SKUPrice) TableName() string {
return "sku_price"
}
// SKUPrice 结构体表示商品 SKU 的价格信息
type SKUPrice struct {
ID int64 `json:"id"` // SKU 价格的唯一标识
GoodsSkuIds []int64 `json:"goods_sku_ids"` // 商品 SKU 的标识数组
GoodsId int64 `json:"goods_id"` // 商品的唯一标识
Weigh int64 `json:"weigh"` // 权重
Image string `json:"image"` // 图片链接
Stock int64 `json:"stock"` // 库存
StockWarning interface{} `json:"stock_warning"` // 库存预警信息,根据实际情况调整数据类型
Sales int64 `json:"sales"` // 销量
SN string `json:"sn"` // 商品编号
Weight int64 `json:"weight"` // 重量
Price string `json:"price"` // 价格
GoodsSkuText string `json:"goods_sku_text"` // 商品 SKU 文本描述
Status string `json:"status"` // 状态
GrouponPrice string `json:"groupon_price"` // 团购价格
ActivityType string `json:"activity_type"` // 活动类型
ActivityId int64 `json:"activity_id"` // 活动的唯一标识
ItemGoodsSkuPrice itemGoodsSkuPrice.ItemGoodsSkuPrice `json:"item_goods_sku_price" xorm:"-"` // 商品 SKU 价格信息
GoodsSkuIdArr []string `json:"goods_sku_id_arr" xorm:"-"` // 商品 SKU 标识数组
}
func (sku *SKUPrice) AfterQuery(session basedboperat.DbTransactionSession) error {
var item itemGoodsSkuPrice.ItemGoodsSkuPrice
err := session.Get(&item, nil, "sku_price_id = ?", sku.ID)
if err != nil {
return err
}
sku.ItemGoodsSkuPrice = item
for _, id := range sku.GoodsSkuIds {
sku.GoodsSkuIdArr = append(sku.GoodsSkuIdArr, strconv.FormatInt(id, 10))
}
return nil
}

@ -1,12 +0,0 @@
package goods
import (
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
"github.com/towgo/towgo/towgo"
)
func init() {
xormDriver.Sync2(new(SKUPrice))
towgo.NewCRUDJsonrpcAPI("/skuprice", SKUPrice{}, []SKUPrice{}).RegAPI()
}

@ -0,0 +1,133 @@
package tencent
import (
"encoding/json"
"fmt"
"log"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
sms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms/v20210111" // 引入sms
)
type SMSResponse struct {
SendStatusSet []SendStatus `json:"SendStatusSet"` // 发送状态集
RequestId string `json:"RequestId"` // 请求ID
}
type SendStatus struct {
SerialNo string `json:"SerialNo"` // 序列号
PhoneNumber string `json:"PhoneNumber"` // 手机号码
Fee int `json:"Fee"` // 费用
SessionContext string `json:"SessionContext"` // 会话上下文
Code string `json:"Code"` // 状态码
Message string `json:"Message"` // 消息
IsoCode string `json:"IsoCode"` // 国际标准化组织代码
}
func SendSMSVerificationCode(templateID, signName, mobile, verificationCode string) error {
/*
* secretIdsecretKey
*
*
*
* SecretIdSecretKey : https://console.cloud.tencent.com/cam/capi */
credential := common.NewCredential(
// os.Getenv("TENCENTCLOUD_SECRET_ID"),
// os.Getenv("TENCENTCLOUD_SECRET_KEY"),
"AKID1EXk8c8b0U5lPh2TrEa1QnCeBphR9wka",
"sjbOE4sidUlx5EIORRRL6jGkAZDmGb1T",
)
/* :
* */
cpf := profile.NewClientProfile()
/* SDK使POST
* 使GETGET */
cpf.HttpProfile.ReqMethod = "POST"
/* SDK
* */
// cpf.HttpProfile.ReqTimeout = 5
/* 指定接入地域域名,默认就近地域接入域名为 sms.tencentcloudapi.com ,也支持指定地域域名访问,例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com */
cpf.HttpProfile.Endpoint = "sms.tencentcloudapi.com"
/* SDK默认用TC3-HMAC-SHA256进行签名非必要请不要修改这个字段 */
cpf.SignMethod = "HmacSHA1"
/* (sms)client
* ap-guangzhou https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */
client, _ := sms.NewClient(credential, "ap-guangzhou", cpf)
/*
* SDK
*
* 使IDE便 */
request := sms.NewSendSmsRequest()
/* :
* SDK使
* SDK
*
* : https://console.cloud.tencent.com/smsv2
* : https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81 */
/* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId示例如1400006666 */
// 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
request.SmsSdkAppId = common.StringPtr("1400878793")
/* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名 */
// 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
request.SignName = common.StringPtr(signName)
/* 模板 ID: 必须填写已审核通过的模板 ID */
// 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
request.TemplateId = common.StringPtr(templateID)
/* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,若无模板参数,则设置为空*/
request.TemplateParamSet = common.StringPtrs([]string{verificationCode})
/* E.164 +[][]
* +8613711112222 + 8613711112222200*/
request.PhoneNumberSet = common.StringPtrs([]string{"+86" + mobile})
/* 用户的 session 内容(无需要可忽略): 可以携带用户侧 ID 等上下文信息server 会原样返回 */
request.SessionContext = common.StringPtr("")
/* 短信码号扩展号(无需要可忽略): 默认未开通,如需开通请联系 [腾讯云短信小助手] */
request.ExtendCode = common.StringPtr("")
/* 国内短信无需填写该项;国际/港澳台短信已申请独立 SenderId 需要填写该字段,默认使用公共 SenderId无需填写该字段。注月度使用量达到指定量级可申请独立 SenderId 使用,详情请联系 [腾讯云短信小助手](https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81)。 */
request.SenderId = common.StringPtr("")
// 通过client对象调用想要访问的接口需要传入请求对象
response, err := client.SendSms(request)
// 处理异常
if _, ok := err.(*errors.TencentCloudSDKError); ok {
fmt.Printf("An API error has returned: %s", err)
return err
}
// 非SDK异常直接失败。实际代码中可以加入其他的处理。
if err != nil {
return err
}
var resp SMSResponse
b, _ := json.Marshal(response.Response)
json.Unmarshal(b, &resp)
// 打印返回的json字符串
log.Print(resp)
/*
* [FailedOperation.SignatureIncorrectOrUnapproved](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Afailedoperation.signatureincorrectorunapproved-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
* [FailedOperation.TemplateIncorrectOrUnapproved](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Afailedoperation.templateincorrectorunapproved-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
* [UnauthorizedOperation.SmsSdkAppIdVerifyFail](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Aunauthorizedoperation.smssdkappidverifyfail-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
* [UnsupportedOperation.ContainDomesticAndInternationalPhoneNumber](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Aunsupportedoperation.containdomesticandinternationalphonenumber-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
* [](https://tccc.qcloud.com/web/im/index.html#/chat?webAppId=8fa15978f85cb41f7e2ea36920cb3ae1&title=Sms)
*/
return nil
}

@ -0,0 +1,51 @@
package usercenter
import (
"bytes"
"crypto/rand"
"math/big"
"sync"
"time"
)
var loginOrRegSMSVerificationCode sync.Map
// 登记注册用验证码
func StoreLoginOrloginOrRegSMSVerificationCode(mobile string) (string, error) {
codeInterface, ok := loginOrRegSMSVerificationCode.Load(mobile)
if ok {
return codeInterface.(string), nil
}
verificationCode := randCharNumber(6)
loginOrRegSMSVerificationCode.Store(mobile, verificationCode)
go func(mobile string) {
time.Sleep(time.Second * 5 * 60)
loginOrRegSMSVerificationCode.Delete(mobile)
}(mobile)
return verificationCode, nil
}
// 验证注册验证码
func LoginOrRegSMSVerification(mobile, verificationCode string) bool {
codeInterface, ok := loginOrRegSMSVerificationCode.LoadAndDelete(mobile)
if !ok {
return false
}
if codeInterface.(string) == verificationCode {
return true
} else {
return false
}
}
// 随机验证码
func randCharNumber(size int) string {
char := "0123456789"
len64 := int64(len(char))
var s bytes.Buffer
for i := 0; i < size; i++ {
in, _ := rand.Int(rand.Reader, big.NewInt(len64))
s.WriteByte(char[in.Int64()])
}
return s.String()
}

@ -0,0 +1,363 @@
package usercenter
import (
"encoding/json"
"log"
"regexp"
"src/module/tencent"
"github.com/towgo/towgo/dao/basedboperat"
"github.com/towgo/towgo/towgo"
)
func InitManageApi() {
//初始化API加载器
initLoader()
//注册JSON-RPC服务处理器method路由
//账户登录 F
towgo.SetFunc(_methodHead+"/user/loginOrRegByMobile", userLoginOrRegByMobile)
//获取自己的账户信息
towgo.SetFunc(_methodHead+"/user/myinfo", userMyinfo)
//账户注销 F
towgo.SetFunc(_methodHead+"/user/logoff", userLogoff)
//账户注册移动用户注册
towgo.SetFunc(_methodHead+"/user/regByMobile", userRegByMobile)
//获取注册短信验证码
towgo.SetFunc(_methodHead+"/user/getLoginOrRegSMSVerificationCode", getLoginOrRegSMSVerificationCode)
//修改密码 F
towgo.SetFunc(_methodHead+"/user/changepassword", userChangepassword)
}
func isPhoneNumber(input string) bool {
// 中国手机号码正则表达式
// 13[0-9], 14[5,7,9], 15[0-3,5-9], 16[6], 17[0-8], 18[0-9], 19[1,8,9]
phoneNumberPattern := `^1([38][0-9]|14[579]|5[^4]|6[6]|7[0-8]|9[189])\d{8}$`
reg := regexp.MustCompile(phoneNumberPattern)
return reg.MatchString(input)
}
func getLoginOrRegSMSVerificationCode(rpcConn towgo.JsonRpcConnection) {
var params struct {
Mobile string `json:"mobile"`
}
rpcConn.ReadParams(&params)
if !isPhoneNumber(params.Mobile) {
rpcConn.WriteError(500, "手机号码非法")
return
}
code, err := StoreLoginOrloginOrRegSMSVerificationCode(params.Mobile)
if err != nil {
rpcConn.WriteError(500, err.Error())
return
}
err = tencent.SendSMSVerificationCode("2030693", "蕊鑫信息科技", params.Mobile, code)
if err != nil {
rpcConn.WriteError(500, err.Error())
return
}
rpcConn.WriteResult("验证码已经发送,请查收")
}
// 注册用户
func userRegByMobile(rpcConn towgo.JsonRpcConnection) {
result := map[string]interface{}{} //初始化结果参数
var params struct {
Mobile string `json:"mobile"`
VerificationCode string `json:"verification_code"`
}
rpcConn.ReadParams(&params)
if params.Mobile == "" {
rpcConn.WriteError(500, "手机号码不能为空")
return
}
if params.VerificationCode == "" {
rpcConn.WriteError(500, "验证码不能为空")
return
}
if !LoginOrRegSMSVerification(params.Mobile, params.VerificationCode) {
rpcConn.WriteError(500, "验证码错误")
return
}
var user User
user.Username = params.Mobile
user.Password = randCharNumber(8)
/*
user := user{}
user.Nickname = jsonObj.Params.Nickname
user.Email = jsonObj.Params.Email
*/
Err := user.Reg(user.Username, user.Password)
if Err != nil {
rpcConn.WriteError(500, Err.Error())
return
}
//拼装结果返回
result["id"] = user.ID
result["username"] = user.Username
rpcConn.WriteResult(result)
}
// 用户登陆
func userLogin(rpcConn towgo.JsonRpcConnection) {
result := map[string]interface{}{} //初始化结果参数
var err error
rpcResponse := rpcConn.GetRpcResponse()
jsonObj := struct {
Params struct {
Username string `json:"username"`
Password string `json:"password"`
} `json:"params"`
}{}
err = json.Unmarshal([]byte(rpcConn.Read()), &jsonObj)
if err != nil {
rpcResponse.Error.Set(1, err.Error())
rpcConn.Write()
return
}
if jsonObj.Params.Username == "" {
rpcResponse.Error.Set(1001, "")
rpcConn.Write()
return
}
if jsonObj.Params.Password == "" {
rpcResponse.Error.Set(1002, "")
rpcConn.Write()
return
}
user := User{}
loginErr := user.Login(jsonObj.Params.Username, jsonObj.Params.Password)
if loginErr != nil { //模型层登陆成功
//dblog.Write("user:info", fmt.Sprintf("%s@%s 登录失败! 错误信息:%s", user.Username, rpcConn.GetRemoteAddr(), loginErr.Error()))
rpcResponse.Error.Set(1, "用户名或密码错误")
rpcConn.Write()
return
}
result["id"] = user.ID
result["username"] = user.Username
result["token"] = user.UserToken.TokenKey
//dblog.Write("user:info", fmt.Sprintf("%s@%s 登录成功!", user.Username, rpcConn.GetRemoteAddr()))
rpcConn.WriteResult(result)
}
// 用户手机验证码登陆
func userLoginOrRegByMobile(rpcConn towgo.JsonRpcConnection) {
var params struct {
Mobile string `json:"mobile"`
VerificationCode string `json:"verification_code"`
}
rpcConn.ReadParams(&params)
if params.Mobile == "" {
rpcConn.WriteError(500, "手机号码不能为空")
return
}
if params.VerificationCode == "" {
rpcConn.WriteError(500, "验证码不能为空")
return
}
if !LoginOrRegSMSVerification(params.Mobile, params.VerificationCode) {
rpcConn.WriteError(500, "验证码错误")
return
}
//验证通过
user := User{}
basedboperat.Get(&user, nil, "username = ?", params.Mobile)
if user.ID > 0 {
loginErr := user.LoginNoAuth(params.Mobile)
if loginErr != nil { //模型层登陆成功
log.Print(loginErr.Error())
//dblog.Write("user:info", fmt.Sprintf("%s@%s 登录失败! 错误信息:%s", user.Username, rpcConn.GetRemoteAddr(), loginErr.Error()))
rpcConn.WriteError(500, "用户名或密码错误")
return
}
user.Password = ""
user.Salt = ""
//dblog.Write("user:info", fmt.Sprintf("%s@%s 登录成功!", user.Username, rpcConn.GetRemoteAddr()))
rpcConn.WriteResult(user)
return
}
user.Username = params.Mobile
user.Password = randCharNumber(8)
Err := user.Reg(user.Username, user.Password)
if Err != nil {
rpcConn.WriteError(500, Err.Error())
return
}
user.Password = ""
user.Salt = ""
rpcConn.WriteResult(user)
}
// token check
func userTokenCheck(rpcConn towgo.JsonRpcConnection) {
result := map[string]interface{}{} //初始化结果参数
var err error
rpcResponse := rpcConn.GetRpcResponse()
jsonObj := struct {
Session string `json:"session"`
Params struct {
Username string `json:"username"`
Userid int `json:"userid"`
Token string `json:"token"`
} `json:"params"`
}{}
err = json.Unmarshal([]byte(rpcConn.Read()), &jsonObj)
if err != nil {
rpcResponse.Error.Set(1, err.Error())
rpcConn.Write()
return
}
var user *User
user, err = user.LoginByToken(jsonObj.Params.Token)
if err != nil {
result["valid"] = false
rpcConn.WriteResult(result)
return
}
if user.ID == 0 {
result["valid"] = false
rpcConn.WriteResult(result)
return
}
if !user.UserToken.Valid() {
result["valid"] = false
rpcConn.WriteResult(result)
return
}
result["valid"] = true
rpcConn.WriteResult(result)
}
// 用户注销
func userLogoff(rpcConn towgo.JsonRpcConnection) {
//result := map[string]interface{}{} //初始化结果参数
var err error
rpcResponse := rpcConn.GetRpcResponse()
jsonObj := struct {
Session string `json:"session"`
}{}
err = json.Unmarshal([]byte(rpcConn.Read()), &jsonObj)
if err != nil {
rpcResponse.Error.Set(1, err.Error())
rpcConn.Write()
return
}
var user *User
user, err = user.LoginByToken(jsonObj.Session)
if err != nil {
rpcConn.WriteResult(map[string]string{"success": "ok"})
return
}
if user.ID > 0 {
user.Logoff()
}
rpcConn.WriteResult(map[string]string{"success": "ok"})
}
func userMyinfo(rpcConn towgo.JsonRpcConnection) {
userSession, err := LoginByToken(rpcConn.GetRpcRequest().Session)
userSession.Token = rpcConn.GetRpcRequest().Session
if err != nil {
rpcConn.GetRpcResponse().Error.Set(401, err.Error())
rpcConn.Write()
return
}
rpcConn.WriteResult(userSession)
}
func userChangepassword(rpcConn towgo.JsonRpcConnection) {
result := map[string]interface{}{} //初始化结果参数
var err error
rpcResponse := rpcConn.GetRpcResponse()
jsonObj := struct {
Session string `json:"session"`
Params struct {
Oldpassword string `json:"oldpassword"`
Newpassword string `json:"newpassword"`
} `json:"params"`
}{}
err = json.Unmarshal([]byte(rpcConn.Read()), &jsonObj)
if err != nil {
rpcResponse.Error.Set(1, err.Error())
rpcConn.WriteResult(result)
return
}
var user *User
user, err = user.LoginByToken(jsonObj.Session)
if err != nil {
rpcResponse.Error.Set(401, err.Error())
rpcConn.WriteResult(result)
return
}
if user.ID == 0 {
rpcResponse.Error.Set(1003, "")
rpcConn.WriteResult(result)
return
}
err = user.Changepassword(jsonObj.Params.Oldpassword, jsonObj.Params.Newpassword)
if err != nil {
rpcResponse.Error.Set(1, err.Error())
rpcConn.WriteResult(result)
return
}
rpcConn.WriteResult(struct {
Success string `json:"success"`
}{Success: "ok"})
}

@ -0,0 +1,25 @@
package usercenter
import (
"github.com/towgo/towgo/dao/ormDriver/xormDriver"
)
var _methodHead string
var _tableHead string
func SetMethodHead(methodHead string) {
_methodHead = methodHead
}
func SetTableHead(tableHead string) {
_tableHead = tableHead
}
func initLoader() {
//token任务
InitTokenTask()
xormDriver.Sync2(new(User), new(UserToken))
}

@ -0,0 +1,331 @@
package usercenter
import (
"errors"
"github.com/towgo/towgo/dao/basedboperat"
"github.com/towgo/towgo/lib/system"
)
func (User) TableName() string {
return _tableHead + "users"
}
func (*User) CacheExpire() int64 {
return 5000
}
// 账户对象 关联账户信息
type User struct {
ID int64 `json:"id"`
Username string `json:"username"`
Nickname string `json:"nickname"`
Password string `json:"password"`
Salt string `json:"-"` //密码加盐
Email string `json:"email"`
Mobile string `json:"mobile"`
CanDelete bool `json:"-"`
AccessToken string `json:"-"`
Token string `json:"token" gorm:"-" xorm:"-"`
UserToken *UserToken `json:"-" gorm:"-" xorm:"-"`
CreatedAt int64 `json:"created_at"` //创建时间
UpdatedAt int64 `json:"updated_at"` //更新时间
GroupID int64 `json:"group_id"` // 用户组ID
Avatar string `json:"avatar"` // 用户头像
Birthday string `json:"birthday"` // 用户生日
Money string `json:"money"` // 用户资金
Score int64 `json:"score"` // 用户积分
//Verification Verification `json:"verification"` // 用户验证信息
ChildUserCount int64 `json:"child_user_count"` // 子用户数量
ChildUserCount1 int64 `json:"child_user_count_1"` // 第一层子用户数量
ChildUserCount2 int64 `json:"child_user_count_2"` // 第二层子用户数量
TotalConsume string `json:"total_consume"` // 总消费金额
UserID int64 `json:"user_id" xorm:"-"` // 用户ID
Createtime int64 `json:"createtime"` // 创建时间
Expiretime int64 `json:"expiretime"` // 过期时间
ExpiresIn int64 `json:"expires_in"` // 过期时长
//Group Group `json:"group"` // 用户组信息
}
type Verification struct {
Email int `json:"email"` // 邮箱验证状态
Mobile int `json:"mobile"` // 手机验证状态
}
type Group struct {
Name string `json:"name"` // 用户组名
Image string `json:"image"` // 用户组图片
}
// 注册
func (a *User) Reg(username, password string) error {
e := a.CheckForInput(username, password)
if e != nil {
return e
}
//数据库查询出用户信息
finduser := User{}
basedboperat.Get(&finduser, nil, "username = ?", username)
//检查用户名是否存在
if username == finduser.Username {
return errors.New("账户已经存在")
}
//生成密码
a.NewPassword(password)
a.Username = username
a.Mobile = username
a.CanDelete = true
_, err := basedboperat.Create(a) // 通过数据的指针来创建
if err != nil {
return err
}
_, err = a.CreateRelation()
return err
}
// 检查输入参数
func (a *User) CheckForInput(username, password string) error {
if username == "" {
return errors.New("用户名不能为空")
}
if password == "" {
return errors.New("密码不能为空")
}
//防sql注入
if system.FilteredSQLInject(username) {
return errors.New("用户名存在系统保留或非法的字符")
}
return nil
}
func (a *User) NewPassword(newpassword string) {
if newpassword == "" {
return
}
//加密密码
password := system.MD5(newpassword)
//生成salt
salt := system.RandCharCrypto(6)
//密码加盐
password = password + salt
//混合加密
password = system.MD5(password)
a.Password = password
a.Salt = salt
}
// 用户登陆
func (a *User) Login(username, password string) error {
erro := a.CheckForInput(username, password)
if erro != nil {
return erro
}
//通过用户名查询用户数据
err := basedboperat.Get(a, nil, "username = ?", username)
if err != nil {
return err
}
//检查用户名是否存在
//判断用户是否存在
if a.Username == "" {
return errors.New("用户名不存在")
}
//加密密码
upassword := system.MD5(password)
//撒盐
upassword = upassword + a.Salt
//混合加密
upassword = system.MD5(upassword)
//判断密码是否一致
if a.Password != upassword {
//不一致:返回错误
return errors.New("密码错误")
}
//验证通过
//生成用户信息
a.UserToken = NewToken(a)
return nil
}
// 用户登陆
func (a *User) LoginNoAuth(username string) error {
//通过用户名查询用户数据
err := basedboperat.Get(a, nil, "username = ?", username)
if err != nil {
return err
}
//检查用户名是否存在
//判断用户是否存在
if a.Username == "" {
return errors.New("用户名不存在")
}
//验证通过
//生成用户信息
a.UserToken = NewToken(a)
a.Token = a.UserToken.TokenKey
return nil
}
// 用户注销
func (a *User) Logoff() {
DeleteToken(a.UserToken.TokenKey)
}
func LoginByToken(tokenKey string) (*User, error) {
userToken, err := GetToken(tokenKey)
if err != nil {
return nil, err
}
sessionuser := userToken.Payload.(*User)
sessionuser.UserToken = userToken
return sessionuser, nil
}
func (a *User) LoginByToken(tokenKey string) (*User, error) {
userToken, err := GetToken(tokenKey)
if err != nil {
return nil, err
}
sessionuser := userToken.Payload.(*User)
sessionuser.UserToken = userToken
return sessionuser, nil
}
func (a *User) CheckToken(s string) bool {
//判断token是否正确
if s != a.UserToken.TokenKey {
return false
}
//再判断token是否过期
return a.UserToken.Valid()
}
func (a *User) Get() error {
if a.ID > 0 {
return basedboperat.Get(a, nil, "id = ?", a.ID)
}
if a.Username != "" {
return basedboperat.Get(a, nil, "username = ?", a.Username)
}
return errors.New("id或username不能为空")
}
// 修改密码
func (a *User) Changepassword(oldpassword, newpassword string) error {
//通过用户名查询用户数据
err := basedboperat.Get(a, nil, "id = ?", a.ID)
if err != nil {
return err
}
//检查用户名是否存在
//判断用户是否存在
if a.Username == "" {
return errors.New("用户名不存在")
}
//加密密码
upassword := system.MD5(oldpassword)
//撒盐
upassword = upassword + a.Salt
//混合加密
upassword = system.MD5(upassword)
//判断密码是否一致
if a.Password != upassword {
//不一致:返回错误
return errors.New("原始密码错误")
}
a.NewPassword(newpassword)
basedboperat.Update(a, []string{"password", "salt"}, "id = ?", a.ID)
return nil
}
func (a *User) Update() error {
var findModel User
basedboperat.Get(&findModel, nil, "id = ?", a.ID)
if findModel.ID <= 0 {
return errors.New("记录不存在")
}
a.DeleteRelation()
_, err := a.CreateRelation()
if err != nil {
return err
}
basedboperat.Update(a, []string{"nickname", "email"}, "id = ?", a.ID)
return nil
}
func (a *User) Delete() (int64, error) {
var findModel User
basedboperat.Get(&findModel, nil, "id = ?", a.ID)
if !findModel.CanDelete {
return 0, errors.New("无法删除系统用户")
}
a.DeleteRelation()
return basedboperat.Delete(a, a.ID, nil)
}
// 删除关联数据
func (a *User) DeleteRelation() {
if a.ID == 0 {
return
}
}
// 创建关联数据
func (a *User) CreateRelation() (int64, error) {
if a.ID == 0 {
return 0, nil
}
var rowsAffected int64
return rowsAffected, nil
}
func (a *User) AfterQuery() {
if a.ID == 0 {
return
}
a.UserID = a.ID
}

@ -0,0 +1,227 @@
package usercenter
import (
"context"
"errors"
"log"
"sync"
"time"
"github.com/towgo/towgo/dao/basedboperat"
"github.com/towgo/towgo/lib/system"
)
// 缓存有效期
var memCacheTimer int64 = 60 * 10
// token有效期 秒单位计算
var expirationLimit int64 = 86400 * 20
var autoClearLimit int64 = 60 * 10 //10分钟清理一次过期的token
// var expirationLimit int64 = 60
var memCache *MemCache
// UserToken结构体
func (UserToken) TableName() string {
return _tableHead + "users_token"
}
type UserToken struct {
TokenKey string
Uid int64
Payload any `gorm:"-" xorm:"-"`
Expiration int64
UpdatedAt int64
CreatedAt int64
}
func InitTokenTask() {
memCache = &MemCache{}
autoTimeToClear()
}
type MemCache struct {
timers sync.Map
cacheObject sync.Map
cancels sync.Map
}
func (mc *MemCache) CreateTimerToDelete(tokenKey string) {
timer := time.NewTimer(time.Second * time.Duration(memCacheTimer))
mc.timers.Store(tokenKey, timer)
ctx, cancel := context.WithCancel(context.Background())
mc.cancels.Store(tokenKey, cancel)
go mc.DeleteWhenTimeOut(ctx, tokenKey, timer)
}
func (mc *MemCache) DeleteWhenTimeOut(ctx context.Context, tokenKey string, timer *time.Timer) {
select {
case <-timer.C:
mc.timers.Delete(tokenKey)
mc.cacheObject.Delete(tokenKey)
mc.cancels.Delete(tokenKey)
return
case <-ctx.Done():
return
}
}
func (mc *MemCache) ResetTimer(tokenKey string) {
timerInterface, ok := mc.timers.Load(tokenKey)
if ok {
timer := timerInterface.(*time.Timer)
timer.Reset(time.Second * time.Duration(memCacheTimer))
}
}
func (mc *MemCache) Add(tokenKey string, value any) {
mc.cacheObject.Store(tokenKey, value)
mc.CreateTimerToDelete(tokenKey)
}
func (mc *MemCache) Del(tokenKey string) {
timerInterface, ok := mc.timers.Load(tokenKey)
if ok {
timer := timerInterface.(*time.Timer)
timer.Stop() //关闭定时器
cancel_any, isLoaded := mc.cancels.LoadAndDelete(tokenKey) //关闭定时器线程
if isLoaded {
cancel := cancel_any.(context.CancelFunc)
if cancel != nil {
cancel()
}
}
mc.timers.Delete(tokenKey) //清除定时器委托
}
mc.cacheObject.Delete(tokenKey) //清除内存
}
func (mc *MemCache) Get(tokenKey string) (any, bool) {
return mc.cacheObject.Load(tokenKey)
}
// 自动清理过期token定时器
func autoTimeToClear() {
go func() {
defer func() {
err := recover()
if err != nil {
log.Print(err)
}
autoTimeToClear()
}()
var userToken UserToken
for {
time.Sleep(time.Second * time.Duration(autoClearLimit))
basedboperat.SqlExec("delete from "+userToken.TableName()+" where expiration < ?", time.Now().Unix())
}
}()
}
func (t *UserToken) NewTokenGUID(salt string) {
guid := system.GetGUID().Hex()
saltEncode := system.MD5(salt)
tokenCode := system.MD5(guid + saltEncode)
t.TokenKey = tokenCode
}
// 返回一个唯一标识的token令牌
func (t *UserToken) String() string {
return t.TokenKey
}
// token是否有效 检查有效期
// 有效返回true
// 无效返回false
func (t *UserToken) Valid() bool {
return time.Now().Unix() < t.Expiration
}
func (t *UserToken) Check(tokenKey string) bool {
return tokenKey == t.TokenKey
}
// 更新token有效期
func (t *UserToken) Update(expiration int64) {
if expiration > 0 {
t.Expiration = time.Now().Unix() + expiration
} else {
t.Expiration = time.Now().Unix() + expirationLimit
}
}
// 新建一个token
func NewToken(user *User) *UserToken {
timenow := time.Now().Unix()
token := &UserToken{
CreatedAt: timenow,
Uid: user.ID,
Payload: user,
Expiration: timenow + expirationLimit,
}
user.Token = token.TokenKey
token.NewTokenGUID(user.Salt)
basedboperat.Create(token)
memCache.Add(token.TokenKey, token)
return token
}
func GetToken(tokenKey string) (*UserToken, error) {
var userToken *UserToken = &UserToken{}
//缓存查询
userTokenInterface, ok := memCache.Get(tokenKey)
if ok {
//缓存命中
userToken = userTokenInterface.(*UserToken)
//缓存过期 清理
if !userToken.Valid() {
memCache.Del(tokenKey)
return nil, errors.New("token过期(登录失效,请重新登录)")
}
} else {
//数据库查询
//查询持久化数据
err := basedboperat.Get(userToken, nil, "token_key = ?", tokenKey)
if err != nil {
return nil, err
}
if userToken.Uid == 0 {
return nil, errors.New("token不存在(登录失效,请重新登录)") //数据不存在
}
//token过期
if !userToken.Valid() {
return nil, errors.New("token过期(登录失效,请重新登录)")
}
//查询token关联的用户
var user *User = &User{}
basedboperat.Get(user, nil, "id = ?", userToken.Uid)
if user.ID == 0 {
return nil, errors.New("token关联用户不存在(登录失效,请重新登录)") //用户不存在
}
//写入缓存
userToken.Payload = user
memCache.Add(userToken.TokenKey, userToken)
}
return userToken, nil
}
func DeleteToken(tokenKey string) {
memCache.Del(tokenKey)
var userToken *UserToken = &UserToken{}
userToken.TokenKey = tokenKey
basedboperat.Delete(userToken, nil, "token_key = ?", tokenKey)
}
func SetExpiration(hour int64) {
expirationLimit = 3600 * hour
}
Loading…
Cancel
Save