From 1bc4c625011f4e64ec48ce8428e72153fd3c130e Mon Sep 17 00:00:00 2001 From: lijikun Date: Thu, 26 Dec 2024 15:44:48 +0800 Subject: [PATCH] =?UTF-8?q?12.26=E6=97=A5=E5=AE=8C=E6=88=90=E4=BB=8Eexcel?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E4=B8=AD=E5=AF=BC=E5=85=A5=E6=95=B0=E6=8D=AE?= =?UTF-8?q?;=E8=B0=83=E6=95=B4=E6=95=B0=E6=8D=AE=E5=BA=93=E4=B8=ADjwcode?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B(varchar->int)=E5=B9=B6=E4=BF=AE=E6=94=B9dao?= =?UTF-8?q?=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 7 ++++ go.sum | 15 +++++++ internal/cmd/cmd.go | 3 +- internal/controller/couponusers/couponUsers.go | 31 ++++++++++++++ internal/dao/internal/coupon.go | 16 +++---- internal/logic/couponusers/couponUsers.go | 58 +++++++++++++++++++++++++- internal/model/do/coupon.go | 16 +++---- internal/model/entity/coupon.go | 18 ++++---- internal/model/entity/coupon_users.go | 2 +- internal/service/couponusers.go | 6 +-- 10 files changed, 140 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index 3db5c4e..1fab199 100644 --- a/go.mod +++ b/go.mod @@ -25,13 +25,20 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/redis/go-redis/v9 v9.7.0 // indirect + github.com/richardlehane/mscfb v1.0.4 // indirect + github.com/richardlehane/msoleps v1.0.4 // indirect github.com/rivo/uniseg v0.4.7 // indirect + github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect + github.com/xuri/excelize/v2 v2.9.0 // indirect + github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect + golang.org/x/crypto v0.30.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/go.sum b/go.sum index 1ceee4e..49b0fcc 100644 --- a/go.sum +++ b/go.sum @@ -43,15 +43,28 @@ 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.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/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/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= +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.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00= +github.com/richardlehane/msoleps v1.0.4/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= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY= +github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/excelize/v2 v2.9.0 h1:1tgOaEq92IOEumR1/JfYS/eR0KHOCsRv/rYXXh6YJQE= +github.com/xuri/excelize/v2 v2.9.0/go.mod h1:uqey4QBZ9gdMeWApPLdhm9x+9o2lq4iVmjiLfBS5hdE= +github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A= +github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= @@ -60,6 +73,8 @@ go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucg go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index 8eb49a9..ca540c9 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -18,7 +18,8 @@ var ( s := g.Server() s.Group("/api/coupon_backend", func(group *ghttp.RouterGroup) { group.POST("/get-coupon-users", couponusers.NewCouponUsers().GetCouponUsers) - group.POST("delete-coupon-user", couponusers.NewCouponUsers().DeleteCouponUserByJwcode) + group.POST("/delete-coupon-user", couponusers.NewCouponUsers().DeleteCouponUserByJwcode) + group.POST("/import-excel", couponusers.NewCouponUsers().InsertJwcodeByExcel) }) s.Run() return nil diff --git a/internal/controller/couponusers/couponUsers.go b/internal/controller/couponusers/couponUsers.go index 0a4acc2..2754c63 100644 --- a/internal/controller/couponusers/couponUsers.go +++ b/internal/controller/couponusers/couponUsers.go @@ -5,6 +5,7 @@ import ( "CouponBackendGo/internal/model/dto" "CouponBackendGo/internal/service" "github.com/gogf/gf/v2/net/ghttp" + "mime/multipart" ) type CouponUsers struct{} @@ -45,3 +46,33 @@ func (c *CouponUsers) DeleteCouponUserByJwcode(r *ghttp.Request) { r.Response.WriteJsonExit(dto.SuccessWithMsg("删除成功")) //r.Response.WriteJsonExit(dto.SuccessWithData(result)) } + +// 待测试 +// 接受前端传来的excel表格,并解析,返回jwcode切片,可以有重复的,在插入时进行验证,如果有重复的,只插入一次 +func (c *CouponUsers) InsertJwcodeByExcel(r *ghttp.Request) { + + // 从请求中获取文件 + file, _, err := r.FormFile("excelFile") + if err != nil { + r.Response.WriteJsonExit(dto.Error(err.Error())) + } + // 关闭文件 + defer func(file multipart.File) { + err := file.Close() + if err != nil { + // 处理关闭文件时的错误 + r.Response.WriteJsonExit(dto.Error("关闭文件失败")) + } + }(file) + + //参数校验,检查文件是否为空 + if file == nil { + r.Response.WriteJsonExit(dto.Error("文件为空")) + } + + jwcodes, err := service.CouponUsers().InsertJwcodeByExcel(file) + if err != nil { + r.Response.WriteJsonExit(dto.Error(err.Error())) + } + r.Response.WriteJsonExit(dto.SuccessWithData(jwcodes)) +} diff --git a/internal/dao/internal/coupon.go b/internal/dao/internal/coupon.go index 58b2a99..09c0b2a 100644 --- a/internal/dao/internal/coupon.go +++ b/internal/dao/internal/coupon.go @@ -21,14 +21,14 @@ type CouponDao struct { // CouponColumns defines and stores column names for table coupon. type CouponColumns struct { Id string // - Title string // - Cover string // - ImgUrl string // - StartTime string // 到期时间 - EndTime string // - Deleted string // - CreatedAt string // - UpdatedAt string // + Title string // 名字 + Cover string // 封面小图片 + ImgUrl string // 放大看全图 + StartTime string // 有效期起始 + EndTime string // 有效期截止 + Deleted string // 是否删除? + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 } // couponColumns holds the columns for table coupon. diff --git a/internal/logic/couponusers/couponUsers.go b/internal/logic/couponusers/couponUsers.go index 21689f1..ee5dce1 100644 --- a/internal/logic/couponusers/couponUsers.go +++ b/internal/logic/couponusers/couponUsers.go @@ -10,6 +10,9 @@ import ( "errors" "fmt" "github.com/gogf/gf/v2/frame/g" + "github.com/xuri/excelize/v2" + "mime/multipart" + "strconv" "strings" ) @@ -101,8 +104,61 @@ func (s *sCouponUsers) DeleteCouponUserByJwcode(ctx context.Context, couponId, j } // 通过excel导入精网号 -func (s *sCouponUsers) InsertJwcodeByExcel(ctx context.Context) { +func (s *sCouponUsers) InsertJwcodeByExcel(file multipart.File) (jwcodes []int, err error) { + //打开文件并返回一个excelize.File对象,用于读取和操作Excel文件的内容 + f, err := excelize.OpenReader(file) + if err != nil { + return nil, errors.New("打开文件失败") + } + // 关闭文件 + defer func(f *excelize.File) { + err := f.Close() + if err != nil { + // 处理关闭文件时的错误 + return + } + }(f) + + //读取所有工作表名称 + GetSheetMap := f.GetSheetMap() + fmt.Println(GetSheetMap) + if len(GetSheetMap) == 0 { + return nil, errors.New("没有工作表") + } + // 读取第一个工作表 + sheetName := GetSheetMap[1] + //rows, err := f.GetRows(f.GetSheetName(1)) + rows, err := f.GetRows(sheetName) + if err != nil { + return nil, err + } + // 将每行的第一列转换为int,并添加到切片中 + for i, row := range rows { + //跳过第一行 + if i == 0 { + continue + } + // 假设jwcode在每行的第一列 + /*参数校验*/ + //参数校验,检查每行是否有足够数据 + if len(row) == 0 { + continue // 跳过空行 + } + //参数校验,检查jwcode是否为非空字符串 + jwcodeStr := row[0] + if jwcodeStr == "" { + continue // 跳过空行 + } + //将字符串转换为整数 + jwcode, err := strconv.Atoi(jwcodeStr) + if err != nil { + return nil, errors.New("参数转换失败") + } + fmt.Println(jwcode) + jwcodes = append(jwcodes, jwcode) + /*参数校验*/ + } return } diff --git a/internal/model/do/coupon.go b/internal/model/do/coupon.go index 47fc0e8..47254e0 100644 --- a/internal/model/do/coupon.go +++ b/internal/model/do/coupon.go @@ -13,12 +13,12 @@ import ( type Coupon struct { g.Meta `orm:"table:coupon, do:true"` Id interface{} // - Title interface{} // - Cover interface{} // - ImgUrl interface{} // - StartTime interface{} // 到期时间 - EndTime interface{} // - Deleted interface{} // - CreatedAt *gtime.Time // - UpdatedAt *gtime.Time // + Title interface{} // 名字 + Cover interface{} // 封面小图片 + ImgUrl interface{} // 放大看全图 + StartTime interface{} // 有效期起始 + EndTime interface{} // 有效期截止 + Deleted interface{} // 是否删除? + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 } diff --git a/internal/model/entity/coupon.go b/internal/model/entity/coupon.go index c71209d..7c90e7c 100644 --- a/internal/model/entity/coupon.go +++ b/internal/model/entity/coupon.go @@ -10,13 +10,13 @@ import ( // Coupon is the golang structure for table coupon. type Coupon struct { - Id uint `json:"id" orm:"id" description:""` // - Title string `json:"title" orm:"title" description:""` // - Cover string `json:"cover" orm:"cover" description:""` // - ImgUrl string `json:"imgUrl" orm:"img_url" description:""` // - StartTime int `json:"startTime" orm:"start_time" description:"到期时间"` // 到期时间 - EndTime int `json:"endTime" orm:"end_time" description:""` // - Deleted int `json:"deleted" orm:"deleted" description:""` // - CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""` // - UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""` // + Id uint `json:"id" orm:"id" description:""` // + Title string `json:"title" orm:"title" description:"名字"` // 名字 + Cover string `json:"cover" orm:"cover" description:"封面小图片"` // 封面小图片 + ImgUrl string `json:"imgUrl" orm:"img_url" description:"放大看全图"` // 放大看全图 + StartTime int `json:"startTime" orm:"start_time" description:"有效期起始"` // 有效期起始 + EndTime int `json:"endTime" orm:"end_time" description:"有效期截止"` // 有效期截止 + Deleted int `json:"deleted" orm:"deleted" description:"是否删除?"` // 是否删除? + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间 + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间 } diff --git a/internal/model/entity/coupon_users.go b/internal/model/entity/coupon_users.go index 967d382..8a49df3 100644 --- a/internal/model/entity/coupon_users.go +++ b/internal/model/entity/coupon_users.go @@ -7,7 +7,7 @@ package entity // CouponUsers is the golang structure for table coupon_users. type CouponUsers struct { Id uint `json:"id" orm:"id" description:""` // - Jwcode string `json:"jwcode" orm:"jwcode" description:""` // + Jwcode int `json:"jwcode" orm:"jwcode" description:""` // Time int `json:"time" orm:"time" description:"领取时间"` // 领取时间 CouponId int `json:"couponId" orm:"coupon_id" description:"优惠券id"` // 优惠券id Code string `json:"code" orm:"code" description:""` // diff --git a/internal/service/couponusers.go b/internal/service/couponusers.go index 6f72c5f..d589d91 100644 --- a/internal/service/couponusers.go +++ b/internal/service/couponusers.go @@ -9,6 +9,7 @@ import ( "CouponBackendGo/api/v1/couponusers" "context" "database/sql" + "mime/multipart" ) type ( @@ -18,12 +19,9 @@ type ( // 根据jwcode,优惠券id删除用户 DeleteCouponUserByJwcode(ctx context.Context, couponId int, jwcode int) (result sql.Result, err error) // 通过excel导入精网号 - InsertJwcodeByExcel(ctx context.Context) + InsertJwcodeByExcel(file multipart.File) (jwcodes []int, err error) // 根据精网号发放用户优惠券 InsertCouponUserByJwcode(ctx context.Context) - // 原来的(不全) - // 根据优惠券id查看拥有优惠券的用户 - GetCouponUsersByCondition1(ctx context.Context, couponId int, jwcode int, name string) (users []couponusers.GetCouponUsersRes, err error) } )