🚧 添加xlsx导入导出功能

This commit is contained in:
孙晓龙
2024-05-27 20:49:52 +08:00
parent 6c09c9a2ea
commit 706fe44ab4
14 changed files with 156 additions and 24 deletions

3
.gitattributes vendored
View File

@@ -1 +1,2 @@
* linguist-language=GO
* linguist-language=GO
*.xlsx filter=lfs diff=lfs merge=lfs -text

View File

@@ -15,6 +15,8 @@ type IAppleCardInfoV1 interface {
CardInfoCreate(ctx context.Context, req *v1.CardInfoCreateReq) (res *v1.CardInfoCreateRes, err error)
CardInfoUpdate(ctx context.Context, req *v1.CardInfoUpdateReq) (res *v1.CardInfoUpdateRes, err error)
CardInfoDelete(ctx context.Context, req *v1.CardInfoDeleteReq) (res *v1.CardInfoDeleteRes, err error)
CardInfoDownloadTemplate(ctx context.Context, req *v1.CardInfoDownloadTemplateReq) (res *v1.CardInfoDownloadTemplateRes, err error)
CardInfoBatchAddFromXlsx(ctx context.Context, req *v1.CardInfoBatchAddFromXlsxReq) (res *v1.CardInfoBatchAddFromXlsxRes, err error)
RechargeHistoryList(ctx context.Context, req *v1.RechargeHistoryListReq) (res *v1.RechargeHistoryListRes, err error)
RechargeSubmit(ctx context.Context, req *v1.RechargeSubmitReq) (res *v1.RechargeSubmitRes, err error)
RechargeSubmitQuery(ctx context.Context, req *v1.RechargeSubmitQueryReq) (res *v1.RechargeSubmitQueryRes, err error)

View File

@@ -2,6 +2,7 @@ package v1
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"kami/api/commonapi"
"kami/internal/model/entity"
@@ -13,7 +14,7 @@ type AppleAccountRecord struct {
}
type CardInfoListReq struct {
g.Meta `path:"/cardInfo/AppleCard/getList" tags:"苹果礼品卡账户" method:"get" summary:"获取苹果账户"`
g.Meta `path:"/cardInfo/AppleCard/account/getList" tags:"苹果礼品卡账户" method:"get" summary:"获取苹果账户"`
commonapi.CommonPageReq
Account string `json:"account" description:"账户"`
}
@@ -23,7 +24,7 @@ type CardInfoListRes struct {
}
type CardInfoCreateReq struct {
g.Meta `path:"/cardInfo/AppleCard/create" tags:"苹果礼品卡账户" method:"post" summary:"创建苹果账户"`
g.Meta `path:"/cardInfo/AppleCard/account/create" tags:"苹果礼品卡账户" method:"post" summary:"创建苹果账户"`
AppleAccountRecord
}
@@ -31,7 +32,7 @@ type CardInfoCreateRes struct {
}
type CardInfoUpdateReq struct {
g.Meta `path:"/cardInfo/AppleCard/update" tags:"苹果礼品卡账户" method:"put" summary:"修改苹果账户"`
g.Meta `path:"/cardInfo/AppleCard/account/update" tags:"苹果礼品卡账户" method:"put" summary:"修改苹果账户"`
AppleAccountRecord
commonapi.CommonStrId
}
@@ -41,9 +42,26 @@ type CardInfoUpdateRes struct {
}
type CardInfoDeleteReq struct {
g.Meta `path:"/cardInfo/AppleCard/delete" tags:"苹果礼品卡账户" method:"delete" summary:"删除苹果账户"`
g.Meta `path:"/cardInfo/AppleCard/account/delete" tags:"苹果礼品卡账户" method:"delete" summary:"删除苹果账户"`
commonapi.CommonStrId
}
type CardInfoDeleteRes struct {
}
type CardInfoDownloadTemplateReq struct {
g.Meta `path:"/cardInfo/AppleCard/account/downloadTemplate" tags:"苹果礼品卡账户" method:"get" summary:"下载导入模板"`
}
type CardInfoDownloadTemplateRes struct {
g.Meta `mime:"application/vnd.ms-excel"`
}
type CardInfoBatchAddFromXlsxReq struct {
g.Meta `path:"/cardInfo/AppleCard/account/batchAdd" tags:"苹果礼品卡账户" method:"post" summary:"批量导入账户"`
File *ghttp.UploadFile `v:"required#文件不能为空" json:"file" type:"file" description:"选择上传文件"`
}
type CardInfoBatchAddFromXlsxRes struct {
Msg string `json:"msg" description:"导入结果"`
}

View File

@@ -8,7 +8,7 @@ import (
)
type RechargeHistoryListReq struct {
g.Meta `path:"/cardInfo/AppleCard/getRechargeHistoryList" tags:"苹果礼品卡充值记录" method:"get" summary:"获取礼品卡充值记录"`
g.Meta `path:"/cardInfo/AppleCard/rechargeOrder/getList" tags:"苹果礼品卡充值记录" method:"get" summary:"获取礼品卡充值记录"`
OrderNo string `json:"orderNo" v:"required#订单ID不能为空" description:"订单ID"`
}

View File

@@ -37,7 +37,7 @@ type RechargeSubmitQueryRes struct {
// RechargeListReq 礼品卡订单记录
type RechargeListReq struct {
g.Meta `path:"/cardInfo/appleCard/rechargeOrderList" tags:"苹果礼品卡充值" method:"get" summary:"获取充值记录列表"`
g.Meta `path:"/cardInfo/appleCard/rechargeOrder/list" tags:"苹果礼品卡充值" method:"get" summary:"获取充值记录列表"`
commonapi.CommonPageReq
AccountID string `json:"accountId" description:"账户ID"`
}
@@ -54,7 +54,7 @@ type RechargeListRes struct {
// RechargeHandlerReq 处理充值订单
type RechargeHandlerReq struct {
g.Meta `path:"/cardInfo/appleCard/handler" tags:"轮询处理礼品卡" method:"post" summary:"获取待处理的iTunes账号"`
g.Meta `path:"/cardInfo/appleCard/rechargeOrder/handler" tags:"轮询处理礼品卡" method:"post" summary:"获取待处理的iTunes账号"`
MachineID string `json:"machineId" v:"required#机器ID不能为空" description:"机器ID"`
}
@@ -68,7 +68,7 @@ type RechargeHandlerRes struct {
}
type RechargeItunesCallbackReq struct {
g.Meta `path:"/cardInfo/appleCard/callback" tags:"轮询处理礼品卡" method:"post" summary:"回调iTunes账号"`
g.Meta `path:"/cardInfo/appleCard/rechargeOrder/callback" tags:"轮询处理礼品卡" method:"post" summary:"回调iTunes账号"`
OrderNo string `json:"orderNo" v:"required#订单ID不能为空" description:"订单ID"`
Amount float64 `json:"amount" v:"required#金额不能为空" description:"金额"`
Status consts.AppleRechargeItunesStatus `json:"status" v:"required#状态不能为空" description:"状态"`
@@ -81,7 +81,7 @@ type RechargeItunesCallbackRes struct {
// CallBackOrderManualReq 这个是回调订单给别人
type CallBackOrderManualReq struct {
g.Meta `path:"/cardInfo/appleCard/callbackByManual" tags:"轮询处理礼品卡" method:"post" summary:"手动回调iTunes账号到gateway用来处理正确订单"`
g.Meta `path:"/cardInfo/appleCard/rechargeOrder/callbackByManual" tags:"轮询处理礼品卡" method:"post" summary:"手动回调iTunes账号到gateway用来处理正确订单"`
OrderNo string `json:"orderNo" v:"required#订单ID不能为空" description:"订单ID"`
ID int64 `json:"id" description:"充值ID"`
}

7
go.mod
View File

@@ -18,8 +18,15 @@ require (
)
require (
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/otiai10/gosseract v2.2.1+incompatible // indirect
github.com/otiai10/gosseract/v2 v2.4.1 // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.3 // indirect
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect
github.com/xuri/excelize/v2 v2.8.1 // indirect
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
golang.org/x/crypto v0.23.0 // indirect
)
require (

15
go.sum
View File

@@ -67,6 +67,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mojocn/base64Captcha v1.3.6 h1:gZEKu1nsKpttuIAQgWHO+4Mhhls8cAKyiV2Ew03H+Tw=
github.com/mojocn/base64Captcha v1.3.6/go.mod h1:i5CtHvm+oMbj1UzEPXaA8IH/xHFZ3DGY3Wh3dBpZ28E=
github.com/mssola/user_agent v0.6.0 h1:uwPR4rtWlCHRFyyP9u2KOV0u8iQXmS7Z7feTrstQwk4=
@@ -81,6 +83,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8=
github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@@ -95,6 +102,12 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/xlzd/gotp v0.1.0 h1:37blvlKCh38s+fkem+fFh7sMnceltoIEBYTVXyoa5Po=
github.com/xlzd/gotp v0.1.0/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg=
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 h1:Chd9DkqERQQuHpXjR/HSV1jLZA6uaoiwwH3vSuF3IW0=
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.8.1 h1:pZLMEwK8ep+CLIUWpWmvW8IWE/yxqG0I1xcN6cVMGuQ=
github.com/xuri/excelize/v2 v2.8.1/go.mod h1:oli1E4C3Pa5RXg1TBXn4ENCXDV5JUMlBluUhG7c+CEE=
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 h1:qhbILQo1K3mphbwKh1vNm4oGezE1eF9fQWmNiIpSfI4=
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
@@ -108,6 +121,8 @@ go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2L
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw=
golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs=

View File

@@ -0,0 +1,69 @@
package apple_card_info
import (
"context"
"github.com/xuri/excelize/v2"
v1 "kami/api/apple_card_info/v1"
"kami/internal/err_handler"
"kami/internal/model"
"kami/internal/service"
)
func (c *ControllerV1) CardInfoBatchAddFromXlsx(ctx context.Context, req *v1.CardInfoBatchAddFromXlsxReq) (res *v1.CardInfoBatchAddFromXlsxRes, err error) {
accountService := service.AppleAccount()
accountEntities, _ := accountService.GetAllAccount(ctx)
f, err := req.File.Open()
if err != nil {
err = err_handler.WrapError(ctx, err_handler.ErrFileBroken, err, "")
return
}
xlsx, err := excelize.OpenReader(f)
if err != nil {
err = err_handler.WrapError(ctx, err_handler.ErrFileBroken, err, "")
return
}
if len(xlsx.GetSheetList()) == 0 {
err = err_handler.WrapError(ctx, err_handler.ErrFileBroken, err, "")
return
}
succeedItem := 0
failedItem := 0
rows, err := xlsx.GetRows(xlsx.GetSheetList()[0])
for _, row := range rows {
isDuplicate := false
for _, accountEntity := range accountEntities {
if accountEntity.Account == row[0] {
isDuplicate = true
}
}
if !isDuplicate {
err = accountService.Add(ctx, model.AppleAccountRecordInput{
AppleAccountRecord: v1.AppleAccountRecord{
Account: row[0],
Password: row[1],
},
}, nil)
if err != nil {
failedItem++
} else {
succeedItem++
}
} else {
failedItem++
}
}
msg := "导入结果"
if failedItem == 0 {
msg += "全部导入成功"
} else {
msg += "成功导入" + string(rune(succeedItem)) + "条,失败" + string(rune(failedItem)) + "条"
}
res = &v1.CardInfoBatchAddFromXlsxRes{
Msg: msg,
}
return
}

View File

@@ -0,0 +1,15 @@
package apple_card_info
import (
"context"
v1 "kami/api/apple_card_info/v1"
"github.com/gogf/gf/v2/frame/g"
)
func (c *ControllerV1) CardInfoDownloadTemplate(ctx context.Context, req *v1.CardInfoDownloadTemplateReq) (res *v1.CardInfoDownloadTemplateRes, err error) {
// 下载文件
g.RequestFromCtx(ctx).Response.ServeFileDownload("./resource/public/苹果账号导入模板.xlsx")
return
}

View File

@@ -9,5 +9,7 @@ var (
ErrAppleAccountRepeat = gcode.New(1003, "账号已存在", nil)
ErrAppleOrderAlreadySucceed = gcode.New(1004, "订单已支付", nil)
ErrFileBroken = gcode.New(2006, "文件损坏", nil)
HttpClientGetError = gcode.New(1005, "http请求失败", nil)
)

View File

@@ -3,6 +3,7 @@ package apple_card_account
import (
"context"
"database/sql"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/glog"
@@ -147,3 +148,14 @@ func (a *sAppleAccount) GetAccordingAccount(ctx context.Context) (data entity.V1
}
return
}
// 获取所有账号
func (a *sAppleAccount) GetAllAccount(ctx context.Context) (data []entity.V1CardAppleAccountInfo, err error) {
data = make([]entity.V1CardAppleAccountInfo, 0)
err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
Scan(&data)
if gerror.Equal(err, sql.ErrNoRows) {
err = nil
}
return
}

View File

@@ -1,14 +0,0 @@
package apple_card_recharge_history
import (
"github.com/gogf/gf/v2/os/glog"
"testing"
"github.com/gogf/gf/v2/os/gctx"
)
func Test_sRechargeHistory_QueryFaceValueByZHL(t *testing.T) {
var h *sRechargeHistory
glog.Info("开始测试")
glog.Info(h.QueryFaceValueByZHL(gctx.New(), "GCA3733900237261"))
}

View File

@@ -32,6 +32,8 @@ type (
GetDetailByAccount(ctx context.Context, account string) (data entity.V1CardAppleAccountInfo, err error)
// GetAccordingAccount 轮播,获取符合条件的第一个账户
GetAccordingAccount(ctx context.Context) (data entity.V1CardAppleAccountInfo, err error)
// 获取所有账号
GetAllAccount(ctx context.Context) (data []entity.V1CardAppleAccountInfo, err error)
}
)

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1005aff14d293396603d8c3704654097ce5fe5beac1b0c4f5474f58738dee797
size 9000