├── .dockerignore ├── .gitattributes ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── question.md ├── .gitignore ├── .travis.yml ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── auxpiAll ├── all.go ├── all_easyjson.go ├── e │ ├── code.go │ └── msg.go └── error.go ├── bootstrap ├── Config.go ├── helper.go └── logo.go ├── build.sh ├── conf └── app.conf ├── controllers ├── admin.go ├── api │ ├── base │ │ └── api.go │ ├── v1 │ │ ├── admin.go │ │ ├── auth.go │ │ ├── auxpi.go │ │ ├── option.go │ │ ├── upload.go │ │ └── user.go │ └── v2 │ │ └── dispatch.go ├── base.go ├── error.go ├── index.go ├── user.go ├── webUpLoad.go └── ws │ └── websocket.go ├── db └── .gitkeep ├── go.mod ├── go.sum ├── hack ├── docker │ └── Dockerfile └── run │ └── entrypoint.sh ├── install.sh ├── log └── logSetter.go ├── main.go ├── manager.sh ├── middleware ├── auth.go ├── cookie.go ├── jwt.go ├── limit.go ├── redirect.go └── xsrf.go ├── models ├── casbin.go ├── distribution.go ├── images.go ├── ips.go ├── logs.go ├── models.go ├── options.go ├── permissions.go ├── roles.go ├── stores.go ├── sync.go └── users.go ├── pem ├── private_key.pem └── public_key.pem ├── resource ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .postcssrc.js ├── LICENSE ├── config │ ├── dev.env.js │ ├── index.js │ └── prod.env.js ├── favicon.ico ├── index.html ├── package.json ├── src │ ├── App.vue │ ├── api │ │ ├── dashbroad.js │ │ ├── dispatch.js │ │ ├── image.js │ │ ├── log.js │ │ ├── login.js │ │ ├── siteconfig.js │ │ ├── table.js │ │ └── user.js │ ├── assets │ │ ├── 404_images │ │ │ ├── 404.png │ │ │ └── 404_cloud.png │ │ └── load.gif │ ├── components │ │ ├── AimerThumb │ │ │ └── index.vue │ │ ├── Breadcrumb │ │ │ └── index.vue │ │ ├── GithubCorner │ │ │ └── index.vue │ │ ├── Hamburger │ │ │ └── index.vue │ │ ├── InfoBox │ │ │ └── index.vue │ │ ├── Pagination │ │ │ └── index.vue │ │ ├── SvgIcon │ │ │ └── index.vue │ │ └── TextHoverEffect │ │ │ └── Mallki.vue │ ├── filters │ │ └── index.js │ ├── icons │ │ ├── index.js │ │ ├── svg │ │ │ ├── ali.svg │ │ │ ├── auxpi.svg │ │ │ ├── baidu1.svg │ │ │ ├── cc.svg │ │ │ ├── cloud.svg │ │ │ ├── config.svg │ │ │ ├── dashboard.svg │ │ │ ├── data-base.svg │ │ │ ├── distribute.svg │ │ │ ├── example.svg │ │ │ ├── eye-open.svg │ │ │ ├── eye.svg │ │ │ ├── flickr.svg │ │ │ ├── form.svg │ │ │ ├── gitee.svg │ │ │ ├── github.svg │ │ │ ├── images.svg │ │ │ ├── img-manager.svg │ │ │ ├── imgur.svg │ │ │ ├── jingdong.svg │ │ │ ├── juejin.svg │ │ │ ├── link.svg │ │ │ ├── list.svg │ │ │ ├── logs.svg │ │ │ ├── manage.svg │ │ │ ├── menu.svg │ │ │ ├── nested.svg │ │ │ ├── ooxx.svg │ │ │ ├── password.svg │ │ │ ├── prnt.svg │ │ │ ├── qihu.svg │ │ │ ├── sm.svg │ │ │ ├── sougou.svg │ │ │ ├── souhu.svg │ │ │ ├── start.svg │ │ │ ├── stop.svg │ │ │ ├── suning.svg │ │ │ ├── sync.svg │ │ │ ├── table.svg │ │ │ ├── toutiao.svg │ │ │ ├── tree.svg │ │ │ ├── upload.svg │ │ │ ├── user.svg │ │ │ ├── users.svg │ │ │ ├── vim.svg │ │ │ ├── wangyi.svg │ │ │ ├── weibo.svg │ │ │ └── xiaomi.svg │ │ └── svgo.yml │ ├── lang │ │ ├── en.js │ │ ├── es.js │ │ ├── index.js │ │ └── zh.js │ ├── main.js │ ├── permission.js │ ├── router │ │ └── index.js │ ├── settings.js │ ├── store │ │ ├── getters.js │ │ ├── index.js │ │ └── modules │ │ │ ├── app.js │ │ │ ├── permission.js │ │ │ ├── settings.js │ │ │ ├── tagsView.js │ │ │ └── user.js │ ├── styles │ │ ├── element-ui.scss │ │ ├── element-variables.scss │ │ ├── index.scss │ │ ├── mixin.scss │ │ ├── sidebar.scss │ │ ├── transition.scss │ │ └── variables.scss │ ├── utils │ │ ├── auth.js │ │ ├── clipboard.js │ │ ├── i18n.js │ │ ├── index.js │ │ ├── request.js │ │ ├── scrollTo.js │ │ └── validate.js │ └── views │ │ ├── 404.vue │ │ ├── card │ │ ├── index.vue │ │ └── sync │ │ │ └── index.vue │ │ ├── dashboard │ │ ├── admin │ │ │ ├── components │ │ │ │ ├── BoxCard.vue │ │ │ │ ├── LineChart.vue │ │ │ │ ├── PanelGroup.vue │ │ │ │ └── PieChart.vue │ │ │ └── index.vue │ │ ├── editor │ │ │ └── index.vue │ │ └── index.vue │ │ ├── form │ │ └── index.vue │ │ ├── layout │ │ ├── Layout.vue │ │ ├── components │ │ │ ├── AppMain.vue │ │ │ ├── Navbar.vue │ │ │ ├── Sidebar │ │ │ │ ├── Item.vue │ │ │ │ ├── Link.vue │ │ │ │ ├── Logo.vue │ │ │ │ ├── SidebarItem.vue │ │ │ │ └── index.vue │ │ │ ├── TagsView │ │ │ │ ├── ScrollPane.vue │ │ │ │ └── index.vue │ │ │ └── index.js │ │ └── mixin │ │ │ └── ResizeHandler.js │ │ ├── login │ │ └── index.vue │ │ ├── logs │ │ └── index.vue │ │ ├── nested │ │ ├── menu1 │ │ │ ├── index.vue │ │ │ ├── menu1-1 │ │ │ │ └── index.vue │ │ │ ├── menu1-2 │ │ │ │ ├── index.vue │ │ │ │ ├── menu1-2-1 │ │ │ │ │ └── index.vue │ │ │ │ └── menu1-2-2 │ │ │ │ │ └── index.vue │ │ │ └── menu1-3 │ │ │ │ └── index.vue │ │ └── menu2 │ │ │ └── index.vue │ │ ├── siteconfig │ │ ├── dispatch.vue │ │ ├── index.vue │ │ └── menu.vue │ │ ├── table │ │ └── index.vue │ │ ├── tree │ │ └── index.vue │ │ ├── upload │ │ ├── index.vue │ │ └── show.vue │ │ └── user │ │ ├── index.vue │ │ ├── info.vue │ │ └── info │ │ ├── components │ │ ├── edit.vue │ │ └── view.vue │ │ └── index.vue └── static │ └── .gitkeep ├── routers ├── api │ ├── auth │ │ └── auth.go │ ├── v1 │ │ ├── admin.go │ │ ├── upload.go │ │ ├── user.go │ │ └── ws.go │ └── v2 │ │ └── dispatch.go └── router.go ├── server ├── Ali.go ├── CC.go ├── Gitee.go ├── Github.go ├── Imgur.go ├── Jd.go ├── JueJin.go ├── Local.go ├── NetEasy.go ├── Ooxx.go ├── Prnt.go ├── Qihoo.go ├── Sina.go ├── Smms.go ├── SouGou.go ├── Souhu.go ├── SuNing.go ├── TouTiao.go ├── VIMCN.go ├── XiaoMi.go ├── flickr.go ├── handle.go └── index.go ├── static ├── app │ ├── admin │ │ ├── css │ │ │ ├── app.e232d983.css │ │ │ ├── app.e232d983.css.gz │ │ │ ├── chunk-0bd4.95190365.css │ │ │ ├── chunk-0fee.3a96d434.css │ │ │ ├── chunk-1ae2.6f706f86.css │ │ │ ├── chunk-1b5e.e285d96e.css │ │ │ ├── chunk-529e.6a3f537c.css │ │ │ ├── chunk-5733.44574f65.css │ │ │ ├── chunk-6f53.360c2484.css │ │ │ ├── chunk-9a76.31e91e47.css │ │ │ ├── chunk-c65d.cf11b174.css │ │ │ ├── chunk-cc24.f9e05c98.css │ │ │ ├── chunk-cf1d.3fd4e8c9.css │ │ │ ├── chunk-dbfc.2200a67c.css │ │ │ ├── chunk-ed47.1b4595b0.css │ │ │ ├── chunk-elementUI.7e429284.css │ │ │ ├── chunk-elementUI.7e429284.css.gz │ │ │ └── chunk-libs.ea76e8e5.css │ │ ├── favicon.ico │ │ ├── fonts │ │ │ └── element-icons.6f0a763.ttf │ │ ├── img │ │ │ └── 404.a57b6f3.png │ │ └── js │ │ │ ├── app.7a9d371b.js │ │ │ ├── app.7a9d371b.js.gz │ │ │ ├── chunk-0bd4.818149eb.js │ │ │ ├── chunk-0fee.ca9d1a47.js │ │ │ ├── chunk-1ae2.47d8888c.js │ │ │ ├── chunk-1ae2.47d8888c.js.gz │ │ │ ├── chunk-1b5e.4b7ec984.js │ │ │ ├── chunk-1b5e.4b7ec984.js.gz │ │ │ ├── chunk-529e.82cb1d16.js │ │ │ ├── chunk-5733.c79d41d0.js │ │ │ ├── chunk-5965.5130ff8b.js │ │ │ ├── chunk-5965.5130ff8b.js.gz │ │ │ ├── chunk-6f53.c7d7a86f.js │ │ │ ├── chunk-9a76.31959552.js │ │ │ ├── chunk-9a76.31959552.js.gz │ │ │ ├── chunk-b02f.0024f8cb.js │ │ │ ├── chunk-b02f.0024f8cb.js.gz │ │ │ ├── chunk-c65d.0c401c71.js │ │ │ ├── chunk-cc24.e448dea5.js │ │ │ ├── chunk-cc24.e448dea5.js.gz │ │ │ ├── chunk-cf1d.0396a251.js │ │ │ ├── chunk-cf1d.0396a251.js.gz │ │ │ ├── chunk-dbfc.8fc7fee7.js │ │ │ ├── chunk-dbfc.8fc7fee7.js.gz │ │ │ ├── chunk-ed47.3d980047.js │ │ │ ├── chunk-elementUI.84dd9cf5.js │ │ │ ├── chunk-elementUI.84dd9cf5.js.gz │ │ │ ├── chunk-libs.b37d8d5d.js │ │ │ └── chunk-libs.b37d8d5d.js.gz │ ├── css │ │ ├── app.css │ │ ├── app.css.map │ │ ├── app.less │ │ └── my-login.css │ ├── iconfont │ │ ├── demo.css │ │ ├── iconfont.css │ │ ├── iconfont.eot │ │ ├── iconfont.js │ │ ├── iconfont.svg │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 │ ├── images │ │ ├── logo.jpg │ │ └── logoko.png │ └── js │ │ ├── app.js │ │ ├── common.js │ │ └── jq-paginator.min.js ├── bootstrap-fileinput │ └── 4.5.1 │ │ ├── css │ │ └── fileinput.min.css │ │ ├── img │ │ ├── loading-sm.gif │ │ └── loading.gif │ │ └── js │ │ ├── fileinput.min.js │ │ └── locales │ │ └── zh.js ├── bootstrap │ ├── 3.3.7 │ │ ├── css │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ └── bootstrap.min.js │ ├── css │ │ ├── bootstrap-grid.css │ │ ├── bootstrap-grid.css.map │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-reboot.css │ │ ├── bootstrap-reboot.css.map │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ └── js │ │ ├── bootstrap.bundle.js │ │ ├── bootstrap.bundle.js.map │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.js │ │ ├── bootstrap.js.map │ │ ├── bootstrap.min.js │ │ └── bootstrap.min.js.map ├── clipboard.js │ └── 2.0.1 │ │ └── clipboard.min.js ├── contextjs │ ├── css │ │ └── context.standalone.css │ └── js │ │ └── context.js ├── dist │ └── static │ │ ├── css │ │ ├── app.c26416b7.css │ │ ├── chunk-06e5.7780a1e3.css │ │ ├── chunk-727c.27cce0c9.css │ │ ├── chunk-8f68.ad0dd7f0.css │ │ ├── chunk-c383.15b0fdb4.css │ │ ├── chunk-db81.4b63c2f2.css │ │ ├── chunk-elementUI.8441406c.css │ │ ├── chunk-f29c.4ec8f0e7.css │ │ ├── chunk-f47c.cf113efb.css │ │ └── chunk-libs.e419eba9.css │ │ ├── fonts │ │ └── element-icons.6f0a763.ttf │ │ ├── images │ │ ├── 123.ts │ │ └── load.gif │ │ ├── img │ │ └── 404.a57b6f3.png │ │ └── js │ │ ├── 27OO.4ee76676.js │ │ ├── 6bwb.935655f4.js │ │ ├── Vc2m.733314d5.js │ │ ├── ZYJW.b9669658.js │ │ ├── ad09.11d972f7.js │ │ ├── app.6b25ae86.js │ │ ├── chunk-06e5.ad60970a.js │ │ ├── chunk-2a20.66f39fe8.js │ │ ├── chunk-727c.8a13c161.js │ │ ├── chunk-8f68.56adade2.js │ │ ├── chunk-c383.12ad7034.js │ │ ├── chunk-db81.dc1821e7.js │ │ ├── chunk-elementUI.a6abb908.js │ │ ├── chunk-f29c.4896f38f.js │ │ ├── chunk-f47c.8d03bd5e.js │ │ ├── chunk-libs.f1446175.js │ │ ├── jYsI.ae151788.js │ │ ├── kP7L.06c62fa2.js │ │ ├── kbPl.7eb515d5.js │ │ └── tvtM.3b4dc552.js ├── favicon.ico ├── jquery-viewer │ └── 1.2.0 │ │ ├── css │ │ └── viewer.css │ │ └── js │ │ ├── jquery-viewer.js │ │ └── viewer.js ├── jquery │ └── 3.3.1 │ │ └── jquery.min.js └── mdui │ └── 0.4.1 │ ├── css │ └── mdui.min.css │ ├── fonts │ └── roboto │ │ ├── LICENSE.txt │ │ ├── Roboto-Black.woff │ │ ├── Roboto-Black.woff2 │ │ ├── Roboto-BlackItalic.woff │ │ ├── Roboto-BlackItalic.woff2 │ │ ├── Roboto-Bold.woff │ │ ├── Roboto-Bold.woff2 │ │ ├── Roboto-BoldItalic.woff │ │ ├── Roboto-BoldItalic.woff2 │ │ ├── Roboto-Light.woff │ │ ├── Roboto-Light.woff2 │ │ ├── Roboto-LightItalic.woff │ │ ├── Roboto-LightItalic.woff2 │ │ ├── Roboto-Medium.woff │ │ ├── Roboto-Medium.woff2 │ │ ├── Roboto-MediumItalic.woff │ │ ├── Roboto-MediumItalic.woff2 │ │ ├── Roboto-Regular.woff │ │ ├── Roboto-Regular.woff2 │ │ ├── Roboto-RegularItalic.woff │ │ ├── Roboto-RegularItalic.woff2 │ │ ├── Roboto-Thin.woff │ │ ├── Roboto-Thin.woff2 │ │ ├── Roboto-ThinItalic.woff │ │ └── Roboto-ThinItalic.woff2 │ ├── icons │ └── material-icons │ │ ├── LICENSE.txt │ │ ├── MaterialIcons-Regular.ijmap │ │ ├── MaterialIcons-Regular.woff │ │ └── MaterialIcons-Regular.woff2 │ └── js │ └── mdui.min.js ├── tests ├── default_test.go └── pem │ ├── private_key.pem │ └── public_key.pem ├── tools ├── FormPost.go ├── check.go ├── checkPorn.go ├── fileInfo.go ├── http_lib.go ├── image.go ├── lock.go ├── short.go ├── sina.go └── websocket.go ├── utils ├── ContentToForm.go ├── encryption.go ├── jwt.go ├── mail.go ├── pagination.go └── upload.go └── views ├── about └── about-me.tpl ├── admin └── index.html ├── auth ├── base.tpl ├── footer.tpl ├── forgot.tpl ├── header.tpl ├── login.tpl ├── msg.tpl ├── register.tpl └── reset.tpl ├── layouts ├── app.tpl ├── footer.tpl ├── header.tpl └── left.tpl ├── mail └── register.tpl ├── user ├── content │ ├── edit.tpl │ └── images.tpl ├── user_app.tpl ├── user_footer.tpl ├── user_header.tpl ├── user_script.tpl └── user_sider_bar.tpl └── webUpload ├── ban.tpl ├── box.tpl └── uploadScript.tpl /.dockerignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Go template 3 | # Binaries for programs and plugins 4 | *.exe 5 | *.exe~ 6 | *.dll 7 | *.so 8 | *.dylib 9 | 10 | # Test binary, built with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # Dependency directories (remove the comment below to include it) 17 | # vendor/ 18 | 19 | ### Example user template template 20 | ### Example user template 21 | 22 | # IntelliJ project files 23 | .idea 24 | *.iml 25 | out 26 | gen 27 | 28 | auxpi 29 | db/auxpi.db 30 | conf/install.lock 31 | conf/siteConfig.json -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.tpl linguist-language=Go 2 | *.js linguist-language=Go -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report(报告问题) 3 | about: Create a report to help us improve 4 | --- 5 | <!-- 6 | 注意:为更好的解决你的问题,请参考模板提供完整信息,准确描述问题,信息不全的 issue 将被关闭。 7 | 8 | Note: In order to better solve your problem, please refer to the template to provide complete information, accurately describe the problem, and the incomplete information issue will be closed. 9 | --> 10 | 11 | 12 | ## Bug report(问题描述) 13 | 14 | #### Steps to reproduce(问题复现步骤) 15 | 16 | 1. [xxx] 17 | 2. [xxx] 18 | 3. [xxxx] 19 | 20 | 21 | #### Screenshot or Gif(截图或动态图) 22 | 23 | 24 | #### Server environment(服务器环境) 25 | - Your OS & version (服务器系统&版本): 26 | - DataBase & version (数据库&版本): 27 | 28 | 29 | #### Other relevant information(格外信息) 30 | - auxpi version: -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question(提问) 3 | about: Asking questions about use 4 | --- 5 | 6 | ## Question(提问) 7 | 8 | <!-- 9 | 提问之前,请确定你已经过自己的努力,尝试解决过这个问题。 10 | 若是代码相关问题,请不要只截图,请提供在线 demo,以便节约彼此的时间。 11 | 12 | Before asking a question, please make sure that you have tried your best to solve this problem. 13 | If it's a code-related issue, please don't just take screenshots. Please provide an online demo to save each other's time. 14 | --> 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | auxpi 2 | auxpi.tar.gz 3 | siteConfig.conf 4 | *.lock 5 | *.tmp 6 | .idea 7 | .idea/* 8 | public/upload/* 9 | *.log 10 | resource/node_modules 11 | build/ 12 | .well-known 13 | .well-known/* 14 | *.memprof 15 | *.pprof 16 | 17 | # Binaries for programs and plugins 18 | *.exe 19 | *.exe~ 20 | *.dll 21 | *.so 22 | *.dylib 23 | *.idea 24 | *.log 25 | main 26 | .key 27 | .crt 28 | 29 | # Test binary, build with `go test -c` 30 | *.test 31 | 32 | # Output of the go coverage tool, specifically when used with LiteIDE 33 | *.out 34 | 35 | db/auxpi.db 36 | conf/install.lock 37 | conf/siteConfig.json -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | osx_image: xcode10.2 3 | sudo: true 4 | 5 | go: 6 | - 1.11.x 7 | - master 8 | 9 | os: 10 | - linux 11 | - osx 12 | 13 | env: 14 | - GO111MODULE=on 15 | 16 | cache: 17 | directories: 18 | - node_modules 19 | 20 | script: 21 | - bash build.sh all 99.99 clear 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.13-stretch AS builder 2 | 3 | ENV TZ Asia/Shanghai 4 | 5 | ENV GO111MODULE on 6 | 7 | ENV GOPROXY https://goproxy.cn 8 | 9 | WORKDIR $GOPATH/src/github.com/auxpi 10 | 11 | COPY . $GOPATH/src/github.com/auxpi 12 | 13 | RUN make build 14 | 15 | FROM debian:stretch-backports 16 | 17 | ENV TZ Asia/Shanghai 18 | 19 | COPY --from=builder /go/src/github.com/auxpi/auxpi /opt/go/auxpi 20 | 21 | COPY static /opt/go/static 22 | 23 | COPY views /opt/go/views 24 | 25 | #COPY db /opt/go/db 26 | RUN mkdir -p /opt/go/db /opt/go/conf 27 | 28 | # 持久化数据库 29 | VOLUME /opt/go/db 30 | # 持久化配置 31 | VOLUME /opt/go/conf 32 | 33 | COPY conf /opt/go/confbak 34 | 35 | COPY hack/run/entrypoint.sh /entrypoint.sh 36 | 37 | RUN chmod 777 /opt/go/auxpi \ 38 | && chmod 777 /entrypoint.sh 39 | 40 | WORKDIR /opt/go 41 | 42 | EXPOSE 2333 43 | 44 | ENTRYPOINT ["/entrypoint.sh"] 45 | 46 | CMD ["run"] 47 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: fmt vet lint default 2 | GO_RELEASE_TAGS := $(shell go list -f ':{{join (context.ReleaseTags) ":"}}:' runtime) 3 | 4 | # Only use the `-race` flag on newer versions of Go (version 1.3 and newer) 5 | ifeq (,$(findstring :go1.3:,$(GO_RELEASE_TAGS))) 6 | RACE_FLAG := 7 | else 8 | RACE_FLAG := -race -cpu 1,2,4 9 | endif 10 | 11 | # Run `go vet` on Go 1.12 and newer. For Go 1.5-1.11, use `go tool vet` 12 | ifneq (,$(findstring :go1.12:,$(GO_RELEASE_TAGS))) 13 | GO_VET := go vet \ 14 | -atomic \ 15 | -bool \ 16 | -copylocks \ 17 | -nilfunc \ 18 | -printf \ 19 | -rangeloops \ 20 | -unreachable \ 21 | -unsafeptr \ 22 | -unusedresult \ 23 | . 24 | else ifneq (,$(findstring :go1.5:,$(GO_RELEASE_TAGS))) 25 | GO_VET := go tool vet \ 26 | -atomic \ 27 | -bool \ 28 | -copylocks \ 29 | -nilfunc \ 30 | -printf \ 31 | -shadow \ 32 | -rangeloops \ 33 | -unreachable \ 34 | -unsafeptr \ 35 | -unusedresult \ 36 | . 37 | else 38 | GO_VET := @echo "go vet skipped -- not supported on this version of Go" 39 | endif 40 | 41 | fmt: ## fmt 42 | 43 | @echo gofmt -l 44 | @OUTPUT=`gofmt -l . 2>&1`; \ 45 | if [ "$OUTPUT" ]; then \ 46 | echo "gofmt must be run on the following files:"; \ 47 | echo "$OUTPUT"; \ 48 | exit 1; \ 49 | fi 50 | 51 | lint: ## lint 52 | 53 | @echo golint ./... 54 | @OUTPUT=`command -v golint >/dev/null 2>&1 && golint ./... 2>&1`; \ 55 | if [ "$OUTPUT" ]; then \ 56 | echo "golint errors:"; \ 57 | echo "$OUTPUT"; \ 58 | exit 1; \ 59 | fi 60 | 61 | vet: ## vet 62 | $(GO_VET) 63 | 64 | default: fmt lint vet 65 | 66 | .PHONY: build 67 | build: ## 构建 68 | GOARCH=amd64 GOOS=linux CGO_ENABLED=1 go build 69 | 70 | .PHONY: docker 71 | docker: ## 构建镜像 72 | # @docker build -t auxpi:base -f hack/docker/Dockerfile . 73 | @docker build -t ysicing/auxpi . 74 | 75 | help: ## this help 76 | @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $2);printf "\033[36m%-20s\033[0m %s\n", $1, $2}' $(MAKEFILE_LIST) 77 | -------------------------------------------------------------------------------- /auxpiAll/e/code.go: -------------------------------------------------------------------------------- 1 | package e 2 | 3 | const ( 4 | SUCCESS = 200 5 | ERROR = 500 6 | INVALID_PARAMS = 400 7 | METHOD_NOT_ALLOWED = 405 8 | FORBIDDEN = 403 9 | 10 | ERROR_FILE_IS_EMPTY = 10001 11 | ERROR_FILE_IS_TOO_LARGE = 10002 12 | ERROR_CAN_NOT_GET_IMG_URL = 10003 13 | ERROR_TOO_MANY_IMAGES = 10004 14 | ERROR_FILE_TYPE = 10005 15 | 16 | ERROR_AUTH_CHECK_TOKEN_FAIL = 20001 17 | ERROR_AUTH_CHECK_TOKEN_TIMEOUT = 20002 18 | ERROR_AUTH_TOKEN = 20003 19 | ERROR_AUTH = 20004 20 | ERROR_ACCESS_DENIED = 20005 21 | 22 | ERROR_TASK_REPEAT = 30001 23 | 24 | //USER ERROR 4xxx 25 | 26 | ERROR_USER_LOGIN = 40001 27 | ERROR_USER_COOKIE = 40002 28 | 29 | ERROR_USER_ALREADY_EXIST = 40003 30 | ERROR_USER_NOT_EXIST = 40004 31 | ERROR_USER_RESET_TOKEN = 40005 32 | ERROR_USER_UN_LOGIN = 40006 33 | ERROR_USER_DELTE = 40007 34 | 35 | //上传参数错误(api 选择) 36 | ERROR_UPLOAD_PARAM = 50001 37 | ERROR_CAN_NOT_UPLOAD = 50002 38 | ERROR_UPLOAD_TOKEN_ERROR = 50003 39 | ) 40 | -------------------------------------------------------------------------------- /auxpiAll/e/msg.go: -------------------------------------------------------------------------------- 1 | package e 2 | 3 | var MsgFlags = map[int]string{ 4 | SUCCESS: "ok", 5 | ERROR: "fail", 6 | 7 | INVALID_PARAMS: "请求参数错误", 8 | 9 | ERROR_FILE_IS_EMPTY: "上传文件为空", 10 | ERROR_FILE_IS_TOO_LARGE: "上传文件太大", 11 | ERROR_FILE_TYPE: "文件类型错误", 12 | ERROR_CAN_NOT_GET_IMG_URL: "无法获取第三方图床 URL", 13 | ERROR_TOO_MANY_IMAGES: "上传图片太多", 14 | ERROR_AUTH_CHECK_TOKEN_FAIL: "Token鉴权失败", 15 | ERROR_AUTH_CHECK_TOKEN_TIMEOUT: "Token 过期", 16 | ERROR_AUTH_TOKEN: "Token 不正确", 17 | ERROR_AUTH: "认证失败", 18 | ERROR_ACCESS_DENIED: "禁止访问", 19 | 20 | ERROR_TASK_REPEAT: "任务重复提交,请等待当前任务完成", 21 | 22 | ERROR_USER_LOGIN: "用户不存在或用户名密码错误", 23 | 24 | ERROR_USER_COOKIE: "用户 COOKIE 错误", 25 | 26 | ERROR_USER_ALREADY_EXIST: "用户已存在", 27 | ERROR_USER_NOT_EXIST: "用户不存在", 28 | ERROR_USER_RESET_TOKEN: "重置 Token 错误", 29 | ERROR_USER_UN_LOGIN: "用户未登录", 30 | 31 | ERROR_UPLOAD_PARAM: "上传参数错误", 32 | ERROR_CAN_NOT_UPLOAD: "无法上传图片到第三方图床", 33 | ERROR_UPLOAD_TOKEN_ERROR: "上传 Token 错误", 34 | } 35 | 36 | func GetMsg(code int) string { 37 | msg, ok := MsgFlags[code] 38 | if ok { 39 | return msg 40 | } 41 | return MsgFlags[ERROR] 42 | } 43 | -------------------------------------------------------------------------------- /auxpiAll/error.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package auxpi 15 | 16 | import ( 17 | "fmt" 18 | "path/filepath" 19 | "runtime" 20 | "strings" 21 | ) 22 | 23 | type Error struct { 24 | code uint32 25 | msg string 26 | where string 27 | } 28 | 29 | func (e *Error) Error() string { 30 | return fmt.Sprintf("code = %d ; msg = %s", e.code, e.msg) 31 | } 32 | 33 | func NewCoder(code uint32, msg string) *Error { 34 | where := caller(1, false) 35 | return &Error{code: code, msg: msg, where: where} 36 | } 37 | 38 | func Wrap(err error, extMsg ...string) *Error { 39 | msg := err.Error() 40 | if len(extMsg) != 0 { 41 | msg = strings.Join(extMsg, ":") + ":" + msg 42 | } 43 | return &Error{msg: msg} 44 | } 45 | 46 | func caller(calldepth int, short bool) string { 47 | _, file, line, ok := runtime.Caller(calldepth + 1) 48 | if !ok { 49 | file = "???" 50 | line = 0 51 | } else { 52 | file = filepath.Base(file) 53 | } 54 | 55 | return fmt.Sprintf("%s:%d", file, line) 56 | } 57 | 58 | //统一化处理为 并且转为 string 类型 59 | //[xxxxx] : "xxxxxxxxxxxxxx" ==>[file:line] 60 | func ErrorToString(err error, tip ...string) string { 61 | if err != nil { 62 | content := fmt.Sprintf("%v", err) 63 | prefix := "" 64 | if len(tip) != 0 { 65 | prefix = "[" + tip[0] + "]" 66 | } 67 | e := prefix + content + ` ===>[` + caller(1, false) + "]" 68 | 69 | return e 70 | } 71 | return "" 72 | } 73 | 74 | func FormatError(err error, tip ...string) (fErr error) { 75 | fErr = fmt.Errorf("%v", ErrorToString(err)) 76 | return 77 | } 78 | -------------------------------------------------------------------------------- /conf/app.conf: -------------------------------------------------------------------------------- 1 | # Base Config 2 | appname = auxpi 3 | # HTTP_PORT 4 | httpport = 2333 5 | #MODEL dev|prod 6 | runmode = dev 7 | EnableGzip = true 8 | 9 | #XSRF 10 | enablexsrf = true 11 | xsrfkey = HIDoas923n;'0shd3jlc903jsp[a332 12 | xsrfexpire = 3600 13 | copyrequestbody = true 14 | sessionon = true 15 | 16 | #Cache 17 | driver = memory #memory|file|redis|memcache 18 | gcTime = 60 # second 19 | 20 | #File Cache 21 | cachePath = ./cache 22 | fileSuffix = .cache 23 | directoryLevel = 2 24 | EmbedExpiry = 120 25 | 26 | #Redis 27 | redisCollection = auxpi 28 | redisPort = 6379 29 | redisPassword = 30 | 31 | #Memcache 32 | memcacheConn = 127.0.0.1:11211 33 | 34 | #SSL 35 | forceSSL = false 36 | EnableHTTPS = false 37 | EnableHttpTLS = true 38 | HTTPSPort = 4333 39 | HTTPSCertFile = "/Users/aimer/.acme.sh/ttt.demo-1s.com/ttt.demo-1s.com.cer" 40 | HTTPSKeyFile = "/Users/aimer/.acme.sh/ttt.demo-1s.com/ttt.demo-1s.com.key" 41 | 42 | #beego admin 43 | EnableAdmin = false 44 | AdminAddr = "localhost" 45 | AdminPort = 8088 46 | 47 | 48 | -------------------------------------------------------------------------------- /controllers/admin.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package controllers 15 | 16 | import "github.com/astaxie/beego" 17 | 18 | type AdminController struct { 19 | beego.Controller 20 | } 21 | 22 | //渲染前端单页面 23 | func (a *AdminController) Index() { 24 | a.TplName = "admin/index.html" 25 | } 26 | -------------------------------------------------------------------------------- /controllers/api/base/api.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "github.com/astaxie/beego" 5 | "github.com/auxpi/bootstrap" 6 | "github.com/auxpi/controllers" 7 | "github.com/auxpi/models" 8 | ) 9 | 10 | type ApiController struct { 11 | beego.Controller 12 | controllers.Base 13 | } 14 | 15 | var picType = []string{"png", "jpg", "jpeg", "gif", "bmp"} 16 | 17 | //所有的 APi 不需要开启 CSRF 18 | func (a *ApiController) Prepare() { 19 | a.EnableXSRF = false 20 | } 21 | 22 | func (a *ApiController) Migrate() { 23 | models.CreateAdminRole() 24 | a.ServeJSON() 25 | } 26 | 27 | func (a *ApiController) ShowIt() { 28 | a.Data["json"] = bootstrap.SiteConfig 29 | a.ServeJSON() 30 | } 31 | -------------------------------------------------------------------------------- /controllers/api/v1/upload.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/auxpi/auxpiAll/e" 7 | "github.com/auxpi/bootstrap" 8 | "github.com/auxpi/controllers/api/base" 9 | "github.com/auxpi/models" 10 | ) 11 | 12 | type ApiUploadController struct { 13 | base.ApiController 14 | } 15 | 16 | var picType = []string{"png", "jpg", "jpeg", "gif", "bmp"} 17 | 18 | func (a *ApiUploadController) UpLoadHandle() { 19 | //默认游客 20 | userID := 0 21 | ip := a.Ctx.Input.IP() 22 | 23 | user := a.Ctx.Input.GetData("user_info") 24 | u, _ := user.(models.User) 25 | userID = u.ID 26 | //} 27 | //获取上传类型 28 | apiSelect := a.GetString("apiSelect") 29 | f, h, err := a.GetFile("image") 30 | if f == nil { 31 | a.ErrorResp(e.ERROR_FILE_IS_EMPTY) 32 | } 33 | if h.Size > bootstrap.SiteConfig.SiteUploadMaxSize<<20 { 34 | a.ErrorResp(e.ERROR_FILE_IS_TOO_LARGE) 35 | } 36 | defer f.Close() 37 | if err != nil { 38 | log.Fatal("File Upload Err", err) 39 | } 40 | //验证 41 | validate := a.Validate(h.Header.Get("Content-Type"), h.Filename) 42 | if validate { 43 | resp, _ := a.UploadHandle(userID, apiSelect, h, ip, true) 44 | a.Data["json"] = resp 45 | a.ServeJSON() 46 | } 47 | //返回失败 json 48 | a.Data["json"] = a.ErrorResp(e.ERROR_FILE_TYPE) 49 | a.ServeJSON() 50 | return 51 | } 52 | -------------------------------------------------------------------------------- /controllers/webUpLoad.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package controllers 15 | 16 | import ( 17 | "log" 18 | "strconv" 19 | 20 | "github.com/astaxie/beego" 21 | auxpi "github.com/auxpi/auxpiAll" 22 | "github.com/auxpi/auxpiAll/e" 23 | auxpiLog "github.com/auxpi/log" 24 | "github.com/auxpi/models" 25 | ) 26 | 27 | type WebUpLoadController struct { 28 | beego.Controller 29 | Base 30 | } 31 | 32 | var picType = []string{"png", "jpg", "jpeg", "gif", "bmp"} 33 | 34 | var site auxpi.SiteBase 35 | 36 | func init() { 37 | err := site.UnmarshalJSON([]byte(models.GetOption("site_base", "conf"))) 38 | if err != nil { 39 | auxpiLog.SetAWarningLog("CONTROLLER", err) 40 | } 41 | } 42 | 43 | //代码冗余,但是使用 API 会造成不必要的消耗 44 | func (w *WebUpLoadController) UpLoadHandle() { 45 | //获取用户信息 46 | userId, _ := strconv.Atoi(w.Ctx.GetCookie("id")) 47 | ip := w.Ctx.Input.IP() 48 | //获取上传类型 49 | apiSelect := w.GetString("apiSelect") 50 | f, h, err := w.GetFile("image") 51 | defer f.Close() 52 | if err != nil { 53 | log.Fatal("File Upload Err", err) 54 | } 55 | //是否为空文件 56 | if f == nil { 57 | w.ErrorResp(e.ERROR_FILE_IS_EMPTY) 58 | return 59 | } 60 | //检测是否超出大小限制 61 | if h.Size > site.SiteUploadMaxSize<<20 { 62 | w.ErrorResp(e.ERROR_FILE_IS_TOO_LARGE) 63 | return 64 | } 65 | //验证 66 | validate := w.Validate(h.Header.Get("Content-Type"), h.Filename) 67 | if validate { 68 | resp, _ := w.UploadHandle(userId, apiSelect, h, ip, true) 69 | w.Data["json"] = resp 70 | w.ServeJSON() 71 | } 72 | w.Data["json"] = w.ErrorResp(e.ERROR_FILE_TYPE) 73 | w.ServeJSON() 74 | return 75 | } 76 | -------------------------------------------------------------------------------- /controllers/ws/websocket.go: -------------------------------------------------------------------------------- 1 | package ws 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/auxpi/tools" 7 | "github.com/auxpi/utils" 8 | 9 | "github.com/astaxie/beego" 10 | "github.com/gorilla/websocket" 11 | ) 12 | 13 | type WebSocketController struct { 14 | beego.Controller 15 | } 16 | 17 | func (this *WebSocketController) Prepare() { 18 | this.EnableXSRF = false 19 | } 20 | 21 | var clients = make(map[*websocket.Conn]bool) 22 | 23 | func (this *WebSocketController) Join() { 24 | //update 25 | upgrader := websocket.Upgrader{ 26 | CheckOrigin: func(r *http.Request) bool { 27 | return true 28 | }, 29 | } 30 | //需要验证 cookie 31 | token := this.Ctx.Input.Cookie("Admin-Token") 32 | 33 | _, err := utils.ParseToken(token) 34 | if err != nil { 35 | beego.Alert("Token parsing unsuccessful") 36 | return 37 | } 38 | 39 | ws, err := upgrader.Upgrade(this.Ctx.ResponseWriter, this.Ctx.Request, nil) 40 | clients = tools.AddClient(ws) 41 | 42 | if err != nil { 43 | beego.Alert("[Upgrade To WebSocket Error] :", err) 44 | } 45 | 46 | go handleMessage() 47 | this.ServeJSON() 48 | 49 | defer ws.Close() 50 | 51 | // Message receive loop. 52 | var read = make(map[string]string) 53 | 54 | for { 55 | err = ws.ReadJSON(&read) 56 | if err != nil { 57 | beego.Alert("[Json Read Error] :", err, clients) 58 | delete(clients, ws) 59 | beego.Alert("Now Client:", clients) 60 | err = ws.Close() 61 | if err != nil { 62 | beego.Alert(err) 63 | } 64 | break 65 | } 66 | 67 | } 68 | 69 | } 70 | 71 | func handleMessage() { 72 | for client := range clients { 73 | beego.Alert("当前存在的客户端:", clients) 74 | for { 75 | select { 76 | case msg := <-tools.MsgChan: 77 | beego.Alert(msg) 78 | err := client.WriteJSON(msg) 79 | beego.Alert(clients) 80 | if err != nil { 81 | beego.Alert(clients) 82 | beego.Alert("[Write Error]:", err) 83 | //client.Close() 84 | delete(clients, client) 85 | return 86 | } 87 | } 88 | 89 | } 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /db/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/db/.gitkeep -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/auxpi 2 | 3 | require ( 4 | github.com/astaxie/beego v1.11.1 5 | github.com/casbin/casbin v1.7.0 6 | github.com/casbin/gorm-adapter v0.0.0-20190318080705-e74a050c51a4 7 | github.com/dgrijalva/jwt-go v3.2.0+incompatible 8 | github.com/go-sql-driver/mysql v1.4.1 9 | github.com/gofrs/uuid v3.2.0+incompatible 10 | github.com/gorilla/websocket v1.4.0 11 | github.com/jinzhu/gorm v1.9.10 12 | github.com/kr/pretty v0.1.0 // indirect 13 | github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983 14 | github.com/pkg/errors v0.8.0 15 | github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a 16 | google.golang.org/appengine v1.5.0 // indirect 17 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect 18 | gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df 19 | gopkg.in/masci/flickr.v2 v2.0.0-20161216033441-3cc496dc15cd 20 | gopkg.in/yaml.v2 v2.2.2 21 | ) 22 | 23 | go 1.13 24 | -------------------------------------------------------------------------------- /hack/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.13-stretch 2 | 3 | ENV TZ Asia/Shanghai 4 | 5 | ENV GO111MODULE on 6 | 7 | ENV GOPROXY https://goproxy.cn 8 | 9 | WORKDIR $GOPATH/src/github.com/auxpi 10 | 11 | COPY . $GOPATH/src/github.com/auxpi -------------------------------------------------------------------------------- /hack/run/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | USERNAME=${USERNAME:-admin} 4 | EMAIL=${EMAIL:-auxpi@example.com} 5 | PASSWORD=${PASSWORD:-12345678} 6 | 7 | # 检查是否已经初始化 8 | [ -f "/opt/go/conf/app.conf" ] || cp -a /opt/go/confbak/app.conf /opt/go/conf/app.conf 9 | [ -f "/opt/go/conf/siteConfig.json" ] || ( 10 | /opt/go/auxpi migrate 11 | /opt/go/auxpi -mod=admin -name=${USERNAME} -email=${EMAIL} -pass=${PASSWORD} 12 | ) 13 | 14 | if [ "$1" = "bash" -o "$1" = "sh" -o "$1" = "ash" ]; then 15 | exec /bin/bash 16 | else 17 | exec /opt/go/auxpi "$@" 18 | fi -------------------------------------------------------------------------------- /middleware/auth.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package middleware 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/astaxie/beego/context" 20 | auxpi "github.com/auxpi/auxpiAll" 21 | "github.com/auxpi/auxpiAll/e" 22 | auxpiLog "github.com/auxpi/log" 23 | "github.com/auxpi/models" 24 | ) 25 | 26 | var Upload = func(ctx *context.Context) { 27 | token := ctx.Input.Header("Authorization") 28 | var api = auxpi.ApiOptions{} 29 | err := api.UnmarshalJSON([]byte(models.GetOption("api_option", "conf"))) 30 | if err != nil { 31 | auxpiLog.SetAWarningLog("MIDDLEWARE", err) 32 | } 33 | fmt.Println(api) 34 | if token == "" { 35 | //API 是否需要认证 36 | if api.Auth { 37 | JWT(ctx) 38 | return 39 | } 40 | //如果开放对外的 api 接口,则无需验证 41 | return 42 | } 43 | //解析 token 44 | user, status := models.GetUserInfoByToken(token) 45 | if status { 46 | //将用户信息写入 ctx 47 | fmt.Println("sldkjlsakjf======>>>>>") 48 | ctx.Input.SetData("user_info", user) 49 | return 50 | } 51 | //返回错误 52 | errorInfo := auxpi.RespJson{ 53 | Code: e.ERROR_UPLOAD_TOKEN_ERROR, 54 | Msg: e.GetMsg(e.ERROR_UPLOAD_TOKEN_ERROR), 55 | } 56 | info, _ := errorInfo.MarshalJSON() 57 | ctx.Output.Header("Content-Type", "application/json; charset=UTF-8") 58 | ctx.ResponseWriter.Write(info) 59 | return 60 | } 61 | -------------------------------------------------------------------------------- /middleware/jwt.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package middleware 15 | 16 | import ( 17 | "fmt" 18 | "time" 19 | 20 | "github.com/auxpi/auxpiAll" 21 | "github.com/auxpi/auxpiAll/e" 22 | "github.com/auxpi/utils" 23 | 24 | "github.com/astaxie/beego/context" 25 | ) 26 | 27 | var JWT = func(ctx *context.Context) { 28 | var code int 29 | var data interface{} 30 | var token string 31 | 32 | code = e.SUCCESS 33 | token = ctx.Request.Header.Get("X-Token") 34 | fmt.Println("JWJWJWJWJWJTTTTTTTTTTTTTTTTTT") 35 | if token == "" { 36 | code = e.INVALID_PARAMS 37 | } else { 38 | claims, err := utils.ParseToken(token) 39 | if err != nil { 40 | code = e.ERROR_AUTH_CHECK_TOKEN_FAIL 41 | } else if time.Now().Unix() > claims.ExpiresAt { 42 | code = e.ERROR_AUTH_CHECK_TOKEN_TIMEOUT 43 | } 44 | } 45 | if code != e.SUCCESS { 46 | errorInfo := auxpi.RespJson{ 47 | Code: code, 48 | Msg: e.GetMsg(code), 49 | Data: data, 50 | } 51 | info, _ := errorInfo.MarshalJSON() 52 | ctx.Output.Header("Content-Type", "application/json; charset=UTF-8") 53 | ctx.ResponseWriter.Write(info) 54 | return 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /middleware/redirect.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package middleware 15 | 16 | import ( 17 | "github.com/astaxie/beego/context" 18 | ) 19 | 20 | var SSLRedirect = func(ctx *context.Context) { 21 | //fmt.Println(ctx.Input.Scheme()) 22 | //if ctx.Input.Scheme() == "http" { 23 | // fmt.Println(ctx.Input.Domain()) 24 | // fmt.Println(ctx.Input.Port()) 25 | // fmt.Println(ctx.Input.URI()) 26 | // port := strconv.Itoa(ctx.Input.Port()) 27 | // url := "https://" + ctx.Input.Domain() + ":" + port + ctx.Input.URI() 28 | // ctx.Redirect(302, url) 29 | //} 30 | //acme.sh --issue -d ssl.demo-1s.com --webroot /root/auxpi/static/ 31 | } 32 | -------------------------------------------------------------------------------- /models/casbin.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package models 15 | 16 | import ( 17 | "fmt" 18 | 19 | "github.com/casbin/casbin" 20 | "github.com/casbin/gorm-adapter" 21 | _ "github.com/go-sql-driver/mysql" 22 | ) 23 | 24 | func Create() { 25 | a := gormadapter.NewAdapter("mysql", "root:root@tcp(127.0.0.1:3306)/auxpi", true) 26 | e := casbin.NewEnforcer("conf/rbac_model.conf", a) 27 | err := e.LoadPolicy() 28 | if err != nil { 29 | fmt.Println(err) 30 | } 31 | 32 | e.AddPolicy("admin", "app", "/app/1", "GET") 33 | e.AddGroupingPolicy("alice", "admin", "app") 34 | 35 | err = e.SavePolicy() 36 | if err != nil { 37 | fmt.Println(err) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /models/ips.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/auxpi/auxpiAll" 5 | ) 6 | 7 | type IP struct { 8 | Model 9 | 10 | Content string 11 | Status int //-1,0,1 || 永久 ,设定时间 block ,白名单 12 | } 13 | 14 | func CreateIpInfo(ip IP) bool { 15 | err := db.Create(&IP{ 16 | Content: ip.Content, 17 | Status: ip.Status, 18 | }).Error 19 | return modelsError(auxpi.ErrorToString(err)) 20 | } 21 | 22 | func DeleteIp(ip string) bool { 23 | err := db.Model(&IP{}). 24 | Where("content=?", ip). 25 | Delete(&IP{}). 26 | Error 27 | return modelsError(auxpi.ErrorToString(err)) 28 | } 29 | -------------------------------------------------------------------------------- /models/logs.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/auxpi/auxpiAll" 5 | ) 6 | 7 | type Log struct { 8 | Model 9 | 10 | Type string `json:"type" gorm:"size:32"` 11 | Content string `json:"content" gorm:"size:255"` 12 | Part string `json:"part" gorm:"size:32"` 13 | Level string `json:"level" gorm:"size:32"` 14 | } 15 | 16 | //创建日志 17 | func AddLog(t, content, part, level string) { 18 | db.Create(&Log{ 19 | Type: t, 20 | Content: content, 21 | Part: part, 22 | Level: level, 23 | }) 24 | } 25 | 26 | //查询日志 27 | func GetLogs(offset, limit int, maps interface{}) (log []Log, count int) { 28 | err := db.Model(&Log{}). 29 | Where(maps). 30 | Count(&count). 31 | Offset(offset). 32 | Limit(limit). 33 | Find(&log).Error 34 | 35 | modelsError(auxpi.ErrorToString(err)) 36 | 37 | return 38 | } 39 | 40 | //查询 api 使用情况 41 | func GetApiInfo() (apis []Report) { 42 | err := db.Model(&Log{}). 43 | Where("type=?", "API Call"). 44 | Select("COUNT(*) AS `number` , created_day AS `date`"). 45 | Order("created_day DESC"). 46 | Group("`created_day`"). 47 | Limit(7). 48 | Scan(&apis).Error 49 | modelsError(auxpi.ErrorToString(err)) 50 | 51 | return 52 | } 53 | 54 | //增加 API 调用记录 55 | func AddApiLog(content string) { 56 | db.Create(&Log{ 57 | Type: "API Call", 58 | Content: content, 59 | Part: "SYSTEM", 60 | Level: "NONE", 61 | }) 62 | } 63 | 64 | //迁移Logs 数据表 65 | func MigrateLogs() error { 66 | if db.HasTable(&Log{}) { 67 | err := db.DropTable(&Log{}).Error 68 | err = db.CreateTable(&Log{}).Error 69 | return err 70 | } else { 71 | err := db.CreateTable(&Log{}).Error 72 | return err 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /models/permissions.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/auxpi/auxpiAll" 5 | 6 | "github.com/astaxie/beego/logs" 7 | ) 8 | 9 | type Permission struct { 10 | Model 11 | 12 | Name string `gorm:"unique;not null VARCHAR(191)" json:"name"` 13 | DisplayName string `gorm:"VARCHAR(191)" json:"display_name"` 14 | Description string `gorm:"VARCHAR(191)" json:"description"` 15 | //匹配的路由黑名单 16 | //RouterBlock string 17 | } 18 | 19 | func GetPermissionsByIds(ids []uint) (ps []*Permission) { 20 | err := db.Model(&Permission{}).Where(ids).Find(&ps).Error 21 | if err != nil { 22 | logs.Alert("[DataBase Error] :", err) 23 | return 24 | } 25 | return 26 | } 27 | 28 | func GetPermissionsById(id uint) (p *Permission) { 29 | err := db.Model(&Permission{}).Where("id=?", id).First(&p).Error 30 | 31 | modelsError(auxpi.ErrorToString(err)) 32 | 33 | return 34 | } 35 | 36 | func createAdminPermissions() { 37 | var p = new(Permission) 38 | p.ID = 1 39 | p.Name = "All" 40 | p.Description = "具有所有权限" 41 | p.DisplayName = "所有权限" 42 | db.Create(p) 43 | 44 | p.ID = 2 45 | p.Name = "edit_user" 46 | p.Description = "edit_user" 47 | p.DisplayName = "修改用户" 48 | db.Create(p) 49 | 50 | p.ID = 3 51 | p.Name = "edit_image" 52 | p.Description = "edit_image" 53 | p.DisplayName = "修改图片" 54 | db.Create(p) 55 | 56 | p.ID = 4 57 | p.Name = "upload_image" 58 | p.Description = "upload_image" 59 | p.DisplayName = "上传图片" 60 | db.Create(p) 61 | 62 | p.ID = 5 63 | p.Name = "delete_image" 64 | p.Description = "delete_image" 65 | p.DisplayName = "删除图片" 66 | db.Create(p) 67 | 68 | } 69 | 70 | func MigratePermissions() error { 71 | if db.HasTable(&Permission{}) { 72 | err := db.DropTable(&Permission{}).Error 73 | err = db.CreateTable(&Permission{}).Error 74 | createAdminPermissions() 75 | return err 76 | } else { 77 | err := db.CreateTable(&Permission{}).Error 78 | createAdminPermissions() 79 | return err 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /models/roles.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/auxpi/auxpiAll" 5 | ) 6 | 7 | type Role struct { 8 | Model 9 | 10 | Name string `gorm:"unique;not null VARCHAR(191)" json:"name"` 11 | DisplayName string `gorm:"VARCHAR(191)" json:"display_name"` 12 | Description string `gorm:"VARCHAR(191)" json:"description"` 13 | 14 | Perms []*Permission `gorm:"many2many:role_perms;" json:"perms"` 15 | } 16 | 17 | const ( 18 | ROLE_ADMIN = 1 19 | ROLE_EDITER = 2 20 | ROLE_NORMAL_USER = 3 21 | ROLE_BLOCKED_USER = 4 22 | ) 23 | 24 | func CreateRole(role auxpi.RoleJson) bool { 25 | err := db.Create(&Role{ 26 | Name: role.Name, 27 | DisplayName: role.DisplayName, 28 | Description: role.Description, 29 | Perms: GetPermissionsByIds(role.PIDs), 30 | }).Error 31 | 32 | return modelsError(auxpi.ErrorToString(err)) 33 | } 34 | 35 | func CreateAdminRole() { 36 | var role = new(Role) 37 | role.ID = ROLE_ADMIN 38 | role.Name = "admin" 39 | role.Description = `可以对用户\用户权限\图片\API\站点 进行管理` 40 | role.DisplayName = `管理员` 41 | var ids = make([]uint, 1) 42 | ids[0] = 1 43 | role.Perms = GetPermissionsByIds(ids) 44 | db.Create(role) 45 | 46 | role.ID = ROLE_NORMAL_USER 47 | role.Name = "normalUser" 48 | role.Description = `可以上传图片,管理自己的图片` 49 | role.DisplayName = `普通用户` 50 | ids = []uint{4, 5} 51 | role.Perms = GetPermissionsByIds(ids) 52 | db.Create(role) 53 | 54 | role.ID = ROLE_BLOCKED_USER 55 | role.Name = "blockUser" 56 | role.DisplayName = `封禁的用户` 57 | role.Description = "无法登录,无法进行任何操作,小黑屋用户" 58 | db.Create(role) 59 | } 60 | 61 | func MigrateRole() error { 62 | if db.HasTable(&Role{}) { 63 | err := db.DropTable(&Role{}).Error 64 | err = db.CreateTable(&Role{}).Error 65 | return err 66 | } else { 67 | err := db.CreateTable(&Role{}).Error 68 | return err 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /pem/private_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvAIBADALBgkqhkiG9w0BAQEEggSoMIIEpAIBAAKCAQEAya++QyM5GtpsNio7 3 | x8Ee4ktHGvBsmfzbFXiOTV4Ghq/5ys0BdUeDVfnnY/zI2bc8wtCqjdhXsNMdBVRO 4 | O6gGG5li0DPxWl3ggvn6kCIMhRfOuiexsO7aLsNJRbf6Y0SHBWyp0d9KrCV1UWpP 5 | MNafrC3j61Dg5Okt8iGiWOE4OwLBRJqrjjvnKIWOsjCmx7RvFfjMkMexy2hklidf 6 | T70SVUFie45JUK3FJU0CURehfXXp0UjIzvJBXzwc3yAzZry0/hzAsS8RnHgXp7P/ 7 | Kj993vSHlCirijzlwOBsIyEB9Ai5WFzM0OB3X7oALSQaSiWpNMGiO4AAQ3F2bk9t 8 | ECsjrwIDAQABAoIBAQCZQbpKOhHCngdsgVs7xzw4qQs3JUrhGItCHYHEuJYs8rvV 9 | p0JcZCMgye1SxVu6VMsPHpD7iFHaRBHhYtav7lX10vCLVW0pRfy8ikgkDjuFRzoH 10 | qvITiOyybCLZn5vcos4XCSNiH1MWzMABRc83RV+/7n8q6SJ7z9TiETzUXQ/lhi71 11 | NpYt/cyhlMDAx1T7TTr5x8YGSyvpmRwnPNzIgYP46nmqjxUYTXNpuL9HP3L2NYBZ 12 | /XxgSClnlVeTrr+awmdriur07Hz6HRJLCPRVmQ/Ltz7UGDsoVTdwet47+XD04KuV 13 | Ts6MKLwJvtxM4GJDIzTlKo815nsRB2DF886bt0IBAoGBAMt1mSIcjY/6D7RI0pXE 14 | Z7B2J84xmUjCy0elEOxd8nI3SfXWU712eomh1ANMSFNk4RSU9PfINxR/Y5Ndflf1 15 | VdfM3ctDJI2U0dqmMex/j0A6iTvvYwVk+NSvUo1AfVCrEt9A+aWHufwJjZ3ve7yY 16 | s9Mlg6XzipjvGr7DH++W6gqPAoGBAP3E8XCU0m8zjXzdtU2TY37N3Jd8/YsE4v7B 17 | LCRefgdTuWU3lkF2FwsIM32ZmtGfy91sCv5Q2vSzG9y8shWgWwzTOSr5iclKbM5M 18 | VoZ7FGRwcVPkeo88f9JdlN5QxcJmxGr7vUdOdYWlZ8cPFKa2T3S3R5YLEKoJMRRL 19 | dxsGKGThAoGBAMM18ddozep2Ytr3hBVufI4yz75mmEvXmnMDTVl8SkKMCcp1+aKv 20 | KqMjQehoKHzbLZox0VhsIWzpTQD3k2GRYuvLBIMhyNCPGUpQa1YejbNydnmrFbb3 21 | SkfGb85XMeVUPqc2EFFiCHBqOhZu0KoDWYYdWFLBeRmDUIX3cYzPn37BAoGAUN+w 22 | 6mYjYlkVoFOv8hckwEavJIAq9WELTpEVlkme9IrULNO4SQhvc46bik2nr2Kzv88s 23 | +bue7Bkgqgpg3s+J9N5j+7QnG0Viw6REdvtGlnPXShsoi/mF6u70AJ3RSJEjy8yK 24 | l+0DOyJpnmDJ/g9f5xx57fF80BO51nPuc2hU+0ECgYAkFeiv7JOeULblbXUXZY38 25 | 9/AUkt7nDJ+hhxNJ5b4riKs0CDJk3EMYsao00J7acOxbJ7z3tGUmSEOOdpcZfp1e 26 | nMCV/zhRNkXqMKS+TZ7LfRkegFkLowwRIRGq/WbRTAwiFkjlzDpfoxFrsEmb4jh9 27 | RVGDihYIJeBfsjhJLjs/9Q== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /pem/public_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAya++QyM5GtpsNio7x8Ee 3 | 4ktHGvBsmfzbFXiOTV4Ghq/5ys0BdUeDVfnnY/zI2bc8wtCqjdhXsNMdBVROO6gG 4 | G5li0DPxWl3ggvn6kCIMhRfOuiexsO7aLsNJRbf6Y0SHBWyp0d9KrCV1UWpPMNaf 5 | rC3j61Dg5Okt8iGiWOE4OwLBRJqrjjvnKIWOsjCmx7RvFfjMkMexy2hklidfT70S 6 | VUFie45JUK3FJU0CURehfXXp0UjIzvJBXzwc3yAzZry0/hzAsS8RnHgXp7P/Kj99 7 | 3vSHlCirijzlwOBsIyEB9Ai5WFzM0OB3X7oALSQaSiWpNMGiO4AAQ3F2bk9tECsj 8 | rwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /resource/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins":["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /resource/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | insert_final_newline = false 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /resource/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | src/assets 4 | -------------------------------------------------------------------------------- /resource/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /resource/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-present PanJiaChen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /resource/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"', 7 | BASE_API: '"http://localhost:2333/api/v1"', 8 | }) 9 | -------------------------------------------------------------------------------- /resource/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"', 4 | BASE_API: '"/api/v1"', 5 | } 6 | -------------------------------------------------------------------------------- /resource/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/resource/favicon.ico -------------------------------------------------------------------------------- /resource/index.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html> 3 | <head> 4 | <meta charset="utf-8"> 5 | <meta name="viewport" content="width=device-width,initial-scale=1.0"> 6 | <title>Auxpi-Admin</title> 7 | </head> 8 | <body> 9 | <div id="app"></div> 10 | <!-- built files will be auto injected --> 11 | </body> 12 | </html> 13 | -------------------------------------------------------------------------------- /resource/src/App.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div id="app"> 3 | <router-view/> 4 | </div> 5 | </template> 6 | 7 | <script> 8 | export default { 9 | name: 'App' 10 | } 11 | </script> 12 | -------------------------------------------------------------------------------- /resource/src/api/dashbroad.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | // 首页图床各状况统计 4 | export function getStorePercent() { 5 | return request({ 6 | url: '/admin/get_store_report', 7 | method: 'get' 8 | }) 9 | } 10 | 11 | export function getUserSevenReport() { 12 | return request({ 13 | url: '/admin/get_user_report', 14 | method: 'get' 15 | }) 16 | } 17 | 18 | export function getApiSevenReport() { 19 | return request({ 20 | url: '/admin/get_api_report', 21 | method: 'get' 22 | }) 23 | } 24 | 25 | export function getAllImageSevenReport() { 26 | return request({ 27 | url: '/admin/get_all_images_report', 28 | method: 'get' 29 | }) 30 | } 31 | 32 | export function getLocalImageSevenReport() { 33 | return request({ 34 | url: '/admin/get_local_images_report', 35 | method: 'get' 36 | }) 37 | } 38 | 39 | export function getAuxpiSystemInfo() { 40 | return request({ 41 | url: '/admin/get_auxpi_info', 42 | method: 'get' 43 | }) 44 | } 45 | 46 | -------------------------------------------------------------------------------- /resource/src/api/dispatch.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getDispatchList(params) { 4 | return request({ 5 | url: '/admin/get_dispatch_list', 6 | method: 'get', 7 | params 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /resource/src/api/image.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getImageList(params) { 4 | return request({ 5 | url: '/admin/get_images_list', 6 | method: 'get', 7 | params 8 | }) 9 | } 10 | 11 | export function delImage(id) { 12 | return request({ 13 | url: '/admin/del_images', 14 | method: 'post', 15 | data: { 16 | id: id 17 | } 18 | }) 19 | } 20 | 21 | export function getStoreList() { 22 | return request({ 23 | url: '/admin/get_store_list', 24 | method: 'get' 25 | }) 26 | } 27 | 28 | export function syncImage(params) { 29 | return request({ 30 | url: '/admin/sync_images', 31 | method: 'post', 32 | data: { 33 | list: params 34 | } 35 | }) 36 | } 37 | 38 | export function getSyncImages(params) { 39 | return request({ 40 | url: '/admin/get_sync_images', 41 | method: 'get', 42 | params 43 | }) 44 | } 45 | 46 | export function deleteSyncImageList(id) { 47 | return request({ 48 | url: '/admin/del_sync_images', 49 | method: 'post', 50 | data: { 51 | id: id 52 | } 53 | }) 54 | } 55 | -------------------------------------------------------------------------------- /resource/src/api/log.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getLogs(params) { 4 | return request({ 5 | url: '/admin/get_logs_list', 6 | method: 'get', 7 | params 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /resource/src/api/login.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | import { stringify } from 'qs' 3 | export function login(username, password) { 4 | return request({ 5 | url: '/auth/login', 6 | method: 'post', 7 | data: stringify({ 8 | username, 9 | password 10 | }) 11 | }) 12 | } 13 | 14 | export function getInfo(token) { 15 | return request({ 16 | url: '/auth/info', 17 | method: 'get', 18 | params: { token } 19 | }) 20 | } 21 | 22 | export function logout() { 23 | return request({ 24 | url: '/auth/logout', 25 | method: 'post' 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /resource/src/api/table.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getList(params) { 4 | return request({ 5 | url: 'test/table/list', 6 | method: 'get', 7 | params 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /resource/src/api/user.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getUser(params) { 4 | return request({ 5 | url: '/admin/get_users_list', 6 | method: 'get', 7 | params 8 | }) 9 | } 10 | 11 | export function getUserImages(uid, params) { 12 | return request({ 13 | url: '/users/' + uid + '/images', 14 | method: 'get', 15 | params 16 | }) 17 | } 18 | 19 | export function getUserInfo(uid) { 20 | return request({ 21 | url: '/users/' + uid + '/info', 22 | method: 'get' 23 | }) 24 | } 25 | 26 | export function DeleteUser(uid) { 27 | return request({ 28 | url: '/admin/delete_user', 29 | method: 'post', 30 | data: { id: uid } 31 | }) 32 | } 33 | 34 | -------------------------------------------------------------------------------- /resource/src/assets/404_images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/resource/src/assets/404_images/404.png -------------------------------------------------------------------------------- /resource/src/assets/404_images/404_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/resource/src/assets/404_images/404_cloud.png -------------------------------------------------------------------------------- /resource/src/assets/load.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/resource/src/assets/load.gif -------------------------------------------------------------------------------- /resource/src/components/GithubCorner/index.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <a href="https://github.com/aimerforreimu/AUXPI" target="_blank" class="github-corner" aria-label="View source on Github"> 3 | <svg 4 | width="80" 5 | height="80" 6 | viewBox="0 0 250 250" 7 | style="fill:#40c9c6; color:#fff;" 8 | aria-hidden="true"> 9 | <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"/> 10 | <path 11 | d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" 12 | fill="currentColor" 13 | style="transform-origin: 130px 106px;" 14 | class="octo-arm"/> 15 | <path 16 | d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" 17 | fill="currentColor" 18 | class="octo-body"/> 19 | </svg> 20 | </a> 21 | </template> 22 | 23 | <style scoped> 24 | .github-corner:hover .octo-arm { 25 | animation: octocat-wave 560ms ease-in-out 26 | } 27 | 28 | @keyframes octocat-wave { 29 | 0%, 30 | 100% { 31 | transform: rotate(0) 32 | } 33 | 20%, 34 | 60% { 35 | transform: rotate(-25deg) 36 | } 37 | 40%, 38 | 80% { 39 | transform: rotate(10deg) 40 | } 41 | } 42 | 43 | @media (max-width:500px) { 44 | .github-corner:hover .octo-arm { 45 | animation: none 46 | } 47 | .github-corner .octo-arm { 48 | animation: octocat-wave 560ms ease-in-out 49 | } 50 | } 51 | </style> 52 | -------------------------------------------------------------------------------- /resource/src/components/Hamburger/index.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div> 3 | <svg 4 | :class="{'is-active':isActive}" 5 | class="hamburger" 6 | viewBox="0 0 1024 1024" 7 | xmlns="http://www.w3.org/2000/svg" 8 | width="64" 9 | height="64" 10 | @click="toggleClick"> 11 | <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" /> 12 | </svg> 13 | </div> 14 | </template> 15 | 16 | <script> 17 | export default { 18 | name: 'Hamburger', 19 | props: { 20 | isActive: { 21 | type: Boolean, 22 | default: false 23 | }, 24 | toggleClick: { 25 | type: Function, 26 | default: null 27 | } 28 | } 29 | } 30 | </script> 31 | 32 | <style scoped> 33 | .hamburger { 34 | display: inline-block; 35 | cursor: pointer; 36 | width: 20px; 37 | height: 20px; 38 | } 39 | .hamburger.is-active { 40 | transform: rotate(180deg); 41 | } 42 | </style> 43 | -------------------------------------------------------------------------------- /resource/src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <svg :class="svgClass" aria-hidden="true"> 3 | <use :xlink:href="iconName"/> 4 | </svg> 5 | </template> 6 | 7 | <script> 8 | export default { 9 | name: 'SvgIcon', 10 | props: { 11 | iconClass: { 12 | type: String, 13 | required: true 14 | }, 15 | className: { 16 | type: String, 17 | default: '' 18 | } 19 | }, 20 | computed: { 21 | iconName() { 22 | return `#icon-${this.iconClass}` 23 | }, 24 | svgClass() { 25 | if (this.className) { 26 | return 'svg-icon ' + this.className 27 | } else { 28 | return 'svg-icon' 29 | } 30 | } 31 | } 32 | } 33 | </script> 34 | 35 | <style scoped> 36 | .svg-icon { 37 | width: 1em; 38 | height: 1em; 39 | vertical-align: -0.15em; 40 | fill: currentColor; 41 | overflow: hidden; 42 | } 43 | </style> 44 | -------------------------------------------------------------------------------- /resource/src/filters/index.js: -------------------------------------------------------------------------------- 1 | // set function parseTime,formatTime to filter 2 | export { parseTime, formatTime } from '@/utils' 3 | 4 | function pluralize(time, label) { 5 | if (time === 1) { 6 | return time + label 7 | } 8 | return time + label + 's' 9 | } 10 | 11 | export function timeAgo(time) { 12 | const between = Date.now() / 1000 - Number(time) 13 | if (between < 3600) { 14 | return pluralize(~~(between / 60), ' minute') 15 | } else if (between < 86400) { 16 | return pluralize(~~(between / 3600), ' hour') 17 | } else { 18 | return pluralize(~~(between / 86400), ' day') 19 | } 20 | } 21 | 22 | /* 数字 格式化*/ 23 | export function numberFormatter(num, digits) { 24 | const si = [ 25 | { value: 1E18, symbol: 'E' }, 26 | { value: 1E15, symbol: 'P' }, 27 | { value: 1E12, symbol: 'T' }, 28 | { value: 1E9, symbol: 'G' }, 29 | { value: 1E6, symbol: 'M' }, 30 | { value: 1E3, symbol: 'k' } 31 | ] 32 | for (let i = 0; i < si.length; i++) { 33 | if (num >= si[i].value) { 34 | return (num / si[i].value + 0.1).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol 35 | } 36 | } 37 | return num.toString() 38 | } 39 | 40 | export function toThousandFilter(num) { 41 | return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ',')) 42 | } 43 | -------------------------------------------------------------------------------- /resource/src/icons/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import SvgIcon from '@/components/SvgIcon' // svg组件 3 | 4 | // register globally 5 | Vue.component('svg-icon', SvgIcon) 6 | 7 | const requireAll = requireContext => requireContext.keys().map(requireContext) 8 | const req = require.context('./svg', false, /\.svg$/) 9 | requireAll(req) 10 | -------------------------------------------------------------------------------- /resource/src/icons/svg/ali.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554568072202" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1294" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M611.84 690.688c143.872-9.216 275.968-58.88 397.824-111.104-83.456 55.296-507.904 266.752-510.464 122.88 0.512-17.92 8.192-37.376 23.04-58.368 13.312-20.48 32.256-41.472 50.688-63.488 29.184-33.792 101.376-112.128 125.952-160.768 4.608-9.216 7.68-17.92 8.704-25.088 3.072-43.52-52.736-60.928-135.168-83.456l-15.872 9.728 30.72 25.088c-139.264 24.576-222.72 50.176-324.096 86.016l14.336 35.84-50.688 49.664c8.704 1.536 97.28 31.232 188.928-32.768l0.512-0.512 1.024-1.024c-3.072-4.608-8.704-9.728-16.384-15.872 27.648 1.536 44.032 25.6 41.472 50.176h-11.776c0.512-8.704-1.536-16.384-4.096-23.04-71.168 52.736-154.112 59.392-224.256 34.816v61.952c-34.816 11.776-94.208 49.664-94.208 86.016 2.048 17.92 10.752 24.064 19.456 28.672 77.824 44.032 288.768-15.872 287.744-15.872-75.776 38.912-150.528 69.632-261.632 74.24-147.968-2.56-168.96-100.352-100.864-202.24 66.048-102.912 169.472-194.56 334.848-252.928 48.128-17.408 118.272-35.84 186.88-37.888 97.792 0 193.024 29.184 186.88 123.392-4.608 72.704-106.496 172.544-161.28 245.76-25.088 31.744-28.672 53.248 11.776 50.176z m92.672-330.24c4.096 8.704 5.12 18.432 4.096 28.672 1.024-11.264 0-20.992-4.096-28.672z" p-id="1295"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/auxpi.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554568093978" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1403" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M511.373 79.67c15.034 0 25.315 3.558 28.922 5.677l325.775 188.12c13.253 7.653 28.939 34.755 28.939 50.1v376.177c0 15.341-15.648 42.433-28.939 50.086L540.295 937.963c-3.607 2.12-13.889 5.769-28.906 5.769-15.013 0-25.271-3.577-28.917-5.713l-325.83-188.104c-13.275-7.683-28.924-34.774-28.924-50.116V323.567c0-15.323 15.632-42.43 28.924-50.1l325.74-188.12a65.412 65.412 0 0 1 28.991-5.677m0-79.017c-24.808 0-49.605 5.439-68.41 16.262l-325.83 188.137C79.505 226.777 48.7 280.101 48.7 323.567v376.177c0 43.448 30.805 96.793 68.433 118.495l325.756 188.12c18.804 10.846 43.606 16.285 68.41 16.285 24.807 0 49.63-5.462 68.433-16.285l325.774-188.104c37.605-21.719 68.41-75.063 68.41-118.512v-376.16c0-43.465-30.805-96.792-68.41-118.51L579.804 17.01C561.001 6.108 536.212 0.653 511.373 0.653z m0 0" fill="" p-id="1404"></path><path d="M795.337 323.091a39.99 39.99 0 0 0-19.728 5.295L491.303 525.917c-17.928 11.357-23.711 34.821-13.11 53.206 10.605 18.388 33.81 25.139 52.618 15.316l284.291-197.533c15.582-8.903 23.207-27.185 18.565-44.521-4.643-17.337-20.386-29.366-38.33-29.294z m0 0" fill="" p-id="1405"></path><path d="M227.425 323.727c-17.962-0.148-33.759 11.864-38.407 29.223-4.649 17.353 3.025 35.652 18.663 44.499L491.956 595c18.798 9.883 42.042 3.148 52.645-15.253 10.602-18.404 4.77-41.891-13.209-53.195l-284.289-197.53a39.445 39.445 0 0 0-19.678-5.295z m0 0" fill="" p-id="1406"></path><path d="M511.062 521.562a39.521 39.521 0 0 0-39.507 39.511v267.918c0.79 21.248 18.245 38.064 39.504 38.064 21.258 0 38.71-16.816 39.496-38.064V561.073c0-21.815-17.674-39.497-39.493-39.511z m0 0" fill="" p-id="1407"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/cc.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554567951873" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1548" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512.325632 0c-283.01312 0-512.325632 229.39648-512.325632 512.325632s229.312512 512.326656 512.325632 512.326656c282.9312 0 512.325632-229.397504 512.325632-512.326656S795.256832 0 512.325632 0zM512.325632 939.264c-235.81696 0-426.938368-191.122432-426.938368-426.938368S276.508672 85.387264 512.325632 85.387264c235.734016 0 426.938368 191.122432 426.938368 426.938368S748.059648 939.264 512.325632 939.264z" p-id="1549"></path><path d="M512.325632 426.938368c-74.130432-173.52704-259.414016-134.002688-255.496192 48.780288 1.918976 92.143616 255.746048 292.770816 255.746048 292.770816S771.156992 566.02624 767.73888 474.55232C760.984576 291.43552 586.039296 257.08032 512.325632 426.938368z" p-id="1550"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/cloud.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1550485029391" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8090" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M772.244691 409.188175c15.569886 0 28.033021 12.463134 28.033021 28.033021 0 15.569886-12.463134 28.033021-28.033021 28.033021-15.569886 0-28.033021-12.463134-28.033021-28.033021C745.765046 420.097933 758.22818 409.188175 772.244691 409.188175L772.244691 409.188175zM270.504198 396.725041c-7.803006-1.553376-15.569886-1.553376-24.926268-1.553376-93.491568 0-169.859874 82.58181-169.859874 183.876385s76.368306 183.876385 169.859874 183.876385l233.728921 0 277.367953 0 59.208918 0c204.106399 0 169.859874-292.93784-105.954703-268.011571 17.123263-45.192408-20.26614-144.897481-115.311084-130.880971C522.945883 228.418542 356.228886 214.402032 270.504198 396.725041L270.504198 396.725041zM948.31807 445.024201c0 10.909758-7.803006 18.712764-18.712764 18.712764s-18.712764-7.803006-18.712764-18.712764c0-81.028434-65.458548-146.486982-146.486982-146.486982-10.909758 0-18.712764-7.803006-18.712764-18.712764s7.803006-18.712764 18.712764-18.712764C865.736259 261.147816 948.31807 343.729627 948.31807 445.024201L948.31807 445.024201zM764.47781 371.762647c-10.909758 0-18.712764-7.803006-18.712764-18.712764s7.803006-18.712764 18.712764-18.712764c60.762295 0 110.614831 49.852537 110.614831 110.614831l0 0c0 10.909758-7.803006 18.712764-18.712764 18.712764s-18.712764-7.803006-18.712764-18.712764C837.703239 404.491921 804.973965 371.762647 764.47781 371.762647L764.47781 371.762647z" p-id="8091"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/dashboard.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1550485919810" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9826" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M219.429 658.286q0-30.286-21.429-51.715t-51.714-21.428T94.57 606.57t-21.428 51.715T94.57 710t51.715 21.429T198 710t21.429-51.714z m109.714-256q0-30.286-21.429-51.715T256 329.143t-51.714 21.428-21.429 51.715T204.286 454 256 475.429 307.714 454t21.429-51.714z m244.571 274.857l57.715-218.286q3.428-14.857-4.286-27.714t-22-16.857T577.714 418t-17.143 22.571l-57.714 218.286q-34.286 2.857-61.143 24.857t-36 56.286q-11.428 44 11.429 83.429T484 874.286t83.429-11.429T618.286 796q9.143-34.286-3.429-66.857t-41.143-52z m377.143-18.857q0-30.286-21.428-51.715t-51.715-21.428T826 606.57t-21.429 51.715T826 710t51.714 21.429T929.43 710t21.428-51.714zM585.143 292.57q0-30.285-21.429-51.714T512 219.43t-51.714 21.428-21.429 51.714 21.429 51.715T512 365.714t51.714-21.428 21.429-51.715z m256 109.715q0-30.286-21.429-51.715T768 329.143t-51.714 21.428-21.429 51.715T716.286 454 768 475.429 819.714 454t21.429-51.714z m182.857 256q0 149.143-80.571 276-10.858 16.571-30.858 16.571H111.43q-20 0-30.858-16.571Q0 808 0 658.286q0-104 40.571-198.857T149.714 296t163.429-109.143T512 146.286t198.857 40.571T874.286 296t109.143 163.429T1024 658.286z" fill="" p-id="9827"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/example.svg: -------------------------------------------------------------------------------- 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/eye-open.svg: -------------------------------------------------------------------------------- 1 | <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg> 2 | -------------------------------------------------------------------------------- /resource/src/icons/svg/eye.svg: -------------------------------------------------------------------------------- 1 | <svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/flickr.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554567989798" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1981" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M0 0" p-id="1982"></path><path d="M298.496 680.925867c-91.7504 0-166.4-74.6496-166.4-166.4S206.7456 348.16 298.496 348.16 464.896 422.8096 464.896 514.56s-74.6496 166.365867-166.4 166.365867z m0-298.5984c-72.942933 0-132.266667 59.323733-132.266667 132.266666s59.323733 132.266667 132.266667 132.266667S430.762667 587.537067 430.762667 514.594133s-59.323733-132.266667-132.266667-132.266666zM725.162667 680.925867c-91.7504 0-166.4-74.6496-166.4-166.4s74.6496-166.4 166.4-166.4S891.562667 422.775467 891.562667 514.525867s-74.615467 166.4-166.4 166.4z m0-298.5984c-72.977067 0-132.266667 59.323733-132.266667 132.266666s59.2896 132.266667 132.266667 132.266667S857.429333 587.537067 857.429333 514.594133s-59.2896-132.266667-132.266666-132.266666z" p-id="1983"></path><path d="M512 1019.733333C232.0384 1019.733333 4.266667 791.9616 4.266667 512 4.266667 232.004267 232.0384 4.266667 512 4.266667S1019.733333 232.004267 1019.733333 512c0 279.927467-227.7376 507.733333-507.733333 507.733333z m0-981.2992c-261.154133 0-473.6 212.445867-473.6 473.6S250.845867 985.634133 512 985.634133c261.12 0 473.6-212.514133 473.6-473.6C985.6 250.914133 773.12 38.434133 512 38.434133z" p-id="1984"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/gitee.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1556538892716" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3643" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M896.3052803 427.59336267H465.08398823c-20.69630173 0-37.49062554 16.79432382-37.49062556 37.49062555l-0.02636472 93.75292941c0 20.69630173 16.76795911 37.49062554 37.49062556 37.51699027h262.51347546c20.69630173 0 37.49062554 16.79432382 37.49062555 37.49062638v18.74531277a112.49824219 112.49824219 0 0 1-112.49824219 112.49824219H296.32344217a37.49062554 37.49062554 0 0 1-37.49062554-37.49062556V371.38378824a112.49824219 112.49824219 0 0 1 112.49824218-112.49824219L896.22618615 258.85918133c20.69630173 0 37.49062554-16.76795911 37.49062557-37.46426165L933.79590585 127.64199027h0.02636472A37.49062554 37.49062554 0 0 0 896.35800973 90.125h-0.02636471L371.38378824 90.15136472C216.06924714 90.15136472 90.15136472 216.06924714 90.15136472 371.38378824v524.94785678c0 20.69630173 16.79432382 37.49062554 37.49062555 37.49062555h553.07900829a253.101272 253.101272 0 0 0 253.10127201-253.10127201v-215.61064563c0-20.69630173-16.79432382-37.49062554-37.49062555-37.49062554z" p-id="3644"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/images.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1550484925289" class="icon" style="" viewBox="0 0 1152 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6016" xmlns:xlink="http://www.w3.org/1999/xlink" width="225" height="200"><defs><style type="text/css"></style></defs><path d="M960 832v32c0 53.02-42.98 96-96 96H96c-53.02 0-96-42.98-96-96V352c0-53.02 42.98-96 96-96h32v416c0 88.224 71.776 160 160 160h672z m192-160V160c0-53.02-42.98-96-96-96H288c-53.02 0-96 42.98-96 96v512c0 53.02 42.98 96 96 96h768c53.02 0 96-42.98 96-96zM512 256c0 53.02-42.98 96-96 96s-96-42.98-96-96 42.98-96 96-96 96 42.98 96 96z m-192 288l111.03-111.03c9.372-9.372 24.568-9.372 33.942 0L544 512l271.03-271.03c9.372-9.372 24.568-9.372 33.942 0L1024 416v224H320v-96z" p-id="6017"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/imgur.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554568292750" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5324" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M640.996 869.7c0 84.308-58.058 153.3-128.996 153.3-70.962 0-128.998-68.992-128.998-153.3V459.104c0-84.312 58.036-153.3 128.998-153.3 70.936 0 128.996 68.988 128.996 153.3V869.7zM512 1c-71.26 0-128.998 57.738-128.998 128.998 0 71.26 57.738 128.998 128.998 128.998 71.21 0 128.996-57.738 128.996-128.998C640.996 58.738 583.21 1 512 1z" fill="" p-id="5325"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/jingdong.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554567073713" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2876" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512 1024C229.249024 1024 0 794.775552 0 512 0 229.2224 229.249024 0 512 0c282.775552 0 512 229.2224 512 512 0 282.775552-229.224448 512-512 512z m108.222464-273.11104c128.333824 0 232.443904-114.444288 232.443904-255.555584 0-141.221888-104.11008-255.666176-232.443904-255.666176h-155.056128v511.22176h155.056128z m-418.582528 0c102.721536 0 185.99936-80.775168 185.99936-180.443136V239.665152h-61.97248v330.778624c0 66.443264-55.5008 120.332288-124.000256 120.332288H170.665984v60.112896H201.66656h-0.026624z" p-id="2877"></path><path d="M620.222464 299.88864h-93.057024v390.887424h92.99968c94.164992 0 170.500096-87.554048 170.500096-195.442688 0-107.999232-76.333056-195.444736-170.500096-195.444736h0.057344z" p-id="2878"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/juejin.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554567654242" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3363" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M208 479l-44 36 349 276 347-276-44-36-304 239-304-239z" p-id="3364"></path><path d="M345 368l-42 36 209 166 210-167-46-34-164 130-167-131zM511 235l-70 55 71 56 68-55-69-56z" p-id="3365"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/link.svg: -------------------------------------------------------------------------------- 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><g><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></g></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/list.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1556811902953" class="icon" style="" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4783" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.1953125" height="200"><defs><style type="text/css"></style></defs><path d="M96.256 636.032l192 0c17.664 0 32-14.336 32-32s-14.336-32-32-32l-192 0c-17.664 0-32 14.336-32 32S78.592 636.032 96.256 636.032zM1015.04 903.424l-110.208-110.208c34.112-43.52 55.36-97.6 55.36-157.248 0-141.376-114.624-256-256-256s-256 114.624-256 256 114.624 256 256 256c59.648 0 113.728-21.248 157.248-55.36l110.208 110.208c12.032 11.968 31.36 11.968 43.392 0C1027.008 934.784 1027.008 915.456 1015.04 903.424zM841.408 770.048c-0.576 0.512-1.344 0.704-1.856 1.28s-0.768 1.344-1.28 1.856c-34.624 33.792-81.792 54.784-134.08 54.784-106.048 0-192-85.952-192-192s85.952-192 192-192 192 85.952 192 192C896.256 688.256 875.264 735.424 841.408 770.048zM96.256 252.032l576 0c17.664 0 32-14.336 32-32s-14.336-32-32-32l-576 0c-17.664 0-32 14.336-32 32S78.592 252.032 96.256 252.032zM352.256 380.032l-256 0c-17.664 0-32 14.336-32 32s14.336 32 32 32l256 0c17.664 0 32-14.336 32-32S369.92 380.032 352.256 380.032zM352.256 764.032l-256 0c-17.664 0-32 14.336-32 32s14.336 32 32 32l256 0c17.664 0 32-14.336 32-32S369.92 764.032 352.256 764.032z" p-id="4784"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/manage.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552067667831" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3684" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M224 423.84V231.744l192-0.096 0.096 192.096L224 423.84z m192.096-256.096H223.904A64 64 0 0 0 160 231.68v192.192a64 64 0 0 0 63.904 63.904h192.192A64 64 0 0 0 480 423.84V231.68a64 64 0 0 0-63.904-63.904zM224 807.84V615.744l192-0.096 0.096 192.096L224 807.84z m192.096-256.096H223.904A64 64 0 0 0 160 615.68v192.192a64 64 0 0 0 63.904 63.904h192.192A64 64 0 0 0 480 807.84V615.68a64 64 0 0 0-63.904-63.904z m287.968-88.128l-135.84-135.84 135.712-135.84L839.84 327.68 704.064 463.616z m181.024-181.024L749.184 146.688a64 64 0 0 0-90.368 0L522.912 282.56a63.456 63.456 0 0 0-18.656 45.056 63.456 63.456 0 0 0 18.656 45.312l135.904 135.936a63.904 63.904 0 0 0 90.368-0.032l135.904-135.904a63.936 63.936 0 0 0 0-90.368zM608 807.84V615.744l192-0.096 0.096 192.096L608 807.84z m192.096-256.096H607.904A64 64 0 0 0 544 615.68v192.192a64 64 0 0 0 63.904 63.904h192.192A64 64 0 0 0 864 807.84V615.68a64 64 0 0 0-63.904-63.904z" fill="" p-id="3685"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/menu.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1556644148704" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2832" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M384 480H192c-52.8 0-96-43.2-96-96V192c0-52.8 43.2-96 96-96h192c52.8 0 96 43.2 96 96v192c0 52.8-43.2 96-96 96zM192 160c-17.6 0-32 14.4-32 32v192c0 17.6 14.4 32 32 32h192c17.6 0 32-14.4 32-32V192c0-17.6-14.4-32-32-32H192zM832 480H640c-52.8 0-96-43.2-96-96V192c0-52.8 43.2-96 96-96h192c52.8 0 96 43.2 96 96v192c0 52.8-43.2 96-96 96zM640 160c-17.6 0-32 14.4-32 32v192c0 17.6 14.4 32 32 32h192c17.6 0 32-14.4 32-32V192c0-17.6-14.4-32-32-32H640zM384 928H192c-52.8 0-96-43.2-96-96V640c0-52.8 43.2-96 96-96h192c52.8 0 96 43.2 96 96v192c0 52.8-43.2 96-96 96zM192 608c-17.6 0-32 14.4-32 32v192c0 17.6 14.4 32 32 32h192c17.6 0 32-14.4 32-32V640c0-17.6-14.4-32-32-32H192zM832 928H640c-52.8 0-96-43.2-96-96V640c0-52.8 43.2-96 96-96h192c52.8 0 96 43.2 96 96v192c0 52.8-43.2 96-96 96zM640 608c-17.6 0-32 14.4-32 32v192c0 17.6 14.4 32 32 32h192c17.6 0 32-14.4 32-32V640c0-17.6-14.4-32-32-32H640z" p-id="2833"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/nested.svg: -------------------------------------------------------------------------------- 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/ooxx.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554568223339" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4472" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M535.1 930c-154.4 0-295.2-84.8-367.9-221-6.1-10.6-3-24.2 9.1-30.3 10.6-6.1 24.2-1.5 30.3 9.1 65.1 121.1 190.8 196.8 328.5 196.8 205.9 0 372.5-166.5 372.5-372.5S741 139.6 535.1 139.6c-137.8 0-263.4 75.7-328.5 196.8-6.1 10.6-19.7 15.1-30.3 9.1-10.6-6.1-15.1-19.7-9.1-30.3 72.7-136.3 213.5-221 367.9-221C766.7 94.2 953 282 953 512.1S766.7 930 535.1 930z" p-id="4473"></path><path d="M697.1 534.8H88.4c-12.1 0-22.7-10.6-22.7-22.7s10.6-22.7 22.7-22.7H697c12.1 0 22.7 10.6 22.7 22.7 0.1 12.1-10.5 22.7-22.6 22.7z" p-id="4474"></path><path d="M500.3 727.1c-6.1 0-12.1-3-16.7-7.6-9.1-9.1-9.1-22.7 0-31.8l181.7-175.6-181.7-175.6c-9.1-9.1-9.1-22.7 0-31.8 9.1-9.1 22.7-9.1 31.8 0L713.7 497c4.5 4.5 7.6 10.6 7.6 16.7s-3 12.1-7.6 16.7L515.4 721c-4.5 3.1-10.6 6.1-15.1 6.1z" p-id="4475"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/password.svg: -------------------------------------------------------------------------------- 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/sm.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554567866580" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7373" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M766.106999 1024l-254.104951-146.707429-254.102904 146.707429-252.82708-145.972244-0.00512-291.939368 254.103927-146.707429 0-293.412811 252.828104-145.968148 252.829128 145.965076 0 293.414859 254.103927 146.706405-0.002048 291.940392L766.106999 1024zM69.186809 841.011464l188.711311 108.954928 189.988159-109.690114-188.714383-108.953904 0-217.908832-189.990207 109.691137L69.186809 841.011464zM576.115769 840.275255l189.990207 109.690114 188.709263-108.956976 0.002048-217.907808-189.988159-109.68909 0 217.908832L576.115769 840.275255zM323.286641 694.305059l188.715407 108.953904 188.713359-108.954928 0-217.908832-188.714383-108.953904-188.714383 108.954928L323.286641 694.305059zM323.285617 182.98444l0 219.379203 188.715407-108.954928 188.713359 108.953904 0-219.380227-188.714383-108.949808L323.285617 182.98444z" p-id="7374"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/sougou.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554567780115" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4902" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M509.7 74.8C270.4 74.8 75 270.1 75 511.5s195.3 436.8 436.8 436.8c57.1 0 112-11 164.6-32.9 65.9-26.3 125.1-70.2 171.2-127.3 61.5-74.6 98.8-171.2 98.8-276.5 0-241.5-195.3-436.8-436.7-436.8z m305 693.6c-41.7 50.5-96.6 90-158 114.2-48.3 15.4-94.4 26.3-144.9 26.3-219.5 0-397.3-177.8-397.3-397.3s177.8-397.3 397.3-397.3 397.3 177.8 397.3 397.3c0 96.5-35.1 186.5-94.4 256.8z" p-id="4903"></path><path d="M503.1 676.2s-158 2.2-245.8-79l-6.6 111.9S773.1 897.9 777.5 595c0 0 11-72.4-177.8-122.9 0 0-74.6-17.6-158-65.8 0 0-46.1-52.7 85.6-41.7 155.8 13.2 237.1 52.7 237.1 52.7v-98.8s-355.6-133.9-493.9 19.8c0 0-46.1 70.2 2.2 114.1 48.3 43.9 144.9 98.8 272.2 131.7-0.1-2.3 164.5 74.5-41.8 92.1z m0 0" p-id="4904"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/start.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554566557141" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1979" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512.055704 0C229.277565 0 0 229.22805 0 511.993811s229.277565 512.006189 512.055704 512.006189 511.993811-229.240429 511.993811-512.006189S794.821464 0 512.055704 0z m0 921.603714c-225.861054 0.037136-409.609903-183.748849-409.609903-409.609903S286.19465 102.396286 512.055704 102.396286s409.597524 183.748849 409.597524 409.597525-183.748849 409.647039-409.597524 409.647039z" p-id="1980"></path><path d="M450.96701 300.083508c-22.021638-16.525513-53.45106-0.804613-53.451059 26.725529v370.369547c0 27.530143 31.429421 43.251043 53.451059 26.72553l246.904779-185.184774a33.422386 33.422386 0 0 0 0-53.451059z" p-id="1981"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/stop.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554565154694" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2853" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0zM841.1 841c-42.7 42.7-92.5 76.3-147.9 99.7C635.8 965 574.8 977.3 512 977.3S388.2 965 330.9 940.8c-55.4-23.4-105.2-57-147.9-99.7s-76.3-92.5-99.7-147.9C59 635.8 46.7 574.8 46.7 512S59 388.2 83.2 330.9c23.4-55.4 57-105.2 99.7-147.9 42.7-42.7 92.5-76.3 147.9-99.7C388.2 59 449.2 46.7 512 46.7S635.8 59 693.1 83.2c55.4 23.4 105.2 57 147.9 99.7 42.7 42.7 76.3 92.5 99.7 147.9 24.3 57.3 36.5 118.3 36.5 181.1S965 635.8 940.8 693.1C917.4 748.5 883.8 798.3 841.1 841z" p-id="2854"></path><path d="M420 274.6c-25.7 0-46.7 21-46.7 46.7l0 373.6c0 25.7 21 46.7 46.7 46.7s46.7-21 46.7-46.7L466.7 321.3C466.7 295.6 445.7 274.6 420 274.6z" p-id="2855"></path><path d="M605.3 274.6c-25.7 0-46.7 21-46.7 46.7l0 373.6c0 25.7 21 46.7 46.7 46.7s46.7-21 46.7-46.7L652 321.3C652 295.6 631 274.6 605.3 274.6z" p-id="2856"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/suning.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554568138528" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2288" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M992.1536 447.1808l-94.72-94.72V218.4192c0-50.3808-41.3696-91.7504-91.7504-91.7504H671.6416l-94.72-94.72c-35.7376-35.7376-94.0032-35.7376-129.7408 0l-94.72 94.72H218.4192c-50.3808 0-91.7504 41.3696-91.7504 91.7504v133.9392l-94.72 94.72c-35.7376 35.7376-35.7376 94.0032 0 129.7408l94.72 94.72v133.9392c0 50.3808 41.3696 91.7504 91.7504 91.7504h133.9392l94.72 94.72c35.7376 35.7376 94.0032 35.7376 129.7408 0l94.72-94.72h133.9392c50.3808 0 91.7504-41.3696 91.7504-91.7504V671.6416l94.72-94.72c35.84-35.7376 35.84-94.1056 0.2048-129.7408z m-333.4144-48.7424c20.2752 0 36.6592 16.384 36.6592 36.6592 0 20.2752-16.384 36.6592-36.6592 36.6592-20.2752 0-36.6592-16.384-36.6592-36.6592 0-20.2752 16.384-36.6592 36.6592-36.6592z m-293.7856 0c20.2752 0 36.6592 16.384 36.6592 36.6592 0 20.2752-16.384 36.6592-36.6592 36.6592-20.2752 0-36.6592-16.384-36.6592-36.6592 0-20.2752 16.4864-36.6592 36.6592-36.6592zM768.1024 693.248c0 59.8016-48.8448 108.6464-108.6464 108.6464H365.8752c-59.8016 0-108.6464-48.8448-108.6464-108.6464v-3.072c0-59.8016 48.8448-108.6464 108.6464-108.6464h1.2288c9.0112-72.3968 70.656-128.4096 145.6128-128.4096 74.9568 0 136.4992 56.1152 145.6128 128.4096h1.2288c59.8016 0 108.6464 48.8448 108.6464 108.6464v3.072h-0.1024z m0 0" p-id="2289"></path><path d="M602.3168 581.8368H421.376c-16.2816 0-22.6304 21.1968-8.9088 30.208l89.3952 58.368c5.4272 3.584 12.288 3.584 17.7152 0.1024l91.648-58.368c13.824-8.8064 7.5776-30.3104-8.9088-30.3104z m0 0" p-id="2290"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/table.svg: -------------------------------------------------------------------------------- 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><g><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></g></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/tree.svg: -------------------------------------------------------------------------------- 1 | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/upload.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1556811844604" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2027" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M662.63 545.37l-128-128a32 32 0 0 0-45.25 0l-128 128a32 32 0 1 0 45.25 45.25L480 517.25V872a32 32 0 0 0 64 0V517.25l73.37 73.37a32 32 0 1 0 45.25-45.25z" p-id="2028"></path><path d="M752 760H640a32 32 0 0 1 0-64h112c79.4 0 144-64.6 144-144a144 144 0 0 0-132.45-143.54 32 32 0 0 1-29.24-28C720.6 268.46 625 184 512 184s-208.6 84.46-222.31 196.45a32 32 0 0 1-29.24 28A144 144 0 0 0 128 552c0 79.4 64.6 144 144 144h112a32 32 0 0 1 0 64H272c-114.69 0-208-93.31-208-208a208.08 208.08 0 0 1 166.23-203.79C258 216.5 375 120 512 120s254 96.5 281.77 228.21A208.08 208.08 0 0 1 960 552c0 114.69-93.31 208-208 208z" p-id="2029"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/user.svg: -------------------------------------------------------------------------------- 1 | <svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/users.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1550483965501" class="icon" style="" viewBox="0 0 1280 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1906" xmlns:xlink="http://www.w3.org/1999/xlink" width="250" height="200"><defs><style type="text/css"></style></defs><path d="M192 448c70.6 0 128-57.4 128-128s-57.4-128-128-128-128 57.4-128 128 57.4 128 128 128z m896 0c70.6 0 128-57.4 128-128s-57.4-128-128-128-128 57.4-128 128 57.4 128 128 128z m64 64h-128c-35.2 0-67 14.2-90.2 37.2 80.6 44.2 137.8 124 150.2 218.8h132c35.4 0 64-28.6 64-64v-64c0-70.6-57.4-128-128-128z m-512 0c123.8 0 224-100.2 224-224S763.8 64 640 64 416 164.2 416 288s100.2 224 224 224z m153.6 64h-16.6c-41.6 20-87.8 32-137 32s-95.2-12-137-32h-16.6C359.2 576 256 679.2 256 806.4V864c0 53 43 96 96 96h576c53 0 96-43 96-96v-57.6c0-127.2-103.2-230.4-230.4-230.4z m-447.4-26.8C323 526.2 291.2 512 256 512H128c-70.6 0-128 57.4-128 128v64c0 35.4 28.6 64 64 64h131.8c12.6-94.8 69.8-174.6 150.4-218.8z" p-id="1907"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svg/xiaomi.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1554568172649" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3021" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512 0C230.4 0 0 230.4 0 512s230.4 512 512 512 512-230.4 512-512S793.6 0 512 0z m0 672h-96v-160h96v160z m160 0h-96v-137.6V480c-3.2-25.6-19.2-32-41.6-32H352v224H256V352h297.6c64 0 118.4 48 118.4 108.8V672z m128 0h-96V352h96v320z" p-id="3022"></path></svg> -------------------------------------------------------------------------------- /resource/src/icons/svgo.yml: -------------------------------------------------------------------------------- 1 | # replace default config 2 | 3 | # multipass: true 4 | # full: true 5 | 6 | plugins: 7 | 8 | # - name 9 | # 10 | # or: 11 | # - name: false 12 | # - name: true 13 | # 14 | # or: 15 | # - name: 16 | # param1: 1 17 | # param2: 2 18 | 19 | - removeAttrs: 20 | attrs: 21 | - 'fill' 22 | - 'fill-rule' 23 | -------------------------------------------------------------------------------- /resource/src/lang/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import Cookies from 'js-cookie' 4 | import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang 5 | import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang 6 | import elementEsLocale from 'element-ui/lib/locale/lang/es'// element-ui lang 7 | import enLocale from './en' 8 | import zhLocale from './zh' 9 | import esLocale from './es' 10 | 11 | Vue.use(VueI18n) 12 | 13 | const messages = { 14 | en: { 15 | ...enLocale, 16 | ...elementEnLocale 17 | }, 18 | zh: { 19 | ...zhLocale, 20 | ...elementZhLocale 21 | }, 22 | es: { 23 | ...esLocale, 24 | ...elementEsLocale 25 | } 26 | } 27 | export function getLanguage() { 28 | const chooseLanguage = Cookies.get('language') 29 | if (chooseLanguage) return chooseLanguage 30 | 31 | // if has not choose language 32 | const language = (navigator.language || navigator.browserLanguage).toLowerCase() 33 | const locales = Object.keys(messages) 34 | for (const locale of locales) { 35 | if (language.indexOf(locale) > -1) { 36 | return locale 37 | } 38 | } 39 | return 'en' 40 | } 41 | const i18n = new VueI18n({ 42 | // set locale 43 | // options: en | zh | es 44 | locale: getLanguage(), 45 | // set locale messages 46 | messages 47 | }) 48 | 49 | export default i18n 50 | -------------------------------------------------------------------------------- /resource/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets 4 | 5 | import Element from 'element-ui' 6 | import 'element-ui/lib/theme-chalk/index.css' 7 | // import locale from 'element-ui/lib/locale/lang/en' // lang i18n 8 | 9 | import Cookies from 'js-cookie' 10 | 11 | import '@/styles/index.scss' // global css 12 | 13 | import App from './App' 14 | import router from './router' 15 | import store from './store' 16 | 17 | import '@/icons' // icon 18 | import './permission' // permission control 19 | 20 | import i18n from './lang' // internationalization 21 | 22 | Vue.use(Element, { 23 | size: Cookies.get('size') || 'medium', // set element-ui default size 24 | i18n: (key, value) => i18n.t(key, value) 25 | }) 26 | 27 | Vue.config.productionTip = false 28 | 29 | import * as filters from './filters' // global filters 30 | 31 | // register global utility filters. 32 | Object.keys(filters).forEach(key => { 33 | Vue.filter(key, filters[key]) 34 | }) 35 | 36 | new Vue({ 37 | el: '#app', 38 | router, 39 | store, 40 | render: h => h(App) 41 | }) 42 | -------------------------------------------------------------------------------- /resource/src/settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'Auxpi-Admin', 3 | 4 | /** 5 | * @type {boolean} true | false 6 | * @description Whether show the settings right-panel 7 | */ 8 | showSettings: true, 9 | 10 | /** 11 | * @type {boolean} true | false 12 | * @description Whether need tagsView 13 | */ 14 | tagsView: true, 15 | 16 | /** 17 | * @type {boolean} true | false 18 | * @description Whether fix the header 19 | */ 20 | fixedHeader: false, 21 | 22 | /** 23 | * @type {boolean} true | false 24 | * @description Whether show the logo in sidebar 25 | */ 26 | sidebarLogo: false, 27 | 28 | /** 29 | * @type {string | array} 'production' | ['production', 'development'] 30 | * @description Need show err logs component. 31 | * The default is only used in the production env 32 | * If you want to also use it in dev, you can pass ['production', 'development'] 33 | */ 34 | errorLog: 'production' 35 | } 36 | -------------------------------------------------------------------------------- /resource/src/store/getters.js: -------------------------------------------------------------------------------- 1 | const getters = { 2 | sidebar: state => state.app.sidebar, 3 | device: state => state.app.device, 4 | token: state => state.user.token, 5 | avatar: state => state.user.avatar, 6 | name: state => state.user.name, 7 | roles: state => state.user.roles, 8 | // 图钉 9 | visitedViews: state => state.tagsView.visitedViews, 10 | cachedViews: state => state.tagsView.cachedViews, 11 | // 路由动态权限 12 | permission_routes: state => state.permission.routes 13 | } 14 | export default getters 15 | -------------------------------------------------------------------------------- /resource/src/store/index.js: -------------------------------------------------------------------------------- 1 | // import Vue from 'vue' 2 | // import Vuex from 'vuex' 3 | // import app from './modules/app' 4 | // import user from './modules/user' 5 | // import getters from './getters' 6 | 7 | // Vue.use(Vuex) 8 | 9 | // const store = new Vuex.Store({ 10 | // modules: { 11 | // app, 12 | // user 13 | // }, 14 | // getters 15 | // }) 16 | 17 | // export default store 18 | 19 | // new 20 | 21 | import Vue from 'vue' 22 | import Vuex from 'vuex' 23 | import getters from './getters' 24 | 25 | Vue.use(Vuex) 26 | 27 | // https://webpack.js.org/guides/dependency-management/#requirecontext 28 | const modulesFiles = require.context('./modules', false, /\.js$/) 29 | 30 | // you do not need `import app from './modules/app'` 31 | // it will auto require all vuex module from modules file 32 | const modules = modulesFiles.keys().reduce((modules, modulePath) => { 33 | // set './app.js' => 'app' 34 | const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') 35 | const value = modulesFiles(modulePath) 36 | modules[moduleName] = value.default 37 | return modules 38 | }, {}) 39 | 40 | const store = new Vuex.Store({ 41 | modules, 42 | getters 43 | }) 44 | 45 | export default store 46 | -------------------------------------------------------------------------------- /resource/src/store/modules/app.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const app = { 4 | state: { 5 | sidebar: { 6 | opened: !+Cookies.get('sidebarStatus'), 7 | withoutAnimation: false 8 | }, 9 | device: 'desktop' 10 | }, 11 | mutations: { 12 | TOGGLE_SIDEBAR: state => { 13 | if (state.sidebar.opened) { 14 | Cookies.set('sidebarStatus', 1) 15 | } else { 16 | Cookies.set('sidebarStatus', 0) 17 | } 18 | state.sidebar.opened = !state.sidebar.opened 19 | state.sidebar.withoutAnimation = false 20 | }, 21 | CLOSE_SIDEBAR: (state, withoutAnimation) => { 22 | Cookies.set('sidebarStatus', 1) 23 | state.sidebar.opened = false 24 | state.sidebar.withoutAnimation = withoutAnimation 25 | }, 26 | TOGGLE_DEVICE: (state, device) => { 27 | state.device = device 28 | } 29 | }, 30 | actions: { 31 | ToggleSideBar: ({ commit }) => { 32 | commit('TOGGLE_SIDEBAR') 33 | }, 34 | CloseSideBar({ commit }, { withoutAnimation }) { 35 | commit('CLOSE_SIDEBAR', withoutAnimation) 36 | }, 37 | ToggleDevice({ commit }, device) { 38 | commit('TOGGLE_DEVICE', device) 39 | } 40 | } 41 | } 42 | 43 | export default app 44 | -------------------------------------------------------------------------------- /resource/src/store/modules/permission.js: -------------------------------------------------------------------------------- 1 | import { asyncRoutes, constantRoutes } from '@/router' 2 | 3 | /** 4 | * Use meta.role to determine if the current user has permission 5 | * @param roles 6 | * @param route 7 | */ 8 | function hasPermission(roles, route) { 9 | if (route.meta && route.meta.roles) { 10 | return roles.some(role => route.meta.roles.includes(role)) 11 | } else { 12 | return true 13 | } 14 | } 15 | 16 | /** 17 | * Filter asynchronous routing tables by recursion 18 | * @param routes asyncRoutes 19 | * @param roles 20 | */ 21 | export function filterAsyncRoutes(routes, roles) { 22 | const res = [] 23 | 24 | routes.forEach(route => { 25 | const tmp = { ...route } 26 | if (hasPermission(roles, tmp)) { 27 | if (tmp.children) { 28 | tmp.children = filterAsyncRoutes(tmp.children, roles) 29 | } 30 | res.push(tmp) 31 | } 32 | }) 33 | 34 | return res 35 | } 36 | 37 | const state = { 38 | routes: [], 39 | addRoutes: [] 40 | } 41 | 42 | const mutations = { 43 | SET_ROUTES: (state, routes) => { 44 | state.addRoutes = routes 45 | state.routes = constantRoutes.concat(routes) 46 | } 47 | } 48 | 49 | const actions = { 50 | generateRoutes({ commit }, roles) { 51 | return new Promise(resolve => { 52 | let accessedRoutes 53 | if (roles.includes('admin')) { 54 | accessedRoutes = asyncRoutes || [] 55 | } else { 56 | accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) 57 | } 58 | commit('SET_ROUTES', accessedRoutes) 59 | resolve(accessedRoutes) 60 | }) 61 | } 62 | } 63 | 64 | export default { 65 | namespaced: true, 66 | state, 67 | mutations, 68 | actions 69 | } 70 | -------------------------------------------------------------------------------- /resource/src/store/modules/settings.js: -------------------------------------------------------------------------------- 1 | import variables from '@/styles/element-variables.scss' 2 | import defaultSettings from '@/settings' 3 | 4 | const { showSettings, tagsView, sidebarLogo } = defaultSettings 5 | 6 | const state = { 7 | theme: variables.theme, 8 | showSettings: showSettings, 9 | tagsView: tagsView, 10 | // fixedHeader: fixedHeader, 11 | sidebarLogo: sidebarLogo 12 | } 13 | 14 | const mutations = { 15 | CHANGE_SETTING: (state, { key, value }) => { 16 | if (state.hasOwnProperty(key)) { 17 | state[key] = value 18 | } 19 | } 20 | } 21 | 22 | const actions = { 23 | changeSetting({ commit }, data) { 24 | commit('CHANGE_SETTING', data) 25 | } 26 | } 27 | 28 | export default { 29 | namespaced: true, 30 | state, 31 | mutations, 32 | actions 33 | } 34 | 35 | -------------------------------------------------------------------------------- /resource/src/styles/element-ui.scss: -------------------------------------------------------------------------------- 1 | //to reset element-ui default css 2 | .el-upload { 3 | input[type="file"] { 4 | display: none !important; 5 | } 6 | } 7 | 8 | .el-upload__input { 9 | display: none; 10 | } 11 | 12 | //暂时性解决diolag 问题 https://github.com/ElemeFE/element/issues/2461 13 | .el-dialog { 14 | transform: none; 15 | left: 0; 16 | position: relative; 17 | margin: 0 auto; 18 | } 19 | 20 | //element ui upload 21 | .upload-container { 22 | .el-upload { 23 | width: 100%; 24 | 25 | .el-upload-dragger { 26 | width: 100%; 27 | height: 200px; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /resource/src/styles/element-variables.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * I think element-ui's default theme color is too light for long-term use. 3 | * So I modified the default color and you can modify it to your liking. 4 | **/ 5 | 6 | /* theme color */ 7 | $--color-primary: #1890ff; 8 | $--color-success: #13ce66; 9 | $--color-warning: #FFBA00; 10 | $--color-danger: #ff4949; 11 | // $--color-info: #1E1E1E; 12 | 13 | $--button-font-weight: 400; 14 | 15 | // $--color-text-regular: #1f2d3d; 16 | 17 | $--border-color-light: #dfe4ed; 18 | $--border-color-lighter: #e6ebf5; 19 | 20 | $--table-border:1px solid#dfe6ec; 21 | 22 | /* icon font path, required */ 23 | $--font-path: '~element-ui/lib/theme-chalk/fonts'; 24 | 25 | @import "~element-ui/packages/theme-chalk/src/index"; 26 | 27 | // the :export directive is the magic sauce for webpack 28 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 29 | :export { 30 | theme: $--color-primary; 31 | } 32 | -------------------------------------------------------------------------------- /resource/src/styles/index.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | @import './mixin.scss'; 3 | @import './transition.scss'; 4 | @import './element-ui.scss'; 5 | @import './sidebar.scss'; 6 | 7 | body { 8 | height: 100%; 9 | -moz-osx-font-smoothing: grayscale; 10 | -webkit-font-smoothing: antialiased; 11 | text-rendering: optimizeLegibility; 12 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; 13 | } 14 | 15 | label { 16 | font-weight: 700; 17 | } 18 | 19 | html { 20 | height: 100%; 21 | box-sizing: border-box; 22 | } 23 | 24 | #app { 25 | height: 100%; 26 | } 27 | 28 | *, 29 | *:before, 30 | *:after { 31 | box-sizing: inherit; 32 | } 33 | 34 | a, 35 | a:focus, 36 | a:hover { 37 | cursor: pointer; 38 | color: inherit; 39 | outline: none; 40 | text-decoration: none; 41 | } 42 | 43 | div:focus { 44 | outline: none; 45 | } 46 | 47 | a:focus, 48 | a:active { 49 | outline: none; 50 | } 51 | 52 | a, 53 | a:focus, 54 | a:hover { 55 | cursor: pointer; 56 | color: inherit; 57 | text-decoration: none; 58 | } 59 | 60 | .clearfix { 61 | &:after { 62 | visibility: hidden; 63 | display: block; 64 | font-size: 0; 65 | content: " "; 66 | clear: both; 67 | height: 0; 68 | } 69 | } 70 | 71 | //main-container全局样式 72 | .app-main { 73 | min-height: 100% 74 | } 75 | 76 | .app-container { 77 | padding: 20px; 78 | } 79 | 80 | .filter-container { 81 | padding-bottom: 10px; 82 | 83 | .filter-item { 84 | display: inline-block; 85 | vertical-align: middle; 86 | margin-bottom: 10px; 87 | } 88 | } -------------------------------------------------------------------------------- /resource/src/styles/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix { 2 | &:after { 3 | content: ""; 4 | display: table; 5 | clear: both; 6 | } 7 | } 8 | 9 | @mixin scrollBar { 10 | &::-webkit-scrollbar-track-piece { 11 | background: #d3dce6; 12 | } 13 | 14 | &::-webkit-scrollbar { 15 | width: 6px; 16 | } 17 | 18 | &::-webkit-scrollbar-thumb { 19 | background: #99a9bf; 20 | border-radius: 20px; 21 | } 22 | } 23 | 24 | @mixin relative { 25 | position: relative; 26 | width: 100%; 27 | height: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /resource/src/styles/transition.scss: -------------------------------------------------------------------------------- 1 | //globl transition css 2 | 3 | /*fade*/ 4 | .fade-enter-active, 5 | .fade-leave-active { 6 | transition: opacity 0.28s; 7 | } 8 | 9 | .fade-enter, 10 | .fade-leave-active { 11 | opacity: 0; 12 | } 13 | 14 | /*fade-transform*/ 15 | .fade-transform-leave-active, 16 | .fade-transform-enter-active { 17 | transition: all .5s; 18 | } 19 | 20 | .fade-transform-enter { 21 | opacity: 0; 22 | transform: translateX(-30px); 23 | } 24 | 25 | .fade-transform-leave-to { 26 | opacity: 0; 27 | transform: translateX(30px); 28 | } 29 | 30 | /*fade*/ 31 | .breadcrumb-enter-active, 32 | .breadcrumb-leave-active { 33 | transition: all .5s; 34 | } 35 | 36 | .breadcrumb-enter, 37 | .breadcrumb-leave-active { 38 | opacity: 0; 39 | transform: translateX(20px); 40 | } 41 | 42 | .breadcrumb-move { 43 | transition: all .5s; 44 | } 45 | 46 | .breadcrumb-leave-active { 47 | position: absolute; 48 | } 49 | -------------------------------------------------------------------------------- /resource/src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | // base color 2 | $blue:#324157; 3 | $light-blue:#3A71A8; 4 | $red:#C03639; 5 | $pink: #E65D6E; 6 | $green: #30B08F; 7 | $tiffany: #4AB7BD; 8 | $yellow:#FEC171; 9 | $panGreen: #30B08F; 10 | 11 | // sidebar 12 | $menuText:#bfcbd9; 13 | $menuActiveText:#409EFF; 14 | $subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951 15 | 16 | $menuBg:#304156; 17 | $menuHover:#263445; 18 | 19 | $subMenuBg:#1f2d3d; 20 | $subMenuHover:#001528; 21 | 22 | $sideBarWidth: 210px; 23 | 24 | // the :export directive is the magic sauce for webpack 25 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 26 | :export { 27 | menuText: $menuText; 28 | menuActiveText: $menuActiveText; 29 | subMenuActiveText: $subMenuActiveText; 30 | menuBg: $menuBg; 31 | menuHover: $menuHover; 32 | subMenuBg: $subMenuBg; 33 | subMenuHover: $subMenuHover; 34 | sideBarWidth: $sideBarWidth; 35 | } 36 | -------------------------------------------------------------------------------- /resource/src/utils/auth.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const TokenKey = 'Admin-Token' 4 | 5 | export function getToken() { 6 | return Cookies.get(TokenKey) 7 | } 8 | 9 | export function setToken(token) { 10 | console.log('setToken:' + token) 11 | return Cookies.set(TokenKey, token) 12 | } 13 | 14 | export function removeToken() { 15 | return Cookies.remove(TokenKey) 16 | } 17 | -------------------------------------------------------------------------------- /resource/src/utils/clipboard.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Clipboard from 'clipboard' 3 | 4 | function clipboardSuccess() { 5 | Vue.prototype.$message({ 6 | message: 'Copy successfully', 7 | type: 'success', 8 | duration: 1500 9 | }) 10 | } 11 | 12 | function clipboardError() { 13 | Vue.prototype.$message({ 14 | message: 'Copy failed', 15 | type: 'error' 16 | }) 17 | } 18 | 19 | export default function handleClipboard(text, event) { 20 | const clipboard = new Clipboard(event.target, { 21 | text: () => text 22 | }) 23 | clipboard.on('success', () => { 24 | clipboardSuccess() 25 | clipboard.off('error') 26 | clipboard.off('success') 27 | clipboard.destroy() 28 | }) 29 | clipboard.on('error', () => { 30 | clipboardError() 31 | clipboard.off('error') 32 | clipboard.off('success') 33 | clipboard.destroy() 34 | }) 35 | clipboard.onClick(event) 36 | } 37 | -------------------------------------------------------------------------------- /resource/src/utils/i18n.js: -------------------------------------------------------------------------------- 1 | // translate router.meta.title, be used in breadcrumb sidebar tagsview 2 | export function generateTitle(title) { 3 | const hasKey = this.$te('route.' + title) 4 | 5 | if (hasKey) { 6 | // $t :this method from vue-i18n, inject in @/lang/index.js 7 | const translatedTitle = this.$t('route.' + title) 8 | return translatedTitle 9 | } 10 | return title 11 | } 12 | -------------------------------------------------------------------------------- /resource/src/utils/scrollTo.js: -------------------------------------------------------------------------------- 1 | Math.easeInOutQuad = function(t, b, c, d) { 2 | t /= d / 2 3 | if (t < 1) { 4 | return c / 2 * t * t + b 5 | } 6 | t-- 7 | return -c / 2 * (t * (t - 2) - 1) + b 8 | } 9 | 10 | // requestAnimationFrame for Smart Animating http://goo.gl/sx5sts 11 | var requestAnimFrame = (function() { 12 | return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } 13 | })() 14 | 15 | // because it's so fucking difficult to detect the scrolling element, just move them all 16 | function move(amount) { 17 | document.documentElement.scrollTop = amount 18 | document.body.parentNode.scrollTop = amount 19 | document.body.scrollTop = amount 20 | } 21 | 22 | function position() { 23 | return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop 24 | } 25 | 26 | export function scrollTo(to, duration, callback) { 27 | const start = position() 28 | const change = to - start 29 | const increment = 20 30 | let currentTime = 0 31 | duration = (typeof (duration) === 'undefined') ? 500 : duration 32 | var animateScroll = function() { 33 | // increment the time 34 | currentTime += increment 35 | // find the value with the quadratic in-out easing function 36 | var val = Math.easeInOutQuad(currentTime, start, change, duration) 37 | // move the document.body 38 | move(val) 39 | // do the animation unless its over 40 | if (currentTime < duration) { 41 | requestAnimFrame(animateScroll) 42 | } else { 43 | if (callback && typeof (callback) === 'function') { 44 | // the animation is done so lets callback 45 | callback() 46 | } 47 | } 48 | } 49 | animateScroll() 50 | } 51 | -------------------------------------------------------------------------------- /resource/src/utils/validate.js: -------------------------------------------------------------------------------- 1 | 2 | export function isvalidUsername(str) { 3 | const valid_map = /^[\w]{5,320}$/ 4 | console.log(valid_map.test(str)) 5 | return valid_map.test(str) 6 | } 7 | 8 | /* 合法uri*/ 9 | export function validateURL(textval) { 10 | const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ 11 | return urlregex.test(textval) 12 | } 13 | 14 | /* 小写字母*/ 15 | export function validateLowerCase(str) { 16 | const reg = /^[a-z]+$/ 17 | return reg.test(str) 18 | } 19 | 20 | /* 大写字母*/ 21 | export function validateUpperCase(str) { 22 | const reg = /^[A-Z]+$/ 23 | return reg.test(str) 24 | } 25 | 26 | /* 大小写字母*/ 27 | export function validatAlphabets(str) { 28 | const reg = /^[A-Za-z]+$/ 29 | return reg.test(str) 30 | } 31 | -------------------------------------------------------------------------------- /resource/src/views/dashboard/editor/index.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div class="dashboard-editor-container"> 3 | <div class=" clearfix"> 4 | <aimer-thumb :image="avatar" style="float: left"> Your roles: 5 | <saimer v-for="item in roles" :key="item" class="aimer-info-roles">{{ item }}</saimer> 6 | </aimer-thumb> 7 | <github-corner style="position: absolute; top: 0px; border: 0; right: 0;"/> 8 | <div class="info-container"> 9 | <saimer class="display_name">{{ name }}</saimer> 10 | <saimer style="font-size:20px;padding-top:20px;display:inline-block;">Editor's Dashboard</saimer> 11 | </div> 12 | </div> 13 | <div> 14 | <img :src="emptyGif" class="emptyGif"> 15 | </div> 16 | </div> 17 | </template> 18 | 19 | <script> 20 | import { mapGetters } from 'vuex' 21 | import AimerThumb from '@/components/AimerThumb' 22 | import GithubCorner from '@/components/GithubCorner' 23 | 24 | export default { 25 | name: 'DashboardEditor', 26 | components: { AimerThumb, GithubCorner }, 27 | data() { 28 | return { 29 | emptyGif: 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3' 30 | } 31 | }, 32 | computed: { 33 | ...mapGetters([ 34 | 'name', 35 | 'avatar', 36 | 'roles' 37 | ]) 38 | } 39 | } 40 | </script> 41 | 42 | <style rel="stylesheet/scss" lang="scss" scoped> 43 | .emptyGif { 44 | display: block; 45 | width: 45%; 46 | margin: 0 auto; 47 | } 48 | 49 | .dashboard-editor-container { 50 | background-color: #e3e3e3; 51 | min-height: 100vh; 52 | padding: 50px 60px 0px; 53 | .aimer-info-roles { 54 | font-size: 12px; 55 | font-weight: 700; 56 | color: #333; 57 | display: block; 58 | } 59 | .info-container { 60 | position: relative; 61 | margin-left: 190px; 62 | height: 150px; 63 | line-height: 200px; 64 | .display_name { 65 | font-size: 48px; 66 | line-height: 48px; 67 | color: #212121; 68 | position: absolute; 69 | top: 25px; 70 | } 71 | } 72 | } 73 | </style> 74 | -------------------------------------------------------------------------------- /resource/src/views/dashboard/index.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div class="dashboard-container"> 3 | <component :is="currentRole"/> 4 | </div> 5 | </template> 6 | 7 | <script> 8 | import { mapGetters } from 'vuex' 9 | import adminDashboard from './admin' 10 | import editorDashboard from './editor' 11 | 12 | export default { 13 | name: 'Dashboard', 14 | components: { adminDashboard, editorDashboard }, 15 | data() { 16 | return { 17 | currentRole: 'adminDashboard' 18 | } 19 | }, 20 | computed: { 21 | ...mapGetters([ 22 | 'roles' 23 | ]) 24 | }, 25 | created() { 26 | if (!this.roles.includes('admin')) { 27 | this.currentRole = 'editorDashboard' 28 | } 29 | } 30 | } 31 | </script> 32 | -------------------------------------------------------------------------------- /resource/src/views/layout/Layout.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div :class="classObj" class="app-wrapper"> 3 | <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/> 4 | <sidebar class="sidebar-container"/> 5 | <div class="main-container"> 6 | <div> 7 | <navbar /> 8 | <!-- <tags-view v-if="needTagsView" /> --> 9 | </div> 10 | <app-main/> 11 | </div> 12 | </div> 13 | </template> 14 | 15 | <script> 16 | import { Navbar, Sidebar, AppMain, TagsView } from './components' 17 | import ResizeMixin from './mixin/ResizeHandler' 18 | import { mapState } from 'vuex' 19 | 20 | export default { 21 | name: 'Layout', 22 | components: { 23 | Navbar, 24 | Sidebar, 25 | AppMain, 26 | TagsView 27 | }, 28 | mixins: [ResizeMixin], 29 | computed: { 30 | ...mapState({ 31 | sidebar: state => state.app.sidebar, 32 | device: state => state.app.device, 33 | howSettings: state => state.settings.showSettings 34 | // needTagsView: state => state.settings.tagsView, 35 | // fixedHeader: state => state.settings.fixedHeader 36 | }), 37 | classObj() { 38 | return { 39 | hideSidebar: !this.sidebar.opened, 40 | openSidebar: this.sidebar.opened, 41 | withoutAnimation: this.sidebar.withoutAnimation, 42 | mobile: this.device === 'mobile' 43 | } 44 | } 45 | }, 46 | methods: { 47 | handleClickOutside() { 48 | this.$store.dispatch('CloseSideBar', { withoutAnimation: false }) 49 | } 50 | } 51 | } 52 | </script> 53 | 54 | <style rel="stylesheet/scss" lang="scss" scoped> 55 | @import "src/styles/mixin.scss"; 56 | .app-wrapper { 57 | @include clearfix; 58 | position: relative; 59 | height: 100%; 60 | width: 100%; 61 | &.mobile.openSidebar{ 62 | position: fixed; 63 | top: 0; 64 | } 65 | } 66 | .drawer-bg { 67 | background: #000; 68 | opacity: 0.3; 69 | width: 100%; 70 | top: 0; 71 | height: 100%; 72 | position: absolute; 73 | z-index: 999; 74 | } 75 | </style> 76 | -------------------------------------------------------------------------------- /resource/src/views/layout/components/AppMain.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <section class="app-main"> 3 | <transition name="fade-transform" mode="out-in"> 4 | <!-- or name="fade" --> 5 | <!-- <router-view :key="key"></router-view> --> 6 | <!-- <keep-alive :include="cachedViews"> 7 | <router-view :key="key" /> 8 | </keep-alive> --> 9 | <router-view/> 10 | </transition> 11 | </section> 12 | </template> 13 | 14 | <script> 15 | export default { 16 | name: 'AppMain', 17 | computed: { 18 | cachedViews() { 19 | return this.$store.state.tagsView.cachedViews 20 | } 21 | // key() { 22 | // return this.$route.fullPath 23 | // } 24 | } 25 | } 26 | </script> 27 | 28 | <style lang="scss" scoped> 29 | .app-main { 30 | /* 50= navbar 50 */ 31 | min-height: calc(100vh - 50px); 32 | width: 100%; 33 | position: relative; 34 | overflow: hidden; 35 | } 36 | 37 | .fixed-header+.app-main { 38 | padding-top: 50px; 39 | } 40 | 41 | .hasTagsView { 42 | .app-main { 43 | /* 84 = navbar + tags-view = 50 + 34 */ 44 | min-height: calc(100vh - 84px); 45 | } 46 | 47 | .fixed-header+.app-main { 48 | padding-top: 84px; 49 | } 50 | } 51 | </style> 52 | 53 | -------------------------------------------------------------------------------- /resource/src/views/layout/components/Sidebar/Item.vue: -------------------------------------------------------------------------------- 1 | <script> 2 | export default { 3 | name: 'MenuItem', 4 | functional: true, 5 | props: { 6 | icon: { 7 | type: String, 8 | default: '' 9 | }, 10 | title: { 11 | type: String, 12 | default: '' 13 | } 14 | }, 15 | render(h, context) { 16 | const { icon, title } = context.props 17 | const vnodes = [] 18 | 19 | if (icon) { 20 | vnodes.push(<svg-icon icon-class={icon}/>) 21 | } 22 | 23 | if (title) { 24 | vnodes.push(<span slot='title'>{(title)}</span>) 25 | } 26 | return vnodes 27 | } 28 | } 29 | </script> 30 | -------------------------------------------------------------------------------- /resource/src/views/layout/components/Sidebar/Link.vue: -------------------------------------------------------------------------------- 1 | 2 | <template> 3 | <!-- eslint-disable vue/require-component-is--> 4 | <component v-bind="linkProps(to)"> 5 | <slot/> 6 | </component> 7 | </template> 8 | 9 | <script> 10 | import { isExternal } from '@/utils' 11 | 12 | export default { 13 | props: { 14 | to: { 15 | type: String, 16 | required: true 17 | } 18 | }, 19 | methods: { 20 | isExternalLink(routePath) { 21 | return isExternal(routePath) 22 | }, 23 | linkProps(url) { 24 | if (this.isExternalLink(url)) { 25 | return { 26 | is: 'a', 27 | href: url, 28 | target: '_blank', 29 | rel: 'noopener' 30 | } 31 | } 32 | return { 33 | is: 'router-link', 34 | to: url 35 | } 36 | } 37 | } 38 | } 39 | </script> 40 | -------------------------------------------------------------------------------- /resource/src/views/layout/components/index.js: -------------------------------------------------------------------------------- 1 | // export { default as Navbar } from './Navbar' 2 | // export { default as Sidebar } from './Sidebar' 3 | // export { default as AppMain } from './AppMain' 4 | 5 | export { default as AppMain } from './AppMain' 6 | export { default as Navbar } from './Navbar' 7 | // export { default as Settings } from './Settings' 8 | export { default as Sidebar } from './Sidebar/index.vue' 9 | export { default as TagsView } from './TagsView/index.vue' 10 | -------------------------------------------------------------------------------- /resource/src/views/layout/mixin/ResizeHandler.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | 3 | const { body } = document 4 | const WIDTH = 1024 5 | const RATIO = 3 6 | 7 | export default { 8 | watch: { 9 | $route(route) { 10 | if (this.device === 'mobile' && this.sidebar.opened) { 11 | store.dispatch('CloseSideBar', { withoutAnimation: false }) 12 | } 13 | } 14 | }, 15 | beforeMount() { 16 | window.addEventListener('resize', this.resizeHandler) 17 | }, 18 | mounted() { 19 | const isMobile = this.isMobile() 20 | if (isMobile) { 21 | store.dispatch('ToggleDevice', 'mobile') 22 | store.dispatch('CloseSideBar', { withoutAnimation: true }) 23 | } 24 | }, 25 | methods: { 26 | isMobile() { 27 | const rect = body.getBoundingClientRect() 28 | return rect.width - RATIO < WIDTH 29 | }, 30 | resizeHandler() { 31 | if (!document.hidden) { 32 | const isMobile = this.isMobile() 33 | store.dispatch('ToggleDevice', isMobile ? 'mobile' : 'desktop') 34 | 35 | if (isMobile) { 36 | store.dispatch('CloseSideBar', { withoutAnimation: true }) 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /resource/src/views/nested/menu1/index.vue: -------------------------------------------------------------------------------- 1 | <template > 2 | <div style="padding:30px;"> 3 | <el-alert :closable="false" title="menu 1"> 4 | <router-view /> 5 | </el-alert> 6 | </div> 7 | </template> 8 | -------------------------------------------------------------------------------- /resource/src/views/nested/menu1/menu1-1/index.vue: -------------------------------------------------------------------------------- 1 | <template > 2 | <div style="padding:30px;"> 3 | <el-alert :closable="false" title="menu 1-1" type="success"> 4 | <router-view /> 5 | </el-alert> 6 | </div> 7 | </template> 8 | -------------------------------------------------------------------------------- /resource/src/views/nested/menu1/menu1-2/index.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div style="padding:30px;"> 3 | <el-alert :closable="false" title="menu 1-2" type="success"> 4 | <router-view /> 5 | </el-alert> 6 | </div> 7 | </template> 8 | -------------------------------------------------------------------------------- /resource/src/views/nested/menu1/menu1-2/menu1-2-1/index.vue: -------------------------------------------------------------------------------- 1 | <template functional> 2 | <div style="padding:30px;"> 3 | <el-alert :closable="false" title="menu 1-2-1" type="warning" /> 4 | </div> 5 | </template> 6 | -------------------------------------------------------------------------------- /resource/src/views/nested/menu1/menu1-2/menu1-2-2/index.vue: -------------------------------------------------------------------------------- 1 | <template functional> 2 | <div style="padding:30px;"> 3 | <el-alert :closable="false" title="menu 1-2-2" type="warning" /> 4 | </div> 5 | </template> 6 | -------------------------------------------------------------------------------- /resource/src/views/nested/menu1/menu1-3/index.vue: -------------------------------------------------------------------------------- 1 | <template functional> 2 | <div style="padding:30px;"> 3 | <el-alert :closable="false" title="menu 1-3" type="success" /> 4 | </div> 5 | </template> 6 | -------------------------------------------------------------------------------- /resource/src/views/nested/menu2/index.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div style="padding:30px;"> 3 | <el-alert :closable="false" title="menu 2" /> 4 | </div> 5 | </template> 6 | -------------------------------------------------------------------------------- /resource/src/views/tree/index.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div class="app-container"> 3 | <el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" /> 4 | 5 | <el-tree 6 | ref="tree2" 7 | :data="data2" 8 | :props="defaultProps" 9 | :filter-node-method="filterNode" 10 | class="filter-tree" 11 | default-expand-all 12 | /> 13 | 14 | </div> 15 | </template> 16 | 17 | <script> 18 | export default { 19 | 20 | data() { 21 | return { 22 | filterText: '', 23 | data2: [{ 24 | id: 1, 25 | label: 'Level one 1', 26 | children: [{ 27 | id: 4, 28 | label: 'Level two 1-1', 29 | children: [{ 30 | id: 9, 31 | label: 'Level three 1-1-1' 32 | }, { 33 | id: 10, 34 | label: 'Level three 1-1-2' 35 | }] 36 | }] 37 | }, { 38 | id: 2, 39 | label: 'Level one 2', 40 | children: [{ 41 | id: 5, 42 | label: 'Level two 2-1' 43 | }, { 44 | id: 6, 45 | label: 'Level two 2-2' 46 | }] 47 | }, { 48 | id: 3, 49 | label: 'Level one 3', 50 | children: [{ 51 | id: 7, 52 | label: 'Level two 3-1' 53 | }, { 54 | id: 8, 55 | label: 'Level two 3-2' 56 | }] 57 | }], 58 | defaultProps: { 59 | children: 'children', 60 | label: 'label' 61 | } 62 | } 63 | }, 64 | watch: { 65 | filterText(val) { 66 | this.$refs.tree2.filter(val) 67 | } 68 | }, 69 | 70 | methods: { 71 | filterNode(value, data) { 72 | if (!value) return true 73 | return data.label.indexOf(value) !== -1 74 | } 75 | } 76 | } 77 | </script> 78 | 79 | -------------------------------------------------------------------------------- /resource/src/views/user/info/index.vue: -------------------------------------------------------------------------------- 1 | <template> 2 | <div class="dashboard-editor-container"> 3 | 4 | <el-row style="margin-left:22px;padding:6px 0px 6px 18px;"> 5 | <el-switch 6 | v-model="currentModel" 7 | style="display: block" 8 | active-color="#13ce66" 9 | inactive-color="#ff4949" 10 | active-text="编辑模式" 11 | inactive-text="总览模式" 12 | active-value="userInfoEdit" 13 | inactive-value="userInfoView" 14 | @change="mod" 15 | /></el-row> 16 | 17 | <!-- <component :is="currentModel" /> --> 18 | <userInfoEdit v-if="abc" /> 19 | <userInfoView v-else-if="abc"/> 20 | </div> 21 | </template> 22 | 23 | <script> 24 | import userInfoEdit from './components/edit' 25 | import userInfoView from './components/view' 26 | 27 | export default { 28 | name: 'UserInfoTest', 29 | components: { userInfoEdit, userInfoView }, 30 | data() { 31 | return { 32 | currentModel: 'userInfoView', 33 | abc: false 34 | } 35 | }, 36 | methods: { 37 | mod() { 38 | this.abc = true 39 | } 40 | } 41 | } 42 | </script> 43 | 44 | -------------------------------------------------------------------------------- /resource/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/resource/static/.gitkeep -------------------------------------------------------------------------------- /routers/api/auth/auth.go: -------------------------------------------------------------------------------- 1 | package AuthRouter 2 | 3 | import ( 4 | "github.com/auxpi/controllers/api/v1" 5 | "github.com/auxpi/middleware" 6 | 7 | "github.com/astaxie/beego" 8 | ) 9 | 10 | func RegisterMiddleWare() { 11 | //登录用户中间件 =>已登录重定向 12 | beego.InsertFilter("/login", beego.BeforeExec, middleware.CookieAuthedCheck) 13 | //重置密码中间件 =>已登录重定向 14 | beego.InsertFilter("/reset/*", beego.BeforeExec, middleware.CookieAuthedCheck) 15 | //忘记密码中间件 =>已登录重定向 16 | beego.InsertFilter("/forgot", beego.BeforeExec, middleware.CookieAuthedCheck) 17 | //注册中间件 =>已登录重定向 18 | beego.InsertFilter("/register/*", beego.BeforeExec, middleware.CookieAuthedCheck) 19 | //登出中间件 =>未登录重定向 20 | beego.InsertFilter("/logout", beego.BeforeExec, middleware.CookieAuthCheck) 21 | } 22 | 23 | //登录所使用的 api ,所有 api 都是无状态的 24 | func RegisterApi() { 25 | ns := 26 | beego.NewNamespace("/api/v1/auth", 27 | beego.NSRouter("/login", &v1.Auth{}, "post:GetAuthByUserName"), 28 | beego.NSRouter("/info", &v1.Admin{}, "get:GetInfo"), 29 | beego.NSRouter("/logout", &v1.Auth{}, "post:Destroy"), 30 | ) 31 | beego.AddNamespace(ns) 32 | } 33 | 34 | //登录所使用的路由 35 | func RegisterRouter() { 36 | //登录 37 | beego.Router("/login", &v1.Auth{}, "get:Show") 38 | beego.Router("/login", &v1.Auth{}, "post:Store") 39 | //注册 40 | beego.Router("/register", &v1.Auth{}, "get:Register") 41 | beego.Router("/register", &v1.Auth{}, "post:DoRegister") 42 | beego.Router(`/register/active/:token(^[\w|-]+$)`, &v1.Auth{}, "get:Register") 43 | //忘记密码 44 | beego.Router("/forgot", &v1.Auth{}, "get:Forgot") 45 | beego.Router("/forgot", &v1.Auth{}, "post:DoForgot") 46 | //密码找回 47 | beego.Router(`/reset/:token(^[\w|-]+$)`, &v1.Auth{}, "get:Reset") 48 | beego.Router(`/reset`, &v1.Auth{}, "post:DoReset") 49 | //信息页 50 | beego.Router("/msg", &v1.Auth{}, "get:Msg") 51 | //登出 52 | beego.Router("/logout", &v1.Auth{}, "get:Destroy") 53 | } 54 | -------------------------------------------------------------------------------- /routers/api/v1/upload.go: -------------------------------------------------------------------------------- 1 | package v1Router 2 | 3 | import ( 4 | "github.com/auxpi/controllers" 5 | "github.com/auxpi/controllers/api/v1" 6 | "github.com/auxpi/middleware" 7 | 8 | "github.com/astaxie/beego" 9 | ) 10 | 11 | //上传中间件 12 | func RegisterUploadMiddleWare() { 13 | beego.InsertFilter("/api/v1/web_upload/", beego.BeforeExec, middleware.CookieUploadControl) 14 | beego.InsertFilter("/api/v1/web_upload/", beego.BeforeExec, middleware.UploadLimit) 15 | beego.InsertFilter("/api/v1/upload", beego.BeforeExec, middleware.UploadLimit) 16 | beego.InsertFilter("/api/v1/upload", beego.BeforeExec, middleware.Upload) 17 | } 18 | 19 | //不需要控制的 API 20 | func RegisterOpenApi() { 21 | //不需要控制的 api 放到这里 22 | ns := 23 | beego.NewNamespace("/api/v1", 24 | beego.NSRouter("/web_upload/", &controllers.WebUpLoadController{}, "post:UpLoadHandle"), 25 | ) 26 | beego.AddNamespace(ns) 27 | } 28 | 29 | //需要控制的 API 30 | func RegisterControlApi() { 31 | //if bootstrap.SiteConfig.OpenApiUpLoad { 32 | beego.Router("api/v1/upload", &v1.ApiUploadController{}, "post:UpLoadHandle") 33 | //} 34 | } 35 | -------------------------------------------------------------------------------- /routers/api/v1/user.go: -------------------------------------------------------------------------------- 1 | package v1Router 2 | 3 | import ( 4 | "github.com/auxpi/controllers" 5 | "github.com/auxpi/controllers/api/v1" 6 | "github.com/auxpi/middleware" 7 | 8 | "github.com/astaxie/beego" 9 | ) 10 | 11 | //注册路由所需的中间件 12 | 13 | func RegisterUserMiddleWare() { 14 | //所有用户开头的路由全部需要登录 15 | beego.InsertFilter("/users/*", beego.BeforeExec, middleware.CookieAuthCheck) 16 | //用户信息需要 jwt 认证 17 | beego.InsertFilter("/api/v1/users/*", beego.BeforeExec, middleware.JWT) 18 | 19 | } 20 | 21 | //不需要控制的 API 22 | func RegisterUserAPi() { 23 | //不需要控制的 api 放到这里 24 | ns := 25 | beego.NewNamespace("/api/v1/users", 26 | //用户图片 27 | beego.NSRouter("/:id/images", &v1.User{}, "get:UserImages"), 28 | //用户信息 29 | beego.NSRouter("/:id/info", &v1.User{}, "get:UserInfo"), 30 | ) 31 | beego.AddNamespace(ns) 32 | } 33 | 34 | //非 api 路由 35 | func RegisterUserRouter() { 36 | ns := 37 | beego.NewNamespace("/users", 38 | //用户后台首页 39 | //TODO:使用 API 40 | beego.NSRouter("/index", &controllers.UsersController{}, "get:Show"), 41 | //用户后台首页重定向 42 | beego.NSRouter("", &controllers.UsersController{}, "get:Show"), 43 | //用户个人信息+修改 44 | //TODO:使用 API 45 | beego.NSRouter("/edit", &controllers.UsersController{}, "get:Edit"), 46 | //修改用户信息 47 | beego.NSRouter("/:id/edit", &controllers.UsersController{}, "post:ResetPass"), 48 | ) 49 | beego.AddNamespace(ns) 50 | } 51 | -------------------------------------------------------------------------------- /routers/api/v1/ws.go: -------------------------------------------------------------------------------- 1 | package v1Router 2 | 3 | import ( 4 | "github.com/auxpi/controllers/ws" 5 | 6 | "github.com/astaxie/beego" 7 | ) 8 | 9 | //WebSocket 路由 10 | 11 | func RegisterWs() { 12 | beego.Router("/api/ws/sync", &ws.WebSocketController{}, "get:Join") 13 | } 14 | -------------------------------------------------------------------------------- /routers/api/v2/dispatch.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package v2Router 15 | 16 | import ( 17 | "github.com/astaxie/beego" 18 | v2 "github.com/auxpi/controllers/api/v2" 19 | "github.com/auxpi/middleware" 20 | ) 21 | 22 | //上传中间件 23 | func RegisterUploadMiddleWare() { 24 | beego.InsertFilter("/api/v2/upload", beego.BeforeExec, middleware.Upload) 25 | 26 | } 27 | 28 | //不需要控制的 API 29 | func RegisterApi() { 30 | //分发路由归属于 v2 31 | beego.Router(`dispatch/:hash(^[\w]+$)`, &v2.DispatchController{}, "get:Dispatch") 32 | 33 | // api 放到这里 34 | ns := 35 | beego.NewNamespace("/api/v2", 36 | beego.NSRouter("/upload/", &v2.DispatchController{}, "post:UploadToRoot"), 37 | ) 38 | beego.AddNamespace(ns) 39 | } 40 | 41 | ////需要控制的 API 42 | //func RegisterControlApi() { 43 | // if bootstrap.SiteConfig.OpenApiUpLoad { 44 | // beego.Router("api/v1/upload", &v1.ApiUploadController{}, "post:UpLoadHandle") 45 | // } 46 | //} 47 | -------------------------------------------------------------------------------- /server/Ali.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package server 15 | 16 | import ( 17 | "github.com/auxpi/auxpiAll" 18 | "github.com/auxpi/tools" 19 | ) 20 | 21 | type Ali struct { 22 | FileLimit []string 23 | MaxSize int 24 | } 25 | 26 | func (s *Ali) UploadToAli(img []byte, imgInfo string, imgType string) string { 27 | url := "https://kfupload.alibaba.com/mupload" 28 | name := tools.GetFileNameByMimeType(imgInfo) 29 | 30 | file := &auxpi.FormFile{ 31 | Name: name, 32 | Key: "file", 33 | Value: img, 34 | Type: imgType, 35 | } 36 | //var header map[string]string 37 | data := tools.AliFormPost(file, url) 38 | j := auxpi.AliResp{} 39 | j.UnmarshalJSON([]byte(data)) 40 | return j.Url 41 | } 42 | 43 | func (s *Ali) Upload(image *ImageParam) (ImageReturn, error) { 44 | url := "https://kfupload.alibaba.com/mupload" 45 | 46 | file := &auxpi.FormFile{ 47 | Name: image.Name, 48 | Key: "file", 49 | Value: *image.Content, 50 | Type: image.Type, 51 | } 52 | //var header map[string]string 53 | data := tools.AliFormPost(file, url) 54 | j := auxpi.AliResp{} 55 | j.UnmarshalJSON([]byte(data)) 56 | return ImageReturn{ 57 | Url: j.Url, 58 | ID: 11, 59 | }, 60 | nil 61 | } 62 | -------------------------------------------------------------------------------- /server/JueJin.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package server 15 | 16 | import ( 17 | "github.com/auxpi/auxpiAll" 18 | "github.com/auxpi/tools" 19 | ) 20 | 21 | type JueJin struct { 22 | FileLimit []string 23 | MaxSize int 24 | } 25 | 26 | func (s *JueJin) Upload(image *ImageParam) (ImageReturn, error) { 27 | url := "https://cdn-ms.juejin.im/v1/upload?bucket=gold-user-assets" 28 | 29 | file := &auxpi.FormFile{ 30 | Name: image.Name, 31 | Key: "file", 32 | Value: *image.Content, 33 | Type: image.Type, 34 | } 35 | var header map[string]string 36 | data := tools.FormPost(file, url, header) 37 | j := auxpi.JueJinResp{} 38 | err := j.UnmarshalJSON([]byte(data)) 39 | if err != nil { 40 | return ImageReturn{}, err 41 | } 42 | return ImageReturn{ 43 | Url: j.D.URL.HTTPS, 44 | ID: 10, 45 | }, nil 46 | } 47 | 48 | func (s *JueJin) UploadToJueJin(img []byte, imgInfo string, imgType string) string { 49 | url := "https://cdn-ms.juejin.im/v1/upload?bucket=gold-user-assets" 50 | name := tools.GetFileNameByMimeType(imgInfo) 51 | 52 | file := &auxpi.FormFile{ 53 | Name: name, 54 | Key: "file", 55 | Value: img, 56 | Type: imgType, 57 | } 58 | var header map[string]string 59 | data := tools.FormPost(file, url, header) 60 | j := auxpi.JueJinResp{} 61 | j.UnmarshalJSON([]byte(data)) 62 | return j.D.URL.HTTPS 63 | } 64 | -------------------------------------------------------------------------------- /server/NetEasy.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package server 15 | 16 | import ( 17 | "github.com/astaxie/beego" 18 | "github.com/auxpi/auxpiAll" 19 | "github.com/auxpi/tools" 20 | ) 21 | 22 | type NetEasy struct { 23 | FileLimit []string 24 | MaxSize int 25 | } 26 | 27 | func (s *NetEasy) Upload(image *ImageParam) (ImageReturn, error) { 28 | url := "http://you.163.com/xhr/file/upload.json" 29 | 30 | file := &auxpi.FormFile{ 31 | Name: image.Name, 32 | Key: "file", 33 | Value: *image.Content, 34 | Type: image.Type, 35 | } 36 | var header map[string]string 37 | data := tools.FormPost(file, url, header) 38 | j := auxpi.NetEasyResp{} 39 | err := j.UnmarshalJSON([]byte(data)) 40 | if err != nil { 41 | return ImageReturn{}, err 42 | } 43 | return ImageReturn{ 44 | Url: j.Data[0], 45 | ID: 8, 46 | }, nil 47 | } 48 | 49 | func (s *NetEasy) UploadToNetEasy(img []byte, imgInfo string, imgType string) string { 50 | url := "http://you.163.com/xhr/file/upload.json" 51 | name := tools.GetFileNameByMimeType(imgInfo) 52 | 53 | file := &auxpi.FormFile{ 54 | Name: name, 55 | Key: "file", 56 | Value: img, 57 | Type: imgType, 58 | } 59 | var header map[string]string 60 | data := tools.FormPost(file, url, header) 61 | j := auxpi.NetEasyResp{} 62 | j.UnmarshalJSON([]byte(data)) 63 | beego.Alert(j.Data[0]) 64 | return j.Data[0] 65 | } 66 | -------------------------------------------------------------------------------- /server/Ooxx.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package server 15 | 16 | import ( 17 | "encoding/json" 18 | 19 | "github.com/auxpi/auxpiAll" 20 | "github.com/auxpi/tools" 21 | ) 22 | 23 | type OOXX struct { 24 | FileLimit []string 25 | MaxSize int 26 | } 27 | 28 | func (s *OOXX) Upload(image *ImageParam) (ImageReturn, error) { 29 | url := "https://ooxx.ooo/upload" 30 | 31 | file := &auxpi.FormFile{ 32 | Name: image.Name, 33 | Key: "files[]", 34 | Value: *image.Content, 35 | Type: image.Type, 36 | } 37 | var header map[string]string 38 | data := tools.FormPost(file, url, header) 39 | var m = []string{} 40 | json.Unmarshal([]byte(data), &m) 41 | 42 | return ImageReturn{ 43 | Url: "https://i.ooxx.ooo" + m[0], 44 | ID: 16, 45 | }, nil 46 | 47 | } 48 | 49 | func (s *OOXX) UploadToOOXX(img []byte, imgInfo string, imgType string) string { 50 | url := "https://ooxx.ooo/upload" 51 | name := tools.GetFileNameByMimeType(imgInfo) 52 | 53 | file := &auxpi.FormFile{ 54 | Name: name, 55 | Key: "files[]", 56 | Value: img, 57 | Type: imgType, 58 | } 59 | var header map[string]string 60 | data := tools.FormPost(file, url, header) 61 | var m = []string{} 62 | json.Unmarshal([]byte(data), &m) 63 | 64 | return "https://i.ooxx.ooo" + m[0] 65 | } 66 | -------------------------------------------------------------------------------- /server/Qihoo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package server 15 | 16 | import ( 17 | "regexp" 18 | 19 | "github.com/auxpi/auxpiAll" 20 | "github.com/auxpi/tools" 21 | ) 22 | 23 | type Qihoo struct { 24 | FileLimit []string 25 | MaxSize int 26 | } 27 | 28 | func (this *Qihoo) UploadToQihoo(img []byte, imgInfo string, imgType string) string { 29 | url := "http://kuaichuan.360.cn/upload/img" 30 | name := tools.GetFileNameByMimeType(imgInfo) 31 | 32 | file := &auxpi.FormFile{ 33 | Name: name, 34 | Key: "upload", 35 | Value: img, 36 | Type: imgType, 37 | } 38 | var header map[string]string 39 | data := tools.FormPost(file, url, header) 40 | var re = regexp.MustCompile(`(?m)data-imgkey="(.*)"`) 41 | imgKey := re.FindAllStringSubmatch(data, -1)[0][1] 42 | url = "https://ps.ssl.qhmsg.com/" + imgKey 43 | return url 44 | } 45 | -------------------------------------------------------------------------------- /server/Souhu.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package server 15 | 16 | import ( 17 | "regexp" 18 | "strings" 19 | 20 | "github.com/astaxie/beego" 21 | "github.com/auxpi/auxpiAll" 22 | "github.com/auxpi/tools" 23 | ) 24 | 25 | type SouHu struct { 26 | FileLimit []string 27 | MaxSize int 28 | } 29 | 30 | func (s *SouHu) Upload(image *ImageParam) (ImageReturn, error) { 31 | url := "http://changyan.sohu.com/api/2/comment/attachment" 32 | 33 | file := &auxpi.FormFile{ 34 | Name: image.Name, 35 | Key: "file", 36 | Value: *image.Content, 37 | Type: image.Type, 38 | } 39 | var header map[string]string 40 | data := tools.FormPost(file, url, header) 41 | var re = regexp.MustCompile(`(?m)"{\\"url\\":\\"(.*)\\"}"`) 42 | imgFix := re.FindAllStringSubmatch(data, -1)[0][1] 43 | url = strings.Replace(imgFix, "http", "https", 4) 44 | 45 | return ImageReturn{ 46 | Url: url, 47 | ID: 17, 48 | }, nil 49 | } 50 | 51 | func (s *SouHu) UploadToSouHu(img []byte, imgInfo string, imgType string) string { 52 | url := "http://changyan.sohu.com/api/2/comment/attachment" 53 | name := tools.GetFileNameByMimeType(imgInfo) 54 | file := &auxpi.FormFile{ 55 | Name: name, 56 | Key: "file", 57 | Value: img, 58 | Type: imgType, 59 | } 60 | var header map[string]string 61 | data := tools.FormPost(file, url, header) 62 | var re = regexp.MustCompile(`(?m)"{\\"url\\":\\"(.*)\\"}"`) 63 | imgFix := re.FindAllStringSubmatch(data, -1)[0][1] 64 | url = strings.Replace(imgFix, "http", "https", 4) 65 | beego.Alert(url) 66 | return url 67 | } 68 | -------------------------------------------------------------------------------- /server/SuNing.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package server 15 | 16 | import ( 17 | "encoding/json" 18 | 19 | "github.com/astaxie/beego" 20 | "github.com/auxpi/auxpiAll" 21 | "github.com/auxpi/tools" 22 | ) 23 | 24 | type SuNing struct { 25 | FileLimit []string 26 | MaxSize int 27 | } 28 | 29 | func (this *SuNing) Upload(image *ImageParam) (ImageReturn, error) { 30 | url := "http://review.suning.com/imageload/uploadImg.do" 31 | 32 | file := &auxpi.FormFile{ 33 | Name: image.Name, 34 | Key: "Filedata", 35 | Value: *image.Content, 36 | Type: image.Type, 37 | } 38 | 39 | data := tools.SuNingFormPost(file, url) 40 | s := auxpi.SuNingResp{} 41 | err := s.UnmarshalJSON([]byte(data)) 42 | 43 | if err != nil { 44 | return ImageReturn{}, err 45 | } 46 | 47 | url = "https:" + s.Src + ".jpg" 48 | 49 | return ImageReturn{ 50 | Url: url, 51 | ID: 13, 52 | }, nil 53 | } 54 | 55 | func (this *SuNing) UploadToSuNing(img []byte, imgInfo string, imgType string) string { 56 | url := "http://review.suning.com/imageload/uploadImg.do" 57 | name := tools.GetFileNameByMimeType(imgInfo) 58 | 59 | file := &auxpi.FormFile{ 60 | Name: name, 61 | Key: "Filedata", 62 | Value: img, 63 | Type: imgType, 64 | } 65 | 66 | data := tools.SuNingFormPost(file, url) 67 | var m = make(map[string]string) 68 | json.Unmarshal([]byte(data), &m) 69 | beego.Alert(data) 70 | url = "https:" + m["src"] + ".jpg" 71 | 72 | return url 73 | } 74 | -------------------------------------------------------------------------------- /server/TouTiao.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package server 15 | 16 | import ( 17 | "github.com/auxpi/auxpiAll" 18 | "github.com/auxpi/tools" 19 | ) 20 | 21 | type TouTiao struct { 22 | FileLimit []string 23 | MaxSize int 24 | } 25 | 26 | func (s *TouTiao) Upload(image *ImageParam) (ImageReturn, error) { 27 | url := "https://mp.toutiao.com/upload_photo/?type=json" 28 | 29 | file := &auxpi.FormFile{ 30 | Name: image.Name, 31 | Key: "photo", 32 | Value: *image.Content, 33 | Type: image.Type, 34 | } 35 | var header map[string]string 36 | data := tools.FormPost(file, url, header) 37 | var t = auxpi.TouTiaoResp{} 38 | err := t.UnmarshalJSON([]byte(data)) 39 | if err != nil { 40 | return ImageReturn{}, err 41 | } 42 | 43 | return ImageReturn{ 44 | Url: t.WebURL, 45 | ID: 19, 46 | }, nil 47 | } 48 | 49 | func (s *TouTiao) UploadToTouTiao(img []byte, imgInfo string, imgType string) string { 50 | url := "https://mp.toutiao.com/upload_photo/?type=json" 51 | name := tools.GetFileNameByMimeType(imgInfo) 52 | 53 | file := &auxpi.FormFile{ 54 | Name: name, 55 | Key: "photo", 56 | Value: img, 57 | Type: imgType, 58 | } 59 | var header map[string]string 60 | data := tools.FormPost(file, url, header) 61 | var t = auxpi.TouTiaoResp{} 62 | t.UnmarshalJSON([]byte(data)) 63 | return t.WebURL 64 | } 65 | -------------------------------------------------------------------------------- /server/VIMCN.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package server 15 | 16 | import ( 17 | "github.com/auxpi/auxpiAll" 18 | "github.com/auxpi/tools" 19 | ) 20 | 21 | type VimCN struct { 22 | FileLimit []string 23 | MaxSize int 24 | } 25 | 26 | func (s *VimCN) Upload(image *ImageParam) (ImageReturn, error) { 27 | url := "https://img.vim-cn.com/" 28 | 29 | file := &auxpi.FormFile{ 30 | Name: image.Name, 31 | Key: "image", 32 | Value: *image.Content, 33 | Type: image.Type, 34 | } 35 | var header map[string]string 36 | data := tools.FormPost(file, url, header) 37 | return ImageReturn{ 38 | Url: data, 39 | ID: 15, 40 | }, nil 41 | } 42 | 43 | func (s *VimCN) UploadToVimCN(img []byte, imgInfo string, imgType string) string { 44 | url := "https://img.vim-cn.com/" 45 | name := tools.GetFileNameByMimeType(imgInfo) 46 | 47 | file := &auxpi.FormFile{ 48 | Name: name, 49 | Key: "image", 50 | Value: img, 51 | Type: imgType, 52 | } 53 | var header map[string]string 54 | data := tools.FormPost(file, url, header) 55 | return data 56 | } 57 | -------------------------------------------------------------------------------- /static/app/admin/css/app.e232d983.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/css/app.e232d983.css.gz -------------------------------------------------------------------------------- /static/app/admin/css/chunk-0bd4.95190365.css: -------------------------------------------------------------------------------- 1 | .login-container .el-input{display:inline-block;height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#eee;height:47px}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #2d3a4b inset!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container[data-v-b07c3e16]{position:fixed;height:100%;width:100%;background-color:#2d3a4b}.login-container .login-form[data-v-b07c3e16]{position:absolute;left:0;right:0;width:520px;max-width:100%;padding:35px 35px 15px;margin:120px auto}.login-container .tips[data-v-b07c3e16]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips span[data-v-b07c3e16]:first-of-type{margin-right:16px}.login-container .svg-container[data-v-b07c3e16]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title[data-v-b07c3e16]{font-size:26px;font-weight:400;color:#eee;margin:0 auto 40px;text-align:center;font-weight:700}.login-container .show-pwd[data-v-b07c3e16]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} -------------------------------------------------------------------------------- /static/app/admin/css/chunk-0fee.3a96d434.css: -------------------------------------------------------------------------------- 1 | .pagination-container[data-v-285e5c16]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-285e5c16]{display:none}.edit-input[data-v-8a99510e]{padding-right:100px}.cancel-btn[data-v-8a99510e]{position:absolute;right:15px;top:10px} -------------------------------------------------------------------------------- /static/app/admin/css/chunk-1ae2.6f706f86.css: -------------------------------------------------------------------------------- 1 | .dashboard-editor-container[data-v-b6a7212a]{padding:32px 32px 50px;background-color:#f0f2f5}.dashboard-editor-container .chart-wrapper[data-v-b6a7212a]{background:#fff;padding:16px 16px 0;margin-bottom:32px}.lineDiv[data-v-b6a7212a]{height:120px}.box[data-v-b6a7212a]{margin-top:10px}.box .el-row[data-v-b6a7212a]{margin:30px}.box .el-card[data-v-b6a7212a]{margin-top:20px} -------------------------------------------------------------------------------- /static/app/admin/css/chunk-529e.6a3f537c.css: -------------------------------------------------------------------------------- 1 | .dashboard-editor-container{padding:32px;background-color:#f0f2f5}.flip-list-move{-webkit-transition:-webkit-transform .5s;transition:-webkit-transform .5s;transition:transform .5s;transition:transform .5s,-webkit-transform .5s}.no-move{-webkit-transition:-webkit-transform 0s;transition:-webkit-transform 0s;transition:transform 0s;transition:transform 0s,-webkit-transform 0s}.ghostUse{opacity:.5;background:#c8ebfb}.list-group{min-height:20px}.el-card__body{padding:10px}.list-card-group-item{cursor:move}.box{margin-top:10px}.box .el-card{margin-top:5px} -------------------------------------------------------------------------------- /static/app/admin/css/chunk-6f53.360c2484.css: -------------------------------------------------------------------------------- 1 | .pagination-container[data-v-285e5c16]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-285e5c16]{display:none}.edit-input[data-v-34e7c135]{padding-right:100px}.cancel-btn[data-v-34e7c135]{position:absolute;right:15px;top:10px} -------------------------------------------------------------------------------- /static/app/admin/css/chunk-9a76.31e91e47.css: -------------------------------------------------------------------------------- 1 | .dashboard-editor-container[data-v-2194643e]{padding:32px;background-color:#f0f2f5}.dashboard-editor-container .chart-wrapper[data-v-2194643e]{background:#fff;padding:16px 16px 0;margin-bottom:32px}.lineDiv[data-v-2194643e]{height:120px}.box[data-v-2194643e]{margin-top:10px}.box .el-row[data-v-2194643e]{margin:30px}.box .el-card[data-v-2194643e]{margin-top:20px} -------------------------------------------------------------------------------- /static/app/admin/css/chunk-cc24.f9e05c98.css: -------------------------------------------------------------------------------- 1 | .dashboard-editor-container[data-v-a5ba94de]{padding:20px 20px 400px;background-color:#f0f2f5}.dashboard-editor-container .chart-wrapper[data-v-a5ba94de]{background:#fff;padding:16px 16px 0;margin-bottom:32px}.lineDiv[data-v-a5ba94de]{height:120px}.pre-scrollable[data-v-a5ba94de]{max-height:340px;overflow-y:scroll}pre[data-v-a5ba94de]{display:block;line-height:1.38461538;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px;text-align:center;min-height:100px}.image[data-v-a5ba94de]{width:100%;height:230px;display:block} -------------------------------------------------------------------------------- /static/app/admin/css/chunk-cf1d.3fd4e8c9.css: -------------------------------------------------------------------------------- 1 | .pagination-container[data-v-285e5c16]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-285e5c16]{display:none}.image{width:100%;height:230px;display:block}.el-row{margin:0 -5px}.header{height:130px;line-height:127px;display:block;margin-bottom:20px}.el-switch{padding-bottom:10px} -------------------------------------------------------------------------------- /static/app/admin/css/chunk-dbfc.2200a67c.css: -------------------------------------------------------------------------------- 1 | .pagination-container[data-v-285e5c16]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-285e5c16]{display:none}.image{width:100%;height:230px;display:block}.el-row{margin:0 -5px}.header{height:130px;line-height:127px;display:block;margin-bottom:20px}.el-switch{padding-bottom:10px} -------------------------------------------------------------------------------- /static/app/admin/css/chunk-ed47.1b4595b0.css: -------------------------------------------------------------------------------- 1 | .pagination-container[data-v-285e5c16]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-285e5c16]{display:none}.edit-input[data-v-87061a56]{padding-right:100px}.cancel-btn[data-v-87061a56]{position:absolute;right:15px;top:10px} -------------------------------------------------------------------------------- /static/app/admin/css/chunk-elementUI.7e429284.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/css/chunk-elementUI.7e429284.css.gz -------------------------------------------------------------------------------- /static/app/admin/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/favicon.ico -------------------------------------------------------------------------------- /static/app/admin/fonts/element-icons.6f0a763.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/fonts/element-icons.6f0a763.ttf -------------------------------------------------------------------------------- /static/app/admin/img/404.a57b6f3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/img/404.a57b6f3.png -------------------------------------------------------------------------------- /static/app/admin/js/app.7a9d371b.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/app.7a9d371b.js.gz -------------------------------------------------------------------------------- /static/app/admin/js/chunk-1ae2.47d8888c.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/chunk-1ae2.47d8888c.js.gz -------------------------------------------------------------------------------- /static/app/admin/js/chunk-1b5e.4b7ec984.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/chunk-1b5e.4b7ec984.js.gz -------------------------------------------------------------------------------- /static/app/admin/js/chunk-5965.5130ff8b.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/chunk-5965.5130ff8b.js.gz -------------------------------------------------------------------------------- /static/app/admin/js/chunk-9a76.31959552.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/chunk-9a76.31959552.js.gz -------------------------------------------------------------------------------- /static/app/admin/js/chunk-b02f.0024f8cb.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/chunk-b02f.0024f8cb.js.gz -------------------------------------------------------------------------------- /static/app/admin/js/chunk-cc24.e448dea5.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/chunk-cc24.e448dea5.js.gz -------------------------------------------------------------------------------- /static/app/admin/js/chunk-cf1d.0396a251.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/chunk-cf1d.0396a251.js.gz -------------------------------------------------------------------------------- /static/app/admin/js/chunk-dbfc.8fc7fee7.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/chunk-dbfc.8fc7fee7.js.gz -------------------------------------------------------------------------------- /static/app/admin/js/chunk-elementUI.84dd9cf5.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/chunk-elementUI.84dd9cf5.js.gz -------------------------------------------------------------------------------- /static/app/admin/js/chunk-libs.b37d8d5d.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/admin/js/chunk-libs.b37d8d5d.js.gz -------------------------------------------------------------------------------- /static/app/css/my-login.css: -------------------------------------------------------------------------------- 1 | html,body { 2 | height: 100%; 3 | } 4 | 5 | body.my-login-page { 6 | background-color: #f7f9fb; 7 | font-size: 14px; 8 | } 9 | 10 | .my-login-page .brand { 11 | width: 90px; 12 | height: 90px; 13 | overflow: hidden; 14 | border-radius: 50%; 15 | margin: 0 auto; 16 | margin: 40px auto; 17 | box-shadow: 0 4px 8px rgba(0,0,0,.05); 18 | position: relative; 19 | z-index: 1; 20 | } 21 | 22 | .my-login-page .brand img { 23 | width: 100%; 24 | } 25 | 26 | .my-login-page .card-wrapper { 27 | width: 400px; 28 | } 29 | 30 | .my-login-page .card { 31 | border-color: transparent; 32 | box-shadow: 0 4px 8px rgba(0,0,0,.05); 33 | } 34 | 35 | .my-login-page .card.fat { 36 | padding: 10px; 37 | } 38 | 39 | .my-login-page .card .card-title { 40 | margin-bottom: 30px; 41 | } 42 | 43 | .my-login-page .form-control { 44 | border-width: 2.3px; 45 | } 46 | 47 | .my-login-page .form-group label { 48 | width: 100%; 49 | } 50 | 51 | .my-login-page .btn.btn-block { 52 | padding: 12px 10px; 53 | } 54 | 55 | .my-login-page .footer { 56 | margin: 40px 0; 57 | color: #888; 58 | text-align: center; 59 | } 60 | 61 | @media screen and (max-width: 425px) { 62 | .my-login-page .card-wrapper { 63 | width: 90%; 64 | margin: 0 auto; 65 | } 66 | } 67 | 68 | @media screen and (max-width: 320px) { 69 | .my-login-page .card.fat { 70 | padding: 0; 71 | } 72 | 73 | .my-login-page .card.fat .card-body { 74 | padding: 15px; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /static/app/iconfont/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/iconfont/iconfont.eot -------------------------------------------------------------------------------- /static/app/iconfont/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/iconfont/iconfont.ttf -------------------------------------------------------------------------------- /static/app/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/iconfont/iconfont.woff -------------------------------------------------------------------------------- /static/app/iconfont/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/iconfont/iconfont.woff2 -------------------------------------------------------------------------------- /static/app/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/images/logo.jpg -------------------------------------------------------------------------------- /static/app/images/logoko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/app/images/logoko.png -------------------------------------------------------------------------------- /static/bootstrap-fileinput/4.5.1/img/loading-sm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/bootstrap-fileinput/4.5.1/img/loading-sm.gif -------------------------------------------------------------------------------- /static/bootstrap-fileinput/4.5.1/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/bootstrap-fileinput/4.5.1/img/loading.gif -------------------------------------------------------------------------------- /static/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /static/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /static/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /static/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /static/dist/static/css/chunk-8f68.ad0dd7f0.css: -------------------------------------------------------------------------------- 1 | .login-container .el-input{display:inline-block;height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#eee;height:47px}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #2d3a4b inset!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container[data-v-2f6e815b]{position:fixed;height:100%;width:100%;background-color:#2d3a4b}.login-container .login-form[data-v-2f6e815b]{position:absolute;left:0;right:0;width:520px;max-width:100%;padding:35px 35px 15px;margin:120px auto}.login-container .tips[data-v-2f6e815b]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips span[data-v-2f6e815b]:first-of-type{margin-right:16px}.login-container .svg-container[data-v-2f6e815b]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title[data-v-2f6e815b]{font-size:26px;font-weight:400;color:#eee;margin:0 auto 40px;text-align:center;font-weight:700}.login-container .show-pwd[data-v-2f6e815b]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} -------------------------------------------------------------------------------- /static/dist/static/css/chunk-db81.4b63c2f2.css: -------------------------------------------------------------------------------- 1 | .line[data-v-302b70d3]{text-align:center} -------------------------------------------------------------------------------- /static/dist/static/css/chunk-f29c.4ec8f0e7.css: -------------------------------------------------------------------------------- 1 | .pagination-container[data-v-285e5c16]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-285e5c16]{display:none}.edit-input[data-v-1d9f3de0]{padding-right:100px}.cancel-btn[data-v-1d9f3de0]{position:absolute;right:15px;top:10px} -------------------------------------------------------------------------------- /static/dist/static/css/chunk-f47c.cf113efb.css: -------------------------------------------------------------------------------- 1 | .pagination-container[data-v-285e5c16]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-285e5c16]{display:none}.image{width:100%;height:230px;display:block}.el-row{margin:0 -5px}.header{height:130px;line-height:127px;display:block;margin-bottom:20px}.el-switch{padding-bottom:10px} -------------------------------------------------------------------------------- /static/dist/static/fonts/element-icons.6f0a763.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/dist/static/fonts/element-icons.6f0a763.ttf -------------------------------------------------------------------------------- /static/dist/static/images/123.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/dist/static/images/123.ts -------------------------------------------------------------------------------- /static/dist/static/images/load.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/dist/static/images/load.gif -------------------------------------------------------------------------------- /static/dist/static/img/404.a57b6f3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/dist/static/img/404.a57b6f3.png -------------------------------------------------------------------------------- /static/dist/static/js/27OO.4ee76676.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["27OO"],{"27OO":function(e,t,n){"use strict";n.r(t);var l=n("KHd+"),i=Object(l.a)({},function(){var e=this.$createElement,t=this._self._c||e;return t("div",{staticStyle:{padding:"30px"}},[t("el-alert",{attrs:{closable:!1,title:"menu 2"}})],1)},[],!1,null,null,null);i.options.__file="index.vue";t.default=i.exports}}]); -------------------------------------------------------------------------------- /static/dist/static/js/6bwb.935655f4.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["6bwb"],{"6bwb":function(e,t,n){"use strict";n.r(t);var l=n("KHd+"),i=Object(l.a)({},function(){var e=this.$createElement,t=this._self._c||e;return t("div",{staticStyle:{padding:"30px"}},[t("el-alert",{attrs:{closable:!1,title:"menu 1"}},[t("router-view")],1)],1)},[],!1,null,null,null);i.options.__file="index.vue";t.default=i.exports}}]); -------------------------------------------------------------------------------- /static/dist/static/js/Vc2m.733314d5.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["Vc2m"],{Vc2m:function(e,t,n){"use strict";n.r(t);var l=n("KHd+"),s=Object(l.a)({},function(){var e=this.$createElement,t=this._self._c||e;return t("div",{staticStyle:{padding:"30px"}},[t("el-alert",{attrs:{closable:!1,title:"menu 1-2",type:"success"}},[t("router-view")],1)],1)},[],!1,null,null,null);s.options.__file="index.vue";t.default=s.exports}}]); -------------------------------------------------------------------------------- /static/dist/static/js/ZYJW.b9669658.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["ZYJW"],{ZYJW:function(n,t,e){"use strict";e.r(t);var l=e("KHd+"),i=Object(l.a)({},function(n,t){var e=t._c;return e("div",{staticStyle:{padding:"30px"}},[e("el-alert",{attrs:{closable:!1,title:"menu 1-2-1",type:"warning"}})],1)},[],!0,null,null,null);i.options.__file="index.vue";t.default=i.exports}}]); -------------------------------------------------------------------------------- /static/dist/static/js/ad09.11d972f7.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["ad09"],{ad09:function(e,l,t){"use strict";t.r(l);var a={data:function(){return{filterText:"",data2:[{id:1,label:"Level one 1",children:[{id:4,label:"Level two 1-1",children:[{id:9,label:"Level three 1-1-1"},{id:10,label:"Level three 1-1-2"}]}]},{id:2,label:"Level one 2",children:[{id:5,label:"Level two 2-1"},{id:6,label:"Level two 2-2"}]},{id:3,label:"Level one 3",children:[{id:7,label:"Level two 3-1"},{id:8,label:"Level two 3-2"}]}],defaultProps:{children:"children",label:"label"}}},watch:{filterText:function(e){this.$refs.tree2.filter(e)}},methods:{filterNode:function(e,l){return!e||-1!==l.label.indexOf(e)}}},i=t("KHd+"),r=Object(i.a)(a,function(){var e=this,l=e.$createElement,t=e._self._c||l;return t("div",{staticClass:"app-container"},[t("el-input",{staticStyle:{"margin-bottom":"30px"},attrs:{placeholder:"Filter keyword"},model:{value:e.filterText,callback:function(l){e.filterText=l},expression:"filterText"}}),e._v(" "),t("el-tree",{ref:"tree2",staticClass:"filter-tree",attrs:{data:e.data2,props:e.defaultProps,"filter-node-method":e.filterNode,"default-expand-all":""}})],1)},[],!1,null,null,null);r.options.__file="index.vue";l.default=r.exports}}]); -------------------------------------------------------------------------------- /static/dist/static/js/jYsI.ae151788.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["jYsI"],{jYsI:function(e,t,n){"use strict";n.r(t);var s=n("KHd+"),l=Object(s.a)({},function(e,t){var n=t._c;return n("div",{staticStyle:{padding:"30px"}},[n("el-alert",{attrs:{closable:!1,title:"menu 1-3",type:"success"}})],1)},[],!0,null,null,null);l.options.__file="index.vue";t.default=l.exports}}]); -------------------------------------------------------------------------------- /static/dist/static/js/kbPl.7eb515d5.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["kbPl"],{kbPl:function(e,t,l){"use strict";l.r(t);var n=l("KHd+"),s=Object(n.a)({},function(){var e=this.$createElement,t=this._self._c||e;return t("div",{staticStyle:{padding:"30px"}},[t("el-alert",{attrs:{closable:!1,title:"menu 1-1",type:"success"}},[t("router-view")],1)],1)},[],!1,null,null,null);s.options.__file="index.vue";t.default=s.exports}}]); -------------------------------------------------------------------------------- /static/dist/static/js/tvtM.3b4dc552.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["tvtM"],{tvtM:function(t,n,e){"use strict";e.r(n);var l=e("KHd+"),i=Object(l.a)({},function(t,n){var e=n._c;return e("div",{staticStyle:{padding:"30px"}},[e("el-alert",{attrs:{closable:!1,title:"menu 1-2-2",type:"warning"}})],1)},[],!0,null,null,null);i.options.__file="index.vue";n.default=i.exports}}]); -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/favicon.ico -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Black.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Black.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-BlackItalic.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-BlackItalic.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Bold.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Bold.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-BoldItalic.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-BoldItalic.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Light.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Light.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-LightItalic.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-LightItalic.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Medium.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Medium.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-MediumItalic.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-MediumItalic.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Regular.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Regular.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-RegularItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-RegularItalic.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-RegularItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-RegularItalic.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Thin.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-Thin.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-ThinItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-ThinItalic.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/fonts/roboto/Roboto-ThinItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/fonts/roboto/Roboto-ThinItalic.woff2 -------------------------------------------------------------------------------- /static/mdui/0.4.1/icons/material-icons/MaterialIcons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/icons/material-icons/MaterialIcons-Regular.woff -------------------------------------------------------------------------------- /static/mdui/0.4.1/icons/material-icons/MaterialIcons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/static/mdui/0.4.1/icons/material-icons/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /tests/default_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "path/filepath" 7 | "runtime" 8 | "testing" 9 | 10 | _ "github.com/auxpi/routers" 11 | 12 | "github.com/astaxie/beego" 13 | . "github.com/smartystreets/goconvey/convey" 14 | ) 15 | 16 | func init() { 17 | _, file, _, _ := runtime.Caller(1) 18 | apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator)))) 19 | beego.TestBeegoInit(apppath) 20 | } 21 | 22 | func TestAuxpi(t *testing.T) { 23 | r, _ := http.NewRequest("GET", "/", nil) 24 | w := httptest.NewRecorder() 25 | beego.BeeApp.Handlers.ServeHTTP(w, r) 26 | 27 | beego.Trace("testing", "TestBeego", "Code[%d]\n%s", w.Code, w.Body.String()) 28 | 29 | Convey("Subject: Test Station Endpoint\n", t, func() { 30 | Convey("Status Code Should Be 200", func() { 31 | So(w.Code, ShouldEqual, 200) 32 | }) 33 | Convey("The Result Should Not Be Empty", func() { 34 | So(w.Body.Len(), ShouldBeGreaterThan, 0) 35 | }) 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /tests/pem/private_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEuwIBADALBgkqhkiG9w0BAQEEggSnMIIEowIBAAKCAQEAqieN7IxtXZAFMaaI 3 | VVbpDY+cQ7jbHU+q/+IcxfUk6CAiYHCldBmwquwH5Ql3vbGRz/7pzfM5PfuylCT5 4 | NoZj6AOiZLVO59j8lCKlhh0qLknKVFCHfl+XF4hdFbSdo/jD7fjLvMUuIaButT/Z 5 | 5xVxdIw3zivFHcOuRG7LSw0f3xYv6wphTBmPpppstP4G83kv15V2vLXuX4+ZtUAJ 6 | xRbNqia99lzLox7QioHo9DH3twZqPrkMGMNd3DqjGpia6v035MvolhWOr/8aCnBU 7 | ePYE25R3o8OmTjlTw26xR7B7+cywpnieIpdQhZXvnBUm3muBXNqoQu0W0VqQKpWJ 8 | 3bO5jwIDAQABAoIBAB7iFQFlL4h21mp/lmke4Cfk8/DawXJdfmT5Lk3Dw9IZ2wN0 9 | DqO28fjj5D7u6/vTGesNknQd/DrCz1PSLiV2WPXIixYKTmsIWDeu3iosavaB0CZj 10 | g2Qth2fvCS4iXSZgxXcQ3DHD/C6ARvfAwhUOMEx+Erbp/Nn9JUkobt+NX0aHHX7k 11 | lG5uh2YxjtzPPr/dMdw/woTuhqnJre6w9nfV12sR21OOKE7+N/f9PYYZALq/AsFX 12 | eDeCociCnXZCPekvME+VFiP9LXuI7Fbwp2/BKocaWOKIPOD6mcLfdDqksYsCNhym 13 | f/5gb83Hmb499mJ2FVIaU1CnM9vsbiLWvvzA8NkCgYEA3ausKAVc6HWwTdVSZrPI 14 | l3/RH6++gMNr7/oTyzNyEfTyNYV9hWMvJ5yQ3AWg1YrT66r0z062MkdakgZT+W0V 15 | h+D8LPdW3Qr7cf5LL25YYdtKkZp493V1GMb3tqzPTnn8lnAvpIteZSG86j0qcvK2 16 | k65E5MIIwx27lkrCPNv8NdUCgYEAxIF7Hs3v0E2rGqBD7DJC8r7oKDRkqMQkA2zm 17 | nlK1IJTqtIenNqSwbhs3+Y4d+ZETJewFoTWvONB1yx1xU+AmMoFsvUEN56uMUlRk 18 | tic0f1V+3RX8ovvQoen+my0I5xY7pLp1NakIcug9foqBJazPeCXzodKTsiLLrN0z 19 | yT2Mb9MCgYA5TCKXxasaOzFzLOy7t0TmRBeeBSNMzTadNRrgr0+Q7Kuewf6L9/M8 20 | Xe/jr2C/Ub8tb2cQHtxhaqgyjoguNNAX60PDq7s8L5aHBKAShoc55CEGOdOCw02d 21 | NfDZuxlqw4VSrXTjJ1Mi+PGH6n+KbspaqfUM3Eq/hHP0iSZj7MjocQKBgBgRb94P 22 | BS9zQ+DH/mnAojiPL2o1OJr/IxYUUY7UvICYHMMt1ko4E6/4v3teb8dwgHLlnK7p 23 | H2QLDFJrccT/ME6BUatAe46DkXVIBunUlXZ/J0G2/rGLvDsIqPmio3OCYp3DhLWk 24 | 1XcVgOqt1jGiH+ssYtHQM+zenCm5Ei20zy2nAoGBAJfgy0wDTNk+xafOT7Of6xYn 25 | /dRjltkrzvEZ6c6giwtvYS1REcBEDDx/UitreGWyzqFcxYgPMXa/BM/GA47tMPuz 26 | mT3PDP3x6y+hK26ony6/DKNGByeyssTuFKTWrmqQH1W754bIOQOr4jHonBSgEN4H 27 | HogJNhERb4HMEEy38Zyh 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /tests/pem/public_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqieN7IxtXZAFMaaIVVbp 3 | DY+cQ7jbHU+q/+IcxfUk6CAiYHCldBmwquwH5Ql3vbGRz/7pzfM5PfuylCT5NoZj 4 | 6AOiZLVO59j8lCKlhh0qLknKVFCHfl+XF4hdFbSdo/jD7fjLvMUuIaButT/Z5xVx 5 | dIw3zivFHcOuRG7LSw0f3xYv6wphTBmPpppstP4G83kv15V2vLXuX4+ZtUAJxRbN 6 | qia99lzLox7QioHo9DH3twZqPrkMGMNd3DqjGpia6v035MvolhWOr/8aCnBUePYE 7 | 25R3o8OmTjlTw26xR7B7+cywpnieIpdQhZXvnBUm3muBXNqoQu0W0VqQKpWJ3bO5 8 | jwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /tools/check.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package tools 15 | 16 | import ( 17 | "net/http" 18 | "strings" 19 | 20 | "github.com/astaxie/beego/logs" 21 | ) 22 | 23 | func CheckStatus(url string) bool { 24 | if url == "" { 25 | return false 26 | } 27 | client := &http.Client{ 28 | CheckRedirect: func(req *http.Request, via []*http.Request) error { 29 | return http.ErrUseLastResponse 30 | }, 31 | } 32 | req, err := http.NewRequest("GET", url, nil) 33 | req.Header.Add("User-Agent", "Mozilla/5.0 (Linux; Android 8.1; EML-AL00 Build/HUAWEIEML-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.143 Crosswalk/24.53.595.0 XWEB/358 MMWEBSDK/23 Mobile Safari/537.36 MicroMessenger/6.7.2.1340(0x2607023A) NetType/4G Language/zh_CN") 34 | 35 | resp, err := client.Do(req) 36 | if err != nil { 37 | logs.Error("[CHECK PIC RESP ERROR]: ", err) 38 | return false 39 | } 40 | 41 | err = resp.Body.Close() 42 | if err != nil { 43 | logs.Error("[CHECK PIC RESP ERROR]: ", err) 44 | return false 45 | } 46 | //检测请求头 47 | if resp.StatusCode != 200 { 48 | return false 49 | } 50 | //解析响应头是否是png/jpg/gif/bmp 等资源 51 | //是否返回的是图片资源 52 | info := resp.Header.Get("Content-Type") 53 | if strings.HasPrefix(info, "image") || strings.HasSuffix(info, "octet-stream") { 54 | return true 55 | } 56 | return false 57 | } 58 | -------------------------------------------------------------------------------- /tools/checkPorn.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package tools 15 | 16 | type CheckPorn interface { 17 | CheckImage() 18 | } 19 | 20 | //https://www.moderatecontent.com/documentation/signup 21 | func CheckImage() { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /tools/fileInfo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package tools 15 | 16 | import ( 17 | "regexp" 18 | ) 19 | 20 | //通过 MimeType 信息获取文件名称 21 | func GetFileNameByMimeType(info string) string { 22 | //beego.Alert(info) 23 | pat := `filename="(.*)"` 24 | res := regexp.MustCompile(pat) 25 | name := res.FindAllStringSubmatch(info, -1) 26 | return name[0][1] 27 | } 28 | -------------------------------------------------------------------------------- /tools/lock.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package tools 15 | 16 | import ( 17 | "time" 18 | 19 | "github.com/astaxie/beego" 20 | "github.com/astaxie/beego/cache" 21 | ) 22 | 23 | var bm, err = cache.NewCache("memory", `{"interval":60}`) 24 | 25 | func Lock() { 26 | if err != nil { 27 | beego.Alert("[Lock memory error]:", err) 28 | return 29 | } 30 | err = bm.Put("isLock", true, 100*time.Second) 31 | if err != nil { 32 | beego.Alert("[Lock memory error]:", err) 33 | return 34 | } 35 | } 36 | 37 | func UnLock() { 38 | if err != nil { 39 | beego.Alert("[Lock memory error]:", err) 40 | return 41 | } 42 | if IsLock() { 43 | err := bm.Delete("isLock") 44 | if err != nil { 45 | beego.Alert("[Lock memory error]:", err) 46 | return 47 | } 48 | } 49 | } 50 | 51 | func IsLock() bool { 52 | if bm.Get("isLock") != nil { 53 | return true 54 | } 55 | return false 56 | } 57 | -------------------------------------------------------------------------------- /tools/short.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package tools 15 | 16 | import ( 17 | "crypto/md5" 18 | "encoding/hex" 19 | "strconv" 20 | ) 21 | 22 | const ( 23 | VAL = 0x3FFFFFFF 24 | INDEX = 0x0000003D 25 | ) 26 | 27 | var ( 28 | alphabet = []byte("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") 29 | ) 30 | 31 | func ToShort(longURL string) ([4]string, error) { 32 | md5Str := getMd5Str(longURL) 33 | //var hexVal int64 34 | var tempVal int64 35 | var result [4]string 36 | var tempUri []byte 37 | for i := 0; i < 4; i++ { 38 | tempSubStr := md5Str[i*8 : (i+1)*8] 39 | hexVal, err := strconv.ParseInt(tempSubStr, 16, 64) 40 | if err != nil { 41 | return result, nil 42 | } 43 | tempVal = int64(VAL) & hexVal 44 | var index int64 45 | tempUri = []byte{} 46 | for i := 0; i < 6; i++ { 47 | index = INDEX & tempVal 48 | tempUri = append(tempUri, alphabet[index]) 49 | tempVal = tempVal >> 5 50 | } 51 | result[i] = string(tempUri) 52 | } 53 | return result, nil 54 | } 55 | 56 | /** generate md5 checksum of URL in hex format **/ 57 | func getMd5Str(str string) string { 58 | m := md5.New() 59 | m.Write([]byte(str)) 60 | c := m.Sum(nil) 61 | return hex.EncodeToString(c) 62 | } 63 | -------------------------------------------------------------------------------- /tools/sina.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package tools 15 | 16 | import ( 17 | "fmt" 18 | "hash/crc32" 19 | ) 20 | 21 | func CheckPid(pid string, imgType string, size string) string { 22 | if pid == "" { 23 | return "" 24 | } 25 | sinaNumber := fmt.Sprint((crc32.ChecksumIEEE([]byte(pid)) & 3) + 1) 26 | n := len(imgType) 27 | rs := []rune(imgType) 28 | suffix := string(rs[6:n]) 29 | if suffix != "gif" { 30 | suffix = "jpg" 31 | } 32 | sinaUrl := "https://ww" + sinaNumber + ".sinaimg.cn/" + size + "/" + pid + "." + suffix 33 | return sinaUrl 34 | 35 | } 36 | -------------------------------------------------------------------------------- /tools/websocket.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package tools 15 | 16 | import ( 17 | "github.com/astaxie/beego" 18 | "github.com/gorilla/websocket" 19 | ) 20 | 21 | var ( 22 | clients = make(map[*websocket.Conn]bool) 23 | ) 24 | 25 | type Message struct { 26 | Title string `json:"title"` 27 | Msg string `json:"msg"` 28 | Status string `json:"status"` 29 | Code int `json:"code"` 30 | Data interface{} `json:"data"` 31 | } 32 | 33 | var MsgChan = make(chan *Message) 34 | 35 | //当前页面用户加入 websocket 列表中 36 | func AddClient(ws *websocket.Conn) map[*websocket.Conn]bool { 37 | clients[ws] = true 38 | beego.Alert("新来了一个弟弟") 39 | return clients 40 | } 41 | 42 | //主动推送消息 43 | func Send(msg *Message) { 44 | if len(clients) == 0 { 45 | beego.Alert("空的,不发") 46 | return 47 | } 48 | beego.Alert("准备发送,别堵住老子……") 49 | beego.Alert(msg) 50 | MsgChan <- msg 51 | beego.Alert("sent!") 52 | beego.Alert(msg) 53 | } 54 | -------------------------------------------------------------------------------- /utils/ContentToForm.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019 aimerforreimu. All Rights Reserved. 2 | // Use of this source code is governed by a GNU GENERAL PUBLIC 3 | // license that can be found in the LICENSE file. 4 | // 5 | // GNU GENERAL PUBLIC LICENSE 6 | // Version 3, 29 June 2007 7 | // 8 | // Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 9 | // Everyone is permitted to copy and distribute verbatim copies 10 | // of this license document, but changing it is not allowed. 11 | // 12 | // repo: https://github.com/aimerforreimu/auxpi 13 | 14 | package utils 15 | 16 | import ( 17 | "io/ioutil" 18 | "net/http" 19 | "strings" 20 | 21 | "github.com/auxpi/auxpiAll" 22 | ) 23 | 24 | func FormPost(file *auxpi.FormFile, url string, header map[string]string) string { 25 | payload := strings.NewReader("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"" + file.Key + "\"; filename=\"" + file.Name + "\"\r\nContent-Type: " + file.Type + "\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--") 26 | 27 | req, _ := http.NewRequest("POST", url, payload) 28 | 29 | req.Header.Add("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW") 30 | req.Header.Add("Content-Type", "application/x-www-form-urlencoded") 31 | req.Header.Add("cache-control", "no-cache") 32 | 33 | if len(header) > 0 { 34 | for k, v := range header { 35 | req.Header.Add(k, v) 36 | } 37 | } 38 | res, _ := http.DefaultClient.Do(req) 39 | 40 | defer res.Body.Close() 41 | 42 | body, _ := ioutil.ReadAll(res.Body) 43 | 44 | return string(body) 45 | } 46 | -------------------------------------------------------------------------------- /utils/jwt.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/auxpi/bootstrap" 7 | 8 | "github.com/dgrijalva/jwt-go" 9 | ) 10 | 11 | var jwtSecret = []byte(bootstrap.SiteConfig.JwtSecret) 12 | 13 | type Claims struct { 14 | Username string `json:"username"` 15 | Email string `json:"email"` 16 | Role string `json:"role"` 17 | jwt.StandardClaims 18 | } 19 | 20 | func GenerateToken(username, email string) (string, error) { 21 | nowTime := time.Now() 22 | expireTime := nowTime.Add(bootstrap.SiteConfig.JwtDueTime * time.Hour) 23 | 24 | claims := Claims{ 25 | username, 26 | email, 27 | "", 28 | jwt.StandardClaims{ 29 | ExpiresAt: expireTime.Unix(), 30 | Issuer: bootstrap.SiteConfig.SiteName, 31 | }, 32 | } 33 | 34 | tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) 35 | token, err := tokenClaims.SignedString(jwtSecret) 36 | return token, err 37 | } 38 | 39 | func ParseToken(token string) (*Claims, error) { 40 | tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) { 41 | return jwtSecret, nil 42 | }) 43 | 44 | if tokenClaims != nil { 45 | if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid { 46 | return claims, nil 47 | } 48 | } 49 | return nil, err 50 | } 51 | -------------------------------------------------------------------------------- /utils/upload.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "regexp" 5 | ) 6 | 7 | func CheckUrl(url string) (bool, bool) { 8 | var re = regexp.MustCompile(`(?m)https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)`) 9 | result := re.MatchString(url) 10 | //logs.Alert(result, url) 11 | isLocal := false 12 | var rex = regexp.MustCompile(`(?m)localhost`) 13 | isLocal = rex.MatchString(url) 14 | 15 | return result, isLocal 16 | } 17 | -------------------------------------------------------------------------------- /views/about/about-me.tpl: -------------------------------------------------------------------------------- 1 | <div class="upload-container"> 2 | <div class="title"> 3 | <h1>{{.title}}</h1> 4 | <br> 5 | <p>在法律允许范围内可以随意使用本图床</p> 6 | <br> 7 | <h1>严禁上传及分享如下类型的图片:</h1> 8 | <ul> 9 | <li>含有色情、暴力、宣扬恐怖主义的图片</li> 10 | <li>侵犯版权、未经授权的图片</li> 11 | <li>其他违反中华人民共和国法律的图片</li> 12 | </ul> 13 | <br> 14 | <h1>隐私政策:</h1> 15 | <ul> 16 | <li>本图床全部上传公共 CDN,大部分 CDN 不提供删除服务,请勿将含有您个人隐私图片上传到本图床</li> 17 | </ul> 18 | </div> 19 | </div> -------------------------------------------------------------------------------- /views/auth/base.tpl: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | {{ .Header}} 4 | <body class="my-login-page"> 5 | <section class="h-100"> 6 | <div class="container h-100"> 7 | <div class="row justify-content-md-center align-items-center h-100"> 8 | <div class="card-wrapper"> 9 | <div class="brand"> 10 | {{/*/static/app/images/logo.jpg*/}} 11 | <a href="{{ .SiteLink}}" target="_blank"><img src="{{ .Logo}}" alt="{{ .SiteName}}"></a> 12 | </div> 13 | <div class="card fat"> 14 | {{ .Content}} 15 | </div> 16 | <div class="footer"> 17 | Copyright © {{ .Time}} — <a href="{{ .SiteLink}}" target="_blank">{{ .SiteName}}</a> 18 | </div> 19 | </div> 20 | </div> 21 | </div> 22 | </section> 23 | {{ .Footer}} 24 | </body> 25 | </html> -------------------------------------------------------------------------------- /views/auth/forgot.tpl: -------------------------------------------------------------------------------- 1 | <div class="card-body"> 2 | <h4 class="card-title">密码找回</h4> 3 | <form method="POST" class="my-login-validation" novalidate=""> 4 | <div class="form-group"> 5 | <label for="email">Email 地址</label> 6 | <input id="email" type="email" class="form-control" name="email" value="" required autofocus> 7 | <div class="invalid-feedback"> 8 | email 不能为空 9 | </div> 10 | <div class="form-text text-muted"> 11 | 点击"重置密码"的按钮,我们会发送一封带有重置链接的邮件到您的邮箱 12 | </div> 13 | </div> 14 | 15 | <div class="form-group m-0"> 16 | <button type="submit" class="btn btn-primary btn-block"> 17 | 重置密码 18 | </button> 19 | </div> 20 | </form> 21 | </div> -------------------------------------------------------------------------------- /views/auth/header.tpl: -------------------------------------------------------------------------------- 1 | <head> 2 | <meta charset="utf-8"> 3 | <meta name="author" content="Kodinger"> 4 | <meta name="viewport" content="width=device-width,initial-scale=1"> 5 | <meta name="_xsrf" content="{{.xsrf_token}}" /> 6 | <title>{{ .SiteName}}-{{ .Part}}</title> 7 | <link rel="stylesheet" type="text/css" href="/static/bootstrap/css/bootstrap.min.css"> 8 | <link rel="stylesheet" type="text/css" href="/static/app/css/my-login.css"> 9 | <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> 10 | </head> 11 | -------------------------------------------------------------------------------- /views/auth/login.tpl: -------------------------------------------------------------------------------- 1 | <div class="card-body"> 2 | <h4 class="card-title">登录</h4> 3 | <form method="POST" class="my-login-validation" novalidate=""> 4 | <div class="form-group"> 5 | <label for="email">Email 地址</label> 6 | <input id="email" type="email" class="form-control" name="email" value="" required autofocus> 7 | <div class="invalid-feedback"> 8 | 邮件不合法 9 | </div> 10 | </div> 11 | 12 | <div class="form-group"> 13 | <label for="password">密码 14 | <a href="/forgot" class="float-right"> 15 | 忘记密码? 16 | </a> 17 | </label> 18 | <input id="password" type="password" class="form-control" name="password" required data-eye> 19 | <div class="invalid-feedback"> 20 | 密码是必须的 21 | </div> 22 | </div> 23 | 24 | <div class="form-group"> 25 | <div class="custom-checkbox custom-control"> 26 | <input type="checkbox" name="remember" id="remember" class="custom-control-input"> 27 | <label for="remember" class="custom-control-label">记住我</label> 28 | </div> 29 | </div> 30 | 31 | <div class="form-group m-0"> 32 | <button type="submit" class="btn btn-primary btn-block"> 33 | 登录 34 | </button> 35 | </div> 36 | <div class="mt-4 text-center"> 37 | 没有账号? <a href="/register">创建一个</a> 38 | </div> 39 | </form> 40 | </div> -------------------------------------------------------------------------------- /views/auth/msg.tpl: -------------------------------------------------------------------------------- 1 | <div class="card-body"> 2 | <div class="alert alert-{{ .Msg.AlertType}}" role="alert"> 3 | {{ .Msg.AlertContent}} 4 | </div> 5 | <a target="_blank" href="{{ .Msg.Link}}" class="btn btn-{{ .Msg.ButtonType}}">{{ .Msg.ButtonContent}}</a> 6 | </div> -------------------------------------------------------------------------------- /views/auth/register.tpl: -------------------------------------------------------------------------------- 1 | <div class="card-body"> 2 | <h4 class="card-title">注册</h4> 3 | <form method="POST" class="my-login-validation" novalidate=""> 4 | <div class="form-group"> 5 | <label for="name">用户名</label> 6 | <input id="name" type="text" class="form-control" name="name" required autofocus> 7 | <div class="invalid-feedback"> 8 | 用户名必须填写 9 | </div> 10 | </div> 11 | 12 | <div class="form-group"> 13 | <label for="email">Email 地址</label> 14 | <input id="email" type="email" class="form-control" name="email" required> 15 | <div class="invalid-feedback"> 16 | 邮箱地址不能为空 17 | </div> 18 | </div> 19 | 20 | <div class="form-group"> 21 | <label for="password">密码</label> 22 | <input id="password" type="password" class="form-control" name="password" required data-eye> 23 | <div class="invalid-feedback"> 24 | 密码不能为空 25 | </div> 26 | </div> 27 | 28 | <div class="form-group"> 29 | <div class="custom-checkbox custom-control"> 30 | <input type="checkbox" name="agree" id="agree" class="custom-control-input" required=""> 31 | <label for="agree" class="custom-control-label">我同意 <a href="/about">条款</a></label> 32 | <div class="invalid-feedback"> 33 | 您必须同意我们的服务条款 34 | </div> 35 | </div> 36 | </div> 37 | 38 | <div class="form-group m-0"> 39 | <button type="submit" class="btn btn-primary btn-block"> 40 | 注册 41 | </button> 42 | </div> 43 | <div class="mt-4 text-center"> 44 | 已经有账户啦? <a href="/login">登录</a> 45 | </div> 46 | </form> 47 | </div> -------------------------------------------------------------------------------- /views/auth/reset.tpl: -------------------------------------------------------------------------------- 1 | <div class="card-body"> 2 | <h4 class="card-title">重置密码</h4> 3 | <form method="POST" class="my-login-validation" novalidate=""> 4 | <div class="form-group"> 5 | <label for="new-password">新密码</label> 6 | <input id="new-password" type="password" class="form-control" name="password" required autofocus data-eye> 7 | <input type="hidden" name="reset" value="{{.resetToken}}"> 8 | <div class="invalid-feedback"> 9 | 必须填写新密码 10 | </div> 11 | <div class="form-text text-muted"> 12 | 请确保您的密码足够健壮并请牢记 13 | </div> 14 | </div> 15 | 16 | <div class="form-group m-0"> 17 | <button type="submit" class="btn btn-primary btn-block"> 18 | 确认重置 19 | </button> 20 | </div> 21 | </form> 22 | </div> -------------------------------------------------------------------------------- /views/layouts/app.tpl: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no"/> 6 | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> 7 | <meta name="renderer" content="webkit"> 8 | <meta http-equiv="Cache-Control" content="no-siteapp"/> 9 | <meta name="keywords" content="{{.siteName}} ,新浪图床,搜狗图床,API图床,图片上传"/> 10 | <meta name="description" content="{{.siteName}} 新浪图床,搜狗图床,图片上传,API 图床"/> 11 | <title>{{ .siteName}}</title> 12 | <link href="/static/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> 13 | <link href="/static/bootstrap-fileinput/4.5.1/css/fileinput.min.css" rel="stylesheet"> 14 | <link rel="shortcut icon" href="/favicon.ico"> 15 | <link rel="stylesheet" href="/static/app/iconfont/iconfont.css"> 16 | <link rel="stylesheet" href="/static/mdui/0.4.1/css/mdui.min.css"> 17 | <link rel="stylesheet" href="/static/app/css/app.css"> 18 | <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> 19 | 20 | <!--[if IE]> 21 | <script>window.location.href = '/compatibility.html';</script> 22 | <![endif]--> 23 | </head> 24 | <body class="mdui-theme-accent-indigo mdui-appbar-with-toolbar "> 25 | {{/*header*/}} 26 | {{ .Header}} 27 | {{/*left*/}} 28 | {{ .Left}} 29 | {{/*content*/}} 30 | <div class="mdui-container"> 31 | <main> 32 | {{.LayoutContent}} 33 | </main> 34 | </div> 35 | {{/*footer*/}} 36 | {{ .Footer}} 37 | 38 | </body> 39 | <script src="/static/jquery/3.3.1/jquery.min.js"></script> 40 | <script src="/static/mdui/0.4.1/js/mdui.min.js"></script> 41 | <script src="/static/app/js/app.js"></script> 42 | 43 | {{ .Scripts}} 44 | </html> -------------------------------------------------------------------------------- /views/layouts/footer.tpl: -------------------------------------------------------------------------------- 1 | <div class="mdui-fab-wrapper"> 2 | <button id="to-top" class="mdui-fab mdui-ripple mdui-fab-hide mdui-color-theme-accent"> 3 | <i class="mdui-icon material-icons"></i> 4 | </button> 5 | </div> 6 | <div id="loading-container"> 7 | <div class="mask"></div> 8 | <div class="loading"> 9 | <div class="mdui-spinner mdui-spinner-colorful"></div> 10 | </div> 11 | </div> 12 | <footer> 13 | <div class="mdui-container"> 14 | Copyright © 2018 <a href="{{ .siteUrl}}">{{ .siteName}}</a>. All rights reserved. {{.siteFooterText}} <span 15 | style="float:right;">自豪的使用<a href="https://github.com/aimerforreimu/AUXPI" target="_blank">auxpi</a>进行驱动 16 | </span> 17 | </div> 18 | </footer> -------------------------------------------------------------------------------- /views/layouts/header.tpl: -------------------------------------------------------------------------------- 1 | <div class="mdui-appbar mdui-appbar-fixed"> 2 | <div class="mdui-toolbar mdui-color-black"> 3 | <span mdui-drawer="{target: '#menu'}" class="mdui-btn mdui-btn-icon open-menu"><i 4 | class="mdui-icon material-icons"></i></span> 5 | <a href="/" class="mdui-typo-headline">{{ .siteName}}</a> 6 | <div class="mdui-toolbar-spacer"></div> 7 | {{if .IsLogin}} 8 | <a href="/users/edit" class="mdui-btn"><i class="mdui-icon material-icons">face</i>{{ .UserName}}</a> 9 | <a href="/logout" class="mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">exit_to_app</i></a> 10 | {{else}} 11 | <a href="/login" class="mdui-btn"><i class="mdui-icon material-icons">account_circle</i>登录</a> 12 | <a href="/register" class="mdui-btn"><i class="mdui-icon material-icons">group_add</i>注册</a> 13 | {{end}} 14 | </div> 15 | </div> 16 | -------------------------------------------------------------------------------- /views/layouts/left.tpl: -------------------------------------------------------------------------------- 1 | <div id="menu" class="mdui-drawer mdui-drawer-close"> 2 | <div class="mdui-list" mdui-collapse="{accordion: true}"> 3 | {{range $elem := .Stores}} 4 | <a class="mdui-list-item mdui-ripple" href="{{$elem.Router}}"> 5 | <i class="mdui-list-item-icon mdui-icon material-icons iconfont icon-{{$elem.Icon}} mdui-text-color-{{$elem.Color}}"></i> 6 | <div class="mdui-list-item-content">{{$elem.Name}}</div> 7 | </a> 8 | {{end}} 9 | <a class="mdui-list-item mdui-ripple " href="{{urlfor "PagesController.AboutShow"}}"> 10 | <i class="mdui-list-item-icon mdui-icon material-icons iconfont icon-about mdui-text-color-teal"></i> 11 | <div class="mdui-list-item-content">说明</div> 12 | </a> 13 | <a class="mdui-list-item mdui-ripple " href="https://github.com/aimerforreimu/AUXPI" target="_blank"> 14 | <i class="mdui-list-item-icon mdui-icon material-icons iconfont icon-icons-code mdui-text-color-red"></i> 15 | <div class="mdui-list-item-content">项目地址</div> 16 | </a> 17 | </div> 18 | </div> -------------------------------------------------------------------------------- /views/user/content/images.tpl: -------------------------------------------------------------------------------- 1 | <div class="mdui-row"> 2 | {{range $index, $image := .Images}} 3 | <div class="mdui-col-sm-6 mdui-col-md-3" style="margin:10px 0px 0px 0px;"> 4 | <div class="mdui-card"> 5 | <div class="mdui-card-media"> 6 | <img src="{{ $image.Link}}" style="height:221px;width: 400px;"/> 7 | <div class="mdui-card-media-covered"> 8 | <div class="mdui-card-primary"> 9 | <div class="mdui-card-primary-title">上传于</div> 10 | <div class="mdui-card-primary-subtitle">{{$image.CreatedDay}}</div> 11 | </div> 12 | </div> 13 | </div> 14 | <div class="mdui-card-actions"> 15 | {{/*<button class="mdui-btn mdui-btn-raised mdui-btn-dense mdui-color-theme-accent mdui-ripple">查看信息</button>*/}} 16 | <button class="mdui-btn mdui-ripple mdui-color-theme-accent mdui-btn-raised mdui-btn-dense" data-clipboard-action="copy" data-clipboard-text="{{ $image.Link}}" id="copy-url">复制链接</button> 17 | {{/*<button class="mdui-btn mdui-ripple mdui-color-red mdui-btn-raised">删除</button>*/}} 18 | 19 | </div> 20 | </div> 21 | </div> 22 | {{end}} 23 | </div> 24 | 25 | <div class="mdui-row" style="margin: 30px 0px 0px 10px"> 26 | {{str2html .Page}} 27 | </div> 28 | 29 | 30 | <script src="/static/jquery/3.3.1/jquery.min.js"></script> 31 | -------------------------------------------------------------------------------- /views/user/user_app.tpl: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | 4 | <head> 5 | <meta charset="UTF-8"> 6 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 | <meta http-equiv="X-UA-Compatible" content="ie=edge"> 8 | <meta name="_xsrf" content="{{.xsrf_token}}" /> 9 | <title>{{ .siteName}} 管理</title> 10 | <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/mdui@0.4.2/dist/css/mdui.min.css"> 11 | <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@7/dist/sweetalert2.min.css"> 12 | <link rel="stylesheet" type="text/css" href="/static/bootstrap/css/bootstrap.min.css"> 13 | <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon"> 14 | <style type="text/css"> 15 | a:hover{ 16 | text-decoration:none; 17 | } 18 | 19 | </style> 20 | 21 | </head> 22 | <body class="mdui-drawer-body-left mdui-appbar-with-toolbar mdui-theme-primary-indigo mdui-theme-accent-blue"> 23 | {{ .Header}} 24 | {{ .SiderBar}} 25 | <a id="anchor-top"></a> 26 | {{/*{{ .Content}}*/}} 27 | <div class="mdui-container-fluid"> 28 | <div class="mdui-container-fluid mdui-m-t-2 mdui-m-b-2"> 29 | {{ .Content}} 30 | </div> 31 | </div> 32 | {{ .Script}} 33 | </body> 34 | 35 | </html> 36 | -------------------------------------------------------------------------------- /views/user/user_footer.tpl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDkd/auxpi/7144707f10fec0a7eb426d9fb1cb362271a16925/views/user/user_footer.tpl -------------------------------------------------------------------------------- /views/user/user_header.tpl: -------------------------------------------------------------------------------- 1 | <header class="mdui-appbar mdui-appbar-fixed"> 2 | <div class="mdui-toolbar mdui-color-theme"> 3 | <span class="mdui-btn mdui-btn-icon mdui-ripple mdui-ripple-white" 4 | mdui-drawer="{target: '#main-drawer', swipe: true}"><i class="mdui-icon material-icons">menu</i></span> 5 | <a href="{{urlfor "PagesController.UserIndexShow"}}" target="_blank" 6 | class="mdui-typo-headline mdui-hidden-xs" style="text-decoration:none">{{ .siteName}} 用户中心</a> 7 | <div class="mdui-toolbar-spacer"></div> 8 | <a href="/users/edit" class="mdui-btn"><i class="mdui-icon material-icons">face</i>{{ .User.Username}}</a> 9 | <a href="/logout" class="mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">exit_to_app</i></a> 10 | </div> 11 | </header> -------------------------------------------------------------------------------- /views/user/user_script.tpl: -------------------------------------------------------------------------------- 1 | <script src="/static/clipboard.js/2.0.1/clipboard.min.js"></script> 2 | <script src="/static/app/js/app.js"></script> 3 | <script src="/static/bootstrap/js/bootstrap.min.js"></script> 4 | <script src="/static/app/js/jq-paginator.min.js"></script> 5 | <script src="https://cdn.jsdelivr.net/combine/npm/mdui@0.4.2/dist/js/mdui.min.js,npm/jquery@3,npm/sweetalert2@7/dist/sweetalert2.min.js"></script> 6 | 7 | <script> 8 | // 监听复制操作 9 | var clipboard = new ClipboardJS('#copy-url'); 10 | clipboard.on('success', function (e) { 11 | app.msg(true, '复制成功!'); 12 | e.clearSelection(); 13 | }); 14 | 15 | clipboard.on('error', function (e) { 16 | console.error('Action:', e.action); 17 | console.error('Trigger:', e.trigger); 18 | app.msg(false, '复制失败!'); 19 | }); 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {{/*$("#page").bootstrapPaginator({*/}} 28 | {{/*currentPage: '{{.Page.PageNo}}',*/}} 29 | {{/*totalPages: '{{.Page.TotalPage}}',*/}} 30 | {{/*bootstrapMajorVersion: 3,*/}} 31 | {{/*size: "small",*/}} 32 | {{/*onPageClicked: function (e, originalEvent, type, page) {*/}} 33 | {{/*window.location.href = "/?page=" + page*/}} 34 | {{/*}*/}} 35 | {{/*});*/}} 36 | 37 | 38 | </script> -------------------------------------------------------------------------------- /views/user/user_sider_bar.tpl: -------------------------------------------------------------------------------- 1 | <div class="mdui-drawer" id="main-drawer"> 2 | <div class="mdui-list" mdui-collapse="{accordion: true}"> 3 | <a href="/" class="mdui-list-item mdui-ripple"> 4 | <i class="mdui-list-item-icon mdui-icon material-icons mdui-text-color-purple">home</i> 5 | <div class="mdui-list-item-content">首页</div> 6 | </a> 7 | <a href="/users/index" class="mdui-list-item mdui-ripple"> 8 | <i class="mdui-list-item-icon mdui-icon material-icons mdui-text-color-pink">image</i> 9 | <div class="mdui-list-item-content">图片管理</div> 10 | </a> 11 | <a href="/users/edit" class="mdui-list-item mdui-ripple"> 12 | <i class="mdui-list-item-icon mdui-icon material-icons mdui-text-color-blue">settings</i> 13 | <div class="mdui-list-item-content">个人设置</div> 14 | </a> 15 | 16 | 17 | 18 | {{ if .IsAdmin}} 19 | <a href="/admin" class="mdui-list-item mdui-ripple"> 20 | <i class="mdui-list-item-icon mdui-icon material-icons mdui-text-color-green">poll</i> 21 | <div class="mdui-list-item-content">后台管理</div> 22 | </a> 23 | {{ end}} 24 | 25 | 26 | </div> 27 | </div> -------------------------------------------------------------------------------- /views/webUpload/ban.tpl: -------------------------------------------------------------------------------- 1 | <div class="upload-container"> 2 | <div class="title"> 3 | <h1>Image Upload <i 4 | class="mdui-list-item-icon mdui-icon material-icons iconfont icon-{{.iconStyle}} mdui-text-color-{{ .iconColor}}"></i> 5 | </h1> 6 | </div> 7 | <div class="mdui-row"> 8 | <div class="mdui-col-lg-1"></div> 9 | <div class="mdui-card mdui-hoverable"> 10 | <div class="mdui-card-media"> 11 | <img src="https://i.loli.net/2017/02/26/58b2b7d9ad09a.jpg" /> 12 | <div class="mdui-card-media-covered"> 13 | <div class="mdui-card-primary"> 14 | <div class="mdui-card-primary-title">暂不开放此图床 : )</div> 15 | </div> 16 | </div> 17 | </div> 18 | </div> 19 | 20 | </div> 21 | </div> -------------------------------------------------------------------------------- /views/webUpload/box.tpl: -------------------------------------------------------------------------------- 1 | <div class="upload-container"> 2 | <div class="title"> 3 | <h1>Image Upload <i 4 | class="mdui-list-item-icon mdui-icon material-icons iconfont icon-{{.iconStyle}} mdui-text-color-{{ .iconColor}}"></i> 5 | </h1> 6 | <p>最大可上传 {{ .maxPicSize}} KB的图片,单次同时可选择 {{ .maxNumber}} 张。</p> 7 | </div> 8 | <form action="" method="post" enctype="multipart/form-data"> 9 | <input id="image" style="display: none;" type="file" multiple name="image" accept="image/*"> 10 | </form> 11 | <div class="success-info"> 12 | <div class="mdui-tab mdui-tab-scrollable" mdui-tab> 13 | <a href="#code-url" class="mdui-ripple mdui-tab-active">URL</a> 14 | <a href="#code-html" class="mdui-ripple">HTML</a> 15 | <a href="#code-bbcode" class="mdui-ripple">BBCode</a> 16 | <a href="#code-markdown" class="mdui-ripple">Markdown</a> 17 | <a href="#code-markdown-with-link" class="mdui-ripple">Markdown with link</a> 18 | </div> 19 | <div id="code-url"> 20 | <ul></ul> 21 | </div> 22 | <div id="code-html"> 23 | <ul></ul> 24 | </div> 25 | <div id="code-bbcode"> 26 | <ul></ul> 27 | </div> 28 | <div id="code-markdown"> 29 | <ul></ul> 30 | </div> 31 | <div id="code-markdown-with-link"> 32 | <ul></ul> 33 | </div> 34 | </div> 35 | </div> --------------------------------------------------------------------------------