├── public ├── favicon.ico └── index.html ├── src ├── assets │ ├── logo.png │ └── impl.js ├── plugins │ └── element.js ├── pages │ ├── test │ │ ├── Test.js │ │ └── TestComponent.vue │ ├── product │ │ ├── list │ │ │ ├── BoughtProducts.vue │ │ │ ├── Selling.vue │ │ │ ├── MyProducts.vue │ │ │ └── CensoringProduct.vue │ │ ├── Edit.vue │ │ └── Detail.vue │ ├── chat │ │ ├── StartChat.vue │ │ └── Chat.vue │ ├── login │ │ └── Login.vue │ ├── register │ │ └── Register.vue │ └── profile │ │ └── Profile.vue ├── main.js ├── router │ └── fleaRouter.js ├── components │ ├── UserSummary.vue │ ├── ProductList.vue │ ├── ChatPanel.vue │ └── ProductDetailTable.vue └── index.vue ├── babel.config.js ├── vue.config.js ├── .editorconfig ├── .gitignore ├── README.md └── package.json /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafee98/flea-market-front/master/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leafee98/flea-market-front/master/src/assets/logo.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | configureWebpack: { 3 | performance: { 4 | hints: false 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /src/plugins/element.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Element from 'element-ui' 3 | import 'element-ui/lib/theme-chalk/index.css' 4 | 5 | Vue.use(Element) 6 | -------------------------------------------------------------------------------- /src/pages/test/Test.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import testComponent from './TestComponent.vue' 3 | 4 | new Vue({ 5 | render: h => h(testComponent) 6 | }).$mount('#app') 7 | -------------------------------------------------------------------------------- /src/pages/product/list/BoughtProducts.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 14 | -------------------------------------------------------------------------------- /src/pages/product/list/Selling.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /src/pages/product/list/MyProducts.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /src/pages/product/list/CensoringProduct.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flea-front 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 | -------------------------------------------------------------------------------- /src/pages/test/TestComponent.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 22 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Element from 'element-ui' 3 | import 'element-ui/lib/theme-chalk/index.css' 4 | import router from '@/router/fleaRouter.js' 5 | import index from './index.vue' 6 | 7 | import compoProductDetailTable from '@/components/ProductDetailTable.vue' 8 | import compoProductList from '@/components/ProductList.vue' 9 | import compoUserSummary from '@/components/UserSummary.vue' 10 | import compoChatPanel from '@/components/ChatPanel.vue' 11 | 12 | Vue.use(Element) 13 | 14 | Vue.component('compo-product-detail-table', compoProductDetailTable) 15 | Vue.component('compo-product-list', compoProductList) 16 | Vue.component('compo-user-summary', compoUserSummary) 17 | Vue.component('compo-chat-panel', compoChatPanel) 18 | 19 | new Vue({ 20 | router, 21 | render: h => h(index) 22 | }).$mount('#app') 23 | -------------------------------------------------------------------------------- /src/pages/product/Edit.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 52 | 53 | 56 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flea-front", 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 | "core-js": "^3.6.4", 12 | "element-ui": "^2.4.5", 13 | "vue": "^2.6.11", 14 | "vue-router": "^3.1.6" 15 | }, 16 | "devDependencies": { 17 | "@vue/cli-plugin-babel": "~4.3.0", 18 | "@vue/cli-plugin-eslint": "~4.3.0", 19 | "@vue/cli-plugin-router": "~4.3.0", 20 | "@vue/cli-service": "~4.3.0", 21 | "@vue/eslint-config-standard": "^5.1.2", 22 | "babel-eslint": "^10.1.0", 23 | "eslint": "^6.7.2", 24 | "eslint-plugin-import": "^2.20.2", 25 | "eslint-plugin-node": "^11.1.0", 26 | "eslint-plugin-promise": "^4.2.1", 27 | "eslint-plugin-standard": "^4.0.0", 28 | "eslint-plugin-vue": "^6.2.2", 29 | "vue-cli-plugin-element": "~1.0.1", 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 | "@vue/standard" 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 | -------------------------------------------------------------------------------- /src/pages/product/Detail.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 52 | 53 | 58 | -------------------------------------------------------------------------------- /src/pages/chat/StartChat.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 49 | 50 | 53 | -------------------------------------------------------------------------------- /src/pages/login/Login.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 60 | -------------------------------------------------------------------------------- /src/pages/register/Register.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 75 | -------------------------------------------------------------------------------- /src/router/fleaRouter.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | 4 | import Login from '@/pages/login/Login.vue' 5 | import Register from '@/pages/register/Register.vue' 6 | 7 | import Profile from '@/pages/profile/Profile' 8 | 9 | import ProductSelling from '@/pages/product/list/Selling.vue' 10 | import MyProducts from '@/pages/product/list/MyProducts.vue' 11 | import BoughtProducts from '@/pages/product/list/BoughtProducts.vue' 12 | import CensoringProduct from '@/pages/product/list/CensoringProduct' 13 | 14 | import ProductDetail from '@/pages/product/Detail.vue' 15 | import ProductDetailEdit from '@/pages/product/Edit.vue' 16 | 17 | import Chat from '@/pages/chat/Chat.vue' 18 | import StartChat from '@/pages/chat/StartChat.vue' 19 | 20 | Vue.use(VueRouter) 21 | 22 | const routes = [ 23 | { path: '', redirect: { name: 'login' } }, 24 | { path: '/login', name: 'login', component: Login }, 25 | { path: '/register', name: 'register', component: Register }, 26 | { path: '/profile', name: 'myProfile', component: Profile }, 27 | { path: '/profile/:username', name: 'profile', component: Profile }, 28 | 29 | { path: '/product/', redirect: { name: 'productSelling' } }, 30 | { path: '/product/list/selling', name: 'productSelling', component: ProductSelling }, 31 | { path: '/product/list/myProducts', name: 'myProducts', component: MyProducts }, 32 | { path: '/product/list/boughtProducts', name: 'boughtProducts', component: BoughtProducts }, 33 | { path: '/product/list/censoringProduct', name: 'censoringProduct', component: CensoringProduct }, 34 | 35 | { path: '/product/detail/:productId', name: 'productDetail', component: ProductDetail }, 36 | { path: '/product/edit/:productId', name: 'productDetailEdit', component: ProductDetailEdit }, 37 | 38 | { path: '/chat/chat/:chatSessionId', name: 'chatSession', component: Chat }, 39 | { path: '/chat/chat', name: 'chat', component: Chat }, 40 | 41 | { path: '/chat/startChat/:username', name: 'startChat', component: StartChat } 42 | ] 43 | 44 | const router = new VueRouter({ 45 | routes: routes, 46 | mode: 'history' 47 | }) 48 | 49 | export default router 50 | -------------------------------------------------------------------------------- /src/components/UserSummary.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 70 | 71 | 84 | -------------------------------------------------------------------------------- /src/pages/chat/Chat.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 91 | 92 | 118 | -------------------------------------------------------------------------------- /src/components/ProductList.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 111 | 112 | 115 | -------------------------------------------------------------------------------- /src/index.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 113 | 114 | 122 | -------------------------------------------------------------------------------- /src/components/ChatPanel.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 134 | 135 | 161 | -------------------------------------------------------------------------------- /src/assets/impl.js: -------------------------------------------------------------------------------- 1 | const fleaHost = location.host 2 | const fleaApiProtocol = 'http://' 3 | 4 | const fleaApiUrl = { 5 | user: { 6 | register: fleaApiProtocol + fleaHost + '/api/user/register', 7 | authorize: fleaApiProtocol + fleaHost + '/api/user/authorize', 8 | logout: fleaApiProtocol + fleaHost + '/api/user/logout', 9 | modifyPassword: fleaApiProtocol + fleaHost + '/api/user/modifyPassword', 10 | modifyNickname: fleaApiProtocol + fleaHost + '/api/user/modifyNickname', 11 | modifyAvatar: fleaApiProtocol + fleaHost + '/api/user/modifyAvatar', 12 | addSocial: fleaApiProtocol + fleaHost + '/api/user/addSocial', 13 | removeSocial: fleaApiProtocol + fleaHost + '/api/user/removeSocial', 14 | getMyDetail: fleaApiProtocol + fleaHost + '/api/user/getMyDetail', 15 | getUserDetail: fleaApiProtocol + fleaHost + '/api/user/getUserDetail' 16 | }, 17 | admin: { 18 | grantUser: fleaApiProtocol + fleaHost + '/api/admin/grantUser', 19 | banUser: fleaApiProtocol + fleaHost + '/api/admin/banUser', 20 | getCensoringProducts: fleaApiProtocol + fleaHost + '/api/admin/getCensoringProducts', 21 | censorProduct: fleaApiProtocol + fleaHost + '/api/admin/censorProduct', 22 | publishBulletin: fleaApiProtocol + fleaHost + '/api/admin/publishBulletin' 23 | }, 24 | picture: { 25 | upload: fleaApiProtocol + fleaHost + '/api/picture/upload', 26 | download: fleaApiProtocol + fleaHost + '/api/picture/download' 27 | }, 28 | chat: { 29 | startChatSession: fleaApiProtocol + fleaHost + '/api/chat/startChatSession', 30 | getChatSessions: fleaApiProtocol + fleaHost + '/api/chat/getChatSessions', 31 | sendMsg: fleaApiProtocol + fleaHost + '/api/chat/sendMsg', 32 | getMsg: fleaApiProtocol + fleaHost + '/api/chat/getMsg' 33 | }, 34 | product: { 35 | getProductList: fleaApiProtocol + fleaHost + '/api/product/getProductList', 36 | getBoughtProductList: fleaApiProtocol + fleaHost + '/api/product/getBoughtProductList', 37 | getMyProductList: fleaApiProtocol + fleaHost + '/api/product/getMyProductList', 38 | getProductDetail: fleaApiProtocol + fleaHost + '/api/product/getProductDetail', 39 | newProduct: fleaApiProtocol + fleaHost + '/api/product/newProduct', 40 | deleteProduct: fleaApiProtocol + fleaHost + '/api/product/deleteProduct', 41 | editProduct: fleaApiProtocol + fleaHost + '/api/product/editProduct', 42 | editFinish: fleaApiProtocol + fleaHost + '/api/product/editFinish', 43 | editExpectedPrice: fleaApiProtocol + fleaHost + '/api/product/editExpectedPrice', 44 | editProductName: fleaApiProtocol + fleaHost + '/api/product/editProductName', 45 | editProductDetail: fleaApiProtocol + fleaHost + '/api/product/editProductDetail', 46 | editAddPic: fleaApiProtocol + fleaHost + '/api/product/editAddPic', 47 | editDeletePic: fleaApiProtocol + fleaHost + '/api/product/editDeletePic', 48 | orderProduct: fleaApiProtocol + fleaHost + '/api/product/orderProduct', 49 | cancelOrder: fleaApiProtocol + fleaHost + '/api/product/cancelOrder', 50 | confirmOrder: fleaApiProtocol + fleaHost + '/api/product/confirmOrder', 51 | comment: fleaApiProtocol + fleaHost + '/api/product/comment', 52 | getComments: fleaApiProtocol + fleaHost + '/api/product/getComments' 53 | } 54 | } 55 | 56 | const fleaApiParam = { 57 | user: { 58 | register: { username: null, nickname: null, password: null }, 59 | authorize: { username: null, password: null }, 60 | logout: { token: null }, 61 | modifyPassword: { token: null, password: null }, 62 | modifyNickname: { token: null, nickname: null }, 63 | modifyAvatar: { token: null, avatarUrl: null }, 64 | addSocial: { token: null, socialType: null, socialUrl: null }, 65 | removeSocial: { token: null, socialId: null }, 66 | getMyDetail: { token: null }, 67 | getUserDetail: { username: null } 68 | }, 69 | admin: { 70 | grantUser: { token: null, username: null }, 71 | banUser: { token: null, username: null, day: null }, 72 | getCensoringProducts: { token: null }, 73 | censorProduct: { token: null, productId: null, pass: null }, 74 | publishBulletin: { token: null, bulletinMsg: null } 75 | }, 76 | picture: { 77 | // upload:{ pic: null }, 78 | download: { picUid: null } 79 | }, 80 | chat: { 81 | startChatSession: { token: null, username: null }, 82 | getChatSessions: { token: null }, 83 | sendMsg: { token: null, chatSessionId: null, content: null }, 84 | getMsg: { token: null, chatSessionId: null } 85 | }, 86 | product: { 87 | getProductList: {}, 88 | getBoughtProductList: { token: null }, 89 | getMyProductList: { token: null }, 90 | getProductDetail: { productId: null }, 91 | newProduct: { token: null }, 92 | deleteProduct: { token: null, productId: null }, 93 | editProduct: { token: null, productId: null }, 94 | editFinish: { token: null, productId: null }, 95 | editExpectedPrice: { token: null, productId: null, price: null }, 96 | editProductName: { token: null, productId: null, productName: null }, 97 | editProductDetail: { token: null, productId: null, productDetail: null }, 98 | editAddPic: { token: null, productId: null, picUrl: null }, 99 | editDeletePic: { token: null, productId: null, picId: null }, 100 | orderProduct: { token: null, productId: null }, 101 | cancelOrder: { token: null, productId: null }, 102 | confirmOrder: { token: null, productId: null }, 103 | comment: { token: null, productId: null, content: null }, 104 | getComments: { productId: null } 105 | } 106 | } 107 | 108 | function fleaApiRequest (url, params) { 109 | const fetchReq = { 110 | method: 'POST', 111 | body: null 112 | } 113 | 114 | const fd = new FormData() 115 | for (const property in params) { 116 | fd.append(property, params[property]) 117 | } 118 | 119 | fetchReq.body = fd 120 | return fetch(url, fetchReq) 121 | } 122 | 123 | async function fleaApiPictureUpload (picFile) { 124 | const handleUpload = function (body) { 125 | if (body.success === true) { 126 | return fleaApiUrl.picture.download + '?picUid=' + body.data 127 | } else { 128 | return '' 129 | } 130 | } 131 | 132 | const fd = new FormData() 133 | fd.append('pic', picFile) 134 | const fetchReq = { 135 | method: 'POST', 136 | body: fd 137 | } 138 | return fetch(fleaApiUrl.picture.upload, fetchReq) 139 | .then(res => res.json()) 140 | .then(handleUpload) 141 | } 142 | 143 | const cookieUitls = { 144 | expireSec: 3600 * 24 * 7, 145 | parseCookie: function (cookieStr) { 146 | const res = {} 147 | if (!cookieStr.endsWith(';')) { 148 | cookieStr += ';' 149 | } 150 | 151 | while (cookieStr.length > 1) { 152 | const ie = cookieStr.indexOf('=') 153 | const is = cookieStr.indexOf(';') 154 | 155 | const key = cookieStr.substring(0, ie) 156 | const value = cookieStr.substring(ie + 1, is) 157 | res[key.trim()] = value 158 | 159 | cookieStr = cookieStr.substring(is + 1) 160 | } 161 | return res 162 | }, 163 | get: function (name) { 164 | return this.parseCookie(document.cookie)[name] 165 | }, 166 | set: function (name, value, expireSeconds) { 167 | let expireDate = null 168 | if (expireSeconds === undefined) { 169 | expireDate = new Date(Date.now() + 7 * 24 * 3600 * 1000) 170 | } else { 171 | expireDate = new Date(Date.now() + expireSeconds) 172 | } 173 | 174 | const tmpCookie = name + '=' + value + '; Expires=' + expireDate + '; SameSite=Strict; Path=/' 175 | document.cookie = tmpCookie 176 | } 177 | } 178 | 179 | const fleaUtils = { 180 | cloneObj: function (obj) { 181 | return Object.assign({}, obj) 182 | }, 183 | cookie: cookieUitls 184 | } 185 | 186 | // export fleaApiParam; 187 | // export fleaApiRequest; 188 | // export fleaApiUrl; 189 | // export fleaUtils; 190 | // export {fleaApiUrl, fleaApiParam, fleaApiRequest, fleaUtils}; 191 | 192 | export default { 193 | api: { 194 | url: fleaApiUrl, 195 | param: fleaApiParam, 196 | request: fleaApiRequest, 197 | picture: { 198 | upload: fleaApiPictureUpload 199 | } 200 | }, 201 | util: fleaUtils 202 | } 203 | -------------------------------------------------------------------------------- /src/pages/profile/Profile.vue: -------------------------------------------------------------------------------- 1 | 104 | 105 | 270 | 271 | > 305 | -------------------------------------------------------------------------------- /src/components/ProductDetailTable.vue: -------------------------------------------------------------------------------- 1 | 113 | 114 | 323 | 324 | 377 | --------------------------------------------------------------------------------