Modify: clean useless codes

This commit is contained in:
HFO4
2020-03-11 15:45:00 +08:00
parent 09de05548f
commit 45b54b3455
28 changed files with 8 additions and 1802 deletions

View File

@@ -6,20 +6,6 @@ import (
"github.com/HFO4/cloudreve/pkg/util"
)
// NewOveruseNotification 新建超额提醒邮件
func NewOveruseNotification(userName, reason string) (string, string) {
options := model.GetSettingByNames("siteName", "siteURL", "siteTitle", "over_used_template")
replace := map[string]string{
"{siteTitle}": options["siteName"],
"{userName}": userName,
"{notifyReason}": reason,
"{siteUrl}": options["siteURL"],
"{siteSecTitle}": options["siteTitle"],
}
return fmt.Sprintf("【%s】空间容量超额提醒", options["siteName"]),
util.Replace(replace, options["over_used_template"])
}
// NewActivationEmail 新建激活邮件
func NewActivationEmail(userName, activateURL string) (string, string) {
options := model.GetSettingByNames("siteName", "siteURL", "siteTitle", "mail_activation_template")

View File

@@ -1,42 +0,0 @@
package payment
import (
"fmt"
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/serializer"
alipay "github.com/smartwalle/alipay/v3"
"net/url"
)
// Alipay 支付宝当面付支付处理
type Alipay struct {
Client *alipay.Client
}
// Create 创建订单
func (pay *Alipay) Create(order *model.Order, pack *serializer.PackProduct, group *serializer.GroupProducts, user *model.User) (*OrderCreateRes, error) {
gateway, _ := url.Parse("/api/v3/callback/alipay")
var p = alipay.TradePreCreate{
Trade: alipay.Trade{
NotifyURL: model.GetSiteURL().ResolveReference(gateway).String(),
Subject: order.Name,
OutTradeNo: order.OrderNo,
TotalAmount: fmt.Sprintf("%.2f", float64(order.Price*order.Num)/100),
},
}
if _, err := order.Create(); err != nil {
return nil, ErrInsertOrder.WithError(err)
}
res, err := pay.Client.TradePreCreate(p)
if err != nil {
return nil, ErrIssueOrder.WithError(err)
}
return &OrderCreateRes{
Payment: true,
QRCode: res.Content.QRCode,
ID: order.OrderNo,
}, nil
}

View File

@@ -1,147 +0,0 @@
package payment
import (
"fmt"
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/serializer"
"github.com/qingwg/payjs"
"github.com/smartwalle/alipay/v3"
"math/rand"
"net/url"
"time"
)
var (
// ErrUnknownPaymentMethod 未知支付方式
ErrUnknownPaymentMethod = serializer.NewError(serializer.CodeNotFound, "未知支付方式", nil)
// ErrUnsupportedPaymentMethod 未知支付方式
ErrUnsupportedPaymentMethod = serializer.NewError(serializer.CodeNotFound, "此订单不支持此支付方式", nil)
// ErrInsertOrder 无法插入订单记录
ErrInsertOrder = serializer.NewError(serializer.CodeDBError, "无法插入订单记录", nil)
// ErrScoreNotEnough 积分不足
ErrScoreNotEnough = serializer.NewError(serializer.CodeNoPermissionErr, "积分不足", nil)
// ErrCreateStoragePack 无法创建容量包
ErrCreateStoragePack = serializer.NewError(serializer.CodeNoPermissionErr, "无法创建容量包", nil)
// ErrGroupConflict 用户组冲突
ErrGroupConflict = serializer.NewError(serializer.CodeNoPermissionErr, "当前用户组仍未过期,请前往个人设置手动解约后继续", nil)
// ErrGroupInvalid 用户组冲突
ErrGroupInvalid = serializer.NewError(serializer.CodeNoPermissionErr, "用户组不可用", nil)
// ErrUpgradeGroup 用户组冲突
ErrUpgradeGroup = serializer.NewError(serializer.CodeDBError, "无法升级用户组", nil)
// ErrUInitPayment 无法初始化支付实例
ErrUInitPayment = serializer.NewError(serializer.CodeInternalSetting, "无法初始化支付实例", nil)
// ErrIssueOrder 订单接口请求失败
ErrIssueOrder = serializer.NewError(serializer.CodeInternalSetting, "无法创建订单", nil)
// ErrOrderNotFound 订单不存在
ErrOrderNotFound = serializer.NewError(serializer.CodeNotFound, "订单不存在", nil)
)
// Pay 支付处理接口
type Pay interface {
Create(order *model.Order, pack *serializer.PackProduct, group *serializer.GroupProducts, user *model.User) (*OrderCreateRes, error)
}
// OrderCreateRes 订单创建结果
type OrderCreateRes struct {
Payment bool `json:"payment"` // 是否需要支付
ID string `json:"id,omitempty"` // 订单号
QRCode string `json:"qr_code,omitempty"` // 支付二维码指向的地址
}
// NewPaymentInstance 获取新的支付实例
func NewPaymentInstance(method string) (Pay, error) {
switch method {
case "score":
return &ScorePayment{}, nil
case "alipay":
options := model.GetSettingByNames("alipay_enabled", "appid", "appkey", "shopid")
if options["alipay_enabled"] != "1" {
return nil, ErrUnknownPaymentMethod
}
// 初始化支付宝客户端
var client, err = alipay.New(options["appid"], options["appkey"], true)
if err != nil {
return nil, ErrUInitPayment.WithError(err)
}
// 加载支付宝公钥
err = client.LoadAliPayPublicKey(options["shopid"])
if err != nil {
return nil, ErrUInitPayment.WithError(err)
}
return &Alipay{Client: client}, nil
case "payjs":
options := model.GetSettingByNames("payjs_enabled", "payjs_secret", "payjs_id")
if options["payjs_enabled"] != "1" {
return nil, ErrUnknownPaymentMethod
}
callback, _ := url.Parse("/api/v3/callback/payjs")
payjsConfig := &payjs.Config{
Key: options["payjs_secret"],
MchID: options["payjs_id"],
NotifyUrl: model.GetSiteURL().ResolveReference(callback).String(),
}
return &PayJSClient{Client: payjs.New(payjsConfig)}, nil
default:
return nil, ErrUnknownPaymentMethod
}
}
// NewOrder 创建新订单
func NewOrder(pack *serializer.PackProduct, group *serializer.GroupProducts, num int, method string, user *model.User) (*OrderCreateRes, error) {
// 获取支付实例
pay, err := NewPaymentInstance(method)
if err != nil {
return nil, err
}
var (
orderType int
productID int64
title string
price int
)
if pack != nil {
orderType = model.PackOrderType
productID = pack.ID
title = pack.Name
price = pack.Price
} else if group != nil {
orderType = model.GroupOrderType
productID = group.ID
title = group.Name
price = group.Price
} else {
orderType = model.ScoreOrderType
productID = 0
title = fmt.Sprintf("%d 积分", num)
price = model.GetIntSetting("score_price", 1)
}
// 创建订单记录
order := &model.Order{
UserID: user.ID,
OrderNo: orderID(),
Type: orderType,
Method: method,
ProductID: productID,
Num: num,
Name: fmt.Sprintf("%s - %s", model.GetSettingByName("siteName"), title),
Price: price,
Status: model.OrderUnpaid,
}
return pay.Create(order, pack, group, user)
}
func orderID() string {
return fmt.Sprintf("%s%d",
time.Now().Format("20060102150405"),
100000+rand.Intn(900000),
)
}

View File

@@ -1,31 +0,0 @@
package payment
import (
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/serializer"
"github.com/qingwg/payjs"
)
// PayJSClient PayJS支付处理
type PayJSClient struct {
Client *payjs.PayJS
}
// Create 创建订单
func (pay *PayJSClient) Create(order *model.Order, pack *serializer.PackProduct, group *serializer.GroupProducts, user *model.User) (*OrderCreateRes, error) {
if _, err := order.Create(); err != nil {
return nil, ErrInsertOrder.WithError(err)
}
PayNative := pay.Client.GetNative()
res, err := PayNative.Create(int64(order.Price*order.Num), order.Name, order.OrderNo, "", "")
if err != nil {
return nil, ErrIssueOrder.WithError(err)
}
return &OrderCreateRes{
Payment: true,
QRCode: res.CodeUrl,
ID: order.OrderNo,
}, nil
}

View File

@@ -1,127 +0,0 @@
package payment
import (
"encoding/json"
"errors"
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/serializer"
"time"
)
// GivePack 创建容量包
func GivePack(user *model.User, packInfo *serializer.PackProduct, num int) error {
timeNow := time.Now()
expires := timeNow.Add(time.Duration(packInfo.Time*int64(num)) * time.Second)
pack := model.StoragePack{
Name: packInfo.Name,
UserID: user.ID,
ActiveTime: &timeNow,
ExpiredTime: &expires,
Size: packInfo.Size,
}
if _, err := pack.Create(); err != nil {
return ErrCreateStoragePack.WithError(err)
}
return nil
}
func checkGroupUpgrade(user *model.User, groupInfo *serializer.GroupProducts) error {
// 检查用户是否已有未过期用户
if user.PreviousGroupID != 0 {
return ErrGroupConflict
}
// 用户组不能相同
if user.GroupID == groupInfo.GroupID {
return ErrGroupInvalid
}
return nil
}
// GiveGroup 升级用户组
func GiveGroup(user *model.User, groupInfo *serializer.GroupProducts, num int) error {
if err := checkGroupUpgrade(user, groupInfo); err != nil {
return err
}
timeNow := time.Now()
expires := timeNow.Add(time.Duration(groupInfo.Time*int64(num)) * time.Second)
if err := user.UpgradeGroup(groupInfo.GroupID, &expires); err != nil {
return ErrUpgradeGroup.WithError(err)
}
return nil
}
// GiveScore 积分充值
func GiveScore(user *model.User, num int) error {
return nil
}
// GiveProduct “发货”
func GiveProduct(user *model.User, pack *serializer.PackProduct, group *serializer.GroupProducts, num int) error {
if pack != nil {
return GivePack(user, pack, num)
} else if group != nil {
return GiveGroup(user, group, num)
} else {
return GiveScore(user, num)
}
}
// OrderPaid 订单已支付处理
func OrderPaid(orderNo string) error {
order, err := model.GetOrderByNo(orderNo)
if err != nil {
return ErrOrderNotFound.WithError(err)
}
// 更新订单状态为 已支付
order.UpdateStatus(model.OrderPaid)
user, err := model.GetActiveUserByID(order.UserID)
if err != nil {
return errors.New("用户不存在")
}
// 查询商品
options := model.GetSettingByNames("pack_data", "group_sell_data")
var (
packs []serializer.PackProduct
groups []serializer.GroupProducts
)
if err := json.Unmarshal([]byte(options["pack_data"]), &packs); err != nil {
return err
}
if err := json.Unmarshal([]byte(options["group_sell_data"]), &groups); err != nil {
return err
}
// 查找要购买的商品
var (
pack *serializer.PackProduct
group *serializer.GroupProducts
)
if order.Type == model.GroupOrderType {
for _, v := range groups {
if v.ID == order.ProductID {
group = &v
break
}
}
} else if order.Type == model.PackOrderType {
for _, v := range packs {
if v.ID == order.ProductID {
pack = &v
break
}
}
}
// "发货"
return GiveProduct(&user, pack, group, order.Num)
}

View File

@@ -1,34 +0,0 @@
package payment
import (
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/serializer"
)
// ScorePayment 积分支付处理
type ScorePayment struct {
}
// Create 创建新订单
func (pay *ScorePayment) Create(order *model.Order, pack *serializer.PackProduct, group *serializer.GroupProducts, user *model.User) (*OrderCreateRes, error) {
if pack != nil {
order.Price = pack.Score
} else {
order.Price = group.Score
}
// 检查此订单是否可用积分支付
if order.Price == 0 {
return nil, ErrUnsupportedPaymentMethod
}
// 创建订单记录
order.Status = model.OrderPaid
if _, err := order.Create(); err != nil {
return nil, ErrInsertOrder.WithError(err)
}
return &OrderCreateRes{
Payment: false,
}, nil
}

View File

@@ -1,211 +0,0 @@
package qq
import (
"crypto/md5"
"encoding/json"
"errors"
"fmt"
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/request"
"github.com/HFO4/cloudreve/pkg/serializer"
"github.com/gofrs/uuid"
"net/url"
"strings"
)
// LoginPage 登陆页面描述
type LoginPage struct {
URL string
SecretKey string
}
// UserCredentials 登陆成功后的凭证
type UserCredentials struct {
OpenID string
AccessToken string
}
// UserInfo 用户信息
type UserInfo struct {
Nick string
Avatar string
}
var (
// ErrNotEnabled 未开启登录功能
ErrNotEnabled = serializer.NewError(serializer.CodeNoPermissionErr, "QQ登录功能未开启", nil)
// ErrObtainAccessToken 无法获取AccessToken
ErrObtainAccessToken = serializer.NewError(serializer.CodeParamErr, "无法获取AccessToken", nil)
// ErrObtainOpenID 无法获取OpenID
ErrObtainOpenID = serializer.NewError(serializer.CodeParamErr, "无法获取OpenID", nil)
//ErrDecodeResponse 无法解析服务端响应
ErrDecodeResponse = serializer.NewError(serializer.CodeInternalSetting, "无法解析服务端响应", nil)
)
// NewLoginRequest 新建登录会话
func NewLoginRequest() (*LoginPage, error) {
// 获取相关设定
options := model.GetSettingByNames("qq_login", "qq_login_id")
if options["qq_login"] == "0" {
return nil, ErrNotEnabled
}
// 生成唯一ID
u2, err := uuid.NewV4()
if err != nil {
return nil, err
}
secret := fmt.Sprintf("%x", md5.Sum(u2.Bytes()))
// 生成登录地址
loginURL, _ := url.Parse("https://graph.qq.com/oauth2.0/authorize?response_type=code")
queries := loginURL.Query()
queries.Add("client_id", options["qq_login_id"])
queries.Add("redirect_uri", getCallbackURL())
queries.Add("state", secret)
loginURL.RawQuery = queries.Encode()
return &LoginPage{
URL: loginURL.String(),
SecretKey: secret,
}, nil
}
func getCallbackURL() string {
//return "https://drive.aoaoao.me/Callback/QQ"
// 生成回调地址
gateway, _ := url.Parse("/#/login/qq")
callback := model.GetSiteURL().ResolveReference(gateway).String()
return callback
}
func getAccessTokenURL(code string) string {
// 获取相关设定
options := model.GetSettingByNames("qq_login_id", "qq_login_key")
api, _ := url.Parse("https://graph.qq.com/oauth2.0/token?grant_type=authorization_code")
queries := api.Query()
queries.Add("client_id", options["qq_login_id"])
queries.Add("redirect_uri", getCallbackURL())
queries.Add("client_secret", options["qq_login_key"])
queries.Add("code", code)
api.RawQuery = queries.Encode()
return api.String()
}
func getUserInfoURL(openid, ak string) string {
// 获取相关设定
options := model.GetSettingByNames("qq_login_id", "qq_login_key")
api, _ := url.Parse("https://graph.qq.com/user/get_user_info")
queries := api.Query()
queries.Add("oauth_consumer_key", options["qq_login_id"])
queries.Add("openid", openid)
queries.Add("access_token", ak)
api.RawQuery = queries.Encode()
return api.String()
}
func getResponse(body string) (map[string]interface{}, error) {
var res map[string]interface{}
if !strings.Contains(body, "callback") {
return res, nil
}
body = strings.TrimPrefix(body, "callback(")
body = strings.TrimSuffix(body, ");\n")
err := json.Unmarshal([]byte(body), &res)
return res, err
}
// Callback 处理回调,返回openid和access key
func Callback(code string) (*UserCredentials, error) {
// 获取相关设定
options := model.GetSettingByNames("qq_login")
if options["qq_login"] == "0" {
return nil, ErrNotEnabled
}
api := getAccessTokenURL(code)
// 获取AccessToken
client := request.HTTPClient{}
res := client.Request("GET", api, nil)
resp, err := res.GetResponse()
if err != nil {
return nil, ErrObtainAccessToken.WithError(err)
}
// 如果服务端返回错误
errResp, err := getResponse(resp)
if msg, ok := errResp["error_description"]; err == nil && ok {
return nil, ErrObtainAccessToken.WithError(errors.New(msg.(string)))
}
// 获取AccessToken
vals, err := url.ParseQuery(resp)
if err != nil {
return nil, ErrDecodeResponse.WithError(err)
}
accessToken := vals.Get("access_token")
// 用 AccessToken 换取OpenID
res = client.Request("GET", "https://graph.qq.com/oauth2.0/me?access_token="+accessToken, nil)
resp, err = res.GetResponse()
if err != nil {
return nil, ErrObtainOpenID.WithError(err)
}
// 解析服务端响应
errResp, err = getResponse(resp)
if msg, ok := errResp["error_description"]; err == nil && ok {
return nil, ErrObtainOpenID.WithError(errors.New(msg.(string)))
}
if openid, ok := errResp["openid"]; ok {
return &UserCredentials{
OpenID: openid.(string),
AccessToken: accessToken,
}, nil
}
return nil, ErrDecodeResponse
}
// GetUserInfo 使用凭证获取用户信息
func GetUserInfo(credential *UserCredentials) (*UserInfo, error) {
api := getUserInfoURL(credential.OpenID, credential.AccessToken)
// 获取用户信息
client := request.HTTPClient{}
res := client.Request("GET", api, nil)
resp, err := res.GetResponse()
if err != nil {
return nil, ErrObtainAccessToken.WithError(err)
}
var resSerialized map[string]interface{}
if err := json.Unmarshal([]byte(resp), &resSerialized); err != nil {
return nil, ErrDecodeResponse.WithError(err)
}
// 如果服务端返回错误
if msg, ok := resSerialized["msg"]; ok && msg.(string) != "" {
return nil, ErrObtainAccessToken.WithError(errors.New(msg.(string)))
}
if avatar, ok := resSerialized["figureurl_qq_2"]; ok {
return &UserInfo{
Nick: resSerialized["nickname"].(string),
Avatar: avatar.(string),
}, nil
}
return nil, ErrDecodeResponse
}

View File

@@ -9,7 +9,6 @@ type SiteConfig struct {
RegCaptcha bool `json:"regCaptcha"`
ForgetCaptcha bool `json:"forgetCaptcha"`
EmailActive bool `json:"emailActive"`
QQLogin bool `json:"QQLogin"`
Themes string `json:"themes"`
DefaultTheme string `json:"defaultTheme"`
HomepageViewMethod string `json:"home_view_method"`
@@ -67,7 +66,6 @@ func BuildSiteConfig(settings map[string]string, user *model.User) Response {
RegCaptcha: model.IsTrueVal(checkSettingValue(settings, "reg_captcha")),
ForgetCaptcha: model.IsTrueVal(checkSettingValue(settings, "forget_captcha")),
EmailActive: model.IsTrueVal(checkSettingValue(settings, "email_active")),
QQLogin: model.IsTrueVal(checkSettingValue(settings, "qq_login")),
Themes: checkSettingValue(settings, "themes"),
DefaultTheme: checkSettingValue(settings, "defaultTheme"),
HomepageViewMethod: checkSettingValue(settings, "home_view_method"),

View File

@@ -44,7 +44,6 @@ type group struct {
AllowShare bool `json:"allowShare"`
AllowRemoteDownload bool `json:"allowRemoteDownload"`
AllowArchiveDownload bool `json:"allowArchiveDownload"`
ShareFreeEnabled bool `json:"shareFree"`
ShareDownload bool `json:"shareDownload"`
CompressEnabled bool `json:"compress"`
WebDAVEnabled bool `json:"webdav"`
@@ -127,7 +126,7 @@ func BuildUserResponse(user model.User) Response {
// BuildUserStorageResponse 序列化用户存储概况响应
func BuildUserStorageResponse(user model.User) Response {
total := user.Group.MaxStorage + user.GetAvailablePackSize()
total := user.Group.MaxStorage
storageResp := storage{
Used: user.Storage,
Free: total - user.Storage,

View File

@@ -1,120 +0,0 @@
package serializer
import (
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/hashid"
"github.com/HFO4/cloudreve/pkg/util"
)
type quota struct {
Base uint64 `json:"base"`
Pack uint64 `json:"pack"`
Used uint64 `json:"used"`
Total uint64 `json:"total"`
Packs []storagePacks `json:"packs"`
}
type storagePacks struct {
Name string `json:"name"`
Size uint64 `json:"size"`
ActivateDate string `json:"activate_date"`
Expiration int `json:"expiration"`
ExpirationDate string `json:"expiration_date"`
}
// MountedFolders 已挂载的目录
type MountedFolders struct {
ID string `json:"id"`
Name string `json:"name"`
PolicyName string `json:"policy_name"`
}
type policyOptions struct {
Name string `json:"name"`
ID string `json:"id"`
}
// BuildPolicySettingRes 构建存储策略选项选择
func BuildPolicySettingRes(policies []model.Policy, current *model.Policy) Response {
options := make([]policyOptions, 0, len(policies))
for _, policy := range policies {
options = append(options, policyOptions{
Name: policy.Name,
ID: hashid.HashID(policy.ID, hashid.PolicyID),
})
}
return Response{
Data: map[string]interface{}{
"options": options,
"current": policyOptions{
Name: current.Name,
ID: hashid.HashID(current.ID, hashid.PolicyID),
},
},
}
}
// BuildUserQuotaResponse 序列化用户存储配额概况响应
func BuildUserQuotaResponse(user *model.User, packs []model.StoragePack) Response {
packSize := user.GetAvailablePackSize()
res := quota{
Base: user.Group.MaxStorage,
Pack: packSize,
Used: user.Storage,
Total: packSize + user.Group.MaxStorage,
Packs: make([]storagePacks, 0, len(packs)),
}
for _, pack := range packs {
res.Packs = append(res.Packs, storagePacks{
Name: pack.Name,
Size: pack.Size,
ActivateDate: pack.ActiveTime.Format("2006-01-02 15:04:05"),
Expiration: int(pack.ExpiredTime.Sub(*pack.ActiveTime).Seconds()),
ExpirationDate: pack.ExpiredTime.Format("2006-01-02 15:04:05"),
})
}
return Response{
Data: res,
}
}
// PackProduct 容量包商品
type PackProduct struct {
ID int64 `json:"id"`
Name string `json:"name"`
Size uint64 `json:"size"`
Time int64 `json:"time"`
Price int `json:"price"`
Score int `json:"score"`
}
// GroupProducts 用户组商品
type GroupProducts struct {
ID int64 `json:"id"`
Name string `json:"name"`
GroupID uint `json:"group_id"`
Time int64 `json:"time"`
Price int `json:"price"`
Score int `json:"score"`
Des []string `json:"des"`
Highlight bool `json:"highlight"`
}
// BuildProductResponse 构建增值服务商品响应
func BuildProductResponse(groups []GroupProducts, packs []PackProduct, alipay, payjs bool, scorePrice int) Response {
// 隐藏响应中的用户组ID
for i := 0; i < len(groups); i++ {
groups[i].GroupID = 0
}
return Response{
Data: map[string]interface{}{
"packs": packs,
"groups": groups,
"alipay": alipay,
"payjs": payjs,
"score_price": scorePrice,
},
}
}