├── .gitignore ├── LICENSE ├── README.md ├── build.go ├── config ├── App.go ├── MySql.go ├── Redis.go ├── Server.go ├── config.go └── file.example │ ├── AppConfig.yaml │ ├── BootLoader.yaml │ ├── MySqlConfig.yaml │ ├── RedisConfig.yaml │ └── ServerConfig.yaml ├── controller ├── ArticleController │ ├── Create.go │ ├── Delete.go │ ├── Get.go │ └── Update.go ├── BookController │ ├── Create.go │ ├── Delete.go │ ├── Get.go │ └── Update.go ├── FolderController │ ├── Create.go │ ├── Delete.go │ ├── Get.go │ └── Update.go └── QiniuController │ └── ImgHandler.go ├── docker ├── Dockerfile ├── README.md ├── docker-compose.yaml └── note-gin │ ├── Dockerfile │ ├── app │ ├── default.conf │ └── dist │ ├── css │ ├── app.83fad599.css │ ├── chunk-f2247ee6.e8ad73e6.css │ └── chunk-vendors.7eff7b90.css │ ├── favicon.ico │ ├── fonts │ ├── element-icons.535877f5.woff │ ├── element-icons.732389de.ttf │ ├── fontello.068ca2b3.ttf │ ├── fontello.8d4a4e6f.woff2 │ ├── fontello.a782baa8.woff │ └── fontello.e73a0647.eot │ ├── img │ └── fontello.9354499c.svg │ ├── index.html │ └── js │ ├── app.18164ccc.js │ ├── app.18164ccc.js.map │ ├── app.6e08aa03.js │ ├── app.6e08aa03.js.map │ ├── chunk-22623979.6ee70ce4.js │ ├── chunk-22623979.6ee70ce4.js.map │ ├── chunk-2d0c08ef.765d6f94.js │ ├── chunk-2d0c08ef.765d6f94.js.map │ ├── chunk-2d0da7c2.72d3377a.js │ ├── chunk-2d0da7c2.72d3377a.js.map │ ├── chunk-2d0ddf23.6aee8312.js │ ├── chunk-2d0ddf23.6aee8312.js.map │ ├── chunk-2d229435.8351435f.js │ ├── chunk-2d229435.8351435f.js.map │ ├── chunk-2d22dd3c.51ac8305.js │ ├── chunk-2d22dd3c.51ac8305.js.map │ ├── chunk-5ad393eb.7bee588b.js │ ├── chunk-5ad393eb.7bee588b.js.map │ ├── chunk-5ad393eb.9aa16d77.js │ ├── chunk-5ad393eb.9aa16d77.js.map │ ├── chunk-61fa93f6.f74629c5.js │ ├── chunk-61fa93f6.f74629c5.js.map │ ├── chunk-f2247ee6.5f14fcfd.js │ ├── chunk-f2247ee6.5f14fcfd.js.map │ ├── chunk-f6b29384.45508bd9.js │ ├── chunk-f6b29384.45508bd9.js.map │ ├── chunk-vendors.cba62fae.js │ └── chunk-vendors.cba62fae.js.map ├── go.mod ├── main.go ├── middleware └── Cors.go ├── models ├── Article.go ├── BaseModel.go ├── Folder.go ├── MyBook.go ├── init.go └── migration.go ├── note-gin【开发环境】.md ├── pkg ├── HttpCode │ ├── HttpMsg.go │ └── code.go ├── QiniuClient │ └── QiniuClient.go ├── RedisClient │ ├── FolderNav.go │ ├── RedisClient.go │ └── RedisHandlerArticle.go ├── logging │ ├── log.log │ └── logging.go └── utils │ ├── ErrReport.go │ ├── SendMail.go │ └── StrToInt.go ├── router ├── ArticleRouter.go ├── BookRouter.go ├── FolderRouter.go ├── QiniuRouter.go └── router.go ├── service ├── ArticleService │ └── Article.go ├── BookService │ └── Book.go ├── FolderService │ └── Folder.go └── QiniuService │ └── Qiniu.go ├── sql └── note-gin-sql.sql ├── test ├── a.txt ├── config_test.go └── model_test.go ├── tmp ├── runner-build.exe └── runner-build.exe~ └── view ├── ArticleView ├── ArticleDetail.go ├── ArticleEditView.go └── ArticleInfo.go ├── FolderView ├── FolderInfo.go └── FolderSelect.go └── common ├── DataList.go ├── FileList.go └── RespBean.go /.gitignore: -------------------------------------------------------------------------------- 1 | build.go 2 | /.idea 3 | go.sum 4 | file 5 | /.gitignore 6 | 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control Rediss, 57 | and issue tracking Rediss that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://github.com/biningo/note-gin) 4 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200228170439491.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4NDI5Mw==,size_16,color_FFFFFF,t_70) 5 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200228170622303.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4NDI5Mw==,size_16,color_FFFFFF,t_70) 6 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200228170455569.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4NDI5Mw==,size_16,color_FFFFFF,t_70) 7 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020022817050670.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4NDI5Mw==,size_16,color_FFFFFF,t_70) 8 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200228170515801.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4NDI5Mw==,size_16,color_FFFFFF,t_70) 9 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200228170528381.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4NDI5Mw==,size_16,color_FFFFFF,t_70) 10 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200228170547784.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4NDI5Mw==,size_16,color_FFFFFF,t_70) 11 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200228170604671.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4NDI5Mw==,size_16,color_FFFFFF,t_70) 12 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200228170654877.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4NDI5Mw==,size_16,color_FFFFFF,t_70) 13 | 14 |
15 | 16 |
17 | 18 | 19 | 20 | -------- 21 | 22 | 23 | 24 | ##### ==============================优美的分割线=============================== 25 | 26 | 27 | 28 | ## ---------------------------更新------------------------------- 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /build.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | ) 8 | 9 | //***将文件编译为Linux文件可执行 10 | 11 | //filepath: 要编译的文件的路径 12 | func build(filepath string) { 13 | _ = os.Setenv("CGO_ENABLED", "0") 14 | _ = os.Setenv("GOARCH", "amd64") 15 | _ = os.Setenv("GOOS", "linux") 16 | 17 | arg := []string{"build", filepath} 18 | if err := exec.Command("go", arg...).Run(); err != nil { 19 | fmt.Println("编译失败:", err) 20 | } else { 21 | fmt.Println("编译成功") 22 | } 23 | } 24 | 25 | func main() { 26 | build(`main.go`) 27 | } 28 | -------------------------------------------------------------------------------- /config/App.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "gopkg.in/yaml.v2" 5 | "io/ioutil" 6 | "log" 7 | ) 8 | 9 | type App struct { 10 | PageSize int `yaml:"PageSize"` 11 | MakeMigration bool `yaml:"MakeMigration"` //是否进行数据库迁移 12 | QiniuAccessKey string `yaml:"QiniuAccessKey"` 13 | QiniuSecretKey string `yaml:"QiniuSecretKey"` 14 | LogFilePath string `yaml:"LogFilePath"` 15 | } 16 | 17 | func (app *App) DefaultAppConfig() { 18 | app.PageSize = 13 19 | app.QiniuAccessKey = "" 20 | app.QiniuSecretKey = "" 21 | app.MakeMigration=false 22 | app.LogFilePath = "panic.log" 23 | } 24 | 25 | func (app *App) InitAppConfig(path string) { 26 | app.DefaultAppConfig() 27 | file, _ := ioutil.ReadFile(path) 28 | if err := yaml.Unmarshal(file, app); err != nil { 29 | log.Println("ERROR", err) 30 | } 31 | if app.PageSize<=0{ 32 | app.PageSize=13 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /config/MySql.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "gopkg.in/yaml.v2" 5 | "io/ioutil" 6 | "log" 7 | ) 8 | 9 | type MySql struct { 10 | Addr string `yaml:"Addr"` 11 | Port string `yaml:"Port"` 12 | UserName string `yaml:"UserName"` 13 | PassWord string `yaml:"PassWord"` 14 | DataBaseName string `yaml:"DataBaseName"` 15 | } 16 | 17 | func (mysql *MySql) DefaultmySqlConfig() { 18 | mysql.Addr = "localhost" 19 | mysql.Port = "3306" 20 | mysql.DataBaseName = "" 21 | mysql.UserName = "" 22 | mysql.PassWord = "" 23 | } 24 | 25 | func (mysql *MySql) InitmySqlConfig(path string) { 26 | mysql.DefaultmySqlConfig() 27 | file, _ := ioutil.ReadFile(path) 28 | if err := yaml.Unmarshal(file, mysql); err != nil { 29 | log.Println("ERROR", err) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /config/Redis.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "gopkg.in/yaml.v2" 5 | "io/ioutil" 6 | "log" 7 | ) 8 | 9 | type Redis struct { 10 | Addr string `yaml:"Addr"` 11 | Port string `yaml:"Port"` 12 | PassWord string `yaml:"PassWord"` 13 | DataBaseNumber int `yaml:"DataBaseNumber"` 14 | } 15 | 16 | func (redis *Redis) DefaultRedisConfig() { 17 | redis.Addr = "localhost" 18 | redis.Port = "6379" 19 | redis.DataBaseNumber = 0 20 | redis.PassWord = "" 21 | } 22 | 23 | func (redis *Redis) InitRedisConfig(path string) { 24 | redis.DefaultRedisConfig() 25 | file, _ := ioutil.ReadFile(path) 26 | if err := yaml.Unmarshal(file, redis); err != nil { 27 | log.Println("ERROR", err) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /config/Server.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | yaml "gopkg.in/yaml.v2" 5 | "io/ioutil" 6 | "log" 7 | ) 8 | 9 | type Server struct { 10 | Host string `yaml:"Host"` 11 | Port string `yaml:"Port"` 12 | RunMode string `yaml:"RunMode"` 13 | } 14 | 15 | func (server *Server) DefaultServerConfig() { 16 | server.Host = "localhost" 17 | server.Port = "9000" 18 | server.RunMode = "release" 19 | } 20 | 21 | func (server *Server) InitServerConfig(path string) { 22 | server.DefaultServerConfig() 23 | file, _ := ioutil.ReadFile(path) 24 | if err := yaml.Unmarshal(file, server); err != nil { 25 | log.Println("ERROR", err) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "flag" 5 | yaml "gopkg.in/yaml.v2" 6 | "io/ioutil" 7 | "log" 8 | ) 9 | 10 | var Conf Config 11 | 12 | //启动 go run main.go -c config/file/BootLoader.yaml 13 | func SetUp() { 14 | var ConfigPath string 15 | flag.StringVar(&ConfigPath, "c", "", "配置文件路径") 16 | flag.Parse() 17 | //log.Println(ConfigPath) 18 | Conf = NewConfig(ConfigPath) 19 | } 20 | 21 | //总配置对象 22 | type Config struct { 23 | //存放各个配置文件的路径 Path 24 | Cfp configFilePath 25 | 26 | //各个配置模块 27 | RedisConfig Redis 28 | MySqlConfig MySql 29 | ServerConfig Server 30 | AppConfig App 31 | } 32 | 33 | //根据命令行输入的BootLoader.yaml路径 创建Config 同时根据BootLoader.yaml配置的其他文件路径初始化其他模块配置 34 | //Config像一个抓手 找到其他文件路径并初始化配置 35 | func NewConfig(path string) Config { 36 | var config Config 37 | config.Cfp = NewconfigFilePath(path) 38 | 39 | config.RedisConfig.InitRedisConfig(config.Cfp.RedisPath) 40 | config.AppConfig.InitAppConfig(config.Cfp.AppPath) 41 | config.ServerConfig.InitServerConfig(config.Cfp.ServerPath) 42 | config.MySqlConfig.InitmySqlConfig(config.Cfp.MySqlPath) 43 | 44 | return config 45 | } 46 | 47 | //该struct保存了各个模块的配置文件路径 48 | type configFilePath struct { 49 | ServerPath string `yaml:"ServerPath"` 50 | MySqlPath string `yaml:"MySqlPath"` 51 | RedisPath string `yaml:"RedisPath"` 52 | AppPath string `yaml:"AppPath"` 53 | } 54 | 55 | //创建 configFilePath 56 | func NewconfigFilePath(path string) configFilePath { 57 | Cfp := configFilePath{} 58 | file, _ := ioutil.ReadFile(path) 59 | if err := yaml.Unmarshal(file, &Cfp); err != nil { 60 | log.Println("ERROR", err) 61 | } 62 | return Cfp 63 | } 64 | -------------------------------------------------------------------------------- /config/file.example/AppConfig.yaml: -------------------------------------------------------------------------------- 1 | PageSize: 13 2 | MakeMigration: false 3 | QiniuAccessKey: Wdlsdsada-dadsasdsadagacdadssa4T 4 | QiniuSecretKey: HdadadsadsadsadsasdadsA 5 | LogFilePath: pkg/logging/log.log 6 | -------------------------------------------------------------------------------- /config/file.example/BootLoader.yaml: -------------------------------------------------------------------------------- 1 | AppPath: config/file.example/AppConfig.yaml 2 | ServerPath: config/file.example/ServerConfig.yaml 3 | MySqlPath: config/file.example/MySqlConfig.yaml 4 | RedisPath: config/file.example/RedisConfig.yaml -------------------------------------------------------------------------------- /config/file.example/MySqlConfig.yaml: -------------------------------------------------------------------------------- 1 | Addr: localhost 2 | Port: 3306 3 | DataBaseName: note 4 | UserName: root 5 | PassWord: 12345 6 | -------------------------------------------------------------------------------- /config/file.example/RedisConfig.yaml: -------------------------------------------------------------------------------- 1 | Addr: localhost 2 | Port: 6379 3 | DataBaseNumber: 1 4 | PassWord: 12345 5 | -------------------------------------------------------------------------------- /config/file.example/ServerConfig.yaml: -------------------------------------------------------------------------------- 1 | Host: localhost 2 | Port: 9000 3 | RunMode: debug 4 | -------------------------------------------------------------------------------- /controller/ArticleController/Create.go: -------------------------------------------------------------------------------- 1 | package ArticleController 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/pkg/HttpCode" 6 | "note-gin/pkg/logging" 7 | "note-gin/service/ArticleService" 8 | "note-gin/view/ArticleView" 9 | "note-gin/view/common" 10 | ) 11 | 12 | func Add(c *gin.Context) { 13 | articleEditView := ArticleView.ArticleEditView{} 14 | err := c.ShouldBind(&articleEditView) 15 | logging.Error(err.Error()) 16 | ArticleService.Add(&articleEditView) 17 | c.JSON(HttpCode.SUCCESS, common.OkWithData("文章创建成功!", articleEditView)) 18 | } 19 | 20 | //上传md 21 | func UploadArticle(c *gin.Context) { 22 | c.Request.ParseMultipartForm(32 << 20) 23 | folder_title := c.GetHeader("Folder-Title") 24 | file_name := "" 25 | 26 | isExist, ERROR := ArticleService.UploadArticle(c.Request.MultipartForm.File, folder_title, &file_name) 27 | 28 | if ERROR != nil && ERROR.Error() == HttpCode.HttpMsg[HttpCode.ERROR_FILE_TYPE] { 29 | c.JSON(200, common.RespBean{ 30 | Code: HttpCode.ERROR_FILE_TYPE, //客户端为满足条件 31 | Msg: HttpCode.HttpMsg[HttpCode.ERROR_FILE_TYPE], 32 | Data: nil, 33 | }) 34 | return 35 | } 36 | 37 | if isExist != true { 38 | c.JSON(HttpCode.SUCCESS, common.OkWithMsg("添加成功:"+file_name)) 39 | } else { 40 | c.JSON(HttpCode.FILE_IS_EXIST_AND_UPDATE, common.RespBean{ 41 | Code: 412, 42 | Msg: "文件 " + file_name + " 已经存在;" + ERROR.Error(), //文件已经更新的警告 43 | Data: nil, 44 | }) 45 | } 46 | return 47 | } 48 | -------------------------------------------------------------------------------- /controller/ArticleController/Delete.go: -------------------------------------------------------------------------------- 1 | package ArticleController 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/pkg/HttpCode" 6 | "note-gin/service/ArticleService" 7 | "note-gin/view/common" 8 | ) 9 | 10 | func Delete(c *gin.Context) { 11 | ID := ArticleService.Delete(c.Query("id")) 12 | c.JSON(HttpCode.SUCCESS, common.OkWithData("成功移动到垃圾箱 定期清除哟!", ID)) 13 | } 14 | 15 | //清空垃圾桶 16 | func ClearRubbish(c *gin.Context) { 17 | ArticleService.ClearRubbish() 18 | c.JSON(HttpCode.SUCCESS, common.OkWithMsg("清空成功!")) 19 | } 20 | -------------------------------------------------------------------------------- /controller/ArticleController/Get.go: -------------------------------------------------------------------------------- 1 | package ArticleController 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gin-gonic/gin" 6 | "io" 7 | "note-gin/pkg/HttpCode" 8 | "note-gin/pkg/utils" 9 | "note-gin/service/ArticleService" 10 | "note-gin/view/ArticleView" 11 | "note-gin/view/common" 12 | "strings" 13 | ) 14 | 15 | func DeleteMany(c *gin.Context) { 16 | ArticleService.DeleteMany(c.QueryArray("items[]")) 17 | c.JSON(200, common.OkWithMsg("删除成功!")) 18 | } 19 | 20 | func GetArticleByPage(c *gin.Context) { 21 | page := utils.StrToInt(c.Param("page")) 22 | articleInfos, total := ArticleService.GetArticleByPage(page) 23 | c.JSON(200, common.DataList{ 24 | Items: articleInfos, 25 | Total: int64(total), 26 | }) 27 | } 28 | 29 | //显示文章请求 30 | func GetArticleDetail(c *gin.Context) { 31 | articleDetail := ArticleService.GetArticleDetail(c.Param("id")) 32 | c.JSON(HttpCode.SUCCESS, articleDetail) 33 | } 34 | 35 | func GetRubbishArticles(c *gin.Context) { 36 | respDataList := ArticleService.GetRubbishArticles() 37 | c.JSON(HttpCode.SUCCESS, respDataList) 38 | } 39 | 40 | //垃圾箱恢复 41 | func ArticleRecover(c *gin.Context) { 42 | err := ArticleService.ArticleRecover(c.Query("id")) 43 | if err != nil { 44 | c.JSON(HttpCode.ERROR_RECOVER, common.ErrorWithMsg(HttpCode.HttpMsg[HttpCode.ERROR_RECOVER])) 45 | } else { 46 | c.JSON(200, common.OkWithMsg("恢复成功!")) 47 | } 48 | } 49 | 50 | //编辑器临时草稿保存 51 | func TempArticleEditSave(c *gin.Context) { 52 | articleEditView := ArticleView.ArticleEditView{} 53 | err := c.ShouldBind(&articleEditView) 54 | utils.ErrReport(err) 55 | flag := ArticleService.TempArticleEditSave(articleEditView) 56 | if flag { 57 | c.JSON(HttpCode.SUCCESS, common.OkWithMsg("文章暂存草稿箱,1天后失效!")) 58 | } else { 59 | c.JSON(HttpCode.ERROR_TEMP_SAVE, common.OkWithMsg(HttpCode.HttpMsg[HttpCode.ERROR_TEMP_SAVE])) 60 | } 61 | } 62 | 63 | func TempArticleEditGet(c *gin.Context) { 64 | 65 | if articleEditView, ok := ArticleService.TempArticleEditGet(); ok { 66 | c.JSON(200, common.OkWithData("", articleEditView)) 67 | } else { 68 | c.JSON(200, common.OkWithData("获取失败", articleEditView)) 69 | } 70 | } 71 | 72 | func TempArticleEditDelete(c *gin.Context) { 73 | flag := ArticleService.TempArticleEditDelete() 74 | if flag == 1 { 75 | c.JSON(200, common.OkWithMsg("清除成功!")) 76 | } else { 77 | c.JSON(200, common.OkWithMsg("清除失败:"+string(flag))) 78 | } 79 | } 80 | 81 | func ArticleDownLoad(c *gin.Context) { 82 | filename, MkValue := ArticleService.ArticleDownLoad(c.Param("id")) 83 | //文件命名 84 | c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename)) 85 | c.Writer.Header().Add("Content-Type", "application/octet-stream") 86 | io.Copy(c.Writer, strings.NewReader(MkValue)) 87 | } 88 | 89 | //编辑按钮点击后请求到编辑器 90 | func Edit(c *gin.Context) { 91 | articleEditView := ArticleView.ArticleEditView{} 92 | err := c.ShouldBindUri(&articleEditView) 93 | utils.ErrReport(err) 94 | ArticleService.Edit(&articleEditView) 95 | c.JSON(HttpCode.SUCCESS, common.OkWithData("", articleEditView)) 96 | } 97 | -------------------------------------------------------------------------------- /controller/ArticleController/Update.go: -------------------------------------------------------------------------------- 1 | package ArticleController 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/pkg/HttpCode" 6 | "note-gin/pkg/logging" 7 | "note-gin/service/ArticleService" 8 | "note-gin/view/ArticleView" 9 | "note-gin/view/common" 10 | ) 11 | 12 | //设置blog 13 | func SetTag(c *gin.Context) { 14 | articleInfo := ArticleView.ArticleInfo{} 15 | _ = c.ShouldBind(&articleInfo) 16 | ArticleService.SetTag(articleInfo) 17 | return 18 | } 19 | 20 | func Update(c *gin.Context) { 21 | articleEditView := ArticleView.ArticleEditView{} 22 | err := c.ShouldBind(&articleEditView) 23 | logging.Error(err.Error()) 24 | ArticleService.Update(&articleEditView) 25 | c.JSON(HttpCode.SUCCESS, common.OkWithData("文章保存成功!", articleEditView)) 26 | } 27 | -------------------------------------------------------------------------------- /controller/BookController/Create.go: -------------------------------------------------------------------------------- 1 | package BookController 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/models" 6 | "note-gin/pkg/HttpCode" 7 | "note-gin/pkg/logging" 8 | "note-gin/pkg/utils" 9 | "note-gin/view/common" 10 | ) 11 | 12 | func AddBook(c *gin.Context) { 13 | book := models.MyBook{} 14 | err := c.ShouldBind(&book) 15 | logging.Error(err.Error()) 16 | book.Add() 17 | c.JSON(HttpCode.SUCCESS, common.OkWithData("添加成功!", book)) 18 | } 19 | 20 | func UpdateBook(c *gin.Context) { 21 | book := models.MyBook{} 22 | err := c.ShouldBind(&book) 23 | utils.ErrReport(err) 24 | book.Save() 25 | c.JSON(HttpCode.SUCCESS, common.OkWithMsg("修改成功!")) 26 | } 27 | -------------------------------------------------------------------------------- /controller/BookController/Delete.go: -------------------------------------------------------------------------------- 1 | package BookController 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/models" 6 | "note-gin/pkg/utils" 7 | "note-gin/view/common" 8 | ) 9 | 10 | func DeleteBook(c *gin.Context) { 11 | book := models.MyBook{} 12 | book.ID = int64(utils.StrToInt(c.Param("id"))) 13 | book.Delete() 14 | c.JSON(200, common.OkWithMsg("删除成功!")) 15 | } 16 | -------------------------------------------------------------------------------- /controller/BookController/Get.go: -------------------------------------------------------------------------------- 1 | package BookController 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/models" 6 | "note-gin/view/common" 7 | ) 8 | 9 | //Book 10 | func GetAllBook(c *gin.Context) { 11 | books := models.MyBook{}.GetAll() 12 | c.JSON(200, common.DataList{ 13 | Items: books, 14 | Total: int64(len(books)), 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /controller/BookController/Update.go: -------------------------------------------------------------------------------- 1 | package BookController 2 | -------------------------------------------------------------------------------- /controller/FolderController/Create.go: -------------------------------------------------------------------------------- 1 | package FolderController 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/service/FolderService" 6 | "note-gin/view/common" 7 | ) 8 | 9 | func Add(c *gin.Context) { 10 | Title := c.Query("title") 11 | FatherTitle := c.Query("FatherTitle") 12 | 13 | FolderService.Add(Title, FatherTitle) 14 | c.JSON(200, common.OkWithMsg("目录创建成功!")) 15 | } 16 | -------------------------------------------------------------------------------- /controller/FolderController/Delete.go: -------------------------------------------------------------------------------- 1 | package FolderController 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/service/FolderService" 6 | "note-gin/view/common" 7 | ) 8 | 9 | func Delete(c *gin.Context) { 10 | id:=c.Query("id") 11 | ID:=FolderService.Delete(id) 12 | c.JSON(200, common.OkWithData("删除目录成功!",ID)) 13 | } 14 | -------------------------------------------------------------------------------- /controller/FolderController/Get.go: -------------------------------------------------------------------------------- 1 | package FolderController 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/pkg/RedisClient" 6 | "note-gin/pkg/utils" 7 | "note-gin/service/FolderService" 8 | "note-gin/view/common" 9 | ) 10 | 11 | func GetCurrentNav(c *gin.Context) { 12 | nav := RedisClient.GetCurrentNav() 13 | nav = append(nav, "Home") 14 | c.JSON(200, common.OkWithData("", nav)) 15 | } 16 | 17 | func GetSubFile(c *gin.Context) { 18 | page := c.Param("page") 19 | folder_title := c.Query("title") 20 | folderInfos, articleInfos, total := FolderService.GetSubFile(folder_title, utils.StrToInt(page)) 21 | //导航 22 | nav := FolderService.ChangeNav(page, folder_title) 23 | resp := common.FileList{ 24 | Folders: folderInfos, 25 | Articles: articleInfos, 26 | Nav: nav, 27 | Total: total, 28 | } 29 | c.JSON(200, resp) 30 | } 31 | 32 | //编辑区目录的懒加载请求 33 | func GetSubFolders(c *gin.Context) { 34 | id := c.Param("id") 35 | folderSelectList := FolderService.GetSubFolders(id) 36 | c.JSON(200, common.OkWithData("", folderSelectList)) 37 | } 38 | -------------------------------------------------------------------------------- /controller/FolderController/Update.go: -------------------------------------------------------------------------------- 1 | package FolderController 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/pkg/HttpCode" 6 | "note-gin/pkg/logging" 7 | "note-gin/service/FolderService" 8 | "note-gin/view/FolderView" 9 | "note-gin/view/common" 10 | ) 11 | 12 | func Update(c *gin.Context) { 13 | folderInfo:=FolderView.FolderInfo{} 14 | err := c.ShouldBind(&folderInfo) 15 | if err!=nil{ 16 | logging.Error(err.Error()) 17 | } 18 | FolderService.Update(folderInfo) 19 | c.JSON(HttpCode.SUCCESS, common.OkWithMsg("修改成功!")) 20 | } 21 | -------------------------------------------------------------------------------- /controller/QiniuController/ImgHandler.go: -------------------------------------------------------------------------------- 1 | package QiniuController 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "fmt" 7 | "github.com/gin-gonic/gin" 8 | "github.com/qiniu/api.v7/v7/auth/qbox" 9 | "github.com/qiniu/api.v7/v7/storage" 10 | "io/ioutil" 11 | "log" 12 | "note-gin/pkg/QiniuClient" 13 | "note-gin/view/common" 14 | ) 15 | 16 | var accessKey = QiniuClient.QiniuAccessKey 17 | var secretKey = QiniuClient.QiniuSecretKey 18 | var bucket = "note-gin" 19 | 20 | func ImgUpload(c *gin.Context) { 21 | 22 | fileUp, _ := c.FormFile("img") 23 | file, _ := fileUp.Open() 24 | 25 | putPolicy := storage.PutPolicy{ 26 | Scope: bucket, 27 | } 28 | mac := qbox.NewMac(accessKey, secretKey) 29 | upToken := putPolicy.UploadToken(mac) 30 | 31 | cfg := storage.Config{} 32 | // 空间对应的机房 33 | cfg.Zone = &storage.ZoneHuanan 34 | // 是否使用https域名 35 | cfg.UseHTTPS = false 36 | // 上传是否使用CDN上传加速 37 | cfg.UseCdnDomains = false 38 | resumeUploader := storage.NewFormUploader(&cfg) 39 | ret := storage.PutRet{} 40 | putExtra := storage.PutExtra{} 41 | bucket = "note-gin" 42 | key := fileUp.Filename 43 | data := []byte{} 44 | 45 | manager := storage.NewBucketManager(mac, &cfg) 46 | FileInfo, err := manager.Stat(bucket, key) 47 | if FileInfo.Fsize != 0 { //图片存在 48 | url := "http://gin-note.binnb.top/" + key 49 | c.JSON(200, common.OkWithData("图片已经存在!", url)) 50 | return 51 | } 52 | 53 | data, _ = ioutil.ReadAll(file) 54 | dataLen := int64(len(data)) 55 | err = resumeUploader.Put(context.Background(), &ret, upToken, key, bytes.NewReader(data), dataLen, &putExtra) 56 | if err != nil { 57 | fmt.Println(err) 58 | return 59 | } 60 | 61 | url := "http://gin-note.binnb.top/" + key 62 | log.Println("上传图片:", url) 63 | c.JSON(200, common.OkWithData("图片上传成功!", url)) 64 | } 65 | 66 | func ImgDelete(c *gin.Context) { 67 | 68 | mac := qbox.NewMac(accessKey, secretKey) 69 | cfg := storage.Config{ 70 | // 是否使用https域名进行资源管理 71 | UseHTTPS: false, 72 | } 73 | // 指定空间所在的区域,如果不指定将自动探测 74 | // 如果没有特殊需求,默认不需要指定 75 | //cfg.Zone=&storage.ZoneHuabei 76 | bucketManager := storage.NewBucketManager(mac, &cfg) 77 | 78 | bucket := "note-gin" 79 | key := c.Query("img_name") 80 | 81 | err := bucketManager.Delete(bucket, key) 82 | if err != nil { 83 | c.JSON(200, common.ErrorWithMsg("云存储图片删除失败!")) 84 | } else { 85 | c.JSON(200, common.OkWithMsg("云存储图片删除成功!")) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | EXPOSE 9000 3 | WORKDIR "/note-gin" 4 | COPY ./note-gin/* ./ 5 | RUN ["mkdir","config","log"] 6 | RUN ["mv","file","config/"] 7 | RUN ["touch","./log/log.log"] 8 | CMD ["./app","-c","config/file/BootLoader.yaml"] 9 | 10 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | ## 生产环境Docker部署教程 2 | 3 | ### 1、使用七牛图片存储 4 | 5 | 注意,要使用七牛图片存储的话需要在 `config/AppConfig.yaml` 加上下面两个字段 `QiniuAccessKey` `QiniuSecretKey` ,当然为了不泄露自己的密钥,我这里就取消这两个配置,**不影响运行** 6 | 7 | ```yaml 8 | PageSize: 13 9 | MakeMigration: false 10 | QiniuAccessKey: #这两个 11 | QiniuSecretKey: #这个 12 | LogFilePath: pkg/logging/log.log 13 | JwtSecretKey: "note-gin" 14 | ``` 15 | 16 |
17 | 18 | ## 2、关于Docker注意的点 19 | 20 | axios在请求后端资源的时候,发出的http请求其实是在宿主机层面的,不是在容器层面的,所以请求需要发送到后端docker容器在宿主机射影的地址上 21 | 22 | -------------------------------------------------------------------------------- /docker/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | redis: 4 | image: 'redis' 5 | container_name: 'redis' 6 | ports: 7 | - "6379:6379" 8 | restart: 'always' 9 | mysql: 10 | image: 'mysql' 11 | container_name: 'mysql' 12 | ports: 13 | - "3306:3306" 14 | command: --default-authentication-plugin=mysql_native_password 15 | environment: 16 | MYSQL_ROOT_PASSWORD: '55555' 17 | MYSQL_DATABASE: 'note' 18 | restart: 'always' 19 | note-gin: 20 | container_name: "note-gin" 21 | build: . 22 | image: 'note-gin' 23 | ports: 24 | - "9000:9000" 25 | depends_on: 26 | - redis 27 | - mysql 28 | restart: 'always' 29 | note-vue: 30 | container_name: "note-vue" 31 | build: 32 | context: ./note-gin 33 | dockerfile: Dockerfile 34 | image: 'note-vue' 35 | ports: 36 | - "8000:80" 37 | depends_on: 38 | - note-gin 39 | restart: 'always' 40 | -------------------------------------------------------------------------------- /docker/note-gin/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | COPY ./dist /usr/share/nginx/html 3 | COPY ./default.conf /etc/nginx/conf.d/ 4 | -------------------------------------------------------------------------------- /docker/note-gin/app: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/docker/note-gin/app -------------------------------------------------------------------------------- /docker/note-gin/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | listen [::]:80; 4 | server_name localhost; 5 | 6 | #charset koi8-r; 7 | #access_log /var/log/nginx/host.access.log main; 8 | client_max_body_size 100m; 9 | location / { 10 | root /usr/share/nginx/html; 11 | index index.html index.htm; 12 | } 13 | location /api/ { 14 | proxy_pass http://note-gin:9000/; 15 | } 16 | #error_page 404 /404.html; 17 | 18 | # redirect server error pages to the static page /50x.html 19 | # 20 | error_page 500 502 503 504 /50x.html; 21 | location = /50x.html { 22 | root /usr/share/nginx/html; 23 | } 24 | 25 | # proxy the PHP scripts to Apache listening on 127.0.0.1:80 26 | # 27 | #location ~ \.php$ { 28 | # proxy_pass http://127.0.0.1; 29 | #} 30 | 31 | # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 32 | # 33 | #location ~ \.php$ { 34 | # root html; 35 | # fastcgi_pass 127.0.0.1:9000; 36 | # fastcgi_index index.php; 37 | # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; 38 | # include fastcgi_params; 39 | #} 40 | 41 | # deny access to .htaccess files, if Apache's document root 42 | # concurs with nginx's one 43 | # 44 | #location ~ /\.ht { 45 | # deny all; 46 | #} 47 | } 48 | 49 | -------------------------------------------------------------------------------- /docker/note-gin/dist/css/app.83fad599.css: -------------------------------------------------------------------------------- 1 | .card{background-color:#fff;-webkit-box-shadow:0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);box-shadow:0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);border-radius:4px;display:inline-block;margin-right:4%;margin-top:20%;vertical-align:top}.card span{font-size:12px;color:#00bfff;display:block;letter-spacing:2px;padding:30px 20px} -------------------------------------------------------------------------------- /docker/note-gin/dist/css/chunk-f2247ee6.e8ad73e6.css: -------------------------------------------------------------------------------- 1 | .avatar-uploader .el-upload[data-v-36e84422]{border:1px dashed #d9d9d9;border-radius:6px;cursor:pointer;position:relative;overflow:hidden}.avatar-uploader .el-upload[data-v-36e84422]:hover{border-color:#409eff}.avatar-uploader-icon[data-v-36e84422]{font-size:28px;color:#8c939d;width:178px;height:178px;line-height:178px;text-align:center}.avatar[data-v-36e84422]{width:178px;height:178px;display:block} -------------------------------------------------------------------------------- /docker/note-gin/dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/docker/note-gin/dist/favicon.ico -------------------------------------------------------------------------------- /docker/note-gin/dist/fonts/element-icons.535877f5.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/docker/note-gin/dist/fonts/element-icons.535877f5.woff -------------------------------------------------------------------------------- /docker/note-gin/dist/fonts/element-icons.732389de.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/docker/note-gin/dist/fonts/element-icons.732389de.ttf -------------------------------------------------------------------------------- /docker/note-gin/dist/fonts/fontello.068ca2b3.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/docker/note-gin/dist/fonts/fontello.068ca2b3.ttf -------------------------------------------------------------------------------- /docker/note-gin/dist/fonts/fontello.8d4a4e6f.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/docker/note-gin/dist/fonts/fontello.8d4a4e6f.woff2 -------------------------------------------------------------------------------- /docker/note-gin/dist/fonts/fontello.a782baa8.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/docker/note-gin/dist/fonts/fontello.a782baa8.woff -------------------------------------------------------------------------------- /docker/note-gin/dist/fonts/fontello.e73a0647.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/docker/note-gin/dist/fonts/fontello.e73a0647.eot -------------------------------------------------------------------------------- /docker/note-gin/dist/img/fontello.9354499c.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Copyright (C) 2017 by original authors @ fontello.com 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /docker/note-gin/dist/index.html: -------------------------------------------------------------------------------- 1 | note-vue
-------------------------------------------------------------------------------- /docker/note-gin/dist/js/app.18164ccc.js: -------------------------------------------------------------------------------- 1 | (function(e){function n(n){for(var r,a,u=n[0],i=n[1],l=n[2],d=0,s=[];d\r\n
\r\n\r\n \r\n
\r\n Article\r\n
\r\n
\r\n\r\n\r\n \r\n
\r\n MyBook\r\n
\r\n\r\n\r\n
\r\n\r\n\r\n\r\n\r\n\r\n
\r\n\r\n\r\n\r\n\r\n","import mod from \"-!../../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../../node_modules/thread-loader/dist/cjs.js!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../../node_modules/thread-loader/dist/cjs.js!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./home.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./home.vue?vue&type=template&id=10ac907a&scoped=true&\"\nimport script from \"./home.vue?vue&type=script&lang=js&\"\nexport * from \"./home.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"10ac907a\",\n null\n \n)\n\nexport default component.exports"],"sourceRoot":""} -------------------------------------------------------------------------------- /docker/note-gin/dist/js/chunk-2d0da7c2.72d3377a.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0da7c2"],{"6c98":function(t,e,n){"use strict";n.r(e);var a=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("el-row",{directives:[{name:"loading",rawName:"v-loading",value:t.loading2,expression:"loading2"}],staticStyle:{padding:"2%"}},[t._l(t.books,(function(e){return n("el-col",{key:e.id,staticStyle:{padding:"1%","margin-right":"8px"},attrs:{span:3}},[n("el-badge",{attrs:{value:e.status,type:t.GetTypeUI(e.status)}},[n("el-card",{attrs:{"body-style":{padding:"0px"},shadow:"hover"}},[n("img",{staticStyle:{height:"180px",width:"100%"},attrs:{src:e.img_url}}),n("div",{staticStyle:{padding:"3px",height:"40px",overflow:"auto"}},[n("el-link",{staticStyle:{"font-weight":"bolder","font-family":"隶书"}},[t._v(t._s(e.title))]),n("el-link",{attrs:{underline:!1,type:"info"}},[t._v(t._s(e.writer))])],1)])],1)],1)})),0==t.books.length?n("center",[n("i",{staticClass:"el-icon-edit",staticStyle:{"margin-top":"10%","font-size":"50px"}}),n("span",{staticStyle:{"font-family":"楷体","font-size":"30px"}},[t._v(" 空空如也")])]):t._e()],2)],1)},i=[],s=n("1bab"),o={name:"my",mounted:function(){var t=this;this.loading2=!0,Object(s["a"])({url:"/my/book/get/all"}).then((function(e){t.books=e.data.items,t.loading2=!1}))},data:function(){return{loading2:!1,books:[]}},methods:{GetTypeUI:function(t){switch(console.log(t),t){case"a在读":return"primary";case"b想读":return"danger";case"c读过":return"success"}},GetStatusUI:function(t){return 1==t?"success":2==t?"warning":"info"}},computed:{}},l=o,r=n("2877"),c=Object(r["a"])(l,a,i,!1,null,"79f44dbc",null);e["default"]=c.exports}}]); 2 | //# sourceMappingURL=chunk-2d0da7c2.72d3377a.js.map -------------------------------------------------------------------------------- /docker/note-gin/dist/js/chunk-2d0da7c2.72d3377a.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///./src/pages/Book/book.vue?dc45","webpack:///src/pages/Book/book.vue","webpack:///./src/pages/Book/book.vue?5794","webpack:///./src/pages/Book/book.vue"],"names":["render","_vm","this","_h","$createElement","_c","_self","directives","name","rawName","value","expression","staticStyle","_l","i","key","id","attrs","status","GetTypeUI","img_url","_v","_s","title","writer","books","length","staticClass","_e","staticRenderFns","component"],"mappings":"yHAAA,IAAIA,EAAS,WAAa,IAAIC,EAAIC,KAASC,EAAGF,EAAIG,eAAmBC,EAAGJ,EAAIK,MAAMD,IAAIF,EAAG,OAAOE,EAAG,MAAM,CAACA,EAAG,SAAS,CAACE,WAAW,CAAC,CAACC,KAAK,UAAUC,QAAQ,YAAYC,MAAOT,EAAY,SAAEU,WAAW,aAAaC,YAAY,CAAC,QAAU,OAAO,CAACX,EAAIY,GAAIZ,EAAS,OAAE,SAASa,GAAG,OAAOT,EAAG,SAAS,CAACU,IAAID,EAAEE,GAAGJ,YAAY,CAAC,QAAU,KAAK,eAAe,OAAOK,MAAM,CAAC,KAAO,IAAI,CAACZ,EAAG,WAAW,CAACY,MAAM,CAAC,MAAQH,EAAEI,OAAO,KAAOjB,EAAIkB,UAAUL,EAAEI,UAAU,CAACb,EAAG,UAAU,CAACY,MAAM,CAAC,aAAa,CAAC,QAAU,OAAO,OAAS,UAAU,CAACZ,EAAG,MAAM,CAACO,YAAY,CAAC,OAAS,QAAQ,MAAQ,QAAQK,MAAM,CAAC,IAAMH,EAAEM,WAAWf,EAAG,MAAM,CAACO,YAAY,CAAC,QAAU,MAAM,OAAS,OAAO,SAAW,SAAS,CAACP,EAAG,UAAU,CAACO,YAAY,CAAC,cAAc,SAAS,cAAc,OAAO,CAACX,EAAIoB,GAAGpB,EAAIqB,GAAGR,EAAES,UAAUlB,EAAG,UAAU,CAACY,MAAM,CAAC,WAAY,EAAM,KAAO,SAAS,CAAChB,EAAIoB,GAAGpB,EAAIqB,GAAGR,EAAEU,YAAY,MAAM,IAAI,MAAwB,GAAlBvB,EAAIwB,MAAMC,OAAWrB,EAAG,SAAS,CAACA,EAAG,IAAI,CAACsB,YAAY,eAAef,YAAY,CAAC,aAAa,MAAM,YAAY,UAAUP,EAAG,OAAO,CAACO,YAAY,CAAC,cAAc,KAAK,YAAY,SAAS,CAACX,EAAIoB,GAAG,aAAapB,EAAI2B,MAAM,IAAI,IACnkCC,EAAkB,G,YC6CtB,GACE,KAAF,KACE,QAFF,WAEI,IAAJ,OACI,KAAJ,YACI,OAAJ,OAAI,CAAJ,CACM,IAAN,qBACA,kBACM,EAAN,mBACM,EAAN,gBAKE,KAAF,WACI,MAAJ,CACM,UAAN,EACM,MAAN,KAGE,QAAF,CACI,UADJ,SACA,GAEM,OADA,QAAN,OACA,GACQ,IAAR,MACU,MAAV,UACQ,IAAR,MACU,MAAV,SACQ,IAAR,MACU,MAAV,YAGI,YAZJ,SAYA,GACM,OAAN,KACA,UACA,KACA,UAEA,SAKE,SAAF,ICxF6V,I,YCOzVC,EAAY,eACd,EACA9B,EACA6B,GACA,EACA,KACA,WACA,MAIa,aAAAC,E","file":"js/chunk-2d0da7c2.72d3377a.js","sourcesContent":["var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_c('el-row',{directives:[{name:\"loading\",rawName:\"v-loading\",value:(_vm.loading2),expression:\"loading2\"}],staticStyle:{\"padding\":\"2%\"}},[_vm._l((_vm.books),function(i){return _c('el-col',{key:i.id,staticStyle:{\"padding\":\"1%\",\"margin-right\":\"8px\"},attrs:{\"span\":3}},[_c('el-badge',{attrs:{\"value\":i.status,\"type\":_vm.GetTypeUI(i.status)}},[_c('el-card',{attrs:{\"body-style\":{'padding':'0px'},\"shadow\":\"hover\"}},[_c('img',{staticStyle:{\"height\":\"180px\",\"width\":\"100%\"},attrs:{\"src\":i.img_url}}),_c('div',{staticStyle:{\"padding\":\"3px\",\"height\":\"40px\",\"overflow\":\"auto\"}},[_c('el-link',{staticStyle:{\"font-weight\":\"bolder\",\"font-family\":\"隶书\"}},[_vm._v(_vm._s(i.title))]),_c('el-link',{attrs:{\"underline\":false,\"type\":\"info\"}},[_vm._v(_vm._s(i.writer))])],1)])],1)],1)}),(_vm.books.length==0)?_c('center',[_c('i',{staticClass:\"el-icon-edit\",staticStyle:{\"margin-top\":\"10%\",\"font-size\":\"50px\"}}),_c('span',{staticStyle:{\"font-family\":\"楷体\",\"font-size\":\"30px\"}},[_vm._v(\" 空空如也\")])]):_vm._e()],2)],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\r\n\r\n\r\n\r\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./book.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./book.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./book.vue?vue&type=template&id=79f44dbc&scoped=true&\"\nimport script from \"./book.vue?vue&type=script&lang=js&\"\nexport * from \"./book.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"79f44dbc\",\n null\n \n)\n\nexport default component.exports"],"sourceRoot":""} -------------------------------------------------------------------------------- /docker/note-gin/dist/js/chunk-2d0ddf23.6aee8312.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0ddf23"],{"840a":function(e,a,n){"use strict";n.r(a);var t=function(){var e=this,a=e.$createElement,n=e._self._c||a;return n("div",[n("el-row",{staticStyle:{padding:"1%"}},[n("router-view")],1)],1)},r=[],c={name:"manage"},i=c,u=n("2877"),d=Object(u["a"])(i,t,r,!1,null,"ef8a23aa",null);a["default"]=d.exports}}]); 2 | //# sourceMappingURL=chunk-2d0ddf23.6aee8312.js.map -------------------------------------------------------------------------------- /docker/note-gin/dist/js/chunk-2d0ddf23.6aee8312.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///./src/pages/manage/manage.vue?e9fe","webpack:///src/pages/manage/manage.vue","webpack:///./src/pages/manage/manage.vue?ef83","webpack:///./src/pages/manage/manage.vue"],"names":["render","_vm","this","_h","$createElement","_c","_self","staticStyle","staticRenderFns","component"],"mappings":"yHAAA,IAAIA,EAAS,WAAa,IAAIC,EAAIC,KAASC,EAAGF,EAAIG,eAAmBC,EAAGJ,EAAIK,MAAMD,IAAIF,EAAG,OAAOE,EAAG,MAAM,CAACA,EAAG,SAAS,CAACE,YAAY,CAAC,QAAU,OAAO,CAACF,EAAG,gBAAgB,IAAI,IACzKG,EAAkB,GCatB,GACE,KAAF,UCf+V,I,YCO3VC,EAAY,eACd,EACAT,EACAQ,GACA,EACA,KACA,WACA,MAIa,aAAAC,E","file":"js/chunk-2d0ddf23.6aee8312.js","sourcesContent":["var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_c('el-row',{staticStyle:{\"padding\":\"1%\"}},[_c('router-view')],1)],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\r\n\r\n\r\n\r\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manage.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./manage.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./manage.vue?vue&type=template&id=ef8a23aa&scoped=true&\"\nimport script from \"./manage.vue?vue&type=script&lang=js&\"\nexport * from \"./manage.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"ef8a23aa\",\n null\n \n)\n\nexport default component.exports"],"sourceRoot":""} -------------------------------------------------------------------------------- /docker/note-gin/dist/js/chunk-2d229435.8351435f.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d229435"],{dd65:function(e,t,a){"use strict";a.r(t);var i=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{directives:[{name:"loading",rawName:"v-loading.fullscreen.lock",value:e.loading,expression:"loading",modifiers:{fullscreen:!0,lock:!0}}],staticStyle:{"padding-left":"1%"},attrs:{"element-loading-text":"拼命加载中","element-loading-spinner":"el-icon-loading","element-loading-background":"rgba(0, 0, 0, 0.8)"}},[a("el-col",{staticStyle:{"padding-right":"1%"},attrs:{span:21}},[a("el-row",[a("div",{staticStyle:{"text-align":"center","margin-bottom":"1%","margin-top":"1%","font-size":"30px"}},[a("el-input",{attrs:{placeholder:"标题"},model:{value:e.article.title,callback:function(t){e.$set(e.article,"title",t)},expression:"article.title"}})],1)]),a("el-row",[a("mavon-editor",{ref:"md",staticStyle:{height:"700px"},attrs:{ishljs:!0},on:{imgAdd:e.ImgAdd,imgDel:e.ImgDel,save:e.Save},model:{value:e.article.mkValue,callback:function(t){e.$set(e.article,"mkValue",t)},expression:"article.mkValue"}})],1),a("el-row",{staticStyle:{"text-align":"center"}},[a("el-link",{attrs:{type:"success"}},[e._v("感谢使用")])],1)],1),a("el-col",{staticStyle:{"padding-top":"2%"},attrs:{span:3}},[a("div",{staticStyle:{"text-align":"center"}},[e._v(" 创建日期: "),a("i",{staticClass:"el-icon-date",staticStyle:{color:"deepskyblue"}},[e._v(e._s(e.article.created_at))]),a("br"),e._v(" 最近更新: "),a("i",{staticClass:"el-icon-date",staticStyle:{color:"orange"}},[e._v(e._s(e.article.updated_at))])]),a("el-divider"),a("div",[e._v(" 目录: "),a("el-cascader",{attrs:{filterable:"",props:e.props,options:e.options,clearable:""},model:{value:e.article.dir_path,callback:function(t){e.$set(e.article,"dir_path",t)},expression:"article.dir_path"}})],1),a("el-divider"),a("div",{staticStyle:{"text-align":"center"}},[a("el-button",{attrs:{type:"success"},on:{click:e.FinishSave}},[e._v("保存文章")]),a("el-link",{on:{click:e.DeleteCache}},[e._v("清空")])],1)],1)],1)},l=[],s=(a("b0c0"),a("1bab")),n={name:"write",components:{},mounted:function(){var e=this;this.$route.params.article?this.article=this.$route.params.article:(this.loading=!0,Object(s["a"])({url:"/article/temp_get"}).then((function(t){e.article=t.data.data,e.loading=!1})))},beforeDestroy:function(){var e=this;0!==this.article.id&&null!=this.article.id&&Object(s["a"])({url:"/article/temp_save",method:"post",data:this.article}).then((function(t){e.$message({type:"warning",message:t.data.msg})}))},data:function(){return{loading:!1,options:[],props:{checkStrictly:!0,lazy:!0,lazyLoad:function(e,t){Object(s["a"])({url:"/folder/sub_folder",params:{id:e.value}}).then((function(e){t(e.data.data)}))}},article:{id:null,created_at:"0-0-0-0",updated_at:"0-0-0-0",title:"无标题",dir_path:[],mkValue:"",folder_id:0}}},methods:{FinishSave:function(){var e=this;this.loading=!0,this.article.mkValue=this.$refs.md.$data.d_value,Object(s["a"])({method:"post",url:"/article/update",data:this.article}).then((function(t){e.$message({type:"success",message:t.data.msg}),e.article=t.data.data,e.loading=!1}))},Save:function(e){var t=this;this.article.mkValue=e,this.loading=!0,Object(s["a"])({url:"/article/update",method:"post",data:this.article}).then((function(e){t.$message({type:"success",message:e.data.msg}),t.article=e.data.data,t.loading=!1})).catch((function(e){console.log(e)}))},ImgAdd:function(e,t){var a=this;console.log(t);var i=new FormData;i.append("img",t),this.loading=!0,Object(s["a"])({headers:{"Content-Type":"multipart/form-data"},method:"post",url:"/qiniu/img_upload",data:i}).then((function(t){a.$message({type:"success",message:t.data.msg}),a.$refs.md.$img2Url(e,t.data.data),a.loading=!1})).catch((function(e){a.$message({type:"error",message:e})}))},ImgDel:function(e){var t=this;this.loading=!0,Object(s["a"])({url:"/qiniu/img_delete",params:{img_name:e[1].name}}).then((function(e){500==e.data.code?t.$message({type:"error",message:e.data.msg}):t.$message({type:"success",message:e.data.msg}),t.loading=!1}))},DeleteCache:function(){var e=this;Object(s["a"])({url:"/article/temp_delete"}).then((function(t){e.$message({type:"success",message:t.data.msg}),e.article={id:null,created_at:null,updated_at:null,title:"无标题",dir_path:[],mkValue:"",folder_id:0}}))}}},c=n,r=a("2877"),d=Object(r["a"])(c,i,l,!1,null,"2775cc5c",null);t["default"]=d.exports}}]); 2 | //# sourceMappingURL=chunk-2d229435.8351435f.js.map -------------------------------------------------------------------------------- /docker/note-gin/dist/js/chunk-2d229435.8351435f.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///./src/pages/write/write.vue?1800","webpack:///src/pages/write/write.vue","webpack:///./src/pages/write/write.vue?7099","webpack:///./src/pages/write/write.vue"],"names":["render","_vm","this","_h","$createElement","_c","_self","directives","name","rawName","value","expression","modifiers","staticStyle","attrs","model","article","callback","$$v","$set","ref","on","ImgAdd","ImgDel","Save","_v","staticClass","_s","created_at","updated_at","props","options","FinishSave","DeleteCache","staticRenderFns","component"],"mappings":"uHAAA,IAAIA,EAAS,WAAa,IAAIC,EAAIC,KAASC,EAAGF,EAAIG,eAAmBC,EAAGJ,EAAIK,MAAMD,IAAIF,EAAG,OAAOE,EAAG,MAAM,CAACE,WAAW,CAAC,CAACC,KAAK,UAAUC,QAAQ,4BAA4BC,MAAOT,EAAW,QAAEU,WAAW,UAAUC,UAAU,CAAC,YAAa,EAAK,MAAO,KAAQC,YAAY,CAAC,eAAe,MAAMC,MAAM,CAAC,uBAAuB,QAAQ,0BAA0B,kBAAkB,6BAA6B,uBAAuB,CAACT,EAAG,SAAS,CAACQ,YAAY,CAAC,gBAAgB,MAAMC,MAAM,CAAC,KAAO,KAAK,CAACT,EAAG,SAAS,CAACA,EAAG,MAAM,CAACQ,YAAY,CAAC,aAAa,SAAS,gBAAgB,KAAK,aAAa,KAAK,YAAY,SAAS,CAACR,EAAG,WAAW,CAACS,MAAM,CAAC,YAAc,MAAMC,MAAM,CAACL,MAAOT,EAAIe,QAAa,MAAEC,SAAS,SAAUC,GAAMjB,EAAIkB,KAAKlB,EAAIe,QAAS,QAASE,IAAMP,WAAW,oBAAoB,KAAKN,EAAG,SAAS,CAACA,EAAG,eAAe,CAACe,IAAI,KAAKP,YAAY,CAAC,OAAS,SAASC,MAAM,CAAC,QAAS,GAAMO,GAAG,CAAC,OAASpB,EAAIqB,OAAO,OAASrB,EAAIsB,OAAO,KAAOtB,EAAIuB,MAAMT,MAAM,CAACL,MAAOT,EAAIe,QAAe,QAAEC,SAAS,SAAUC,GAAMjB,EAAIkB,KAAKlB,EAAIe,QAAS,UAAWE,IAAMP,WAAW,sBAAsB,GAAGN,EAAG,SAAS,CAACQ,YAAY,CAAC,aAAa,WAAW,CAACR,EAAG,UAAU,CAACS,MAAM,CAAC,KAAO,YAAY,CAACb,EAAIwB,GAAG,WAAW,IAAI,GAAGpB,EAAG,SAAS,CAACQ,YAAY,CAAC,cAAc,MAAMC,MAAM,CAAC,KAAO,IAAI,CAACT,EAAG,MAAM,CAACQ,YAAY,CAAC,aAAa,WAAW,CAACZ,EAAIwB,GAAG,WAAWpB,EAAG,IAAI,CAACqB,YAAY,eAAeb,YAAY,CAAC,MAAQ,gBAAgB,CAACZ,EAAIwB,GAAGxB,EAAI0B,GAAG1B,EAAIe,QAAQY,eAAevB,EAAG,MAAMJ,EAAIwB,GAAG,WAAWpB,EAAG,IAAI,CAACqB,YAAY,eAAeb,YAAY,CAAC,MAAQ,WAAW,CAACZ,EAAIwB,GAAGxB,EAAI0B,GAAG1B,EAAIe,QAAQa,iBAAiBxB,EAAG,cAAcA,EAAG,MAAM,CAACJ,EAAIwB,GAAG,SAASpB,EAAG,cAAc,CAACS,MAAM,CAAC,WAAa,GAAG,MAAQb,EAAI6B,MAAM,QAAU7B,EAAI8B,QAAQ,UAAY,IAAIhB,MAAM,CAACL,MAAOT,EAAIe,QAAgB,SAAEC,SAAS,SAAUC,GAAMjB,EAAIkB,KAAKlB,EAAIe,QAAS,WAAYE,IAAMP,WAAW,uBAAuB,GAAGN,EAAG,cAAcA,EAAG,MAAM,CAACQ,YAAY,CAAC,aAAa,WAAW,CAACR,EAAG,YAAY,CAACS,MAAM,CAAC,KAAO,WAAWO,GAAG,CAAC,MAAQpB,EAAI+B,aAAa,CAAC/B,EAAIwB,GAAG,UAAUpB,EAAG,UAAU,CAACgB,GAAG,CAAC,MAAQpB,EAAIgC,cAAc,CAAChC,EAAIwB,GAAG,SAAS,IAAI,IAAI,IACthES,EAAkB,G,wBC4EtB,GACE,KAAF,QACE,WAAF,GAEE,QAJF,WAII,IAAJ,OACA,2BACM,KAAN,oCAEM,KAAN,WACM,OAAN,OAAM,CAAN,CACQ,IAAR,sBACA,kBACQ,EAAR,oBACQ,EAAR,gBAME,cAnBF,WAmBI,IAAJ,OACA,4CACM,OAAN,OAAM,CAAN,CACQ,IAAR,qBACQ,OAAR,OACQ,KAAR,eACA,kBACQ,EAAR,UACU,KAAV,UACU,QAAV,iBASE,KAAF,WACI,MAAJ,CAEM,SAAN,EAEM,QAAN,GACM,MAAN,CACQ,eAAR,EACQ,MAAR,EACQ,SAHR,SAGA,KAEU,OAAV,OAAU,CAAV,CACY,IAAZ,qBACY,OAAZ,CACc,GAAd,WAGA,kBACY,EAAZ,kBASM,QAAN,CACQ,GAAR,KACQ,WAAR,UACQ,WAAR,UACQ,MAAR,MACQ,SAAR,GACQ,QAAR,GACQ,UAAR,KAQE,QAAF,CAGI,WAHJ,WAGM,IAAN,OACM,KAAN,WACM,KAAN,4CACM,OAAN,OAAM,CAAN,CACQ,OAAR,OACQ,IAAR,kBACQ,KAAR,eACA,kBACQ,EAAR,UACU,KAAV,UACU,QAAV,aAEQ,EAAR,oBACQ,EAAR,eAKI,KArBJ,SAqBA,GAAM,IAAN,OAEM,KAAN,kBACM,KAAN,WAEM,OAAN,OAAM,CAAN,CACQ,IAAR,kBACQ,OAAR,OACQ,KAAR,eACA,kBACQ,EAAR,UACU,KAAV,UACU,QAAV,aAEQ,EAAR,oBACQ,EAAR,cACA,mBACQ,QAAR,WAKI,OA3CJ,SA2CA,KAAM,IAAN,OACM,QAAN,OACM,IAAN,eACM,EAAN,gBACM,KAAN,WACM,OAAN,OAAM,CAAN,CACQ,QAAR,CACU,eAAV,uBAEQ,OAAR,OACQ,IAAR,oBACQ,KAAR,IACA,kBACQ,EAAR,UACU,KAAV,UACU,QAAV,aAGQ,EAAR,iCACQ,EAAR,cAEA,mBACQ,EAAR,UACU,KAAV,QACU,QAAV,QAMI,OAzEJ,SAyEA,GAAM,IAAN,OACM,KAAN,WACM,OAAN,OAAM,CAAN,CACQ,IAAR,oBACQ,OAAR,CACU,SAAV,aAEA,kBACA,iBACU,EAAV,UACY,KAAZ,QACY,QAAZ,aAGU,EAAV,UACY,KAAZ,UACY,QAAZ,aAIQ,EAAR,eAMI,YAnGJ,WAmGM,IAAN,OACM,OAAN,OAAM,CAAN,CACQ,IAAR,yBACA,kBACQ,EAAR,UACU,KAAV,UACU,QAAV,aAEQ,EAAR,SACU,GAAV,KACU,WAAV,KACU,WAAV,KACU,MAAV,MACU,SAAV,GACU,QAAV,GACU,UAAV,SC9Q8V,I,YCO1VC,EAAY,eACd,EACAnC,EACAkC,GACA,EACA,KACA,WACA,MAIa,aAAAC,E","file":"js/chunk-2d229435.8351435f.js","sourcesContent":["var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{directives:[{name:\"loading\",rawName:\"v-loading.fullscreen.lock\",value:(_vm.loading),expression:\"loading\",modifiers:{\"fullscreen\":true,\"lock\":true}}],staticStyle:{\"padding-left\":\"1%\"},attrs:{\"element-loading-text\":\"拼命加载中\",\"element-loading-spinner\":\"el-icon-loading\",\"element-loading-background\":\"rgba(0, 0, 0, 0.8)\"}},[_c('el-col',{staticStyle:{\"padding-right\":\"1%\"},attrs:{\"span\":21}},[_c('el-row',[_c('div',{staticStyle:{\"text-align\":\"center\",\"margin-bottom\":\"1%\",\"margin-top\":\"1%\",\"font-size\":\"30px\"}},[_c('el-input',{attrs:{\"placeholder\":\"标题\"},model:{value:(_vm.article.title),callback:function ($$v) {_vm.$set(_vm.article, \"title\", $$v)},expression:\"article.title\"}})],1)]),_c('el-row',[_c('mavon-editor',{ref:\"md\",staticStyle:{\"height\":\"700px\"},attrs:{\"ishljs\":true},on:{\"imgAdd\":_vm.ImgAdd,\"imgDel\":_vm.ImgDel,\"save\":_vm.Save},model:{value:(_vm.article.mkValue),callback:function ($$v) {_vm.$set(_vm.article, \"mkValue\", $$v)},expression:\"article.mkValue\"}})],1),_c('el-row',{staticStyle:{\"text-align\":\"center\"}},[_c('el-link',{attrs:{\"type\":\"success\"}},[_vm._v(\"感谢使用\")])],1)],1),_c('el-col',{staticStyle:{\"padding-top\":\"2%\"},attrs:{\"span\":3}},[_c('div',{staticStyle:{\"text-align\":\"center\"}},[_vm._v(\" 创建日期: \"),_c('i',{staticClass:\"el-icon-date\",staticStyle:{\"color\":\"deepskyblue\"}},[_vm._v(_vm._s(_vm.article.created_at))]),_c('br'),_vm._v(\" 最近更新: \"),_c('i',{staticClass:\"el-icon-date\",staticStyle:{\"color\":\"orange\"}},[_vm._v(_vm._s(_vm.article.updated_at))])]),_c('el-divider'),_c('div',[_vm._v(\" 目录: \"),_c('el-cascader',{attrs:{\"filterable\":\"\",\"props\":_vm.props,\"options\":_vm.options,\"clearable\":\"\"},model:{value:(_vm.article.dir_path),callback:function ($$v) {_vm.$set(_vm.article, \"dir_path\", $$v)},expression:\"article.dir_path\"}})],1),_c('el-divider'),_c('div',{staticStyle:{\"text-align\":\"center\"}},[_c('el-button',{attrs:{\"type\":\"success\"},on:{\"click\":_vm.FinishSave}},[_vm._v(\"保存文章\")]),_c('el-link',{on:{\"click\":_vm.DeleteCache}},[_vm._v(\"清空\")])],1)],1)],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\r\n\r\n\r\n\r\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./write.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./write.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./write.vue?vue&type=template&id=2775cc5c&scoped=true&\"\nimport script from \"./write.vue?vue&type=script&lang=js&\"\nexport * from \"./write.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"2775cc5c\",\n null\n \n)\n\nexport default component.exports"],"sourceRoot":""} -------------------------------------------------------------------------------- /docker/note-gin/dist/js/chunk-2d22dd3c.51ac8305.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d22dd3c"],{f8c7:function(e,t,a){"use strict";a.r(t);var n=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",[a("el-page-header",{attrs:{content:"Article"},on:{back:e.goBack}}),a("el-divider"),a("el-row",[a("el-button",{attrs:{type:"danger",size:"mini"},on:{click:e.DeleteAll}},[e._v("批量删除")]),a("el-button",{attrs:{size:"mini"}},[e._v("批量下载")]),a("el-table",{directives:[{name:"loading",rawName:"v-loading",value:e.loading,expression:"loading"}],ref:"multipleTable",staticStyle:{width:"100%"},attrs:{data:e.tableData,"tooltip-effect":"dark"},on:{"selection-change":e.handleSelectionChange}},[a("el-table-column",{attrs:{type:"selection",width:"55"}}),a("el-table-column",{attrs:{label:"ID",prop:"id",width:"60"}}),a("el-table-column",{attrs:{label:"日期",width:"100",prop:"updated_at"}}),a("el-table-column",{attrs:{width:""},scopedSlots:e._u([{key:"default",fn:function(t){return[a("el-link",{on:{click:function(a){return e.ShowArticle(t.row)}}},[e._v(e._s(t.row.title))])]}}])}),a("el-table-column",{attrs:{width:""},scopedSlots:e._u([{key:"default",fn:function(t){return[a("el-button",{attrs:{size:"mini"},on:{click:function(a){return e.DownLoad(t.row)}}},[e._v("下载")])]}}])})],1),a("el-pagination",{attrs:{background:"",layout:"prev, pager, next",total:e.Total,"page-size":10,"current-page":e.currentPage},on:{"current-change":e.handleCurrentChange}})],1),a("el-drawer",{staticStyle:{"overflow-y":"auto",width:"60%"},attrs:{title:e.ArticleInfo.title,visible:e.dialogVisible,size:"auto",direction:"ttb"},on:{"update:visible":function(t){e.dialogVisible=t}}},[a("div",{},[a("makedown-show",{attrs:{background:"#F0FFF0","mk-value":e.ArticleInfo.mkValue}})],1)])],1)},l=[],i=(a("d3b7"),a("3ca3"),a("ddb0"),a("2b3d"),a("1bab")),o=a("cde3"),r={components:{makedownShow:o["a"]},mounted:function(){var e=this;this.loading=!0,Object(i["a"])({url:"/article/many/1"}).then((function(t){e.tableData=t.data.items,e.Total=t.data.total,e.loading=!1}))},name:"article",data:function(){return{loading:!1,currentPage:1,Total:1,multipleSelection:[],keywords:"",tableData:[],ArticleInfo:{title:"",mkValue:"",id:null},dialogVisible:!1}},methods:{handleCurrentChange:function(e){var t=this;this.currentPage=e,this.loading=!0,Object(i["a"])({url:"/article/many/"+e}).then((function(e){t.tableData=e.data.items,t.Total=e.data.total,t.loading=!1}))},goBack:function(){this.$router.push("/manage")},handleSelectionChange:function(e){for(var t=[],a=0;a\r\n
\r\n \r\n \r\n \r\n\r\n \r\n批量删除\r\n 批量下载\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n\r\n \r\n \r\n \r\n\r\n\r\n \r\n
\r\n \r\n
\r\n \r\n\r\n
\r\n\r\n\r\n\r\n\r\n","import mod from \"-!../../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../../node_modules/thread-loader/dist/cjs.js!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./article.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../../node_modules/thread-loader/dist/cjs.js!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./article.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./article.vue?vue&type=template&id=edbbd73e&scoped=true&\"\nimport script from \"./article.vue?vue&type=script&lang=js&\"\nexport * from \"./article.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"edbbd73e\",\n null\n \n)\n\nexport default component.exports"],"sourceRoot":""} -------------------------------------------------------------------------------- /docker/note-gin/dist/js/chunk-5ad393eb.7bee588b.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-5ad393eb"],{"0a06":function(e,t,n){"use strict";var r=n("c532"),o=n("30b5"),i=n("f6b4"),s=n("5270"),a=n("4a7b");function u(e){this.defaults=e,this.interceptors={request:new i,response:new i}}u.prototype.request=function(e){"string"===typeof e?(e=arguments[1]||{},e.url=arguments[0]):e=e||{},e=a(this.defaults,e),e.method?e.method=e.method.toLowerCase():this.defaults.method?e.method=this.defaults.method.toLowerCase():e.method="get";var t=[s,void 0],n=Promise.resolve(e);this.interceptors.request.forEach((function(e){t.unshift(e.fulfilled,e.rejected)})),this.interceptors.response.forEach((function(e){t.push(e.fulfilled,e.rejected)}));while(t.length)n=n.then(t.shift(),t.shift());return n},u.prototype.getUri=function(e){return e=a(this.defaults,e),o(e.url,e.params,e.paramsSerializer).replace(/^\?/,"")},r.forEach(["delete","get","head","options"],(function(e){u.prototype[e]=function(t,n){return this.request(r.merge(n||{},{method:e,url:t}))}})),r.forEach(["post","put","patch"],(function(e){u.prototype[e]=function(t,n,o){return this.request(r.merge(o||{},{method:e,url:t,data:n}))}})),e.exports=u},"0df6":function(e,t,n){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}},"1bab":function(e,t,n){"use strict";n.d(t,"a",(function(){return i}));n("d3b7");var r=n("bc3a"),o=n.n(r);function i(e){return new Promise((function(t,n){var r=o.a.create({baseURL:"http://localhost:8000/api",timeout:36e5});r(e).then((function(e){t(e)})).catch((function(e){n(e)}))}))}},"1d2b":function(e,t,n){"use strict";e.exports=function(e,t){return function(){for(var n=new Array(arguments.length),r=0;r=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*"}}};r.forEach(["delete","get","head"],(function(e){u.headers[e]={}})),r.forEach(["post","put","patch"],(function(e){u.headers[e]=r.merge(i)})),e.exports=u}).call(this,n("4362"))},"2d83":function(e,t,n){"use strict";var r=n("387f");e.exports=function(e,t,n,o,i){var s=new Error(e);return r(s,t,n,o,i)}},"2e67":function(e,t,n){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},"30b5":function(e,t,n){"use strict";var r=n("c532");function o(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(r.isURLSearchParams(t))i=t.toString();else{var s=[];r.forEach(t,(function(e,t){null!==e&&"undefined"!==typeof e&&(r.isArray(e)?t+="[]":e=[e],r.forEach(e,(function(e){r.isDate(e)?e=e.toISOString():r.isObject(e)&&(e=JSON.stringify(e)),s.push(o(t)+"="+o(e))})))})),i=s.join("&")}if(i){var a=e.indexOf("#");-1!==a&&(e=e.slice(0,a)),e+=(-1===e.indexOf("?")?"?":"&")+i}return e}},"387f":function(e,t,n){"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e.isAxiosError=!0,e.toJSON=function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code}},e}},3934:function(e,t,n){"use strict";var r=n("c532");e.exports=r.isStandardBrowserEnv()?function(){var e,t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");function o(e){var r=e;return t&&(n.setAttribute("href",r),r=n.href),n.setAttribute("href",r),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:"/"===n.pathname.charAt(0)?n.pathname:"/"+n.pathname}}return e=o(window.location.href),function(t){var n=r.isString(t)?o(t):t;return n.protocol===e.protocol&&n.host===e.host}}():function(){return function(){return!0}}()},4362:function(e,t,n){t.nextTick=function(e){var t=Array.prototype.slice.call(arguments);t.shift(),setTimeout((function(){e.apply(null,t)}),0)},t.platform=t.arch=t.execPath=t.title="browser",t.pid=1,t.browser=!0,t.env={},t.argv=[],t.binding=function(e){throw new Error("No such module. (Possibly not yet loaded)")},function(){var e,r="/";t.cwd=function(){return r},t.chdir=function(t){e||(e=n("df7c")),r=e.resolve(t,r)}}(),t.exit=t.kill=t.umask=t.dlopen=t.uptime=t.memoryUsage=t.uvCounters=function(){},t.features={}},"467f":function(e,t,n){"use strict";var r=n("2d83");e.exports=function(e,t,n){var o=n.config.validateStatus;!o||o(n.status)?e(n):t(r("Request failed with status code "+n.status,n.config,null,n.request,n))}},"4a7b":function(e,t,n){"use strict";var r=n("c532");e.exports=function(e,t){t=t||{};var n={},o=["url","method","params","data"],i=["headers","auth","proxy"],s=["baseURL","url","transformRequest","transformResponse","paramsSerializer","timeout","withCredentials","adapter","responseType","xsrfCookieName","xsrfHeaderName","onUploadProgress","onDownloadProgress","maxContentLength","validateStatus","maxRedirects","httpAgent","httpsAgent","cancelToken","socketPath"];r.forEach(o,(function(e){"undefined"!==typeof t[e]&&(n[e]=t[e])})),r.forEach(i,(function(o){r.isObject(t[o])?n[o]=r.deepMerge(e[o],t[o]):"undefined"!==typeof t[o]?n[o]=t[o]:r.isObject(e[o])?n[o]=r.deepMerge(e[o]):"undefined"!==typeof e[o]&&(n[o]=e[o])})),r.forEach(s,(function(r){"undefined"!==typeof t[r]?n[r]=t[r]:"undefined"!==typeof e[r]&&(n[r]=e[r])}));var a=o.concat(i).concat(s),u=Object.keys(t).filter((function(e){return-1===a.indexOf(e)}));return r.forEach(u,(function(r){"undefined"!==typeof t[r]?n[r]=t[r]:"undefined"!==typeof e[r]&&(n[r]=e[r])})),n}},5270:function(e,t,n){"use strict";var r=n("c532"),o=n("c401"),i=n("2e67"),s=n("2444");function a(e){e.cancelToken&&e.cancelToken.throwIfRequested()}e.exports=function(e){a(e),e.headers=e.headers||{},e.data=o(e.data,e.headers,e.transformRequest),e.headers=r.merge(e.headers.common||{},e.headers[e.method]||{},e.headers),r.forEach(["delete","get","head","post","put","patch","common"],(function(t){delete e.headers[t]}));var t=e.adapter||s.adapter;return t(e).then((function(t){return a(e),t.data=o(t.data,t.headers,e.transformResponse),t}),(function(t){return i(t)||(a(e),t&&t.response&&(t.response.data=o(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)}))}},"7a77":function(e,t,n){"use strict";function r(e){this.message=e}r.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},r.prototype.__CANCEL__=!0,e.exports=r},"7aac":function(e,t,n){"use strict";var r=n("c532");e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,o,i,s){var a=[];a.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&a.push("expires="+new Date(n).toGMTString()),r.isString(o)&&a.push("path="+o),r.isString(i)&&a.push("domain="+i),!0===s&&a.push("secure"),document.cookie=a.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},"83b9":function(e,t,n){"use strict";var r=n("d925"),o=n("e683");e.exports=function(e,t){return e&&!r(t)?o(e,t):t}},"8df4":function(e,t,n){"use strict";var r=n("7a77");function o(e){if("function"!==typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise((function(e){t=e}));var n=this;e((function(e){n.reason||(n.reason=new r(e),t(n.reason))}))}o.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},o.source=function(){var e,t=new o((function(t){e=t}));return{token:t,cancel:e}},e.exports=o},b50d:function(e,t,n){"use strict";var r=n("c532"),o=n("467f"),i=n("30b5"),s=n("83b9"),a=n("c345"),u=n("3934"),c=n("2d83");e.exports=function(e){return new Promise((function(t,f){var p=e.data,l=e.headers;r.isFormData(p)&&delete l["Content-Type"];var d=new XMLHttpRequest;if(e.auth){var h=e.auth.username||"",m=e.auth.password||"";l.Authorization="Basic "+btoa(h+":"+m)}var g=s(e.baseURL,e.url);if(d.open(e.method.toUpperCase(),i(g,e.params,e.paramsSerializer),!0),d.timeout=e.timeout,d.onreadystatechange=function(){if(d&&4===d.readyState&&(0!==d.status||d.responseURL&&0===d.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in d?a(d.getAllResponseHeaders()):null,r=e.responseType&&"text"!==e.responseType?d.response:d.responseText,i={data:r,status:d.status,statusText:d.statusText,headers:n,config:e,request:d};o(t,f,i),d=null}},d.onabort=function(){d&&(f(c("Request aborted",e,"ECONNABORTED",d)),d=null)},d.onerror=function(){f(c("Network Error",e,null,d)),d=null},d.ontimeout=function(){var t="timeout of "+e.timeout+"ms exceeded";e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),f(c(t,e,"ECONNABORTED",d)),d=null},r.isStandardBrowserEnv()){var v=n("7aac"),y=(e.withCredentials||u(g))&&e.xsrfCookieName?v.read(e.xsrfCookieName):void 0;y&&(l[e.xsrfHeaderName]=y)}if("setRequestHeader"in d&&r.forEach(l,(function(e,t){"undefined"===typeof p&&"content-type"===t.toLowerCase()?delete l[t]:d.setRequestHeader(t,e)})),r.isUndefined(e.withCredentials)||(d.withCredentials=!!e.withCredentials),e.responseType)try{d.responseType=e.responseType}catch(b){if("json"!==e.responseType)throw b}"function"===typeof e.onDownloadProgress&&d.addEventListener("progress",e.onDownloadProgress),"function"===typeof e.onUploadProgress&&d.upload&&d.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then((function(e){d&&(d.abort(),f(e),d=null)})),void 0===p&&(p=null),d.send(p)}))}},bc3a:function(e,t,n){e.exports=n("cee4")},c345:function(e,t,n){"use strict";var r=n("c532"),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,i,s={};return e?(r.forEach(e.split("\n"),(function(e){if(i=e.indexOf(":"),t=r.trim(e.substr(0,i)).toLowerCase(),n=r.trim(e.substr(i+1)),t){if(s[t]&&o.indexOf(t)>=0)return;s[t]="set-cookie"===t?(s[t]?s[t]:[]).concat([n]):s[t]?s[t]+", "+n:n}})),s):s}},c401:function(e,t,n){"use strict";var r=n("c532");e.exports=function(e,t,n){return r.forEach(n,(function(n){e=n(e,t)})),e}},c532:function(e,t,n){"use strict";var r=n("1d2b"),o=Object.prototype.toString;function i(e){return"[object Array]"===o.call(e)}function s(e){return"undefined"===typeof e}function a(e){return null!==e&&!s(e)&&null!==e.constructor&&!s(e.constructor)&&"function"===typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function u(e){return"[object ArrayBuffer]"===o.call(e)}function c(e){return"undefined"!==typeof FormData&&e instanceof FormData}function f(e){var t;return t="undefined"!==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer,t}function p(e){return"string"===typeof e}function l(e){return"number"===typeof e}function d(e){return null!==e&&"object"===typeof e}function h(e){return"[object Date]"===o.call(e)}function m(e){return"[object File]"===o.call(e)}function g(e){return"[object Blob]"===o.call(e)}function v(e){return"[object Function]"===o.call(e)}function y(e){return d(e)&&v(e.pipe)}function b(e){return"undefined"!==typeof URLSearchParams&&e instanceof URLSearchParams}function w(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function x(){return("undefined"===typeof navigator||"ReactNative"!==navigator.product&&"NativeScript"!==navigator.product&&"NS"!==navigator.product)&&("undefined"!==typeof window&&"undefined"!==typeof document)}function E(e,t){if(null!==e&&"undefined"!==typeof e)if("object"!==typeof e&&(e=[e]),i(e))for(var n=0,r=e.length;n=0;r--){var o=e[r];"."===o?e.splice(r,1):".."===o?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function r(e){"string"!==typeof e&&(e+="");var t,n=0,r=-1,o=!0;for(t=e.length-1;t>=0;--t)if(47===e.charCodeAt(t)){if(!o){n=t+1;break}}else-1===r&&(o=!1,r=t+1);return-1===r?"":e.slice(n,r)}function o(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r=-1&&!r;i--){var s=i>=0?arguments[i]:e.cwd();if("string"!==typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(t=s+"/"+t,r="/"===s.charAt(0))}return t=n(o(t.split("/"),(function(e){return!!e})),!r).join("/"),(r?"/":"")+t||"."},t.normalize=function(e){var r=t.isAbsolute(e),s="/"===i(e,-1);return e=n(o(e.split("/"),(function(e){return!!e})),!r).join("/"),e||r||(e="."),e&&s&&(e+="/"),(r?"/":"")+e},t.isAbsolute=function(e){return"/"===e.charAt(0)},t.join=function(){var e=Array.prototype.slice.call(arguments,0);return t.normalize(o(e,(function(e,t){if("string"!==typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},t.relative=function(e,n){function r(e){for(var t=0;t=0;n--)if(""!==e[n])break;return t>n?[]:e.slice(t,n-t+1)}e=t.resolve(e).substr(1),n=t.resolve(n).substr(1);for(var o=r(e.split("/")),i=r(n.split("/")),s=Math.min(o.length,i.length),a=s,u=0;u=1;--i)if(t=e.charCodeAt(i),47===t){if(!o){r=i;break}}else o=!1;return-1===r?n?"/":".":n&&1===r?"/":e.slice(0,r)},t.basename=function(e,t){var n=r(e);return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},t.extname=function(e){"string"!==typeof e&&(e+="");for(var t=-1,n=0,r=-1,o=!0,i=0,s=e.length-1;s>=0;--s){var a=e.charCodeAt(s);if(47!==a)-1===r&&(o=!1,r=s+1),46===a?-1===t?t=s:1!==i&&(i=1):-1!==t&&(i=-1);else if(!o){n=s+1;break}}return-1===t||-1===r||0===i||1===i&&t===r-1&&t===n+1?"":e.slice(t,r)};var i="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,n("4362"))},e683:function(e,t,n){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},f6b4:function(e,t,n){"use strict";var r=n("c532");function o(){this.handlers=[]}o.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},o.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},o.prototype.forEach=function(e){r.forEach(this.handlers,(function(t){null!==t&&e(t)}))},e.exports=o}}]); 2 | //# sourceMappingURL=chunk-5ad393eb.7bee588b.js.map -------------------------------------------------------------------------------- /docker/note-gin/dist/js/chunk-5ad393eb.9aa16d77.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-5ad393eb"],{"0a06":function(e,t,n){"use strict";var r=n("c532"),o=n("30b5"),i=n("f6b4"),s=n("5270"),a=n("4a7b");function u(e){this.defaults=e,this.interceptors={request:new i,response:new i}}u.prototype.request=function(e){"string"===typeof e?(e=arguments[1]||{},e.url=arguments[0]):e=e||{},e=a(this.defaults,e),e.method?e.method=e.method.toLowerCase():this.defaults.method?e.method=this.defaults.method.toLowerCase():e.method="get";var t=[s,void 0],n=Promise.resolve(e);this.interceptors.request.forEach((function(e){t.unshift(e.fulfilled,e.rejected)})),this.interceptors.response.forEach((function(e){t.push(e.fulfilled,e.rejected)}));while(t.length)n=n.then(t.shift(),t.shift());return n},u.prototype.getUri=function(e){return e=a(this.defaults,e),o(e.url,e.params,e.paramsSerializer).replace(/^\?/,"")},r.forEach(["delete","get","head","options"],(function(e){u.prototype[e]=function(t,n){return this.request(r.merge(n||{},{method:e,url:t}))}})),r.forEach(["post","put","patch"],(function(e){u.prototype[e]=function(t,n,o){return this.request(r.merge(o||{},{method:e,url:t,data:n}))}})),e.exports=u},"0df6":function(e,t,n){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}},"1bab":function(e,t,n){"use strict";n.d(t,"a",(function(){return i}));n("d3b7");var r=n("bc3a"),o=n.n(r);function i(e){return new Promise((function(t,n){var r=o.a.create({baseURL:"http://localhost:80/api",timeout:36e5});r(e).then((function(e){t(e)})).catch((function(e){n(e)}))}))}},"1d2b":function(e,t,n){"use strict";e.exports=function(e,t){return function(){for(var n=new Array(arguments.length),r=0;r=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*"}}};r.forEach(["delete","get","head"],(function(e){u.headers[e]={}})),r.forEach(["post","put","patch"],(function(e){u.headers[e]=r.merge(i)})),e.exports=u}).call(this,n("4362"))},"2d83":function(e,t,n){"use strict";var r=n("387f");e.exports=function(e,t,n,o,i){var s=new Error(e);return r(s,t,n,o,i)}},"2e67":function(e,t,n){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},"30b5":function(e,t,n){"use strict";var r=n("c532");function o(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(r.isURLSearchParams(t))i=t.toString();else{var s=[];r.forEach(t,(function(e,t){null!==e&&"undefined"!==typeof e&&(r.isArray(e)?t+="[]":e=[e],r.forEach(e,(function(e){r.isDate(e)?e=e.toISOString():r.isObject(e)&&(e=JSON.stringify(e)),s.push(o(t)+"="+o(e))})))})),i=s.join("&")}if(i){var a=e.indexOf("#");-1!==a&&(e=e.slice(0,a)),e+=(-1===e.indexOf("?")?"?":"&")+i}return e}},"387f":function(e,t,n){"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e.isAxiosError=!0,e.toJSON=function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code}},e}},3934:function(e,t,n){"use strict";var r=n("c532");e.exports=r.isStandardBrowserEnv()?function(){var e,t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");function o(e){var r=e;return t&&(n.setAttribute("href",r),r=n.href),n.setAttribute("href",r),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:"/"===n.pathname.charAt(0)?n.pathname:"/"+n.pathname}}return e=o(window.location.href),function(t){var n=r.isString(t)?o(t):t;return n.protocol===e.protocol&&n.host===e.host}}():function(){return function(){return!0}}()},4362:function(e,t,n){t.nextTick=function(e){var t=Array.prototype.slice.call(arguments);t.shift(),setTimeout((function(){e.apply(null,t)}),0)},t.platform=t.arch=t.execPath=t.title="browser",t.pid=1,t.browser=!0,t.env={},t.argv=[],t.binding=function(e){throw new Error("No such module. (Possibly not yet loaded)")},function(){var e,r="/";t.cwd=function(){return r},t.chdir=function(t){e||(e=n("df7c")),r=e.resolve(t,r)}}(),t.exit=t.kill=t.umask=t.dlopen=t.uptime=t.memoryUsage=t.uvCounters=function(){},t.features={}},"467f":function(e,t,n){"use strict";var r=n("2d83");e.exports=function(e,t,n){var o=n.config.validateStatus;!o||o(n.status)?e(n):t(r("Request failed with status code "+n.status,n.config,null,n.request,n))}},"4a7b":function(e,t,n){"use strict";var r=n("c532");e.exports=function(e,t){t=t||{};var n={},o=["url","method","params","data"],i=["headers","auth","proxy"],s=["baseURL","url","transformRequest","transformResponse","paramsSerializer","timeout","withCredentials","adapter","responseType","xsrfCookieName","xsrfHeaderName","onUploadProgress","onDownloadProgress","maxContentLength","validateStatus","maxRedirects","httpAgent","httpsAgent","cancelToken","socketPath"];r.forEach(o,(function(e){"undefined"!==typeof t[e]&&(n[e]=t[e])})),r.forEach(i,(function(o){r.isObject(t[o])?n[o]=r.deepMerge(e[o],t[o]):"undefined"!==typeof t[o]?n[o]=t[o]:r.isObject(e[o])?n[o]=r.deepMerge(e[o]):"undefined"!==typeof e[o]&&(n[o]=e[o])})),r.forEach(s,(function(r){"undefined"!==typeof t[r]?n[r]=t[r]:"undefined"!==typeof e[r]&&(n[r]=e[r])}));var a=o.concat(i).concat(s),u=Object.keys(t).filter((function(e){return-1===a.indexOf(e)}));return r.forEach(u,(function(r){"undefined"!==typeof t[r]?n[r]=t[r]:"undefined"!==typeof e[r]&&(n[r]=e[r])})),n}},5270:function(e,t,n){"use strict";var r=n("c532"),o=n("c401"),i=n("2e67"),s=n("2444");function a(e){e.cancelToken&&e.cancelToken.throwIfRequested()}e.exports=function(e){a(e),e.headers=e.headers||{},e.data=o(e.data,e.headers,e.transformRequest),e.headers=r.merge(e.headers.common||{},e.headers[e.method]||{},e.headers),r.forEach(["delete","get","head","post","put","patch","common"],(function(t){delete e.headers[t]}));var t=e.adapter||s.adapter;return t(e).then((function(t){return a(e),t.data=o(t.data,t.headers,e.transformResponse),t}),(function(t){return i(t)||(a(e),t&&t.response&&(t.response.data=o(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)}))}},"7a77":function(e,t,n){"use strict";function r(e){this.message=e}r.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},r.prototype.__CANCEL__=!0,e.exports=r},"7aac":function(e,t,n){"use strict";var r=n("c532");e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,o,i,s){var a=[];a.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&a.push("expires="+new Date(n).toGMTString()),r.isString(o)&&a.push("path="+o),r.isString(i)&&a.push("domain="+i),!0===s&&a.push("secure"),document.cookie=a.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},"83b9":function(e,t,n){"use strict";var r=n("d925"),o=n("e683");e.exports=function(e,t){return e&&!r(t)?o(e,t):t}},"8df4":function(e,t,n){"use strict";var r=n("7a77");function o(e){if("function"!==typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise((function(e){t=e}));var n=this;e((function(e){n.reason||(n.reason=new r(e),t(n.reason))}))}o.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},o.source=function(){var e,t=new o((function(t){e=t}));return{token:t,cancel:e}},e.exports=o},b50d:function(e,t,n){"use strict";var r=n("c532"),o=n("467f"),i=n("30b5"),s=n("83b9"),a=n("c345"),u=n("3934"),c=n("2d83");e.exports=function(e){return new Promise((function(t,f){var p=e.data,l=e.headers;r.isFormData(p)&&delete l["Content-Type"];var d=new XMLHttpRequest;if(e.auth){var h=e.auth.username||"",m=e.auth.password||"";l.Authorization="Basic "+btoa(h+":"+m)}var g=s(e.baseURL,e.url);if(d.open(e.method.toUpperCase(),i(g,e.params,e.paramsSerializer),!0),d.timeout=e.timeout,d.onreadystatechange=function(){if(d&&4===d.readyState&&(0!==d.status||d.responseURL&&0===d.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in d?a(d.getAllResponseHeaders()):null,r=e.responseType&&"text"!==e.responseType?d.response:d.responseText,i={data:r,status:d.status,statusText:d.statusText,headers:n,config:e,request:d};o(t,f,i),d=null}},d.onabort=function(){d&&(f(c("Request aborted",e,"ECONNABORTED",d)),d=null)},d.onerror=function(){f(c("Network Error",e,null,d)),d=null},d.ontimeout=function(){var t="timeout of "+e.timeout+"ms exceeded";e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),f(c(t,e,"ECONNABORTED",d)),d=null},r.isStandardBrowserEnv()){var v=n("7aac"),y=(e.withCredentials||u(g))&&e.xsrfCookieName?v.read(e.xsrfCookieName):void 0;y&&(l[e.xsrfHeaderName]=y)}if("setRequestHeader"in d&&r.forEach(l,(function(e,t){"undefined"===typeof p&&"content-type"===t.toLowerCase()?delete l[t]:d.setRequestHeader(t,e)})),r.isUndefined(e.withCredentials)||(d.withCredentials=!!e.withCredentials),e.responseType)try{d.responseType=e.responseType}catch(b){if("json"!==e.responseType)throw b}"function"===typeof e.onDownloadProgress&&d.addEventListener("progress",e.onDownloadProgress),"function"===typeof e.onUploadProgress&&d.upload&&d.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then((function(e){d&&(d.abort(),f(e),d=null)})),void 0===p&&(p=null),d.send(p)}))}},bc3a:function(e,t,n){e.exports=n("cee4")},c345:function(e,t,n){"use strict";var r=n("c532"),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,i,s={};return e?(r.forEach(e.split("\n"),(function(e){if(i=e.indexOf(":"),t=r.trim(e.substr(0,i)).toLowerCase(),n=r.trim(e.substr(i+1)),t){if(s[t]&&o.indexOf(t)>=0)return;s[t]="set-cookie"===t?(s[t]?s[t]:[]).concat([n]):s[t]?s[t]+", "+n:n}})),s):s}},c401:function(e,t,n){"use strict";var r=n("c532");e.exports=function(e,t,n){return r.forEach(n,(function(n){e=n(e,t)})),e}},c532:function(e,t,n){"use strict";var r=n("1d2b"),o=Object.prototype.toString;function i(e){return"[object Array]"===o.call(e)}function s(e){return"undefined"===typeof e}function a(e){return null!==e&&!s(e)&&null!==e.constructor&&!s(e.constructor)&&"function"===typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function u(e){return"[object ArrayBuffer]"===o.call(e)}function c(e){return"undefined"!==typeof FormData&&e instanceof FormData}function f(e){var t;return t="undefined"!==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer,t}function p(e){return"string"===typeof e}function l(e){return"number"===typeof e}function d(e){return null!==e&&"object"===typeof e}function h(e){return"[object Date]"===o.call(e)}function m(e){return"[object File]"===o.call(e)}function g(e){return"[object Blob]"===o.call(e)}function v(e){return"[object Function]"===o.call(e)}function y(e){return d(e)&&v(e.pipe)}function b(e){return"undefined"!==typeof URLSearchParams&&e instanceof URLSearchParams}function w(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function x(){return("undefined"===typeof navigator||"ReactNative"!==navigator.product&&"NativeScript"!==navigator.product&&"NS"!==navigator.product)&&("undefined"!==typeof window&&"undefined"!==typeof document)}function E(e,t){if(null!==e&&"undefined"!==typeof e)if("object"!==typeof e&&(e=[e]),i(e))for(var n=0,r=e.length;n=0;r--){var o=e[r];"."===o?e.splice(r,1):".."===o?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function r(e){"string"!==typeof e&&(e+="");var t,n=0,r=-1,o=!0;for(t=e.length-1;t>=0;--t)if(47===e.charCodeAt(t)){if(!o){n=t+1;break}}else-1===r&&(o=!1,r=t+1);return-1===r?"":e.slice(n,r)}function o(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r=-1&&!r;i--){var s=i>=0?arguments[i]:e.cwd();if("string"!==typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(t=s+"/"+t,r="/"===s.charAt(0))}return t=n(o(t.split("/"),(function(e){return!!e})),!r).join("/"),(r?"/":"")+t||"."},t.normalize=function(e){var r=t.isAbsolute(e),s="/"===i(e,-1);return e=n(o(e.split("/"),(function(e){return!!e})),!r).join("/"),e||r||(e="."),e&&s&&(e+="/"),(r?"/":"")+e},t.isAbsolute=function(e){return"/"===e.charAt(0)},t.join=function(){var e=Array.prototype.slice.call(arguments,0);return t.normalize(o(e,(function(e,t){if("string"!==typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},t.relative=function(e,n){function r(e){for(var t=0;t=0;n--)if(""!==e[n])break;return t>n?[]:e.slice(t,n-t+1)}e=t.resolve(e).substr(1),n=t.resolve(n).substr(1);for(var o=r(e.split("/")),i=r(n.split("/")),s=Math.min(o.length,i.length),a=s,u=0;u=1;--i)if(t=e.charCodeAt(i),47===t){if(!o){r=i;break}}else o=!1;return-1===r?n?"/":".":n&&1===r?"/":e.slice(0,r)},t.basename=function(e,t){var n=r(e);return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},t.extname=function(e){"string"!==typeof e&&(e+="");for(var t=-1,n=0,r=-1,o=!0,i=0,s=e.length-1;s>=0;--s){var a=e.charCodeAt(s);if(47!==a)-1===r&&(o=!1,r=s+1),46===a?-1===t?t=s:1!==i&&(i=1):-1!==t&&(i=-1);else if(!o){n=s+1;break}}return-1===t||-1===r||0===i||1===i&&t===r-1&&t===n+1?"":e.slice(t,r)};var i="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,n("4362"))},e683:function(e,t,n){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},f6b4:function(e,t,n){"use strict";var r=n("c532");function o(){this.handlers=[]}o.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},o.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},o.prototype.forEach=function(e){r.forEach(this.handlers,(function(t){null!==t&&e(t)}))},e.exports=o}}]); 2 | //# sourceMappingURL=chunk-5ad393eb.9aa16d77.js.map -------------------------------------------------------------------------------- /docker/note-gin/dist/js/chunk-61fa93f6.f74629c5.js: -------------------------------------------------------------------------------- 1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-61fa93f6"],{"1dde":function(e,t,i){var n=i("d039"),r=i("b622"),o=i("2d00"),l=r("species");e.exports=function(e){return o>=51||!n((function(){var t=[],i=t.constructor={};return i[l]=function(){return{foo:1}},1!==t[e](Boolean).foo}))}},"65f0":function(e,t,i){var n=i("861d"),r=i("e8b5"),o=i("b622"),l=o("species");e.exports=function(e,t){var i;return r(e)&&(i=e.constructor,"function"!=typeof i||i!==Array&&!r(i.prototype)?n(i)&&(i=i[l],null===i&&(i=void 0)):i=void 0),new(void 0===i?Array:i)(0===t?0:t)}},"74e5":function(e,t,i){"use strict";i.r(t);var n=function(){var e=this,t=e.$createElement,i=e._self._c||t;return i("div",[i("top-bar",{on:{ForeverDelete:e.ForeverDelete}}),i("el-row",{directives:[{name:"loading",rawName:"v-loading",value:e.loading,expression:"loading"}],staticStyle:{padding:"2%"},attrs:{"element-loading-text":"拼命加载中","element-loading-spinner":"el-icon-loading"}},[e._l(e.ArticleList,(function(t){return i("rubbish-file",{key:t.id,attrs:{"file-info":t},on:{Recover:e.Recover}})})),0==e.ArticleList.length?i("center",[i("i",{staticClass:"el-icon-edit",staticStyle:{"margin-top":"10%","font-size":"50px"}}),i("span",{staticStyle:{"font-family":"楷体","font-size":"30px"}},[e._v(" 空空如也")])]):e._e()],2)],1)},r=[],o=(i("a434"),function(){var e=this,t=e.$createElement,i=e._self._c||t;return i("div",[i("el-row",[i("el-col",{attrs:{span:18}},[i("el-tooltip",{attrs:{effect:"light",placement:"right"}},[i("div",{attrs:{slot:"content"},slot:"content"},[i("el-link",{attrs:{icon:"el-icon-refresh-right"},on:{click:e.Recover}}),i("el-divider",{attrs:{direction:"vertical"}}),i("el-link",{staticClass:"el-icon-info"})],1),i("el-link",{staticStyle:{"font-weight":"bolder","font-size":"17px"},attrs:{target:"_blank"},on:{click:function(t){e.dialogVisible=!0}}},[i("i",{staticClass:"el-icon-document",staticStyle:{"margin-right":"1px"}}),e._v(" "+e._s(e.FileInfo.title))])],1)],1),i("el-col",{attrs:{span:4}},[i("i",{staticClass:"el-icon-date",staticStyle:{color:"gainsboro"}},[e._v(e._s(e.FileInfo.deleted_time))])])],1),i("el-row",[i("hr",{staticStyle:{border:"0.08em solid lightgoldenrodyellow"}})]),i("el-dialog",{attrs:{title:"提示",visible:e.dialogVisible,width:"90%"},on:{"update:visible":function(t){e.dialogVisible=t}}},[e._v(" "+e._s(e.FileInfo.mkHtml)+" ")])],1)}),l=[],a={name:"RublishFile",props:["FileInfo"],data:function(){return{dialogVisible:!1}},methods:{Recover:function(){this.$emit("Recover",this.FileInfo.id)}}},s=a,c=i("2877"),d=Object(c["a"])(s,o,l,!1,null,"eed387a8",null),u=d.exports,f=function(){var e=this,t=e.$createElement,i=e._self._c||t;return i("div",[i("el-row",{staticStyle:{padding:"1%"}},[i("el-col",{staticStyle:{"padding-top":"6px"},attrs:{span:2}},[i("el-button",{staticClass:"el-icon-delete",attrs:{type:"danger",round:"",size:"mini"},on:{click:e.ForeverDelete}},[e._v("清空")])],1)],1)],1)},p=[],g={name:"TopBar",methods:{ForeverDelete:function(){this.$emit("ForeverDelete")}}},v=g,h=Object(c["a"])(v,f,p,!1,null,"94f104c0",null),b=h.exports,m=i("1bab"),y={name:"rubbish",components:{TopBar:b,RubbishFile:u},mounted:function(){var e=this;this.loading=!0,Object(m["a"])({url:"/article/rubbish"}).then((function(t){e.ArticleList=t.data.items,null==e.ArticleList&&(e.ArticleList=[]),e.Count=t.data.total,e.loading=!1}))},data:function(){return{loading:!1,keywords:"",ArticleList:[],Count:0}},methods:{Recover:function(e){var t=this;this.loading=!0,Object(m["a"])({url:"/article/recover",params:{id:e}}).then((function(i){if(500==i.data.code)t.$message({type:"warning",message:i.data.msg});else{t.$message({type:"success",message:i.data.msg});for(var n=0;nh)throw TypeError(b);for(d=s(m,n),u=0;uy-n+i;u--)delete m[u-1]}else if(i>n)for(u=y-n;u>w;u--)f=u+n-1,p=u+i-1,f in m?m[p]=m[f]:delete m[p];for(u=0;u 0").Delete(&Article{}) 70 | } 71 | 72 | //垃圾箱恢复 73 | func (this Article) Recover() error { 74 | hasFolder := 0 75 | db.First(&this) 76 | db.Table("folder").Where("id=?", this.FolderID).Count(&hasFolder) 77 | 78 | if hasFolder != 0 || this.FolderID == 0 { 79 | db.Table("article").Where("id=?", this.ID).Update("deleted", 0) 80 | return nil 81 | } else { 82 | return errors.New("父目录不存在!恢复失败") 83 | } 84 | } 85 | 86 | func (this Article) IsExist() bool { 87 | c := 0 88 | db.Table("article").Where("title=?", this.Title).Count(&c) 89 | return c > 0 90 | } 91 | -------------------------------------------------------------------------------- /models/BaseModel.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type BaseModel struct { 8 | ID int64 `gorm:"primary_key"` 9 | CreatedAt time.Time 10 | UpdatedAt time.Time 11 | Deleted bool 12 | DeletedTime time.Time 13 | } 14 | 15 | //增 16 | func AddOne(obj interface{}) { 17 | 18 | } 19 | func AddMany(obj []interface{}) { 20 | 21 | } 22 | 23 | //删 24 | func DeleteOne(obj interface{}) { 25 | 26 | } 27 | func DeleteMany(attr map[string]string) { 28 | 29 | } 30 | 31 | //查 32 | func FindOne(obj interface{}) { 33 | 34 | } 35 | func FindByPage(obj interface{}, page int) { 36 | 37 | } 38 | 39 | //改 40 | func Update(attr map[string]string) { 41 | 42 | } 43 | func UpdateMany(obj interface{}, attr map[string]string) { 44 | 45 | } 46 | -------------------------------------------------------------------------------- /models/Folder.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "note-gin/config" 5 | "time" 6 | ) 7 | 8 | var PageSize = config.Conf.AppConfig.PageSize 9 | 10 | type Folder struct { 11 | BaseModel 12 | Title string 13 | FolderID int64 //前一个文件夹 14 | } 15 | 16 | //Find 17 | func (this Folder) GetRootFolder() (roots []Folder) { 18 | db.Find(&roots, "folder_id=?", 0) 19 | return 20 | } 21 | 22 | //目录路径查找[root->sub] 23 | func (this Folder) GetFolderPath(FolderID int64, DirPath *[]int64) { 24 | if FolderID == 0 { 25 | return 26 | } 27 | folder := Folder{} 28 | db.Where("id=?", FolderID).First(&folder) 29 | 30 | if folder.FolderID != 0 { 31 | *DirPath = append([]int64{folder.FolderID}, *DirPath...) 32 | this.GetFolderPath(folder.FolderID, DirPath) 33 | } else { 34 | return 35 | } 36 | } 37 | 38 | func (this Folder) GetFolderByID() { 39 | db.Where("id=?", this.ID).First(&this) 40 | return 41 | } 42 | 43 | func (this Folder) GetSubFile(page int) (fds []Folder, articles []Article, total int) { 44 | if PageSize<=0{ 45 | PageSize=13 46 | } 47 | fds = this.GetSubFolderOnPage(page, PageSize) 48 | total = this.CountSubFile() 49 | fdsCount := len(fds) 50 | if fdsCount < PageSize && fdsCount > 0 { 51 | //page=page-(this.CountSubFolder()/PageSize) page-1=0 52 | articles = this.GetSubArticle(PageSize-fdsCount, 0) 53 | } else if fdsCount == 0 { 54 | SubFolderCount := this.CountSubFolder() 55 | offset := PageSize - (SubFolderCount % PageSize) 56 | page = page - ((SubFolderCount / PageSize) + 1) 57 | articles = this.GetSubArticle(PageSize, offset+(page-1)*PageSize) 58 | } 59 | return 60 | 61 | } 62 | 63 | func (this Folder) GetSubFolders() (folders []Folder) { 64 | db.Table("folder").Where("folder_id=?", this.ID).Find(&folders) 65 | return 66 | } 67 | 68 | func (this Folder) GetSubFolderOnPage(page, PageSize int) (fds []Folder) { 69 | db.Limit(PageSize).Offset((page-1)*PageSize).Find(&fds, "folder_id=?", this.ID) 70 | return 71 | } 72 | 73 | func (this Folder) GetSubArticle(limit, offset int) (articles []Article) { 74 | db.Limit(limit).Offset(offset).Where("deleted=?", 0).Select([]string{"id", "title", "updated_at", "publish_blog"}).Find(&articles, "folder_id=?", this.ID) 75 | return 76 | } 77 | 78 | func (this Folder) GetFolderInfo() { 79 | db.Where(this).First(&this) 80 | } 81 | 82 | func (this Folder) GetFolderByTitle() { 83 | db.Where("title=?", this.Title).First(&this) 84 | } 85 | 86 | //count 87 | func (this Folder) CountSubFile() int { 88 | sum := this.CountSubFolder() + this.CountSubArticle() 89 | return sum 90 | } 91 | 92 | func (this Folder) CountSubFolder() (count int) { 93 | db.Table("folder").Where("folder_id=?", this.ID).Count(&count) 94 | return 95 | } 96 | func (this Folder) CountSubArticle() (count int) { 97 | db.Model(&Article{}).Where("folder_id=? and deleted=?", this.ID, 0).Count(&count) 98 | return 99 | } 100 | 101 | //Create 102 | func (this *Folder) Add() { 103 | db.Create(this) 104 | } 105 | 106 | //Update 107 | func (this *Folder) Update() { 108 | db.Model(this).Where("id=?", this.ID).Updates(map[string]interface{}{"title": this.Title, "updated_at": time.Now()}) 109 | } 110 | 111 | //Delete递归删除 112 | func (this *Folder) Delete() { 113 | db.Delete(this) 114 | deleteDFS(this.ID) 115 | } 116 | func deleteDFS(FolderID int64) { 117 | db.Table("article").Where("folder_id=?", FolderID).Update("deleted", true) 118 | sub_folder := []Folder{} 119 | db.Find(&sub_folder, "folder_id=?", FolderID) 120 | for index := range sub_folder { 121 | sub_folder[index].Delete() 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /models/MyBook.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import "time" 4 | 5 | const ( 6 | Reading = "a在读" 7 | Finish = "b读完" 8 | Plan = "c想读" 9 | ) 10 | 11 | type MyBook struct { 12 | ID int64 `form:"id" json:"id"` 13 | Title string `form:"title" json:"title"` 14 | Writer string `form:"writer" json:"writer"` 15 | ImgURL string `form:"img_url" json:"img_url"` //封面图片 16 | Status string `form:"status" json:"status"` 17 | UpdatedAt time.Time `form:"updated_at" json:"updated_at"` 18 | } 19 | 20 | func (this *MyBook) Add() { 21 | this.UpdatedAt = time.Now() 22 | db.Create(this) 23 | } 24 | 25 | func (this *MyBook) Delete() { 26 | db.Delete(this, "id=?", this.ID) 27 | } 28 | 29 | func (this MyBook) GetAll() (books []MyBook) { 30 | db.Table("my_book").Order("status").Find(&books) 31 | return 32 | } 33 | 34 | func (this *MyBook) Save() { 35 | this.UpdatedAt = time.Now() 36 | db.Save(this) 37 | } 38 | -------------------------------------------------------------------------------- /models/init.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gin-gonic/gin" 6 | _ "github.com/go-sql-driver/mysql" 7 | "github.com/jinzhu/gorm" 8 | "note-gin/config" 9 | ) 10 | 11 | var db *gorm.DB 12 | 13 | func SetUp() { 14 | mySqlConfig := config.Conf.MySqlConfig 15 | //注意添加表情的编码 并且将mysql数据库编码设置好 16 | connStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true", 17 | mySqlConfig.UserName, mySqlConfig.PassWord, mySqlConfig.Addr, mySqlConfig.Port, mySqlConfig.DataBaseName) 18 | 19 | DB, err := gorm.Open("mysql", connStr) 20 | 21 | if err != nil { 22 | panic(err) 23 | } 24 | 25 | //不加s建表 26 | DB.SingularTable(true) 27 | 28 | if gin.Mode() == gin.ReleaseMode { 29 | DB.LogMode(false) 30 | }else if gin.Mode()==gin.DebugMode { 31 | DB.LogMode(true) 32 | } 33 | 34 | if config.Conf.AppConfig.MakeMigration { 35 | migration(DB) //迁移 首次创建数据库需要迁移创建表 36 | } 37 | 38 | db = DB 39 | } 40 | -------------------------------------------------------------------------------- /models/migration.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/jinzhu/gorm" 5 | ) 6 | 7 | func migration(DB *gorm.DB) { 8 | // 自动迁移模式 9 | DB.Set("gorm:table_options", "charset=utf8mb4") 10 | DB.AutoMigrate(&Folder{}). 11 | AutoMigrate(&Article{}). 12 | AutoMigrate(&MyBook{}) 13 | } 14 | -------------------------------------------------------------------------------- /note-gin【开发环境】.md: -------------------------------------------------------------------------------- 1 | ## 开发环境【Goland】 2 | 3 | #### 第一步:安装依赖 4 | 5 | 1. 首先clone项目到本地,用 **goland** 打开,要安装一些依赖,耐心等待一会儿 6 | 7 | > 依赖哪些大家可以看 go.mod 文件 8 | 9 |
10 | 11 | 12 | 13 | ----- 14 | 15 | #### 第二步:寻找配置文件 16 | 17 | 2. 环境准备完毕之后,注意到有一个 `config` 文件夹,里面存放了配置相关的,`config/file.example` 存放了 **yaml** 配置文件,这个配置文件编译后是找不到的,所以需要自己在部署的环境上上传服务器,然后指定文件路径,当然在开发环境下就不用管那么多了 18 | 19 |
20 | 21 | 22 | 23 | ---- 24 | 25 | #### 第三步:环境准备 26 | 27 | 3. 前提是你配置要正确,比如redis有没有装,地址有没有对,mysql数据库名字正不正确等),**注意,刚启动时数据库是没有建立的,需要手动建立数据库,建立一个 名字为 note 数据库 ,本项目的表是用gorm配置的,所以在第一次启动时,需要在 ** ```AppConfig.yaml``` 的 ```MakeMigration: true``` 设置为 **True** ,表示开始迁移表结构。 28 | 29 | **Appconfig.yaml** 30 | 31 | ```yaml 32 | PageSize: 13 #这一项先不用改变 33 | MakeMigration: true #下次启动要设置为false了 如果你要修改表结构 则启动还要设置为true 详情请看gorm文档关于数据库迁移内容 34 | 35 | QiniuAccessKey: xxxx #七牛oss相关配置 36 | QiniuSecretKey: xxxx 37 | LogFilePath: pkg/logging/log.log #这一项删除也没事 就这样也没事 目前还用不到 38 | ``` 39 | 40 |
41 | 42 | > 具体环境如下: 43 | > 44 | > - 七牛oss空间【小流量免费】 如果不需要 直接在 main.go 注释掉 Qiniu.setup() 即可 45 | > - mysql 46 | > - redis 47 | > - 域名 48 | 49 |
50 | 51 |
52 | 53 | 54 | 55 | 56 | 57 | ---- 58 | 59 | #### 第四步:运行main.go 60 | 61 | 4. 下面在 **main.go** 所在的目录下,也就是顶层目录下,运行如下命令(路径和文件都是可以自己修改的) 62 | 63 | **BootLoader.yaml** 记录的是各个模块的配置文件路径(也可以都放在一个配置文件下,笔者觉得这样太混了,所以分开,用 BootLoader.yaml 读取各个配置文件) 64 | 65 | ```bash 66 | go run main.go - c config/file.example/BootLoader.yaml #在win下的goland下跑的话就是这个路径 不用修改 看目录结构就看得出 这是相对路径 67 | ``` 68 | 69 | ```mermaid 70 | graph TB 71 | 读取BootLoader.yaml-->从BootLoader.yaml获取各个模块配置文件的路径 72 | 从BootLoader.yaml获取各个模块配置文件的路径-->根据配置文件路径最后读取到配置 73 | ``` 74 | 75 |
76 | 77 | 78 | 79 |
80 | 81 |
82 | 83 | 84 | 85 | --- 86 | 87 | #### 第五步:验证后端 88 | 89 | 根据配置的端口和主机,比如: 90 | 91 | ```http 92 | localhost:9000/ping 93 | ``` 94 | 95 | 如果返回 ```Pong``` 则表示成功! 96 | 97 |
98 | 99 | 100 | 101 | ---- 102 | 103 | #### 第六步:配置vue前端 104 | 105 | 前端的 ```vue.config.js``` 目录下配置了 node服务器相关的配置 106 | 107 | ```js 108 | module.exports = { 109 | devServer: { 110 | port:9002, #表示前端启动的端口 111 | 112 | proxy: { 113 | '/api': { // 转发路径 114 | target: 'http://localhost:9000', // 后端地址 115 | ws: true, // 是否代理websockets 116 | changeOrigin: true , // 设置同源 默认false,是否需要改变原始主机头为目标URL, 117 | pathRewrite: { 118 | '^/api': '' // 把 '/api/user' 替换为 '/user' 119 | } 120 | } 121 | 122 | } 123 | 124 | 125 | 126 | } 127 | }; 128 | ``` 129 | 130 | ```http 131 | localhost:9002/api/user ---> locahost:9000/user 132 | ``` 133 | 134 | 这就是 **跨域配置** 135 | 136 | 运行命令,然后项目就会以 9002 端口 运行 137 | 138 | ```bash 139 | npm run serve 140 | ``` 141 | 142 |
143 | 144 |
145 | 146 | 147 | 148 | ---- 149 | 150 | #### 第七步:测试前端 151 | 152 | > 注意,要前后端同时开启 153 | 154 | ```http 155 | locahost:9002/ 156 | ``` 157 | 158 | 然后就会看到界面了。 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | ---- 169 | 170 | linux生产环境 编译后 171 | 172 | ```bash 173 | [root@blog www.binnb.top]# ls 174 | main note-gin-cfg 175 | [root@blog www.binnb.top]# ls note-gin-cfg 176 | AppConfig.yaml MySqlConfig.yaml ServerConfig.yaml 177 | BootLoader.yaml RedisConfig.yaml 178 | [root@blog www.binnb.top]# ./main -c note-gin-cfg/BootLoader.yaml 179 | ``` 180 | 181 | **后面的path是在Linux下配置文件的路径 配置文件需要单独上传** 182 | 183 | 下面是```BootLoader.yaml``` 文件的内容,这个内容根据大家配置文件的目录不同可以**自由修改**,只要main能找的到就行 184 | 185 | ```yaml 186 | AppPath: note-gin-cfg/AppConfig.yaml 187 | ServerPath: note-gin-cfg/ServerConfig.yaml 188 | MySqlPath: note-gin-cfg/MySqlConfig.yaml 189 | RedisPath: note-gin-cfg/RedisConfig.yaml 190 | ``` 191 | 192 | 193 | 194 | 下面是我的配置文件,供大家参考,可以自己修改 195 | 196 | pass 197 | 198 | 199 | 200 | 201 | 202 | 编译后的**main**文件在linux下一定要给予执行权限 203 | 204 | ```bash 205 | chmod 777 main 206 | ``` 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | ## 为什么要这样配置 217 | 218 | 1. 部署方便(这也是golang的优势之一,也是我喜欢go的原因之一,毕竟被环境坑过...),如果你换服务器了,只需要带走 main、配置文件这两样东西即可 219 | 2. 升级方便,如数据库升级.... 220 | 3. 移动环境方便 221 | 4. 可以配置多套环境,如开发环境、测试环境、生产环境... 222 | 5. 总之.....没有总之了.... 223 | 224 | 225 | 226 | ## 如何算部署成功 227 | 228 | 浏览器输入(网址,你自己配置的): 229 | 230 | ```http 231 | http://localhost:9000/ping 232 | 返回 233 | Pong 234 | ``` 235 | 236 | 就算成功了 237 | 238 | 239 | 240 | ## 开发环境的跨域问题 241 | 242 | vue-config.js文件 243 | 244 | ```javascript 245 | module.exports = { 246 | devServer: { 247 | port:9002,//npm run serve 启动前端 端口为9002 访问也是这个地址 248 | 249 | //下面是代理转发 axios会用 9002/api/url 这种方式来请求数据 这里将转化为 /9000/url 250 | proxy: { 251 | '/api': { // search为转发路径 252 | target: 'http://localhost:9000', // 后端地址 253 | ws: true, // 是否代理websockets 254 | changeOrigin: true , // 设置同源 默认false,是否需要改变原始主机头为目标URL, 255 | pathRewrite: { 256 | '^/api': '' // 把 '/api/user' 替换为 '/user' 257 | } 258 | } 259 | 260 | } 261 | 262 | 263 | 264 | } 265 | }; 266 | ``` 267 | -------------------------------------------------------------------------------- /pkg/HttpCode/HttpMsg.go: -------------------------------------------------------------------------------- 1 | package HttpCode 2 | 3 | var HttpMsg = map[int]string{ 4 | 5 | SUCCESS: "successful", 6 | ERROR: "ERROR", 7 | ERROR_FILE_TYPE: "文件类型不允许", 8 | ERROR_FILE_NOT_EXIST: "文件不存在", 9 | ERROR_TEMP_SAVE: "文章保存失败", 10 | ERROR_RECOVER: "文章恢复失败", 11 | ERROR_FILE_IS_EXIST: "存在同名文件", 12 | FILE_IS_EXIST_AND_UPDATE: "存在同名文件,文件已经更新", 13 | } 14 | -------------------------------------------------------------------------------- /pkg/HttpCode/code.go: -------------------------------------------------------------------------------- 1 | package HttpCode 2 | 3 | const ( 4 | SUCCESS = 200 5 | ERROR = 500 6 | 7 | ERROR_FILE_TYPE = 10000 8 | ERROR_FILE_NOT_EXIST = 10001 9 | ERROR_TEMP_SAVE = 10002 10 | ERROR_RECOVER = 10003 11 | ERROR_FILE_IS_EXIST = 10004 12 | FILE_IS_EXIST_AND_UPDATE = 10005 13 | ) 14 | -------------------------------------------------------------------------------- /pkg/QiniuClient/QiniuClient.go: -------------------------------------------------------------------------------- 1 | package QiniuClient 2 | 3 | import "note-gin/config" 4 | 5 | var QiniuAccessKey string 6 | var QiniuSecretKey string 7 | 8 | func SetUp() { 9 | QiniuAccessKey = config.Conf.AppConfig.QiniuAccessKey 10 | QiniuSecretKey = config.Conf.AppConfig.QiniuSecretKey 11 | } 12 | -------------------------------------------------------------------------------- /pkg/RedisClient/FolderNav.go: -------------------------------------------------------------------------------- 1 | package RedisClient 2 | 3 | func ChangeFolderNav(folder_title string) (nav []string) { 4 | if folder_title == "Home" { 5 | RedisClient.Del("folder_nav") 6 | return 7 | } 8 | 9 | length := RedisClient.LLen("folder_nav").Val() 10 | 11 | nav = RedisClient.LRange("folder_nav", 0, length-1).Val() 12 | //注意 这里的nav顺序是反的 0是最后一个目录 13 | if len(nav) > 0 && nav[0] == folder_title { //如果page=1 同时还是本目录 则不执行下面的操作 14 | return 15 | } 16 | 17 | result := []string{} 18 | 19 | for i, v := range nav { 20 | if folder_title == v { 21 | RedisClient.LTrim("folder_nav", int64(i), length-1) //【】前后都包括 所以这里-1 当然超过了也没事 不会报错 22 | result = RedisClient.LRange("folder_nav", 0, RedisClient.LLen("folder_nav").Val()-1).Val() 23 | nav = result 24 | } 25 | } 26 | 27 | //如果是新项 28 | if len(result) == 0 { 29 | arr := []string{folder_title} 30 | nav = append(arr, nav...) 31 | RedisClient.LPush("folder_nav", folder_title) 32 | } 33 | return 34 | } 35 | 36 | func GetCurrentNav() (nav []string) { 37 | length := RedisClient.LLen("folder_nav").Val() 38 | if length > 0 { 39 | nav = RedisClient.LRange("folder_nav", 0, length-1).Val() 40 | } 41 | return 42 | } 43 | -------------------------------------------------------------------------------- /pkg/RedisClient/RedisClient.go: -------------------------------------------------------------------------------- 1 | package RedisClient 2 | 3 | import ( 4 | "github.com/go-redis/redis" 5 | "note-gin/config" 6 | ) 7 | 8 | //单例 9 | var RedisClient *redis.Client 10 | var redisConfig = config.Conf.RedisConfig 11 | 12 | func SetUp() { 13 | 14 | client := redis.NewClient(&redis.Options{ 15 | Addr: redisConfig.Addr, 16 | DB: redisConfig.DataBaseNumber, 17 | Password: redisConfig.PassWord, 18 | }) 19 | RedisClient = client 20 | } 21 | -------------------------------------------------------------------------------- /pkg/RedisClient/RedisHandlerArticle.go: -------------------------------------------------------------------------------- 1 | package RedisClient 2 | 3 | import ( 4 | "encoding/json" 5 | "note-gin/pkg/utils" 6 | "note-gin/view/ArticleView" 7 | "time" 8 | ) 9 | 10 | func GetTempEdit(article_view *ArticleView.ArticleEditView) bool { 11 | isExist := RedisClient.Exists("temp_edit").Val() 12 | if isExist == 1 { 13 | s := RedisClient.Get("temp_edit").Val() 14 | 15 | err := json.Unmarshal([]byte(s), article_view) 16 | utils.ErrReport(err) 17 | return true 18 | } else { 19 | return false 20 | } 21 | } 22 | 23 | func SaveTempEdit(temp ArticleView.ArticleEditView) string { 24 | s, _ := json.Marshal(temp) //直接序列化存储了 因为还需要考虑没有ID的临时编辑 25 | return RedisClient.Set("temp_edit", s, time.Hour*24).Val() //1天 26 | } 27 | func DeleteTempEdit() int64 { 28 | return RedisClient.Del("temp_edit").Val() 29 | } 30 | -------------------------------------------------------------------------------- /pkg/logging/log.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/pkg/logging/log.log -------------------------------------------------------------------------------- /pkg/logging/logging.go: -------------------------------------------------------------------------------- 1 | package logging 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "note-gin/config" 7 | "os" 8 | 9 | "runtime" 10 | ) 11 | 12 | var ( 13 | F *os.File 14 | DefaultPrefix = "INFO" 15 | logPrefix = "" 16 | logger *log.Logger 17 | levelFlags = []string{"TRACE", "INFO", "WARN", "ERROR", "FATAL"} 18 | ) 19 | 20 | 21 | type Level int 22 | 23 | const ( 24 | TRACE Level = iota 25 | INFO 26 | WARN 27 | ERROR 28 | FATAL 29 | ) 30 | 31 | func SetUp() { 32 | filePath := config.Conf.AppConfig.LogFilePath 33 | F, err := os.Open(filePath) 34 | if err != nil { 35 | log.Fatal("logging.Setup err: %v", err) 36 | } 37 | logger = log.New(F, DefaultPrefix, log.LstdFlags|log.Lshortfile) 38 | } 39 | 40 | func Trace(v ...interface{}) { 41 | setPrefix(TRACE) 42 | logger.Println(v) 43 | } 44 | func Info(v ...interface{}) { 45 | setPrefix(INFO) 46 | logger.Println(v) 47 | } 48 | func Warn(v ...interface{}) { 49 | setPrefix(WARN) 50 | logger.Println(v) 51 | } 52 | func Error(v ...interface{}) { 53 | setPrefix(ERROR) 54 | logger.Println(v) 55 | } 56 | func Fatal(v ...interface{}) { 57 | setPrefix(FATAL) 58 | logger.Println(v) 59 | } 60 | 61 | func setPrefix(level Level) { 62 | _, filename, line, ok := runtime.Caller(0) 63 | if ok { 64 | logPrefix = fmt.Sprintf("【%s】-【%s:%d】-", levelFlags[level], filename, line) 65 | } else { 66 | logPrefix = fmt.Sprintf("【%s】", levelFlags[level]) 67 | } 68 | logger.SetPrefix(logPrefix) 69 | } 70 | -------------------------------------------------------------------------------- /pkg/utils/ErrReport.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | func ErrReport(err error) { 4 | if err != nil { 5 | panic(err) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /pkg/utils/SendMail.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "strconv" 4 | import "gopkg.in/gomail.v2" 5 | 6 | func SendMail(mailTo []string, subject string, body string) error { 7 | 8 | mailConn := map[string]string{ 9 | "user": "m19884605250@163.com", 10 | "pass": "m19884605250", 11 | "host": "smtp.163.com", 12 | "port": "465", 13 | } 14 | 15 | port, _ := strconv.Atoi(mailConn["port"]) //转换端口类型为int 16 | m := gomail.NewMessage() 17 | m.SetHeader("To", mailTo...) //发送给多个用户 18 | m.SetHeader("Subject", subject) //设置邮件主题 19 | m.SetBody("text/html", body) //设置邮件正文 20 | m.SetHeader("From", m.FormatAddress(mailConn["user"], "note-gin")) 21 | d := gomail.NewDialer(mailConn["host"], port, mailConn["user"], mailConn["pass"]) 22 | err := d.DialAndSend(m) 23 | return err 24 | 25 | } 26 | -------------------------------------------------------------------------------- /pkg/utils/StrToInt.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "log" 5 | "strconv" 6 | ) 7 | 8 | func StrToInt(val string) int { 9 | v1, err := strconv.ParseInt(val, 10, 64) 10 | if err != nil { 11 | log.Println(err) 12 | } 13 | return int(v1) 14 | } 15 | -------------------------------------------------------------------------------- /router/ArticleRouter.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import "note-gin/controller/ArticleController" 4 | 5 | func ArticleRouter(base string) { 6 | r := Router.Group("/" + base) 7 | 8 | r.GET("/download/:id", ArticleController.ArticleDownLoad) 9 | r.GET("/many/:page", ArticleController.GetArticleByPage) 10 | r.GET("/get/:id", ArticleController.GetArticleDetail) 11 | r.GET("/clear_rubbish", ArticleController.ClearRubbish) 12 | r.GET("/delete", ArticleController.Delete) 13 | r.GET("/delete/many", ArticleController.DeleteMany) 14 | r.GET("/rubbish", ArticleController.GetRubbishArticles) 15 | r.GET("/recover", ArticleController.ArticleRecover) 16 | r.GET("/temp_get", ArticleController.TempArticleEditGet) //获取上次的编辑器保存 17 | r.GET("/temp_delete", ArticleController.TempArticleEditDelete) 18 | r.POST("/temp_save", ArticleController.TempArticleEditSave) //编辑器保存 19 | r.POST("/add", ArticleController.Add) 20 | r.POST("/update", ArticleController.Update) 21 | r.GET("/edit/:id", ArticleController.Edit) 22 | r.POST("/set_tag", ArticleController.SetTag) 23 | r.POST("/upload_md", ArticleController.UploadArticle) 24 | } 25 | -------------------------------------------------------------------------------- /router/BookRouter.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "note-gin/controller/BookController" 5 | ) 6 | 7 | func BookRouter(base string) { 8 | r := Router.Group("/" + base) 9 | r.GET("/book/get/all", BookController.GetAllBook) //不设分页 直接从redis里面取 不判断是否存在 10 | r.GET("/book/delete/:id", BookController.DeleteBook) 11 | r.POST("/book/add", BookController.AddBook) 12 | r.POST("/book/update", BookController.UpdateBook) 13 | 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /router/FolderRouter.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "note-gin/controller/FolderController" 5 | ) 6 | 7 | func FolderRouter(base string) { 8 | r := Router.Group("/" + base) 9 | r.GET("/current", FolderController.GetCurrentNav) 10 | r.GET("/sub_file/:page", FolderController.GetSubFile) 11 | r.GET("/sub_folder", FolderController.GetSubFolders) //用于编辑文章选择目录时请求 12 | r.GET("/update", FolderController.Update) 13 | r.GET("/add", FolderController.Add) 14 | r.GET("/delete", FolderController.Delete) 15 | } 16 | -------------------------------------------------------------------------------- /router/QiniuRouter.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import "note-gin/controller/QiniuController" 4 | 5 | func QiniuRouter(base string) { 6 | r := Router.Group("/" + base) 7 | r.GET("/img_delete", QiniuController.ImgDelete) 8 | r.POST("/img_upload", QiniuController.ImgUpload) 9 | } 10 | -------------------------------------------------------------------------------- /router/router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "note-gin/middleware" 6 | ) 7 | 8 | var Router *gin.Engine 9 | 10 | func NewRouter() *gin.Engine { 11 | r := gin.Default() 12 | 13 | r.Use(middleware.Cors()) //配置跨域 14 | 15 | r.GET("/ping", func(context *gin.Context) { 16 | context.Writer.WriteString("Pong") 17 | 18 | }) 19 | r.NoRoute(func(context *gin.Context) { 20 | context.Writer.WriteString("对不起,页面找不到") 21 | }) 22 | 23 | Router = r 24 | 25 | FolderRouter("folder") 26 | ArticleRouter("article") 27 | QiniuRouter("qiniu") 28 | //TimeLineRouter("time_line") 29 | BookRouter("my") 30 | return r 31 | } 32 | -------------------------------------------------------------------------------- /service/ArticleService/Article.go: -------------------------------------------------------------------------------- 1 | package ArticleService 2 | 3 | import ( 4 | "errors" 5 | "mime/multipart" 6 | "note-gin/models" 7 | "note-gin/pkg/HttpCode" 8 | "note-gin/pkg/RedisClient" 9 | "note-gin/pkg/utils" 10 | "note-gin/service/FolderService" 11 | "note-gin/view/ArticleView" 12 | "note-gin/view/common" 13 | "strings" 14 | "time" 15 | ) 16 | 17 | func ArticleDownLoad(ID string) (string, string) { 18 | article := GetArticleDetail(ID) 19 | return article.Title, article.MkValue 20 | } 21 | 22 | func GetArticleByPage(page int) ([]ArticleView.ArticleInfo, int) { 23 | articles := models.Article{}.GetMany(page) 24 | total := models.Article{}.Count() 25 | ArticleInfos := ArticleView.ToArticleInfos(articles) 26 | return ArticleInfos, total 27 | } 28 | 29 | func GetArticleDetail(ID string) ArticleView.ArticleDetail { 30 | article := models.Article{} 31 | article.ID = int64(utils.StrToInt(ID)) 32 | article.GetArticleInfo() 33 | articleDetail := ArticleView.ToArticleDetail(article) 34 | return articleDetail 35 | } 36 | 37 | func ClearRubbish() { 38 | models.Article{}.ClearRubbish() 39 | } 40 | 41 | func Delete(ID string) int64 { 42 | article := models.Article{} 43 | article.ID = int64(utils.StrToInt(ID)) 44 | article.Delete() 45 | return article.ID 46 | } 47 | 48 | func DeleteMany(IDs []string) { 49 | models.Article{}.DeleteMany(IDs) 50 | } 51 | 52 | func GetRubbishArticles() common.DataList { 53 | articles := models.Article{}.GetDeletedArticle() 54 | respDataList := common.DataList{ 55 | Items: articles, 56 | Total: int64(len(articles)), 57 | } 58 | return respDataList 59 | } 60 | 61 | func ArticleRecover(ID string) error { 62 | article := models.Article{} 63 | article.ID = int64(utils.StrToInt(ID)) 64 | return article.Recover() 65 | } 66 | 67 | func Add(articleEditView *ArticleView.ArticleEditView) { 68 | article := models.Article{} 69 | article.Title = articleEditView.Title 70 | if articleEditView.FolderTitle != "Home" { 71 | article.FolderID = FolderService.GetFolderByTitle(articleEditView.FolderTitle).ID 72 | } 73 | article.Add() //这里调用的方法必须是指针类型 74 | articleEditView.FolderID = article.FolderID 75 | articleEditView.DirPath = append(articleEditView.DirPath, articleEditView.FolderID) //先添加自己的根目录 76 | models.Folder{}.GetFolderPath(articleEditView.FolderID, &articleEditView.DirPath) //查找路径 77 | } 78 | 79 | func Update(articleEditView *ArticleView.ArticleEditView) { 80 | article := models.Article{} 81 | article.ID = articleEditView.ID 82 | article.UpdatedAt = time.Now() 83 | if len(articleEditView.DirPath) != 0 { 84 | article.FolderID = articleEditView.DirPath[len(articleEditView.DirPath)-1] 85 | } 86 | 87 | article.MkValue = articleEditView.MkValue 88 | article.Title = articleEditView.Title 89 | article.Update() 90 | 91 | articleEditView.UpdatedAt = article.UpdatedAt.Format("2006-01-02") 92 | articleEditView.CreatedAt = article.UpdatedAt.Format("2006-01-02") 93 | articleEditView.ID = article.ID 94 | } 95 | 96 | func Edit(articleEditView *ArticleView.ArticleEditView) { 97 | //目录路径回溯 98 | articleEditView.DirPath = append(articleEditView.DirPath, articleEditView.FolderID) //先添加自己的根目录 99 | FolderService.GetFolderPath(articleEditView.FolderID, &articleEditView.DirPath) //查找路径 100 | } 101 | 102 | func SetTag(articleInfo ArticleView.ArticleInfo) { 103 | article := ArticleView.ToArticle(articleInfo) 104 | article.SetTag() 105 | } 106 | 107 | func TempArticleEditGet() (ArticleView.ArticleEditView, bool) { 108 | articleEditView := ArticleView.ArticleEditView{} 109 | ok := RedisClient.GetTempEdit(&articleEditView) 110 | return articleEditView, ok 111 | } 112 | 113 | func TempArticleEditDelete() int64 { 114 | return RedisClient.DeleteTempEdit() 115 | } 116 | 117 | func TempArticleEditSave(articleEditView ArticleView.ArticleEditView) bool { 118 | flag := RedisClient.SaveTempEdit(articleEditView) 119 | if strings.ToLower(flag) == "ok" { 120 | return true 121 | } else { 122 | return false 123 | } 124 | } 125 | 126 | func UploadArticle(files map[string][]*multipart.FileHeader, folder_title string, file_name *string) (bool, error) { 127 | folder_id := FolderService.GetFolderByTitle(folder_title).ID 128 | for name, file := range files { 129 | names := strings.Split(name, ".") 130 | typeName := names[1] 131 | if typeName != "md" { 132 | return false, errors.New(HttpCode.HttpMsg[HttpCode.ERROR_FILE_TYPE]) 133 | } 134 | 135 | fp, _ := file[0].Open() 136 | b := make([]byte, file[0].Size) 137 | fp.Read(b) 138 | 139 | article := models.Article{} 140 | article.Title = names[0] 141 | *file_name = article.Title 142 | isExist := article.IsExist() 143 | if isExist != true { 144 | article.FolderID = folder_id 145 | article.MkValue = string(b) 146 | article.Add() 147 | return true, nil 148 | } else { //存在同名文件则更新 不管是否是在同一个目录下 【整个系统不允许出现同名文件】 149 | article.GetArticleInfoByTitle() 150 | article.FolderID = folder_id 151 | article.MkValue = string(b) 152 | article.Update() 153 | return false, errors.New(HttpCode.HttpMsg[HttpCode.FILE_IS_EXIST_AND_UPDATE]) 154 | } 155 | 156 | } 157 | return false, nil 158 | } 159 | -------------------------------------------------------------------------------- /service/BookService/Book.go: -------------------------------------------------------------------------------- 1 | package BookService 2 | -------------------------------------------------------------------------------- /service/FolderService/Folder.go: -------------------------------------------------------------------------------- 1 | package FolderService 2 | 3 | import ( 4 | "note-gin/models" 5 | "note-gin/pkg/RedisClient" 6 | "note-gin/pkg/utils" 7 | "note-gin/view/ArticleView" 8 | "note-gin/view/FolderView" 9 | ) 10 | 11 | func GetFolderPath(FolderID int64, DirPath *[]int64) { 12 | models.Folder{}.GetFolderPath(FolderID, DirPath) 13 | } 14 | 15 | func GetFolderByTitle(folder_title string) FolderView.FolderInfo { 16 | folderInfo := FolderView.ToFolderInfo(models.Folder{Title: folder_title}) 17 | return folderInfo 18 | } 19 | 20 | func GetSubFile(folder_title string, page int) ([]FolderView.FolderInfo, []ArticleView.ArticleInfo, int) { 21 | folder := models.Folder{} 22 | 23 | folder.Title = folder_title 24 | folder.GetFolderByTitle() 25 | 26 | folders, articles, total := folder.GetSubFile(page) //根据页码查找这个目录下的全部文件 total 27 | articleInfos := ArticleView.ToArticleInfos(articles) 28 | folderInfos := FolderView.ToFolderInfos(folders) 29 | 30 | return folderInfos, articleInfos, total 31 | 32 | } 33 | 34 | func ChangeNav(page string, folder_title string) []string { 35 | var nav []string //如果是AccessFolder 则需要加载 如果是页码跳转 则不需要加载 前端还是保留以前的nav 36 | if page == "1" { //page=1才可能是其他目录 37 | nav = RedisClient.ChangeFolderNav(folder_title) //改变redis目录路径的缓存 38 | nav = append(nav, "Home") 39 | } 40 | return nav 41 | } 42 | 43 | func GetSubFolders(id string) []FolderView.FolderSelectView { 44 | folder := models.Folder{} 45 | folder.ID = int64(utils.StrToInt(id)) 46 | folders := folder.GetSubFolders() 47 | //这里出错了一个小细节 make指定长度切片就可以直接引用位置了 如果再append的方式加入元素则会重新创建空间 48 | folderSelectList := make([]FolderView.FolderSelectView, len(folders)) 49 | for i := range folders { 50 | folderSelectList[i] = FolderView.FolderSelectView{ 51 | Value: folders[i].ID, 52 | Label: folders[i].Title, 53 | Leaf: folders[i].CountSubFolder() <= 0, 54 | } 55 | } 56 | return folderSelectList 57 | } 58 | 59 | func Update(folderInfo FolderView.FolderInfo) { 60 | folder := FolderView.ToFolder(folderInfo) 61 | folder.Update() 62 | } 63 | 64 | func Add(title string, fatherTitle string) { 65 | folder := models.Folder{} 66 | folder.Title = title 67 | 68 | father := models.Folder{} 69 | father.Title = fatherTitle 70 | father.GetFolderByTitle() 71 | 72 | folder.FolderID = father.ID 73 | folder.Add() 74 | } 75 | 76 | func Delete(id string) int64 { 77 | folder := models.Folder{} 78 | folder.ID = int64(utils.StrToInt(id)) 79 | folder.Delete() 80 | return folder.ID 81 | } 82 | -------------------------------------------------------------------------------- /service/QiniuService/Qiniu.go: -------------------------------------------------------------------------------- 1 | package QiniuService 2 | -------------------------------------------------------------------------------- /sql/note-gin-sql.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE article( 2 | id BIGINT(20) PRIMARY KEY AUTO_INCREMENT, 3 | created_at DATETIME, 4 | updated_at DATETIME, 5 | deleted TINYINT, 6 | deleted_time DATETIME, 7 | title VARCHAR(255) NOT NULL, 8 | folder_id BIGINT(20),FOREIGN KEY(folder_id) REFERENCES folder(id), 9 | mk_value TEXT, 10 | tags VARCHAR(255) 11 | ) 12 | ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; 13 | 14 | 15 | CREATE TABLE folder( 16 | id BIGINT(20) PRIMARY KEY AUTO_INCREMENT, 17 | created_at DATETIME, 18 | updated_at DATETIME, 19 | deleted TINYINT, 20 | deleted_time DATETIME, 21 | title VARCHAR(255) NOT NULL, 22 | folder_id BIGINT(20),FOREIGN KEY(folder_id) REFERENCES folder(id) 23 | ) 24 | ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; 25 | 26 | 27 | CREATE TABLE my_book( 28 | id BIGINT(20) PRIMARY KEY AUTO_INCREMENT, 29 | title VARCHAR(255), 30 | writer VARCHAR(255), 31 | img_url VARCHAR(255), 32 | STATUS VARCHAR(255), 33 | COUNT INT(11), 34 | updated_at DATETIME 35 | ) 36 | ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; -------------------------------------------------------------------------------- /test/a.txt: -------------------------------------------------------------------------------- 1 | a -------------------------------------------------------------------------------- /test/config_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "io/ioutil" 5 | "note-gin/config" 6 | "testing" 7 | ) 8 | 9 | func TestConfigPath(t *testing.T) { 10 | cfp := config.NewconfigFilePath("../config/file/BootLoader.yaml") //路径是从当前目录出发 不是从NewconfigFilePath的目录出发 11 | t.Log(cfp.AppPath) 12 | cfg := config.Config{} 13 | 14 | cfg.AppConfig.InitAppConfig(cfp.AppPath) 15 | t.Log(cfg.AppConfig) 16 | } 17 | 18 | func TestIoutil(t *testing.T) { 19 | b, e := ioutil.ReadFile("../config/file/BootLoader.yaml") 20 | t.Log(string(b), e) 21 | } 22 | 23 | func TestApp(t *testing.T) { 24 | var cfg config.Config //所有属性都会初始化 25 | t.Log(cfg.AppConfig) 26 | } 27 | -------------------------------------------------------------------------------- /test/model_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "fmt" 5 | "github.com/jinzhu/gorm" 6 | "note-gin/config" 7 | "testing" 8 | 9 | ) 10 | var mySqlConfig = config.Conf.MySqlConfig 11 | func TestOpenSql(t *testing.T){ 12 | connStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true", 13 | "root", "55555", "118.178.180.115","6379", "note") 14 | 15 | _, err := gorm.Open("mysql", connStr) 16 | t.Log(err) 17 | t.Log(connStr) 18 | } 19 | -------------------------------------------------------------------------------- /tmp/runner-build.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/tmp/runner-build.exe -------------------------------------------------------------------------------- /tmp/runner-build.exe~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/biningo/note-gin/7a95798e0afbd2c3488560047a8af5ecce1123bc/tmp/runner-build.exe~ -------------------------------------------------------------------------------- /view/ArticleView/ArticleDetail.go: -------------------------------------------------------------------------------- 1 | package ArticleView 2 | 3 | import "note-gin/models" 4 | 5 | type ArticleDetail struct { 6 | ID int64 `form:"id" json:"id"` 7 | Title string `form:"title" json:"title"` 8 | MkValue string `form:"mkValue" json:"mkValue"` 9 | } 10 | 11 | func ToArticleDetail(article models.Article) ArticleDetail { 12 | articleDetail := ArticleDetail{ 13 | ID: article.ID, 14 | Title: article.Title, 15 | MkValue: article.MkValue, 16 | } 17 | return articleDetail 18 | } 19 | -------------------------------------------------------------------------------- /view/ArticleView/ArticleEditView.go: -------------------------------------------------------------------------------- 1 | package ArticleView 2 | 3 | type ArticleEditView struct { 4 | ID int64 `form:"id" json:"id"` 5 | CreatedAt string `json:"created_at" form:"created_at"` 6 | UpdatedAt string `json:"updated_at" form:"updated_at"` 7 | Title string `json:"title" form:"title"` 8 | DirPath []int64 `json:"dir_path" form:"dir_path"` 9 | FolderID int64 `json:"folder_id" form:"folder_id"` 10 | FolderTitle string `json:"folder_title" form:"folder_title"` 11 | MkValue string `form:"mkValue" json:"mkValue"` 12 | } 13 | -------------------------------------------------------------------------------- /view/ArticleView/ArticleInfo.go: -------------------------------------------------------------------------------- 1 | package ArticleView 2 | 3 | import ( 4 | "note-gin/models" 5 | "strings" 6 | "time" 7 | ) 8 | 9 | type ArticleInfo struct { 10 | ID int64 `json:"id" form:"id"` 11 | Title string `json:"title" form:"title"` 12 | UpdatedAt string `json:"updated_at" form:"updated_at"` 13 | Tags []string `json:"blogs" form:"blogs"` 14 | } 15 | 16 | func ToArticleInfos(articles []models.Article) []ArticleInfo { 17 | ArticleInfos := make([]ArticleInfo, len(articles)) 18 | 19 | for index := range articles { 20 | ArticleInfos[index].ID = articles[index].ID 21 | ArticleInfos[index].Title = articles[index].Title 22 | ArticleInfos[index].UpdatedAt = articles[index].UpdatedAt.Format("2006/1/2") 23 | ArticleInfos[index].Tags = strings.Split(articles[index].Tags, ",") 24 | } 25 | return ArticleInfos 26 | } 27 | 28 | func ToArticle(articleInfo ArticleInfo) models.Article { 29 | article := models.Article{} 30 | article.ID = articleInfo.ID 31 | article.Title = articleInfo.Title 32 | article.Tags = strings.Join(articleInfo.Tags, ",") 33 | article.UpdatedAt, _ = time.Parse("2006-01-02", articleInfo.UpdatedAt) 34 | return article 35 | } 36 | -------------------------------------------------------------------------------- /view/FolderView/FolderInfo.go: -------------------------------------------------------------------------------- 1 | package FolderView 2 | 3 | import ( 4 | "note-gin/models" 5 | "time" 6 | ) 7 | 8 | type FolderInfo struct { 9 | ID int64 `json:"id" form:"id"` 10 | Title string `json:"title" form:"title"` 11 | UpdatedAt string `form:"updated_at" json:"updated_at"` 12 | } 13 | 14 | 15 | func ToFolder(folderInfo FolderInfo) models.Folder { 16 | folder:=models.Folder{} 17 | folder.ID = folderInfo.ID 18 | folder.Title = folderInfo.Title 19 | folder.UpdatedAt,_ = time.Parse("2006-01-02", folderInfo.UpdatedAt) 20 | return folder 21 | } 22 | 23 | func ToFolderInfo(folder models.Folder) FolderInfo { 24 | folderInfo := FolderInfo{} 25 | folderInfo.ID = folder.ID 26 | folderInfo.UpdatedAt = folder.UpdatedAt.Format("2006-01-02") 27 | folderInfo.Title = folder.Title 28 | return folderInfo 29 | } 30 | 31 | func ToFolderInfos(folders []models.Folder) []FolderInfo { 32 | folderInfos := make([]FolderInfo, len(folders)) 33 | for i := range folders { 34 | folderInfos[i].ID = folders[i].ID 35 | folderInfos[i].UpdatedAt = folders[i].UpdatedAt.Format("2006-01-02") 36 | folderInfos[i].Title = folders[i].Title 37 | } 38 | return folderInfos 39 | } 40 | -------------------------------------------------------------------------------- /view/FolderView/FolderSelect.go: -------------------------------------------------------------------------------- 1 | package FolderView 2 | 3 | type FolderSelectView struct { 4 | Value int64 `json:"value" form:"value"` 5 | Label string `json:"label" form:"label"` 6 | Leaf bool `json:"leaf" form:"leaf"` 7 | Children []FolderSelectView `json:"children" form:"children"` 8 | } 9 | -------------------------------------------------------------------------------- /view/common/DataList.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | type DataList struct { 4 | Items interface{} `form:"items" json:"items"` 5 | Total int64 `form:"total" json:"total"` 6 | } 7 | -------------------------------------------------------------------------------- /view/common/FileList.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "note-gin/view/ArticleView" 5 | "note-gin/view/FolderView" 6 | ) 7 | 8 | type FileList struct { 9 | Folders []FolderView.FolderInfo 10 | Articles []ArticleView.ArticleInfo 11 | Nav []string 12 | Total int 13 | } 14 | -------------------------------------------------------------------------------- /view/common/RespBean.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | type RespBean struct { 4 | Code int `form:"code" json:"code"` 5 | Msg string `form:"msg" json:"msg"` 6 | Data interface{} `form:"data" json:"data"` 7 | } 8 | func NewRespBean() RespBean{ 9 | return RespBean{} 10 | } 11 | 12 | func OkWithMsg(msg string) RespBean { 13 | return RespBean{ 14 | Code: 200, 15 | Msg: msg, 16 | Data: nil, 17 | } 18 | } 19 | 20 | func OkWithData(msg string,data interface{}) RespBean{ 21 | return RespBean{ 22 | Code: 200, 23 | Msg: msg, 24 | Data: data, 25 | } 26 | } 27 | 28 | 29 | 30 | func ErrorWithMsg(msg string) RespBean { 31 | return RespBean{ 32 | Code: 500, 33 | Msg: msg, 34 | Data: nil, 35 | } 36 | } 37 | 38 | func ErrorWithData(msg string,data interface{}) RespBean{ 39 | return RespBean{ 40 | Code: 500, 41 | Msg: msg, 42 | Data: data, 43 | } 44 | } 45 | 46 | 47 | --------------------------------------------------------------------------------