mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +08:00 
			
		
		
		
	初始化
This commit is contained in:
		
							
								
								
									
										1
									
								
								build/configs/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								build/configs/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
server.yaml
 | 
			
		||||
							
								
								
									
										16
									
								
								build/configs/server.template.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								build/configs/server.template.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
# environment code
 | 
			
		||||
env: prod
 | 
			
		||||
 | 
			
		||||
# http
 | 
			
		||||
http:
 | 
			
		||||
  "on": true
 | 
			
		||||
  listen: [ "0.0.0.0:8001" ]
 | 
			
		||||
 | 
			
		||||
# https
 | 
			
		||||
https:
 | 
			
		||||
  "on": false
 | 
			
		||||
  listen: [ "0.0.0.0:443"]
 | 
			
		||||
  cert: ""
 | 
			
		||||
  key: ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								build/logs/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								build/logs/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
*.log
 | 
			
		||||
							
								
								
									
										31
									
								
								cmd/edge-admin/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								cmd/edge-admin/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/apps"
 | 
			
		||||
	teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
	_ "github.com/iwind/TeaGo/bootstrap"
 | 
			
		||||
	"github.com/iwind/TeaGo/rands"
 | 
			
		||||
	"github.com/iwind/TeaGo/sessions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	app := apps.NewAppCmd().
 | 
			
		||||
		Version(teaconst.Version).
 | 
			
		||||
		Product(teaconst.ProductName).
 | 
			
		||||
		Usage(teaconst.ProcessName + " [-v|start|stop|restart]")
 | 
			
		||||
 | 
			
		||||
	app.Run(func() {
 | 
			
		||||
		// 启动管理界面
 | 
			
		||||
		server := TeaGo.NewServer(false).
 | 
			
		||||
			AccessLog(false).
 | 
			
		||||
			EndAll().
 | 
			
		||||
 | 
			
		||||
			Session(sessions.NewFileSessionManager(
 | 
			
		||||
				86400,
 | 
			
		||||
				rands.String(32),
 | 
			
		||||
			))
 | 
			
		||||
		server.Start()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								dist/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								dist/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
*.zip
 | 
			
		||||
shield-admin
 | 
			
		||||
							
								
								
									
										20
									
								
								docs/TODO.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								docs/TODO.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
# 一期
 | 
			
		||||
* 服务管理
 | 
			
		||||
* 节点管理
 | 
			
		||||
  * 边缘节点
 | 
			
		||||
* 资源管理
 | 
			
		||||
* 组件管理:缓存策略、WAF等
 | 
			
		||||
* 设置
 | 
			
		||||
 * 供应商
 | 
			
		||||
 * 用户
 | 
			
		||||
 * 授权管理
 | 
			
		||||
     
 | 
			
		||||
# 二期
 | 
			
		||||
* 节点管理
 | 
			
		||||
  * 数据库集群
 | 
			
		||||
  * 统计分析节点
 | 
			
		||||
  * API集群
 | 
			
		||||
  * DNS集群
 | 
			
		||||
  * 监控系统
 | 
			
		||||
 | 
			
		||||
# TODO
 | 
			
		||||
							
								
								
									
										5
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
module github.com/TeaOSLab/EdgeAdmin
 | 
			
		||||
 | 
			
		||||
go 1.14
 | 
			
		||||
 | 
			
		||||
require github.com/iwind/TeaGo v0.0.0-20200722010955-47dd648dc761
 | 
			
		||||
							
								
								
									
										61
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 | 
			
		||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 | 
			
		||||
github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
 | 
			
		||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 | 
			
		||||
github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=
 | 
			
		||||
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
 | 
			
		||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 | 
			
		||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
 | 
			
		||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
 | 
			
		||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
 | 
			
		||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
 | 
			
		||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
 | 
			
		||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 | 
			
		||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
			
		||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 | 
			
		||||
github.com/iwind/TeaGo v0.0.0-20200722010955-47dd648dc761 h1:70Iaf6iVF4CiH1P5Au3hqile/2Ea0XIkR4SPpdiaKI0=
 | 
			
		||||
github.com/iwind/TeaGo v0.0.0-20200722010955-47dd648dc761/go.mod h1:zjM7k+b+Jthhf0T0fKwuF0iy4TWb5SsU1gmKR2l+OmE=
 | 
			
		||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
			
		||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 | 
			
		||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
			
		||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 | 
			
		||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 | 
			
		||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 | 
			
		||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 | 
			
		||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 | 
			
		||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
 | 
			
		||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 | 
			
		||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 | 
			
		||||
github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7 h1:xoIK0ctDddBMnc74udxJYBqlo9Ylnsp1waqjLsnef20=
 | 
			
		||||
github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 | 
			
		||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 | 
			
		||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 | 
			
		||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 | 
			
		||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
 | 
			
		||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
 | 
			
		||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
 | 
			
		||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 | 
			
		||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
 | 
			
		||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 | 
			
		||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 | 
			
		||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
			
		||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
 | 
			
		||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
			
		||||
							
								
								
									
										234
									
								
								internal/apps/app_cmd.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								internal/apps/app_cmd.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,234 @@
 | 
			
		||||
package apps
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/iwind/TeaGo/Tea"
 | 
			
		||||
	"github.com/iwind/TeaGo/logs"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// App命令帮助
 | 
			
		||||
type AppCmd struct {
 | 
			
		||||
	product       string
 | 
			
		||||
	version       string
 | 
			
		||||
	usage         string
 | 
			
		||||
	options       []*CommandHelpOption
 | 
			
		||||
	appendStrings []string
 | 
			
		||||
 | 
			
		||||
	directives []*Directive
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewAppCmd() *AppCmd {
 | 
			
		||||
	return &AppCmd{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CommandHelpOption struct {
 | 
			
		||||
	Code        string
 | 
			
		||||
	Description string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 产品
 | 
			
		||||
func (this *AppCmd) Product(product string) *AppCmd {
 | 
			
		||||
	this.product = product
 | 
			
		||||
	return this
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 版本
 | 
			
		||||
func (this *AppCmd) Version(version string) *AppCmd {
 | 
			
		||||
	this.version = version
 | 
			
		||||
	return this
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 使用方法
 | 
			
		||||
func (this *AppCmd) Usage(usage string) *AppCmd {
 | 
			
		||||
	this.usage = usage
 | 
			
		||||
	return this
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 选项
 | 
			
		||||
func (this *AppCmd) Option(code string, description string) *AppCmd {
 | 
			
		||||
	this.options = append(this.options, &CommandHelpOption{
 | 
			
		||||
		Code:        code,
 | 
			
		||||
		Description: description,
 | 
			
		||||
	})
 | 
			
		||||
	return this
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 附加内容
 | 
			
		||||
func (this *AppCmd) Append(appendString string) *AppCmd {
 | 
			
		||||
	this.appendStrings = append(this.appendStrings, appendString)
 | 
			
		||||
	return this
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 打印
 | 
			
		||||
func (this *AppCmd) Print() {
 | 
			
		||||
	fmt.Println(this.product + " v" + this.version)
 | 
			
		||||
 | 
			
		||||
	usage := this.usage
 | 
			
		||||
	fmt.Println("Usage:", "\n   "+usage)
 | 
			
		||||
 | 
			
		||||
	if len(this.options) > 0 {
 | 
			
		||||
		fmt.Println("")
 | 
			
		||||
		fmt.Println("Options:")
 | 
			
		||||
 | 
			
		||||
		spaces := 20
 | 
			
		||||
		max := 40
 | 
			
		||||
		for _, option := range this.options {
 | 
			
		||||
			l := len(option.Code)
 | 
			
		||||
			if l < max && l > spaces {
 | 
			
		||||
				spaces = l + 4
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, option := range this.options {
 | 
			
		||||
			if len(option.Code) > max {
 | 
			
		||||
				fmt.Println("")
 | 
			
		||||
				fmt.Println("  " + option.Code)
 | 
			
		||||
				option.Code = ""
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fmt.Printf("  %-"+strconv.Itoa(spaces)+"s%s\n", option.Code, ": "+option.Description)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(this.appendStrings) > 0 {
 | 
			
		||||
		fmt.Println("")
 | 
			
		||||
		for _, s := range this.appendStrings {
 | 
			
		||||
			fmt.Println(s)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 添加指令
 | 
			
		||||
func (this *AppCmd) On(arg string, callback func()) {
 | 
			
		||||
	this.directives = append(this.directives, &Directive{
 | 
			
		||||
		Arg:      arg,
 | 
			
		||||
		Callback: callback,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 运行
 | 
			
		||||
func (this *AppCmd) Run(main func()) {
 | 
			
		||||
	// 获取参数
 | 
			
		||||
	args := os.Args[1:]
 | 
			
		||||
	if len(args) > 0 {
 | 
			
		||||
		switch args[0] {
 | 
			
		||||
		case "-v", "version", "-version", "--version":
 | 
			
		||||
			this.runVersion()
 | 
			
		||||
			return
 | 
			
		||||
		case "?", "help", "-help", "h", "-h":
 | 
			
		||||
			this.runHelp()
 | 
			
		||||
			return
 | 
			
		||||
		case "start":
 | 
			
		||||
			this.runStart()
 | 
			
		||||
			return
 | 
			
		||||
		case "stop":
 | 
			
		||||
			this.runStop()
 | 
			
		||||
			return
 | 
			
		||||
		case "restart":
 | 
			
		||||
			this.runRestart()
 | 
			
		||||
			return
 | 
			
		||||
		case "status":
 | 
			
		||||
			this.runStatus()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 查找指令
 | 
			
		||||
		for _, directive := range this.directives {
 | 
			
		||||
			if directive.Arg == args[0] {
 | 
			
		||||
				directive.Callback()
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Println("unknown command '" + args[0] + "'")
 | 
			
		||||
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 记录PID
 | 
			
		||||
	_ = this.writePid()
 | 
			
		||||
 | 
			
		||||
	// 日志
 | 
			
		||||
	writer := new(LogWriter)
 | 
			
		||||
	writer.Init()
 | 
			
		||||
	logs.SetWriter(writer)
 | 
			
		||||
 | 
			
		||||
	// 运行主函数
 | 
			
		||||
	main()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 版本号
 | 
			
		||||
func (this *AppCmd) runVersion() {
 | 
			
		||||
	fmt.Println(this.product+" v"+this.version, "(build: "+runtime.Version(), runtime.GOOS, runtime.GOARCH+")")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 帮助
 | 
			
		||||
func (this *AppCmd) runHelp() {
 | 
			
		||||
	this.Print()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 启动
 | 
			
		||||
func (this *AppCmd) runStart() {
 | 
			
		||||
	proc := this.checkPid()
 | 
			
		||||
	if proc != nil {
 | 
			
		||||
		fmt.Println(this.product+" already started, pid:", proc.Pid)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cmd := exec.Command(os.Args[0])
 | 
			
		||||
	err := cmd.Start()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Println(this.product+"  start failed:", err.Error())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fmt.Println(this.product+" started ok, pid:", cmd.Process.Pid)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 停止
 | 
			
		||||
func (this *AppCmd) runStop() {
 | 
			
		||||
	proc := this.checkPid()
 | 
			
		||||
	if proc == nil {
 | 
			
		||||
		fmt.Println(this.product + " not started yet")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 停止进程
 | 
			
		||||
	_ = proc.Kill()
 | 
			
		||||
 | 
			
		||||
	// 在Windows上经常不能及时释放资源
 | 
			
		||||
	_ = DeletePid(Tea.Root + "/bin/pid")
 | 
			
		||||
	fmt.Println(this.product+" stopped ok, pid:", proc.Pid)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 重启
 | 
			
		||||
func (this *AppCmd) runRestart() {
 | 
			
		||||
	this.runStop()
 | 
			
		||||
	time.Sleep(1 * time.Second)
 | 
			
		||||
	this.runStart()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 状态
 | 
			
		||||
func (this *AppCmd) runStatus() {
 | 
			
		||||
	proc := this.checkPid()
 | 
			
		||||
	if proc == nil {
 | 
			
		||||
		fmt.Println(this.product + " not started yet")
 | 
			
		||||
	} else {
 | 
			
		||||
		fmt.Println(this.product + " is running, pid: " + fmt.Sprintf("%d", proc.Pid))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 检查PID
 | 
			
		||||
func (this *AppCmd) checkPid() *os.Process {
 | 
			
		||||
	return CheckPid(Tea.Root + "/bin/pid")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 写入PID
 | 
			
		||||
func (this *AppCmd) writePid() error {
 | 
			
		||||
	return WritePid(Tea.Root + "/bin/pid")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								internal/apps/directive.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								internal/apps/directive.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
package apps
 | 
			
		||||
 | 
			
		||||
type Directive struct {
 | 
			
		||||
	Arg      string
 | 
			
		||||
	Callback func()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								internal/apps/file_others.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								internal/apps/file_others.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
// +build !windows
 | 
			
		||||
 | 
			
		||||
package apps
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// lock file
 | 
			
		||||
func LockFile(fp *os.File) error {
 | 
			
		||||
	return syscall.Flock(int(fp.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func UnlockFile(fp *os.File) error {
 | 
			
		||||
	return syscall.Flock(int(fp.Fd()), syscall.LOCK_UN)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								internal/apps/file_windows.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								internal/apps/file_windows.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package apps
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// lock file
 | 
			
		||||
func LockFile(fp *os.File) error {
 | 
			
		||||
	return errors.New("not implemented on windows")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func UnlockFile(fp *os.File) error {
 | 
			
		||||
	return errors.New("not implemented on windows")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								internal/apps/log_writer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								internal/apps/log_writer.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
package apps
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/iwind/TeaGo/Tea"
 | 
			
		||||
	"github.com/iwind/TeaGo/files"
 | 
			
		||||
	"github.com/iwind/TeaGo/logs"
 | 
			
		||||
	"github.com/iwind/TeaGo/utils/time"
 | 
			
		||||
	"log"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type LogWriter struct {
 | 
			
		||||
	fileAppender *files.Appender
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *LogWriter) Init() {
 | 
			
		||||
	// 创建目录
 | 
			
		||||
	dir := files.NewFile(Tea.LogDir())
 | 
			
		||||
	if !dir.Exists() {
 | 
			
		||||
		err := dir.Mkdir()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println("[error]" + err.Error())
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logFile := files.NewFile(Tea.LogFile("run.log"))
 | 
			
		||||
 | 
			
		||||
	// 打开要写入的日志文件
 | 
			
		||||
	appender, err := logFile.Appender()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logs.Error(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		this.fileAppender = appender
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *LogWriter) Write(message string) {
 | 
			
		||||
	log.Println(message)
 | 
			
		||||
 | 
			
		||||
	if this.fileAppender != nil {
 | 
			
		||||
		_, err := this.fileAppender.AppendString(timeutil.Format("Y/m/d H:i:s ") + message + "\n")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println("[error]" + err.Error())
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *LogWriter) Close() {
 | 
			
		||||
	if this.fileAppender != nil {
 | 
			
		||||
		_ = this.fileAppender.Close()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										113
									
								
								internal/apps/pid.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								internal/apps/pid.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
package apps
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/iwind/TeaGo/types"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var pidFileList = []*os.File{}
 | 
			
		||||
 | 
			
		||||
// 检查Pid
 | 
			
		||||
func CheckPid(path string) *os.Process {
 | 
			
		||||
	// windows上打开的文件是不能删除的
 | 
			
		||||
	if runtime.GOOS == "windows" {
 | 
			
		||||
		if os.Remove(path) == nil {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	file, err := os.Open(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer func() {
 | 
			
		||||
		_ = file.Close()
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	// 是否能取得Lock
 | 
			
		||||
	err = LockFile(file)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		_ = UnlockFile(file)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pidBytes, err := ioutil.ReadAll(file)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	pid := types.Int(string(pidBytes))
 | 
			
		||||
 | 
			
		||||
	if pid <= 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	proc, _ := os.FindProcess(pid)
 | 
			
		||||
	return proc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 写入Pid
 | 
			
		||||
func WritePid(path string) error {
 | 
			
		||||
	fp, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_RDONLY, 0666)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if runtime.GOOS != "windows" {
 | 
			
		||||
		err = LockFile(fp)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	pidFileList = append(pidFileList, fp) // hold the file pointers
 | 
			
		||||
 | 
			
		||||
	_, err = fp.WriteString(fmt.Sprintf("%d", os.Getpid()))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 写入Ppid
 | 
			
		||||
func WritePpid(path string) error {
 | 
			
		||||
	fp, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_RDONLY, 0666)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if runtime.GOOS != "windows" {
 | 
			
		||||
		err = LockFile(fp)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	pidFileList = append(pidFileList, fp) // hold the file pointers
 | 
			
		||||
 | 
			
		||||
	_, err = fp.WriteString(fmt.Sprintf("%d", os.Getppid()))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 删除Pid
 | 
			
		||||
func DeletePid(path string) error {
 | 
			
		||||
	_, err := os.Stat(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if !os.IsNotExist(err) {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, fp := range pidFileList {
 | 
			
		||||
		_ = UnlockFile(fp)
 | 
			
		||||
		_ = fp.Close()
 | 
			
		||||
	}
 | 
			
		||||
	return os.Remove(path)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								internal/const/const.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								internal/const/const.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
package teaconst
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	Version = "0.0.1"
 | 
			
		||||
 | 
			
		||||
	ProductName = "Edge Admin"
 | 
			
		||||
	ProcessName = "edge-admin"
 | 
			
		||||
 | 
			
		||||
	Role = "admin"
 | 
			
		||||
 | 
			
		||||
	EncryptKey = "8f983f4d69b83aaa0d74b21a212f6967"
 | 
			
		||||
 | 
			
		||||
	ErrServer = "服务器出了点小问题,请稍后重试"
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										5
									
								
								internal/web/actions.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								internal/web/actions.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
package web
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/index"
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										18
									
								
								internal/web/actions/default/index/index.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								internal/web/actions/default/index/index.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
package index
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	stringutil "github.com/iwind/TeaGo/utils/string"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction actions.Action
 | 
			
		||||
 | 
			
		||||
// 首页(登录页)
 | 
			
		||||
 | 
			
		||||
var TokenSalt = stringutil.Rand(32)
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	From string
 | 
			
		||||
}) {
 | 
			
		||||
	this.WriteString("Hello, i am index")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								internal/web/actions/default/index/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								internal/web/actions/default/index/init.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
package index
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
			
		||||
		server.Prefix("/").
 | 
			
		||||
			GetPost("", new(IndexAction)).
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								web/public/js/axios.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										9
									
								
								web/public/js/axios.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								web/public/js/axios.min.map
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								web/public/js/axios.min.map
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								web/public/js/md5.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										2
									
								
								web/public/js/md5.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
!function(n){"use strict";function d(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function f(n,t,r,e,o,u){return d(function(n,t){return n<<t|n>>>32-t}(d(d(t,n),d(e,u)),o),r)}function l(n,t,r,e,o,u,c){return f(t&r|~t&e,n,t,o,u,c)}function g(n,t,r,e,o,u,c){return f(t&e|r&~e,n,t,o,u,c)}function v(n,t,r,e,o,u,c){return f(t^r^e,n,t,o,u,c)}function m(n,t,r,e,o,u,c){return f(r^(t|~e),n,t,o,u,c)}function i(n,t){var r,e,o,u,c;n[t>>5]|=128<<t%32,n[14+(t+64>>>9<<4)]=t;var f=1732584193,i=-271733879,a=-1732584194,h=271733878;for(r=0;r<n.length;r+=16)i=m(i=m(i=m(i=m(i=v(i=v(i=v(i=v(i=g(i=g(i=g(i=g(i=l(i=l(i=l(i=l(o=i,a=l(u=a,h=l(c=h,f=l(e=f,i,a,h,n[r],7,-680876936),i,a,n[r+1],12,-389564586),f,i,n[r+2],17,606105819),h,f,n[r+3],22,-1044525330),a=l(a,h=l(h,f=l(f,i,a,h,n[r+4],7,-176418897),i,a,n[r+5],12,1200080426),f,i,n[r+6],17,-1473231341),h,f,n[r+7],22,-45705983),a=l(a,h=l(h,f=l(f,i,a,h,n[r+8],7,1770035416),i,a,n[r+9],12,-1958414417),f,i,n[r+10],17,-42063),h,f,n[r+11],22,-1990404162),a=l(a,h=l(h,f=l(f,i,a,h,n[r+12],7,1804603682),i,a,n[r+13],12,-40341101),f,i,n[r+14],17,-1502002290),h,f,n[r+15],22,1236535329),a=g(a,h=g(h,f=g(f,i,a,h,n[r+1],5,-165796510),i,a,n[r+6],9,-1069501632),f,i,n[r+11],14,643717713),h,f,n[r],20,-373897302),a=g(a,h=g(h,f=g(f,i,a,h,n[r+5],5,-701558691),i,a,n[r+10],9,38016083),f,i,n[r+15],14,-660478335),h,f,n[r+4],20,-405537848),a=g(a,h=g(h,f=g(f,i,a,h,n[r+9],5,568446438),i,a,n[r+14],9,-1019803690),f,i,n[r+3],14,-187363961),h,f,n[r+8],20,1163531501),a=g(a,h=g(h,f=g(f,i,a,h,n[r+13],5,-1444681467),i,a,n[r+2],9,-51403784),f,i,n[r+7],14,1735328473),h,f,n[r+12],20,-1926607734),a=v(a,h=v(h,f=v(f,i,a,h,n[r+5],4,-378558),i,a,n[r+8],11,-2022574463),f,i,n[r+11],16,1839030562),h,f,n[r+14],23,-35309556),a=v(a,h=v(h,f=v(f,i,a,h,n[r+1],4,-1530992060),i,a,n[r+4],11,1272893353),f,i,n[r+7],16,-155497632),h,f,n[r+10],23,-1094730640),a=v(a,h=v(h,f=v(f,i,a,h,n[r+13],4,681279174),i,a,n[r],11,-358537222),f,i,n[r+3],16,-722521979),h,f,n[r+6],23,76029189),a=v(a,h=v(h,f=v(f,i,a,h,n[r+9],4,-640364487),i,a,n[r+12],11,-421815835),f,i,n[r+15],16,530742520),h,f,n[r+2],23,-995338651),a=m(a,h=m(h,f=m(f,i,a,h,n[r],6,-198630844),i,a,n[r+7],10,1126891415),f,i,n[r+14],15,-1416354905),h,f,n[r+5],21,-57434055),a=m(a,h=m(h,f=m(f,i,a,h,n[r+12],6,1700485571),i,a,n[r+3],10,-1894986606),f,i,n[r+10],15,-1051523),h,f,n[r+1],21,-2054922799),a=m(a,h=m(h,f=m(f,i,a,h,n[r+8],6,1873313359),i,a,n[r+15],10,-30611744),f,i,n[r+6],15,-1560198380),h,f,n[r+13],21,1309151649),a=m(a,h=m(h,f=m(f,i,a,h,n[r+4],6,-145523070),i,a,n[r+11],10,-1120210379),f,i,n[r+2],15,718787259),h,f,n[r+9],21,-343485551),f=d(f,e),i=d(i,o),a=d(a,u),h=d(h,c);return[f,i,a,h]}function a(n){var t,r="",e=32*n.length;for(t=0;t<e;t+=8)r+=String.fromCharCode(n[t>>5]>>>t%32&255);return r}function h(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t<r.length;t+=1)r[t]=0;var e=8*n.length;for(t=0;t<e;t+=8)r[t>>5]|=(255&n.charCodeAt(t/8))<<t%32;return r}function e(n){var t,r,e="0123456789abcdef",o="";for(r=0;r<n.length;r+=1)t=n.charCodeAt(r),o+=e.charAt(t>>>4&15)+e.charAt(15&t);return o}function r(n){return unescape(encodeURIComponent(n))}function o(n){return function(n){return a(i(h(n),8*n.length))}(r(n))}function u(n,t){return function(n,t){var r,e,o=h(n),u=[],c=[];for(u[15]=c[15]=void 0,16<o.length&&(o=i(o,8*n.length)),r=0;r<16;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(h(t)),512+8*t.length),a(i(c.concat(e),640))}(r(n),r(t))}function t(n,t,r){return t?r?u(t,n):function(n,t){return e(u(n,t))}(t,n):r?o(n):function(n){return e(o(n))}(n)}"function"==typeof define&&define.amd?define(function(){return t}):"object"==typeof module&&module.exports?module.exports=t:n.md5=t}(this);
 | 
			
		||||
//# sourceMappingURL=md5.min.js.map
 | 
			
		||||
							
								
								
									
										1
									
								
								web/public/js/md5.min.js.map
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								web/public/js/md5.min.js.map
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								web/public/js/moment.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								web/public/js/moment.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										239
									
								
								web/public/js/pikaday.css
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										239
									
								
								web/public/js/pikaday.css
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,239 @@
 | 
			
		||||
@charset "UTF-8";
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 * Pikaday
 | 
			
		||||
 * Copyright © 2014 David Bushell | BSD & MIT license | https://dbushell.com/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
.pika-single {
 | 
			
		||||
    z-index: 9999;
 | 
			
		||||
    display: block;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    color: #333;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    border: 1px solid #ccc;
 | 
			
		||||
    border-bottom-color: #bbb;
 | 
			
		||||
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
clear child float (pika-lendar), using the famous micro clearfix hack
 | 
			
		||||
http://nicolasgallagher.com/micro-clearfix-hack/
 | 
			
		||||
*/
 | 
			
		||||
.pika-single:before,
 | 
			
		||||
.pika-single:after {
 | 
			
		||||
    content: " ";
 | 
			
		||||
    display: table;
 | 
			
		||||
}
 | 
			
		||||
.pika-single:after { clear: both }
 | 
			
		||||
.pika-single { *zoom: 1 }
 | 
			
		||||
 | 
			
		||||
.pika-single.is-hidden {
 | 
			
		||||
    display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-single.is-bound {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    box-shadow: 0 5px 15px -5px rgba(0,0,0,.5);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-lendar {
 | 
			
		||||
    float: left;
 | 
			
		||||
    width: 240px;
 | 
			
		||||
    margin: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-title {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-label {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    *display: inline;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    z-index: 9999;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    padding: 5px 3px;
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    line-height: 20px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    background-color: #fff;
 | 
			
		||||
}
 | 
			
		||||
.pika-title select {
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    z-index: 9998;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    top: 5px;
 | 
			
		||||
    filter: alpha(opacity=0);
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-prev,
 | 
			
		||||
.pika-next {
 | 
			
		||||
    display: block;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    outline: none;
 | 
			
		||||
    border: 0;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    width: 20px;
 | 
			
		||||
    height: 30px;
 | 
			
		||||
    /* hide text using text-indent trick, using width value (it's enough) */
 | 
			
		||||
    text-indent: 20px;
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
    background-position: center center;
 | 
			
		||||
    background-repeat: no-repeat;
 | 
			
		||||
    background-size: 75% 75%;
 | 
			
		||||
    opacity: .5;
 | 
			
		||||
    *position: absolute;
 | 
			
		||||
    *top: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-prev:hover,
 | 
			
		||||
.pika-next:hover {
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-prev,
 | 
			
		||||
.is-rtl .pika-next {
 | 
			
		||||
    float: left;
 | 
			
		||||
    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==');
 | 
			
		||||
    *left: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-next,
 | 
			
		||||
.is-rtl .pika-prev {
 | 
			
		||||
    float: right;
 | 
			
		||||
    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=');
 | 
			
		||||
    *right: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-prev.is-disabled,
 | 
			
		||||
.pika-next.is-disabled {
 | 
			
		||||
    cursor: default;
 | 
			
		||||
    opacity: .2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-select {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    *display: inline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-table {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    border-collapse: collapse;
 | 
			
		||||
    border-spacing: 0;
 | 
			
		||||
    border: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-table th,
 | 
			
		||||
.pika-table td {
 | 
			
		||||
    width: 14.285714285714286%;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-table th {
 | 
			
		||||
    color: #999;
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    line-height: 25px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-button {
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    display: block;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    -moz-box-sizing: border-box;
 | 
			
		||||
    outline: none;
 | 
			
		||||
    border: 0;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    padding: 5px;
 | 
			
		||||
    color: #666;
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    line-height: 15px;
 | 
			
		||||
    text-align: right;
 | 
			
		||||
    background: #f5f5f5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-week {
 | 
			
		||||
    font-size: 11px;
 | 
			
		||||
    color: #999;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.is-today .pika-button {
 | 
			
		||||
    color: #33aaff;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.is-selected .pika-button,
 | 
			
		||||
.has-event .pika-button {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    background: #33aaff;
 | 
			
		||||
    box-shadow: inset 0 1px 3px #178fe5;
 | 
			
		||||
    border-radius: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.has-event .pika-button {
 | 
			
		||||
    background: #005da9;
 | 
			
		||||
    box-shadow: inset 0 1px 3px #0076c9;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.is-disabled .pika-button,
 | 
			
		||||
.is-inrange .pika-button {
 | 
			
		||||
    background: #D5E9F7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.is-startrange .pika-button {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    background: #6CB31D;
 | 
			
		||||
    box-shadow: none;
 | 
			
		||||
    border-radius: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.is-endrange .pika-button {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    background: #33aaff;
 | 
			
		||||
    box-shadow: none;
 | 
			
		||||
    border-radius: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.is-disabled .pika-button {
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
    cursor: default;
 | 
			
		||||
    color: #999;
 | 
			
		||||
    opacity: .3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.is-outside-current-month .pika-button {
 | 
			
		||||
    color: #999;
 | 
			
		||||
    opacity: .3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.is-selection-disabled {
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
    cursor: default;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pika-button:hover,
 | 
			
		||||
.pika-row.pick-whole-week:hover .pika-button {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    background: #ff8000;
 | 
			
		||||
    box-shadow: none;
 | 
			
		||||
    border-radius: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* styling for abbr */
 | 
			
		||||
.pika-table abbr {
 | 
			
		||||
    border-bottom: none;
 | 
			
		||||
    cursor: help;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1257
									
								
								web/public/js/pikaday.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1257
									
								
								web/public/js/pikaday.js
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										56
									
								
								web/public/js/pikaday.theme.css
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										56
									
								
								web/public/js/pikaday.theme.css
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
/**
 | 
			
		||||
 * This theme is an example to show how you can create your own.
 | 
			
		||||
 */
 | 
			
		||||
.pika-single.dark-theme {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    background: #333;
 | 
			
		||||
    border: 1px solid #666;
 | 
			
		||||
    border-bottom-color: #999;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-theme .pika-label {
 | 
			
		||||
    background-color: #333;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-theme .pika-prev,
 | 
			
		||||
.dark-theme .is-rtl .pika-next {
 | 
			
		||||
    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAQAAACGG/bgAAAAQ0lEQVR4Ae3KIQ4AIBTD0N0/IeHGI3UIRA3ut/Zl+ltXc5++htVAmIAwAWECwgSEKbgthEoIlRAqIVRCqINQB9nDgQd7ktwFo6UpWQAAAABJRU5ErkJggg==');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-theme .pika-next,
 | 
			
		||||
.dark-theme .is-rtl .pika-prev {
 | 
			
		||||
    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAQAAACGG/bgAAAAP0lEQVQ4y+3TMQoAMAgEwfwfAvvjTZ1uGzuvHhBPPGczEG+FRqqRaqQaqUaqkX6QBmmjacvQ6qEVTjsh+xizebvlaWptGXZAAAAAAElFTkSuQmCC');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-theme .pika-table th {
 | 
			
		||||
    color: #999;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-theme .pika-button {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    background: #222;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-theme .pika-week {
 | 
			
		||||
    color: #999;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-theme .is-today .pika-button {
 | 
			
		||||
    color: #33aaff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-theme .is-selected .pika-button {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    background: #33aaff;
 | 
			
		||||
    box-shadow: inset 0 1px 3px #178fe5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-theme .is-disabled .pika-button {
 | 
			
		||||
    color: #999;
 | 
			
		||||
    opacity: .3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dark-theme .pika-button:hover {
 | 
			
		||||
    color: #fff !important;
 | 
			
		||||
    background: #ff8000 !important;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								web/public/js/pikaday.triangle.css
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								web/public/js/pikaday.triangle.css
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
/**
 | 
			
		||||
 * This theme is an example to show how you can add triangles to the dropdowns.
 | 
			
		||||
 */
 | 
			
		||||
.triangle-theme .pika-label:after {
 | 
			
		||||
    content:" \25be";
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								web/public/js/semantic.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										11
									
								
								web/public/js/semantic.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								web/public/js/sortable.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								web/public/js/sortable.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										212
									
								
								web/public/js/utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								web/public/js/utils.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,212 @@
 | 
			
		||||
window.teaweb = {
 | 
			
		||||
	set: function (key, value) {
 | 
			
		||||
		localStorage.setItem(key, JSON.stringify(value));
 | 
			
		||||
	},
 | 
			
		||||
	get: function (key) {
 | 
			
		||||
		var item = localStorage.getItem(key);
 | 
			
		||||
		if (item == null || item.length == 0) {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return JSON.parse(item);
 | 
			
		||||
	},
 | 
			
		||||
	getString: function (key) {
 | 
			
		||||
		var value = this.get(key);
 | 
			
		||||
		if (typeof (value) == "string") {
 | 
			
		||||
			return value;
 | 
			
		||||
		}
 | 
			
		||||
		return "";
 | 
			
		||||
	},
 | 
			
		||||
	getBool: function (key) {
 | 
			
		||||
		return Boolean(this.get(key));
 | 
			
		||||
	},
 | 
			
		||||
	remove: function (key) {
 | 
			
		||||
		localStorage.removeItem(key)
 | 
			
		||||
	},
 | 
			
		||||
	match: function (source, keyword) {
 | 
			
		||||
		if (source == null) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		if (keyword == null) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		source = source.trim();
 | 
			
		||||
		keyword = keyword.trim();
 | 
			
		||||
		if (keyword.length == 0) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		if (source.length == 0) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		var pieces = keyword.split(/\s+/);
 | 
			
		||||
		for (var i = 0; i < pieces.length; i++) {
 | 
			
		||||
			var pattern = pieces[i];
 | 
			
		||||
			pattern = pattern.replace(/(\+|\*|\?|[|]|{|}|\||\\|\(|\)|\.)/g, "\\$1");
 | 
			
		||||
			var reg = new RegExp(pattern, "i");
 | 
			
		||||
			if (!reg.test(source)) {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	datepicker: function (element, callback) {
 | 
			
		||||
		if (typeof (element) == "string") {
 | 
			
		||||
			element = document.getElementById(element);
 | 
			
		||||
		}
 | 
			
		||||
		var year = new Date().getFullYear();
 | 
			
		||||
		var picker = new Pikaday({
 | 
			
		||||
			field: element,
 | 
			
		||||
			firstDay: 1,
 | 
			
		||||
			minDate: new Date(year - 1, 0, 1),
 | 
			
		||||
			maxDate: new Date(year + 10, 11, 31),
 | 
			
		||||
			yearRange: [year - 1, year + 10],
 | 
			
		||||
			format: "YYYY-MM-DD",
 | 
			
		||||
			i18n: {
 | 
			
		||||
				previousMonth: '上月',
 | 
			
		||||
				nextMonth: '下月',
 | 
			
		||||
				months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
 | 
			
		||||
				weekdays: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
 | 
			
		||||
				weekdaysShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
 | 
			
		||||
			},
 | 
			
		||||
			theme: 'triangle-theme',
 | 
			
		||||
			onSelect: function () {
 | 
			
		||||
				if (typeof (callback) == "function") {
 | 
			
		||||
					callback.call(Tea.Vue, picker.toString());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	formatBytes: function (bytes) {
 | 
			
		||||
		bytes = Math.ceil(bytes);
 | 
			
		||||
		if (bytes < 1024) {
 | 
			
		||||
			return bytes + " bytes";
 | 
			
		||||
		}
 | 
			
		||||
		if (bytes < 1024 * 1024) {
 | 
			
		||||
			return (Math.ceil(bytes * 100 / 1024) / 100) + " k";
 | 
			
		||||
		}
 | 
			
		||||
		return (Math.ceil(bytes * 100 / 1024 / 1024) / 100) + " m";
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	popup: function (url, options) {
 | 
			
		||||
		if (options == null) {
 | 
			
		||||
			options = {};
 | 
			
		||||
		}
 | 
			
		||||
		var width = "40em";
 | 
			
		||||
		var height = "20em";
 | 
			
		||||
		window.POPUP_CALLBACK = function () {
 | 
			
		||||
			Swal.close();
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		if (options["width"] != null) {
 | 
			
		||||
			width = options["width"];
 | 
			
		||||
		}
 | 
			
		||||
		if (options["height"] != null) {
 | 
			
		||||
			height = options["height"];
 | 
			
		||||
		}
 | 
			
		||||
		if (typeof (options["callback"]) == "function") {
 | 
			
		||||
			window.POPUP_CALLBACK = function () {
 | 
			
		||||
				Swal.close();
 | 
			
		||||
				options["callback"].apply(window, arguments);
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Swal.fire({
 | 
			
		||||
			html: '<iframe src="' + url + '#popup-' + width + '" style="border:0; width: 100%; height:' + height + '"></iframe>',
 | 
			
		||||
			width: width,
 | 
			
		||||
			padding: "0.5em",
 | 
			
		||||
			showConfirmButton: false,
 | 
			
		||||
			showCloseButton: true,
 | 
			
		||||
			focusConfirm: false
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	popupFinish: function () {
 | 
			
		||||
		if (window.POPUP_CALLBACK != null) {
 | 
			
		||||
			window.POPUP_CALLBACK.apply(window, arguments);
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	isPopup: function () {
 | 
			
		||||
		var hash = window.location.hash;
 | 
			
		||||
		return hash != null && hash.startsWith("#popup");
 | 
			
		||||
	},
 | 
			
		||||
	Swal: function () {
 | 
			
		||||
		return this.isPopup() ? window.parent.Swal : window.Swal;
 | 
			
		||||
	},
 | 
			
		||||
	success: function (message, callback) {
 | 
			
		||||
		var width = "20em";
 | 
			
		||||
		if (message.length > 30) {
 | 
			
		||||
			width = "30em";
 | 
			
		||||
		}
 | 
			
		||||
		Swal.fire({
 | 
			
		||||
			text: message,
 | 
			
		||||
			confirmButtonText: "确定",
 | 
			
		||||
			buttonsStyling: false,
 | 
			
		||||
			icon: "success",
 | 
			
		||||
			customClass: {
 | 
			
		||||
				closeButton: "ui button",
 | 
			
		||||
				cancelButton: "ui button",
 | 
			
		||||
				confirmButton: "ui button primary"
 | 
			
		||||
			},
 | 
			
		||||
			width: width,
 | 
			
		||||
			onAfterClose: function () {
 | 
			
		||||
				if (typeof (callback) == "function") {
 | 
			
		||||
					setTimeout(function () {
 | 
			
		||||
						callback();
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	warn: function (message, callback) {
 | 
			
		||||
		var width = "20em";
 | 
			
		||||
		if (message.length > 30) {
 | 
			
		||||
			width = "30em";
 | 
			
		||||
		}
 | 
			
		||||
		Swal.fire({
 | 
			
		||||
			text: message,
 | 
			
		||||
			confirmButtonText: "确定",
 | 
			
		||||
			buttonsStyling: false,
 | 
			
		||||
			customClass: {
 | 
			
		||||
				closeButton: "ui button",
 | 
			
		||||
				cancelButton: "ui button",
 | 
			
		||||
				confirmButton: "ui button primary"
 | 
			
		||||
			},
 | 
			
		||||
			icon: "warning",
 | 
			
		||||
			width: width,
 | 
			
		||||
			onAfterClose: function () {
 | 
			
		||||
				if (typeof (callback) == "function") {
 | 
			
		||||
					setTimeout(function () {
 | 
			
		||||
						callback();
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	confirm: function (message, callback) {
 | 
			
		||||
		var width = "20em";
 | 
			
		||||
		if (message.length > 30) {
 | 
			
		||||
			width = "30em";
 | 
			
		||||
		}
 | 
			
		||||
		Swal.fire({
 | 
			
		||||
			text: message,
 | 
			
		||||
			confirmButtonText: "确定",
 | 
			
		||||
			cancelButtonText: "取消",
 | 
			
		||||
			showCancelButton: true,
 | 
			
		||||
			showCloseButton: false,
 | 
			
		||||
			buttonsStyling: false,
 | 
			
		||||
			customClass: {
 | 
			
		||||
				closeButton: "ui button",
 | 
			
		||||
				cancelButton: "ui button",
 | 
			
		||||
				confirmButton: "ui button primary"
 | 
			
		||||
			},
 | 
			
		||||
			icon: "warning",
 | 
			
		||||
			width: width,
 | 
			
		||||
			preConfirm: function () {
 | 
			
		||||
				if (typeof (callback) == "function") {
 | 
			
		||||
					callback.call(Tea.Vue);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										10978
									
								
								web/public/js/vue.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10978
									
								
								web/public/js/vue.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										6
									
								
								web/public/js/vue.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								web/public/js/vue.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1155
									
								
								web/public/js/vue.tea.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1155
									
								
								web/public/js/vue.tea.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Reference in New Issue
	
	Block a user