├── .browserslistrc ├── public ├── favicon.ico ├── background.jpeg └── index.html ├── src ├── assets │ └── logo.png ├── store │ └── index.js ├── main.js ├── components │ ├── LayoutSider.vue │ ├── EditableCell.vue │ ├── EditableCellImg.vue │ ├── EditableCellNumber.vue │ ├── CommentItem.vue │ ├── EditableCellSelect.vue │ ├── ProductDetailCarousel.vue │ ├── CarouselTwo.vue │ ├── CommodityItem.vue │ ├── RecommendedProducts.vue │ ├── CartItem.vue │ ├── OrderItem.vue │ ├── AdminProductItem.vue │ ├── AdminOrderItem.vue │ └── LayoutHeader.vue ├── user │ └── index.js ├── views │ ├── MainIndex.vue │ ├── ProduceDetailIntroduction.vue │ ├── MainView.vue │ ├── AdminIndex.vue │ ├── ForgetPassword.vue │ ├── ProduceDetailComment.vue │ ├── AdminProductType.vue │ ├── Cart.vue │ ├── ConfirmOrder.vue │ ├── Login.vue │ ├── Personal.vue │ ├── Search.vue │ ├── ProductType.vue │ ├── ProductDetail.vue │ ├── AdminCarousel.vue │ ├── Registration.vue │ ├── AdminOrder.vue │ ├── AdminProductNew.vue │ ├── Order.vue │ └── AdminProduct.vue ├── App.vue ├── api │ └── index.js ├── http │ └── index.js └── router │ └── index.js ├── babel.config.js ├── .gitignore ├── .editorconfig ├── vue.config.js ├── package.json ├── README.md └── LICENSE /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/sports-mall-client/master/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/sports-mall-client/master/src/assets/logo.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /public/background.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/sports-mall-client/master/public/background.jpeg -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | Vue.use(Vuex); 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | now_path: '' 9 | }, 10 | mutations: {}, 11 | actions: {}, 12 | modules: {} 13 | }) 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.vue] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.js] 12 | charset = utf-8 13 | indent_style = space 14 | indent_size = 2 15 | end_of_line = lf 16 | insert_final_newline = true 17 | trim_trailing_whitespace = true 18 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | // vue.config.js 2 | module.exports = { 3 | css: { 4 | loaderOptions: { 5 | less: { 6 | modifyVars: { 7 | 'primary-color': '#1890ff', 8 | 'link-color': '#1890ff', 9 | 'border-radius-base': '2px', 10 | }, 11 | javascriptEnabled: true 12 | } 13 | } 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import store from './store' 5 | import User from "./user"; 6 | import Antd from 'ant-design-vue' 7 | import 'ant-design-vue/dist/antd.less' 8 | import "./http" 9 | 10 | Vue.config.productionTip = false; 11 | Vue.use(Antd); 12 | Vue.use(User); 13 | 14 | new Vue({ 15 | router, 16 | store, 17 | render: h => h(App) 18 | }).$mount('#app'); 19 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 体育用品商城 9 | 10 | 11 | 14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /src/components/LayoutSider.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 23 | 24 | 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sports-mall-client", 3 | "version": "1.0.1-RELEASE", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "@itning/axios-helper": "^1.1.0", 11 | "ant-design-vue": "^1.6.4", 12 | "core-js": "^3.6.5", 13 | "js-base64": "^2.5.2", 14 | "moment": "^2.27.0", 15 | "vue": "^2.6.11", 16 | "vue-router": "^3.3.4", 17 | "vuex": "^3.4.0" 18 | }, 19 | "devDependencies": { 20 | "@vue/cli-plugin-babel": "^4.4.4", 21 | "@vue/cli-plugin-router": "^4.4.4", 22 | "@vue/cli-plugin-vuex": "^4.4.4", 23 | "@vue/cli-service": "^4.4.4", 24 | "less": "^3.11.3", 25 | "less-loader": "^5.0.0", 26 | "vue-template-compiler": "^2.6.11" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/user/index.js: -------------------------------------------------------------------------------- 1 | import {Base64} from 'js-base64'; 2 | 3 | export const LOCAL_STORAGE_KEY = 'authorization_token'; 4 | let User = {}; 5 | 6 | export function analyze(token) { 7 | try { 8 | return JSON.parse(JSON.parse( 9 | Base64.decode(token.split('.')[1]) 10 | ).loginUser); 11 | } catch (e) { 12 | return {}; 13 | } 14 | } 15 | 16 | User.loginUser = function () { 17 | if (window.localStorage.getItem(LOCAL_STORAGE_KEY) === null) { 18 | return {}; 19 | } 20 | try { 21 | return JSON.parse(JSON.parse( 22 | Base64.decode( 23 | window.localStorage.getItem(LOCAL_STORAGE_KEY) 24 | .split('.')[1] 25 | ) 26 | ).loginUser); 27 | } catch (e) { 28 | window.localStorage.removeItem(LOCAL_STORAGE_KEY); 29 | return {}; 30 | } 31 | }; 32 | 33 | User.install = function (Vue, options) { 34 | Vue.prototype.$user = User; 35 | }; 36 | export default User; 37 | -------------------------------------------------------------------------------- /src/components/EditableCell.vue: -------------------------------------------------------------------------------- 1 | 13 | 39 | -------------------------------------------------------------------------------- /src/views/MainIndex.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 32 | 33 | 36 | -------------------------------------------------------------------------------- /src/components/EditableCellImg.vue: -------------------------------------------------------------------------------- 1 | 13 | 39 | -------------------------------------------------------------------------------- /src/components/EditableCellNumber.vue: -------------------------------------------------------------------------------- 1 | 13 | 40 | -------------------------------------------------------------------------------- /src/components/CommentItem.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 25 | 26 | 44 | -------------------------------------------------------------------------------- /src/components/EditableCellSelect.vue: -------------------------------------------------------------------------------- 1 | 15 | 43 | -------------------------------------------------------------------------------- /src/components/ProductDetailCarousel.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 29 | 30 | 61 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | 19 | 55 | -------------------------------------------------------------------------------- /src/views/ProduceDetailIntroduction.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 46 | 47 | 50 | -------------------------------------------------------------------------------- /src/views/MainView.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 49 | 50 | 53 | -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | export const SERVER_HOST = "http://localhost:8888"; 2 | export const API = { 3 | user: { 4 | login: `${SERVER_HOST}/login`, 5 | modify: `${SERVER_HOST}/user`, 6 | reg: `${SERVER_HOST}/reg`, 7 | pwd: `${SERVER_HOST}/pwd` 8 | }, 9 | commodityType: { 10 | all: `${SERVER_HOST}/commodity_types`, 11 | modify: `${SERVER_HOST}/commodity_type`, 12 | del: `${SERVER_HOST}/commodity_type/`, 13 | add: `${SERVER_HOST}/commodity_type` 14 | }, 15 | commodity: { 16 | type: `${SERVER_HOST}/commodity/type`, 17 | recommend: `${SERVER_HOST}/commodity/recommends`, 18 | one: `${SERVER_HOST}/commodity/one/`, 19 | commodityDetail: `${SERVER_HOST}/commodityDetail/`, 20 | search: `${SERVER_HOST}/commodity/search/`, 21 | admin_all: `${SERVER_HOST}/commodity/admin`, 22 | admin_modify: `${SERVER_HOST}/commodity/admin`, 23 | admin_modify_detail: `${SERVER_HOST}/commodityDetail`, 24 | admin_add: `${SERVER_HOST}/commodity/admin` 25 | }, 26 | comment: { 27 | all: `${SERVER_HOST}/comment/`, 28 | add: `${SERVER_HOST}/comment` 29 | }, 30 | cart: { 31 | add: `${SERVER_HOST}/cart`, 32 | all: `${SERVER_HOST}/carts`, 33 | del: `${SERVER_HOST}/cart/` 34 | }, 35 | order: { 36 | all: `${SERVER_HOST}/orders`, 37 | del: `${SERVER_HOST}/order/`, 38 | pay: `${SERVER_HOST}/order/pay`, 39 | hip: `${SERVER_HOST}/order/hip`, 40 | receipt: `${SERVER_HOST}/order/receipt`, 41 | add: `${SERVER_HOST}/order`, 42 | admin_all: `${SERVER_HOST}/orders/admin`, 43 | admin_modify_price: `${SERVER_HOST}/order/price` 44 | }, 45 | carousel: { 46 | all: `${SERVER_HOST}/carousels`, 47 | add: `${SERVER_HOST}/carousel`, 48 | del: `${SERVER_HOST}/carousel/`, 49 | modify: `${SERVER_HOST}/carousel` 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /src/components/CarouselTwo.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 52 | 53 | 66 | -------------------------------------------------------------------------------- /src/components/CommodityItem.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 35 | 36 | 93 | -------------------------------------------------------------------------------- /src/components/RecommendedProducts.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 52 | 53 | 81 | -------------------------------------------------------------------------------- /src/views/AdminIndex.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 65 | 66 | 69 | -------------------------------------------------------------------------------- /src/http/index.js: -------------------------------------------------------------------------------- 1 | import {AxiosHelperConfig} from '@itning/axios-helper' 2 | import Vue from 'vue' 3 | import {LOCAL_STORAGE_KEY} from "../user"; 4 | 5 | AxiosHelperConfig.errorMsgImpl = { 6 | showErrorToast(title, data) { 7 | let msg; 8 | if (typeof data === "string") { 9 | msg = data; 10 | } else { 11 | msg = data.msg; 12 | } 13 | Vue.prototype.$notification.error({ 14 | message: title, 15 | description: msg, 16 | duration: 4.5, 17 | onClose: () => { 18 | AxiosHelperConfig.onceMsgFinish(); 19 | } 20 | }); 21 | } 22 | }; 23 | 24 | AxiosHelperConfig.axiosInstanceBuilder 25 | .timeOut(1000 * 12) 26 | .requestInterceptor({ 27 | onFulfilled: request => { 28 | let token = window.localStorage.getItem(LOCAL_STORAGE_KEY); 29 | if (token !== undefined) { 30 | request.headers = { 31 | "Authorization": token, 32 | "Accept": "application/json" 33 | }; 34 | } else { 35 | request.headers = {"Accept": "application/json"}; 36 | } 37 | return request; 38 | }, 39 | onRejected: error => { 40 | return Promise.reject(error); 41 | } 42 | }) 43 | .responseInterceptor({ 44 | onFulfilled: response => { 45 | return Promise.resolve(response); 46 | }, 47 | onRejected: error => { 48 | if (error.response === undefined) { 49 | return Promise.reject(error); 50 | } 51 | if (error.response.status) { 52 | switch (error.response.status) { 53 | case 401: 54 | setTimeout(() => { 55 | window.location.href = "/login"; 56 | }, 2000); 57 | break; 58 | case 403: 59 | setTimeout(() => { 60 | window.location.href = "/login"; 61 | }, 2000); 62 | console.warn('权限不足'); 63 | break; 64 | case 404: 65 | console.warn('请求URL不存在'); 66 | break; 67 | case 500: 68 | console.warn('服务器错误'); 69 | break; 70 | case 503: 71 | console.warn('服务器错误'); 72 | break; 73 | default: 74 | console.warn(error); 75 | } 76 | return Promise.reject(error); 77 | } 78 | } 79 | }) 80 | .build(); 81 | -------------------------------------------------------------------------------- /src/views/ForgetPassword.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 92 | 93 | 99 | -------------------------------------------------------------------------------- /src/views/ProduceDetailComment.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 87 | 88 | 95 | -------------------------------------------------------------------------------- /src/components/CartItem.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 85 | 86 | 119 | -------------------------------------------------------------------------------- /src/components/OrderItem.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 104 | 105 | 143 | -------------------------------------------------------------------------------- /src/components/AdminProductItem.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 85 | 86 | 119 | -------------------------------------------------------------------------------- /src/views/AdminProductType.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 117 | 118 | 123 | -------------------------------------------------------------------------------- /src/components/AdminOrderItem.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 113 | 114 | 152 | -------------------------------------------------------------------------------- /src/views/Cart.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 104 | 105 | 123 | -------------------------------------------------------------------------------- /src/components/LayoutHeader.vue: -------------------------------------------------------------------------------- 1 | 58 | 59 | 102 | 103 | 106 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 体育用品商城-客户端 2 | 3 | [![GitHub stars](https://img.shields.io/github/stars/itning/sports-mall-client.svg?style=social&label=Stars)](https://github.com/itning/sports-mall-client/stargazers) 4 | [![GitHub forks](https://img.shields.io/github/forks/itning/sports-mall-client.svg?style=social&label=Fork)](https://github.com/itning/sports-mall-client/network/members) 5 | [![GitHub watchers](https://img.shields.io/github/watchers/itning/sports-mall-client.svg?style=social&label=Watch)](https://github.com/itning/sports-mall-client/watchers) 6 | [![GitHub followers](https://img.shields.io/github/followers/itning.svg?style=social&label=Follow)](https://github.com/itning?tab=followers) 7 | 8 | [![GitHub issues](https://img.shields.io/github/issues/itning/sports-mall-client.svg)](https://github.com/itning/sports-mall-client/issues) 9 | [![GitHub license](https://img.shields.io/github/license/itning/sports-mall-client.svg)](https://github.com/itning/sports-mall-client/blob/master/LICENSE) 10 | [![GitHub last commit](https://img.shields.io/github/last-commit/itning/sports-mall-client.svg)](https://github.com/itning/sports-mall-client/commits) 11 | [![GitHub release](https://img.shields.io/github/release/itning/sports-mall-client.svg)](https://github.com/itning/sports-mall-client/releases) 12 | [![GitHub repo size in bytes](https://img.shields.io/github/repo-size/itning/sports-mall-client.svg)](https://github.com/itning/sports-mall-client) 13 | [![HitCount](http://hits.dwyl.com/itning/sports-mall-client.svg)](http://hits.dwyl.com/itning/sports-mall-client) 14 | [![language](https://img.shields.io/badge/language-Vue-green.svg)](https://github.com/itning/sports-mall-client) 15 | 16 | ## 架构: 17 | - MySQL 8 18 | - Java 8 19 | - Spring Boot 2 20 | - Vue.JS 21 | 22 | ## 功能 23 | 24 | - 垂直/水平轮播图展示管理 25 | - 商品分类展示管理 26 | - 商品搜索 27 | - 推荐商品管理展示 28 | - 订单管理 29 | - 购物车管理 30 | - 登录注册 31 | - 商品评论展示 32 | - 商品详情信息展示 33 | - 商品介绍跑马灯 34 | 35 | ## 部署 36 | 37 | 1. 使用git克隆项目([Git是什么,如何使用?](https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/)) 38 | 39 | ```bash 40 | # 克隆后端文件到本地磁盘 41 | git clone https://github.com/itning/sports-mall-server 42 | # 克隆前端文件到本地磁盘 43 | git clone https://github.com/itning/sports-mall-client 44 | ``` 45 | 46 | 2. 打开前端文件夹 47 | 48 | 安装之前确保你有[node.js](https://nodejs.org/zh-cn/)和[yarn](https://classic.yarnpkg.com/zh-Hans/docs/install/#windows-stable) 49 | 50 | ```bash 51 | # 如果已经在前端文件夹内了,则不需要这个命令 52 | cd sports-mall-client 53 | # 安装依赖 54 | yarn install 55 | ``` 56 | 57 | 3. 后端建议使用[idea](https://www.jetbrains.com/idea/)打开本项目,不建议使用Eclipse或MyEclipse 58 | 59 | 确保你有[maven](https://maven.apache.org/download.cgi),并执行编译命令 60 | 61 | ```bash 62 | mvn clean compile 63 | ``` 64 | 65 | 不出意外会出现`BUILD SUCCESS` 66 | 67 | 4. 数据库密码在哪改? 68 | 69 | [在这](https://github.com/itning/sports-mall-server/blob/master/src/main/resources/application.properties#L22) 70 | 71 | 5. 前端接口域名在哪改? 72 | 73 | [在这](https://github.com/itning/sports-mall-client/blob/master/src/api/index.js#L1) 74 | 75 | 6. 登录管理员账户? 76 | 77 | ```sql 78 | # 先插入管理员账户数据 用户名:admin 密码:admin 79 | INSERT INTO `mail_user` VALUES ('admin', NULL, 'admin@admin.co', '2020-02-13 11:31:24.451000', '2020-02-13 11:31:24.451000', 'admin', '17588755691', '1'); 80 | ``` 81 | 82 | 7. 运行项目: 83 | 84 | 后端[main方法](https://github.com/itning/sports-mall-server/blob/master/src/main/java/com/sport/sportsmallserver/SportsMailServerApplication.java#L9)直接运行 85 | 86 | 前端执行以下命令进行开发运行 87 | 88 | ```bash 89 | yarn serve 90 | ``` 91 | 92 | 8. 数据库SQL文件? 93 | 94 | JPA自动建库建表不需要SQL文件。 95 | 96 | ## 项目预览 97 | 98 | ![a](https://raw.githubusercontent.com/itning/sports-mall-server/master/pic/1.png) 99 | 100 | ![b](https://raw.githubusercontent.com/itning/sports-mall-server/master/pic/2.png) 101 | 102 | ![c](https://raw.githubusercontent.com/itning/sports-mall-server/master/pic/3.png) 103 | 104 | ![d](https://raw.githubusercontent.com/itning/sports-mall-server/master/pic/4.png) 105 | 106 | ![e](https://raw.githubusercontent.com/itning/sports-mall-server/master/pic/5.png) 107 | 108 | ![f](https://raw.githubusercontent.com/itning/sports-mall-server/master/pic/6.png) 109 | -------------------------------------------------------------------------------- /src/views/ConfirmOrder.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 108 | 109 | 138 | -------------------------------------------------------------------------------- /src/views/Login.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 100 | 101 | 128 | -------------------------------------------------------------------------------- /src/views/Personal.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 114 | 115 | 130 | -------------------------------------------------------------------------------- /src/views/Search.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 108 | 109 | 142 | -------------------------------------------------------------------------------- /src/views/ProductType.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 119 | 120 | 153 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import Vuex from '../store' 4 | import MainIndex from "../views/MainIndex"; 5 | import MainView from "../views/MainView"; 6 | import User, {LOCAL_STORAGE_KEY} from "../user"; 7 | import AdminIndex from "../views/AdminIndex"; 8 | 9 | Vue.use(VueRouter); 10 | 11 | const routes = [ 12 | { 13 | path: '/', 14 | component: MainIndex, 15 | children: [ 16 | { 17 | path: '', 18 | components: { 19 | subContent: MainView 20 | } 21 | }, 22 | { 23 | path: 'search/:keyword', 24 | components: { 25 | subContent: () => import(/* webpackChunkName: "Search" */ '../views/Search.vue') 26 | } 27 | }, 28 | { 29 | path: 'product_type/:id', 30 | components: { 31 | subContent: () => import(/* webpackChunkName: "ProductType" */ '../views/ProductType.vue') 32 | } 33 | }, 34 | { 35 | path: 'order', 36 | components: { 37 | subContent: () => import(/* webpackChunkName: "Order" */ '../views/Order.vue') 38 | } 39 | }, 40 | { 41 | path: 'cart', 42 | components: { 43 | subContent: () => import(/* webpackChunkName: "Cart" */ '../views/Cart.vue') 44 | } 45 | }, 46 | { 47 | path: 'product_detail/:id', 48 | components: { 49 | subContent: () => import(/* webpackChunkName: "ProductDetail" */ '../views/ProductDetail.vue') 50 | }, 51 | children: [ 52 | { 53 | path: '', 54 | components: { 55 | product: () => import(/* webpackChunkName: "ProduceDetailIntroduction" */ '../views/ProduceDetailIntroduction.vue') 56 | } 57 | }, 58 | { 59 | path: 'comment', 60 | components: { 61 | product: () => import(/* webpackChunkName: "ProduceDetailComment" */ '../views/ProduceDetailComment.vue') 62 | } 63 | } 64 | ] 65 | }, 66 | { 67 | path: 'confirm_order/:id/:count', 68 | components: { 69 | subContent: () => import(/* webpackChunkName: "ConfirmOrder" */ '../views/ConfirmOrder.vue') 70 | } 71 | }, 72 | { 73 | path: 'personal', 74 | components: { 75 | subContent: () => import(/* webpackChunkName: "Personal" */ '../views/Personal.vue') 76 | } 77 | } 78 | ] 79 | }, 80 | { 81 | path: '/admin', 82 | component: AdminIndex, 83 | children: [ 84 | { 85 | path: '', 86 | redirect: 'product' 87 | }, 88 | { 89 | path: 'productType', 90 | components: { 91 | subContent: () => import(/* webpackChunkName: "AdminProductType" */ '../views/AdminProductType.vue') 92 | } 93 | }, 94 | { 95 | path: 'carousel', 96 | components: { 97 | subContent: () => import(/* webpackChunkName: "AdminCarousel" */ '../views/AdminCarousel.vue') 98 | } 99 | }, 100 | { 101 | path: 'order', 102 | components: { 103 | subContent: () => import(/* webpackChunkName: "AdminOrder" */ '../views/AdminOrder.vue') 104 | } 105 | }, 106 | { 107 | path: 'product', 108 | components: { 109 | subContent: () => import(/* webpackChunkName: "AdminProduct" */ '../views/AdminProduct.vue') 110 | } 111 | }, 112 | { 113 | path: 'product_new', 114 | components: { 115 | subContent: () => import(/* webpackChunkName: "AdminProductNew" */ '../views/AdminProductNew.vue') 116 | } 117 | } 118 | ], 119 | }, 120 | { 121 | path: '/login', 122 | name: 'Login', 123 | component: () => import(/* webpackChunkName: "Login" */ '../views/Login.vue') 124 | }, 125 | { 126 | path: '/reg', 127 | name: 'Registration', 128 | component: () => import(/* webpackChunkName: "Registration" */ '../views/Registration.vue') 129 | }, 130 | { 131 | path: '/forget_pwd', 132 | name: 'ForgetPassword', 133 | component: () => import(/* webpackChunkName: "ForgetPassword" */ '../views/ForgetPassword.vue') 134 | }, 135 | { 136 | path: '*', 137 | redirect: '/' 138 | } 139 | ]; 140 | 141 | const router = new VueRouter({ 142 | mode: 'history', 143 | base: process.env.BASE_URL, 144 | routes 145 | }); 146 | 147 | router.beforeEach((to, from, next) => { 148 | if (to.path === "/login" || 149 | to.path === "/reg" || 150 | to.path === "/" || 151 | to.path === '/forget_pwd') { 152 | next(); 153 | return; 154 | } 155 | if (to.path.startsWith("/admin")) { 156 | if (!localStorage.getItem(LOCAL_STORAGE_KEY)) { 157 | next("/login"); 158 | } else { 159 | if (User.loginUser().role.id === '1') { 160 | next(); 161 | } else { 162 | next('/login'); 163 | } 164 | } 165 | return; 166 | } 167 | next(); 168 | }); 169 | 170 | router.afterEach((to, from) => { 171 | if (to.path === "/login" || 172 | to.path === "/reg" || 173 | to.path === "/forget_pwd") { 174 | return; 175 | } 176 | Vuex.state.now_path = to.path; 177 | }); 178 | 179 | export default router 180 | -------------------------------------------------------------------------------- /src/views/ProductDetail.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 134 | 135 | 171 | -------------------------------------------------------------------------------- /src/views/AdminCarousel.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 154 | 155 | 160 | -------------------------------------------------------------------------------- /src/views/Registration.vue: -------------------------------------------------------------------------------- 1 | 108 | 109 | 205 | 206 | 212 | -------------------------------------------------------------------------------- /src/views/AdminOrder.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 171 | 172 | 190 | -------------------------------------------------------------------------------- /src/views/AdminProductNew.vue: -------------------------------------------------------------------------------- 1 | 144 | 145 | 231 | 232 | 235 | -------------------------------------------------------------------------------- /src/views/Order.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 192 | 193 | 211 | -------------------------------------------------------------------------------- /src/views/AdminProduct.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 202 | 203 | 210 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2019 itning 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------