├── README.md
├── admin
├── .env.development
├── .env.production
├── .gitignore
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── static
│ │ └── lib
│ │ ├── echarts
│ │ ├── dark.js
│ │ ├── echarts.min.js
│ │ └── shine.js
│ │ └── jsencrypt.min.js
├── src
│ ├── App.vue
│ ├── api
│ │ ├── common
│ │ │ ├── authorize.js
│ │ │ ├── index.js
│ │ │ ├── menu.js
│ │ │ └── messageCenter.js
│ │ ├── index.js
│ │ └── instance.js
│ ├── assets
│ │ ├── css
│ │ │ ├── common.scss
│ │ │ ├── reset.scss
│ │ │ └── variables.scss
│ │ └── images
│ │ │ ├── avatar.png
│ │ │ ├── beian2.png
│ │ │ ├── favicon.ico
│ │ │ ├── favicon.png
│ │ │ ├── login-bg.jpg
│ │ │ ├── security.png
│ │ │ ├── sprites-arrow-20.png
│ │ │ ├── sprites-common-20.png
│ │ │ ├── sprites-commons-30.png
│ │ │ ├── sprites-edit-20.png
│ │ │ ├── sprites-login-20.png
│ │ │ └── success.png
│ ├── components
│ │ ├── BaseInfo
│ │ │ └── index.vue
│ │ ├── Charts
│ │ │ ├── PieRnglike
│ │ │ │ └── index.vue
│ │ │ ├── chartColor.js
│ │ │ └── index.vue
│ │ ├── FileUploader
│ │ │ └── index.vue
│ │ ├── FormDialog
│ │ │ ├── Form
│ │ │ │ ├── FormItem.vue
│ │ │ │ └── index.vue
│ │ │ ├── index.js
│ │ │ └── main.vue
│ │ ├── PagerSelf
│ │ │ └── index.vue
│ │ ├── Pagination
│ │ │ └── index.vue
│ │ ├── TableColumnFilter
│ │ │ └── index.vue
│ │ ├── TableFilter
│ │ │ ├── SearchItem.vue
│ │ │ ├── components
│ │ │ │ ├── HSelect.vue
│ │ │ │ └── ZoneSelect
│ │ │ │ │ └── index.vue
│ │ │ └── index.vue
│ │ ├── TableMain
│ │ │ ├── TableItem.vue
│ │ │ ├── components
│ │ │ │ └── ContextMenu
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── main.vue
│ │ │ └── index.vue
│ │ └── layout
│ │ │ ├── EmptyLayout.vue
│ │ │ ├── components
│ │ │ ├── Breadcrumb.vue
│ │ │ ├── HeaderBar.vue
│ │ │ ├── LangSelect.vue
│ │ │ ├── MenuBar.vue
│ │ │ ├── MenuBarItem.vue
│ │ │ ├── MenuToggle
│ │ │ │ └── index.vue
│ │ │ ├── MessageIco.vue
│ │ │ ├── MyCollection.vue
│ │ │ ├── ServiceMenu.vue
│ │ │ └── UserInfo.vue
│ │ │ ├── index.vue
│ │ │ └── mixin
│ │ │ └── ResizeHandler.js
│ ├── filters
│ │ └── index.js
│ ├── main.js
│ ├── router
│ │ └── index.js
│ ├── store
│ │ ├── getters.js
│ │ ├── index.js
│ │ └── modules
│ │ │ ├── app.js
│ │ │ └── user.js
│ ├── utils
│ │ ├── cloudPlatform.js
│ │ ├── constant.js
│ │ ├── eventTracer.js
│ │ ├── index.js
│ │ ├── scrollTo.js
│ │ └── validate.js
│ └── views
│ │ ├── dashboard
│ │ ├── api
│ │ │ └── index.js
│ │ ├── router.js
│ │ └── views
│ │ │ └── index.vue
│ │ ├── errorPage
│ │ ├── 401.vue
│ │ ├── 403.vue
│ │ ├── 404.vue
│ │ └── permission.vue
│ │ ├── good
│ │ ├── api
│ │ │ ├── category.js
│ │ │ ├── good.js
│ │ │ └── index.js
│ │ ├── router.js
│ │ └── views
│ │ │ ├── category
│ │ │ └── index.vue
│ │ │ └── list
│ │ │ ├── edit.vue
│ │ │ └── index.vue
│ │ ├── login
│ │ ├── router.js
│ │ └── views
│ │ │ ├── Login.vue
│ │ │ └── particles.js
│ │ ├── merchant
│ │ ├── api
│ │ │ ├── index.js
│ │ │ └── merchant.js
│ │ ├── router.js
│ │ └── views
│ │ │ └── merchant
│ │ │ ├── detail.vue
│ │ │ └── index.vue
│ │ ├── order
│ │ ├── api
│ │ │ ├── index.js
│ │ │ └── order.js
│ │ ├── router.js
│ │ └── views
│ │ │ └── list
│ │ │ ├── detail.vue
│ │ │ └── index.vue
│ │ ├── setting
│ │ ├── router.js
│ │ └── views
│ │ │ ├── person
│ │ │ └── index.vue
│ │ │ └── shop
│ │ │ └── index.vue
│ │ └── system
│ │ ├── api
│ │ ├── file.js
│ │ ├── index.js
│ │ ├── log.js
│ │ ├── menu.js
│ │ ├── permission.js
│ │ ├── role.js
│ │ └── user.js
│ │ ├── router.js
│ │ └── views
│ │ ├── file
│ │ └── index.vue
│ │ ├── log
│ │ └── index.vue
│ │ ├── menu
│ │ └── index.vue
│ │ ├── permission
│ │ └── index.vue
│ │ ├── role
│ │ ├── index.vue
│ │ ├── roleMenu.vue
│ │ └── rolePermission.vue
│ │ └── user
│ │ └── index.vue
└── vue.config.js
├── eggjs-uniapp-shop.sql
├── server
├── .autod.conf.js
├── .eslintignore
├── .eslintrc
├── .github
│ └── workflows
│ │ └── nodejs.yml
├── .gitignore
├── .travis.yml
├── README.md
├── app
│ ├── config
│ │ ├── index.ts
│ │ └── permission.ts
│ ├── controller
│ │ ├── good
│ │ │ ├── category.ts
│ │ │ ├── home.ts
│ │ │ └── order.ts
│ │ ├── home.ts
│ │ ├── log
│ │ │ └── message.ts
│ │ ├── member
│ │ │ ├── address.ts
│ │ │ └── fav.ts
│ │ ├── merchant
│ │ │ └── index.ts
│ │ └── system
│ │ │ ├── file.ts
│ │ │ ├── menu.ts
│ │ │ ├── permission.ts
│ │ │ ├── req_log.ts
│ │ │ ├── role.ts
│ │ │ └── user.ts
│ ├── extend
│ │ ├── context.ts
│ │ └── helper.ts
│ ├── middleware
│ │ ├── admin_req_log.ts
│ │ ├── execption.ts
│ │ └── requireLogin.ts
│ ├── model
│ │ ├── Good.ts
│ │ ├── GoodCategory.ts
│ │ ├── GoodImage.ts
│ │ ├── GoodOrder.ts
│ │ ├── GoodOrderLine.ts
│ │ ├── GoodSpec.ts
│ │ ├── LogMessage.ts
│ │ ├── Merchant.ts
│ │ ├── SystemFile.ts
│ │ ├── SystemMenu.ts
│ │ ├── SystemPermission.ts
│ │ ├── SystemReqLog.ts
│ │ ├── SystemRole.ts
│ │ ├── SystemRoleMenu.ts
│ │ ├── SystemRolePermission.ts
│ │ ├── SystemUser.ts
│ │ ├── UserAddress.ts
│ │ └── UserFav.ts
│ ├── public
│ │ └── doc
│ │ │ ├── api_data.json
│ │ │ ├── api_project.json
│ │ │ ├── css
│ │ │ └── style.css
│ │ │ ├── fonts
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ └── glyphicons-halflings-regular.woff2
│ │ │ ├── img
│ │ │ └── favicon.ico
│ │ │ ├── index.html
│ │ │ └── vendor
│ │ │ ├── bootstrap.min.css
│ │ │ ├── path-to-regexp
│ │ │ └── LICENSE
│ │ │ └── prism.css
│ ├── router.ts
│ └── service
│ │ ├── good
│ │ ├── category.ts
│ │ ├── home.ts
│ │ └── order.ts
│ │ ├── log
│ │ └── message.ts
│ │ ├── member
│ │ ├── address.ts
│ │ └── fav.ts
│ │ ├── merchant
│ │ └── index.ts
│ │ └── system
│ │ ├── file.ts
│ │ ├── menu.ts
│ │ ├── permission.ts
│ │ ├── req_log.ts
│ │ ├── role.ts
│ │ └── user.ts
├── appveyor.yml
├── config
│ ├── config.default.ts
│ ├── config.local.ts
│ ├── config.prod.ts
│ └── plugin.ts
├── package-lock.json
├── package.json
├── test
│ └── app
│ │ ├── controller
│ │ └── home.test.ts
│ │ └── service
│ │ └── Test.test.ts
├── tsconfig.json
└── typings
│ ├── app
│ ├── controller
│ │ └── index.d.ts
│ ├── extend
│ │ ├── context.d.ts
│ │ └── helper.d.ts
│ ├── index.d.ts
│ ├── middleware
│ │ └── index.d.ts
│ ├── model
│ │ └── index.d.ts
│ └── service
│ │ └── index.d.ts
│ ├── config
│ ├── index.d.ts
│ └── plugin.d.ts
│ └── index.d.ts
└── uniapp
├── App.vue
├── Json.js
├── common
├── api
│ ├── axios.js
│ ├── common
│ │ ├── file.js
│ │ └── index.js
│ ├── good
│ │ ├── category.js
│ │ └── index.js
│ ├── index.js
│ └── user
│ │ ├── address.js
│ │ ├── fav.js
│ │ ├── index.js
│ │ └── order.js
└── utils
│ └── index.js
├── components
├── empty.vue
├── mix-list-cell.vue
├── mix-loading
│ └── mix-loading.vue
├── share.vue
├── uni-load-more
│ └── uni-load-more.vue
├── uni-number-box.vue
└── upload-images.vue
├── main.js
├── manifest.json
├── node_modules
├── axios
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── UPGRADE_GUIDE.md
│ ├── dist
│ │ ├── axios.js
│ │ ├── axios.map
│ │ ├── axios.min.js
│ │ └── axios.min.map
│ ├── index.d.ts
│ ├── index.js
│ ├── lib
│ │ ├── adapters
│ │ │ ├── README.md
│ │ │ ├── http.js
│ │ │ └── xhr.js
│ │ ├── axios.js
│ │ ├── cancel
│ │ │ ├── Cancel.js
│ │ │ ├── CancelToken.js
│ │ │ └── isCancel.js
│ │ ├── core
│ │ │ ├── Axios.js
│ │ │ ├── InterceptorManager.js
│ │ │ ├── README.md
│ │ │ ├── buildFullPath.js
│ │ │ ├── createError.js
│ │ │ ├── dispatchRequest.js
│ │ │ ├── enhanceError.js
│ │ │ ├── mergeConfig.js
│ │ │ ├── settle.js
│ │ │ └── transformData.js
│ │ ├── defaults.js
│ │ ├── helpers
│ │ │ ├── README.md
│ │ │ ├── bind.js
│ │ │ ├── buildURL.js
│ │ │ ├── combineURLs.js
│ │ │ ├── cookies.js
│ │ │ ├── deprecatedMethod.js
│ │ │ ├── isAbsoluteURL.js
│ │ │ ├── isURLSameOrigin.js
│ │ │ ├── normalizeHeaderName.js
│ │ │ ├── parseHeaders.js
│ │ │ └── spread.js
│ │ └── utils.js
│ └── package.json
└── follow-redirects
│ ├── LICENSE
│ ├── README.md
│ ├── debug.js
│ ├── http.js
│ ├── https.js
│ ├── index.js
│ └── package.json
├── package-lock.json
├── pages.json
├── pages
├── address
│ ├── address.vue
│ └── addressManage.vue
├── cart
│ └── cart.vue
├── category
│ └── category.vue
├── detail
│ └── detail.vue
├── index
│ └── index.vue
├── money
│ ├── money.vue
│ ├── orderSuccess.vue
│ ├── pay.vue
│ └── paySuccess.vue
├── notice
│ └── notice.vue
├── order
│ ├── createOrder.vue
│ └── order.vue
├── product
│ ├── list.vue
│ └── product.vue
├── public
│ └── login.vue
├── set
│ └── set.vue
├── user
│ ├── fav.vue
│ └── user.vue
└── userinfo
│ ├── setting.vue
│ └── 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
│ ├── ad-splash.jpg
│ ├── ad1.jpg
│ ├── ad2.jpg
│ ├── ad3.jpg
│ ├── banner1.jpg
│ ├── banner2.jpg
│ ├── banner3.jpg
│ ├── banner4.jpg
│ ├── c1.png
│ ├── c2.png
│ ├── c3.png
│ ├── c4.png
│ ├── c5.png
│ ├── c6.png
│ ├── c7.png
│ ├── c8.png
│ ├── cate1.jpg
│ ├── cate10.jpg
│ ├── cate11.jpg
│ ├── cate12.jpg
│ ├── cate13.jpg
│ ├── cate14.jpg
│ ├── cate15.jpg
│ ├── cate16.jpg
│ ├── cate17.jpg
│ ├── cate18.jpg
│ ├── cate19.jpg
│ ├── cate2.jpg
│ ├── cate20.jpg
│ ├── cate21.jpg
│ ├── cate22.jpg
│ ├── cate23.jpg
│ ├── cate24.jpg
│ ├── cate3.jpg
│ ├── cate4.jpg
│ ├── cate5.jpg
│ ├── cate6.jpg
│ ├── cate7.jpg
│ ├── cate8.jpg
│ ├── cate9.jpg
│ ├── h1.png
│ ├── secskill-img.jpg
│ ├── share_moment.png
│ ├── share_qq.png
│ ├── share_qqzone.png
│ └── share_wechat.png
├── user-bg.jpg
├── vip-card-bg.png
└── yticon.ttf
├── store
└── index.js
└── uni.scss
/README.md:
--------------------------------------------------------------------------------
1 | # eggjs-uniapp-shop
2 | 基于eggjs的商场管理系统,包含后端服务、后台管理、小程序商城
3 |
4 | ##技术栈
5 |
6 | 微信小程序:uni-app
7 |
8 | pc前端:vue2 + vuex + vue-router + element-ui
9 |
10 | 后端:node + egg.js + ES6
11 |
12 | ## 演示
13 |
14 | 后台管理地址:[http://mall.tucy.top/]
15 |
16 | 演示环境账号密码:
17 | |账号 | 密码 | 权限|
18 | | :----------: | :----: | :----------------------: |
19 | |admin|123456 |超级管理员,拥有菜单、权限商家等功能管理|
20 | |tcy|123456|商家,拥有商品、订单等功能|
21 |
22 | ## 功能模块
23 |
24 | -- 小程序
25 |
26 | ✔登录 ✔分类列表 ✔商品列表 ✔购物车 ✔订单管理 ✔地址管理 ✔我的收藏 ✔资料设置
27 |
28 | -- pc管理后台
29 |
30 | ** 系统管理员 **
31 |
32 | ✔ 用户管理
33 | ✔ 角色管理
34 | ✔ 权限管理
35 | ✔ 操作日志
36 | ✔ 文件管理
37 | ✔ 商家管理
38 |
39 | ** 商家 **
40 |
41 | ✔ 商品管理
42 | ✔ 订单管理
43 | ✔ 商品分类
44 | ✔ 个人资料
45 | ✔ 店铺资料
46 |
47 | ## 欢迎Star && PR
48 |
49 | 如果项目有帮助到你可以点个Star支持下。有更好的实现欢迎PR。
50 |
51 | ## 沟通交流
52 |
53 | 交流群:145679486
54 |
55 |
--------------------------------------------------------------------------------
/admin/.env.development:
--------------------------------------------------------------------------------
1 | VUE_APP_SERVER_URL=http://localhost:7001
2 | VUE_APP_MODULE=system,login,merchant,good,setting,dashboard,order
--------------------------------------------------------------------------------
/admin/.env.production:
--------------------------------------------------------------------------------
1 | VUE_APP_SERVER_URL=
2 | VUE_APP_MODULE=system,login,merchant,good,setting,dashboard,order
--------------------------------------------------------------------------------
/admin/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/admin/README.md:
--------------------------------------------------------------------------------
1 | # devops-viper
2 |
3 | ## Project setup
4 | ```
5 | npm install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | npm run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | npm run lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
--------------------------------------------------------------------------------
/admin/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/admin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "devops-viper",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "@tinymce/tinymce-vue": "^3.2.4",
12 | "ansicolor": "^1.1.93",
13 | "axios": "^0.20.0",
14 | "core-js": "^3.6.5",
15 | "element-ui": "^2.13.2",
16 | "js-cookie": "^2.2.1",
17 | "node-sass": "^4.14.1",
18 | "sass-loader": "^10.0.4",
19 | "vue": "^2.6.11",
20 | "vue-router": "^3.4.7",
21 | "vuex": "^3.5.1"
22 | },
23 | "devDependencies": {
24 | "@vue/cli-plugin-babel": "~4.5.0",
25 | "@vue/cli-plugin-eslint": "~4.5.0",
26 | "@vue/cli-service": "~4.5.0",
27 | "babel-eslint": "^10.1.0",
28 | "eslint": "^6.7.2",
29 | "eslint-plugin-vue": "^6.2.2",
30 | "vue-template-compiler": "^2.6.11"
31 | },
32 | "eslintConfig": {
33 | "root": true,
34 | "env": {
35 | "node": true
36 | },
37 | "extends": [
38 | "plugin:vue/essential",
39 | "eslint:recommended"
40 | ],
41 | "parserOptions": {
42 | "parser": "babel-eslint"
43 | },
44 | "rules": {}
45 | },
46 | "browserslist": [
47 | "> 1%",
48 | "last 2 versions",
49 | "not dead"
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/admin/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/public/favicon.ico
--------------------------------------------------------------------------------
/admin/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/admin/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
15 |
16 |
19 |
--------------------------------------------------------------------------------
/admin/src/api/common/authorize.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @description 用户相关api接口
3 | *
4 | * @author
5 | * @email
6 | * @phone
7 | * @create 2019-02-12 11:00
8 | * */
9 |
10 | import axios from '../index';
11 |
12 | export default{
13 | me:()=>axios.get('/authorize/me'),
14 | login:(opt)=>axios.post('/authorize/login',{token_type: 'SMART_SESSIONID',...opt}),
15 | logout:()=>axios.get('/authorize/login-out')
16 | }
--------------------------------------------------------------------------------
/admin/src/api/common/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @description 公共api接口
3 | *
4 | * @author
5 | * @email
6 | * @phone
7 | * @create 2019-02-12 11:00
8 | * */
9 |
10 | import axios from '../index';
11 | import {genNonDuplicateID} from '@/utils/index';
12 | import menu from './menu'
13 |
14 | export default{
15 | menu
16 | }
17 | /**
18 | * @description 设置语言
19 | *
20 | * @return [ Object ] 必反,返回菜单数组
21 | *
22 | * */
23 | export function setLanguage(lan){
24 | return axios.get('/language?locale='+lan);
25 | }
26 | /**
27 | * @description 主机操作触发事件
28 | *
29 | * params {Object} opt 参数对象 必含属性eventIds
30 | * @return {}
31 | * */
32 | // var tracerTime = 0;
33 | export function eventTracer(opt){
34 | return axios.get('/eventTracer',{params:opt});
35 | }
36 |
37 | /**
38 | * @description 文件上传
39 | *
40 | * @return [ Object ] 必反,返回菜单数组
41 | *
42 | * */
43 | export function fileUpload(formData,currFile,progressCallback,singleLoading){
44 |
45 | return axios({
46 | method: 'post',
47 | url: '/api/file/upload?random='+genNonDuplicateID(6),
48 | headers: {
49 | 'Content-Type': 'multipart/form-data'
50 | },
51 | data: formData,
52 | onUploadProgress: (progressEvent) => {
53 | if(!currFile) return
54 | currFile['percent'] = (progressEvent.loaded / progressEvent.total * 100 | 0);
55 | if(progressCallback && typeof progressCallback == 'function'){
56 | progressCallback(currFile['percent']);
57 | }
58 |
59 | if(singleLoading){
60 | singleLoading['percent'] = (progressEvent.loaded / progressEvent.total * 100 | 0);
61 | if(progressCallback && typeof progressCallback == 'function'){
62 | progressCallback(singleLoading['percent']);
63 | }
64 | }
65 | }
66 | })
67 |
68 | // return axios.post('/hyperone/file/upload?random='+genNonDuplicateID(6),formData);
69 | }
70 | /**
71 | * @description 文件删除
72 | *
73 | * @return [ Object ]
74 | *
75 | * */
76 | export function deleteUpload(opt){
77 | return axios.delete('/file/'+opt.id);
78 | }
79 |
80 |
81 | //获取当前系统版本
82 | export function getCurrentVersion(){
83 | return axios.get('/version');
84 | }
--------------------------------------------------------------------------------
/admin/src/api/common/messageCenter.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @description 审计日志
3 | *
4 | * @author
5 | * @email
6 | * @phone
7 | * @create 2019-09-17 11:00
8 | * */
9 |
10 | import axios from '@/api';
11 |
12 | export default{
13 | list:()=>axios.get('/messageCenter/'+id),
14 | remove:(id)=>axios.post('/messageCenter/readOrDelete',id)
15 | }
--------------------------------------------------------------------------------
/admin/src/api/instance.js:
--------------------------------------------------------------------------------
1 | import system from '@/views/system/api'
2 | import merchant from '@/views/merchant/api'
3 | export default{
4 | system,
5 | merchant
6 | }
--------------------------------------------------------------------------------
/admin/src/assets/css/variables.scss:
--------------------------------------------------------------------------------
1 | // base color
2 | $base-color: #d55e9a; //基础粉色
3 | $blue-auto:#5fbbfc; //基础蓝色
4 | $blue-dark:#256ba9; //基础蓝色
5 | $theme-bg: rgba(67,67,67,1); //头部与左侧黑色
6 | $light-blue: #3A71A8; //蓝色
7 | $red-auto: #ff0000; //红色
8 | $green-auto: #39c700; //绿色
9 | $orange-auto: #ff9600; //橙色
10 | $orange-light: #faf2ed;
11 | $background-aoto:#efe6d6; //背景颜色
12 |
13 | $black-dark: #323232; //菜单选中背景色
14 | $black-light: #434343; //菜单背景色
15 | $black-pale: #666666;
16 | $black-half: #aaa;
17 | $gray-1: #808080; //文字颜色
18 | $gray-2: #cccccc; //文字
19 | $gray-3: #e7e7e7; //描边
20 | $gray-4: #f2f2f2; //表头
21 | $gray-5: #fafafa; //隔行换色
22 |
23 | $red-select: #ff8d1a;
24 |
25 | $boxShadow: rgba(0,0,0,.05);
26 |
--------------------------------------------------------------------------------
/admin/src/assets/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/avatar.png
--------------------------------------------------------------------------------
/admin/src/assets/images/beian2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/beian2.png
--------------------------------------------------------------------------------
/admin/src/assets/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/favicon.ico
--------------------------------------------------------------------------------
/admin/src/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/favicon.png
--------------------------------------------------------------------------------
/admin/src/assets/images/login-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/login-bg.jpg
--------------------------------------------------------------------------------
/admin/src/assets/images/security.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/security.png
--------------------------------------------------------------------------------
/admin/src/assets/images/sprites-arrow-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/sprites-arrow-20.png
--------------------------------------------------------------------------------
/admin/src/assets/images/sprites-common-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/sprites-common-20.png
--------------------------------------------------------------------------------
/admin/src/assets/images/sprites-commons-30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/sprites-commons-30.png
--------------------------------------------------------------------------------
/admin/src/assets/images/sprites-edit-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/sprites-edit-20.png
--------------------------------------------------------------------------------
/admin/src/assets/images/sprites-login-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/sprites-login-20.png
--------------------------------------------------------------------------------
/admin/src/assets/images/success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/assets/images/success.png
--------------------------------------------------------------------------------
/admin/src/components/FormDialog/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import main from './main.vue'
3 | import store from '@/store'
4 | const Constructor = Vue.extend(main);
5 | let instance
6 |
7 | const initInstance = (options) => {
8 | instance = new Constructor({
9 | el: document.createElement('div'),
10 | store,
11 | data: options
12 | });
13 | document.body.appendChild(instance.$el)
14 | instance.doClose = function(){
15 | instance.visible = false;
16 | setTimeout(()=>{
17 | if(instance){
18 | instance.svisible=false;
19 | document.body.removeChild(instance && instance.$el);
20 | instance =null
21 | }
22 | },300)
23 | };
24 | };
25 |
26 | const dialogForm = {
27 | show(options) {
28 | if(!instance){
29 | initInstance(options)
30 | }
31 | // for (let prop in options) {
32 | // if (options.hasOwnProperty(prop)) {
33 | // instance[prop] = options[prop];
34 | // }
35 | // }
36 | instance.visible =true
37 | },
38 | hide(){
39 | instance && instance.doClose()
40 | },
41 | close() {
42 | instance && instance.doClose();
43 | }
44 | }
45 | export default dialogForm
--------------------------------------------------------------------------------
/admin/src/components/FormDialog/main.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
17 |
18 |
19 |
78 |
--------------------------------------------------------------------------------
/admin/src/components/PagerSelf/index.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
{{$t('common.together')}}{{' '+total+' '}}{{$t('common.item')}}
10 |
21 |
22 |
23 |
83 |
--------------------------------------------------------------------------------
/admin/src/components/TableColumnFilter/index.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {{item.label}}
17 |
18 |
19 |
20 |
21 |
48 |
--------------------------------------------------------------------------------
/admin/src/components/TableFilter/components/ZoneSelect/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
55 |
--------------------------------------------------------------------------------
/admin/src/components/TableMain/TableItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{item.header?item.header:item.label}}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/admin/src/components/TableMain/components/ContextMenu/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import main from './main.vue'
3 | import store from '@/store'
4 | const Constructor = Vue.extend(main);
5 | let instance
6 |
7 | const initInstance = (options) => {
8 | instance = new Constructor({
9 | el: document.createElement('div'),
10 | store,
11 | data: options
12 | });
13 | document.body.appendChild(instance.$el)
14 | instance.doClose = function(){
15 | instance.visible = false;
16 |
17 | document.body.removeChild(instance.$el);
18 | instance =null
19 |
20 |
21 | }
22 | };
23 |
24 | const dialogForm = {
25 | show(options) {
26 | if(instance){
27 | instance.doClose();
28 | }
29 | setTimeout(()=>{
30 | initInstance(options)
31 |
32 | instance.visible =true
33 | })
34 |
35 | },
36 | hide(){
37 | instance && instance.doClose()
38 | }
39 | }
40 | export default dialogForm
--------------------------------------------------------------------------------
/admin/src/components/layout/EmptyLayout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/admin/src/components/layout/components/LangSelect.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
62 |
--------------------------------------------------------------------------------
/admin/src/components/layout/components/MenuBarItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{menu.name}}
8 | {{menu.name}}
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{menu.name}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/admin/src/components/layout/components/MenuToggle/index.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
32 |
33 |
41 |
--------------------------------------------------------------------------------
/admin/src/components/layout/mixin/ResizeHandler.js:
--------------------------------------------------------------------------------
1 | import store from '@/store'
2 |
3 | const { body } = document
4 | const WIDTH = 900
5 | const RATIO = 3
6 |
7 | export default {
8 | watch: {
9 | $route() {
10 | if (this.device === 'mobile' && this.sidebar.opened) {
11 | // store.dispatch('closeSideBar', { withoutAnimation: false })
12 | }
13 | }
14 | },
15 | beforeMount() {
16 | window.addEventListener('resize', this.resizeHandler)
17 | },
18 | mounted() {
19 | const isMobile = this.isMobile()
20 | if (isMobile) {
21 | store.dispatch('toggleDevice', 'mobile')
22 | store.dispatch('showSideBar', { withoutAnimation: true })
23 | }
24 | /* header二级菜单添加最大高度,防止内容溢出 */
25 | let bodyHeight = body.clientHeight;
26 | let submenus = document.getElementsByClassName('submenu');
27 | for(let i=0;i {
18 | Vue.filter(key, filters[key])
19 | })
20 | /* 全局权限配置 */
21 | Vue.prototype.$auth = function(authId, action) {
22 | if (store.getters.permission && store.getters.permission[authId] && store.getters.permission[authId][action]) {
23 | return true;
24 | }
25 | return false;
26 | }
27 | import TableMain from '@/components/TableMain';
28 | Vue.component('TableMain',TableMain)
29 | import TableFilter from '@/components/TableFilter';
30 | Vue.component('TableFilter',TableFilter)
31 | new Vue({
32 | render: h => h(App),
33 | router,
34 | store
35 | }).$mount('#app')
36 |
--------------------------------------------------------------------------------
/admin/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 | import store from '@/store';
4 | Vue.use(VueRouter)
5 |
6 | const routes = [
7 | ]
8 |
9 | const router = new VueRouter({
10 | mode: 'hash',
11 | base: process.env.BASE_URL,
12 | routes
13 | })
14 | var isAdd = false;
15 | var initDynamicRouters = function(callback){
16 | if(isAdd){
17 | callback && callback();
18 | return;
19 | }
20 | /* 根据env配置文件,动态加载路由 */
21 | Promise.all(
22 | process.env.VUE_APP_MODULE && process.env.VUE_APP_MODULE.split(',').map(item=>{
23 | return import('@/views/'+item+'/router')
24 | })
25 | ).then(modules=>{
26 | modules.forEach((module)=>{
27 | router.options.routes = [...module.default,...router.options.routes]
28 | router.addRoutes(module.default)
29 | })
30 | /* 添加404路由,必须加在路由最后面 */
31 | let notfoundRoute = [{
32 | path: '*',
33 | component: ()=>import('@/components/layout/index.vue'),
34 | children: [{
35 | path: '',
36 | component: () => import('@/views/errorPage/404.vue'),
37 | hidden: true
38 | }]
39 | }]
40 | router.options.routes = [...router.options.routes,...notfoundRoute]
41 | router.addRoutes(notfoundRoute);
42 | callback && callback();
43 | isAdd=true;
44 | })
45 | }
46 | initDynamicRouters();
47 |
48 | router.beforeEach((to, from, next) => {
49 | const whiteList = ['/login','/401','/404','/403','/signup'] // 不需要重定向白名单
50 | // next();return;//暂时去掉登录拦截
51 | if (whiteList.indexOf(to.path) != -1 || to.path.indexOf('login')>-1) { // 在免登录白名单,直接进入
52 | next()
53 | } else {
54 | if (!store.getters.user.id) { // 判断页面是否刷新
55 | store.dispatch('GetUserInfo',true).then(() => {// 拉取user_info
56 | next({
57 | path: to.path,
58 | query: to.query,
59 | params: to.params,
60 | replace: true
61 | })
62 |
63 | }).catch(() => {
64 | let path = '/login'
65 | next({
66 | path: path,
67 | query: { redirect: to.fullPath },
68 | replace: true
69 | })
70 | })
71 | } else {
72 | next()
73 | }
74 | }
75 | // eslint-disable-next-line no-console
76 |
77 | })
78 | router.afterEach(() => {
79 |
80 | });
81 |
82 | export default router
83 |
--------------------------------------------------------------------------------
/admin/src/store/getters.js:
--------------------------------------------------------------------------------
1 | export default {
2 | user: state => state.user.user,
3 | sidebar: state => state.app.sidebar,
4 | device: state => state.app.device,
5 | theme: state => state.app.theme,
6 | baseUrl: state=>state.app.baseUrl,
7 | }
--------------------------------------------------------------------------------
/admin/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | import app from './modules/app'
5 | import user from './modules/user'
6 | import getters from './getters'
7 |
8 | Vue.use(Vuex);
9 |
10 | export default new Vuex.Store({
11 | modules: {
12 | app,
13 | user,
14 | },
15 | getters,
16 | })
--------------------------------------------------------------------------------
/admin/src/store/modules/user.js:
--------------------------------------------------------------------------------
1 | import systemApi from '@/views/system/api';
2 | import Cookies from 'js-cookie'
3 | const user = {
4 | state: {
5 | user: {},
6 | },
7 |
8 | mutations: {
9 | SET_USER: (state, user) => {
10 | state.user = user
11 | localStorage.setItem('currentUser',JSON.stringify(user));
12 | },
13 | },
14 |
15 | actions: {
16 |
17 | // 获取用户信息,refresh为true时,从后台获取数据
18 | GetUserInfo({ dispatch,commit, state },refresh) {
19 |
20 | return new Promise((resolve, reject) => {
21 | if(refresh){
22 | systemApi.user.info().then((response,error) => {
23 | if(!response){ reject();return ;}
24 | commit('SET_USER', response.result);
25 | Cookies.set('currentUser',response.result.id);
26 | resolve(response)
27 | }).catch(error => {
28 | console.log(error,'error')
29 | reject(error)
30 | })
31 |
32 | }else{
33 | let currentUserId = Cookies.get('currentUser');
34 | let currentUser = localStorage.getItem('currentUser');
35 | if(currentUserId && currentUser){
36 | currentUser = JSON.parse(currentUser);
37 | commit('SET_USER', currentUser);
38 | resolve({result:currentUser});
39 | }else{
40 | reject()
41 | }
42 | }
43 | })
44 | },
45 |
46 | // 登出
47 | LogOut({ commit, state }) {
48 | return new Promise((resolve, reject) => {
49 | systemApi.user.logout(state.token).then(() => {
50 | commit('SET_USER', {});
51 | Cookies.remove('currentUser');
52 | localStorage.removeItem('currentUser');
53 | resolve()
54 | }).catch(error => {
55 | reject(error)
56 | })
57 | })
58 | },
59 | clearUser({ commit, state }){
60 | commit('SET_USER', {});
61 | Cookies.remove('currentUser');
62 | localStorage.removeItem('currentUser');
63 | },
64 |
65 | }
66 | };
67 |
68 | export default user
--------------------------------------------------------------------------------
/admin/src/utils/constant.js:
--------------------------------------------------------------------------------
1 | /*
2 | * des 枚举类型(数据转换)
3 | *
4 | * author hwx
5 | *
6 | * */
7 |
8 |
9 | /**
10 | * @description FIXME qinjunqiang 优化调整
11 | * value 对应后台的参数(* 该字段的值不可随意修改)
12 | * title 仅仅是写给自己看或后期维护的人看(过一段时间后给自己或维护的人看能很快对应上)
13 | * displayName 最终的翻译后的字段
14 | * */
15 | let _constMap = (() => {
16 | let obj = {
17 | UserStatus:[
18 | {value: 1,label:'可用'},
19 | {value: 2,label:'禁用'}
20 | ],
21 | UserSex:[
22 | {value: 1,label:'男'},
23 | {value: 2,label:'女'}
24 | ],
25 | UserType:[
26 | {value: 1,label:'管理员'},
27 | {value: 2,label:'商家'},
28 | {value: 3,label:'用户'},
29 | ],
30 | // ordered: '待付款', inpayment: '付款中', paid: '已付款,待发货', receiving: '已发货,待收货', completed: '已完成', canceled: '已取消',closed:已关闭
31 | OrderStatus:[
32 | {value: "ordered",label: '待付款'},
33 | {value: "inpayment",label: '付款中'},
34 | {value: "paid",label: '待发货'},
35 | {value: "receiving",label: '待收货'},
36 | {value: "completed",label: '已完成'},
37 | {value: "canceled",label: '已取消'},
38 | {value: "closed",label: '已关闭'},
39 | ]
40 | };
41 |
42 | for (let key in obj) {
43 | let item = obj[key];
44 |
45 | for (let i = 0; i < item.length; i++) {
46 | let cItem = item[i];
47 | let k = item[i].langKey?item[i].langKey:'common';
48 |
49 | // 给每一个数组对象新增一个翻译 lang 参数
50 | //!cItem['displayName'] && (cItem['displayName'] = i18n.t(k + '.' + cItem.lang));
51 | }
52 | }
53 |
54 | return obj;
55 | })();
56 |
57 | export const constantMap = _constMap;
--------------------------------------------------------------------------------
/admin/src/utils/scrollTo.js:
--------------------------------------------------------------------------------
1 | Math.easeInOutQuad = function(t, b, c, d) {
2 | t /= d / 2
3 | if (d <= 0){
4 | return c;
5 | }
6 | if (t < 1) {
7 | return c / 2 * t * t + b
8 | }
9 | t--
10 | return -c / 2 * (t * (t - 2) - 1) + b
11 | }
12 |
13 | // requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
14 | var requestAnimFrame = (function() {
15 | return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
16 | })()
17 |
18 | // because it's so fucking difficult to detect the scrolling element, just move them all
19 | function move(amount,container) {
20 | if(container){
21 | container.scrollTop = amount;
22 | }else{
23 | document.documentElement.scrollTop = amount
24 | document.body.parentNode.scrollTop = amount
25 | document.body.scrollTop = amount
26 | }
27 |
28 | }
29 |
30 | function position(container) {
31 | if(!container){
32 | return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
33 | }else{
34 | return container.scrollTop
35 | }
36 | }
37 |
38 | export function scrollTo(to, duration, callback,container) {
39 | const start = position(container)
40 | const change = to - start
41 | const increment = 20
42 | let currentTime = 0
43 | duration = (typeof (duration) === 'undefined') ? 500 : duration
44 | var animateScroll = function() {
45 | // increment the time
46 | currentTime += increment
47 | // find the value with the quadratic in-out easing function
48 | var val = Math.easeInOutQuad(currentTime, start, change, duration)
49 | // move the document.body
50 | move(val,container)
51 | // do the animation unless its over
52 | if (currentTime < duration) {
53 | requestAnimFrame(animateScroll)
54 | } else {
55 | if (callback && typeof (callback) === 'function') {
56 | // the animation is done so lets callback
57 | callback()
58 | }
59 | }
60 | }
61 | animateScroll()
62 | }
63 |
--------------------------------------------------------------------------------
/admin/src/views/dashboard/api/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/admin/src/views/dashboard/api/index.js
--------------------------------------------------------------------------------
/admin/src/views/dashboard/router.js:
--------------------------------------------------------------------------------
1 | import Layout from '@/components/layout/index.vue'
2 |
3 | export default [{
4 | path: '/',
5 | component: Layout,
6 | redirect: '/dashboard',
7 | children: [
8 | {
9 | path: '/dashboard',
10 | component: ()=>import('./views/index'),
11 | },
12 | ]
13 | }]
--------------------------------------------------------------------------------
/admin/src/views/dashboard/views/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
35 |
--------------------------------------------------------------------------------
/admin/src/views/errorPage/401.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
{{$t('message.tips401')}}
12 |
13 | {{$t('actions.backHome')}}
14 |
15 |
16 |
17 |
30 |
--------------------------------------------------------------------------------
/admin/src/views/errorPage/403.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
{{$t('message.tips403')}}
12 |
13 | {{$t('actions.backHome')}}
14 |
15 |
16 |
17 |
30 |
--------------------------------------------------------------------------------
/admin/src/views/errorPage/404.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 | 开发中,敬请期待...
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/admin/src/views/good/api/category.js:
--------------------------------------------------------------------------------
1 | import axios from '@/api';
2 | export default{
3 | save:(params)=>axios.post('/api/goodCategory/save',params),
4 | select:(params)=>axios.get('/api/goodCategory/list',{params}),
5 | list:(params)=>axios.get('/api/goodCategory',{params}),
6 | tree:(params)=>axios.get('/api/goodCategory/tree',{params}),
7 | remove:(id)=>axios.delete('/api/goodCategory/'+id),
8 | update:(params)=>axios.post('/api/goodCategory/update',params),
9 | }
--------------------------------------------------------------------------------
/admin/src/views/good/api/good.js:
--------------------------------------------------------------------------------
1 | import axios from '@/api';
2 | export default{
3 | save:(params)=>axios.post('/api/good/save',params),
4 | list:(params)=>axios.get('/api/good',{params}),
5 | detail:(id)=>axios.get('/api/good/'+id),
6 | remove:(id)=>axios.delete('/api/good/'+id),
7 | update:(params)=>axios.post('/api/good/update',params),
8 | }
--------------------------------------------------------------------------------
/admin/src/views/good/api/index.js:
--------------------------------------------------------------------------------
1 | import good from './good'
2 | import category from './category'
3 | export default{
4 | good,
5 | category
6 | }
--------------------------------------------------------------------------------
/admin/src/views/good/router.js:
--------------------------------------------------------------------------------
1 | import Layout from '@/components/layout/index.vue'
2 |
3 | export default [{
4 | path: '/good',
5 | component: Layout,
6 | redirect: '/good/list',
7 | children: [
8 | {
9 | path: 'list',
10 | component: ()=>import('./views/list'),
11 | },
12 | {
13 | path: 'list/create',
14 | component: ()=>import('./views/list/edit'),
15 | },
16 | {
17 | path: 'category',
18 | component: ()=>import('./views/category'),
19 | },
20 | ]
21 | }]
--------------------------------------------------------------------------------
/admin/src/views/login/router.js:
--------------------------------------------------------------------------------
1 | import Login from './views/Login.vue'
2 |
3 | export default [
4 | {
5 | path: '/login',
6 | name: 'login',
7 | component: Login,
8 | },
9 | ]
--------------------------------------------------------------------------------
/admin/src/views/merchant/api/index.js:
--------------------------------------------------------------------------------
1 | import merchant from './merchant'
2 | export default{
3 | merchant
4 | }
--------------------------------------------------------------------------------
/admin/src/views/merchant/api/merchant.js:
--------------------------------------------------------------------------------
1 | import axios from '@/api';
2 | export default{
3 | save:(params)=>axios.post('/api/merchant/save',params),
4 | list:(params)=>axios.get('/api/merchant',{params}),
5 | remove:(id)=>axios.delete('/api/merchant/'+id),
6 | update:(params)=>axios.post('/api/merchant/update',params),
7 | }
--------------------------------------------------------------------------------
/admin/src/views/merchant/router.js:
--------------------------------------------------------------------------------
1 | import Layout from '@/components/layout/index.vue'
2 |
3 | export default [{
4 | path: '/merchant',
5 | component: Layout,
6 | redirect: '/merchant/merchant',
7 | children: [
8 | {
9 | path: 'merchant',
10 | component: ()=>import('./views/merchant'),
11 | },
12 | ]
13 | }]
--------------------------------------------------------------------------------
/admin/src/views/order/api/index.js:
--------------------------------------------------------------------------------
1 | import order from './order'
2 | export default{
3 | order
4 | }
--------------------------------------------------------------------------------
/admin/src/views/order/api/order.js:
--------------------------------------------------------------------------------
1 | import axios from '@/api';
2 | export default{
3 | save:(params)=>axios.post('/api/order/save',params),
4 | list:(params)=>axios.get('/api/order',{params}),
5 | detail:(id)=>axios.get('/api/order/'+id),
6 | remove:(id)=>axios.delete('/api/order/'+id),
7 | update:(params)=>axios.post('/api/order/update',params),
8 | }
--------------------------------------------------------------------------------
/admin/src/views/order/router.js:
--------------------------------------------------------------------------------
1 | import Layout from '@/components/layout/index.vue'
2 |
3 | export default [{
4 | path: '/order',
5 | component: Layout,
6 | redirect: '/order/list',
7 | children: [
8 | {
9 | path: 'list',
10 | component: ()=>import('./views/list'),
11 | },
12 | ]
13 | }]
--------------------------------------------------------------------------------
/admin/src/views/setting/router.js:
--------------------------------------------------------------------------------
1 | import Layout from '@/components/layout/index.vue'
2 |
3 | export default [{
4 | path: '/setting',
5 | component: Layout,
6 | redirect: '/setting/person',
7 | children: [
8 | {
9 | path: 'person',
10 | component: ()=>import('./views/person'),
11 | },
12 | {
13 | path: 'shop',
14 | component: ()=>import('./views/shop'),
15 | },
16 | ]
17 | }]
--------------------------------------------------------------------------------
/admin/src/views/system/api/file.js:
--------------------------------------------------------------------------------
1 | import axios from '@/api';
2 | export default{
3 | save:(params)=>axios.post('/api/file/save',params),
4 | list:(params)=>axios.get('/api/file',{params}),
5 | remove:(id)=>axios.delete('/api/file/'+id),
6 | update:(params)=>axios.post('/api/file/update',params),
7 | }
--------------------------------------------------------------------------------
/admin/src/views/system/api/index.js:
--------------------------------------------------------------------------------
1 | import user from './user'
2 | import menu from './menu'
3 | import role from './role'
4 | import permission from './permission'
5 | import file from './file'
6 | import log from './log'
7 | export default{user,menu,role,permission,file,log}
--------------------------------------------------------------------------------
/admin/src/views/system/api/log.js:
--------------------------------------------------------------------------------
1 | import axios from '@/api';
2 | export default{
3 | list:(params)=>axios.get('/api/system/reqlog',{params}),
4 | select:(params)=>axios.get('/api/system/reqlog/list',{params}),
5 | save:(opt)=>axios.post('/api/system/reqlog/save',opt),
6 | remove:(id)=>axios.delete('/api/system/reqlog/'+id),
7 | }
--------------------------------------------------------------------------------
/admin/src/views/system/api/menu.js:
--------------------------------------------------------------------------------
1 | import axios from '@/api';
2 | export default{
3 | tree:(params)=>axios.get('/api/menu/tree',{params}),
4 | list:(params)=>axios.get('/api/menu',{params}),
5 | select:(params)=>axios.get('/api/menu/list',{params}),
6 | save:(opt)=>axios.post('/api/menu/save',opt),
7 | remove:(id)=>axios.delete('/api/menu/'+id),
8 | }
--------------------------------------------------------------------------------
/admin/src/views/system/api/permission.js:
--------------------------------------------------------------------------------
1 | import axios from '@/api';
2 | export default{
3 | list:(params)=>axios.get('/api/permission',{params}),
4 | select:(params)=>axios.get('/api/permission/list',{params}),
5 | save:(opt)=>axios.post('/api/permission/save',opt),
6 | remove:(id)=>axios.delete('/api/permission/'+id),
7 | }
--------------------------------------------------------------------------------
/admin/src/views/system/api/role.js:
--------------------------------------------------------------------------------
1 | import axios from '@/api';
2 | export default{
3 | list:(params)=>axios.get('/api/role',{params}),
4 | select:(params)=>axios.get('/api/role/list',{params}),
5 | detail:(id)=>axios.get('/api/role/'+id),
6 | save:(opt)=>axios.post('/api/role/save',opt),
7 | remove:(id)=>axios.delete('/api/role/'+id),
8 | //角色菜单保存
9 | menuSave:(id,opt)=>axios.post('/api/role/'+id+'/menu',opt),
10 | //角色菜单列表
11 | menuList:(id)=>axios.get('/api/role/'+id+'/menu'),
12 | //角色权限列表
13 | authList:(id)=>axios.get('/api/role/'+id+'/permission'),
14 | //角色权限保存
15 | authSave:(id,opt)=>axios.post('/api/role/'+id+'/permission',opt),
16 | }
--------------------------------------------------------------------------------
/admin/src/views/system/api/user.js:
--------------------------------------------------------------------------------
1 | import axios from '@/api';
2 | export default{
3 | login:(params)=>axios.post('/api/user/login',params),
4 | logout:()=>axios.get('/api/user/logout'),
5 | save:(params)=>axios.post('/api/user/save',params),
6 | info:()=>axios.get('/api/user/info'),
7 | list:(params)=>axios.get('/api/user',{params}),
8 | remove:(id)=>axios.delete('/api/user/'+id),
9 | detail:(id)=>axios.get('/api/user/detail/'+id),
10 | update:(params)=>axios.post('/api/user/update',params),
11 | menu:()=>axios.get('/api/user/menu'),
12 | }
--------------------------------------------------------------------------------
/admin/src/views/system/router.js:
--------------------------------------------------------------------------------
1 | import Layout from '@/components/layout/index.vue'
2 |
3 | export default [{
4 | path: '/system',
5 | component: Layout,
6 | redirect: '/system/menu',
7 | children: [
8 | {
9 | path: 'menu',
10 | component: ()=>import('./views/menu'),
11 | },
12 | {
13 | path: 'role',
14 | component: ()=>import('./views/role'),
15 | },
16 | {
17 | path: 'permission',
18 | component: ()=>import('./views/permission'),
19 | },
20 | {
21 | path: 'user',
22 | component: ()=>import('./views/user'),
23 | },
24 | {
25 | path: 'file',
26 | component: ()=>import('./views/file'),
27 | },
28 | {
29 | path: 'log',
30 | component: ()=>import('./views/log'),
31 | }
32 | ]
33 | }]
--------------------------------------------------------------------------------
/admin/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports={
2 | lintOnSave: false,
3 | publicPath: '/',
4 | // 输出文件目录
5 | outputDir: 'dist',
6 | assetsDir: 'assets',
7 | productionSourceMap: false,
8 | pages: {
9 | index: {
10 | // page 的入口
11 | entry: 'src/main.js',
12 | // 模板来源
13 | template: 'public/index.html',
14 | // 在 dist/index.html 的输出
15 | filename: 'index.html',
16 | // 当使用 title 选项时,
17 | // template 中的 title 标签需要是 <%= htmlWebpackPlugin.options.title %>
18 | title: '后台管理系统',
19 | // 在这个页面中包含的块,默认情况下会包含
20 | // 提取出来的通用 chunk 和 vendor chunk。
21 | chunks: ['chunk-vendors', 'chunk-common', 'index']
22 | }
23 |
24 | }
25 | }
--------------------------------------------------------------------------------
/server/.autod.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | write: true,
5 | plugin: 'autod-egg',
6 | prefix: '^',
7 | devprefix: '^',
8 | exclude: [
9 | 'test/fixtures',
10 | 'coverage',
11 | ],
12 | dep: [
13 | 'egg',
14 | 'egg-scripts',
15 | ],
16 | devdep: [
17 | 'autod',
18 | 'autod-egg',
19 | 'egg-bin',
20 | 'tslib',
21 | 'typescript',
22 | ],
23 | keep: [
24 | ],
25 | semver: [
26 | ],
27 | test: 'scripts',
28 | };
29 |
--------------------------------------------------------------------------------
/server/.eslintignore:
--------------------------------------------------------------------------------
1 | **/*.d.ts
2 | node_modules/
3 |
--------------------------------------------------------------------------------
/server/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint-config-egg/typescript",
3 | "parserOptions": {
4 | "project": "./tsconfig.json"
5 | }
6 | }
--------------------------------------------------------------------------------
/server/.github/workflows/nodejs.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Node.js CI
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ${{ matrix.os }}
16 |
17 | strategy:
18 | matrix:
19 | node-version: [8.x]
20 | os: [ubuntu-latest, windows-latest, macos-latest]
21 |
22 | steps:
23 | - uses: actions/checkout@v2
24 | - name: Use Node.js ${{ matrix.node-version }}
25 | uses: actions/setup-node@v1
26 | with:
27 | node-version: ${{ matrix.node-version }}
28 | - run: npm i -g npminstall && npminstall
29 | - run: npm run ci
30 | env:
31 | CI: true
32 |
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | logs/
2 | npm-debug.log
3 | node_modules/
4 | coverage/
5 | .idea/
6 | run/
7 | logs/
8 | .DS_Store
9 | .vscode
10 | *.swp
11 | *.lock
12 | *.js
13 | !.autod.conf.js
14 |
15 | app/**/*.js
16 | test/**/*.js
17 | config/**/*.js
18 | app/**/*.map
19 | test/**/*.map
20 | config/**/*.map
21 | app/public/uploads/
22 |
--------------------------------------------------------------------------------
/server/.travis.yml:
--------------------------------------------------------------------------------
1 |
2 | language: node_js
3 | node_js:
4 | - '8'
5 | before_install:
6 | - npm i npminstall -g
7 | install:
8 | - npminstall
9 | script:
10 | - npm run ci
11 | after_script:
12 | - npminstall codecov && codecov
13 |
--------------------------------------------------------------------------------
/server/README.md:
--------------------------------------------------------------------------------
1 | # eggjs-uniapp-shop
2 | ### 基于egg.js+jwt+mysql编写的开箱即用的权限管理后台
3 | ### 后台: egg.js
4 | ### 数据库: mysql
5 |
6 |
7 | 👤 **tuchongyang**
8 |
9 | * Github: [@tuchongyang](https://github.com/tuchongyang)
10 | * QQ: 779311998
11 | * QQ群: 145679486
12 |
13 | ### 已实现功能
14 | #### 使用之前请先了解`egg.js`,然后把`/server/config/config.local.js`数据库配置成自己的,只要手动创建数据库就行,数据表在系统运行时会自动创建,并且自动创建超级管理员账号,为了系统稳定性该账号不可以被删除,不可以被降级权限
15 |
16 | - [x] 注册
17 | - [x] 登录
18 | - [x] token校验过期处理(临时过期,永久过期)
19 | - [ ] 微信登录
20 | - [x] 个人资料修改
21 | - [x] 角色管理,(增加,删除,修改)系统默认创建超级管理员角色,除了超级管理员任何角色不可对其删除修改
22 | - [x] 权限管理 对每个角色分配不同的页面路由权限和按钮权限,(当前角色的用户只能分配自己拥有的页面权限和按钮权限)
23 | - [x] 管理员对普通用户资料修改
24 | - [x] 账号管理(增加,删除,修改)系统默认创建超级管理员账号,除了超级管理员任何角色不可对其删除修改
25 | - [x] 添加账号
26 | - [x] 用户列表
27 | - [x] 用户状态管理
28 |
29 |
30 |
31 |
32 | ## 结语
33 | 如果这个框架对你有帮助的话,请给个星点个star
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/server/app/config/index.ts:
--------------------------------------------------------------------------------
1 | import permission from './permission'
2 | export default {permission}
--------------------------------------------------------------------------------
/server/app/config/permission.ts:
--------------------------------------------------------------------------------
1 | export default{
2 | actionNames: {
3 | "detail":'详情',
4 | "query":"查询",
5 | "add":"添加",
6 | "delete":"删除"
7 | }
8 | }
--------------------------------------------------------------------------------
/server/app/controller/good/category.ts:
--------------------------------------------------------------------------------
1 | import { Controller } from 'egg';
2 | import { bp } from 'egg-blueprint'
3 | /**
4 | * @Controller 商品分类
5 | */
6 | bp.prefix('/api/goodCategory', 'GoodCategoryController')
7 | export default class GoodCategoryController extends Controller {
8 | /** 分页列表 */
9 | @bp.get('/')
10 | public async index() {
11 | const { ctx } = this;
12 | let list = await ctx.service.good.category.list(ctx.query)
13 | ctx.success(list)
14 | }
15 | /** 不分页列表 */
16 | @bp.get('/list')
17 | public async list() {
18 | const { ctx } = this;
19 | let list = await ctx.service.good.category.select(ctx.query)
20 | ctx.success(list)
21 | }
22 | /** 不分页列表,树形,用于类型选择框 */
23 | @bp.get('/tree')
24 | public async tree() {
25 | const { ctx } = this;
26 | let list = await ctx.service.good.category.select(ctx.query);
27 | var getChildren = (parentId)=>{
28 | var results = list.filter(a=>a.parentId==parentId);
29 | for(let i=0;i{
66 | ctx.success()
67 | }).catch(err=>{
68 | ctx.fail(400,err.message)
69 | })
70 | }
71 | /**获取角色权限 */
72 | @bp.get('/:id/permission')
73 | public async permission(){
74 | const { ctx } = this;
75 | const data = await ctx.service.system.role.getPermission(ctx.params.id)
76 | ctx.success(data)
77 | }
78 | /**新增、保存角色权限 */
79 | @bp.post('/:id/permission')
80 | public async permissionSave(){
81 | const { ctx } = this;
82 | await ctx.service.system.role.savePermission(ctx.params.id,ctx.request.body).then(()=>{
83 | ctx.success()
84 | }).catch(err=>{
85 | ctx.fail(400,err.message)
86 | })
87 | }
88 |
89 |
90 |
91 | }
--------------------------------------------------------------------------------
/server/app/extend/context.ts:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | SUCCESS_CODE: 200, // 成功
3 | NO_LOGIN_CODE: 401, // 未登录
4 | UNIQUE_CODE: 200, // 唯一性冲突
5 | ERROR_CODE: 500, // 失败
6 | user() {
7 | return this.ctx.session.user;
8 | },
9 |
10 | success(data, status) {
11 | this.body = { status: this.SUCCESS_CODE, result:data };
12 | this.status = status || 200;
13 | },
14 |
15 | fail(status, message,data) {
16 | this.body = { status, message, result:data };
17 | this.status = status||400;
18 | },
19 |
20 | notFound(msg) {
21 | msg = msg || 'not found';
22 | this.throw(404, msg);
23 | }
24 | };
--------------------------------------------------------------------------------
/server/app/extend/helper.ts:
--------------------------------------------------------------------------------
1 | import { IHelper } from 'egg';
2 | module.exports = {
3 | /**
4 | * 获取请求IP
5 | */
6 | getReqIP(this: IHelper) {
7 | const req: any = this.ctx.req;
8 | return (req.headers['x-forwarded-for'] || // 判断是否有反向代理 IP
9 | req.connection.remoteAddress || // 判断 connection 的远程 IP
10 | req.socket.remoteAddress || // 判断后端的 socket 的 IP
11 | req.connection.socket.remoteAddress).replace('::ffff:', '');
12 | },
13 | randomNo(j) {
14 | var random_no = "";
15 | for (var i = 0; i < j; i++) //j位随机数,用以加在时间戳后面。
16 | {
17 | random_no += Math.floor(Math.random() * 10);
18 | }
19 | random_no = new Date().getTime() + random_no;
20 | return random_no;
21 | }
22 | };
--------------------------------------------------------------------------------
/server/app/middleware/admin_req_log.ts:
--------------------------------------------------------------------------------
1 | import { Context } from 'egg';
2 |
3 | /**
4 | * 日志中间件,记录请求
5 | */
6 | export default function AdminReqLog(): any {
7 | return async (ctx: Context, next: () => Promise) => {
8 | const startTime = Date.now();
9 | await next();
10 | const reportTime = Date.now() - startTime;
11 | const { url } = ctx;
12 | // 该接口不做记录/admin/sys/log/page
13 | if (url.startsWith('/api') && !url.startsWith('/api/system/reqlog') && ctx.req.method!=='GET') {
14 | ctx.service.system.reqLog.save(url.split('?')[0],
15 | ctx.req.method === 'GET' ? ctx.request.query : ctx.request.body, ctx.status, reportTime, ctx.req.method, ctx.session && ctx.session.user ? ctx.session.user.id : null);
16 | }
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/server/app/middleware/execption.ts:
--------------------------------------------------------------------------------
1 | import { Context } from 'egg';
2 |
3 | /**
4 | * 统一异常处理
5 | */
6 | export default function Exception(): any {
7 | return async (ctx: Context, next: () => Promise) => {
8 | try {
9 | await next();
10 | } catch (err) {
11 | const { errors } = err;
12 | ctx.logger.error('[Exception]', err.message, errors);
13 | ctx.set('Content-Type', 'application/json');
14 | // 生产环境时 500 错误的详细错误内容不返回给客户端,因为可能包含敏感信息
15 | const status = err.status || 500;
16 | const message = status === 500 && ctx.app.config.env === 'prod' ? '服务器好像出了点问题...稍后再试试' : err.message;
17 | ctx.status = status;
18 | ctx.body = JSON.stringify({
19 | status: err.errorCode || 500,
20 | message,
21 | });
22 | }
23 | };
24 | }
25 |
--------------------------------------------------------------------------------
/server/app/middleware/requireLogin.ts:
--------------------------------------------------------------------------------
1 | import { Context } from 'egg';
2 | module.exports = function(needLogin){
3 | return async function requireLogin(ctx: Context) {
4 | const token = ctx.request.header.authorization;
5 | needLogin = typeof(needLogin)=='undefined'?true:needLogin
6 | // let decode: any;
7 | if (token) {
8 | try {
9 | // 解码token
10 | var pass = false;
11 | ctx.app.jwt.verify(token, ctx.app.config.secret,(err, payload) => {
12 | if(err){
13 | needLogin && ctx.fail(401,err.message||'登录过期')
14 | pass = false
15 | return false
16 | }
17 | else{
18 | ctx.session.user = payload.user;
19 | // console.log('获取到用户===============',payload)
20 | pass =true
21 | }
22 | });
23 |
24 | return pass;
25 | } catch (error) {
26 | needLogin && ctx.fail(401,error.message||'解析失败')
27 | return !needLogin;
28 | }
29 | } else {
30 | needLogin && ctx.fail(401,"未登录")
31 | return !needLogin;
32 | }
33 | }
34 | };
35 |
36 |
--------------------------------------------------------------------------------
/server/app/model/Good.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER,TEXT,DECIMAL } = app.Sequelize;
3 |
4 | const Good = app.model.define('good', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | name: { type: STRING, allowNull: false }, // 商品名称
7 | description: { type: STRING }, // 商品描述
8 | content: { type: TEXT }, // 商品描述
9 | thumbnail: INTEGER, // 缩略图,关联图片id
10 | // salePrice: { type: DECIMAL}, // 售卖价
11 | // marketPrice: { type: DECIMAL}, // 市场价
12 | categoryId: INTEGER, // 关联商品分类
13 | mechantId: INTEGER, // 关联商家id
14 | salePrice: DECIMAL, //售价,用于显示和排序,实际价格以商品规格为主
15 | marketPrice: DECIMAL,
16 | sales: {type: INTEGER, defaultValue: 0}, // 销量,方便做排序
17 | status: { type: INTEGER, defaultValue: 1 }, // 状态: 1:上架 2:下架
18 | },{freezeTableName: true});
19 | // 表关联的字段
20 | Good.associate = function() {
21 | // 一对多
22 | app.model.Good.hasMany(app.model.GoodImage, { foreignKey: 'goodId', targetKey: 'id'});
23 | // 一对多
24 | app.model.Good.hasMany(app.model.GoodSpec, { foreignKey: 'goodId', targetKey: 'id',as:'apecs'});
25 | // 一对一
26 | Good.belongsTo(app.model.GoodCategory, { foreignKey: 'categoryId', targetKey: 'id', as: 'category'});// 一对一
27 | Good.belongsTo(app.model.SystemFile, { foreignKey: 'thumbnail', targetKey: 'id', as: 'thumbnailImage'});
28 | }
29 | return Good;
30 | };
--------------------------------------------------------------------------------
/server/app/model/GoodCategory.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER,TEXT } = app.Sequelize;
3 |
4 | const GoodCategory = app.model.define('good_category', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | name: { type: STRING, allowNull: false }, // 名称
7 | description: { type: TEXT }, // 商品描述
8 | imageId: INTEGER, // 分类图标
9 | parentId: { type: INTEGER}, // 上级Id
10 | merchantId: INTEGER, // 关联商家id
11 | status: { type: INTEGER, defaultValue: 1 }, // 状态: 1:可用 2:禁用
12 | },{freezeTableName: true});
13 | // 表关联的字段
14 | GoodCategory.associate = function() {
15 | GoodCategory.belongsTo(app.model.GoodCategory, { foreignKey: 'parentId', targetKey: 'id', as: 'parent'});
16 | GoodCategory.belongsTo(app.model.SystemFile, { foreignKey: 'imageId', targetKey: 'id', as: 'image'});
17 | }
18 | return GoodCategory;
19 | };
--------------------------------------------------------------------------------
/server/app/model/GoodImage.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { INTEGER } = app.Sequelize;
3 |
4 | const GoodImage = app.model.define('good_image', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | fileId: INTEGER, // 图片id
7 | goodId: INTEGER, // 关联商品id
8 | mechantId: INTEGER, // 关联商家id
9 | },{freezeTableName: true});
10 | // 表关联的字段
11 | GoodImage.associate = function() {
12 | // 一对一
13 | GoodImage.belongsTo(app.model.SystemFile, { foreignKey: 'fileId', targetKey: 'id', as: 'file'});
14 | }
15 | return GoodImage;
16 | };
--------------------------------------------------------------------------------
/server/app/model/GoodOrder.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER,ENUM,DECIMAL } = app.Sequelize;
3 |
4 | const GoodOrder = app.model.define('good_order', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | orderNo: { type: STRING, unique:true, allowNull: false }, // 商品名称
7 | // ordered: '待付款', inpayment: '付款中', paid: '已付款,待发货', receiving: '已发货,待收货', completed: '已完成', canceled: '已取消',closed:已关闭
8 | status: ENUM('ordered', 'inpayment', 'paid', 'receiving', 'completed', 'canceled','closed'),
9 | addressId: INTEGER, // 地址Id
10 | address: STRING,//收货地址:省市区街道+详细
11 | linkMan: STRING,
12 | linkPhone: STRING,
13 | goodsTotalQty: DECIMAL,//商品总数量
14 | totalAmount:DECIMAL,
15 | merchantId: INTEGER,
16 | shopName: STRING,
17 | remark:STRING,//备注
18 | userName: STRING,
19 | userId: INTEGER,
20 |
21 | },{freezeTableName: true});
22 | // 表关联的字段
23 | GoodOrder.associate = function() {
24 | // 一对多
25 | app.model.GoodOrder.hasMany(app.model.GoodOrderLine, { foreignKey: 'orderId', targetKey: 'id',as:'goodList'});
26 | GoodOrder.belongsTo(app.model.Merchant, { foreignKey: 'merchantId', targetKey: 'id', as: 'merchant'});// 一对一
27 | GoodOrder.belongsTo(app.model.SystemUser, { foreignKey: 'userId', targetKey: 'id', as: 'user'});
28 | }
29 | return GoodOrder;
30 | };
--------------------------------------------------------------------------------
/server/app/model/GoodOrderLine.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER,DECIMAL } = app.Sequelize;
3 |
4 | const GoodOrderLine = app.model.define('good_order_line', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | goodId: INTEGER,
7 | goodName: STRING,
8 | salePrice: DECIMAL,
9 | marketPrice: DECIMAL,
10 | qty: INTEGER,
11 | amount: DECIMAL,
12 | orderId: INTEGER,
13 | goodPic: STRING,
14 | goodSpecId: INTEGER,
15 | goodSpecName: STRING,
16 | goodCategoryName: STRING,
17 | goodCategoryId: INTEGER,
18 |
19 | },{freezeTableName: true});
20 | // 表关联的字段
21 | GoodOrderLine.associate = function() {
22 |
23 | }
24 | return GoodOrderLine;
25 | };
--------------------------------------------------------------------------------
/server/app/model/GoodSpec.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER,DECIMAL,TEXT } = app.Sequelize;
3 |
4 | const GoodSpec = app.model.define('good_spec', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | name: { type: STRING, allowNull: false }, // 规格名称
7 | description: { type: TEXT }, // 商品描述
8 | pic: { type: STRING}, // 缩略图
9 | salePrice: { type: DECIMAL}, // 售卖价
10 | marketPrice: { type: DECIMAL}, // 市场价
11 | stock: INTEGER, // 库存
12 | sales: {type: INTEGER, defaultValue: 0}, //销量
13 | goodId: INTEGER, // 关联商品id
14 | mechantId: INTEGER, // 关联商家id
15 | },{freezeTableName: true});
16 |
17 | return GoodSpec;
18 | };
--------------------------------------------------------------------------------
/server/app/model/LogMessage.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER } = app.Sequelize;
3 |
4 | const Message = app.model.define('log_message', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | title: STRING, // 消息名
7 | content: STRING, //消息内容
8 | sender: { type: INTEGER, defaultValue: 1 }, //发送者,1 系统,2 其他
9 | receiver: INTEGER, // 接收消息的人,0:全部成员,其他 用户id
10 | status: { type: INTEGER, defaultValue: 1 },//1 未读 2 已读
11 | },{freezeTableName: true});
12 |
13 | return Message;
14 | };
--------------------------------------------------------------------------------
/server/app/model/Merchant.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER } = app.Sequelize;
3 |
4 | const Merchant = app.model.define('merchant', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | appId: { type: STRING, unique: true, }, // 小程序appId
7 | appSecret: { type: STRING }, // 邮箱
8 | mchId: { type: STRING}, // 微信商户id
9 | mchKey: { type: STRING}, // 微信商户key
10 | name: STRING, // 商户名称
11 | userId: INTEGER, // 关联用户id
12 | status: { type: INTEGER, defaultValue: 1 }, // 状态: 1:启用 2:禁用
13 | address: STRING,//商户地址
14 | logoId: INTEGER
15 | // session_key: STRING, // 微信session_key
16 | },{freezeTableName: true});
17 | // 表关联的字段
18 | Merchant.associate = function() {
19 | Merchant.belongsTo(app.model.SystemFile, { foreignKey: 'logoId', targetKey: 'id', as: 'logo'});
20 | }
21 | return Merchant;
22 | };
--------------------------------------------------------------------------------
/server/app/model/SystemFile.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER } = app.Sequelize;
3 |
4 | const SystemFile = app.model.define('system_file', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | format: STRING,
7 | url: STRING,//文件路径,相对路径,用于前端图片访问
8 | path: STRING,//物理路径,服务器上的路径
9 | size: INTEGER,//文件大小
10 | name: STRING,//文件名称
11 | type: STRING,//文件类型 image/video/application
12 | creator: INTEGER,//创建的用户id
13 | },{freezeTableName: true,timestamps: true});
14 |
15 | return SystemFile;
16 | };
--------------------------------------------------------------------------------
/server/app/model/SystemMenu.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER } = app.Sequelize;
3 |
4 | const User = app.model.define('system_menu', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | name: STRING, // 菜单名
7 | url: STRING, //菜单路径
8 | icon: STRING, //菜单图标
9 | parentId: { type: INTEGER, defaultValue: null }, // 上级菜单id
10 | sort: INTEGER,
11 | status: { type: INTEGER, defaultValue: 1 }, // 状态: 0:禁用, 1:启用
12 | },{freezeTableName: true});
13 |
14 | return User;
15 | };
--------------------------------------------------------------------------------
/server/app/model/SystemPermission.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING } = app.Sequelize;
3 |
4 | const Permission = app.model.define('system_permission', {
5 | id: { type: STRING, primaryKey: true },//权限id
6 | name: STRING, //权限名
7 | describe: STRING, //描述
8 | actions: STRING, // 操作
9 | },{freezeTableName: true});
10 |
11 | return Permission;
12 | };
--------------------------------------------------------------------------------
/server/app/model/SystemReqLog.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER } = app.Sequelize;
3 |
4 | const ReqLog = app.model.define('system_req_log', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | ip: STRING,
7 | userId: INTEGER,
8 | params: STRING,
9 | action: STRING,
10 | method: STRING,
11 | status: { type: INTEGER }, // 状态: 0:禁用, 1:启用
12 | consumeTime: INTEGER
13 | // session_key: STRING, // 微信session_key
14 | },{timestamps: true,freezeTableName: true});
15 | // 表关联的字段
16 | ReqLog.associate = function() {
17 | // 一对一
18 | ReqLog.belongsTo(app.model.SystemUser, { foreignKey: 'userId', targetKey: 'id', as: 'user'});
19 | }
20 | return ReqLog;
21 | };
--------------------------------------------------------------------------------
/server/app/model/SystemRole.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER } = app.Sequelize;
3 |
4 | const User = app.model.define('system_role', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | name: STRING, // 角色名
7 | describe: STRING, // 角色描述
8 | status: { type: INTEGER, defaultValue: 1 }, // 状态: 0:禁用, 1:启用
9 | // session_key: STRING, // 微信session_key
10 | },{timestamps: true,freezeTableName: true});
11 |
12 | return User;
13 | };
--------------------------------------------------------------------------------
/server/app/model/SystemRoleMenu.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { INTEGER } = app.Sequelize;
3 |
4 | const RoleMenu = app.model.define('system_role_menu', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | roleId: INTEGER, // 角色Id
7 | menuId: INTEGER, //菜单Id
8 | },{freezeTableName: true});
9 | // 表关联的字段
10 | RoleMenu.associate = function() {
11 | /**
12 | * User.belongsTo(关联的模型, { foreignKey: '使用什么字段关联', targetKey: '与关联的模型那个字段关联', as: '别名' });
13 | */
14 | // 一对一
15 | RoleMenu.belongsTo(app.model.SystemMenu, { foreignKey: 'menuId', targetKey: 'id', as: 'menu'});
16 | }
17 | return RoleMenu;
18 | };
--------------------------------------------------------------------------------
/server/app/model/SystemRolePermission.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { INTEGER,STRING } = app.Sequelize;
3 |
4 | const RolePermission = app.model.define('system_role_permission', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | roleId: INTEGER, // 角色Id
7 | permissionId: STRING, //权限Id
8 | actions: STRING
9 | },{freezeTableName: true});
10 | // 表关联的字段
11 | RolePermission.associate = function() {
12 | /**
13 | * User.belongsTo(关联的模型, { foreignKey: '使用什么字段关联', targetKey: '与关联的模型那个字段关联', as: '别名' });
14 | */
15 | // 一对一
16 | RolePermission.belongsTo(app.model.SystemPermission, { foreignKey: 'permissionId', targetKey: 'id', as: 'permission'});
17 | }
18 | return RolePermission;
19 | };
--------------------------------------------------------------------------------
/server/app/model/SystemUser.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER } = app.Sequelize;
3 |
4 | const User = app.model.define('system_user', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | username: { type: STRING, unique: true, allowNull: false }, // 用户名
7 | email: { type: STRING }, // 邮箱
8 | password: { type: STRING, allowNull: false }, // 密码
9 | name: STRING, // 姓名
10 | sex: { type: INTEGER, defaultValue: 1 }, // 用户性别:1男性, 2女性, 0未知
11 | // age: { type: INTEGER, defaultValue: 0 }, // 年龄
12 | avatarId: INTEGER, // 头像
13 | type: INTEGER, // 类型,1:管理员,2:商家,3:普通用户
14 | phone: { type: STRING }, // 手机号码
15 | roleId: INTEGER, // 角色id
16 | status: { type: INTEGER, defaultValue: 1 }, // 用户状态: 0:禁用, 1:启用
17 | lastLoginTime: INTEGER, // 上次登录时间
18 | unionid: STRING, // 微信unionid
19 | openid: STRING, // 微信openid
20 | // session_key: STRING, // 微信session_key
21 | },{freezeTableName: true});
22 |
23 | // 表关联的字段
24 | User.associate = function() {
25 | // 一对多
26 | // app.model.User.hasMany(app.model.Diary, { foreignKey: 'user_id', targetKey: 'id'});
27 | /**
28 | * User.belongsTo(关联的模型, { foreignKey: '使用什么字段关联', targetKey: '与关联的模型那个字段关联', as: '别名' });
29 | */
30 | // 一对一
31 | User.belongsTo(app.model.SystemFile, { foreignKey: 'avatarId', targetKey: 'id', as: 'avatar'});
32 | User.belongsTo(app.model.SystemRole, { foreignKey: 'roleId', targetKey: 'id', as: 'role'});
33 | }
34 | return User;
35 | };
--------------------------------------------------------------------------------
/server/app/model/UserAddress.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { STRING, INTEGER,BOOLEAN,DOUBLE } = app.Sequelize;
3 |
4 | const UserAddress = app.model.define('user_address', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | province: { type: STRING, allowNull: false }, // 省
7 | city: { type: STRING }, // 市
8 | district: { type: STRING, }, // 区
9 | township: STRING, // 街道
10 | place: STRING, //详细地址
11 | linkMan: STRING,
12 | linkPhone: STRING,
13 | isDefault: BOOLEAN,
14 | longitude: DOUBLE, //
15 | latitude: DOUBLE,
16 | userId: INTEGER,
17 | // session_key: STRING, // 微信session_key
18 | },{freezeTableName: true});
19 |
20 | // 表关联的字段
21 | UserAddress.associate = function() {
22 | // 一对一
23 | UserAddress.belongsTo(app.model.SystemUser, { foreignKey: 'userId', targetKey: 'id', as: 'user'});
24 | }
25 | return UserAddress;
26 | };
--------------------------------------------------------------------------------
/server/app/model/UserFav.ts:
--------------------------------------------------------------------------------
1 | module.exports = app => {
2 | const { INTEGER } = app.Sequelize;
3 |
4 | const UserFav = app.model.define('user_fav', {
5 | id: { type: INTEGER, primaryKey: true, autoIncrement: true },
6 | goodId: INTEGER,
7 | userId: INTEGER,
8 | // session_key: STRING, // 微信session_key
9 | },{freezeTableName: true});
10 |
11 | // 表关联的字段
12 | UserFav.associate = function() {
13 | // 一对一
14 | UserFav.belongsTo(app.model.SystemUser, { foreignKey: 'userId', targetKey: 'id', as: 'user'});
15 | UserFav.belongsTo(app.model.Good, { foreignKey: 'goodId', targetKey: 'id', as: 'good'});
16 | }
17 | return UserFav;
18 | };
--------------------------------------------------------------------------------
/server/app/public/doc/api_project.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tinyshop商城",
3 | "version": "0.1.0",
4 | "description": "tinyshop商城api文档",
5 | "title": "tinyshop商城API文档",
6 | "url": "http://mall.tucy.top",
7 | "sampleUrl": false,
8 | "defaultVersion": "0.0.0",
9 | "apidoc": "0.3.0",
10 | "generator": {
11 | "name": "apidoc",
12 | "time": "2021-01-15T13:43:52.945Z",
13 | "url": "https://apidocjs.com",
14 | "version": "0.26.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/server/app/public/doc/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/server/app/public/doc/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/server/app/public/doc/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/server/app/public/doc/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/server/app/public/doc/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/server/app/public/doc/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/server/app/public/doc/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/server/app/public/doc/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/server/app/public/doc/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/server/app/public/doc/img/favicon.ico
--------------------------------------------------------------------------------
/server/app/public/doc/vendor/path-to-regexp/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
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
13 | all 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
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/server/app/public/doc/vendor/prism.css:
--------------------------------------------------------------------------------
1 | /* PrismJS 1.21.0
2 | https://prismjs.com/download.html#themes=prism-tomorrow&languages=clike+javascript+bash+c+csharp+cpp+clojure+elixir+erlang+go+http+json+json5+jsonp+lua+perl+python+rust */
3 | /**
4 | * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML
5 | * Based on https://github.com/chriskempson/tomorrow-theme
6 | * @author Rose Pritchard
7 | */
8 |
9 | code[class*="language-"],
10 | pre[class*="language-"] {
11 | color: #ccc;
12 | background: none;
13 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
14 | font-size: 1em;
15 | text-align: left;
16 | white-space: pre;
17 | word-spacing: normal;
18 | word-break: normal;
19 | word-wrap: normal;
20 | line-height: 1.5;
21 |
22 | -moz-tab-size: 4;
23 | -o-tab-size: 4;
24 | tab-size: 4;
25 |
26 | -webkit-hyphens: none;
27 | -moz-hyphens: none;
28 | -ms-hyphens: none;
29 | hyphens: none;
30 |
31 | }
32 |
33 | /* Code blocks */
34 | pre[class*="language-"] {
35 | padding: 1em;
36 | margin: .5em 0;
37 | overflow: auto;
38 | }
39 |
40 | :not(pre) > code[class*="language-"],
41 | pre[class*="language-"] {
42 | background: #2d2d2d;
43 | }
44 |
45 | /* Inline code */
46 | :not(pre) > code[class*="language-"] {
47 | padding: .1em;
48 | border-radius: .3em;
49 | white-space: normal;
50 | }
51 |
52 | .token.comment,
53 | .token.block-comment,
54 | .token.prolog,
55 | .token.doctype,
56 | .token.cdata {
57 | color: #999;
58 | }
59 |
60 | .token.punctuation {
61 | color: #ccc;
62 | }
63 |
64 | .token.tag,
65 | .token.attr-name,
66 | .token.namespace,
67 | .token.deleted {
68 | color: #e2777a;
69 | }
70 |
71 | .token.function-name {
72 | color: #6196cc;
73 | }
74 |
75 | .token.boolean,
76 | .token.number,
77 | .token.function {
78 | color: #f08d49;
79 | }
80 |
81 | .token.property,
82 | .token.class-name,
83 | .token.constant,
84 | .token.symbol {
85 | color: #f8c555;
86 | }
87 |
88 | .token.selector,
89 | .token.important,
90 | .token.atrule,
91 | .token.keyword,
92 | .token.builtin {
93 | color: #cc99cd;
94 | }
95 |
96 | .token.string,
97 | .token.char,
98 | .token.attr-value,
99 | .token.regex,
100 | .token.variable {
101 | color: #7ec699;
102 | }
103 |
104 | .token.operator,
105 | .token.entity,
106 | .token.url {
107 | color: #67cdcc;
108 | }
109 |
110 | .token.important,
111 | .token.bold {
112 | font-weight: bold;
113 | }
114 | .token.italic {
115 | font-style: italic;
116 | }
117 |
118 | .token.entity {
119 | cursor: help;
120 | }
121 |
122 | .token.inserted {
123 | color: green;
124 | }
125 |
126 |
--------------------------------------------------------------------------------
/server/app/router.ts:
--------------------------------------------------------------------------------
1 | import { Application } from 'egg';
2 | import { Blueprint } from 'egg-blueprint'
3 |
4 | export default (app: Application) => {
5 | const { controller, router } = app;
6 | router.get('/test1', controller.home.test);
7 | Blueprint(app);
8 | };
9 |
--------------------------------------------------------------------------------
/server/app/service/good/category.ts:
--------------------------------------------------------------------------------
1 | import { Service } from 'egg';
2 |
3 | /**
4 | * role Service
5 | */
6 | export default class CategoryService extends Service {
7 |
8 | /**
9 | * 列表
10 | * @param params - 列表查询参数
11 | */
12 | public async list(options) {
13 | let {page = 1, pageSize = this.config.pageSize} = options
14 | let list = await this.app.model.GoodCategory.findAndCountAll({
15 | limit: +pageSize,
16 | offset: pageSize * (page-1),
17 | order:[
18 | ['created_at','DESC']
19 | ],
20 | include:[
21 | {model: this.app.model.GoodCategory,as: 'parent'},
22 | {model: this.app.model.SystemFile,as: 'image'},
23 | ]
24 | })
25 | return list;
26 | }
27 | /**
28 | * 列表
29 | * @param params - 列表查询参数
30 | */
31 | public async select(options) {
32 | var where = {};
33 | for(const i in options){
34 | options[i] && (where[i] = options[i])
35 | }
36 | let list = await this.app.model.GoodCategory.findAll({
37 | where: where,
38 | include:[
39 | {model: this.app.model.SystemFile,as: 'image'},
40 | ]
41 | })
42 | return list;
43 | }
44 |
45 | /**
46 | * 保存
47 | * @param options - 参数
48 | */
49 | public async save(options: any) {
50 | const { ctx } = this
51 | let results = { code: 400, message: "失败", }
52 | if(!options.parentId){
53 | delete options.parentId;
54 | }
55 | await ctx.model.GoodCategory.upsert(options).then(() => {
56 | results = { code: 0, message: "添加成功", }
57 | }).catch(err => {
58 | results = { code: 400, message: err, }
59 | })
60 |
61 | return results
62 | }
63 |
64 | public async detail(id){
65 | // const { ctx } = this
66 | let data = await this.app.model.GoodCategory.findOne({where: {id}})
67 | return data
68 | }
69 | //删除
70 | public async remove(id){
71 | let results
72 | await this.ctx.model.GoodCategory.destroy({ where: { id}}).then(() => {
73 | results = { code: 0, message: "删除成功", }
74 | }).catch(error => {
75 | results = { code: 400, message: error, }
76 | })
77 | return results
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/server/app/service/log/message.ts:
--------------------------------------------------------------------------------
1 | import { Service } from 'egg';
2 |
3 |
4 | /**
5 | * role Service
6 | */
7 | export default class MessageService extends Service {
8 |
9 | /**
10 | * 列表
11 | * @param params - 列表查询参数
12 | */
13 | public async list(options) {
14 | let {page = 1, pageSize = this.config.pageSize} = options
15 | let list = await this.app.model.LogMessage.findAndCountAll({
16 | limit: +pageSize,
17 | offset: pageSize * (page-1)
18 | })
19 | return list;
20 | }
21 |
22 | /**
23 | * 保存
24 | * @param options - 参数
25 | */
26 | public async save(options: any) {
27 | const { ctx } = this
28 | let results = { code: 400, message: "失败", }
29 | await ctx.model.LogMessage.upsert(options).then(() => {
30 | results = { code: 0, message: "添加成功", }
31 | }).catch(err => {
32 | results = { code: 400, message: err, }
33 | })
34 |
35 | return results
36 | }
37 |
38 | public async detail(id){
39 | // const { ctx } = this
40 | let data = await this.app.model.LogMessage.findOne({where: {id}})
41 | return data
42 | }
43 | //删除
44 | public async remove(id){
45 | let results
46 | await this.ctx.model.LogMessage.destroy({ where: { id}}).then(() => {
47 | results = { code: 0, message: "删除成功", }
48 | }).catch(error => {
49 | results = { code: 400, message: error, }
50 | })
51 | return results
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/server/app/service/member/address.ts:
--------------------------------------------------------------------------------
1 | import { Service } from 'egg';
2 |
3 | /**
4 | * role Service
5 | */
6 | export default class AddressService extends Service {
7 |
8 | /**
9 | * 列表
10 | * @param params - 列表查询参数
11 | */
12 | public async list(options) {
13 | const { ctx } = this
14 | let {page = 1, pageSize = this.config.pageSize} = options
15 | const where = {userId: ctx.session.user.id};
16 | if(typeof options.isDefault !== 'undefined'){
17 | where['isDefault']=options.isDefault?true:false
18 | }
19 | let list = await this.app.model.UserAddress.findAndCountAll({
20 | limit: +pageSize,
21 | offset: pageSize * (page-1),
22 | where: where
23 | })
24 | return list;
25 | }
26 | /**
27 | * 列表
28 | * @param params - 列表查询参数
29 | */
30 | public async select() {
31 | let list = await this.app.model.UserAddress.findAll()
32 | return list;
33 | }
34 |
35 | /**
36 | * 保存
37 | * @param options - 参数
38 | */
39 | public async save(options: any) {
40 | const { ctx } = this
41 | let results = { code: 400, message: "失败", }
42 | options.userId = ctx.session.user.id;
43 |
44 | if(options.isDefault){//先将其它地址默认地址去掉
45 | await ctx.model.UserAddress.update({isDefault: false},{
46 | where:{userId: ctx.session.user.id}
47 | })
48 | }
49 | await ctx.model.UserAddress.upsert(options).then(() => {
50 | results = { code: 0, message: "添加成功", }
51 | }).catch(err => {
52 | results = { code: 400, message: err, }
53 | })
54 |
55 | return results
56 | }
57 | public async detail(id){
58 | // const { ctx } = this
59 | let data = await this.app.model.UserAddress.findOne({where: {id}})
60 | return data
61 | }
62 | //删除
63 | public async remove(id){
64 | let results
65 | await this.ctx.model.UserAddress.destroy({ where: { id}}).then(() => {
66 | results = { code: 0, message: "删除成功", }
67 | }).catch(error => {
68 | results = { code: 400, message: error, }
69 | })
70 | return results
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/server/app/service/member/fav.ts:
--------------------------------------------------------------------------------
1 | import { Service } from 'egg';
2 |
3 | /**
4 | * role Service
5 | */
6 | export default class FavService extends Service {
7 |
8 | /**
9 | * 列表
10 | * @param params - 列表查询参数
11 | */
12 | public async list(options) {
13 | const { ctx } = this
14 | let {page = 1, pageSize = this.config.pageSize} = options
15 | const where = {userId: ctx.session.user.id};
16 | let list = await this.app.model.UserFav.findAndCountAll({
17 | limit: +pageSize,
18 | offset: pageSize * (page-1),
19 | where: where,
20 | include:[
21 | {model: this.app.model.Good, as:'good',include:[{model:this.app.model.SystemFile,as:'thumbnailImage'}]}
22 | ]
23 | })
24 | return list;
25 | }
26 | /**
27 | * 列表
28 | * @param params - 列表查询参数
29 | */
30 | public async select() {
31 | let list = await this.app.model.UserFav.findAll()
32 | return list;
33 | }
34 |
35 | /**
36 | * 保存
37 | * @param options - 参数
38 | */
39 | public async save(options: any) {
40 | const { ctx } = this
41 | let results = { code: 400, message: "失败", }
42 | options.userId = ctx.session.user.id;
43 |
44 | await ctx.model.UserFav.upsert(options).then(() => {
45 | results = { code: 0, message: "添加成功", }
46 | }).catch(err => {
47 | results = { code: 400, message: err, }
48 | })
49 |
50 | return results
51 | }
52 | public async detail(id){
53 | // const { ctx } = this
54 | let data = await this.app.model.UserFav.findOne({where: {id}})
55 | return data
56 | }
57 | //删除
58 | public async remove(id){
59 | let results
60 | await this.ctx.model.UserFav.destroy({ where: { id}}).then(() => {
61 | results = { code: 0, message: "删除成功", }
62 | }).catch(error => {
63 | results = { code: 400, message: error, }
64 | })
65 | return results
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/server/app/service/merchant/index.ts:
--------------------------------------------------------------------------------
1 | import { Service } from 'egg';
2 |
3 | /**
4 | * role Service
5 | */
6 | export default class MerchantService extends Service {
7 |
8 | /**
9 | * 列表
10 | * @param params - 列表查询参数
11 | */
12 | public async list(options) {
13 | let {page = 1, pageSize = this.config.pageSize} = options
14 | let list = await this.app.model.Merchant.findAndCountAll({
15 | limit: +pageSize,
16 | offset: pageSize * (page-1),
17 | include:[
18 | {model: this.app.model.SystemFile,as:'logo'}
19 | ]
20 | })
21 | return list;
22 | }
23 | /**
24 | * 列表
25 | * @param params - 列表查询参数
26 | */
27 | public async select() {
28 | let list = await this.app.model.Merchant.findAll()
29 | return list;
30 | }
31 |
32 | /**
33 | * 保存
34 | * @param options - 参数
35 | */
36 | public async save(options: any) {
37 | const { ctx } = this
38 | let results = { code: 400, message: "失败", }
39 | await ctx.model.Merchant.upsert(options).then(() => {
40 | results = { code: 0, message: "添加成功", }
41 | }).catch(err => {
42 | results = { code: 400, message: err, }
43 | })
44 |
45 | return results
46 | }
47 | /**
48 | * 保存
49 | * @param options - 参数
50 | */
51 | public async update(options: any) {
52 | const { ctx } = this
53 | let results = { code: 400, message: "失败", }
54 | await ctx.model.Merchant.update(options,{
55 | where:{id: options.id}
56 | }).then(() => {
57 | results = { code: 0, message: "添加成功", }
58 | }).catch(err => {
59 | results = { code: 400, message: err, }
60 | })
61 |
62 | return results
63 | }
64 | public async detail(id){
65 | // const { ctx } = this
66 | let data = await this.app.model.Merchant.findOne({where: {id}})
67 | return data
68 | }
69 | //删除
70 | public async remove(id){
71 | let results
72 | await this.ctx.model.Merchant.destroy({ where: { id}}).then(() => {
73 | results = { code: 0, message: "删除成功", }
74 | }).catch(error => {
75 | results = { code: 400, message: error, }
76 | })
77 | return results
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/server/app/service/system/file.ts:
--------------------------------------------------------------------------------
1 | import { Service } from 'egg';
2 | const fs = require('mz/fs');
3 | /**
4 | * role Service
5 | */
6 | export default class FileService extends Service {
7 |
8 | /**
9 | * 列表
10 | * @param params - 列表查询参数
11 | */
12 | public async list(options) {
13 | let {page = 1, pageSize = this.config.pageSize} = options
14 | let list = await this.app.model.SystemFile.findAndCountAll({
15 | limit: +pageSize,
16 | offset: pageSize * (page-1)
17 | })
18 | return list;
19 | }
20 | /**
21 | * 列表
22 | * @param params - 列表查询参数
23 | */
24 | public async select() {
25 | let list = await this.app.model.SystemFile.findAll()
26 | return list;
27 | }
28 |
29 | /**
30 | * 保存
31 | * @param options - 参数
32 | */
33 | public async save(options: any) {
34 | const { ctx } = this
35 | let results = { code: 400, message: "失败", }
36 | await ctx.model.SystemFile.upsert(options).then(() => {
37 | results = { code: 0, message: "添加成功", }
38 | }).catch(err => {
39 | results = { code: 400, message: err, }
40 | })
41 |
42 | return results
43 | }
44 |
45 | public async detail(id){
46 | // const { ctx } = this
47 | let data = await this.app.model.SystemFile.findOne({where: {id}})
48 | return data
49 | }
50 | //删除
51 | public async remove(id){
52 | let results
53 | let data = await this.app.model.SystemFile.findOne({where: {id}})
54 |
55 | await this.ctx.model.SystemFile.destroy({ where: { id}}).then(() => {
56 | results = { code: 0, message: "删除成功", }
57 | }).catch(error => {
58 | results = { code: 400, message: error, }
59 | })
60 | if(results.code===0 && data){
61 | try{
62 | await fs.unlinkSync(data.path)
63 | }catch(e){
64 | console.log('err==================',e)
65 | }
66 | }
67 | return results
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/server/app/service/system/permission.ts:
--------------------------------------------------------------------------------
1 | import { Service } from 'egg';
2 |
3 |
4 | /**
5 | * role Service
6 | */
7 | export default class PermissionService extends Service {
8 |
9 | /**
10 | * 列表
11 | * @param params - 列表查询参数
12 | */
13 | public async list(options) {
14 | let {page = 1, pageSize = this.config.pageSize} = options
15 | let list = await this.app.model.SystemPermission.findAndCountAll({
16 | limit: +pageSize,
17 | offset: pageSize * (page-1)
18 | })
19 | return list;
20 | }
21 | /**
22 | * 不分页列表
23 | * @param params - 列表查询参数
24 | */
25 | public async select() {
26 | let list = await this.app.model.SystemPermission.findAll()
27 | return list;
28 | }
29 |
30 | /**
31 | * 保存
32 | * @param options - 参数
33 | */
34 | public async save(options: any) {
35 | const { ctx } = this
36 | let results = { code: 400, message: "失败", }
37 | await ctx.model.SystemPermission.upsert(options).then(() => {
38 | results = { code: 0, message: "添加成功", }
39 | }).catch(err => {
40 | results = { code: 400, message: err, }
41 | })
42 |
43 | return results
44 | }
45 |
46 | public async detail(id){
47 | // const { ctx } = this
48 | let data = await this.app.model.SystemPermission.findOne({where: {id}})
49 | return data
50 | }
51 | //删除
52 | public async remove(id){
53 | let results
54 | await this.ctx.model.SystemPermission.destroy({ where: { id}}).then(() => {
55 | results = { code: 0, message: "删除成功", }
56 | }).catch(error => {
57 | results = { code: 400, message: error, }
58 | })
59 | return results
60 | }
61 | // 获取角色菜单
62 | async getMenuTree (roleId:number) {
63 | const { ctx } = this
64 | let list = await ctx.model.SystemPermissionMenu.findAll({
65 | where: {roleId: roleId},
66 | include:[
67 | {model: this.app.model.SystemMenu,as: 'menu'}
68 | ]
69 | })
70 | list = list.map(item=>item.menu);
71 | let result:Array = [];
72 | let find = (menus,parentId)=>{
73 | list.filter(item=>item.parentId==parentId).map(item=>{
74 | item.dataValues.children = [];
75 | find(item.dataValues.children,item.id);
76 | menus.push(item);
77 | })
78 | }
79 | find(result,null);
80 | return result
81 | }
82 |
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/server/app/service/system/req_log.ts:
--------------------------------------------------------------------------------
1 | import { Service } from 'egg';
2 |
3 | /**
4 | * 请求追踪服务
5 | */
6 | export default class SysReqLogService extends Service {
7 |
8 | /**
9 | * 记录日志
10 | */
11 | async save(url: string, params: string, status: number, consumeTime: number, method: string | undefined, userId: number | null) {
12 | const ip = this.ctx.helper.getReqIP();
13 | await this.app.model.SystemReqLog.create({
14 | action: url,
15 | params: JSON.stringify(params),
16 | userId: userId === null ? undefined : userId,
17 | ip,
18 | method: method ? method.toUpperCase() : undefined,
19 | status,
20 | consumeTime,
21 | });
22 | }
23 |
24 | /**
25 | * 计算日志总数
26 | */
27 | async count() {
28 | return await this.app.model.SystemReqLog.count();
29 | }
30 |
31 | /**
32 | * 分页加载日志信息
33 | */
34 | async list(options) {
35 | let {page = 1, pageSize = this.config.pageSize} = options
36 | const result = await this.app.model.SystemReqLog.findAndCountAll({
37 | order: [
38 | ["id", 'DESC'],
39 | ],
40 | limit: +pageSize,
41 | offset: pageSize * (page-1),
42 | include:[
43 | {model: this.app.model.SystemUser,as:'user'}
44 | ]
45 | });
46 | return result;
47 | }
48 |
49 |
50 | //删除
51 | public async remove(id){
52 | let results
53 | await this.ctx.model.SystemReqLog.destroy({ where: { id}}).then(() => {
54 | results = { code: 0, message: "删除成功", }
55 | }).catch(error => {
56 | results = { code: 400, message: error, }
57 | })
58 | return results
59 | }
60 |
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/server/appveyor.yml:
--------------------------------------------------------------------------------
1 | environment:
2 | matrix:
3 | - nodejs_version: '8'
4 |
5 | install:
6 | - ps: Install-Product node $env:nodejs_version
7 | - npm i npminstall && node_modules\.bin\npminstall
8 |
9 | test_script:
10 | - node --version
11 | - npm --version
12 | - npm run test
13 |
14 | build: off
15 |
--------------------------------------------------------------------------------
/server/config/config.default.ts:
--------------------------------------------------------------------------------
1 | import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg';
2 |
3 | export default (appInfo: EggAppInfo) => {
4 | const config = {} as PowerPartial;
5 |
6 | // override config from framework / plugin
7 | // use for cookie sign key, should change to your own and keep security
8 | config.keys = appInfo.name + '_1598064376175_9435';
9 |
10 | // add your egg config in here
11 |
12 | // config.middleware = [ 'adminReqLog', 'execption', 'adminAuthority' ];
13 | config.middleware = ['adminReqLog','execption'];
14 |
15 | // add your special config in here
16 | const bizConfig = {
17 | sourceUrl: `https://github.com/eggjs/examples/tree/master/${appInfo.name}`,
18 | };
19 |
20 | config.jwt = {
21 | secret: "12345678",
22 | enable: false,
23 | }
24 | config.security= {
25 | csrf : {
26 | enable: false,
27 | },
28 | domainWhiteList: [ '*' ]
29 | }
30 | config.cors = {
31 | origin: '*',
32 | allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS'
33 | };
34 | config.sequelize = {
35 | timezone: '+08:00',
36 | dialectOptions: {
37 | dateStrings: true,
38 | typeCast(field, next) {
39 | // for reading from database
40 | if (field.type === "DATETIME") {
41 | return field.string();
42 | }
43 | return next();
44 | }
45 | }
46 | }
47 | config.multipart = {
48 | mode: 'file',
49 | fileSize: '100mb',
50 | };
51 | config.pageSize = 20
52 |
53 | // the return config will combines to EggAppConfig
54 | return {
55 | ...config,
56 | ...bizConfig,
57 | };
58 | };
59 |
--------------------------------------------------------------------------------
/server/config/config.local.ts:
--------------------------------------------------------------------------------
1 | import { EggAppConfig, PowerPartial } from 'egg';
2 |
3 | export default () => {
4 | const config: PowerPartial = {};
5 | config.sequelize = {
6 | dialect: "mysql",// 数据库类型
7 | host: "localhost",// host
8 | port: 3306,// 端口号
9 | username: "root",// 用户名
10 | password: "123456",// 密码
11 | database: "eggjs-uniapp-shop"// 数据库名
12 | };
13 |
14 | return config;
15 | };
16 |
--------------------------------------------------------------------------------
/server/config/config.prod.ts:
--------------------------------------------------------------------------------
1 | import { EggAppConfig, PowerPartial } from 'egg';
2 |
3 | export default () => {
4 | const config: PowerPartial = {};
5 | config.sequelize = {
6 | dialect: "mysql",// 数据库类型
7 | host: "localhost",// host
8 | port: 3306,// 端口号
9 | username: "root",// 用户名
10 | password: "root",// 密码
11 | database: "eggjs-uniapp-shop"// 数据库名
12 | };
13 | return config;
14 | };
15 |
--------------------------------------------------------------------------------
/server/config/plugin.ts:
--------------------------------------------------------------------------------
1 | import { EggPlugin } from 'egg';
2 |
3 | const plugin: EggPlugin = {
4 | // static: true,
5 | // nunjucks: {
6 | // enable: true,
7 | // package: 'egg-view-nunjucks',
8 | // },
9 | jwt: {
10 | enable: true,
11 | package: "egg-jwt",
12 | },
13 | sequelize: {
14 | enable: true,
15 | package: 'egg-sequelize'
16 | },
17 | cors: {
18 | enable: true,
19 | package: 'egg-cors'
20 | }
21 | };
22 |
23 | export default plugin;
24 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eggjs-uniapp-shop",
3 | "version": "1.0.0",
4 | "description": "",
5 | "private": true,
6 | "egg": {
7 | "typescript": true,
8 | "declarations": true
9 | },
10 | "scripts": {
11 | "start": "egg-scripts start --daemon --title=egg-server-eggjs-uniapp-shop",
12 | "stop": "egg-scripts stop --title=egg-server-eggjs-uniapp-shop",
13 | "dev": "egg-bin dev",
14 | "debug": "egg-bin debug",
15 | "test-local": "egg-bin test",
16 | "test": "npm run lint -- --fix && npm run test-local",
17 | "cov": "egg-bin cov",
18 | "tsc": "ets && tsc -p tsconfig.json",
19 | "ci": "npm run lint && npm run cov && npm run tsc",
20 | "autod": "autod",
21 | "lint": "eslint . --ext .ts",
22 | "clean": "ets clean"
23 | },
24 | "dependencies": {
25 | "dayjs": "^1.9.7",
26 | "egg": "^2.6.1",
27 | "egg-blueprint": "^1.2.1",
28 | "egg-cors": "^2.2.3",
29 | "egg-jwt": "^3.1.7",
30 | "egg-redis": "^2.4.0",
31 | "egg-scripts": "^2.6.0",
32 | "egg-sequelize": "^5.2.2",
33 | "mysql2": "^2.1.0"
34 | },
35 | "devDependencies": {
36 | "@types/mocha": "^2.2.40",
37 | "@types/node": "^7.0.12",
38 | "@types/supertest": "^2.0.0",
39 | "autod": "^3.0.1",
40 | "autod-egg": "^1.1.0",
41 | "egg-ci": "^1.8.0",
42 | "egg-bin": "^4.11.0",
43 | "egg-mock": "^3.16.0",
44 | "tslib": "^1.9.0",
45 | "eslint": "^6.7.2",
46 | "eslint-config-egg": "^8.0.0",
47 | "typescript": "^3.0.0"
48 | },
49 | "engines": {
50 | "node": ">=8.9.0"
51 | },
52 | "ci": {
53 | "version": "8"
54 | },
55 | "repository": {
56 | "type": "git",
57 | "url": ""
58 | },
59 | "eslintIgnore": [
60 | "coverage"
61 | ],
62 | "author": "tcy",
63 | "license": "MIT"
64 | }
65 |
--------------------------------------------------------------------------------
/server/test/app/controller/home.test.ts:
--------------------------------------------------------------------------------
1 | import * as assert from 'assert';
2 | import { app } from 'egg-mock/bootstrap';
3 |
4 | describe('test/app/controller/home.test.ts', () => {
5 | it('should GET /', async () => {
6 | const result = await app.httpRequest().get('/').expect(200);
7 | assert(result.text === 'hi, egg');
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/server/test/app/service/Test.test.ts:
--------------------------------------------------------------------------------
1 | import * as assert from 'assert';
2 | import { Context } from 'egg';
3 | import { app } from 'egg-mock/bootstrap';
4 |
5 | describe('test/app/service/Test.test.js', () => {
6 | let ctx: Context;
7 |
8 | before(async () => {
9 | ctx = app.mockContext();
10 | });
11 |
12 | it('sayHi', async () => {
13 | const result = await ctx.service.test.sayHi('egg');
14 | assert(result === 'hi, egg');
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": true,
3 | "compilerOptions": {
4 | "target": "es2017",
5 | "module": "commonjs",
6 | "strict": true,
7 | "noImplicitAny": false,
8 | "experimentalDecorators": true,
9 | "emitDecoratorMetadata": true,
10 | "charset": "utf8",
11 | "allowJs": false,
12 | "pretty": true,
13 | "noEmitOnError": false,
14 | "noUnusedLocals": true,
15 | "noUnusedParameters": true,
16 | "allowUnreachableCode": false,
17 | "allowUnusedLabels": false,
18 | "strictPropertyInitialization": false,
19 | "noFallthroughCasesInSwitch": true,
20 | "skipLibCheck": true,
21 | "skipDefaultLibCheck": true,
22 | "inlineSourceMap": true,
23 | "importHelpers": true
24 | },
25 | "exclude": [
26 | "app/public",
27 | "app/views",
28 | "node_modules*"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/server/typings/app/controller/index.d.ts:
--------------------------------------------------------------------------------
1 | // This file is created by egg-ts-helper@1.25.8
2 | // Do not modify this file!!!!!!!!!
3 |
4 | import 'egg';
5 | import ExportHome from '../../../app/controller/home';
6 | import ExportGoodCategory from '../../../app/controller/good/category';
7 | import ExportGoodHome from '../../../app/controller/good/home';
8 | import ExportGoodOrder from '../../../app/controller/good/order';
9 | import ExportLogMessage from '../../../app/controller/log/message';
10 | import ExportMemberAddress from '../../../app/controller/member/address';
11 | import ExportMemberFav from '../../../app/controller/member/fav';
12 | import ExportMerchantIndex from '../../../app/controller/merchant/index';
13 | import ExportSystemFile from '../../../app/controller/system/file';
14 | import ExportSystemMenu from '../../../app/controller/system/menu';
15 | import ExportSystemPermission from '../../../app/controller/system/permission';
16 | import ExportSystemReqLog from '../../../app/controller/system/req_log';
17 | import ExportSystemRole from '../../../app/controller/system/role';
18 | import ExportSystemUser from '../../../app/controller/system/user';
19 |
20 | declare module 'egg' {
21 | interface IController {
22 | home: ExportHome;
23 | good: {
24 | category: ExportGoodCategory;
25 | home: ExportGoodHome;
26 | order: ExportGoodOrder;
27 | }
28 | log: {
29 | message: ExportLogMessage;
30 | }
31 | member: {
32 | address: ExportMemberAddress;
33 | fav: ExportMemberFav;
34 | }
35 | merchant: {
36 | index: ExportMerchantIndex;
37 | }
38 | system: {
39 | file: ExportSystemFile;
40 | menu: ExportSystemMenu;
41 | permission: ExportSystemPermission;
42 | reqLog: ExportSystemReqLog;
43 | role: ExportSystemRole;
44 | user: ExportSystemUser;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/server/typings/app/extend/context.d.ts:
--------------------------------------------------------------------------------
1 | // This file is created by egg-ts-helper@1.25.8
2 | // Do not modify this file!!!!!!!!!
3 |
4 | import 'egg';
5 | import ExtendContext from '../../../app/extend/context';
6 | type ExtendContextType = typeof ExtendContext;
7 | declare module 'egg' {
8 | interface Context extends ExtendContextType { }
9 | }
--------------------------------------------------------------------------------
/server/typings/app/extend/helper.d.ts:
--------------------------------------------------------------------------------
1 | // This file is created by egg-ts-helper@1.25.8
2 | // Do not modify this file!!!!!!!!!
3 |
4 | import 'egg';
5 | import ExtendIHelper from '../../../app/extend/helper';
6 | type ExtendIHelperType = typeof ExtendIHelper;
7 | declare module 'egg' {
8 | interface IHelper extends ExtendIHelperType { }
9 | }
--------------------------------------------------------------------------------
/server/typings/app/index.d.ts:
--------------------------------------------------------------------------------
1 | // This file is created by egg-ts-helper@1.25.8
2 | // Do not modify this file!!!!!!!!!
3 |
4 | import 'egg';
5 | export * from 'egg';
6 | export as namespace Egg;
7 |
--------------------------------------------------------------------------------
/server/typings/app/middleware/index.d.ts:
--------------------------------------------------------------------------------
1 | // This file is created by egg-ts-helper@1.25.8
2 | // Do not modify this file!!!!!!!!!
3 |
4 | import 'egg';
5 | import ExportAdminReqLog from '../../../app/middleware/admin_req_log';
6 | import ExportExecption from '../../../app/middleware/execption';
7 | import ExportRequireLogin from '../../../app/middleware/requireLogin';
8 |
9 | declare module 'egg' {
10 | interface IMiddleware {
11 | adminReqLog: typeof ExportAdminReqLog;
12 | execption: typeof ExportExecption;
13 | requireLogin: typeof ExportRequireLogin;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/server/typings/app/model/index.d.ts:
--------------------------------------------------------------------------------
1 | // This file is created by egg-ts-helper@1.25.8
2 | // Do not modify this file!!!!!!!!!
3 |
4 | import 'egg';
5 | import ExportGood from '../../../app/model/Good';
6 | import ExportGoodCategory from '../../../app/model/GoodCategory';
7 | import ExportGoodImage from '../../../app/model/GoodImage';
8 | import ExportGoodOrder from '../../../app/model/GoodOrder';
9 | import ExportGoodOrderLine from '../../../app/model/GoodOrderLine';
10 | import ExportGoodSpec from '../../../app/model/GoodSpec';
11 | import ExportLogMessage from '../../../app/model/LogMessage';
12 | import ExportMerchant from '../../../app/model/Merchant';
13 | import ExportSystemFile from '../../../app/model/SystemFile';
14 | import ExportSystemMenu from '../../../app/model/SystemMenu';
15 | import ExportSystemPermission from '../../../app/model/SystemPermission';
16 | import ExportSystemReqLog from '../../../app/model/SystemReqLog';
17 | import ExportSystemRole from '../../../app/model/SystemRole';
18 | import ExportSystemRoleMenu from '../../../app/model/SystemRoleMenu';
19 | import ExportSystemRolePermission from '../../../app/model/SystemRolePermission';
20 | import ExportSystemUser from '../../../app/model/SystemUser';
21 | import ExportUserAddress from '../../../app/model/UserAddress';
22 | import ExportUserFav from '../../../app/model/UserFav';
23 |
24 | declare module 'egg' {
25 | interface IModel {
26 | Good: ReturnType;
27 | GoodCategory: ReturnType;
28 | GoodImage: ReturnType;
29 | GoodOrder: ReturnType;
30 | GoodOrderLine: ReturnType;
31 | GoodSpec: ReturnType;
32 | LogMessage: ReturnType;
33 | Merchant: ReturnType;
34 | SystemFile: ReturnType;
35 | SystemMenu: ReturnType;
36 | SystemPermission: ReturnType;
37 | SystemReqLog: ReturnType;
38 | SystemRole: ReturnType;
39 | SystemRoleMenu: ReturnType;
40 | SystemRolePermission: ReturnType;
41 | SystemUser: ReturnType;
42 | UserAddress: ReturnType;
43 | UserFav: ReturnType;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/server/typings/app/service/index.d.ts:
--------------------------------------------------------------------------------
1 | // This file is created by egg-ts-helper@1.25.8
2 | // Do not modify this file!!!!!!!!!
3 |
4 | import 'egg';
5 | type AnyClass = new (...args: any[]) => any;
6 | type AnyFunc = (...args: any[]) => T;
7 | type CanExportFunc = AnyFunc> | AnyFunc>;
8 | type AutoInstanceType : T> = U extends AnyClass ? InstanceType : U;
9 | import ExportGoodCategory from '../../../app/service/good/category';
10 | import ExportGoodHome from '../../../app/service/good/home';
11 | import ExportGoodOrder from '../../../app/service/good/order';
12 | import ExportLogMessage from '../../../app/service/log/message';
13 | import ExportMemberAddress from '../../../app/service/member/address';
14 | import ExportMemberFav from '../../../app/service/member/fav';
15 | import ExportMerchantIndex from '../../../app/service/merchant/index';
16 | import ExportSystemFile from '../../../app/service/system/file';
17 | import ExportSystemMenu from '../../../app/service/system/menu';
18 | import ExportSystemPermission from '../../../app/service/system/permission';
19 | import ExportSystemReqLog from '../../../app/service/system/req_log';
20 | import ExportSystemRole from '../../../app/service/system/role';
21 | import ExportSystemUser from '../../../app/service/system/user';
22 |
23 | declare module 'egg' {
24 | interface IService {
25 | good: {
26 | category: AutoInstanceType;
27 | home: AutoInstanceType;
28 | order: AutoInstanceType;
29 | }
30 | log: {
31 | message: AutoInstanceType;
32 | }
33 | member: {
34 | address: AutoInstanceType;
35 | fav: AutoInstanceType;
36 | }
37 | merchant: {
38 | index: AutoInstanceType;
39 | }
40 | system: {
41 | file: AutoInstanceType;
42 | menu: AutoInstanceType;
43 | permission: AutoInstanceType;
44 | reqLog: AutoInstanceType;
45 | role: AutoInstanceType;
46 | user: AutoInstanceType;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/server/typings/config/index.d.ts:
--------------------------------------------------------------------------------
1 | // This file is created by egg-ts-helper@1.25.8
2 | // Do not modify this file!!!!!!!!!
3 |
4 | import 'egg';
5 | import { EggAppConfig } from 'egg';
6 | import ExportConfigDefault from '../../config/config.default';
7 | type ConfigDefault = ReturnType;
8 | type NewEggAppConfig = ConfigDefault;
9 | declare module 'egg' {
10 | interface EggAppConfig extends NewEggAppConfig { }
11 | }
--------------------------------------------------------------------------------
/server/typings/config/plugin.d.ts:
--------------------------------------------------------------------------------
1 | // This file is created by egg-ts-helper@1.25.8
2 | // Do not modify this file!!!!!!!!!
3 |
4 | import 'egg';
5 | import 'egg-onerror';
6 | import 'egg-session';
7 | import 'egg-i18n';
8 | import 'egg-watcher';
9 | import 'egg-multipart';
10 | import 'egg-security';
11 | import 'egg-development';
12 | import 'egg-logrotator';
13 | import 'egg-schedule';
14 | import 'egg-static';
15 | import 'egg-jsonp';
16 | import 'egg-view';
17 | import 'egg-jwt';
18 | import 'egg-sequelize';
19 | import 'egg-cors';
20 | import { EggPluginItem } from 'egg';
21 | declare module 'egg' {
22 | interface EggPlugin {
23 | onerror?: EggPluginItem;
24 | session?: EggPluginItem;
25 | i18n?: EggPluginItem;
26 | watcher?: EggPluginItem;
27 | multipart?: EggPluginItem;
28 | security?: EggPluginItem;
29 | development?: EggPluginItem;
30 | logrotator?: EggPluginItem;
31 | schedule?: EggPluginItem;
32 | static?: EggPluginItem;
33 | jsonp?: EggPluginItem;
34 | view?: EggPluginItem;
35 | jwt?: EggPluginItem;
36 | sequelize?: EggPluginItem;
37 | cors?: EggPluginItem;
38 | }
39 | }
--------------------------------------------------------------------------------
/server/typings/index.d.ts:
--------------------------------------------------------------------------------
1 | import 'egg';
2 |
3 | declare module 'egg' {
4 | jwt: any
5 | }
--------------------------------------------------------------------------------
/uniapp/common/api/common/file.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import store from '@/store'
3 |
4 | export default{
5 | upload: (tempFilePaths)=>{
6 | const header = {"ContentType":"application/json"};
7 | if (store.state.token) {
8 | // 给请求头添加user-token
9 | header["authorization"] = store.state.token;
10 | }
11 | return new Promise((resolve,reject)=>{
12 | uni.uploadFile({
13 | url: store.state.baseUrl + '/api/file/upload', //仅为示例,非真实的接口地址
14 | filePath: tempFilePaths[0],
15 | name: 'file',
16 | header: header,
17 | success: (uploadFileRes) => {
18 | resolve(JSON.parse(uploadFileRes.data))
19 | },
20 | fail: (err)=>{
21 | reject(err)
22 | }
23 | });
24 | })
25 |
26 |
27 | // axios.post('/api/file/upload',opt)
28 | }
29 | }
--------------------------------------------------------------------------------
/uniapp/common/api/common/index.js:
--------------------------------------------------------------------------------
1 | import file from './file'
2 | export default{
3 | file
4 | }
--------------------------------------------------------------------------------
/uniapp/common/api/good/category.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 |
3 | export default{
4 | list: (params)=>axios.get('/api/goodCategory',{params}),
5 | tree: (params)=>axios.get('/api/goodCategory/tree',{params}),
6 | save: (opt)=>axios.post('/api/goodCategory/save',opt),
7 | remove: (id)=>axios.delete('/api/goodCategory/'+id),
8 | }
--------------------------------------------------------------------------------
/uniapp/common/api/good/index.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import category from './category'
3 | export default{
4 | category,
5 | list: (params)=>axios.get('/api/good',{params}),
6 | detail: (id)=>axios.get('/api/good/'+id)
7 | }
--------------------------------------------------------------------------------
/uniapp/common/api/index.js:
--------------------------------------------------------------------------------
1 | import user from './user'
2 | import good from './good'
3 | import common from './common'
4 | export default{
5 | user,
6 | good,
7 | common
8 | }
--------------------------------------------------------------------------------
/uniapp/common/api/user/address.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 |
3 | export default{
4 | list: (params)=>axios.get('/api/member/address',{params}),
5 | save: (opt)=>axios.post('/api/member/address/save',opt),
6 | remove: (id)=>axios.delete('/api/member/address/'+id),
7 | }
--------------------------------------------------------------------------------
/uniapp/common/api/user/fav.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 |
3 | export default{
4 | list: (params)=>axios.get('/api/member/fav',{params}),
5 | save: (opt)=>axios.post('/api/member/fav/save',opt),
6 | remove: (id)=>axios.delete('/api/member/fav/'+id),
7 | }
--------------------------------------------------------------------------------
/uniapp/common/api/user/index.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import address from './address'
3 | import order from './order'
4 | import fav from './fav'
5 | export default{
6 | login: (opt)=>axios.post('/api/user/login',opt),
7 | info: ()=>axios.get('/api/user/info'),
8 | update: (opt)=>axios.post('/api/user/update',opt),
9 | address,
10 | order,
11 | fav
12 | }
--------------------------------------------------------------------------------
/uniapp/common/api/user/order.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 |
3 | export default{
4 | list: (params)=>axios.get('/api/order',{params}),
5 | save: (opt)=>axios.post('/api/order/save',opt),
6 | remove: (id)=>axios.delete('/api/order/'+id),
7 | cancel: (id)=>axios.post('/api/order/cancel/'+id),
8 | }
--------------------------------------------------------------------------------
/uniapp/components/mix-list-cell.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 | {{title}}
14 | {{tips}}
15 |
18 |
19 |
20 |
21 |
22 |
23 |
76 |
77 |
120 |
--------------------------------------------------------------------------------
/uniapp/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import store from './store'
3 | import App from './App'
4 |
5 | import Json from './Json' //测试用数据
6 | /**
7 | * 因工具函数属于公司资产, 所以直接在Vue实例挂载几个常用的函数
8 | * 所有测试用数据均存放于根目录json.js
9 | *
10 | * css部分使用了App.vue下的全局样式和iconfont图标,有需要图标库的可以留言。
11 | * 示例使用了uni.scss下的变量, 除变量外已尽量移除特有语法,可直接替换为其他预处理器使用
12 | */
13 | const msg = (title, duration=1500, mask=false, icon='none')=>{
14 | //统一提示方便全局修改
15 | if(Boolean(title) === false){
16 | return;
17 | }
18 | uni.showToast({
19 | title,
20 | duration,
21 | mask,
22 | icon
23 | });
24 | }
25 | const json = type=>{
26 | //模拟异步请求数据
27 | return new Promise(resolve=>{
28 | setTimeout(()=>{
29 | resolve(Json[type]);
30 | }, 500)
31 | })
32 | }
33 |
34 | const prePage = ()=>{
35 | let pages = getCurrentPages();
36 | let prePage = pages[pages.length - 2];
37 | // #ifdef H5
38 | return prePage;
39 | // #endif
40 | return prePage.$vm;
41 | }
42 |
43 |
44 | import api from './common/api'
45 |
46 | Vue.config.productionTip = false
47 | Vue.prototype.$fire = new Vue();
48 | Vue.prototype.$store = store;
49 | Vue.prototype.$api = {msg, json, prePage,...api};
50 |
51 |
52 | App.mpType = 'app'
53 |
54 | const app = new Vue({
55 | ...App
56 | })
57 | app.$mount()
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014-present Matt Zabriskie
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./lib/axios');
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/adapters/README.md:
--------------------------------------------------------------------------------
1 | # axios // adapters
2 |
3 | The modules under `adapters/` are modules that handle dispatching a request and settling a returned `Promise` once a response is received.
4 |
5 | ## Example
6 |
7 | ```js
8 | var settle = require('./../core/settle');
9 |
10 | module.exports = function myAdapter(config) {
11 | // At this point:
12 | // - config has been merged with defaults
13 | // - request transformers have already run
14 | // - request interceptors have already run
15 |
16 | // Make the request using config provided
17 | // Upon response settle the Promise
18 |
19 | return new Promise(function(resolve, reject) {
20 |
21 | var response = {
22 | data: responseData,
23 | status: request.status,
24 | statusText: request.statusText,
25 | headers: responseHeaders,
26 | config: config,
27 | request: request
28 | };
29 |
30 | settle(resolve, reject, response);
31 |
32 | // From here:
33 | // - response transformers will run
34 | // - response interceptors will run
35 | });
36 | }
37 | ```
38 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/axios.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./utils');
4 | var bind = require('./helpers/bind');
5 | var Axios = require('./core/Axios');
6 | var mergeConfig = require('./core/mergeConfig');
7 | var defaults = require('./defaults');
8 |
9 | /**
10 | * Create an instance of Axios
11 | *
12 | * @param {Object} defaultConfig The default config for the instance
13 | * @return {Axios} A new instance of Axios
14 | */
15 | function createInstance(defaultConfig) {
16 | var context = new Axios(defaultConfig);
17 | var instance = bind(Axios.prototype.request, context);
18 |
19 | // Copy axios.prototype to instance
20 | utils.extend(instance, Axios.prototype, context);
21 |
22 | // Copy context to instance
23 | utils.extend(instance, context);
24 |
25 | return instance;
26 | }
27 |
28 | // Create the default instance to be exported
29 | var axios = createInstance(defaults);
30 |
31 | // Expose Axios class to allow class inheritance
32 | axios.Axios = Axios;
33 |
34 | // Factory for creating new instances
35 | axios.create = function create(instanceConfig) {
36 | return createInstance(mergeConfig(axios.defaults, instanceConfig));
37 | };
38 |
39 | // Expose Cancel & CancelToken
40 | axios.Cancel = require('./cancel/Cancel');
41 | axios.CancelToken = require('./cancel/CancelToken');
42 | axios.isCancel = require('./cancel/isCancel');
43 |
44 | // Expose all/spread
45 | axios.all = function all(promises) {
46 | return Promise.all(promises);
47 | };
48 | axios.spread = require('./helpers/spread');
49 |
50 | module.exports = axios;
51 |
52 | // Allow use of default import syntax in TypeScript
53 | module.exports.default = axios;
54 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/cancel/Cancel.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * A `Cancel` is an object that is thrown when an operation is canceled.
5 | *
6 | * @class
7 | * @param {string=} message The message.
8 | */
9 | function Cancel(message) {
10 | this.message = message;
11 | }
12 |
13 | Cancel.prototype.toString = function toString() {
14 | return 'Cancel' + (this.message ? ': ' + this.message : '');
15 | };
16 |
17 | Cancel.prototype.__CANCEL__ = true;
18 |
19 | module.exports = Cancel;
20 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/cancel/CancelToken.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var Cancel = require('./Cancel');
4 |
5 | /**
6 | * A `CancelToken` is an object that can be used to request cancellation of an operation.
7 | *
8 | * @class
9 | * @param {Function} executor The executor function.
10 | */
11 | function CancelToken(executor) {
12 | if (typeof executor !== 'function') {
13 | throw new TypeError('executor must be a function.');
14 | }
15 |
16 | var resolvePromise;
17 | this.promise = new Promise(function promiseExecutor(resolve) {
18 | resolvePromise = resolve;
19 | });
20 |
21 | var token = this;
22 | executor(function cancel(message) {
23 | if (token.reason) {
24 | // Cancellation has already been requested
25 | return;
26 | }
27 |
28 | token.reason = new Cancel(message);
29 | resolvePromise(token.reason);
30 | });
31 | }
32 |
33 | /**
34 | * Throws a `Cancel` if cancellation has been requested.
35 | */
36 | CancelToken.prototype.throwIfRequested = function throwIfRequested() {
37 | if (this.reason) {
38 | throw this.reason;
39 | }
40 | };
41 |
42 | /**
43 | * Returns an object that contains a new `CancelToken` and a function that, when called,
44 | * cancels the `CancelToken`.
45 | */
46 | CancelToken.source = function source() {
47 | var cancel;
48 | var token = new CancelToken(function executor(c) {
49 | cancel = c;
50 | });
51 | return {
52 | token: token,
53 | cancel: cancel
54 | };
55 | };
56 |
57 | module.exports = CancelToken;
58 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/cancel/isCancel.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function isCancel(value) {
4 | return !!(value && value.__CANCEL__);
5 | };
6 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/core/InterceptorManager.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./../utils');
4 |
5 | function InterceptorManager() {
6 | this.handlers = [];
7 | }
8 |
9 | /**
10 | * Add a new interceptor to the stack
11 | *
12 | * @param {Function} fulfilled The function to handle `then` for a `Promise`
13 | * @param {Function} rejected The function to handle `reject` for a `Promise`
14 | *
15 | * @return {Number} An ID used to remove interceptor later
16 | */
17 | InterceptorManager.prototype.use = function use(fulfilled, rejected) {
18 | this.handlers.push({
19 | fulfilled: fulfilled,
20 | rejected: rejected
21 | });
22 | return this.handlers.length - 1;
23 | };
24 |
25 | /**
26 | * Remove an interceptor from the stack
27 | *
28 | * @param {Number} id The ID that was returned by `use`
29 | */
30 | InterceptorManager.prototype.eject = function eject(id) {
31 | if (this.handlers[id]) {
32 | this.handlers[id] = null;
33 | }
34 | };
35 |
36 | /**
37 | * Iterate over all the registered interceptors
38 | *
39 | * This method is particularly useful for skipping over any
40 | * interceptors that may have become `null` calling `eject`.
41 | *
42 | * @param {Function} fn The function to call for each interceptor
43 | */
44 | InterceptorManager.prototype.forEach = function forEach(fn) {
45 | utils.forEach(this.handlers, function forEachHandler(h) {
46 | if (h !== null) {
47 | fn(h);
48 | }
49 | });
50 | };
51 |
52 | module.exports = InterceptorManager;
53 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/core/README.md:
--------------------------------------------------------------------------------
1 | # axios // core
2 |
3 | The modules found in `core/` should be modules that are specific to the domain logic of axios. These modules would most likely not make sense to be consumed outside of the axios module, as their logic is too specific. Some examples of core modules are:
4 |
5 | - Dispatching requests
6 | - Managing interceptors
7 | - Handling config
8 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/core/buildFullPath.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var isAbsoluteURL = require('../helpers/isAbsoluteURL');
4 | var combineURLs = require('../helpers/combineURLs');
5 |
6 | /**
7 | * Creates a new URL by combining the baseURL with the requestedURL,
8 | * only when the requestedURL is not already an absolute URL.
9 | * If the requestURL is absolute, this function returns the requestedURL untouched.
10 | *
11 | * @param {string} baseURL The base URL
12 | * @param {string} requestedURL Absolute or relative URL to combine
13 | * @returns {string} The combined full path
14 | */
15 | module.exports = function buildFullPath(baseURL, requestedURL) {
16 | if (baseURL && !isAbsoluteURL(requestedURL)) {
17 | return combineURLs(baseURL, requestedURL);
18 | }
19 | return requestedURL;
20 | };
21 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/core/createError.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var enhanceError = require('./enhanceError');
4 |
5 | /**
6 | * Create an Error with the specified message, config, error code, request and response.
7 | *
8 | * @param {string} message The error message.
9 | * @param {Object} config The config.
10 | * @param {string} [code] The error code (for example, 'ECONNABORTED').
11 | * @param {Object} [request] The request.
12 | * @param {Object} [response] The response.
13 | * @returns {Error} The created error.
14 | */
15 | module.exports = function createError(message, config, code, request, response) {
16 | var error = new Error(message);
17 | return enhanceError(error, config, code, request, response);
18 | };
19 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/core/dispatchRequest.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./../utils');
4 | var transformData = require('./transformData');
5 | var isCancel = require('../cancel/isCancel');
6 | var defaults = require('../defaults');
7 |
8 | /**
9 | * Throws a `Cancel` if cancellation has been requested.
10 | */
11 | function throwIfCancellationRequested(config) {
12 | if (config.cancelToken) {
13 | config.cancelToken.throwIfRequested();
14 | }
15 | }
16 |
17 | /**
18 | * Dispatch a request to the server using the configured adapter.
19 | *
20 | * @param {object} config The config that is to be used for the request
21 | * @returns {Promise} The Promise to be fulfilled
22 | */
23 | module.exports = function dispatchRequest(config) {
24 | throwIfCancellationRequested(config);
25 |
26 | // Ensure headers exist
27 | config.headers = config.headers || {};
28 |
29 | // Transform request data
30 | config.data = transformData(
31 | config.data,
32 | config.headers,
33 | config.transformRequest
34 | );
35 |
36 | // Flatten headers
37 | config.headers = utils.merge(
38 | config.headers.common || {},
39 | config.headers[config.method] || {},
40 | config.headers
41 | );
42 |
43 | utils.forEach(
44 | ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
45 | function cleanHeaderConfig(method) {
46 | delete config.headers[method];
47 | }
48 | );
49 |
50 | var adapter = config.adapter || defaults.adapter;
51 |
52 | return adapter(config).then(function onAdapterResolution(response) {
53 | throwIfCancellationRequested(config);
54 |
55 | // Transform response data
56 | response.data = transformData(
57 | response.data,
58 | response.headers,
59 | config.transformResponse
60 | );
61 |
62 | return response;
63 | }, function onAdapterRejection(reason) {
64 | if (!isCancel(reason)) {
65 | throwIfCancellationRequested(config);
66 |
67 | // Transform response data
68 | if (reason && reason.response) {
69 | reason.response.data = transformData(
70 | reason.response.data,
71 | reason.response.headers,
72 | config.transformResponse
73 | );
74 | }
75 | }
76 |
77 | return Promise.reject(reason);
78 | });
79 | };
80 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/core/enhanceError.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Update an Error with the specified config, error code, and response.
5 | *
6 | * @param {Error} error The error to update.
7 | * @param {Object} config The config.
8 | * @param {string} [code] The error code (for example, 'ECONNABORTED').
9 | * @param {Object} [request] The request.
10 | * @param {Object} [response] The response.
11 | * @returns {Error} The error.
12 | */
13 | module.exports = function enhanceError(error, config, code, request, response) {
14 | error.config = config;
15 | if (code) {
16 | error.code = code;
17 | }
18 |
19 | error.request = request;
20 | error.response = response;
21 | error.isAxiosError = true;
22 |
23 | error.toJSON = function toJSON() {
24 | return {
25 | // Standard
26 | message: this.message,
27 | name: this.name,
28 | // Microsoft
29 | description: this.description,
30 | number: this.number,
31 | // Mozilla
32 | fileName: this.fileName,
33 | lineNumber: this.lineNumber,
34 | columnNumber: this.columnNumber,
35 | stack: this.stack,
36 | // Axios
37 | config: this.config,
38 | code: this.code
39 | };
40 | };
41 | return error;
42 | };
43 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/core/settle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var createError = require('./createError');
4 |
5 | /**
6 | * Resolve or reject a Promise based on response status.
7 | *
8 | * @param {Function} resolve A function that resolves the promise.
9 | * @param {Function} reject A function that rejects the promise.
10 | * @param {object} response The response.
11 | */
12 | module.exports = function settle(resolve, reject, response) {
13 | var validateStatus = response.config.validateStatus;
14 | if (!response.status || !validateStatus || validateStatus(response.status)) {
15 | resolve(response);
16 | } else {
17 | reject(createError(
18 | 'Request failed with status code ' + response.status,
19 | response.config,
20 | null,
21 | response.request,
22 | response
23 | ));
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/core/transformData.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./../utils');
4 |
5 | /**
6 | * Transform the data for a request or a response
7 | *
8 | * @param {Object|String} data The data to be transformed
9 | * @param {Array} headers The headers for the request or response
10 | * @param {Array|Function} fns A single function or Array of functions
11 | * @returns {*} The resulting transformed data
12 | */
13 | module.exports = function transformData(data, headers, fns) {
14 | /*eslint no-param-reassign:0*/
15 | utils.forEach(fns, function transform(fn) {
16 | data = fn(data, headers);
17 | });
18 |
19 | return data;
20 | };
21 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/README.md:
--------------------------------------------------------------------------------
1 | # axios // helpers
2 |
3 | The modules found in `helpers/` should be generic modules that are _not_ specific to the domain logic of axios. These modules could theoretically be published to npm on their own and consumed by other modules or apps. Some examples of generic modules are things like:
4 |
5 | - Browser polyfills
6 | - Managing cookies
7 | - Parsing HTTP headers
8 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/bind.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function bind(fn, thisArg) {
4 | return function wrap() {
5 | var args = new Array(arguments.length);
6 | for (var i = 0; i < args.length; i++) {
7 | args[i] = arguments[i];
8 | }
9 | return fn.apply(thisArg, args);
10 | };
11 | };
12 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/buildURL.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./../utils');
4 |
5 | function encode(val) {
6 | return encodeURIComponent(val).
7 | replace(/%3A/gi, ':').
8 | replace(/%24/g, '$').
9 | replace(/%2C/gi, ',').
10 | replace(/%20/g, '+').
11 | replace(/%5B/gi, '[').
12 | replace(/%5D/gi, ']');
13 | }
14 |
15 | /**
16 | * Build a URL by appending params to the end
17 | *
18 | * @param {string} url The base of the url (e.g., http://www.google.com)
19 | * @param {object} [params] The params to be appended
20 | * @returns {string} The formatted url
21 | */
22 | module.exports = function buildURL(url, params, paramsSerializer) {
23 | /*eslint no-param-reassign:0*/
24 | if (!params) {
25 | return url;
26 | }
27 |
28 | var serializedParams;
29 | if (paramsSerializer) {
30 | serializedParams = paramsSerializer(params);
31 | } else if (utils.isURLSearchParams(params)) {
32 | serializedParams = params.toString();
33 | } else {
34 | var parts = [];
35 |
36 | utils.forEach(params, function serialize(val, key) {
37 | if (val === null || typeof val === 'undefined') {
38 | return;
39 | }
40 |
41 | if (utils.isArray(val)) {
42 | key = key + '[]';
43 | } else {
44 | val = [val];
45 | }
46 |
47 | utils.forEach(val, function parseValue(v) {
48 | if (utils.isDate(v)) {
49 | v = v.toISOString();
50 | } else if (utils.isObject(v)) {
51 | v = JSON.stringify(v);
52 | }
53 | parts.push(encode(key) + '=' + encode(v));
54 | });
55 | });
56 |
57 | serializedParams = parts.join('&');
58 | }
59 |
60 | if (serializedParams) {
61 | var hashmarkIndex = url.indexOf('#');
62 | if (hashmarkIndex !== -1) {
63 | url = url.slice(0, hashmarkIndex);
64 | }
65 |
66 | url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
67 | }
68 |
69 | return url;
70 | };
71 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/combineURLs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Creates a new URL by combining the specified URLs
5 | *
6 | * @param {string} baseURL The base URL
7 | * @param {string} relativeURL The relative URL
8 | * @returns {string} The combined URL
9 | */
10 | module.exports = function combineURLs(baseURL, relativeURL) {
11 | return relativeURL
12 | ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
13 | : baseURL;
14 | };
15 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/cookies.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./../utils');
4 |
5 | module.exports = (
6 | utils.isStandardBrowserEnv() ?
7 |
8 | // Standard browser envs support document.cookie
9 | (function standardBrowserEnv() {
10 | return {
11 | write: function write(name, value, expires, path, domain, secure) {
12 | var cookie = [];
13 | cookie.push(name + '=' + encodeURIComponent(value));
14 |
15 | if (utils.isNumber(expires)) {
16 | cookie.push('expires=' + new Date(expires).toGMTString());
17 | }
18 |
19 | if (utils.isString(path)) {
20 | cookie.push('path=' + path);
21 | }
22 |
23 | if (utils.isString(domain)) {
24 | cookie.push('domain=' + domain);
25 | }
26 |
27 | if (secure === true) {
28 | cookie.push('secure');
29 | }
30 |
31 | document.cookie = cookie.join('; ');
32 | },
33 |
34 | read: function read(name) {
35 | var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
36 | return (match ? decodeURIComponent(match[3]) : null);
37 | },
38 |
39 | remove: function remove(name) {
40 | this.write(name, '', Date.now() - 86400000);
41 | }
42 | };
43 | })() :
44 |
45 | // Non standard browser env (web workers, react-native) lack needed support.
46 | (function nonStandardBrowserEnv() {
47 | return {
48 | write: function write() {},
49 | read: function read() { return null; },
50 | remove: function remove() {}
51 | };
52 | })()
53 | );
54 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/deprecatedMethod.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*eslint no-console:0*/
4 |
5 | /**
6 | * Supply a warning to the developer that a method they are using
7 | * has been deprecated.
8 | *
9 | * @param {string} method The name of the deprecated method
10 | * @param {string} [instead] The alternate method to use if applicable
11 | * @param {string} [docs] The documentation URL to get further details
12 | */
13 | module.exports = function deprecatedMethod(method, instead, docs) {
14 | try {
15 | console.warn(
16 | 'DEPRECATED method `' + method + '`.' +
17 | (instead ? ' Use `' + instead + '` instead.' : '') +
18 | ' This method will be removed in a future release.');
19 |
20 | if (docs) {
21 | console.warn('For more information about usage see ' + docs);
22 | }
23 | } catch (e) { /* Ignore */ }
24 | };
25 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/isAbsoluteURL.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Determines whether the specified URL is absolute
5 | *
6 | * @param {string} url The URL to test
7 | * @returns {boolean} True if the specified URL is absolute, otherwise false
8 | */
9 | module.exports = function isAbsoluteURL(url) {
10 | // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL).
11 | // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
12 | // by any combination of letters, digits, plus, period, or hyphen.
13 | return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
14 | };
15 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/isURLSameOrigin.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./../utils');
4 |
5 | module.exports = (
6 | utils.isStandardBrowserEnv() ?
7 |
8 | // Standard browser envs have full support of the APIs needed to test
9 | // whether the request URL is of the same origin as current location.
10 | (function standardBrowserEnv() {
11 | var msie = /(msie|trident)/i.test(navigator.userAgent);
12 | var urlParsingNode = document.createElement('a');
13 | var originURL;
14 |
15 | /**
16 | * Parse a URL to discover it's components
17 | *
18 | * @param {String} url The URL to be parsed
19 | * @returns {Object}
20 | */
21 | function resolveURL(url) {
22 | var href = url;
23 |
24 | if (msie) {
25 | // IE needs attribute set twice to normalize properties
26 | urlParsingNode.setAttribute('href', href);
27 | href = urlParsingNode.href;
28 | }
29 |
30 | urlParsingNode.setAttribute('href', href);
31 |
32 | // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
33 | return {
34 | href: urlParsingNode.href,
35 | protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
36 | host: urlParsingNode.host,
37 | search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
38 | hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
39 | hostname: urlParsingNode.hostname,
40 | port: urlParsingNode.port,
41 | pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
42 | urlParsingNode.pathname :
43 | '/' + urlParsingNode.pathname
44 | };
45 | }
46 |
47 | originURL = resolveURL(window.location.href);
48 |
49 | /**
50 | * Determine if a URL shares the same origin as the current location
51 | *
52 | * @param {String} requestURL The URL to test
53 | * @returns {boolean} True if URL shares the same origin, otherwise false
54 | */
55 | return function isURLSameOrigin(requestURL) {
56 | var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
57 | return (parsed.protocol === originURL.protocol &&
58 | parsed.host === originURL.host);
59 | };
60 | })() :
61 |
62 | // Non standard browser envs (web workers, react-native) lack needed support.
63 | (function nonStandardBrowserEnv() {
64 | return function isURLSameOrigin() {
65 | return true;
66 | };
67 | })()
68 | );
69 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/normalizeHeaderName.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('../utils');
4 |
5 | module.exports = function normalizeHeaderName(headers, normalizedName) {
6 | utils.forEach(headers, function processHeader(value, name) {
7 | if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
8 | headers[normalizedName] = value;
9 | delete headers[name];
10 | }
11 | });
12 | };
13 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/parseHeaders.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var utils = require('./../utils');
4 |
5 | // Headers whose duplicates are ignored by node
6 | // c.f. https://nodejs.org/api/http.html#http_message_headers
7 | var ignoreDuplicateOf = [
8 | 'age', 'authorization', 'content-length', 'content-type', 'etag',
9 | 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
10 | 'last-modified', 'location', 'max-forwards', 'proxy-authorization',
11 | 'referer', 'retry-after', 'user-agent'
12 | ];
13 |
14 | /**
15 | * Parse headers into an object
16 | *
17 | * ```
18 | * Date: Wed, 27 Aug 2014 08:58:49 GMT
19 | * Content-Type: application/json
20 | * Connection: keep-alive
21 | * Transfer-Encoding: chunked
22 | * ```
23 | *
24 | * @param {String} headers Headers needing to be parsed
25 | * @returns {Object} Headers parsed into an object
26 | */
27 | module.exports = function parseHeaders(headers) {
28 | var parsed = {};
29 | var key;
30 | var val;
31 | var i;
32 |
33 | if (!headers) { return parsed; }
34 |
35 | utils.forEach(headers.split('\n'), function parser(line) {
36 | i = line.indexOf(':');
37 | key = utils.trim(line.substr(0, i)).toLowerCase();
38 | val = utils.trim(line.substr(i + 1));
39 |
40 | if (key) {
41 | if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
42 | return;
43 | }
44 | if (key === 'set-cookie') {
45 | parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
46 | } else {
47 | parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
48 | }
49 | }
50 | });
51 |
52 | return parsed;
53 | };
54 |
--------------------------------------------------------------------------------
/uniapp/node_modules/axios/lib/helpers/spread.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Syntactic sugar for invoking a function and expanding an array for arguments.
5 | *
6 | * Common use case would be to use `Function.prototype.apply`.
7 | *
8 | * ```js
9 | * function f(x, y, z) {}
10 | * var args = [1, 2, 3];
11 | * f.apply(null, args);
12 | * ```
13 | *
14 | * With `spread` this example can be re-written.
15 | *
16 | * ```js
17 | * spread(function(x, y, z) {})([1, 2, 3]);
18 | * ```
19 | *
20 | * @param {Function} callback
21 | * @returns {Function}
22 | */
23 | module.exports = function spread(callback) {
24 | return function wrap(arr) {
25 | return callback.apply(null, arr);
26 | };
27 | };
28 |
--------------------------------------------------------------------------------
/uniapp/node_modules/follow-redirects/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2014–present Olivier Lalonde , James Talmage , Ruben Verborgh
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7 | of the Software, and to permit persons to whom the Software is furnished to do
8 | so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
18 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/uniapp/node_modules/follow-redirects/debug.js:
--------------------------------------------------------------------------------
1 | var debug;
2 | try {
3 | /* eslint global-require: off */
4 | debug = require("debug")("follow-redirects");
5 | }
6 | catch (error) {
7 | debug = function () { /* */ };
8 | }
9 | module.exports = debug;
10 |
--------------------------------------------------------------------------------
/uniapp/node_modules/follow-redirects/http.js:
--------------------------------------------------------------------------------
1 | module.exports = require("./").http;
2 |
--------------------------------------------------------------------------------
/uniapp/node_modules/follow-redirects/https.js:
--------------------------------------------------------------------------------
1 | module.exports = require("./").https;
2 |
--------------------------------------------------------------------------------
/uniapp/node_modules/follow-redirects/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "_from": "follow-redirects@^1.10.0",
3 | "_id": "follow-redirects@1.13.0",
4 | "_inBundle": false,
5 | "_integrity": "sha1-tC6Nk6Kn7qXtiGM2dtZZe8jjhNs=",
6 | "_location": "/follow-redirects",
7 | "_phantomChildren": {},
8 | "_requested": {
9 | "type": "range",
10 | "registry": true,
11 | "raw": "follow-redirects@^1.10.0",
12 | "name": "follow-redirects",
13 | "escapedName": "follow-redirects",
14 | "rawSpec": "^1.10.0",
15 | "saveSpec": null,
16 | "fetchSpec": "^1.10.0"
17 | },
18 | "_requiredBy": [
19 | "/axios"
20 | ],
21 | "_resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.13.0.tgz",
22 | "_shasum": "b42e8d93a2a7eea5ed88633676d6597bc8e384db",
23 | "_spec": "follow-redirects@^1.10.0",
24 | "_where": "F:\\workspace\\eggjs-uniapp-shop\\uniapp\\node_modules\\axios",
25 | "author": {
26 | "name": "Ruben Verborgh",
27 | "email": "ruben@verborgh.org",
28 | "url": "https://ruben.verborgh.org/"
29 | },
30 | "bugs": {
31 | "url": "https://github.com/follow-redirects/follow-redirects/issues"
32 | },
33 | "bundleDependencies": false,
34 | "contributors": [
35 | {
36 | "name": "Olivier Lalonde",
37 | "email": "olalonde@gmail.com",
38 | "url": "http://www.syskall.com"
39 | },
40 | {
41 | "name": "James Talmage",
42 | "email": "james@talmage.io"
43 | }
44 | ],
45 | "deprecated": false,
46 | "description": "HTTP and HTTPS modules that follow redirects.",
47 | "devDependencies": {
48 | "concat-stream": "^2.0.0",
49 | "eslint": "^5.16.0",
50 | "express": "^4.16.4",
51 | "lolex": "^3.1.0",
52 | "mocha": "^6.0.2",
53 | "nyc": "^14.1.1"
54 | },
55 | "engines": {
56 | "node": ">=4.0"
57 | },
58 | "files": [
59 | "*.js"
60 | ],
61 | "funding": [
62 | {
63 | "type": "individual",
64 | "url": "https://github.com/sponsors/RubenVerborgh"
65 | }
66 | ],
67 | "homepage": "https://github.com/follow-redirects/follow-redirects",
68 | "keywords": [
69 | "http",
70 | "https",
71 | "url",
72 | "redirect",
73 | "client",
74 | "location",
75 | "utility"
76 | ],
77 | "license": "MIT",
78 | "main": "index.js",
79 | "name": "follow-redirects",
80 | "repository": {
81 | "type": "git",
82 | "url": "git+ssh://git@github.com/follow-redirects/follow-redirects.git"
83 | },
84 | "scripts": {
85 | "lint": "eslint *.js test",
86 | "mocha": "nyc mocha",
87 | "test": "npm run lint && npm run mocha"
88 | },
89 | "version": "1.13.0"
90 | }
91 |
--------------------------------------------------------------------------------
/uniapp/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "requires": true,
3 | "lockfileVersion": 1,
4 | "dependencies": {
5 | "axios": {
6 | "version": "0.21.0",
7 | "resolved": "https://registry.npm.taobao.org/axios/download/axios-0.21.0.tgz?cache=0&sync_timestamp=1603468783865&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.21.0.tgz",
8 | "integrity": "sha1-Jt8IiAOiNQ3/LCf5b++Z/klEKso=",
9 | "requires": {
10 | "follow-redirects": "^1.10.0"
11 | }
12 | },
13 | "follow-redirects": {
14 | "version": "1.13.0",
15 | "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.13.0.tgz",
16 | "integrity": "sha1-tC6Nk6Kn7qXtiGM2dtZZe8jjhNs="
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/uniapp/pages/money/money.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
23 |
--------------------------------------------------------------------------------
/uniapp/pages/money/orderSuccess.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 订单提交成功
5 |
6 |
7 | 查看订单
8 | 返回首页
9 |
10 |
11 |
12 |
13 |
25 |
26 |
63 |
--------------------------------------------------------------------------------
/uniapp/pages/money/paySuccess.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 支付成功
5 |
6 |
7 | 查看订单
8 | 返回首页
9 |
10 |
11 |
12 |
13 |
25 |
26 |
63 |
--------------------------------------------------------------------------------
/uniapp/pages/userinfo/setting.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
66 |
67 |
94 |
--------------------------------------------------------------------------------
/uniapp/static/arc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/arc.png
--------------------------------------------------------------------------------
/uniapp/static/emptyCart.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/emptyCart.jpg
--------------------------------------------------------------------------------
/uniapp/static/errorImage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/errorImage.jpg
--------------------------------------------------------------------------------
/uniapp/static/missing-face.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/missing-face.png
--------------------------------------------------------------------------------
/uniapp/static/select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/select.png
--------------------------------------------------------------------------------
/uniapp/static/selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/selected.png
--------------------------------------------------------------------------------
/uniapp/static/tab-cart-current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/tab-cart-current.png
--------------------------------------------------------------------------------
/uniapp/static/tab-cart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/tab-cart.png
--------------------------------------------------------------------------------
/uniapp/static/tab-cate-current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/tab-cate-current.png
--------------------------------------------------------------------------------
/uniapp/static/tab-cate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/tab-cate.png
--------------------------------------------------------------------------------
/uniapp/static/tab-home-current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/tab-home-current.png
--------------------------------------------------------------------------------
/uniapp/static/tab-home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/tab-home.png
--------------------------------------------------------------------------------
/uniapp/static/tab-my-current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/tab-my-current.png
--------------------------------------------------------------------------------
/uniapp/static/tab-my.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/tab-my.png
--------------------------------------------------------------------------------
/uniapp/static/temp/ad-splash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/ad-splash.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/ad1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/ad1.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/ad2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/ad2.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/ad3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/ad3.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/banner1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/banner1.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/banner2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/banner2.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/banner3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/banner3.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/banner4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/banner4.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/c1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/c1.png
--------------------------------------------------------------------------------
/uniapp/static/temp/c2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/c2.png
--------------------------------------------------------------------------------
/uniapp/static/temp/c3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/c3.png
--------------------------------------------------------------------------------
/uniapp/static/temp/c4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/c4.png
--------------------------------------------------------------------------------
/uniapp/static/temp/c5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/c5.png
--------------------------------------------------------------------------------
/uniapp/static/temp/c6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/c6.png
--------------------------------------------------------------------------------
/uniapp/static/temp/c7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/c7.png
--------------------------------------------------------------------------------
/uniapp/static/temp/c8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/c8.png
--------------------------------------------------------------------------------
/uniapp/static/temp/cate1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate1.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate10.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate11.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate12.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate13.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate14.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate15.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate16.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate16.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate17.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate17.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate18.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate18.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate19.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate19.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate2.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate20.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate20.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate21.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate21.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate22.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate23.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate23.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate24.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate24.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate3.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate4.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate5.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate6.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate7.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate8.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/cate9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/cate9.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/h1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/h1.png
--------------------------------------------------------------------------------
/uniapp/static/temp/secskill-img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/secskill-img.jpg
--------------------------------------------------------------------------------
/uniapp/static/temp/share_moment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/share_moment.png
--------------------------------------------------------------------------------
/uniapp/static/temp/share_qq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/share_qq.png
--------------------------------------------------------------------------------
/uniapp/static/temp/share_qqzone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/share_qqzone.png
--------------------------------------------------------------------------------
/uniapp/static/temp/share_wechat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/temp/share_wechat.png
--------------------------------------------------------------------------------
/uniapp/static/user-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/user-bg.jpg
--------------------------------------------------------------------------------
/uniapp/static/vip-card-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/vip-card-bg.png
--------------------------------------------------------------------------------
/uniapp/static/yticon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anderw/eggjs-uniapp-shop/919baae2010e45c597d6d40630ebbaa37b5ea141/uniapp/static/yticon.ttf
--------------------------------------------------------------------------------
/uniapp/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 | user: {},
10 | token: '',
11 | baseUrl: 'http://localhost:7001',
12 | merchantId: 1
13 | },
14 | mutations: {
15 | login(state, provider) {
16 | state.hasLogin = true;
17 | state.user = provider;
18 | uni.setStorage({//缓存用户登陆状态
19 | key: 'userInfo',
20 | data: provider
21 | })
22 | },
23 | logout(state) {
24 | state.hasLogin = false;
25 | state.user = {};
26 | uni.removeStorage({
27 | key: 'userInfo'
28 | })
29 | },
30 | setToken(state,token){
31 | state.token = token
32 | uni.setStorage({
33 | key: 'token',
34 | data: token
35 | })
36 | }
37 | },
38 | actions: {
39 | logout({commit}){
40 | commit('logout')
41 | }
42 | }
43 | })
44 |
45 | export default store
46 |
--------------------------------------------------------------------------------
/uniapp/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 |
--------------------------------------------------------------------------------