├── server ├── .vscode │ └── settings.json ├── tools │ ├── gormt.exe │ └── config.yml ├── conf │ ├── gen_router.data │ ├── config.yml │ └── cert │ │ └── apiclient_cert.pem ├── internal │ ├── service │ │ ├── history │ │ │ ├── def.go │ │ │ ├── history.go │ │ │ └── common.go │ │ ├── login │ │ │ ├── oauth2.go │ │ │ └── def.go │ │ ├── order │ │ │ └── sql.go │ │ ├── notify │ │ │ ├── common.go │ │ │ ├── def.go │ │ │ └── notify.go │ │ ├── file │ │ │ └── file.go │ │ ├── oplog │ │ │ └── common.go │ │ ├── weixin │ │ │ └── def.go │ │ └── product │ │ │ ├── def.go │ │ │ └── common.go │ ├── config │ │ └── test_def.go │ └── api │ │ └── context.go ├── gogenerate.go ├── docs │ └── markdown │ │ ├── Upload.md │ │ └── Login.md └── generate │ └── proto_makefile ├── admin ├── .eslintignore ├── public │ ├── favicon.ico │ └── index.html ├── tests │ └── unit │ │ ├── .eslintrc.js │ │ ├── utils │ │ ├── param2Obj.spec.js │ │ ├── formatTime.spec.js │ │ ├── validate.spec.js │ │ └── parseTime.spec.js │ │ └── components │ │ ├── Hamburger.spec.js │ │ └── SvgIcon.spec.js ├── postcss.config.js ├── .env.production ├── src │ ├── assets │ │ ├── 401_images │ │ │ └── 401.gif │ │ ├── 404_images │ │ │ ├── 404.png │ │ │ └── 404_cloud.png │ │ └── custom-theme │ │ │ └── fonts │ │ │ ├── element-icons.ttf │ │ │ └── element-icons.woff │ ├── views │ │ ├── nested │ │ │ ├── menu2 │ │ │ │ └── index.vue │ │ │ └── menu1 │ │ │ │ ├── menu1-3 │ │ │ │ └── index.vue │ │ │ │ ├── index.vue │ │ │ │ ├── menu1-2 │ │ │ │ ├── menu1-2-1 │ │ │ │ │ └── index.vue │ │ │ │ ├── menu1-2-2 │ │ │ │ │ └── index.vue │ │ │ │ └── index.vue │ │ │ │ └── menu1-1 │ │ │ │ └── index.vue │ │ ├── error-log │ │ │ ├── components │ │ │ │ ├── ErrorTestB.vue │ │ │ │ └── ErrorTestA.vue │ │ │ └── index.vue │ │ ├── example │ │ │ ├── components │ │ │ │ ├── Dropdown │ │ │ │ │ ├── index.js │ │ │ │ │ ├── SourceUrl.vue │ │ │ │ │ ├── Comment.vue │ │ │ │ │ └── Platform.vue │ │ │ │ └── Warning.vue │ │ │ ├── edit.vue │ │ │ └── create.vue │ │ ├── icons │ │ │ └── svg-icons.js │ │ ├── redirect │ │ │ └── index.vue │ │ ├── login │ │ │ └── auth-redirect.vue │ │ ├── pdf │ │ │ └── index.vue │ │ ├── charts │ │ │ ├── line.vue │ │ │ ├── mix-chart.vue │ │ │ └── keyboard.vue │ │ ├── permission │ │ │ ├── page.vue │ │ │ └── components │ │ │ │ └── SwitchRoles.vue │ │ ├── table │ │ │ └── dynamic-table │ │ │ │ ├── index.vue │ │ │ │ └── components │ │ │ │ └── UnfixedThead.vue │ │ ├── excel │ │ │ ├── components │ │ │ │ ├── FilenameOption.vue │ │ │ │ ├── AutoWidthOption.vue │ │ │ │ └── BookTypeOption.vue │ │ │ └── upload-excel.vue │ │ ├── dashboard │ │ │ ├── index.vue │ │ │ └── admin │ │ │ │ └── components │ │ │ │ └── TransactionTable.vue │ │ ├── profile │ │ │ ├── components │ │ │ │ ├── Account.vue │ │ │ │ └── Timeline.vue │ │ │ └── index.vue │ │ ├── components-demo │ │ │ ├── dnd-list.vue │ │ │ ├── dropzone.vue │ │ │ ├── drag-select.vue │ │ │ ├── json-editor.vue │ │ │ ├── drag-kanban.vue │ │ │ ├── tinymce.vue │ │ │ └── split-pane.vue │ │ ├── guide │ │ │ ├── index.vue │ │ │ └── steps.js │ │ ├── qiniu │ │ │ └── upload.vue │ │ ├── clipboard │ │ │ └── index.vue │ │ └── tab │ │ │ └── index.vue │ ├── App.vue │ ├── icons │ │ ├── svg │ │ │ ├── chart.svg │ │ │ ├── size.svg │ │ │ ├── link.svg │ │ │ ├── component.svg │ │ │ ├── guide.svg │ │ │ ├── money.svg │ │ │ ├── email.svg │ │ │ ├── drag.svg │ │ │ ├── documentation.svg │ │ │ ├── fullscreen.svg │ │ │ ├── user.svg │ │ │ ├── lock.svg │ │ │ ├── excel.svg │ │ │ ├── example.svg │ │ │ ├── star.svg │ │ │ ├── table.svg │ │ │ ├── search.svg │ │ │ ├── password.svg │ │ │ ├── education.svg │ │ │ ├── tab.svg │ │ │ ├── message.svg │ │ │ ├── theme.svg │ │ │ ├── peoples.svg │ │ │ ├── edit.svg │ │ │ ├── nested.svg │ │ │ ├── tree-table.svg │ │ │ ├── eye.svg │ │ │ ├── clipboard.svg │ │ │ ├── list.svg │ │ │ ├── icon.svg │ │ │ ├── international.svg │ │ │ ├── wechat.svg │ │ │ ├── skill.svg │ │ │ ├── people.svg │ │ │ ├── language.svg │ │ │ ├── eye-open.svg │ │ │ ├── 404.svg │ │ │ ├── zip.svg │ │ │ ├── bug.svg │ │ │ ├── pdf.svg │ │ │ ├── exit-fullscreen.svg │ │ │ └── tree.svg │ │ └── index.js │ ├── api │ │ ├── qiniu.js │ │ ├── remote-search.js │ │ ├── user.js │ │ ├── role.js │ │ └── article.js │ ├── components │ │ ├── ImageCropper │ │ │ └── utils │ │ │ │ ├── mimes.js │ │ │ │ ├── data2blob.js │ │ │ │ └── effectRipple.js │ │ ├── Tinymce │ │ │ ├── toolbar.js │ │ │ └── plugins.js │ │ ├── MarkdownEditor │ │ │ └── default-options.js │ │ ├── Screenfull │ │ │ └── index.vue │ │ ├── Hamburger │ │ │ └── index.vue │ │ ├── SvgIcon │ │ │ └── index.vue │ │ ├── SizeSelect │ │ │ └── index.vue │ │ ├── Charts │ │ │ └── mixins │ │ │ │ └── resize.js │ │ └── DragSelect │ │ │ └── index.vue │ ├── layout │ │ ├── components │ │ │ ├── index.js │ │ │ ├── Sidebar │ │ │ │ ├── FixiOSBug.js │ │ │ │ ├── Link.vue │ │ │ │ ├── Item.vue │ │ │ │ └── index.vue │ │ │ └── AppMain.vue │ │ └── mixin │ │ │ └── ResizeHandler.js │ ├── utils │ │ ├── get-page-title.js │ │ ├── auth.js │ │ ├── permission.js │ │ ├── clipboard.js │ │ ├── error-log.js │ │ └── open-window.js │ ├── directive │ │ ├── waves │ │ │ ├── index.js │ │ │ └── waves.css │ │ ├── el-drag-dialog │ │ │ └── index.js │ │ ├── clipboard │ │ │ ├── index.js │ │ │ └── clipboard.js │ │ ├── permission │ │ │ ├── index.js │ │ │ └── permission.js │ │ └── el-table │ │ │ ├── index.js │ │ │ └── adaptive.js │ ├── store │ │ ├── modules │ │ │ ├── errorLog.js │ │ │ ├── settings.js │ │ │ ├── app.js │ │ │ └── permission.js │ │ ├── getters.js │ │ └── index.js │ ├── vendor │ │ └── Export2Zip.js │ ├── styles │ │ ├── variables.scss │ │ ├── element-variables.scss │ │ ├── transition.scss │ │ ├── element-ui.scss │ │ └── mixin.scss │ ├── settings.js │ ├── router │ │ └── modules │ │ │ ├── charts.js │ │ │ └── table.js │ └── main.js ├── .env.development ├── plop-templates │ ├── utils.js │ ├── store │ │ ├── index.hbs │ │ └── prompt.js │ ├── view │ │ ├── index.hbs │ │ └── prompt.js │ └── component │ │ ├── index.hbs │ │ └── prompt.js ├── .env.staging ├── jsconfig.json ├── .editorconfig ├── .gitignore ├── plopfile.js ├── babel.config.js ├── jest.config.js ├── build │ └── index.js ├── LICENSE └── mock │ ├── remote-search.js │ ├── utils.js │ └── index.js ├── image ├── 1.jpg ├── 10.jpg ├── 11.jpg ├── 12.jpg ├── 13.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg ├── 6.jpg ├── 7.jpg ├── 8.jpg └── 9.jpg ├── cert ├── cert.zip ├── 1600841165_20200807_cert.zip ├── 1600841165_20200807_cert │ ├── apiclient_cert.p12 │ └── apiclient_cert.pem └── 配置.txt ├── uniapp └── commcn │ ├── static │ ├── to.png │ ├── arc.png │ ├── uni.ttf │ ├── select.png │ ├── tab-my.png │ ├── temp │ │ ├── c1.png │ │ ├── c2.png │ │ ├── c3.png │ │ ├── c4.png │ │ ├── c5.png │ │ ├── c6.png │ │ ├── c7.png │ │ ├── c8.png │ │ ├── h1.png │ │ ├── ad1.jpg │ │ ├── share_qq.png │ │ ├── secskill-img.jpg │ │ ├── share_moment.png │ │ ├── share_qqzone.png │ │ └── share_wechat.png │ ├── user-bg.jpg │ ├── yticon.ttf │ ├── emptyCart.jpg │ ├── selected.png │ ├── tab-cart.png │ ├── tab-cate.png │ ├── tab-home.png │ ├── truetype.ttf │ ├── errorImage.jpg │ ├── missing-face.png │ ├── vip-card-bg.png │ ├── tab-my-current.png │ ├── tab-cart-current.png │ ├── tab-cate-current.png │ └── tab-home-current.png │ ├── components │ └── zz-prompt │ │ └── README.md │ ├── store │ └── index.js │ ├── uni.scss │ ├── pages │ ├── logistics │ │ └── logistics.vue │ └── money │ │ └── paySuccess.vue │ └── main.js ├── .gitignore ├── .gitmodules └── apidoc └── proto ├── common └── common_public.proto └── caoguo └── weixin.proto /server/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "go.inferGopath": false 3 | } -------------------------------------------------------------------------------- /admin/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | src/assets 3 | public 4 | dist 5 | -------------------------------------------------------------------------------- /image/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/1.jpg -------------------------------------------------------------------------------- /image/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/10.jpg -------------------------------------------------------------------------------- /image/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/11.jpg -------------------------------------------------------------------------------- /image/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/12.jpg -------------------------------------------------------------------------------- /image/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/13.jpg -------------------------------------------------------------------------------- /image/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/2.jpg -------------------------------------------------------------------------------- /image/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/3.jpg -------------------------------------------------------------------------------- /image/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/4.jpg -------------------------------------------------------------------------------- /image/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/5.jpg -------------------------------------------------------------------------------- /image/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/6.jpg -------------------------------------------------------------------------------- /image/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/7.jpg -------------------------------------------------------------------------------- /image/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/8.jpg -------------------------------------------------------------------------------- /image/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/image/9.jpg -------------------------------------------------------------------------------- /cert/cert.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/cert/cert.zip -------------------------------------------------------------------------------- /server/tools/gormt.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/server/tools/gormt.exe -------------------------------------------------------------------------------- /admin/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/admin/public/favicon.ico -------------------------------------------------------------------------------- /admin/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /admin/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /server/conf/gen_router.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/server/conf/gen_router.data -------------------------------------------------------------------------------- /uniapp/commcn/static/to.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/to.png -------------------------------------------------------------------------------- /uniapp/commcn/static/arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/arc.png -------------------------------------------------------------------------------- /uniapp/commcn/static/uni.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/uni.ttf -------------------------------------------------------------------------------- /uniapp/commcn/static/select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/select.png -------------------------------------------------------------------------------- /uniapp/commcn/static/tab-my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/tab-my.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/c1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/c1.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/c2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/c2.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/c3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/c3.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/c4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/c4.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/c5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/c5.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/c6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/c6.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/c7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/c7.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/c8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/c8.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/h1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/h1.png -------------------------------------------------------------------------------- /uniapp/commcn/static/user-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/user-bg.jpg -------------------------------------------------------------------------------- /uniapp/commcn/static/yticon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/yticon.ttf -------------------------------------------------------------------------------- /cert/1600841165_20200807_cert.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/cert/1600841165_20200807_cert.zip -------------------------------------------------------------------------------- /uniapp/commcn/static/emptyCart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/emptyCart.jpg -------------------------------------------------------------------------------- /uniapp/commcn/static/selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/selected.png -------------------------------------------------------------------------------- /uniapp/commcn/static/tab-cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/tab-cart.png -------------------------------------------------------------------------------- /uniapp/commcn/static/tab-cate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/tab-cate.png -------------------------------------------------------------------------------- /uniapp/commcn/static/tab-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/tab-home.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/ad1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/ad1.jpg -------------------------------------------------------------------------------- /uniapp/commcn/static/truetype.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/truetype.ttf -------------------------------------------------------------------------------- /admin/.env.production: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'production' 3 | 4 | # base api 5 | VUE_APP_BASE_API = '/prod-api' 6 | 7 | -------------------------------------------------------------------------------- /admin/src/assets/401_images/401.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/admin/src/assets/401_images/401.gif -------------------------------------------------------------------------------- /admin/src/assets/404_images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/admin/src/assets/404_images/404.png -------------------------------------------------------------------------------- /uniapp/commcn/static/errorImage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/errorImage.jpg -------------------------------------------------------------------------------- /uniapp/commcn/static/missing-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/missing-face.png -------------------------------------------------------------------------------- /uniapp/commcn/static/vip-card-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/vip-card-bg.png -------------------------------------------------------------------------------- /admin/.env.development: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'development' 3 | 4 | # base api 5 | VUE_APP_BASE_API = '/commcn/api/v1/' 6 | -------------------------------------------------------------------------------- /admin/plop-templates/utils.js: -------------------------------------------------------------------------------- 1 | exports.notEmpty = name => v => 2 | !v || v.trim() === '' ? `${name} is required` : true 3 | -------------------------------------------------------------------------------- /uniapp/commcn/static/tab-my-current.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/tab-my-current.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/share_qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/share_qq.png -------------------------------------------------------------------------------- /admin/src/assets/404_images/404_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/admin/src/assets/404_images/404_cloud.png -------------------------------------------------------------------------------- /uniapp/commcn/static/tab-cart-current.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/tab-cart-current.png -------------------------------------------------------------------------------- /uniapp/commcn/static/tab-cate-current.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/tab-cate-current.png -------------------------------------------------------------------------------- /uniapp/commcn/static/tab-home-current.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/tab-home-current.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/secskill-img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/secskill-img.jpg -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/share_moment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/share_moment.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/share_qqzone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/share_qqzone.png -------------------------------------------------------------------------------- /uniapp/commcn/static/temp/share_wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/uniapp/commcn/static/temp/share_wechat.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | uniapp/commcn/unpackage/ 2 | server/file/ 3 | *.DS_Store 4 | *.log 5 | server/.DS_Store 6 | server/caoguo.exe 7 | server/caoguo 8 | -------------------------------------------------------------------------------- /admin/.env.staging: -------------------------------------------------------------------------------- 1 | NODE_ENV = production 2 | 3 | # just a flag 4 | ENV = 'staging' 5 | 6 | # base api 7 | VUE_APP_BASE_API = '/stage-api' 8 | 9 | -------------------------------------------------------------------------------- /cert/1600841165_20200807_cert/apiclient_cert.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/cert/1600841165_20200807_cert/apiclient_cert.p12 -------------------------------------------------------------------------------- /server/internal/service/history/def.go: -------------------------------------------------------------------------------- 1 | package history 2 | 3 | type queInfo struct { 4 | UserID string 5 | Gpid string 6 | Icon string 7 | } 8 | -------------------------------------------------------------------------------- /server/internal/service/login/oauth2.go: -------------------------------------------------------------------------------- 1 | package login 2 | 3 | //修改密码 4 | func OnChangePwd(username, passworld string) bool { 5 | return false 6 | } 7 | -------------------------------------------------------------------------------- /admin/src/assets/custom-theme/fonts/element-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/admin/src/assets/custom-theme/fonts/element-icons.ttf -------------------------------------------------------------------------------- /admin/src/assets/custom-theme/fonts/element-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/caoguo/HEAD/admin/src/assets/custom-theme/fonts/element-icons.woff -------------------------------------------------------------------------------- /admin/src/views/nested/menu2/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /cert/配置.txt: -------------------------------------------------------------------------------- 1 | 密码:718921 2 | APPID: wxc085afa3e133c093 3 | mch_id: 1600841165 4 | key: adf2a407283e59ddd08dc5e27820d7d1 (md5:kcxxj) 5 | secret: 4EE0A9A43B9B911C067BEE5CC50A9972 -------------------------------------------------------------------------------- /server/gogenerate.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 编译所有 4 | //go:generate make -s -f generate/proto_makefile 5 | // go:generate make gen_proto -f generate/proto_makefile //部分 6 | -------------------------------------------------------------------------------- /admin/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | }, 8 | "exclude": ["node_modules", "dist"] 9 | } -------------------------------------------------------------------------------- /admin/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /admin/src/icons/svg/chart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/views/nested/menu1/menu1-3/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /admin/src/api/qiniu.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getToken() { 4 | return request({ 5 | url: '/qiniu/upload/token', // 假地址 自行替换 6 | method: 'get' 7 | }) 8 | } 9 | -------------------------------------------------------------------------------- /admin/src/components/ImageCropper/utils/mimes.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'jpg': 'image/jpeg', 3 | 'png': 'image/png', 4 | 'gif': 'image/gif', 5 | 'svg': 'image/svg+xml', 6 | 'psd': 'image/photoshop' 7 | } 8 | -------------------------------------------------------------------------------- /admin/src/views/nested/menu1/index.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /admin/src/views/nested/menu1/menu1-2/menu1-2-1/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /admin/src/views/nested/menu1/menu1-2/menu1-2-2/index.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /admin/src/views/error-log/components/ErrorTestB.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /admin/src/views/example/components/Dropdown/index.js: -------------------------------------------------------------------------------- 1 | export { default as CommentDropdown } from './Comment' 2 | export { default as PlatformDropdown } from './Platform' 3 | export { default as SourceUrlDropdown } from './SourceUrl' 4 | -------------------------------------------------------------------------------- /admin/src/icons/svg/size.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/views/nested/menu1/menu1-1/index.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /admin/src/views/nested/menu1/menu1-2/index.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /admin/src/views/error-log/components/ErrorTestA.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ginrpc"] 2 | path = ginrpc 3 | url = https://github.com/xxjwxc/ginrpc 4 | [submodule "public"] 5 | path = public 6 | url = https://github.com/xxjwxc/public 7 | [submodule "goplugins"] 8 | path = goplugins 9 | url = https://github.com/gmsec/goplugins 10 | -------------------------------------------------------------------------------- /admin/plop-templates/store/index.hbs: -------------------------------------------------------------------------------- 1 | {{#if state}} 2 | const state = {} 3 | {{/if}} 4 | 5 | {{#if mutations}} 6 | const mutations = {} 7 | {{/if}} 8 | 9 | {{#if actions}} 10 | const actions = {} 11 | {{/if}} 12 | 13 | export default { 14 | namespaced: true, 15 | {{options}} 16 | } 17 | -------------------------------------------------------------------------------- /admin/src/views/example/edit.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /admin/src/icons/svg/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/layout/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as AppMain } from './AppMain' 2 | export { default as Navbar } from './Navbar' 3 | export { default as Settings } from './Settings' 4 | export { default as Sidebar } from './Sidebar/index.vue' 5 | export { default as TagsView } from './TagsView/index.vue' 6 | -------------------------------------------------------------------------------- /admin/src/utils/get-page-title.js: -------------------------------------------------------------------------------- 1 | import defaultSettings from '@/settings' 2 | 3 | const title = defaultSettings.title || 'Vue Element Admin' 4 | 5 | export default function getPageTitle(pageTitle) { 6 | if (pageTitle) { 7 | return `${pageTitle} - ${title}` 8 | } 9 | return `${title}` 10 | } 11 | -------------------------------------------------------------------------------- /admin/src/views/example/create.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /server/internal/service/history/history.go: -------------------------------------------------------------------------------- 1 | package history 2 | 3 | // Add 添加一个历史记录 4 | func Add(userID, gpid, icon string) { 5 | getLevelDB() 6 | _que.Push(queInfo{UserID: userID, Gpid: gpid, Icon: icon}) 7 | } 8 | 9 | // Get 获取 10 | func Get(userID string) []queInfo { 11 | return gets(userID) 12 | } 13 | -------------------------------------------------------------------------------- /admin/src/directive/waves/index.js: -------------------------------------------------------------------------------- 1 | import waves from './waves' 2 | 3 | const install = function(Vue) { 4 | Vue.directive('waves', waves) 5 | } 6 | 7 | if (window.Vue) { 8 | window.waves = waves 9 | Vue.use(install); // eslint-disable-line 10 | } 11 | 12 | waves.install = install 13 | export default waves 14 | -------------------------------------------------------------------------------- /admin/src/views/icons/svg-icons.js: -------------------------------------------------------------------------------- 1 | const req = require.context('../../icons/svg', false, /\.svg$/) 2 | const requireAll = requireContext => requireContext.keys() 3 | 4 | const re = /\.\/(.*)\.svg/ 5 | 6 | const svgIcons = requireAll(req).map(i => { 7 | return i.match(re)[1] 8 | }) 9 | 10 | export default svgIcons 11 | -------------------------------------------------------------------------------- /admin/.editorconfig: -------------------------------------------------------------------------------- 1 | # https://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 | -------------------------------------------------------------------------------- /admin/src/views/redirect/index.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /admin/src/directive/el-drag-dialog/index.js: -------------------------------------------------------------------------------- 1 | import drag from './drag' 2 | 3 | const install = function(Vue) { 4 | Vue.directive('el-drag-dialog', drag) 5 | } 6 | 7 | if (window.Vue) { 8 | window['el-drag-dialog'] = drag 9 | Vue.use(install); // eslint-disable-line 10 | } 11 | 12 | drag.install = install 13 | export default drag 14 | -------------------------------------------------------------------------------- /admin/src/icons/svg/component.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/icons/svg/guide.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/icons/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import SvgIcon from '@/components/SvgIcon'// svg component 3 | 4 | // register globally 5 | Vue.component('svg-icon', SvgIcon) 6 | 7 | const req = require.context('./svg', false, /\.svg$/) 8 | const requireAll = requireContext => requireContext.keys().map(requireContext) 9 | requireAll(req) 10 | -------------------------------------------------------------------------------- /admin/src/directive/clipboard/index.js: -------------------------------------------------------------------------------- 1 | import Clipboard from './clipboard' 2 | 3 | const install = function(Vue) { 4 | Vue.directive('Clipboard', Clipboard) 5 | } 6 | 7 | if (window.Vue) { 8 | window.clipboard = Clipboard 9 | Vue.use(install); // eslint-disable-line 10 | } 11 | 12 | Clipboard.install = install 13 | export default Clipboard 14 | -------------------------------------------------------------------------------- /admin/src/icons/svg/money.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/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 | return Cookies.set(TokenKey, token) 11 | } 12 | 13 | export function removeToken() { 14 | return Cookies.remove(TokenKey) 15 | } 16 | -------------------------------------------------------------------------------- /admin/src/directive/permission/index.js: -------------------------------------------------------------------------------- 1 | import permission from './permission' 2 | 3 | const install = function(Vue) { 4 | Vue.directive('permission', permission) 5 | } 6 | 7 | if (window.Vue) { 8 | window['permission'] = permission 9 | Vue.use(install); // eslint-disable-line 10 | } 11 | 12 | permission.install = install 13 | export default permission 14 | -------------------------------------------------------------------------------- /admin/src/icons/svg/email.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | **/*.log 8 | 9 | tests/**/coverage/ 10 | tests/e2e/reports 11 | selenium-debug.log 12 | 13 | # Editor directories and files 14 | .idea 15 | .vscode 16 | *.suo 17 | *.ntvs* 18 | *.njsproj 19 | *.sln 20 | *.local 21 | 22 | package-lock.json 23 | yarn.lock 24 | -------------------------------------------------------------------------------- /admin/src/icons/svg/drag.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/directive/el-table/index.js: -------------------------------------------------------------------------------- 1 | import adaptive from './adaptive' 2 | 3 | const install = function(Vue) { 4 | Vue.directive('el-height-adaptive-table', adaptive) 5 | } 6 | 7 | if (window.Vue) { 8 | window['el-height-adaptive-table'] = adaptive 9 | Vue.use(install); // eslint-disable-line 10 | } 11 | 12 | adaptive.install = install 13 | export default adaptive 14 | -------------------------------------------------------------------------------- /admin/src/views/login/auth-redirect.vue: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /admin/plopfile.js: -------------------------------------------------------------------------------- 1 | const viewGenerator = require('./plop-templates/view/prompt') 2 | const componentGenerator = require('./plop-templates/component/prompt') 3 | const storeGenerator = require('./plop-templates/store/prompt.js') 4 | 5 | module.exports = function(plop) { 6 | plop.setGenerator('view', viewGenerator) 7 | plop.setGenerator('component', componentGenerator) 8 | plop.setGenerator('store', storeGenerator) 9 | } 10 | -------------------------------------------------------------------------------- /admin/src/views/pdf/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | -------------------------------------------------------------------------------- /admin/src/api/remote-search.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function searchUser(name) { 4 | return request({ 5 | url: '/vue-element-admin/search/user', 6 | method: 'get', 7 | params: { name } 8 | }) 9 | } 10 | 11 | export function transactionList(query) { 12 | return request({ 13 | url: '/vue-element-admin/transaction/list', 14 | method: 'get', 15 | params: query 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /admin/src/icons/svg/documentation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/icons/svg/fullscreen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/plop-templates/view/index.hbs: -------------------------------------------------------------------------------- 1 | {{#if template}} 2 | 5 | {{/if}} 6 | 7 | {{#if script}} 8 | 20 | {{/if}} 21 | 22 | {{#if style}} 23 | 26 | {{/if}} 27 | -------------------------------------------------------------------------------- /admin/src/icons/svg/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/plop-templates/component/index.hbs: -------------------------------------------------------------------------------- 1 | {{#if template}} 2 | 5 | {{/if}} 6 | 7 | {{#if script}} 8 | 20 | {{/if}} 21 | 22 | {{#if style}} 23 | 26 | {{/if}} 27 | -------------------------------------------------------------------------------- /admin/src/icons/svg/lock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/icons/svg/excel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/views/charts/line.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 23 | 24 | -------------------------------------------------------------------------------- /admin/src/views/charts/mix-chart.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 23 | 24 | -------------------------------------------------------------------------------- /admin/src/views/charts/keyboard.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 23 | 24 | -------------------------------------------------------------------------------- /admin/tests/unit/utils/param2Obj.spec.js: -------------------------------------------------------------------------------- 1 | import { param2Obj } from '@/utils/index.js' 2 | describe('Utils:param2Obj', () => { 3 | const url = 'https://github.com/PanJiaChen/vue-element-admin?name=bill&age=29&sex=1&field=dGVzdA==&key=%E6%B5%8B%E8%AF%95' 4 | 5 | it('param2Obj test', () => { 6 | expect(param2Obj(url)).toEqual({ 7 | name: 'bill', 8 | age: '29', 9 | sex: '1', 10 | field: window.btoa('test'), 11 | key: '测试' 12 | }) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /admin/src/views/permission/page.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | -------------------------------------------------------------------------------- /admin/src/icons/svg/example.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apidoc/proto/common/common_public.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; // 指定proto版本 2 | 3 | package common; // 指定包名 4 | 5 | // import "google/protobuf/descriptor.proto"; 6 | 7 | // option go_package = "common;common"; // 指定路径 8 | option go_package = "rpc/common"; 9 | 10 | message ResultResp { 11 | bool result = 1; 12 | string msg = 2; 13 | } 14 | 15 | // Empty 空 16 | message Empty {} 17 | 18 | // Page 分页 19 | message Page{ 20 | int32 size = 1;// 每页尺寸 21 | int32 index = 2;// 第几页 22 | int32 limit = 3;// 总页数 23 | } -------------------------------------------------------------------------------- /admin/src/components/Tinymce/toolbar.js: -------------------------------------------------------------------------------- 1 | // Here is a list of the toolbar 2 | // Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols 3 | 4 | const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen'] 5 | 6 | export default toolbar 7 | -------------------------------------------------------------------------------- /admin/src/api/user.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function login(data) { 4 | return request({ 5 | url: '/login/login', 6 | method: 'post', 7 | data 8 | }) 9 | } 10 | 11 | export function getInfo(token) { 12 | return request({ 13 | url: '/vue-element-admin/user/info', 14 | method: 'get', 15 | params: { token } 16 | }) 17 | } 18 | 19 | export function logout() { 20 | return request({ 21 | url: '/vue-element-admin/user/logout', 22 | method: 'post' 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /admin/src/store/modules/errorLog.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | logs: [] 3 | } 4 | 5 | const mutations = { 6 | ADD_ERROR_LOG: (state, log) => { 7 | state.logs.push(log) 8 | }, 9 | CLEAR_ERROR_LOG: (state) => { 10 | state.logs.splice(0) 11 | } 12 | } 13 | 14 | const actions = { 15 | addErrorLog({ commit }, log) { 16 | commit('ADD_ERROR_LOG', log) 17 | }, 18 | clearErrorLog({ commit }) { 19 | commit('CLEAR_ERROR_LOG') 20 | } 21 | } 22 | 23 | export default { 24 | namespaced: true, 25 | state, 26 | mutations, 27 | actions 28 | } 29 | -------------------------------------------------------------------------------- /admin/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <%= webpackConfig.name %> 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /admin/src/icons/svg/star.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/icons/svg/table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/icons/svg/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/components/Tinymce/plugins.js: -------------------------------------------------------------------------------- 1 | // Any plugins you want to use has to be imported 2 | // Detail plugins list see https://www.tinymce.com/docs/plugins/ 3 | // Custom builds see https://www.tinymce.com/download/custom-builds/ 4 | 5 | const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount'] 6 | 7 | export default plugins 8 | -------------------------------------------------------------------------------- /admin/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app 4 | '@vue/cli-plugin-babel/preset' 5 | ], 6 | 'env': { 7 | 'development': { 8 | // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require(). 9 | // This plugin can significantly increase the speed of hot updates, when you have a large number of pages. 10 | // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html 11 | 'plugins': ['dynamic-import-node'] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /admin/src/store/getters.js: -------------------------------------------------------------------------------- 1 | const getters = { 2 | sidebar: state => state.app.sidebar, 3 | size: state => state.app.size, 4 | device: state => state.app.device, 5 | visitedViews: state => state.tagsView.visitedViews, 6 | cachedViews: state => state.tagsView.cachedViews, 7 | token: state => state.user.token, 8 | avatar: state => state.user.avatar, 9 | name: state => state.user.name, 10 | introduction: state => state.user.introduction, 11 | roles: state => state.user.roles, 12 | permission_routes: state => state.permission.routes, 13 | errorLogs: state => state.errorLog.logs 14 | } 15 | export default getters 16 | -------------------------------------------------------------------------------- /admin/src/icons/svg/password.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/components/ImageCropper/utils/data2blob.js: -------------------------------------------------------------------------------- 1 | /** 2 | * database64文件格式转换为2进制 3 | * 4 | * @param {[String]} data dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了 5 | * @param {[String]} mime [description] 6 | * @return {[blob]} [description] 7 | */ 8 | export default function(data, mime) { 9 | data = data.split(',')[1] 10 | data = window.atob(data) 11 | var ia = new Uint8Array(data.length) 12 | for (var i = 0; i < data.length; i++) { 13 | ia[i] = data.charCodeAt(i) 14 | } 15 | // canvas.toDataURL 返回的默认格式就是 image/png 16 | return new Blob([ia], { 17 | type: mime 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /admin/src/icons/svg/education.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/views/table/dynamic-table/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 24 | 25 | -------------------------------------------------------------------------------- /server/docs/markdown/Upload.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## [推荐查看工具](https://www.iminho.me/) 4 | 5 | ## 总览: 6 | - [Upload] 7 | - [Waiting to write...] 8 | 9 | -------------------- 10 | 11 | ### UploadMult 12 | 13 | #### 简要描述: 14 | 15 | - [上传文件 多个] 16 | 17 | #### 请求URL: 18 | 19 | - http://localhost:9001/commcn/api/v1/upload 20 | 21 | #### 请求方式: 22 | 23 | - post 24 | 25 | #### 请求参数: 26 | 27 | 28 | #### 请求示例: 29 | ``` 30 | {} 31 | ``` 32 | 33 | #### 返回参数说明: 34 | 35 | 36 | #### 返回示例: 37 | 38 | ``` 39 | {} 40 | ``` 41 | 42 | #### 备注: 43 | 44 | - 上传文件 多个 45 | 46 | 47 | -------------------- 48 | -------------------- 49 | 50 | #### 自定义类型: 51 | 52 | 53 | -------------------------------------------------------------------------------- /admin/src/icons/svg/tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/views/example/components/Warning.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | -------------------------------------------------------------------------------- /admin/src/utils/permission.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | 3 | /** 4 | * @param {Array} value 5 | * @returns {Boolean} 6 | * @example see @/views/permission/directive.vue 7 | */ 8 | export default function checkPermission(value) { 9 | if (value && value instanceof Array && value.length > 0) { 10 | const roles = store.getters && store.getters.roles 11 | const permissionRoles = value 12 | 13 | const hasPermission = roles.some(role => { 14 | return permissionRoles.includes(role) 15 | }) 16 | return hasPermission 17 | } else { 18 | console.error(`need roles! Like v-permission="['admin','editor']"`) 19 | return false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /admin/src/icons/svg/message.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/icons/svg/theme.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/views/excel/components/FilenameOption.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 28 | -------------------------------------------------------------------------------- /admin/src/vendor/Export2Zip.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import { saveAs } from 'file-saver' 3 | import JSZip from 'jszip' 4 | 5 | export function export_txt_to_zip(th, jsonData, txtName, zipName) { 6 | const zip = new JSZip() 7 | const txt_name = txtName || 'file' 8 | const zip_name = zipName || 'file' 9 | const data = jsonData 10 | let txtData = `${th}\r\n` 11 | data.forEach((row) => { 12 | let tempStr = '' 13 | tempStr = row.toString() 14 | txtData += `${tempStr}\r\n` 15 | }) 16 | zip.file(`${txt_name}.txt`, txtData) 17 | zip.generateAsync({ 18 | type: "blob" 19 | }).then((blob) => { 20 | saveAs(blob, `${zip_name}.zip`) 21 | }, (err) => { 22 | alert('导出失败') 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /uniapp/commcn/components/zz-prompt/README.md: -------------------------------------------------------------------------------- 1 | # Prompt 2 | 3 | ## 说明 4 | 5 | 一个可以输入内容并返回的prompt组件, 支持一个默认slot放入中间. 6 | 7 | ## 用法 8 | 9 | **父组件** 10 | 11 | template中 12 | ```html 13 | 14 | 15 | 16 | ``` 17 | 18 | ```js 19 | import Prompt from '@/components/prompt/index.vue' 20 | 21 | export default { 22 | data() { 23 | return { 24 | // 控制弹框输入框显示 25 | promptVisible: false, 26 | } 27 | }, 28 | methods: { 29 | /** 30 | * 点击弹出输入框确定 31 | */ 32 | clickPromptConfirm(val) { 33 | console.log(val) 34 | }, 35 | } 36 | } 37 | ``` -------------------------------------------------------------------------------- /uniapp/commcn/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | Vue.use(Vuex) 5 | 6 | const store = new Vuex.Store({ 7 | state: { 8 | hasLogin: false, 9 | userInfo: {}, 10 | }, 11 | mutations: { 12 | login(state, provider) { 13 | state.hasLogin = true; 14 | state.userInfo = provider; 15 | uni.setStorage({//缓存用户登陆状态 16 | key: 'userInfo', 17 | data: provider 18 | }) 19 | console.log(state.userInfo); 20 | }, 21 | logout(state) { 22 | state.hasLogin = false; 23 | state.userInfo = {}; 24 | uni.removeStorage({ 25 | key: 'userInfo' 26 | }) 27 | } 28 | }, 29 | actions: { 30 | 31 | } 32 | }) 33 | 34 | export default store 35 | -------------------------------------------------------------------------------- /admin/src/views/dashboard/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 32 | -------------------------------------------------------------------------------- /admin/src/icons/svg/peoples.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/components/MarkdownEditor/default-options.js: -------------------------------------------------------------------------------- 1 | // doc: https://nhnent.github.io/tui.editor/api/latest/ToastUIEditor.html#ToastUIEditor 2 | export default { 3 | minHeight: '200px', 4 | previewStyle: 'vertical', 5 | useCommandShortcut: true, 6 | useDefaultHTMLSanitizer: true, 7 | usageStatistics: false, 8 | hideModeSwitch: false, 9 | toolbarItems: [ 10 | 'heading', 11 | 'bold', 12 | 'italic', 13 | 'strike', 14 | 'divider', 15 | 'hr', 16 | 'quote', 17 | 'divider', 18 | 'ul', 19 | 'ol', 20 | 'task', 21 | 'indent', 22 | 'outdent', 23 | 'divider', 24 | 'table', 25 | 'image', 26 | 'link', 27 | 'divider', 28 | 'code', 29 | 'codeblock' 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /admin/tests/unit/components/Hamburger.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import Hamburger from '@/components/Hamburger/index.vue' 3 | describe('Hamburger.vue', () => { 4 | it('toggle click', () => { 5 | const wrapper = shallowMount(Hamburger) 6 | const mockFn = jest.fn() 7 | wrapper.vm.$on('toggleClick', mockFn) 8 | wrapper.find('.hamburger').trigger('click') 9 | expect(mockFn).toBeCalled() 10 | }) 11 | it('prop isActive', () => { 12 | const wrapper = shallowMount(Hamburger) 13 | wrapper.setProps({ isActive: true }) 14 | expect(wrapper.contains('.is-active')).toBe(true) 15 | wrapper.setProps({ isActive: false }) 16 | expect(wrapper.contains('.is-active')).toBe(false) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /admin/tests/unit/components/SvgIcon.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import SvgIcon from '@/components/SvgIcon/index.vue' 3 | describe('SvgIcon.vue', () => { 4 | it('iconClass', () => { 5 | const wrapper = shallowMount(SvgIcon, { 6 | propsData: { 7 | iconClass: 'test' 8 | } 9 | }) 10 | expect(wrapper.find('use').attributes().href).toBe('#icon-test') 11 | }) 12 | it('className', () => { 13 | const wrapper = shallowMount(SvgIcon, { 14 | propsData: { 15 | iconClass: 'test' 16 | } 17 | }) 18 | expect(wrapper.classes().length).toBe(1) 19 | wrapper.setProps({ className: 'test' }) 20 | expect(wrapper.classes().includes('test')).toBe(true) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /uniapp/commcn/uni.scss: -------------------------------------------------------------------------------- 1 | 2 | /* 页面左右间距 */ 3 | $page-row-spacing: 30upx; 4 | $page-color-base: #f8f8f8; 5 | $page-color-light: #f8f6fc; 6 | $base-color: #fa436a; 7 | 8 | /* 文字尺寸 */ 9 | $font-sm: 24upx; 10 | $font-base: 28upx; 11 | $font-lg: 32upx; 12 | /*文字颜色*/ 13 | $font-color-dark: #303133; 14 | $font-color-base: #606266; 15 | $font-color-light: #909399; 16 | $font-color-disabled: #C0C4CC; 17 | $font-color-spec: #4399fc; 18 | /* 边框颜色 */ 19 | $border-color-dark: #DCDFE6; 20 | $border-color-base: #E4E7ED; 21 | $border-color-light: #EBEEF5; 22 | /* 图片加载中颜色 */ 23 | $image-bg-color: #eee; 24 | /* 行为相关颜色 */ 25 | $uni-color-primary:#fa436a; 26 | $uni-color-success: #4cd964; 27 | $uni-color-warning: #f0ad4e; 28 | $uni-color-error: #dd524d; 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /admin/src/layout/components/Sidebar/FixiOSBug.js: -------------------------------------------------------------------------------- 1 | export default { 2 | computed: { 3 | device() { 4 | return this.$store.state.app.device 5 | } 6 | }, 7 | mounted() { 8 | // In order to fix the click on menu on the ios device will trigger the mouseleave bug 9 | // https://github.com/PanJiaChen/vue-element-admin/issues/1135 10 | this.fixBugIniOS() 11 | }, 12 | methods: { 13 | fixBugIniOS() { 14 | const $subMenu = this.$refs.subMenu 15 | if ($subMenu) { 16 | const handleMouseleave = $subMenu.handleMouseleave 17 | $subMenu.handleMouseleave = (e) => { 18 | if (this.device === 'mobile') { 19 | return 20 | } 21 | handleMouseleave(e) 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /admin/src/views/excel/components/AutoWidthOption.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 35 | -------------------------------------------------------------------------------- /admin/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.destroy() 26 | }) 27 | clipboard.on('error', () => { 28 | clipboardError() 29 | clipboard.destroy() 30 | }) 31 | clipboard.onClick(event) 32 | } 33 | -------------------------------------------------------------------------------- /admin/src/views/permission/components/SwitchRoles.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 33 | -------------------------------------------------------------------------------- /admin/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import getters from './getters' 4 | 5 | Vue.use(Vuex) 6 | 7 | // https://webpack.js.org/guides/dependency-management/#requirecontext 8 | const modulesFiles = require.context('./modules', true, /\.js$/) 9 | 10 | // you do not need `import app from './modules/app'` 11 | // it will auto require all vuex module from modules file 12 | const modules = modulesFiles.keys().reduce((modules, modulePath) => { 13 | // set './app.js' => 'app' 14 | const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') 15 | const value = modulesFiles(modulePath) 16 | modules[moduleName] = value.default 17 | return modules 18 | }, {}) 19 | 20 | const store = new Vuex.Store({ 21 | modules, 22 | getters 23 | }) 24 | 25 | export default store 26 | -------------------------------------------------------------------------------- /admin/src/icons/svg/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/icons/svg/nested.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/api/role.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getRoutes() { 4 | return request({ 5 | url: '/vue-element-admin/routes', 6 | method: 'get' 7 | }) 8 | } 9 | 10 | export function getRoles() { 11 | return request({ 12 | url: '/vue-element-admin/roles', 13 | method: 'get' 14 | }) 15 | } 16 | 17 | export function addRole(data) { 18 | return request({ 19 | url: '/vue-element-admin/role', 20 | method: 'post', 21 | data 22 | }) 23 | } 24 | 25 | export function updateRole(id, data) { 26 | return request({ 27 | url: `/vue-element-admin/role/${id}`, 28 | method: 'put', 29 | data 30 | }) 31 | } 32 | 33 | export function deleteRole(id) { 34 | return request({ 35 | url: `/vue-element-admin/role/${id}`, 36 | method: 'delete' 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /server/internal/config/test_def.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | ) 7 | 8 | const ( 9 | testFile = ` 10 | serial_number : "1.0" #版本号 11 | service_name : #服务名 12 | service_displayname : #服务显示名 13 | sercice_desc : #服务描述 14 | is_dev : false # 是否开发者模式 15 | out_dir : ./db # 输出目录 16 | singular_table : true # 单表模式:true:禁用表名复数,false:采用表明复数 参考:gorm.SingularTable 17 | simple : true #简单输出 18 | isJsonTag : true #是否打json标记 19 | mysql_info: 20 | host : 127.0.0.1 21 | port : 3306 22 | username : root 23 | password : qwer 24 | database : oauth_db 25 | ` 26 | ) 27 | 28 | // IsRunTesting Determine whether to use it in a test environment.判断是否在测试环境下使用 29 | func IsRunTesting() bool { 30 | if len(os.Args) > 1 { 31 | return strings.HasPrefix(os.Args[1], "-test") 32 | } 33 | return false 34 | } 35 | -------------------------------------------------------------------------------- /admin/src/directive/permission/permission.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | 3 | function checkPermission(el, binding) { 4 | const { value } = binding 5 | const roles = store.getters && store.getters.roles 6 | 7 | if (value && value instanceof Array) { 8 | if (value.length > 0) { 9 | const permissionRoles = value 10 | 11 | const hasPermission = roles.some(role => { 12 | return permissionRoles.includes(role) 13 | }) 14 | 15 | if (!hasPermission) { 16 | el.parentNode && el.parentNode.removeChild(el) 17 | } 18 | } 19 | } else { 20 | throw new Error(`need roles! Like v-permission="['admin','editor']"`) 21 | } 22 | } 23 | 24 | export default { 25 | inserted(el, binding) { 26 | checkPermission(el, binding) 27 | }, 28 | update(el, binding) { 29 | checkPermission(el, binding) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /server/internal/service/order/sql.go: -------------------------------------------------------------------------------- 1 | package order 2 | 3 | import "time" 4 | 5 | // BillOrderTbl 账单订单列表 6 | type BillOrderTbl struct { 7 | ID int64 `gorm:"primary_key"` 8 | BillID string `gorm:"unique_index:user_gpid;index:bill_id"` // 账单id 9 | Gpid string `gorm:"unique_index:user_gpid"` // 商品id 10 | Name string // 商品名字 11 | Price int64 // 商品价格(分) 12 | Icon string // 图标信息 13 | UserID string `gorm:"unique_index:user_gpid"` // 用户id 14 | Number int // 数量 15 | SkuList string `gorm:"unique_index:user_gpid"` // 属性列表 16 | SkuArrt string // 属性描述 17 | CreatedBy string // 创建者 18 | CreatedAt time.Time // 创建时间 19 | UpdatedBy string // 更新者 20 | UpdatedAt time.Time // 更新时间 21 | Status int // 状态 22 | CouponID int // 优惠券 23 | Title string // 优惠券名称 24 | } 25 | -------------------------------------------------------------------------------- /admin/src/store/modules/settings.js: -------------------------------------------------------------------------------- 1 | import variables from '@/styles/element-variables.scss' 2 | import defaultSettings from '@/settings' 3 | 4 | const { showSettings, tagsView, fixedHeader, 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 | // eslint-disable-next-line no-prototype-builtins 17 | if (state.hasOwnProperty(key)) { 18 | state[key] = value 19 | } 20 | } 21 | } 22 | 23 | const actions = { 24 | changeSetting({ commit }, data) { 25 | commit('CHANGE_SETTING', data) 26 | } 27 | } 28 | 29 | export default { 30 | namespaced: true, 31 | state, 32 | mutations, 33 | actions 34 | } 35 | 36 | -------------------------------------------------------------------------------- /admin/src/views/excel/components/BookTypeOption.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 40 | -------------------------------------------------------------------------------- /admin/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], 3 | transform: { 4 | '^.+\\.vue$': 'vue-jest', 5 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 6 | 'jest-transform-stub', 7 | '^.+\\.jsx?$': 'babel-jest' 8 | }, 9 | moduleNameMapper: { 10 | '^@/(.*)$': '/src/$1' 11 | }, 12 | snapshotSerializers: ['jest-serializer-vue'], 13 | testMatch: [ 14 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 15 | ], 16 | collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'], 17 | coverageDirectory: '/tests/unit/coverage', 18 | // 'collectCoverage': true, 19 | 'coverageReporters': [ 20 | 'lcov', 21 | 'text-summary' 22 | ], 23 | testURL: 'http://localhost/' 24 | } 25 | -------------------------------------------------------------------------------- /admin/src/layout/components/Sidebar/Link.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 44 | -------------------------------------------------------------------------------- /admin/src/layout/components/Sidebar/Item.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 42 | -------------------------------------------------------------------------------- /admin/src/icons/svg/tree-table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/views/profile/components/Account.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 39 | -------------------------------------------------------------------------------- /admin/src/icons/svg/eye.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/api/article.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function fetchList(query) { 4 | return request({ 5 | url: '/vue-element-admin/article/list', 6 | method: 'get', 7 | params: query 8 | }) 9 | } 10 | 11 | export function fetchArticle(id) { 12 | return request({ 13 | url: '/vue-element-admin/article/detail', 14 | method: 'get', 15 | params: { id } 16 | }) 17 | } 18 | 19 | export function fetchPv(pv) { 20 | return request({ 21 | url: '/vue-element-admin/article/pv', 22 | method: 'get', 23 | params: { pv } 24 | }) 25 | } 26 | 27 | export function createArticle(data) { 28 | return request({ 29 | url: '/vue-element-admin/article/create', 30 | method: 'post', 31 | data 32 | }) 33 | } 34 | 35 | export function updateArticle(data) { 36 | return request({ 37 | url: '/vue-element-admin/article/update', 38 | method: 'post', 39 | data 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /admin/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 | -------------------------------------------------------------------------------- /admin/src/directive/waves/waves.css: -------------------------------------------------------------------------------- 1 | .waves-ripple { 2 | position: absolute; 3 | border-radius: 100%; 4 | background-color: rgba(0, 0, 0, 0.15); 5 | background-clip: padding-box; 6 | pointer-events: none; 7 | -webkit-user-select: none; 8 | -moz-user-select: none; 9 | -ms-user-select: none; 10 | user-select: none; 11 | -webkit-transform: scale(0); 12 | -ms-transform: scale(0); 13 | transform: scale(0); 14 | opacity: 1; 15 | } 16 | 17 | .waves-ripple.z-active { 18 | opacity: 0; 19 | -webkit-transform: scale(2); 20 | -ms-transform: scale(2); 21 | transform: scale(2); 22 | -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; 23 | transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; 24 | transition: opacity 1.2s ease-out, transform 0.6s ease-out; 25 | transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out; 26 | } -------------------------------------------------------------------------------- /admin/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 | -------------------------------------------------------------------------------- /admin/src/styles/transition.scss: -------------------------------------------------------------------------------- 1 | // global 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 | /* breadcrumb transition */ 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 | -------------------------------------------------------------------------------- /uniapp/commcn/pages/logistics/logistics.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /admin/src/settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'Vue Element 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 | -------------------------------------------------------------------------------- /admin/src/icons/svg/clipboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/icons/svg/list.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/router/modules/charts.js: -------------------------------------------------------------------------------- 1 | /** When your routing table is too long, you can split it into small modules**/ 2 | 3 | import Layout from '@/layout' 4 | 5 | const chartsRouter = { 6 | path: '/charts', 7 | component: Layout, 8 | redirect: 'noRedirect', 9 | name: 'Charts', 10 | meta: { 11 | title: 'Charts', 12 | icon: 'chart' 13 | }, 14 | children: [ 15 | { 16 | path: 'keyboard', 17 | component: () => import('@/views/charts/keyboard'), 18 | name: 'KeyboardChart', 19 | meta: { title: 'Keyboard Chart', noCache: true } 20 | }, 21 | { 22 | path: 'line', 23 | component: () => import('@/views/charts/line'), 24 | name: 'LineChart', 25 | meta: { title: 'Line Chart', noCache: true } 26 | }, 27 | { 28 | path: 'mix-chart', 29 | component: () => import('@/views/charts/mix-chart'), 30 | name: 'MixChart', 31 | meta: { title: 'Mix Chart', noCache: true } 32 | } 33 | ] 34 | } 35 | 36 | export default chartsRouter 37 | -------------------------------------------------------------------------------- /admin/src/views/components-demo/dnd-list.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 39 | 40 | -------------------------------------------------------------------------------- /admin/src/views/guide/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 37 | -------------------------------------------------------------------------------- /admin/build/index.js: -------------------------------------------------------------------------------- 1 | const { run } = require('runjs') 2 | const chalk = require('chalk') 3 | const config = require('../vue.config.js') 4 | const rawArgv = process.argv.slice(2) 5 | const args = rawArgv.join(' ') 6 | 7 | if (process.env.npm_config_preview || rawArgv.includes('--preview')) { 8 | const report = rawArgv.includes('--report') 9 | 10 | run(`vue-cli-service build ${args}`) 11 | 12 | const port = 9526 13 | const publicPath = config.publicPath 14 | 15 | var connect = require('connect') 16 | var serveStatic = require('serve-static') 17 | const app = connect() 18 | 19 | app.use( 20 | publicPath, 21 | serveStatic('./dist', { 22 | index: ['index.html', '/'] 23 | }) 24 | ) 25 | 26 | app.listen(port, function () { 27 | console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) 28 | if (report) { 29 | console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) 30 | } 31 | 32 | }) 33 | } else { 34 | run(`vue-cli-service build ${args}`) 35 | } 36 | -------------------------------------------------------------------------------- /admin/src/views/example/components/Dropdown/SourceUrl.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 39 | -------------------------------------------------------------------------------- /admin/src/icons/svg/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/utils/error-log.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import store from '@/store' 3 | import { isString, isArray } from '@/utils/validate' 4 | import settings from '@/settings' 5 | 6 | // you can set in settings.js 7 | // errorLog:'production' | ['production', 'development'] 8 | const { errorLog: needErrorLog } = settings 9 | 10 | function checkNeed() { 11 | const env = process.env.NODE_ENV 12 | if (isString(needErrorLog)) { 13 | return env === needErrorLog 14 | } 15 | if (isArray(needErrorLog)) { 16 | return needErrorLog.includes(env) 17 | } 18 | return false 19 | } 20 | 21 | if (checkNeed()) { 22 | Vue.config.errorHandler = function(err, vm, info, a) { 23 | // Don't ask me why I use Vue.nextTick, it just a hack. 24 | // detail see https://forum.vuejs.org/t/dispatch-in-vue-config-errorhandler-has-some-problem/23500 25 | Vue.nextTick(() => { 26 | store.dispatch('errorLog/addErrorLog', { 27 | err, 28 | vm, 29 | info, 30 | url: window.location.href 31 | }) 32 | console.error(err, info) 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /admin/src/icons/svg/international.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/tools/config.yml: -------------------------------------------------------------------------------- 1 | base: 2 | is_dev : false 3 | out_dir : ./model # 输出目录 4 | url_tag : json # web url tag(json,db(https://github.com/google/go-querystring)) 5 | language : # 语言(English,中 文) 6 | db_tag : gorm # 数据库标签(gorm,db) 7 | simple : true # 简单输出(默认gorm标签不输出) 8 | is_out_sql : false # 是否输出 sql 原信息 9 | is_out_func : true # 是否输出 快捷函数 10 | is_web_tag : true # 是否打web标记(json标记前提条件) 11 | is_web_tag_pk_hidden: true # web标记是否隐藏主键 12 | is_foreign_key : true # 是否导出外键关联 13 | is_gui : false # 是否ui模式显示 14 | is_table_name : true # 是否直接生成表名,列名 15 | is_null_to_point : false # 数据库默认 'DEFAULT NULL' 时设置结构为指针类型 16 | table_prefix : "" # 表前缀, 如果有则使用, 没有留空 17 | db_info: 18 | host : 192.155.1.150 # type=1的时候,host为yml文件全路径 19 | port : 3306 20 | database : dev_haitrain 21 | username : devserver 22 | password : dev.hello123 23 | type: 0 # 数据库类型:0:mysql , 1:sqlite , 2:mssql 24 | 25 | # sqlite 26 | # db_info: 27 | # host : /Users/xxj/Downloads/caoguo # type=1的时候,host为yml文件全路径 28 | # port : 29 | # username : 30 | # password : 31 | # database : 32 | # type: 1 # 数据库类型:0:mysql , 1:sqlite , 2:mssql -------------------------------------------------------------------------------- /server/conf/config.yml: -------------------------------------------------------------------------------- 1 | base: 2 | serial_number: "v1" # 版本号 3 | service_name: "caoguo" # 服务名 4 | service_displayname: "caoguo" # 服务显示名 5 | sercice_desc: "caoguo" # 描述 6 | is_dev: true 7 | mysql_info: 8 | port : 3306 # 端口号 9 | username : root # 用户名 10 | host : localhost # 地址 11 | password : 123456 # 密码 12 | # host : localhost 13 | # password : qwer 14 | database : caoguo_dev # 数据库名 15 | kdniao: # 快递鸟配置 16 | business_id : 1317777 17 | app_key : 111111-2222-3333-4444-555555555 18 | email: # 发邮件配置 19 | user: xie1xiao1jun@126.com 20 | password: pppppppppppppp 21 | host: smtp.126.com:25 22 | wx_info: # 微信相关配置 23 | app_id : wxc111111111111 24 | app_secret : 111111111111111111111 25 | api_key : 1111111111111111111111111 26 | mch_id : 1111111111111111 27 | notify_url : http://www.xxjwxc.cn 28 | shear_url : "" 29 | file_host: https://localhost/commcn/api/v1 30 | oauth2_url: http://localhost/oauth2/api/v1 31 | register_url: http://localhost/register/api/v1 32 | token_type: nomal 33 | app_id: wwwthings 34 | app_secret: 4EE0A9A43B9B911C067BEE5CC50A9972 35 | port : 8001 -------------------------------------------------------------------------------- /admin/src/views/components-demo/dropzone.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 31 | 32 | -------------------------------------------------------------------------------- /admin/src/views/example/components/Dropdown/Comment.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 42 | -------------------------------------------------------------------------------- /admin/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 | -------------------------------------------------------------------------------- /server/internal/service/notify/common.go: -------------------------------------------------------------------------------- 1 | package notify 2 | 3 | import ( 4 | "caoguo/internal/core" 5 | "caoguo/internal/model" 6 | "sync" 7 | "time" 8 | 9 | "github.com/xxjwxc/public/mycache" 10 | ) 11 | 12 | var cache *mycache.MyCache 13 | var once sync.Once 14 | var mtx sync.Mutex 15 | 16 | func getEmailList(username string) (resp []string) { 17 | once.Do(func() { 18 | cache = mycache.NewCache("_email_list") 19 | }) 20 | 21 | mp := make(map[string][]string) 22 | mtx.Lock() 23 | defer mtx.Unlock() 24 | err := cache.Value("list", &mp) 25 | if err == nil { // 找到 26 | resp = append(resp, mp[""]...) 27 | if _, ok := mp[username]; ok { 28 | resp = append(resp, mp[username]...) 29 | } 30 | return 31 | } 32 | 33 | mp = make(map[string][]string) 34 | orm := core.Dao.GetDBr() 35 | list, _ := model.EmailNotifyTblMgr(orm.DB).Gets() 36 | for _, v := range list { 37 | mp[v.UserID] = append(mp[v.UserID], v.Email) 38 | } 39 | 40 | //添加 41 | cache.Add("list", mp, 1*time.Hour) // 1小时更新一次 42 | resp = append(resp, mp[""]...) 43 | if _, ok := mp[username]; ok { 44 | resp = append(resp, mp[username]...) 45 | } 46 | return resp 47 | } 48 | -------------------------------------------------------------------------------- /admin/src/icons/svg/wechat.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/icons/svg/skill.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/tests/unit/utils/formatTime.spec.js: -------------------------------------------------------------------------------- 1 | import { formatTime } from '@/utils/index.js' 2 | describe('Utils:formatTime', () => { 3 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" 4 | const retrofit = 5 * 1000 5 | 6 | it('ten digits timestamp', () => { 7 | expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分') 8 | }) 9 | it('test now', () => { 10 | expect(formatTime(+new Date() - 1)).toBe('刚刚') 11 | }) 12 | it('less two minute', () => { 13 | expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前') 14 | }) 15 | it('less two hour', () => { 16 | expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前') 17 | }) 18 | it('less one day', () => { 19 | expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前') 20 | }) 21 | it('more than one day', () => { 22 | expect(formatTime(d)).toBe('7月13日17时54分') 23 | }) 24 | it('format', () => { 25 | expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') 26 | expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') 27 | expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') 28 | }) 29 | }) 30 | -------------------------------------------------------------------------------- /admin/src/icons/svg/people.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/views/error-log/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 27 | 28 | 33 | -------------------------------------------------------------------------------- /admin/src/router/modules/table.js: -------------------------------------------------------------------------------- 1 | /** When your routing table is too long, you can split it into small modules **/ 2 | 3 | import Layout from '@/layout' 4 | 5 | const tableRouter = { 6 | path: '/table', 7 | component: Layout, 8 | redirect: '/table/complex-table', 9 | name: 'Table', 10 | meta: { 11 | title: 'Table', 12 | icon: 'table' 13 | }, 14 | children: [ 15 | { 16 | path: 'dynamic-table', 17 | component: () => import('@/views/table/dynamic-table/index'), 18 | name: 'DynamicTable', 19 | meta: { title: 'Dynamic Table' } 20 | }, 21 | { 22 | path: 'drag-table', 23 | component: () => import('@/views/table/drag-table'), 24 | name: 'DragTable', 25 | meta: { title: 'Drag Table' } 26 | }, 27 | { 28 | path: 'inline-edit-table', 29 | component: () => import('@/views/table/inline-edit-table'), 30 | name: 'InlineEditTable', 31 | meta: { title: 'Inline Edit' } 32 | }, 33 | { 34 | path: 'complex-table', 35 | component: () => import('@/views/table/complex-table'), 36 | name: 'ComplexTable', 37 | meta: { title: 'Complex Table' } 38 | } 39 | ] 40 | } 41 | export default tableRouter 42 | -------------------------------------------------------------------------------- /admin/src/views/qiniu/upload.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 42 | -------------------------------------------------------------------------------- /admin/src/views/excel/upload-excel.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 43 | -------------------------------------------------------------------------------- /admin/src/views/components-demo/drag-select.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 44 | -------------------------------------------------------------------------------- /admin/src/icons/svg/language.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/layout/components/AppMain.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 24 | 25 | 49 | 50 | 58 | -------------------------------------------------------------------------------- /admin/tests/unit/utils/validate.spec.js: -------------------------------------------------------------------------------- 1 | import { validUsername, validURL, validLowerCase, validUpperCase, validAlphabets } from '@/utils/validate.js' 2 | describe('Utils:validate', () => { 3 | it('validUsername', () => { 4 | expect(validUsername('admin')).toBe(true) 5 | expect(validUsername('editor')).toBe(true) 6 | expect(validUsername('xxxx')).toBe(false) 7 | }) 8 | it('validURL', () => { 9 | expect(validURL('https://github.com/PanJiaChen/vue-element-admin')).toBe(true) 10 | expect(validURL('http://github.com/PanJiaChen/vue-element-admin')).toBe(true) 11 | expect(validURL('github.com/PanJiaChen/vue-element-admin')).toBe(false) 12 | }) 13 | it('validLowerCase', () => { 14 | expect(validLowerCase('abc')).toBe(true) 15 | expect(validLowerCase('Abc')).toBe(false) 16 | expect(validLowerCase('123abc')).toBe(false) 17 | }) 18 | it('validUpperCase', () => { 19 | expect(validUpperCase('ABC')).toBe(true) 20 | expect(validUpperCase('Abc')).toBe(false) 21 | expect(validUpperCase('123ABC')).toBe(false) 22 | }) 23 | it('validAlphabets', () => { 24 | expect(validAlphabets('ABC')).toBe(true) 25 | expect(validAlphabets('Abc')).toBe(true) 26 | expect(validAlphabets('123aBC')).toBe(false) 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /server/generate/proto_makefile: -------------------------------------------------------------------------------- 1 | NAME := caoguo 2 | 3 | BUILDSHELLFILE :=`ls ../apidoc/proto/$(NAME)/*.proto | cut -d'/' -f5` 4 | COMMSHELLFILE :=`ls ../apidoc/proto/common/*.proto | cut -d'/' -f5` 5 | 6 | gen_proto: gen_build gen_base 7 | clean_proto: 8 | rm -f rpc/common/*.pb.go 9 | gen_build:# 自定义注册 10 | @mkdir -p rpc/$(NAME) 11 | @echo "gen_build proto" 12 | @rm -f rpc/$(NAME)/*.pb.go 13 | @rm -f rpc/$(NAME)/*.pb.gmsec.go 14 | @for file in $(BUILDSHELLFILE); do \ 15 | echo build $$file; \ 16 | protoc --proto_path="../apidoc/proto/" --gmsec_out=plugins=gmsec:./ $(NAME)/$$file; \ 17 | done; 18 | @sed -i 's/,omitempty//g' ./rpc/$(NAME)/*.pb.go #开始取消json omitempty 19 | cp -rf ./rpc/$(NAME)/ ../rpc/ #子目录向父目录拷贝 20 | @sed -i 's#common "rpc/common"#common "$(NAME)/rpc/common"#g' ./rpc/$(NAME)/*.go #开始替换common包 21 | 22 | gen_base:# 基础库 23 | @mkdir -p ../rpc/common 24 | @echo "gen proto" 25 | @rm -f rpc/common/*.pb.go 26 | @rm -f rpc/common/*.pb.gmsec.go 27 | @for file in $(COMMSHELLFILE); do \ 28 | echo base $$file; \ 29 | protoc --proto_path="../apidoc/proto/" --gmsec_out=plugins=gmsec:../ common/$$file; \ 30 | done; 31 | @sed -i 's/,omitempty//g' ../rpc/common/*.pb.go #开始取消json omitempty 32 | cp -rf ../rpc/common/ ./rpc/ #父目录向当前目录拷贝 33 | 34 | 35 | -------------------------------------------------------------------------------- /admin/src/views/profile/components/Timeline.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 44 | -------------------------------------------------------------------------------- /admin/src/icons/svg/eye-open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/src/utils/open-window.js: -------------------------------------------------------------------------------- 1 | /** 2 | *Created by PanJiaChen on 16/11/29. 3 | * @param {Sting} url 4 | * @param {Sting} title 5 | * @param {Number} w 6 | * @param {Number} h 7 | */ 8 | export default function openWindow(url, title, w, h) { 9 | // Fixes dual-screen position Most browsers Firefox 10 | const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left 11 | const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top 12 | 13 | const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width 14 | const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height 15 | 16 | const left = ((width / 2) - (w / 2)) + dualScreenLeft 17 | const top = ((height / 2) - (h / 2)) + dualScreenTop 18 | const newWindow = window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left) 19 | 20 | // Puts focus on the newWindow 21 | if (window.focus) { 22 | newWindow.focus() 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /server/internal/service/file/file.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | import ( 4 | "caoguo/internal/config" 5 | "mime/multipart" 6 | "net/http" 7 | 8 | "github.com/xxjwxc/public/mylog" 9 | 10 | "github.com/xxjwxc/public/message" 11 | 12 | "github.com/xxjwxc/public/myfile" 13 | 14 | "github.com/gin-gonic/gin" 15 | ) 16 | 17 | // Upload file deal 18 | type Upload struct { 19 | } 20 | 21 | // UploadMult 上传文件 多个 22 | // @Router /upload [post] 23 | func (u *Upload) UploadMult(c *gin.Context) { 24 | op := myfile.NewWebFile("file/image/", true) 25 | // Multipart form 26 | form, _ := c.MultipartForm() 27 | if form == nil { 28 | mylog.ErrorString("/upload is empty") 29 | msg := message.GetErrorMsg(message.ParameterInvalid) 30 | c.JSON(http.StatusBadRequest, msg) 31 | return 32 | } 33 | 34 | var files []*multipart.FileHeader 35 | for _, v := range form.File { 36 | files = append(files, v...) 37 | } 38 | 39 | //op := myfile.NewWebFile("file/image/", true) 40 | result := make([]string, 0, len(files)) 41 | for _, file := range files { 42 | src, err := op.SaveOne(file) 43 | if err != nil { 44 | return 45 | } 46 | result = append(result, config.GetFileHost()+src) 47 | } 48 | 49 | msg := message.GetSuccessMsg() 50 | msg.Data = result 51 | 52 | c.JSON(http.StatusOK, msg) 53 | } 54 | -------------------------------------------------------------------------------- /admin/src/views/guide/steps.js: -------------------------------------------------------------------------------- 1 | const steps = [ 2 | { 3 | element: '#hamburger-container', 4 | popover: { 5 | title: 'Hamburger', 6 | description: 'Open && Close sidebar', 7 | position: 'bottom' 8 | } 9 | }, 10 | { 11 | element: '#breadcrumb-container', 12 | popover: { 13 | title: 'Breadcrumb', 14 | description: 'Indicate the current page location', 15 | position: 'bottom' 16 | } 17 | }, 18 | { 19 | element: '#header-search', 20 | popover: { 21 | title: 'Page Search', 22 | description: 'Page search, quick navigation', 23 | position: 'left' 24 | } 25 | }, 26 | { 27 | element: '#screenfull', 28 | popover: { 29 | title: 'Screenfull', 30 | description: 'Set the page into fullscreen', 31 | position: 'left' 32 | } 33 | }, 34 | { 35 | element: '#size-select', 36 | popover: { 37 | title: 'Switch Size', 38 | description: 'Switch the system size', 39 | position: 'left' 40 | } 41 | }, 42 | { 43 | element: '#tags-view-container', 44 | popover: { 45 | title: 'Tags view', 46 | description: 'The history of the page you visited', 47 | position: 'bottom' 48 | }, 49 | padding: 0 50 | } 51 | ] 52 | 53 | export default steps 54 | -------------------------------------------------------------------------------- /admin/tests/unit/utils/parseTime.spec.js: -------------------------------------------------------------------------------- 1 | import { parseTime } from '@/utils/index.js' 2 | 3 | describe('Utils:parseTime', () => { 4 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" 5 | it('timestamp', () => { 6 | expect(parseTime(d)).toBe('2018-07-13 17:54:01') 7 | }) 8 | 9 | it('timestamp string', () => { 10 | expect(parseTime((d + ''))).toBe('2018-07-13 17:54:01') 11 | }) 12 | 13 | it('ten digits timestamp', () => { 14 | expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01') 15 | }) 16 | it('new Date', () => { 17 | expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01') 18 | }) 19 | it('format', () => { 20 | expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') 21 | expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') 22 | expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') 23 | }) 24 | it('get the day of the week', () => { 25 | expect(parseTime(d, '{a}')).toBe('五') // 星期五 26 | }) 27 | it('get the day of the week', () => { 28 | expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日 29 | }) 30 | it('empty argument', () => { 31 | expect(parseTime()).toBeNull() 32 | }) 33 | 34 | it('null', () => { 35 | expect(parseTime(null)).toBeNull() 36 | }) 37 | }) 38 | -------------------------------------------------------------------------------- /admin/src/views/example/components/Dropdown/Platform.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 47 | -------------------------------------------------------------------------------- /admin/mock/remote-search.js: -------------------------------------------------------------------------------- 1 | const Mock = require('mockjs') 2 | 3 | const NameList = [] 4 | const count = 100 5 | 6 | for (let i = 0; i < count; i++) { 7 | NameList.push(Mock.mock({ 8 | name: '@first' 9 | })) 10 | } 11 | NameList.push({ name: 'mock-Pan' }) 12 | 13 | module.exports = [ 14 | // username search 15 | { 16 | url: '/vue-element-admin/search/user', 17 | type: 'get', 18 | response: config => { 19 | const { name } = config.query 20 | const mockNameList = NameList.filter(item => { 21 | const lowerCaseName = item.name.toLowerCase() 22 | return !(name && lowerCaseName.indexOf(name.toLowerCase()) < 0) 23 | }) 24 | return { 25 | code: 20000, 26 | data: { items: mockNameList } 27 | } 28 | } 29 | }, 30 | 31 | // transaction list 32 | { 33 | url: '/vue-element-admin/transaction/list', 34 | type: 'get', 35 | response: _ => { 36 | return { 37 | code: 20000, 38 | data: { 39 | total: 20, 40 | 'items|20': [{ 41 | order_no: '@guid()', 42 | timestamp: +Mock.Random.date('T'), 43 | username: '@name()', 44 | price: '@float(1000, 15000, 0, 2)', 45 | 'status|1': ['success', 'pending'] 46 | }] 47 | } 48 | } 49 | } 50 | } 51 | ] 52 | -------------------------------------------------------------------------------- /admin/src/components/Screenfull/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 50 | 51 | 61 | -------------------------------------------------------------------------------- /server/internal/service/oplog/common.go: -------------------------------------------------------------------------------- 1 | package oplog 2 | 3 | import ( 4 | "caoguo/internal/model" 5 | "time" 6 | 7 | "caoguo/internal/core" 8 | 9 | "github.com/xxjwxc/public/tools" 10 | ) 11 | 12 | // AddOpLog 添加日志数据 13 | func AddOpLog(operator, receive, topic, bundle, pid, ipAddr string, num0 int, Attach0 string) bool { 14 | var info model.OpLogTbl 15 | info.Operator = operator 16 | info.Receive = receive 17 | info.CreateTime = time.Now() 18 | info.Topic = topic 19 | info.Bundle = bundle 20 | info.Pid = pid 21 | info.IPAddr = ipAddr 22 | info.Num0 = num0 23 | info.Attach0 = Attach0 24 | 25 | return OpLogBaseAdd(&info) 26 | } 27 | 28 | // OpLogBaseAdd 添加日志数据 29 | func OpLogBaseAdd(info *model.OpLogTbl) bool { 30 | info.CreateTime = time.Now() //默认时间 31 | core.Dao.GetDBw().Create(info) 32 | return true 33 | } 34 | 35 | // GetWxLog 1:收藏 2:点赞 3:订单 0:全部 36 | func GetWxLog(openID string, action int) (result []*Wx_user_log_view) { 37 | orm := core.Dao.GetDBw() 38 | if action == 0 { //全部 39 | orm.Where("open_id = ?", openID).Order("create_time desc").Find(&result) 40 | } else { 41 | orm.Where("open_id = ? and type = ?", openID, action).Order("create_time desc").Find(&result) 42 | } 43 | if len(result) > 0 { 44 | for _, v := range result { 45 | tools.JSONEncode(v.Pic_url_str, &v.Pic_url) 46 | } 47 | } 48 | return 49 | } 50 | -------------------------------------------------------------------------------- /admin/mock/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} url 3 | * @returns {Object} 4 | */ 5 | function param2Obj(url) { 6 | const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') 7 | if (!search) { 8 | return {} 9 | } 10 | const obj = {} 11 | const searchArr = search.split('&') 12 | searchArr.forEach(v => { 13 | const index = v.indexOf('=') 14 | if (index !== -1) { 15 | const name = v.substring(0, index) 16 | const val = v.substring(index + 1, v.length) 17 | obj[name] = val 18 | } 19 | }) 20 | return obj 21 | } 22 | 23 | /** 24 | * This is just a simple version of deep copy 25 | * Has a lot of edge cases bug 26 | * If you want to use a perfect deep copy, use lodash's _.cloneDeep 27 | * @param {Object} source 28 | * @returns {Object} 29 | */ 30 | function deepClone(source) { 31 | if (!source && typeof source !== 'object') { 32 | throw new Error('error arguments', 'deepClone') 33 | } 34 | const targetObj = source.constructor === Array ? [] : {} 35 | Object.keys(source).forEach(keys => { 36 | if (source[keys] && typeof source[keys] === 'object') { 37 | targetObj[keys] = deepClone(source[keys]) 38 | } else { 39 | targetObj[keys] = source[keys] 40 | } 41 | }) 42 | return targetObj 43 | } 44 | 45 | module.exports = { 46 | param2Obj, 47 | deepClone 48 | } 49 | -------------------------------------------------------------------------------- /admin/src/directive/el-table/adaptive.js: -------------------------------------------------------------------------------- 1 | import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event' 2 | 3 | /** 4 | * How to use 5 | * ... 6 | * el-table height is must be set 7 | * bottomOffset: 30(default) // The height of the table from the bottom of the page. 8 | */ 9 | 10 | const doResize = (el, binding, vnode) => { 11 | const { componentInstance: $table } = vnode 12 | 13 | const { value } = binding 14 | 15 | if (!$table.height) { 16 | throw new Error(`el-$table must set the height. Such as height='100px'`) 17 | } 18 | const bottomOffset = (value && value.bottomOffset) || 30 19 | 20 | if (!$table) return 21 | 22 | const height = window.innerHeight - el.getBoundingClientRect().top - bottomOffset 23 | $table.layout.setHeight(height) 24 | $table.doLayout() 25 | } 26 | 27 | export default { 28 | bind(el, binding, vnode) { 29 | el.resizeListener = () => { 30 | doResize(el, binding, vnode) 31 | } 32 | // parameter 1 is must be "Element" type 33 | addResizeListener(window.document.body, el.resizeListener) 34 | }, 35 | inserted(el, binding, vnode) { 36 | doResize(el, binding, vnode) 37 | }, 38 | unbind(el) { 39 | removeResizeListener(window.document.body, el.resizeListener) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /admin/src/components/Hamburger/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 32 | 33 | 45 | -------------------------------------------------------------------------------- /server/internal/service/weixin/def.go: -------------------------------------------------------------------------------- 1 | package weixin 2 | 3 | const ( 4 | cacheSessionkey = "session_key" 5 | cacheWxUser = "wx_user_cache" 6 | ) 7 | 8 | // OauthReq 微信授权请求信息 9 | type OauthReq struct { 10 | Jscode string `json:"jscode" binding:"required"` // 微信端jscode 11 | } 12 | 13 | // OauthResp 微信授权返回信息 14 | type OauthResp struct { 15 | SessionID string `json:"session_id"` // 用户sessionid 用于当前交互使用 16 | OpenID string `json:"open_id"` // openid 17 | OverdueTime int64 `json:"overdue_time"` // 逾期时间点(时间戳) 18 | } 19 | 20 | // WxSessionKey ... 21 | type WxSessionKey struct { 22 | Openid string `json:"openid"` 23 | SessionKey string `json:"session_key"` 24 | Unionid string `json:"unionid"` 25 | } 26 | 27 | // BaseSessionID 基础类型(sessionid) 28 | type BaseSessionID struct { 29 | SessionID string `json:"session_id" binding:"required"` 30 | } 31 | 32 | // WxUserinfo 用户信息 33 | type WxUserinfo struct { 34 | NickName string `json:"nickName"` //用户昵称 35 | AvatarURL string `json:"avatarUrl"` //用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 36 | Gender int `json:"gender"` //用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 37 | City string `json:"city"` //用户所在城市 38 | Province string `json:"province"` //用户所在省份 39 | Country string `json:"country"` //用户所在国家 40 | Language string `json:"language"` //用户的语言,简体中文为zh_CN 41 | } 42 | -------------------------------------------------------------------------------- /uniapp/commcn/pages/money/paySuccess.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 25 | 26 | 63 | -------------------------------------------------------------------------------- /admin/src/icons/svg/404.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/internal/service/login/def.go: -------------------------------------------------------------------------------- 1 | package login 2 | 3 | import ( 4 | "github.com/xxjwxc/public/message" 5 | ) 6 | 7 | // LoginReq 登陆请求 8 | type LoginReq struct { 9 | UserName string `json:"username" binding:"required"` // 用户名 10 | Password string `json:"password" binding:"required"` // 密码(用户输入的md5值,大写) 11 | } 12 | 13 | // RefreshReq reflashToken 14 | type RefreshReq struct { 15 | Token string `json:"refresh_token"` // token 16 | } 17 | 18 | type ReqChangepwd struct { 19 | AccessToken string `json:"access_token"` //access_token 20 | UserName string `json:"username"` //用户名 21 | Password string `json:"password"` //新密码 22 | } 23 | 24 | // LoginTokenMsg ... 25 | type LoginTokenMsg struct { 26 | message.MessageBody 27 | Data *LoginToken `json:"data,omitempty"` 28 | } 29 | 30 | // LoginToken ... 31 | type LoginToken struct { 32 | AccessToken string `json:"access_token,omitempty"` //access_token 33 | ExpireTime string `json:"expire_time,omitempty"` // 34 | RefreshToken string `json:"refresh_token,omitempty"` // 35 | } 36 | 37 | // 38 | // type Req_doaction struct { 39 | // mysign.Sing_head 40 | // UserName string `json:"username"` //用户名 41 | // Password string `json:"password"` //密码 42 | // Verify string `json:"verify,omitempty"` //验证码 43 | // Flag int `json:"flag,omitempty"` //1:注册,2:修改密码 44 | // Bundleid string `json:"bundleid,omitempty"` //bundleid 45 | // } 46 | -------------------------------------------------------------------------------- /admin/plop-templates/view/prompt.js: -------------------------------------------------------------------------------- 1 | const { notEmpty } = require('../utils.js') 2 | 3 | module.exports = { 4 | description: 'generate a view', 5 | prompts: [{ 6 | type: 'input', 7 | name: 'name', 8 | message: 'view name please', 9 | validate: notEmpty('name') 10 | }, 11 | { 12 | type: 'checkbox', 13 | name: 'blocks', 14 | message: 'Blocks:', 15 | choices: [{ 16 | name: '