fix 代码生成树形虚拟表,微信模块
This commit is contained in:
parent
e2b44392a3
commit
d1e24c44f8
@ -102,6 +102,7 @@ type ToolsGenTableColumnsEditReq struct {
|
||||
TreeName string `p:"tree_name"`
|
||||
ExcelPort string `p:"excelPort"`
|
||||
UseSnowId string `p:"useSnowId"`
|
||||
UseVirtual string `p:"useVirtual"`
|
||||
}
|
||||
|
||||
type ToolsGenTableColumnsEditRes struct {
|
||||
|
23
api/v1/wechat/demo.go
Normal file
23
api/v1/wechat/demo.go
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* @desc:测试登录小程序后才能访问
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2023/11/3 16:06
|
||||
*/
|
||||
|
||||
package wechat
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/tiger1103/gfast/v3/api/v1/common"
|
||||
)
|
||||
|
||||
type DemoReq struct {
|
||||
g.Meta `path:"/demo" tags:"微信小程序测试" method:"get" summary:"测试"`
|
||||
common.Author
|
||||
}
|
||||
|
||||
type DemoRes struct {
|
||||
common.EmptyRes
|
||||
Info string `json:"info"`
|
||||
}
|
44
api/v1/wechat/login.go
Normal file
44
api/v1/wechat/login.go
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* @desc:警务采集登陆了
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2023/2/24 11:38
|
||||
*/
|
||||
|
||||
package wechat
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
)
|
||||
|
||||
type WxUrlReq struct {
|
||||
g.Meta `path:"/wxUrl" tags:"微信小程序登陆" method:"get" summary:"获取微信小程序url"`
|
||||
}
|
||||
|
||||
type WxUrlRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
type WxLoginReq struct {
|
||||
g.Meta `path:"/wxLogin" tags:"微信小程序登陆" method:"post" summary:"微信登录"`
|
||||
Code string `p:"code" v:"required#code必须"`
|
||||
PhoneCode string `p:"phoneCode"`
|
||||
}
|
||||
|
||||
type WxLoginRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
UserInfo *model.LoginUserRes `json:"userInfo"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type UserLoginOutReq struct {
|
||||
g.Meta `path:"/logout" tags:"微信小程序登陆" method:"get" summary:"退出登录"`
|
||||
commonApi.Author
|
||||
}
|
||||
|
||||
type UserLoginOutRes struct {
|
||||
}
|
||||
|
11
go.mod
11
go.mod
@ -17,13 +17,16 @@ require (
|
||||
github.com/shirou/gopsutil/v3 v3.23.2
|
||||
github.com/sony/sonyflake v1.2.0
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.34
|
||||
github.com/tiger1103/gfast-cache v1.0.1
|
||||
github.com/tiger1103/gfast-cache v1.0.2
|
||||
github.com/tiger1103/gfast-token v1.0.4
|
||||
github.com/xuri/excelize/v2 v2.7.1
|
||||
golang.org/x/tools v0.6.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/ArtisanCloud/PowerLibs/v3 v3.0.15 // indirect
|
||||
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7 // indirect
|
||||
github.com/ArtisanCloud/PowerWeChat/v3 v3.1.8 // indirect
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
@ -57,7 +60,7 @@ require (
|
||||
github.com/mozillazg/go-httpheader v0.2.1 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pkg/errors v0.8.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/redis/go-redis/v9 v9.2.1 // indirect
|
||||
github.com/richardlehane/mscfb v1.0.4 // indirect
|
||||
@ -78,7 +81,9 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.18.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.18.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.18.0 // indirect
|
||||
go.uber.org/atomic v1.5.1 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/zap v1.21.0 // indirect
|
||||
golang.org/x/crypto v0.13.0 // indirect
|
||||
golang.org/x/image v0.5.0 // indirect
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect
|
||||
|
32
go.sum
32
go.sum
@ -1,3 +1,9 @@
|
||||
github.com/ArtisanCloud/PowerLibs/v3 v3.0.15 h1:EKWDvgu3y6S7OjT3ku7LEF6l5KpIKygBVVnbn2d+lns=
|
||||
github.com/ArtisanCloud/PowerLibs/v3 v3.0.15/go.mod h1:KBO7ZQGTBjvYTveKY5M4QQpwxuoGBI0V2fZ4xP+TIuM=
|
||||
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7 h1:P+erNlErr+X2v7Et+yTWaTfIRhw+HfpAPdvNIEwk9Gw=
|
||||
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7/go.mod h1:VZQNCvcK/rldF3QaExiSl1gJEAkyc5/I8RLOd3WFZq4=
|
||||
github.com/ArtisanCloud/PowerWeChat/v3 v3.1.8 h1:azjjwozzUNm1xnGXJIjfU7tjQeqDsTdnFJxAi+jtOpU=
|
||||
github.com/ArtisanCloud/PowerWeChat/v3 v3.1.8/go.mod h1:N6ATGWtdjvnts0dzbe9AYxQ1aRuA1yuTTabcUTQPFZo=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
@ -8,6 +14,7 @@ github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible h1:6JF1bjhT0WN2srEmijfOF
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/apache/rocketmq-client-go/v2 v2.1.1 h1:WY/LkOYSQaVyV+HOqdiIgF4LE3beZ/jwdSLKZlzpabw=
|
||||
github.com/apache/rocketmq-client-go/v2 v2.1.1/go.mod h1:GZzExtXY9zpI6FfiVJYAhw2IXQtgnHUuWpULo7nr5lw=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/casbin/casbin/v2 v2.42.0 h1:EA0aE5PZnFSYY6WulzTScOo4YO6xrGAAZkXRLs8p2ME=
|
||||
@ -124,6 +131,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTK
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
@ -166,6 +175,7 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
@ -182,6 +192,8 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tiger1103/gfast-cache v1.0.1 h1:82U4+DWeaM7BGuXgE9hOzCioiIupMZbvRqYHv+ALe6U=
|
||||
github.com/tiger1103/gfast-cache v1.0.1/go.mod h1:LYOlyTyvlY5Pf1u6tqFrDgG+8zZFmAg5xuKFeehNcnI=
|
||||
github.com/tiger1103/gfast-cache v1.0.2 h1:p+siY2qISzqowGQZvJjnXnrye7D50uVYyJvdBQbrbqk=
|
||||
github.com/tiger1103/gfast-cache v1.0.2/go.mod h1:LYOlyTyvlY5Pf1u6tqFrDgG+8zZFmAg5xuKFeehNcnI=
|
||||
github.com/tiger1103/gfast-token v1.0.4 h1:/tYnh2DjPzXVTfm0wHLR3V21JsTkm1HhiKKIfM6NobE=
|
||||
github.com/tiger1103/gfast-token v1.0.4/go.mod h1:OurEktIaHPJes7lJsIjMo1yz1vSiBRGyV3T8muWytfo=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
@ -196,6 +208,7 @@ github.com/xuri/excelize/v2 v2.7.1/go.mod h1:qc0+2j4TvAUrBw36ATtcTeC1VCM0fFdAXZO
|
||||
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
||||
github.com/xuri/nfp v0.0.0-20230802015359-2d5eeba905e9 h1:jmhvNv5by7bXDzzjzBXaIWmEI4lMYfv5iJtI5Pw5/aM=
|
||||
github.com/xuri/nfp v0.0.0-20230802015359-2d5eeba905e9/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
@ -209,8 +222,16 @@ go.opentelemetry.io/otel/trace v1.18.0 h1:NY+czwbHbmndxojTEKiSMHkG2ClNH2PwmcHrdo
|
||||
go.opentelemetry.io/otel/trace v1.18.0/go.mod h1:T2+SGJGuYZY3bjj5rgh/hN7KIrlpWC5nS8Mjvzckz+0=
|
||||
go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM=
|
||||
go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
|
||||
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
@ -221,12 +242,15 @@ golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
|
||||
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
@ -234,14 +258,18 @@ golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -278,11 +306,14 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
@ -290,6 +321,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
10
internal/app/boot/wechat.go
Normal file
10
internal/app/boot/wechat.go
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* @desc:微信小程序
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2023/11/3 15:31
|
||||
*/
|
||||
|
||||
package boot
|
||||
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/wechat/logic"
|
@ -77,6 +77,7 @@ func (c *loginController) Login(ctx context.Context, req *system.UserLoginReq) (
|
||||
if g.Cfg().MustGet(ctx, "gfToken.multiLogin").Bool() {
|
||||
key = gconv.String(user.Id) + "-" + gmd5.MustEncryptString(user.UserName) + gmd5.MustEncryptString(user.UserPassword+ip+userAgent)
|
||||
}
|
||||
user.UserPassword = ""
|
||||
token, err = service.GfToken().GenerateToken(ctx, key, user)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, err)
|
||||
|
@ -40,6 +40,7 @@ type SysUserColumns struct {
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 删除时间
|
||||
OpenId string // 微信open id
|
||||
}
|
||||
|
||||
// sysUserColumns holds the columns for table sys_user.
|
||||
@ -65,6 +66,7 @@ var sysUserColumns = SysUserColumns{
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
OpenId: "open_id",
|
||||
}
|
||||
|
||||
// NewSysUserDao creates and returns a new DAO object for table data access.
|
||||
|
@ -40,6 +40,7 @@ type ToolsGenTableColumns struct {
|
||||
ShowDetail string // 是否有查看详情功能
|
||||
ExcelPort string // 是否有导入导出excel功能
|
||||
UseSnowId string //主键是否使用雪花ID
|
||||
UseVirtual string // 树表是否使用虚拟表
|
||||
}
|
||||
|
||||
// toolsGenTableColumns holds the columns for table tools_gen_table.
|
||||
@ -64,6 +65,7 @@ var toolsGenTableColumns = ToolsGenTableColumns{
|
||||
ShowDetail: "show_detail",
|
||||
ExcelPort: "excel_port",
|
||||
UseSnowId: "use_snow_id",
|
||||
UseVirtual: "use_virtual",
|
||||
}
|
||||
|
||||
// NewToolsGenTableDao creates and returns a new DAO object for table data access.
|
||||
|
@ -96,6 +96,15 @@ func (s *sSysUser) GetUserByUsername(ctx context.Context, userName string) (user
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysUser) GetUserByPhone(ctx context.Context, phone string) (user *model.LoginUserRes, err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
err = dao.SysUser.Ctx(ctx).Fields(user).Where(dao.SysUser.Columns().Mobile, phone).
|
||||
Scan(&user)
|
||||
liberr.ErrIsNil(ctx, err, "登录失败,用户信息不存在")
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserById 通过用户名获取用户信息
|
||||
func (s *sSysUser) GetUserById(ctx context.Context, id uint64) (user *model.LoginUserRes, err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
@ -127,12 +136,16 @@ func (s *sSysUser) LoginLog(ctx context.Context, params *model.LoginLogParams) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *sSysUser) UpdateLoginInfo(ctx context.Context, id uint64, ip string) (err error) {
|
||||
func (s *sSysUser) UpdateLoginInfo(ctx context.Context, id uint64, ip string, openId ...string) (err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
_, err = dao.SysUser.Ctx(ctx).WherePri(id).Unscoped().Update(g.Map{
|
||||
data := g.Map{
|
||||
dao.SysUser.Columns().LastLoginIp: ip,
|
||||
dao.SysUser.Columns().LastLoginTime: gtime.Now(),
|
||||
})
|
||||
}
|
||||
if len(openId) > 0 && openId[0] != "" {
|
||||
data[dao.SysUser.Columns().OpenId] = openId[0]
|
||||
}
|
||||
_, err = dao.SysUser.Ctx(ctx).WherePri(id).Unscoped().Update(data)
|
||||
liberr.ErrIsNil(ctx, err, "更新用户登录信息失败")
|
||||
})
|
||||
return
|
||||
|
@ -371,6 +371,9 @@ func (s *sToolsGenTable) SaveEdit(ctx context.Context, req *system.ToolsGenTable
|
||||
if req.UseSnowId != "" {
|
||||
table.UseSnowId = gconv.Bool(req.UseSnowId)
|
||||
}
|
||||
if req.UseVirtual != ""{
|
||||
table.UseVirtual = gconv.Bool(req.UseVirtual)
|
||||
}
|
||||
if req.TplCategory != "" {
|
||||
table.TplCategory = req.TplCategory
|
||||
}
|
||||
@ -662,9 +665,14 @@ func (s *sToolsGenTable) GenData(ctx context.Context, tableId int64) (data g.Map
|
||||
var tmpVue string
|
||||
tmpFile := "vue/list-vue.template"
|
||||
if extendData.TplCategory == "tree" {
|
||||
if extendData.UseVirtual{
|
||||
//使用虚拟表树表
|
||||
tmpFile = "vue/tree-virtual-vue.template"
|
||||
}else{
|
||||
//树表
|
||||
tmpFile = "vue/tree-vue.template"
|
||||
}
|
||||
}
|
||||
if tmpVue, err = view.Parse(ctx, tmpFile, tplData); err == nil {
|
||||
vueValue = tmpVue
|
||||
vueValue, err = s.trimBreak(vueValue)
|
||||
|
@ -170,7 +170,7 @@ func (s *sToolsGenTableColumn) InitColumnField(column *entity.ToolsGenTableColum
|
||||
column.ColSpan = 12
|
||||
column.RowSpan = 1
|
||||
column.IsRowStart = false
|
||||
column.MinWidth = 100
|
||||
column.MinWidth = 150
|
||||
column.IsFixed = false
|
||||
column.IsOverflowTooltip = false
|
||||
column.IsCascade = false
|
||||
|
@ -33,4 +33,5 @@ type SysUser struct {
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
DeletedAt *gtime.Time // 删除时间
|
||||
OpenId interface{} // 微信小程序open id
|
||||
}
|
||||
|
@ -32,4 +32,5 @@ type ToolsGenTable struct {
|
||||
ShowDetail interface{} // 是否有查看详情功能
|
||||
ExcelPort interface{} // 是否有导入导出excel功能
|
||||
UseSnowId interface{} //主键是否使用雪花ID
|
||||
UseVirtual interface{} //树表是否使用虚拟表
|
||||
}
|
||||
|
@ -31,4 +31,5 @@ type SysUser struct {
|
||||
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"`
|
||||
DeletedAt *gtime.Time `json:"deletedAt" description:"删除时间"`
|
||||
OpenId string `json:"openId " description:"微信小程序open id"`
|
||||
}
|
||||
|
@ -30,4 +30,5 @@ type ToolsGenTable struct {
|
||||
ShowDetail bool `json:"showDetail" description:"是否有查看详情功能"`
|
||||
ExcelPort bool `json:"excelPort" description:"是否有excel导入导出功能"`
|
||||
UseSnowId bool `json:"useSnowId" description:"主键是否使用雪花ID"`
|
||||
UseVirtual bool `json:"useVirtual" orm:"use_virtual" description:"树表是否使用虚拟表"`
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
type LoginUserRes struct {
|
||||
Id uint64 `orm:"id,primary" json:"id"` //
|
||||
UserName string `orm:"user_name,unique" json:"userName"` // 用户名
|
||||
Mobile string `orm:"mobile" json:"mobile"` //手机号
|
||||
UserNickname string `orm:"user_nickname" json:"userNickname"` // 用户昵称
|
||||
UserPassword string `orm:"user_password" json:"-"` // 登录密码;cmf_password加密
|
||||
UserSalt string `orm:"user_salt" json:"-"` // 加密盐
|
||||
|
@ -37,6 +37,7 @@ type ToolsGenTableEx struct {
|
||||
ShowDetail bool // 是否有查看详情功能
|
||||
ExcelPort bool // 是否有导入导出excel功能
|
||||
UseSnowId bool // 主键是否使用雪花ID
|
||||
UseVirtual bool // 树表是否使用虚拟表
|
||||
TreeCode string // 树编码字段
|
||||
TreeParentCode string // 树父编码字段
|
||||
TreeName string // 树名称字段
|
||||
|
@ -24,9 +24,10 @@ type (
|
||||
NotCheckAuthAdminIds(ctx context.Context) *gset.Set
|
||||
GetAdminUserByUsernamePassword(ctx context.Context, req *system.UserLoginReq) (user *model.LoginUserRes, err error)
|
||||
GetUserByUsername(ctx context.Context, userName string) (user *model.LoginUserRes, err error)
|
||||
GetUserByPhone(ctx context.Context, phone string) (user *model.LoginUserRes, err error)
|
||||
GetUserById(ctx context.Context, id uint64) (user *model.LoginUserRes, err error)
|
||||
LoginLog(ctx context.Context, params *model.LoginLogParams)
|
||||
UpdateLoginInfo(ctx context.Context, id uint64, ip string) (err error)
|
||||
UpdateLoginInfo(ctx context.Context, id uint64, ip string,openId ...string) (err error)
|
||||
GetAdminRules(ctx context.Context, userId uint64) (menuList []*model.UserMenus, permissions []string, err error)
|
||||
GetAdminRole(ctx context.Context, userId uint64, allRoleList []*entity.SysRole) (roles []*entity.SysRole, err error)
|
||||
GetAdminRoleIds(ctx context.Context, userId uint64) (roleIds []uint, err error)
|
||||
|
13
internal/app/wechat/consts/context.go
Normal file
13
internal/app/wechat/consts/context.go
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* @desc:context 相关常量
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2022/3/16 14:52
|
||||
*/
|
||||
|
||||
package consts
|
||||
|
||||
const (
|
||||
// CtxKey 上下文变量存储键名,前后端系统共享
|
||||
CtxKey = "GFastContextWechat"
|
||||
)
|
23
internal/app/wechat/controller/base.go
Normal file
23
internal/app/wechat/controller/base.go
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* @desc:system base controller
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu
|
||||
* @Date: 2022/3/4 18:12
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
commonController "github.com/tiger1103/gfast/v3/internal/app/common/controller"
|
||||
)
|
||||
|
||||
type BaseController struct {
|
||||
commonController.BaseController
|
||||
}
|
||||
|
||||
// Init 自动执行的初始化方法
|
||||
func (c *BaseController) Init(r *ghttp.Request) {
|
||||
c.BaseController.Init(r)
|
||||
}
|
||||
|
24
internal/app/wechat/controller/demo.go
Normal file
24
internal/app/wechat/controller/demo.go
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* @desc:测试登录后才可以访问
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2023/11/3 16:05
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/tiger1103/gfast/v3/api/v1/wechat"
|
||||
)
|
||||
|
||||
var Demo = new(demoController)
|
||||
|
||||
type demoController struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
func (c *demoController) Demo(ctx context.Context,req *wechat.DemoReq)(res *wechat.DemoRes,err error){
|
||||
res = &wechat.DemoRes{Info: "hello word"}
|
||||
return
|
||||
}
|
128
internal/app/wechat/controller/login.go
Normal file
128
internal/app/wechat/controller/login.go
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* @desc:用户登录
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2023/2/24 11:39
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/auth/response"
|
||||
resp "github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/phoneNumber/response"
|
||||
"github.com/gogf/gf/v2/crypto/gmd5"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/tiger1103/gfast/v3/api/v1/wechat"
|
||||
systemModel "github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
systemService "github.com/tiger1103/gfast/v3/internal/app/system/service"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/wechat/service"
|
||||
"github.com/tiger1103/gfast/v3/library/libUtils"
|
||||
"github.com/tiger1103/gfast/v3/library/liberr"
|
||||
)
|
||||
|
||||
var Login = new(loginController)
|
||||
|
||||
type loginController struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
func (c *loginController) WxUrl(ctx context.Context, req *wechat.WxUrlReq) (res *wechat.WxUrlRes, err error) {
|
||||
res = new(wechat.WxUrlRes)
|
||||
res.Url, err = service.Wechat().GetWxUrl(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *loginController) WxLogin(ctx context.Context, req *wechat.WxLoginReq) (res *wechat.WxLoginRes, err error) {
|
||||
var (
|
||||
data *response.ResponseCode2Session
|
||||
phoneData *resp.ResponseGetUserPhoneNumber
|
||||
user *systemModel.LoginUserRes
|
||||
token string
|
||||
)
|
||||
data, err = service.Wechat().Session(ctx, req.Code)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if data.ResponseMiniProgram.ErrCode != 0 {
|
||||
err = gerror.New(fmt.Sprintf("errCode: %d , errMsg: %s", data.ResponseMiniProgram.ErrCode, data.ResponseMiniProgram.ErrMsg))
|
||||
return
|
||||
}
|
||||
phoneData, err = service.Wechat().GetUserPhoneNumber(ctx, req.PhoneCode)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if phoneData.ErrCode != 0 {
|
||||
err = gerror.New(fmt.Sprintf("errCode: %d , errMsg: %s", phoneData.ErrCode, phoneData.ErrMsg))
|
||||
return
|
||||
}
|
||||
user, token, err = c.doLogin(ctx, phoneData.PhoneInfo.PhoneNumber, data.OpenID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
res = &wechat.WxLoginRes{
|
||||
UserInfo: user,
|
||||
Token: token,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *loginController) doLogin(ctx context.Context, phone, openId string) (user *systemModel.LoginUserRes, token string, err error) {
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
ip := libUtils.GetClientIp(ctx)
|
||||
userAgent := libUtils.GetUserAgent(ctx)
|
||||
err = g.Try(ctx, func(ctx context.Context) {
|
||||
//警员服务器未获取到,从本地获取
|
||||
user, err = systemService.SysUser().GetUserByPhone(ctx, phone)
|
||||
liberr.ErrIsNil(ctx, err)
|
||||
if user == nil {
|
||||
// 保存登录失败的日志信息
|
||||
systemService.SysLoginLog().Invoke(gctx.New(), &systemModel.LoginLogParams{
|
||||
Status: 0,
|
||||
Username: phone,
|
||||
Ip: ip,
|
||||
UserAgent: userAgent,
|
||||
Msg: "用户不存在",
|
||||
Module: "微信小程序",
|
||||
})
|
||||
return
|
||||
}
|
||||
err = systemService.SysUser().UpdateLoginInfo(ctx, user.Id, ip, openId)
|
||||
liberr.ErrIsNil(ctx, err)
|
||||
})
|
||||
if user == nil {
|
||||
liberr.ErrIsNil(ctx, errors.New("用户不存在"))
|
||||
}
|
||||
// 报存登录成功的日志信息
|
||||
systemService.SysLoginLog().Invoke(gctx.New(), &systemModel.LoginLogParams{
|
||||
Status: 1,
|
||||
Username: user.Mobile,
|
||||
Ip: ip,
|
||||
UserAgent: userAgent,
|
||||
Msg: "登录成功",
|
||||
Module: "微信小程序",
|
||||
})
|
||||
key := gconv.String(user.Id) + "-" + gmd5.MustEncryptString(gconv.String(user.Id)) + gmd5.MustEncryptString(user.Mobile)
|
||||
if g.Cfg("wechat").MustGet(ctx, "gfToken.multiLogin").Bool() {
|
||||
key = gconv.String(user.Id) + "-" + gmd5.MustEncryptString(gconv.String(user.Id)) + gmd5.MustEncryptString(user.Mobile+ip+userAgent)
|
||||
}
|
||||
user.UserPassword = ""
|
||||
user.UserSalt = ""
|
||||
token, err = service.GfToken().GenerateToken(ctx, key, user)
|
||||
liberr.ErrIsNil(ctx, err, "登录失败,后端服务出现错误")
|
||||
//用户在线状态保存
|
||||
systemService.SysUserOnline().Invoke(gctx.New(), &systemModel.SysUserOnlineParams{
|
||||
UserAgent: userAgent,
|
||||
Uuid: gmd5.MustEncrypt(token),
|
||||
Token: token,
|
||||
Username: user.UserNickname,
|
||||
Ip: ip,
|
||||
})
|
||||
})
|
||||
return
|
||||
}
|
74
internal/app/wechat/logic/context/context.go
Normal file
74
internal/app/wechat/logic/context/context.go
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* @desc:context-service
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2022/9/23 14:51
|
||||
*/
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/wechat/consts"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/wechat/service"
|
||||
)
|
||||
|
||||
func init() {
|
||||
service.RegisterContext(New())
|
||||
}
|
||||
|
||||
type sContext struct{}
|
||||
|
||||
func New() service.IContext {
|
||||
return &sContext{}
|
||||
}
|
||||
|
||||
// Init 初始化上下文对象指针到上下文对象中,以便后续的请求流程中可以修改。
|
||||
func (s *sContext) Init(r *ghttp.Request, customCtx *model.Context) {
|
||||
r.SetCtxVar(consts.CtxKey, customCtx)
|
||||
}
|
||||
|
||||
// Get 获得上下文变量,如果没有设置,那么返回nil
|
||||
func (s *sContext) Get(ctx context.Context) *model.Context {
|
||||
value := ctx.Value(consts.CtxKey)
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
if localCtx, ok := value.(*model.Context); ok {
|
||||
return localCtx
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetUser 将上下文信息设置到上下文请求中,注意是完整覆盖
|
||||
func (s *sContext) SetUser(ctx context.Context, ctxUser *model.ContextUser) {
|
||||
s.Get(ctx).User = ctxUser
|
||||
}
|
||||
|
||||
// GetLoginUser 获取当前登陆用户信息
|
||||
func (s *sContext) GetLoginUser(ctx context.Context) *model.ContextUser {
|
||||
context := s.Get(ctx)
|
||||
if context == nil {
|
||||
return nil
|
||||
}
|
||||
return context.User
|
||||
}
|
||||
|
||||
// GetUserId 获取当前登录用户id
|
||||
func (s *sContext) GetUserId(ctx context.Context) uint64 {
|
||||
user := s.GetLoginUser(ctx)
|
||||
if user != nil {
|
||||
return user.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (s *sContext) GetDeptId(ctx context.Context) uint64 {
|
||||
user := s.GetLoginUser(ctx)
|
||||
if user != nil {
|
||||
return user.DeptId
|
||||
}
|
||||
return 0
|
||||
}
|
13
internal/app/wechat/logic/logic.go
Normal file
13
internal/app/wechat/logic/logic.go
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* @desc:logic注册
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2023/2/24 11:48
|
||||
*/
|
||||
|
||||
package logic
|
||||
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/wechat/logic/token"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/wechat/logic/context"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/wechat/logic/middleware"
|
||||
import _ "github.com/tiger1103/gfast/v3/internal/app/wechat/logic/wechat"
|
49
internal/app/wechat/logic/middleware/middleware.go
Normal file
49
internal/app/wechat/logic/middleware/middleware.go
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* @desc:中间件
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2022/9/23 15:05
|
||||
*/
|
||||
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/wechat/service"
|
||||
)
|
||||
|
||||
func init() {
|
||||
service.RegisterMiddleware(New())
|
||||
}
|
||||
|
||||
func New() service.IMiddleware {
|
||||
return &sMiddleware{}
|
||||
}
|
||||
|
||||
type sMiddleware struct{}
|
||||
|
||||
// Ctx 自定义上下文对象
|
||||
func (s *sMiddleware) Ctx(r *ghttp.Request) {
|
||||
ctx := r.GetCtx()
|
||||
// 初始化登录用户信息
|
||||
data, err := service.GfToken().ParseToken(r)
|
||||
if err != nil {
|
||||
// 执行下一步请求逻辑
|
||||
r.Middleware.Next()
|
||||
}
|
||||
if data != nil {
|
||||
context := new(model.Context)
|
||||
err = gconv.Struct(data.Data, &context.User)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, err)
|
||||
// 执行下一步请求逻辑
|
||||
r.Middleware.Next()
|
||||
}
|
||||
service.Context().Init(r, context)
|
||||
}
|
||||
// 执行下一步请求逻辑
|
||||
r.Middleware.Next()
|
||||
}
|
51
internal/app/wechat/logic/token/token.go
Normal file
51
internal/app/wechat/logic/token/token.go
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* @desc:token功能
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2022/9/27 17:01
|
||||
*/
|
||||
|
||||
package token
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/tiger1103/gfast-token/gftoken"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/common/consts"
|
||||
commonModel "github.com/tiger1103/gfast/v3/internal/app/common/model"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/wechat/service"
|
||||
"github.com/tiger1103/gfast/v3/library/liberr"
|
||||
)
|
||||
|
||||
type sToken struct {
|
||||
*gftoken.GfToken
|
||||
}
|
||||
|
||||
func New() service.IGfToken {
|
||||
var (
|
||||
ctx = gctx.New()
|
||||
opt *commonModel.TokenOptions
|
||||
err = g.Cfg("wechat").MustGet(ctx, "gfToken").Struct(&opt)
|
||||
fun gftoken.OptionFunc
|
||||
)
|
||||
liberr.ErrIsNil(ctx, err)
|
||||
if opt.CacheModel == consts.CacheModelRedis {
|
||||
fun = gftoken.WithGRedis()
|
||||
} else {
|
||||
fun = gftoken.WithGCache()
|
||||
}
|
||||
return &sToken{
|
||||
GfToken: gftoken.NewGfToken(
|
||||
gftoken.WithCacheKey(opt.CacheKey),
|
||||
gftoken.WithTimeout(opt.Timeout),
|
||||
gftoken.WithMaxRefresh(opt.MaxRefresh),
|
||||
gftoken.WithMultiLogin(opt.MultiLogin),
|
||||
gftoken.WithExcludePaths(opt.ExcludePaths),
|
||||
fun,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
service.RegisterGToken(New())
|
||||
}
|
96
internal/app/wechat/logic/wechat/wechat.go
Normal file
96
internal/app/wechat/logic/wechat/wechat.go
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* @desc:微信小程序接口
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2023/3/22 9:08
|
||||
*/
|
||||
|
||||
package wechat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/auth/response"
|
||||
phoneNumberResp "github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/phoneNumber/response"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/urlLink/request"
|
||||
wxlinkResp "github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/urlLink/response"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/wechat/service"
|
||||
)
|
||||
|
||||
func init() {
|
||||
service.RegisterWechat(New())
|
||||
}
|
||||
|
||||
func New() service.IWechat {
|
||||
var (
|
||||
ctx = gctx.New()
|
||||
cfg = g.Cfg("wechat")
|
||||
)
|
||||
miniProgramApp, err := miniProgram.NewMiniProgram(&miniProgram.UserConfig{
|
||||
AppID: cfg.MustGet(ctx, "wechat.AppID").String(), // 小程序appid
|
||||
Secret: cfg.MustGet(ctx, "wechat.Secret").String(), // 小程序app secret
|
||||
HttpDebug: cfg.MustGet(ctx, "wechat.HttpDebug").Bool(),
|
||||
AESKey: cfg.MustGet(ctx, "wechat.AesKey").String(),
|
||||
Log: miniProgram.Log{
|
||||
Level: cfg.MustGet(ctx, "wechat.Log.Leave").String(),
|
||||
File: cfg.MustGet(ctx, "wechat.Log.File").String(),
|
||||
Error: cfg.MustGet(ctx, "wechat.Log.Error").String(),
|
||||
},
|
||||
// 可选,不传默认走程序内存
|
||||
Cache: kernel.NewRedisClient(&kernel.RedisOptions{
|
||||
Addr: cfg.MustGet(ctx, "wechat.Cache.Addr").String(),
|
||||
Password: cfg.MustGet(ctx, "wechat.Cache.Password").String(),
|
||||
DB: cfg.MustGet(ctx, "wechat.Cache.DB").Int(),
|
||||
}),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &sWechat{
|
||||
miniProgramApp: miniProgramApp,
|
||||
}
|
||||
}
|
||||
|
||||
type sWechat struct {
|
||||
miniProgramApp *miniProgram.MiniProgram
|
||||
}
|
||||
|
||||
func (s *sWechat) Session(ctx context.Context, code string) (data *response.ResponseCode2Session, err error) {
|
||||
data, err = s.miniProgramApp.Auth.Session(ctx, code)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sWechat) GetUserPhoneNumber(ctx context.Context, code string) (data *phoneNumberResp.ResponseGetUserPhoneNumber, err error) {
|
||||
data, err = s.miniProgramApp.PhoneNumber.GetUserPhoneNumber(ctx, code)
|
||||
return
|
||||
}
|
||||
|
||||
// IsDebug 是否开发调试模式
|
||||
func (s *sWechat) IsDebug(ctx context.Context) bool {
|
||||
debug := g.Cfg("wechat").MustGet(ctx, "wechat.isDebug").Bool()
|
||||
debug2 := g.Cfg("wechat").MustGet(ctx, "wechat.isDebug2").Bool()
|
||||
return debug || debug2
|
||||
}
|
||||
|
||||
func (s *sWechat) GetWxUrl(ctx context.Context) (url string, err error) {
|
||||
var res *wxlinkResp.ResponseURLLinkGenerate
|
||||
res, err = s.miniProgramApp.URLLink.Generate(ctx, &request.URLLinkGenerate{
|
||||
EnvVersion: "release",
|
||||
ExpireInterval: 1606737600,
|
||||
Path: "pages/index/index",
|
||||
Query: "",
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if res.ErrMsg != "ok" {
|
||||
err = gerror.New("获取小程序url失败,err:" + res.ErrMsg + ",errCode:" + res.Code)
|
||||
return
|
||||
}
|
||||
url = res.URLLink
|
||||
return
|
||||
}
|
23
internal/app/wechat/router/demo.go
Normal file
23
internal/app/wechat/router/demo.go
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* @desc:xxxx功能描述
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu<yxh669@qq.com>
|
||||
* @Date: 2023/11/3 16:23
|
||||
*/
|
||||
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/wechat/controller"
|
||||
)
|
||||
|
||||
func (router *Router) BindDemoController(ctx context.Context, group *ghttp.RouterGroup) {
|
||||
group.Group("/demo", func(group *ghttp.RouterGroup) {
|
||||
group.Bind(
|
||||
controller.Demo,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
37
internal/app/wechat/router/router.go
Normal file
37
internal/app/wechat/router/router.go
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* @desc:扶苗工作路由
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu
|
||||
* @Date: 2022/2/18 17:34
|
||||
*/
|
||||
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/wechat/controller"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/wechat/service"
|
||||
"github.com/tiger1103/gfast/v3/library/libRouter"
|
||||
)
|
||||
|
||||
var R = new(Router)
|
||||
|
||||
type Router struct{}
|
||||
|
||||
func (router *Router) BindController(ctx context.Context, group *ghttp.RouterGroup) {
|
||||
group.Group("/wechat", func(group *ghttp.RouterGroup) {
|
||||
group.Bind(
|
||||
//登录
|
||||
controller.Login,
|
||||
)
|
||||
//登录验证拦截
|
||||
service.GfToken().Middleware(group)
|
||||
//context拦截器
|
||||
group.Middleware(service.Middleware().Ctx)
|
||||
//自动绑定定义的控制器
|
||||
if err := libRouter.RouterAutoBind(ctx, router, group); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
}
|
35
internal/app/wechat/service/context.go
Normal file
35
internal/app/wechat/service/context.go
Normal file
@ -0,0 +1,35 @@
|
||||
// ================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// You can delete these comments if you wish manually maintain this interface file.
|
||||
// ================================================================================
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
)
|
||||
|
||||
type IContext interface {
|
||||
Init(r *ghttp.Request, customCtx *model.Context)
|
||||
Get(ctx context.Context) *model.Context
|
||||
SetUser(ctx context.Context, ctxUser *model.ContextUser)
|
||||
GetLoginUser(ctx context.Context) *model.ContextUser
|
||||
GetUserId(ctx context.Context) uint64
|
||||
GetDeptId(ctx context.Context) uint64
|
||||
}
|
||||
|
||||
var localContext IContext
|
||||
|
||||
func Context() IContext {
|
||||
if localContext == nil {
|
||||
panic("implement not found for interface IContext, forgot register?")
|
||||
}
|
||||
return localContext
|
||||
}
|
||||
|
||||
func RegisterContext(i IContext) {
|
||||
localContext = i
|
||||
}
|
27
internal/app/wechat/service/middleware.go
Normal file
27
internal/app/wechat/service/middleware.go
Normal file
@ -0,0 +1,27 @@
|
||||
// ================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// You can delete these comments if you wish manually maintain this interface file.
|
||||
// ================================================================================
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
type IMiddleware interface {
|
||||
Ctx(r *ghttp.Request)
|
||||
}
|
||||
|
||||
var localMiddleware IMiddleware
|
||||
|
||||
func Middleware() IMiddleware {
|
||||
if localMiddleware == nil {
|
||||
panic("implement not found for interface IMiddleware, forgot register?")
|
||||
}
|
||||
return localMiddleware
|
||||
}
|
||||
|
||||
func RegisterMiddleware(i IMiddleware) {
|
||||
localMiddleware = i
|
||||
}
|
38
internal/app/wechat/service/token.go
Normal file
38
internal/app/wechat/service/token.go
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* @desc:token功能
|
||||
* @company:云南奇讯科技有限公司
|
||||
* @Author: yixiaohu
|
||||
* @Date: 2022/3/8 15:54
|
||||
*/
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/tiger1103/gfast-token/gftoken"
|
||||
)
|
||||
|
||||
type IGfToken interface {
|
||||
GenerateToken(ctx context.Context, key string, data interface{}) (keys string, err error)
|
||||
Middleware(group *ghttp.RouterGroup) error
|
||||
ParseToken(r *ghttp.Request) (*gftoken.CustomClaims, error)
|
||||
IsLogin(r *ghttp.Request) (b bool, failed *gftoken.AuthFailed)
|
||||
GetRequestToken(r *ghttp.Request) (token string)
|
||||
RemoveToken(ctx context.Context, token string) (err error)
|
||||
GetTokenData(ctx context.Context, token string) (tData *gftoken.TokenData, key string, err error)
|
||||
}
|
||||
|
||||
var gt IGfToken
|
||||
|
||||
func RegisterGToken(gtk IGfToken) {
|
||||
gt = gtk
|
||||
}
|
||||
|
||||
func GfToken() IGfToken {
|
||||
if gt == nil {
|
||||
panic("implement not found for interface IGfToken, forgot register?")
|
||||
}
|
||||
return gt
|
||||
}
|
37
internal/app/wechat/service/wechat.go
Normal file
37
internal/app/wechat/service/wechat.go
Normal file
@ -0,0 +1,37 @@
|
||||
// ================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// You can delete these comments if you wish manually maintain this interface file.
|
||||
// ================================================================================
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/auth/response"
|
||||
phoneNumberResp "github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/phoneNumber/response"
|
||||
)
|
||||
|
||||
type (
|
||||
IWechat interface {
|
||||
Session(ctx context.Context, code string) (data *response.ResponseCode2Session, err error)
|
||||
GetUserPhoneNumber(ctx context.Context, code string) (data *phoneNumberResp.ResponseGetUserPhoneNumber, err error)
|
||||
IsDebug(ctx context.Context)bool
|
||||
GetWxUrl(ctx context.Context) (url string,err error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
localWechat IWechat
|
||||
)
|
||||
|
||||
func Wechat() IWechat {
|
||||
if localWechat == nil {
|
||||
panic("implement not found for interface IWechat, forgot register?")
|
||||
}
|
||||
return localWechat
|
||||
}
|
||||
|
||||
func RegisterWechat(i IWechat) {
|
||||
localWechat = i
|
||||
}
|
@ -9,5 +9,5 @@ package consts
|
||||
|
||||
const (
|
||||
Logo = `CiAgIF9fX19fX19fX19fXyAgICAgICAgICAgX18gCiAgLyBfX19fLyBfX19fL19fXyBfX19fX18vIC9fCiAvIC8gX18vIC9fICAvIF9fIGAvIF9fXy8gX18vCi8gL18vIC8gX18vIC8gL18vIChfXyAgKSAvXyAgClxfX19fL18vICAgIFxfXyxfL19fX18vXF9fLyAg`
|
||||
Version = "3.2.9"
|
||||
Version = "3.2.10"
|
||||
)
|
||||
|
11
internal/router/wechat.go
Normal file
11
internal/router/wechat.go
Normal file
@ -0,0 +1,11 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
wechat "github.com/tiger1103/gfast/v3/internal/app/wechat/router"
|
||||
)
|
||||
|
||||
func (router *Router) BindWechatModuleController(ctx context.Context, group *ghttp.RouterGroup) {
|
||||
wechat.R.BindController(ctx, group)
|
||||
}
|
25
manifest/config/wechat.yaml
Normal file
25
manifest/config/wechat.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
gfToken:
|
||||
cacheKey: "WechatGfToken:"
|
||||
timeOut: 2592000 #30天
|
||||
maxRefresh: 1296000
|
||||
multiLogin: true
|
||||
encryptKey: "49c54195e750b04e74a8429b17896586"
|
||||
cacheModel: "redis"
|
||||
excludePaths:
|
||||
- "/api/v1/wechat/login"
|
||||
wechat:
|
||||
AppID: "wx54888472b36230aa"
|
||||
Secret: "0f805412db892087ffc5c5c2f2ae80a5"
|
||||
HttpDebug: false
|
||||
AesKey: "zUfVSOan3B5ZZZZZZ66ixY6OrB28MTS9OIiBLaq3q2PhNG"
|
||||
isDebug: true
|
||||
isDebug2: true
|
||||
Log:
|
||||
Level: "debug"
|
||||
File: "./resource/log/wechat/wechat.log"
|
||||
Error: "./resource/log/wechat/error.log"
|
||||
Cache:
|
||||
Type: 1 #0使用内存 1使用redis
|
||||
Addr: "127.0.0.1:6379"
|
||||
Password: ""
|
||||
DB: 0
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@
|
||||
<template #header>
|
||||
<div v-drag="['.{{.table.ModuleName}}-{{.table.BusinessName|CaseCamelLower}}-edit .el-dialog', '.{{.table.ModuleName}}-{{.table.BusinessName|CaseCamelLower}}-edit .el-dialog__header']">{{"{{"}}(!formData.{{.table.PkColumn.HtmlField}} || formData.{{.table.PkColumn.HtmlField}}==0?'添加':'修改')+'{{.table.FunctionName}}'{{"}}"}}</div>
|
||||
</template>
|
||||
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
||||
{{if .table.IsPkInsertable}}
|
||||
<el-form-item label="{{.table.PkColumn.ColumnComment}}" prop="{{.table.PkColumn.HtmlField}}">
|
||||
<el-input v-model="formData.{{.table.PkColumn.HtmlField}}" placeholder="请输入{{.table.PkColumn.ColumnComment}}" v-bind:disabled="this.currentOp === 'edit'" />
|
||||
|
795
resource/template/vm/vue/tree-virtual-vue.template
Normal file
795
resource/template/vm/vue/tree-virtual-vue.template
Normal file
@ -0,0 +1,795 @@
|
||||
<template>
|
||||
{{$lens := .table.Columns|len}}
|
||||
{{$businessName := .table.BusinessName | CaseCamelLower}}
|
||||
{{$treeParentCode := .table.TreeParentCode}}
|
||||
{{$treeCode := .table.TreeCode}}
|
||||
{{$treeName := .table.TreeName}}
|
||||
{{$plugin:=""}}
|
||||
{{if ContainsI $.table.PackageName "plugins"}}
|
||||
{{$plugin = "plugins/"}}
|
||||
{{end}}
|
||||
<div class="{{.table.ModuleName}}-{{.table.BusinessName|CaseCamelLower}}-container">
|
||||
<el-card shadow="hover">
|
||||
<div class="{{.table.ModuleName}}-{{.table.BusinessName|CaseCamelLower}}-search mb15">
|
||||
<el-form :model="tableData.param" ref="queryRef" :inline="true" label-width="100px">
|
||||
<el-row>
|
||||
{{$colIndex := 0}}
|
||||
{{range $index, $column := .table.QueryColumns}}
|
||||
{{if and $column.IsQuery (ne $column.ColumnName "created_by") (ne $column.ColumnName "updated_by")}}
|
||||
{{if eq $colIndex 2}}
|
||||
<el-col :span="8" :class="!showAll ? 'colBlock' : 'colNone'">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="{{$businessName}}List"><el-icon><ele-Search /></el-icon>搜索</el-button>
|
||||
<el-button @click="resetQuery(queryRef)"><el-icon><ele-Refresh /></el-icon>重置</el-button>
|
||||
<el-button type="primary" link @click="toggleSearch">
|
||||
{{"{{"}} word {{"}}"}}
|
||||
<el-icon v-show="showAll"><ele-ArrowUp/></el-icon>
|
||||
<el-icon v-show="!showAll"><ele-ArrowDown /></el-icon>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{end}}
|
||||
{{if eq $column.HtmlType "input" "textarea"}}
|
||||
<el-col :span="8" {{if lt $colIndex 2}}class="colBlock"{{else}}:class="showAll ? 'colBlock' : 'colNone'"{{end}}>
|
||||
<el-form-item label="{{$column.ColumnComment}}" prop="{{$column.HtmlField}}">
|
||||
<el-input
|
||||
v-model="tableData.param.{{$column.HtmlField}}{{if eq $column.QueryType "BETWEEN"}}[0]{{end}}"
|
||||
placeholder="请输入{{$column.ColumnComment}}"
|
||||
clearable
|
||||
{{if eq $column.QueryType "BETWEEN"}}style="width:100px"{{end}}
|
||||
@keyup.enter.native="{{$businessName}}List"
|
||||
/>
|
||||
{{if eq $column.QueryType "BETWEEN"}} -
|
||||
<el-input
|
||||
v-model="tableData.param.{{$column.HtmlField}}[1]"
|
||||
placeholder="请输入{{$column.ColumnComment}}"
|
||||
clearable
|
||||
style="width:100px"
|
||||
@keyup.enter.native="{{$businessName}}List"
|
||||
/>
|
||||
{{end}}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{$colIndex = ($colIndex | plus 1)}}
|
||||
{{else if and (eq $column.HtmlType "select" "radio" "checkbox" "selects") (ne $column.DictType "") }}
|
||||
<el-col :span="8" {{if lt $colIndex 2}}class="colBlock"{{else}}:class="showAll ? 'colBlock' : 'colNone'"{{end}}>
|
||||
<el-form-item label="{{$column.ColumnComment}}" prop="{{$column.HtmlField}}">
|
||||
<el-select v-model="tableData.param.{{$column.HtmlField}}" placeholder="请选择{{$column.ColumnComment}}" clearable >
|
||||
<el-option
|
||||
v-for="dict in {{$column.DictType}}"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{$colIndex = ($colIndex | plus 1)}}
|
||||
{{else if and (eq $column.HtmlType "treeSelect" "treeSelects") (ne $column.LinkTableName "")}}
|
||||
<el-col :span="8" {{if lt $colIndex 2}}class="colBlock"{{else}}:class="showAll ? 'colBlock' : 'colNone'"{{end}}>
|
||||
<el-form-item label="{{$column.ColumnComment}}" prop="{{$column.HtmlField}}">
|
||||
{{$tLabel:=""}}
|
||||
{{$tValue:=""}}
|
||||
{{range $li,$lc := $.table.LinkedTables}}
|
||||
{{if eq $lc.TableName $column.LinkTableName}}
|
||||
{{$tLabel = $lc.OptionsStruct.TreeName}}
|
||||
{{$tValue = $lc.OptionsStruct.TreeCode}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
<el-cascader
|
||||
v-model="tableData.param.{{$column.HtmlField}}"
|
||||
placeholder="请选择"
|
||||
:options="{{$column.HtmlField}}Options"
|
||||
filterable
|
||||
clearable
|
||||
:props="{ label: '{{$tLabel}}',value: '{{$tValue}}',checkStrictly: true,emitPath: false }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{$colIndex = ($colIndex | plus 1)}}
|
||||
{{else if eq $column.HtmlType "date"}}
|
||||
<el-col :span="8" {{if lt $colIndex 2}}class="colBlock"{{else}}:class="showAll ? 'colBlock' : 'colNone'"{{end}}>
|
||||
<el-form-item label="{{$column.ColumnComment}}" prop="{{$column.HtmlField}}">
|
||||
<el-date-picker
|
||||
clearable style="width: 200px"
|
||||
v-model="tableData.param.{{$column.HtmlField}}"
|
||||
value-format="YYYY-MM-DD"
|
||||
{{if eq $column.QueryType "BETWEEN"}}
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
{{else}}
|
||||
type="date"
|
||||
placeholder="选择{{$column.ColumnComment}}"
|
||||
{{end}}
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{$colIndex = ($colIndex | plus 1)}}
|
||||
{{else if eq $column.HtmlType "datetime"}}
|
||||
<el-col :span="8" {{if lt $colIndex 2}}class="colBlock"{{else}}:class="showAll ? 'colBlock' : 'colNone'"{{end}}>
|
||||
<el-form-item label="{{$column.ColumnComment}}" prop="{{$column.HtmlField}}">
|
||||
<el-date-picker
|
||||
clearable style="width: 200px"
|
||||
v-model="tableData.param.{{$column.HtmlField}}"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
{{if eq $column.QueryType "BETWEEN"}}
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
{{else}}
|
||||
type="datetime"
|
||||
placeholder="选择{{$column.ColumnComment}}"
|
||||
{{end}}
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{$colIndex = ($colIndex | plus 1)}}
|
||||
{{else if and (eq $column.HtmlType "select" "radio" "checkbox" "selects") (ne $column.LinkTableName "")}}
|
||||
<el-col :span="8" {{if lt $colIndex 2}}class="colBlock"{{else}}:class="showAll ? 'colBlock' : 'colNone'"{{end}}>
|
||||
<el-form-item label="{{$column.ColumnComment}}" prop="{{$column.HtmlField}}">
|
||||
<el-select v-model="tableData.param.{{$column.HtmlField}}" placeholder="请选择{{$column.ColumnComment}}" clearable {{if $column.IsCascadeParent}}@change="query{{$column.ColumnName | CaseCamel}}Changed"{{end}}>
|
||||
<el-option
|
||||
{{if $column.IsCascade}}
|
||||
v-for="item in {{$column.HtmlField}}QueryOptions"
|
||||
{{else}}
|
||||
v-for="item in {{$column.HtmlField}}Options"
|
||||
{{end}}
|
||||
:key="item.key"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{$colIndex = ($colIndex | plus 1)}}
|
||||
{{else if and (eq $column.HtmlType "treeSelect" "treeSelects") (ne $column.LinkTableName "")}}
|
||||
<el-col :span="8" {{if lt $colIndex 2}}class="colBlock"{{else}}:class="showAll ? 'colBlock' : 'colNone'"{{end}}>
|
||||
<el-form-item label="{{$column.ColumnComment}}" prop="{{$column.HtmlField}}">
|
||||
{{$tLabel:=""}}
|
||||
{{$tValue:=""}}
|
||||
{{range $li,$lc := $.table.LinkedTables}}
|
||||
{{if eq $lc.TableName $column.LinkTableName}}
|
||||
{{$tLabel = $lc.OptionsStruct.TreeName}}
|
||||
{{$tValue = $lc.OptionsStruct.TreeCode}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
<el-cascader
|
||||
v-model="tableData.param.{{$column.HtmlField}}"
|
||||
placeholder="请选择"
|
||||
:options="{{$column.HtmlField}}Options"
|
||||
filterable
|
||||
clearable
|
||||
:props="{ label: '{{$tLabel}}',value: '{{$tValue}}',checkStrictly: true,emitPath: false }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{$colIndex = ($colIndex | plus 1)}}
|
||||
{{else}}
|
||||
<el-col :span="8" {{if lt $colIndex 2}}class="colBlock"{{else}}:class="showAll ? 'colBlock' : 'colNone'"{{end}}>
|
||||
<el-form-item label="{{$column.ColumnComment}}" prop="{{$column.HtmlField}}">
|
||||
<el-select v-model="tableData.param.{{$column.HtmlField}}" placeholder="请选择{{$column.ColumnComment}}" clearable >
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{$colIndex = ($colIndex | plus 1)}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{if gt $colIndex 2}}
|
||||
<el-col :span="8" :class="showAll ? 'colBlock' : 'colNone'">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="{{$businessName}}List"><el-icon><ele-Search /></el-icon>搜索</el-button>
|
||||
<el-button @click="resetQuery(queryRef)"><el-icon><ele-Refresh /></el-icon>重置</el-button>
|
||||
<el-button type="primary" link @click="toggleSearch">
|
||||
{{"{{"}} word {{"}}"}}
|
||||
<el-icon v-show="showAll"><ele-ArrowUp/></el-icon>
|
||||
<el-icon v-show="!showAll"><ele-ArrowDown /></el-icon>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{else}}
|
||||
<el-col :span="8" class="colBlock">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="{{$businessName}}List"><el-icon><ele-Search /></el-icon>搜索</el-button>
|
||||
<el-button @click="resetQuery(queryRef)"><el-icon><ele-Refresh /></el-icon>重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
{{end}}
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
|
||||
@click="handleAdd"
|
||||
v-auth="'{{.apiVersion}}/{{.table.ModuleName}}/{{$businessName}}/add'"
|
||||
><el-icon><ele-Plus /></el-icon>新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
|
||||
:disabled="single"
|
||||
@click="handleUpdate(null)"
|
||||
v-auth="'{{.apiVersion}}/{{.table.ModuleName}}/{{$businessName}}/edit'"
|
||||
><el-icon><ele-Edit /></el-icon>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
|
||||
:disabled="multiple"
|
||||
@click="handleDelete(null)"
|
||||
v-auth="'{{.apiVersion}}/{{.table.ModuleName}}/{{$businessName}}/delete'"
|
||||
><el-icon><ele-Delete /></el-icon>删除</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div style="height: 800px;">
|
||||
<el-auto-resizer>
|
||||
<template #default="{ height, width }">
|
||||
<el-table-v2
|
||||
v-model:expanded-row-keys="expandedRowKeys"
|
||||
:columns="columns"
|
||||
:data="treeData"
|
||||
:width="width"
|
||||
:height="height"
|
||||
:expand-column-key="expandColumnKey"
|
||||
fixed
|
||||
@row-expand="onRowExpanded"
|
||||
@expanded-rows-change="onExpandedRowsChange"
|
||||
/>
|
||||
</template>
|
||||
</el-auto-resizer>
|
||||
</div>
|
||||
</el-card>
|
||||
<{{$plugin}}{{if ne $plugin ""}}{{.apiVersion|replace "/" "_"|CaseCamel}}{{else}}{{.apiVersion|replace "/" "_"|CaseCamelLower}}{{end}}{{.table.ModuleName|CaseCamel}}{{.table.ClassName}}Edit
|
||||
ref="editRef"
|
||||
{{range $index, $column := .table.Columns}}
|
||||
{{if ne $column.DictType ""}}
|
||||
:{{$column.HtmlField}}Options="{{$column.DictType}}"
|
||||
{{else if ne $column.LinkTableName ""}}
|
||||
{{if $column.IsCascade}}
|
||||
{{/*级联处理*/}}
|
||||
{{else}}
|
||||
{{/*关联表处理*/}}
|
||||
:{{$column.HtmlField}}Options="{{$column.HtmlField}}Options"
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
:{{$businessName}}Options="tableData.data"
|
||||
@{{$businessName}}List="{{$businessName}}List"
|
||||
></{{$plugin}}{{if ne $plugin ""}}{{.apiVersion|replace "/" "_"|CaseCamel}}{{else}}{{.apiVersion|replace "/" "_"|CaseCamelLower}}{{end}}{{.table.ModuleName|CaseCamel}}{{.table.ClassName}}Edit>
|
||||
<{{$plugin}}{{if ne $plugin ""}}{{.apiVersion|replace "/" "_"|CaseCamel}}{{else}}{{.apiVersion|replace "/" "_"|CaseCamelLower}}{{end}}{{.table.ModuleName|CaseCamel}}{{.table.ClassName}}Detail
|
||||
ref="detailRef"
|
||||
{{range $index, $column := .table.Columns}}
|
||||
{{if ne $column.DictType ""}}
|
||||
:{{$column.HtmlField}}Options="{{$column.DictType}}"
|
||||
{{else if ne $column.LinkTableName ""}}
|
||||
{{if $column.IsCascade}}
|
||||
{{/*级联处理*/}}
|
||||
{{else}}
|
||||
{{/*关联表处理*/}}
|
||||
:{{$column.HtmlField}}Options="{{$column.HtmlField}}Options"
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
:{{$businessName}}Options="tableData.data"
|
||||
@{{$businessName}}List="{{$businessName}}List"
|
||||
></{{$plugin}}{{if ne $plugin ""}}{{.apiVersion|replace "/" "_"|CaseCamel}}{{else}}{{.apiVersion|replace "/" "_"|CaseCamelLower}}{{end}}{{.table.ModuleName|CaseCamel}}{{.table.ClassName}}Detail>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
{{$tokenImp := false}}
|
||||
{{$imgsImp := false}}
|
||||
{{$editImp := false }}
|
||||
{{$fileImp := false}}
|
||||
{{$getUserList:=false}}
|
||||
|
||||
{{range $index,$column:=.table.Columns}}
|
||||
{{if eq $column.HtmlType "richtext"}}
|
||||
{{$editImp = true}}
|
||||
{{else if eq $column.HtmlType "imagefile"}}
|
||||
{{$tokenImp = true}}
|
||||
{{else if eq $column.HtmlType "images"}}
|
||||
{{$imgsImp = true}}
|
||||
{{else if eq $column.HtmlType "file" "files"}}
|
||||
{{$fileImp = true}}
|
||||
{{end}}
|
||||
{{if eq $column.HtmlField "createdBy" "updatedBy"}}
|
||||
{{$getUserList = true}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{/*去重处理*/}}
|
||||
{{$hasImports:=newArray}}
|
||||
import {ItemOptions} from "/@/api/items";
|
||||
import {toRefs, reactive, onMounted, ref, defineComponent, computed,getCurrentInstance,toRaw,h,unref,FunctionalComponent} from 'vue';
|
||||
import {ElMessageBox, ElMessage, FormInstance,RowExpandHandler,ExpandedRowsChangeHandler,TableV2FixedDir, Column, ElLink, ElIcon, ElCheckbox, CheckboxValueType,ElImage,ElTag} from 'element-plus';
|
||||
import { EditPen,View,DeleteFilled } from '@element-plus/icons-vue'
|
||||
import {
|
||||
list{{.table.ClassName}},
|
||||
get{{.table.ClassName}},
|
||||
del{{.table.ClassName}},
|
||||
add{{.table.ClassName}},
|
||||
update{{.table.ClassName}},
|
||||
{{range $index,$column:= .table.Columns}}
|
||||
{{if and $column.IsStatus $column.IsList}}
|
||||
change{{$.table.ClassName}}{{$column.GoField}},
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{if gt (len .table.LinkedTables) 0}}
|
||||
linkedDataSearch
|
||||
{{end}}
|
||||
} from "/@/api/{{$plugin}}{{.table.ModuleName}}/{{$businessName}}";
|
||||
import {
|
||||
{{.table.ClassName}}TableColumns,
|
||||
{{.table.ClassName}}InfoData,
|
||||
{{.table.ClassName}}TableDataState,
|
||||
{{range $ti, $linkedTable := .table.LinkedTables}}
|
||||
Linked{{$.table.ClassName}}{{$linkedTable.ClassName}},
|
||||
{{end}}
|
||||
} from "/@/views/{{$plugin}}{{.table.ModuleName}}/{{$businessName}}/list/component/model"
|
||||
import {{$plugin}}{{if ne $plugin ""}}{{.apiVersion|replace "/" "_"|CaseCamel}}{{else}}{{.apiVersion|replace "/" "_"|CaseCamelLower}}{{end}}{{.table.ModuleName|CaseCamel}}{{.table.ClassName}}Edit from "/@/views/{{$plugin}}{{.table.ModuleName}}/{{$businessName}}/list/component/edit.vue"
|
||||
import {{$plugin}}{{if ne $plugin ""}}{{.apiVersion|replace "/" "_"|CaseCamel}}{{else}}{{.apiVersion|replace "/" "_"|CaseCamelLower}}{{end}}{{.table.ModuleName|CaseCamel}}{{.table.ClassName}}Detail from "/@/views/{{$plugin}}{{.table.ModuleName}}/{{$businessName}}/list/component/detail.vue"
|
||||
import _ from 'lodash'
|
||||
export default defineComponent({
|
||||
name: "{{$plugin}}{{if ne $plugin ""}}{{.apiVersion|replace "/" "_"|CaseCamel}}{{else}}{{.apiVersion|replace "/" "_"|CaseCamelLower}}{{end}}{{.table.ModuleName|CaseCamel}}{{.table.ClassName}}List",
|
||||
components:{
|
||||
{{$plugin}}{{if ne $plugin ""}}{{.apiVersion|replace "/" "_"|CaseCamel}}{{else}}{{.apiVersion|replace "/" "_"|CaseCamelLower}}{{end}}{{.table.ModuleName|CaseCamel}}{{.table.ClassName}}Edit,
|
||||
{{$plugin}}{{if ne $plugin ""}}{{.apiVersion|replace "/" "_"|CaseCamel}}{{else}}{{.apiVersion|replace "/" "_"|CaseCamelLower}}{{end}}{{.table.ModuleName|CaseCamel}}{{.table.ClassName}}Detail
|
||||
},
|
||||
setup() {
|
||||
const {proxy} = <any>getCurrentInstance()
|
||||
const loading = ref(false)
|
||||
const queryRef = ref()
|
||||
const editRef = ref();
|
||||
const detailRef = ref();
|
||||
// 是否显示所有搜索选项
|
||||
const showAll = ref(false)
|
||||
// 非单个禁用
|
||||
const single = ref(true)
|
||||
// 非多个禁用
|
||||
const multiple =ref(true)
|
||||
const word = computed(()=>{
|
||||
if(showAll.value === false) {
|
||||
//对文字进行处理
|
||||
return "展开搜索";
|
||||
} else {
|
||||
return "收起搜索";
|
||||
}
|
||||
})
|
||||
// 字典选项数据
|
||||
{{$dictArr:=newArray}}
|
||||
{{range $index, $column := .table.Columns}}
|
||||
{{if and (ne $column.DictType "") (ne (inArray $dictArr $column.DictType) true)}}
|
||||
{{$dictArr = append $dictArr $column.DictType}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
const {
|
||||
{{range $index, $column := $dictArr}}
|
||||
{{$column}},
|
||||
{{end}}
|
||||
} = proxy.useDict(
|
||||
{{range $index, $column := $dictArr}}
|
||||
'{{$column}}',
|
||||
{{end}}
|
||||
)
|
||||
{{range $index, $column := .table.Columns}}
|
||||
{{if ne $column.LinkTableName ""}}
|
||||
{{if $column.IsCascade }}
|
||||
// {{$column.HtmlField}}QueryOptions关联表数据
|
||||
const {{$column.HtmlField}}QueryOptions = ref<Array<ItemOptions>>([])
|
||||
// {{$column.HtmlField}}FormOptions关联表数据
|
||||
const {{$column.HtmlField}}FormOptions = ref<Array<ItemOptions>>([])
|
||||
{{else}}
|
||||
// {{$column.HtmlField}}Options关联表数据
|
||||
const {{$column.HtmlField}}Options = ref<Array<ItemOptions>>([])
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
const dataList = ref<Array<{{$.table.ClassName}}TableColumns>>([])
|
||||
const state = reactive<{{.table.ClassName}}TableDataState>({
|
||||
{{.table.PkColumn.HtmlField}}s:[],
|
||||
tableData: {
|
||||
data: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
param: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
{{range $index, $column := .table.QueryColumns}}
|
||||
{{if eq $column.QueryType "BETWEEN"}}
|
||||
{{$column.HtmlField}}: [],
|
||||
{{else}}
|
||||
{{$column.HtmlField}}: undefined,
|
||||
{{end}}{{end}}
|
||||
dateRange: []
|
||||
},
|
||||
},
|
||||
});
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
{{if gt (len .table.LinkedTables) 0}}
|
||||
linkedData()
|
||||
{{end}}
|
||||
{{$businessName}}List()
|
||||
};
|
||||
{{if gt (len .table.LinkedTables) 0}}
|
||||
const linkedData = ()=>{
|
||||
linkedDataSearch().then((res:any)=>{
|
||||
{{range $index, $column := .table.Columns}}
|
||||
{{if ne $column.LinkTableName ""}}
|
||||
//关联{{$column.LinkTableName}}表选项
|
||||
{{range $li,$lc := $.table.LinkedTables}}
|
||||
{{if eq $lc.TableName $column.LinkTableName}}
|
||||
{{if eq $lc.TplCategory "tree"}}
|
||||
{{$column.HtmlField}}Options.value = proxy.handleTree(res.data.linked{{$.table.ClassName}}{{$column.LinkTableClass}}, '{{$lc.OptionsStruct.TreeCode}}', '{{$lc.OptionsStruct.TreeParentCode}}')
|
||||
{{else}}
|
||||
{{$column.HtmlField}}Options.value = proxy.setItems(res, '{{$column.LinkLabelId | CaseCamelLower}}', '{{$column.LinkLabelName | CaseCamelLower}}','linked{{$.table.ClassName}}{{$column.LinkTableClass}}')
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
})
|
||||
}
|
||||
{{end}}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
{{$businessName}}List()
|
||||
};
|
||||
// 获取列表数据
|
||||
const {{$businessName}}List = ()=>{
|
||||
loading.value = true
|
||||
list{{.table.ClassName}}(state.tableData.param).then((res:any)=>{
|
||||
let list = res.data.list??[];
|
||||
{{range $index,$column := .table.ListColumns}}
|
||||
{{if eq $column.HtmlField "createdBy" "updatedBy"}}
|
||||
list.map((item:any)=>{
|
||||
{{if eq $column.HtmlField "createdBy"}}
|
||||
item.createdBy = item?.createdUser.userNickname
|
||||
{{end}}
|
||||
{{if eq $column.HtmlField "updatedBy"}}
|
||||
item.updatedBy = item?.updatedUser.userNickname
|
||||
{{end}}
|
||||
})
|
||||
{{end}}
|
||||
{{end}}
|
||||
dataList.value = _.clone(res.data.list)
|
||||
list = proxy.handleTree(res.data.list||[], "{{$treeCode}}", "{{$treeParentCode}}");
|
||||
state.tableData.data = list;
|
||||
loading.value = false
|
||||
setVrData(list)
|
||||
})
|
||||
};
|
||||
const toggleSearch = () => {
|
||||
showAll.value = !showAll.value;
|
||||
}
|
||||
{{range $index, $column := .table.Columns}}
|
||||
{{if ne $column.DictType ""}}
|
||||
{{if eq $column.HtmlType "checkbox"}}
|
||||
// {{$column.ColumnComment}}字典翻译
|
||||
const {{$column.HtmlField}}Format = (row:{{$.table.ClassName}}TableColumns) => {
|
||||
let {{$column.HtmlField}} = row.{{$column.HtmlField}}.split(",")
|
||||
let data:Array<string> = [];
|
||||
{{$column.HtmlField}}.map(item=>{
|
||||
data.push(proxy.selectDictLabel({{$column.DictType}}.value, item))
|
||||
})
|
||||
return data.join(",")
|
||||
}
|
||||
{{else}}
|
||||
// {{$column.ColumnComment}}字典翻译
|
||||
const {{$column.HtmlField}}Format = (row:{{$.table.ClassName}}TableColumns) => {
|
||||
return proxy.selectDictLabel({{$column.DictType}}.value, row.{{$column.HtmlField}});
|
||||
}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
// 多选框选中数据
|
||||
const handleSelectionChange = (selection:Array<{{.table.ClassName}}InfoData>) => {
|
||||
state.{{.table.PkColumn.HtmlField}}s = selection.map(item => item.{{.table.PkColumn.HtmlField}})
|
||||
single.value = selection.length!=1
|
||||
multiple.value = !selection.length
|
||||
}
|
||||
const handleAdd = ()=>{
|
||||
editRef.value.openDialog()
|
||||
}
|
||||
const handleUpdate = (row: {{$.table.ClassName}}TableColumns) => {
|
||||
if(!row){
|
||||
row = dataList.value.find((item:{{$.table.ClassName}}TableColumns)=>{
|
||||
return item.{{.table.PkColumn.HtmlField}} ===state.{{.table.PkColumn.HtmlField}}s[0]
|
||||
}) as {{$.table.ClassName}}TableColumns
|
||||
}
|
||||
editRef.value.openDialog(toRaw(row));
|
||||
};
|
||||
const handleDelete = (row: {{$.table.ClassName}}TableColumns) => {
|
||||
let msg = '你确定要删除所选数据?';
|
||||
let {{.table.PkColumn.HtmlField}}:number[] = [] ;
|
||||
if(row){
|
||||
msg = `此操作将永久删除数据,是否继续?`
|
||||
{{.table.PkColumn.HtmlField}} = [row.{{.table.PkColumn.HtmlField}}]
|
||||
}else{
|
||||
{{.table.PkColumn.HtmlField}} = state.{{.table.PkColumn.HtmlField}}s
|
||||
}
|
||||
if({{.table.PkColumn.HtmlField}}.length===0){
|
||||
ElMessage.error('请选择要删除的数据。');
|
||||
return
|
||||
}
|
||||
ElMessageBox.confirm(msg, '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
del{{.table.ClassName}}({{.table.PkColumn.HtmlField}}).then(()=>{
|
||||
ElMessage.success('删除成功');
|
||||
{{$businessName}}List();
|
||||
})
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
const handleView = (row:{{$.table.ClassName}}TableColumns)=>{
|
||||
detailRef.value.openDialog(toRaw(row));
|
||||
}
|
||||
//========================================================================================================
|
||||
const columns = ref<Column[]>([])
|
||||
const treeData = ref<any[]>([])
|
||||
|
||||
type SelectionCellProps = {
|
||||
value: boolean
|
||||
intermediate?: boolean
|
||||
onChange: (value: CheckboxValueType) => void
|
||||
}
|
||||
|
||||
const SelectionCell: FunctionalComponent<SelectionCellProps> = ({
|
||||
value,
|
||||
intermediate = false,
|
||||
onChange,
|
||||
}) => {
|
||||
return h(ElCheckbox,{modelValue:value,indeterminate:intermediate,onChange:onChange})
|
||||
}
|
||||
const setVrData = (list:{{$.table.ClassName}}TableColumns[])=>{
|
||||
const _columns:any[] = [
|
||||
{key: 'selection',dataKey: '{{.table.PkColumn.HtmlField}}',title: ``,width:80,
|
||||
{{if .table.PkColumn.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
headerCellRenderer:()=>{
|
||||
let _data = unref(dataList.value)
|
||||
const onChange = (value: CheckboxValueType) =>{
|
||||
_data = _data.map((row:any) => {
|
||||
row.checked = value
|
||||
return row
|
||||
})
|
||||
treeData.value = proxy.handleTree(_data||[], "{{$treeCode}}", "{{$treeParentCode}}")
|
||||
state.{{.table.PkColumn.HtmlField}}s = _data.map((item:any) => {
|
||||
if(item.checked){
|
||||
return item.{{.table.PkColumn.HtmlField}}
|
||||
}
|
||||
}).filter(item=>item!==undefined)
|
||||
single.value = state.{{.table.PkColumn.HtmlField}}s.length!=1
|
||||
multiple.value = !state.{{.table.PkColumn.HtmlField}}s.length
|
||||
}
|
||||
const allSelected = _data.every((row:any) => row.checked)
|
||||
const containsChecked = _data.some((row:any) => row.checked)
|
||||
return h(ElCheckbox,{value:allSelected,intermediate:containsChecked && !allSelected,onChange:onChange})
|
||||
},
|
||||
cellRenderer:({rowData: row})=>{
|
||||
return h(SelectionCell, {value:row.checked,intermediate:false,onChange:(v:CheckboxValueType)=>{
|
||||
row.checked=v
|
||||
if(v){
|
||||
state.{{.table.PkColumn.HtmlField}}s.push(row.{{.table.PkColumn.HtmlField}})
|
||||
state.{{.table.PkColumn.HtmlField}}s = [...new Set(state.{{.table.PkColumn.HtmlField}}s)]
|
||||
}else{
|
||||
state.{{.table.PkColumn.HtmlField}}s = state.{{.table.PkColumn.HtmlField}}s.filter(item=>item!==row.{{.table.PkColumn.HtmlField}})
|
||||
}
|
||||
single.value = state.{{.table.PkColumn.HtmlField}}s.length!=1
|
||||
multiple.value = !state.{{.table.PkColumn.HtmlField}}s.length
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
{{range $index, $column := .table.ListColumns}}
|
||||
{{if $column.IsPk}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: '{{$column.HtmlField}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
})
|
||||
{{else if eq $column.HtmlType "date"}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: '{{$column.HtmlField}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
cellRenderer: ({ cellData: {{$column.HtmlField}} }) => {
|
||||
return h('span', proxy.parseTime({{$column.HtmlField}}, '{y}-{m}-{d}'));
|
||||
}
|
||||
})
|
||||
{{else if eq $column.HtmlType "datetime"}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: '{{$column.HtmlField}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
cellRenderer: ({ cellData: {{$column.HtmlField}} }) => {
|
||||
return h('span', proxy.parseTime({{$column.HtmlField}}, '{y}-{m}-{d} {h}:{i}:{s}'));
|
||||
}
|
||||
})
|
||||
{{else if eq $column.HtmlField "createdBy"}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: '{{$column.HtmlField}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
})
|
||||
{{else if eq $column.HtmlField "updatedBy"}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: '{{$column.HtmlField}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
})
|
||||
{{else if eq $column.HtmlType "imagefile"}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: '{{$column.HtmlField}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
cellRenderer: ({cellData: {{$column.HtmlField}} }) => {
|
||||
const children = []
|
||||
if(!proxy.isEmpty({{$column.HtmlField}})){
|
||||
children.push(h(ElImage,{fit:'contain',style:'width:50px;height:50px',src:proxy.getUpFileUrl({{$column.HtmlField}})}))
|
||||
}
|
||||
return ('div',children)
|
||||
}
|
||||
})
|
||||
{{else if eq $column.HtmlType "selects" "checkbox" "treeSelects"}}
|
||||
{{if ne $column.LinkTableName ""}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: '{{$column.HtmlField}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
cellRenderer: ({cellData: {{$column.HtmlField}} }) => {
|
||||
const children = []
|
||||
if(linked{{$column.GoField}}){
|
||||
linked{{$column.GoField}}.map(item=>{
|
||||
children.push(h(ElTag,{class:"ml-2",type:'success'},[item.{{$column.LinkLabelName|CaseCamelLower}}]))
|
||||
})
|
||||
}
|
||||
return ('div',children)
|
||||
}
|
||||
})
|
||||
{{else if ne $column.DictType ""}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: '{{$column.HtmlField}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
cellRenderer: ({rowData:row}) => {
|
||||
return ('span',[{{$column.HtmlField}}Format(row)])
|
||||
}
|
||||
})
|
||||
{{end}}
|
||||
{{else if ne $column.LinkTableName ""}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: 'linked{{$column.GoField}}.{{$column.LinkLabelName | CaseCamelLower}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
})
|
||||
{{else if ne $column.DictType ""}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: '{{$column.HtmlField}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
cellRenderer: ({rowData:row}) => {
|
||||
return ('span',[{{$column.HtmlField}}Format(row)])
|
||||
}
|
||||
})
|
||||
{{else if ne $column.HtmlField ""}}
|
||||
_columns.push({key: '{{$column.HtmlField}}',dataKey: '{{$column.HtmlField}}',title: `{{$column.ColumnComment}}`,
|
||||
{{if gt $column.MinWidth 0}}width:{{$column.MinWidth}},{{end}}
|
||||
{{if $column.IsFixed}}fixed: TableV2FixedDir.LEFT,{{end}}
|
||||
})
|
||||
{{end}}
|
||||
{{end}}
|
||||
_columns.push({key: 'operations',dataKey: '{{$.table.PkColumn.HtmlField}}',title: `操作`,width:200,fixed: TableV2FixedDir.RIGHT,
|
||||
cellRenderer: ({rowData:row,cellData:{{$.table.PkColumn.HtmlField}}}) => {
|
||||
return h('div',{class:'tb-operations'},[
|
||||
h(ElLink, { type: 'primary',underline:false, onClick: () => { handleView(row) } },
|
||||
() => [
|
||||
h(ElIcon, () => [h(View)]),
|
||||
'详情'
|
||||
],
|
||||
),
|
||||
h(ElLink, { type: 'primary',underline:false, onClick: () => { handleUpdate(row) } },
|
||||
() => [
|
||||
h(ElIcon, () => [h(EditPen)]),
|
||||
'修改'
|
||||
],
|
||||
),
|
||||
h(ElLink, { type: 'primary',underline:false, onClick: () => { handleDelete(row) } },
|
||||
() => [
|
||||
h(ElIcon, () => [h(DeleteFilled)]),
|
||||
'删除'
|
||||
],
|
||||
)
|
||||
])
|
||||
}
|
||||
})
|
||||
columns.value = _columns
|
||||
treeData.value = list
|
||||
}
|
||||
//=============================================================================================================
|
||||
const expandColumnKey = '{{$treeCode}}'
|
||||
|
||||
const expandedRowKeys = ref<string[]>([])
|
||||
|
||||
const onRowExpanded = (exp: Parameters<RowExpandHandler<any>>[0]) => {
|
||||
console.log('Expanded:', exp)
|
||||
}
|
||||
|
||||
const onExpandedRowsChange = (
|
||||
expandedKeys: Parameters<ExpandedRowsChangeHandler>[0]
|
||||
) => {
|
||||
console.log('expandedKeys:',expandedKeys)
|
||||
}
|
||||
|
||||
return {
|
||||
proxy,
|
||||
editRef,
|
||||
detailRef,
|
||||
showAll,
|
||||
loading,
|
||||
single,
|
||||
multiple,
|
||||
word,
|
||||
queryRef,
|
||||
resetQuery,
|
||||
{{$businessName}}List,
|
||||
toggleSearch,
|
||||
{{range $index, $column := .table.Columns}}
|
||||
{{if ne $column.DictType ""}}
|
||||
{{$column.HtmlField}}Format,
|
||||
{{$column.DictType}},
|
||||
{{end}}
|
||||
{{if ne $column.LinkTableName ""}}
|
||||
{{if $column.IsCascade}}
|
||||
//级联关联{{$column.LinkTableName}}表选项
|
||||
{{else}}
|
||||
//关联表数据选项
|
||||
{{$column.HtmlField}}Options,
|
||||
//关联{{$column.LinkTableName}}表选项获取数据方法
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
handleSelectionChange,
|
||||
handleAdd,
|
||||
handleUpdate,
|
||||
handleDelete,
|
||||
{{if eq .table.ShowDetail "true"}}
|
||||
handleView,
|
||||
{{end}}
|
||||
columns,
|
||||
treeData,
|
||||
expandedRowKeys,
|
||||
onRowExpanded,
|
||||
expandColumnKey,
|
||||
onExpandedRowsChange,
|
||||
...toRefs(state),
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.colBlock {
|
||||
display: block;
|
||||
}
|
||||
.colNone {
|
||||
display: none;
|
||||
}
|
||||
:deep(.tb-operations .el-link){
|
||||
margin-left: 12px;
|
||||
.el-icon{
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user