├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── admin ├── .editorconfig ├── .env.development ├── .env.production ├── .env.staging ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── LICENSE ├── README.es.md ├── README.ja.md ├── README.md ├── README.zh-CN.md ├── babel.config.js ├── build │ └── index.js ├── jest.config.js ├── jsconfig.json ├── mock │ ├── article.js │ ├── index.js │ ├── mock-server.js │ ├── remote-search.js │ ├── role │ │ ├── index.js │ │ └── routes.js │ ├── user.js │ └── utils.js ├── package.json ├── plop-templates │ ├── component │ │ ├── index.hbs │ │ └── prompt.js │ ├── store │ │ ├── index.hbs │ │ └── prompt.js │ ├── utils.js │ └── view │ │ ├── index.hbs │ │ └── prompt.js ├── plopfile.js ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── api │ │ ├── article.js │ │ ├── qiniu.js │ │ ├── remote-search.js │ │ ├── role.js │ │ └── user.js │ ├── assets │ │ ├── 401_images │ │ │ └── 401.gif │ │ ├── 404_images │ │ │ ├── 404.png │ │ │ └── 404_cloud.png │ │ └── custom-theme │ │ │ ├── fonts │ │ │ ├── element-icons.ttf │ │ │ └── element-icons.woff │ │ │ └── index.css │ ├── components │ │ ├── BackToTop │ │ │ └── index.vue │ │ ├── Breadcrumb │ │ │ └── index.vue │ │ ├── Charts │ │ │ ├── Keyboard.vue │ │ │ ├── LineMarker.vue │ │ │ ├── MixChart.vue │ │ │ └── mixins │ │ │ │ └── resize.js │ │ ├── DndList │ │ │ └── index.vue │ │ ├── DragSelect │ │ │ └── index.vue │ │ ├── Dropzone │ │ │ └── index.vue │ │ ├── ErrorLog │ │ │ └── index.vue │ │ ├── GithubCorner │ │ │ └── index.vue │ │ ├── Hamburger │ │ │ └── index.vue │ │ ├── HeaderSearch │ │ │ └── index.vue │ │ ├── ImageCropper │ │ │ ├── index.vue │ │ │ └── utils │ │ │ │ ├── data2blob.js │ │ │ │ ├── effectRipple.js │ │ │ │ ├── language.js │ │ │ │ └── mimes.js │ │ ├── JsonEditor │ │ │ └── index.vue │ │ ├── Kanban │ │ │ └── index.vue │ │ ├── MDinput │ │ │ └── index.vue │ │ ├── MarkdownEditor │ │ │ ├── default-options.js │ │ │ └── index.vue │ │ ├── Pagination │ │ │ └── index.vue │ │ ├── PanThumb │ │ │ └── index.vue │ │ ├── RightPanel │ │ │ └── index.vue │ │ ├── Screenfull │ │ │ └── index.vue │ │ ├── Share │ │ │ └── DropdownMenu.vue │ │ ├── SizeSelect │ │ │ └── index.vue │ │ ├── Sticky │ │ │ └── index.vue │ │ ├── SvgIcon │ │ │ └── index.vue │ │ ├── TextHoverEffect │ │ │ └── Mallki.vue │ │ ├── ThemePicker │ │ │ └── index.vue │ │ ├── Tinymce │ │ │ ├── components │ │ │ │ └── EditorImage.vue │ │ │ ├── dynamicLoadScript.js │ │ │ ├── index.vue │ │ │ ├── plugins.js │ │ │ └── toolbar.js │ │ ├── Upload │ │ │ ├── SingleImage.vue │ │ │ ├── SingleImage2.vue │ │ │ └── SingleImage3.vue │ │ └── UploadExcel │ │ │ └── index.vue │ ├── directive │ │ ├── clipboard │ │ │ ├── clipboard.js │ │ │ └── index.js │ │ ├── el-drag-dialog │ │ │ ├── drag.js │ │ │ └── index.js │ │ ├── el-table │ │ │ ├── adaptive.js │ │ │ └── index.js │ │ ├── permission │ │ │ ├── index.js │ │ │ └── permission.js │ │ ├── sticky.js │ │ └── waves │ │ │ ├── index.js │ │ │ ├── waves.css │ │ │ └── waves.js │ ├── filters │ │ └── index.js │ ├── icons │ │ ├── index.js │ │ └── svg │ │ │ ├── 404.svg │ │ │ ├── bug.svg │ │ │ ├── chart.svg │ │ │ ├── clipboard.svg │ │ │ ├── component.svg │ │ │ ├── dashboard.svg │ │ │ ├── documentation.svg │ │ │ ├── drag.svg │ │ │ ├── edit.svg │ │ │ ├── education.svg │ │ │ ├── email.svg │ │ │ ├── example.svg │ │ │ ├── excel.svg │ │ │ ├── exit-fullscreen.svg │ │ │ ├── eye-open.svg │ │ │ ├── eye.svg │ │ │ ├── form.svg │ │ │ ├── fullscreen.svg │ │ │ ├── guide.svg │ │ │ ├── icon.svg │ │ │ ├── international.svg │ │ │ ├── language.svg │ │ │ ├── link.svg │ │ │ ├── list.svg │ │ │ ├── lock.svg │ │ │ ├── message.svg │ │ │ ├── money.svg │ │ │ ├── nested.svg │ │ │ ├── password.svg │ │ │ ├── pdf.svg │ │ │ ├── people.svg │ │ │ ├── peoples.svg │ │ │ ├── qq.svg │ │ │ ├── search.svg │ │ │ ├── shopping.svg │ │ │ ├── size.svg │ │ │ ├── skill.svg │ │ │ ├── star.svg │ │ │ ├── tab.svg │ │ │ ├── table.svg │ │ │ ├── theme.svg │ │ │ ├── tree-table.svg │ │ │ ├── tree.svg │ │ │ ├── user.svg │ │ │ ├── wechat.svg │ │ │ └── zip.svg │ ├── layout │ │ ├── components │ │ │ ├── AppMain.vue │ │ │ ├── Navbar.vue │ │ │ ├── Settings │ │ │ │ └── index.vue │ │ │ ├── Sidebar │ │ │ │ ├── FixiOSBug.js │ │ │ │ ├── Item.vue │ │ │ │ ├── Link.vue │ │ │ │ ├── Logo.vue │ │ │ │ ├── SidebarItem.vue │ │ │ │ └── index.vue │ │ │ ├── TagsView │ │ │ │ ├── ScrollPane.vue │ │ │ │ └── index.vue │ │ │ └── index.js │ │ ├── index.vue │ │ └── mixin │ │ │ └── ResizeHandler.js │ ├── main.js │ ├── permission.js │ ├── router │ │ ├── index.js │ │ └── modules │ │ │ ├── charts.js │ │ │ ├── components.js │ │ │ ├── nested.js │ │ │ └── table.js │ ├── settings.js │ ├── store │ │ ├── getters.js │ │ ├── index.js │ │ └── modules │ │ │ ├── app.js │ │ │ ├── errorLog.js │ │ │ ├── permission.js │ │ │ ├── settings.js │ │ │ ├── tagsView.js │ │ │ └── user.js │ ├── styles │ │ ├── btn.scss │ │ ├── element-ui.scss │ │ ├── element-variables.scss │ │ ├── index.scss │ │ ├── mixin.scss │ │ ├── sidebar.scss │ │ ├── transition.scss │ │ └── variables.scss │ ├── utils │ │ ├── auth.js │ │ ├── clipboard.js │ │ ├── error-log.js │ │ ├── get-page-title.js │ │ ├── index.js │ │ ├── open-window.js │ │ ├── permission.js │ │ ├── request.js │ │ ├── scroll-to.js │ │ └── validate.js │ ├── vendor │ │ ├── Export2Excel.js │ │ └── Export2Zip.js │ └── views │ │ ├── charts │ │ ├── keyboard.vue │ │ ├── line.vue │ │ └── mix-chart.vue │ │ ├── clipboard │ │ └── index.vue │ │ ├── components-demo │ │ ├── avatar-upload.vue │ │ ├── back-to-top.vue │ │ ├── count-to.vue │ │ ├── dnd-list.vue │ │ ├── drag-dialog.vue │ │ ├── drag-kanban.vue │ │ ├── drag-select.vue │ │ ├── dropzone.vue │ │ ├── json-editor.vue │ │ ├── markdown.vue │ │ ├── mixin.vue │ │ ├── split-pane.vue │ │ ├── sticky.vue │ │ └── tinymce.vue │ │ ├── dashboard │ │ ├── admin │ │ │ ├── components │ │ │ │ ├── BarChart.vue │ │ │ │ ├── BoxCard.vue │ │ │ │ ├── LineChart.vue │ │ │ │ ├── PanelGroup.vue │ │ │ │ ├── PieChart.vue │ │ │ │ ├── RaddarChart.vue │ │ │ │ ├── TodoList │ │ │ │ │ ├── Todo.vue │ │ │ │ │ ├── index.scss │ │ │ │ │ └── index.vue │ │ │ │ ├── TransactionTable.vue │ │ │ │ └── mixins │ │ │ │ │ └── resize.js │ │ │ └── index.vue │ │ ├── editor │ │ │ └── index.vue │ │ └── index.vue │ │ ├── documentation │ │ └── index.vue │ │ ├── error-log │ │ ├── components │ │ │ ├── ErrorTestA.vue │ │ │ └── ErrorTestB.vue │ │ └── index.vue │ │ ├── error-page │ │ ├── 401.vue │ │ └── 404.vue │ │ ├── example │ │ ├── components │ │ │ ├── ArticleDetail.vue │ │ │ ├── Dropdown │ │ │ │ ├── Comment.vue │ │ │ │ ├── Platform.vue │ │ │ │ ├── SourceUrl.vue │ │ │ │ └── index.js │ │ │ └── Warning.vue │ │ ├── create.vue │ │ ├── edit.vue │ │ └── list.vue │ │ ├── excel │ │ ├── components │ │ │ ├── AutoWidthOption.vue │ │ │ ├── BookTypeOption.vue │ │ │ └── FilenameOption.vue │ │ ├── export-excel.vue │ │ ├── merge-header.vue │ │ ├── select-excel.vue │ │ └── upload-excel.vue │ │ ├── guide │ │ ├── index.vue │ │ └── steps.js │ │ ├── icons │ │ ├── element-icons.js │ │ ├── index.vue │ │ └── svg-icons.js │ │ ├── login │ │ ├── auth-redirect.vue │ │ ├── components │ │ │ └── SocialSignin.vue │ │ └── index.vue │ │ ├── nested │ │ ├── menu1 │ │ │ ├── index.vue │ │ │ ├── menu1-1 │ │ │ │ └── index.vue │ │ │ ├── menu1-2 │ │ │ │ ├── index.vue │ │ │ │ ├── menu1-2-1 │ │ │ │ │ └── index.vue │ │ │ │ └── menu1-2-2 │ │ │ │ │ └── index.vue │ │ │ └── menu1-3 │ │ │ │ └── index.vue │ │ └── menu2 │ │ │ └── index.vue │ │ ├── pdf │ │ ├── content.js │ │ ├── download.vue │ │ └── index.vue │ │ ├── permission │ │ ├── components │ │ │ └── SwitchRoles.vue │ │ ├── directive.vue │ │ ├── page.vue │ │ └── role.vue │ │ ├── profile │ │ ├── components │ │ │ ├── Account.vue │ │ │ ├── Activity.vue │ │ │ ├── Timeline.vue │ │ │ └── UserCard.vue │ │ └── index.vue │ │ ├── qiniu │ │ └── upload.vue │ │ ├── redirect │ │ └── index.vue │ │ ├── tab │ │ ├── components │ │ │ └── TabPane.vue │ │ └── index.vue │ │ ├── table │ │ ├── complex-table.vue │ │ ├── drag-table.vue │ │ ├── dynamic-table │ │ │ ├── components │ │ │ │ ├── FixedThead.vue │ │ │ │ └── UnfixedThead.vue │ │ │ └── index.vue │ │ └── inline-edit-table.vue │ │ ├── theme │ │ └── index.vue │ │ └── zip │ │ └── index.vue ├── tests │ └── unit │ │ ├── .eslintrc.js │ │ ├── components │ │ ├── Hamburger.spec.js │ │ └── SvgIcon.spec.js │ │ └── utils │ │ ├── formatTime.spec.js │ │ ├── param2Obj.spec.js │ │ ├── parseTime.spec.js │ │ └── validate.spec.js └── vue.config.js ├── apidoc └── proto │ ├── caoguo │ ├── product.proto │ └── weixin.proto │ └── common │ └── common_public.proto ├── caoguo └── rpc │ └── common │ └── common_public.pb.go ├── cert ├── 1600841165_20200807_cert.zip ├── 1600841165_20200807_cert │ ├── apiclient_cert.p12 │ ├── apiclient_cert.pem │ └── apiclient_key.pem ├── cert.zip ├── rootca.pem └── 配置.txt ├── 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 ├── mysql └── caoguo_tmp.sql ├── rpc ├── caoguo │ ├── product.pb.gmsec.go │ ├── product.pb.go │ ├── weixin.pb.gmsec.go │ ├── weixin.pb.go │ └── weixin │ │ ├── weixin.pb.gmsec.go │ │ └── weixin.pb.go ├── commcn │ ├── product.pb.gmsec.go │ ├── product.pb.go │ └── weixin │ │ ├── weixin.pb.gmsec.go │ │ └── weixin.pb.go └── common │ └── common_public.pb.go ├── server ├── .vscode │ └── settings.json ├── Makefile ├── conf │ ├── cert │ │ ├── apiclient_cert.pem │ │ ├── apiclient_key.pem │ │ └── rootca.pem │ ├── config.yml │ └── gen_router.data ├── docs │ ├── caoguo.json │ ├── markdown │ │ ├── Coupon.md │ │ ├── Dist.md │ │ ├── Login.md │ │ ├── Order.md │ │ ├── Product.md │ │ ├── Upload.md │ │ ├── User.md │ │ └── Weixin.md │ ├── swagger │ │ └── swagger.json │ └── 添加一个商品.md ├── generate │ └── proto_makefile ├── go.mod ├── go.sum ├── gogenerate.go ├── internal │ ├── api │ │ ├── context.go │ │ └── user.go │ ├── config │ │ ├── MyIni.go │ │ ├── common.go │ │ └── test_def.go │ ├── core │ │ └── dao.go │ ├── model │ │ ├── caoguo_dev.gen.address_tbl.go │ │ ├── caoguo_dev.gen.bill_address_tbl.go │ │ ├── caoguo_dev.gen.bill_coupon_tbl.go │ │ ├── caoguo_dev.gen.bill_deal_log_tbl.go │ │ ├── caoguo_dev.gen.bill_order_tbl.go │ │ ├── caoguo_dev.gen.bill_refund_tbl.go │ │ ├── caoguo_dev.gen.bill_tbl.go │ │ ├── caoguo_dev.gen.cart_tbl.go │ │ ├── caoguo_dev.gen.cart_tmp_tbl.go │ │ ├── caoguo_dev.gen.coupon_my_tbl.go │ │ ├── caoguo_dev.gen.coupon_tbl.go │ │ ├── caoguo_dev.gen.dist_order_tbl.go │ │ ├── caoguo_dev.gen.dist_userinfo_tbl.go │ │ ├── caoguo_dev.gen.email_notify_tbl.go │ │ ├── caoguo_dev.gen.favorite_tbl.go │ │ ├── caoguo_dev.gen.logistics_tbl.go │ │ ├── caoguo_dev.gen.op_log_tbl.go │ │ ├── caoguo_dev.gen.post_tbl.go │ │ ├── caoguo_dev.gen.product_ad_group_tbl.go │ │ ├── caoguo_dev.gen.product_ad_tbl.go │ │ ├── caoguo_dev.gen.product_info_tbl.go │ │ ├── caoguo_dev.gen.product_sku_price_tbl.go │ │ ├── caoguo_dev.gen.product_sku_tbl.go │ │ ├── caoguo_dev.gen.product_tbl.go │ │ ├── caoguo_dev.gen.product_type_tbl.go │ │ ├── caoguo_dev.gen.proposal_tbl.go │ │ ├── caoguo_dev.gen.shipment_tbl.go │ │ ├── caoguo_dev.gen.user_link_log_tbl.go │ │ ├── caoguo_dev.gen.user_link_tbl.go │ │ ├── caoguo_dev.gen.user_tbl.go │ │ ├── caoguo_dev.gen.wx_userinfo.go │ │ ├── caoguo_dev.go │ │ └── gen.base.go │ ├── routers │ │ ├── api_root.go │ │ └── gen_router.go │ └── service │ │ ├── coupon │ │ ├── admin.go │ │ ├── common.go │ │ └── coupon.go │ │ ├── dist │ │ ├── common.go │ │ └── dist.go │ │ ├── file │ │ └── file.go │ │ ├── history │ │ ├── common.go │ │ ├── def.go │ │ └── history.go │ │ ├── login │ │ ├── common.go │ │ ├── def.go │ │ ├── login.go │ │ └── oauth2.go │ │ ├── notify │ │ ├── common.go │ │ ├── def.go │ │ └── notify.go │ │ ├── oplog │ │ ├── common.go │ │ ├── def.go │ │ └── oplog.go │ │ ├── order │ │ ├── admin.go │ │ ├── common.go │ │ ├── order.go │ │ ├── ordertrack.go │ │ └── sql.go │ │ ├── product │ │ ├── admin.go │ │ ├── common.go │ │ ├── def.go │ │ ├── home.go │ │ └── product.go │ │ ├── user │ │ └── user.go │ │ └── weixin │ │ ├── common.go │ │ ├── def.go │ │ └── weixin.go ├── main.go ├── rpc │ ├── caoguo │ │ ├── product.pb.gmsec.go │ │ ├── product.pb.go │ │ └── weixin │ │ │ ├── weixin.pb.gmsec.go │ │ │ └── weixin.pb.go │ └── common │ │ └── common_public.pb.go ├── tools │ ├── config.yml │ └── gormt.exe └── weixin │ ├── weixin.pb.gmsec.go │ └── weixin.pb.go └── uniapp └── commcn ├── App.vue ├── Json.js ├── components ├── empty.vue ├── jp-select │ └── jp-select.vue ├── l-modal.vue ├── mix-list-cell.vue ├── mix-loading │ └── mix-loading.vue ├── share.vue ├── uni-icons │ ├── icons.js │ └── uni-icons.vue ├── uni-load-more │ └── uni-load-more.vue ├── uni-number-box-new.vue ├── uni-number-box.vue ├── uni-rate │ └── uni-rate.vue ├── upload-images.vue ├── xinyu-logistics │ └── xinyu-logistics.vue └── zz-prompt │ ├── README.md │ └── index.vue ├── main.js ├── manifest.json ├── pages.json ├── pages ├── address │ ├── address.vue │ └── addressManage.vue ├── admin │ ├── afterMsg.vue │ └── index.vue ├── cart │ └── cart.vue ├── category │ └── category.vue ├── coupon │ ├── getCoupon.vue │ └── myCoupon.vue ├── detail │ └── detail.vue ├── favorite │ └── favorite.vue ├── feedback │ ├── feedback.vue │ └── feedbacksystem.vue ├── index │ └── index.vue ├── logistics │ └── logistics.vue ├── money │ ├── pay.vue │ └── paySuccess.vue ├── notice │ └── notice.vue ├── order │ ├── createOrder.vue │ └── order.vue ├── product │ ├── list.vue │ └── product.vue ├── public │ └── login.vue ├── set │ └── set.vue ├── user │ └── user.vue └── userinfo │ └── userinfo.vue ├── static ├── arc.png ├── emptyCart.jpg ├── errorImage.jpg ├── missing-face.png ├── select.png ├── selected.png ├── tab-cart-current.png ├── tab-cart.png ├── tab-cate-current.png ├── tab-cate.png ├── tab-home-current.png ├── tab-home.png ├── tab-my-current.png ├── tab-my.png ├── temp │ ├── ad1.jpg │ ├── c1.png │ ├── c2.png │ ├── c3.png │ ├── c4.png │ ├── c5.png │ ├── c6.png │ ├── c7.png │ ├── c8.png │ ├── h1.png │ ├── secskill-img.jpg │ ├── share_moment.png │ ├── share_qq.png │ ├── share_qqzone.png │ └── share_wechat.png ├── to.png ├── truetype.ttf ├── uni.ttf ├── uni.wxss ├── user-bg.jpg ├── vip-card-bg.png └── yticon.ttf ├── store └── index.js ├── uni.scss └── utils ├── md5.js └── server ├── admin.js ├── def.js ├── oauth.js ├── order.js └── product.js /.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 | -------------------------------------------------------------------------------- /.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/.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/.env.development: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'development' 3 | 4 | # base api 5 | VUE_APP_BASE_API = '/commcn/api/v1/' 6 | -------------------------------------------------------------------------------- /admin/.env.production: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'production' 3 | 4 | # base api 5 | VUE_APP_BASE_API = '/prod-api' 6 | 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /admin/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | src/assets 3 | public 4 | dist 5 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/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/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | }, 8 | "exclude": ["node_modules", "dist"] 9 | } -------------------------------------------------------------------------------- /admin/mock/index.js: -------------------------------------------------------------------------------- 1 | const Mock = require('mockjs') 2 | const { param2Obj } = require('./utils') 3 | 4 | const user = require('./user') 5 | const role = require('./role') 6 | const article = require('./article') 7 | const search = require('./remote-search') 8 | 9 | const mocks = [ 10 | ...user, 11 | ...role, 12 | ...article, 13 | ...search 14 | ] 15 | 16 | // for front mock 17 | // please use it cautiously, it will redefine XMLHttpRequest, 18 | // which will cause many of your third-party libraries to be invalidated(like progress event). 19 | function mockXHR() { 20 | // mock patch 21 | // https://github.com/nuysoft/Mock/issues/300 22 | Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send 23 | Mock.XHR.prototype.send = function() { 24 | if (this.custom.xhr) { 25 | this.custom.xhr.withCredentials = this.withCredentials || false 26 | 27 | if (this.responseType) { 28 | this.custom.xhr.responseType = this.responseType 29 | } 30 | } 31 | this.proxy_send(...arguments) 32 | } 33 | 34 | function XHR2ExpressReqWrap(respond) { 35 | return function(options) { 36 | let result = null 37 | if (respond instanceof Function) { 38 | const { body, type, url } = options 39 | // https://expressjs.com/en/4x/api.html#req 40 | result = respond({ 41 | method: type, 42 | body: JSON.parse(body), 43 | query: param2Obj(url) 44 | }) 45 | } else { 46 | result = respond 47 | } 48 | return Mock.mock(result) 49 | } 50 | } 51 | 52 | for (const i of mocks) { 53 | Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) 54 | } 55 | } 56 | 57 | module.exports = { 58 | mocks, 59 | mockXHR 60 | } 61 | -------------------------------------------------------------------------------- /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/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/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/plop-templates/component/prompt.js: -------------------------------------------------------------------------------- 1 | const { notEmpty } = require('../utils.js') 2 | 3 | module.exports = { 4 | description: 'generate vue component', 5 | prompts: [{ 6 | type: 'input', 7 | name: 'name', 8 | message: 'component name please', 9 | validate: notEmpty('name') 10 | }, 11 | { 12 | type: 'checkbox', 13 | name: 'blocks', 14 | message: 'Blocks:', 15 | choices: [{ 16 | name: '