├── web
├── build
│ ├── logo.png
│ ├── vue-loader.conf.js
│ ├── build.js
│ ├── check-versions.js
│ └── webpack.base.conf.js
├── static
│ └── .gitkeep
├── .eslintignore
├── test
│ └── unit
│ │ ├── .eslintrc
│ │ └── specs
│ │ └── HelloWorld.spec.js
├── config
│ ├── prod.env.js
│ ├── test.env.js
│ ├── dev.env.js
│ └── index.js
├── src
│ ├── assets
│ │ └── images
│ │ │ ├── logo.png
│ │ │ ├── avatar.jpg
│ │ │ ├── login.png
│ │ │ ├── front-logo.png
│ │ │ ├── tel-icon.svg
│ │ │ ├── address-right-icon.svg
│ │ │ ├── search-icon.svg
│ │ │ ├── searchIcon.svg
│ │ │ ├── add.svg
│ │ │ ├── order-point-icon.svg
│ │ │ ├── pwd-icon.svg
│ │ │ ├── setting-msg-icon.svg
│ │ │ ├── register-name.svg
│ │ │ ├── clear-search.svg
│ │ │ ├── mail-icon.svg
│ │ │ ├── order-address-icon.svg
│ │ │ ├── message-icon.svg
│ │ │ ├── delete-icon.svg
│ │ │ ├── ebook-download-icon.svg
│ │ │ ├── code-icon.svg
│ │ │ ├── read-online-icon.svg
│ │ │ ├── share-icon.svg
│ │ │ ├── ali-pay-icon.svg
│ │ │ ├── wx-pay-icon.svg
│ │ │ ├── order-thing-icon.svg
│ │ │ ├── order-icon.svg
│ │ │ ├── want-read-hover.svg
│ │ │ ├── pwd-hidden.svg
│ │ │ ├── setting-icon.svg
│ │ │ ├── setting-safe-icon.svg
│ │ │ ├── cart-icon.svg
│ │ │ ├── recommend-hover.svg
│ │ │ ├── setting-card-icon.svg
│ │ │ └── wb-share.svg
│ ├── style
│ │ ├── index.less
│ │ ├── _var.less
│ │ └── scrollbar.less
│ ├── views
│ │ ├── index
│ │ │ ├── index.vue
│ │ │ ├── portal.vue
│ │ │ ├── search.vue
│ │ │ ├── user.vue
│ │ │ ├── user
│ │ │ │ ├── score-view.vue
│ │ │ │ ├── fans-view.vue
│ │ │ │ └── follow-view.vue
│ │ │ ├── components
│ │ │ │ └── footer.vue
│ │ │ └── modal
│ │ │ │ └── add-address.vue
│ │ └── admin
│ │ │ ├── layout
│ │ │ └── adminLayout.vue
│ │ │ ├── components
│ │ │ └── header.vue
│ │ │ ├── model
│ │ │ ├── edit-comment.vue
│ │ │ ├── edit-tag.vue
│ │ │ ├── edit-role.vue
│ │ │ ├── edit-password.vue
│ │ │ ├── edit-classification.vue
│ │ │ └── edit-notice.vue
│ │ │ ├── login-log.vue
│ │ │ ├── error-log.vue
│ │ │ ├── sys-info.vue
│ │ │ └── op-log.vue
│ ├── store
│ │ ├── constants.js
│ │ └── index.js
│ ├── api
│ │ ├── index
│ │ │ ├── tag.js
│ │ │ ├── notice.js
│ │ │ ├── classification.js
│ │ │ ├── address.js
│ │ │ ├── order.js
│ │ │ ├── user.js
│ │ │ ├── comment.js
│ │ │ └── thing.js
│ │ └── admin
│ │ │ ├── op-log.js
│ │ │ ├── error-log.js
│ │ │ ├── overview.js
│ │ │ ├── thing.js
│ │ │ ├── ad.js
│ │ │ ├── tag.js
│ │ │ ├── role.js
│ │ │ ├── banner.js
│ │ │ ├── notice.js
│ │ │ ├── comment.js
│ │ │ ├── login-log.js
│ │ │ ├── classification.js
│ │ │ ├── order.js
│ │ │ └── user.js
│ ├── utils
│ │ ├── global.js
│ │ ├── request.js
│ │ └── util.js
│ ├── App.vue
│ ├── core
│ │ └── bootstrap.js
│ ├── main.js
│ └── permission.js
├── .editorconfig
├── jsconfig.json
├── .gitignore
├── .postcssrc.js
├── index.html
├── .babelrc
├── .eslintrc.js
├── README.md
├── vue.config.js
└── package.json
├── server
├── myapp
│ ├── __init__.py
│ ├── auth
│ │ ├── __init__.py
│ │ ├── .DS_Store
│ │ └── authentication.py
│ ├── middlewares
│ │ ├── __init__.py
│ │ ├── .DS_Store
│ │ └── LogMiddleware.py
│ ├── permission
│ │ ├── __init__.py
│ │ ├── .DS_Store
│ │ └── permission.py
│ ├── tests.py
│ ├── .DS_Store
│ ├── views
│ │ ├── __init__.py
│ │ ├── .DS_Store
│ │ └── index
│ │ │ ├── __init__.py
│ │ │ ├── tag.py
│ │ │ ├── notice.py
│ │ │ ├── classification.py
│ │ │ ├── address.py
│ │ │ ├── order.py
│ │ │ └── comment.py
│ ├── apps.py
│ ├── admin.py
│ ├── handler.py
│ └── utils.py
├── 表结构.png
├── .DS_Store
├── server
│ ├── .DS_Store
│ ├── __init__.py
│ ├── asgi.py
│ ├── wsgi.py
│ └── urls.py
├── upload
│ ├── .DS_Store
│ ├── cover
│ │ ├── 1.jpg
│ │ ├── 2.jpg
│ │ ├── 3.jpg
│ │ ├── 4.jpg
│ │ ├── 5.jpg
│ │ ├── 6.jpg
│ │ ├── 7.jpg
│ │ ├── 8.jpg
│ │ ├── 9.jpg
│ │ ├── 1.jpeg
│ │ ├── 10.jpg
│ │ ├── 11.jpg
│ │ ├── 12.jpg
│ │ ├── 13.jpg
│ │ ├── 14.jpg
│ │ ├── 15.jpg
│ │ ├── 16.jpg
│ │ ├── 17.jpg
│ │ ├── 18.jpg
│ │ ├── 19.jpg
│ │ ├── 20.jpg
│ │ ├── 21.jpg
│ │ ├── 22.jpg
│ │ ├── 23.jpg
│ │ ├── 24.jpg
│ │ ├── 25.jpg
│ │ ├── 26.jpg
│ │ ├── 27.jpg
│ │ ├── 28.jpg
│ │ ├── 29.jpg
│ │ ├── 30.jpg
│ │ ├── 1676186872895.png
│ │ ├── 1676186935002.png
│ │ ├── 1676188277099.png
│ │ ├── 1676188355688.png
│ │ ├── 1676381084256.png
│ │ ├── 1676381091144.png
│ │ ├── 1676381097051.png
│ │ ├── 1676381103032.png
│ │ ├── 1676381110015.png
│ │ ├── 1679056528013.png
│ │ ├── 1672749055571.jpeg
│ │ ├── 1674044230851.jpeg
│ │ ├── 1676186518276.jpeg
│ │ ├── 1677500674281.jpeg
│ │ ├── 1677501266461.jpeg
│ │ ├── 1677501470234.jpeg
│ │ ├── 1677501544737.jpeg
│ │ ├── 1677505180730.jpeg
│ │ ├── 1677505298772.jpeg
│ │ ├── 1677505357042.jpeg
│ │ ├── 1677505364969.jpeg
│ │ ├── 1677505380921.jpeg
│ │ ├── 1677505393025.jpeg
│ │ ├── 1677505410960.jpeg
│ │ ├── 1677505421920.jpeg
│ │ ├── 1677505436478.jpeg
│ │ ├── 1677505452753.jpeg
│ │ ├── 1677505579480.jpeg
│ │ ├── 1677505616285.jpeg
│ │ ├── 1677505626565.jpeg
│ │ ├── 1677505637425.jpeg
│ │ ├── 1677505648826.jpeg
│ │ ├── 1677505659291.jpeg
│ │ ├── 1677505667178.jpeg
│ │ ├── 1677505685641.jpeg
│ │ ├── 1677505695894.jpeg
│ │ ├── 1677505706333.jpeg
│ │ ├── 1677505876732.jpeg
│ │ ├── 1677505884200.jpeg
│ │ ├── 1677505890616.jpeg
│ │ ├── 1677505897079.jpeg
│ │ ├── 1677505910282.jpeg
│ │ ├── 1677505919134.jpeg
│ │ ├── 1677505928898.jpeg
│ │ ├── 1677505937048.jpeg
│ │ ├── 1677505945207.jpeg
│ │ ├── 1677505953782.jpeg
│ │ ├── 1677588447622.jpeg
│ │ ├── 1677677497401.jpeg
│ │ ├── 1678529114670.jpeg
│ │ ├── 1679056479437.jpeg
│ │ ├── 1679056561868.jpeg
│ │ ├── 1679056587496.jpeg
│ │ ├── 1679058036014.jpeg
│ │ ├── 1679058043365.jpeg
│ │ ├── 1679229610791.jpeg
│ │ ├── 1679229780971.jpeg
│ │ ├── 1679229853940.jpeg
│ │ ├── 1679229963230.jpeg
│ │ ├── 1679230045590.jpeg
│ │ ├── 1679230092657.jpeg
│ │ ├── 1679230147996.jpeg
│ │ ├── 1679230364390.jpeg
│ │ ├── 1679230543572.jpeg
│ │ ├── 1679230586243.jpeg
│ │ ├── 1679230641879.jpeg
│ │ ├── 1679230894621.jpeg
│ │ ├── 1679230935716.jpeg
│ │ ├── 1679230989243.jpeg
│ │ ├── 1679231022326.jpeg
│ │ ├── 1679231052822.jpeg
│ │ ├── 1679231084420.jpeg
│ │ ├── 1679231113572.jpeg
│ │ ├── 1679231151929.jpeg
│ │ ├── 1679231184020.jpeg
│ │ ├── 1679231221940.jpeg
│ │ ├── 1679231465845.jpeg
│ │ ├── 1679232418133.jpeg
│ │ ├── 1679232448857.jpeg
│ │ ├── 1679232480948.jpeg
│ │ ├── 1679232514230.jpeg
│ │ ├── 1679232543082.jpeg
│ │ ├── 1679232587234.jpeg
│ │ ├── 1679232615578.jpeg
│ │ ├── 1679232650073.jpeg
│ │ ├── 1679232676818.jpeg
│ │ ├── 1679232717023.jpeg
│ │ ├── 1679232756075.jpeg
│ │ ├── 1679315151478.jpeg
│ │ ├── 1679315191893.jpeg
│ │ ├── 1679315240787.jpeg
│ │ ├── 1679315276060.jpeg
│ │ ├── 1679315310720.jpeg
│ │ ├── 1679315343720.jpeg
│ │ ├── 1679315365210.jpeg
│ │ ├── 1679315396953.jpeg
│ │ ├── 1679315437571.jpeg
│ │ ├── 1679315478327.jpeg
│ │ ├── 1679315749022.jpeg
│ │ ├── 1679315761797.jpeg
│ │ ├── 1679315803245.jpeg
│ │ ├── 1679315842977.jpeg
│ │ ├── 1679315883620.jpeg
│ │ ├── 1679315915467.jpeg
│ │ ├── 1679315954931.jpeg
│ │ ├── 1679315985852.jpeg
│ │ ├── 1679316037517.jpeg
│ │ ├── 1679316072493.jpeg
│ │ ├── 1679316422812.jpeg
│ │ ├── 1679316453474.jpeg
│ │ ├── 1679316484842.jpeg
│ │ ├── 1679316513693.jpeg
│ │ ├── 1679316533369.jpeg
│ │ ├── 1679316566135.jpeg
│ │ ├── 1679316605104.jpeg
│ │ ├── 1679316637185.jpeg
│ │ ├── 1679316666891.jpeg
│ │ ├── 1679316698087.jpeg
│ │ ├── 1679403034316.jpeg
│ │ ├── 1679403102225.jpeg
│ │ ├── 1679403138846.jpeg
│ │ ├── 1679403158073.jpeg
│ │ ├── 1679403193320.jpeg
│ │ ├── 1679403239138.jpeg
│ │ ├── 1679403285129.jpeg
│ │ ├── 1679403331202.jpeg
│ │ ├── 1679403370669.jpeg
│ │ ├── 1679403403756.jpeg
│ │ ├── 1679403503106.jpeg
│ │ ├── 1679403631942.jpeg
│ │ ├── 1679403697740.jpeg
│ │ ├── 1679403736341.jpeg
│ │ └── 1679488092121.jpeg
│ ├── img
│ │ ├── a.png
│ │ ├── b.png
│ │ ├── Wechat.jpeg
│ │ └── weixin.png
│ ├── ad
│ │ ├── 1674045266113.jpeg
│ │ ├── 1674045282581.jpeg
│ │ ├── 1674045308177.png
│ │ └── 1674045324510.jpeg
│ ├── avatar
│ │ ├── 1676553050529.png
│ │ ├── 1676553366217.png
│ │ ├── 1676553498600.jpeg
│ │ ├── 1676553815688.jpeg
│ │ ├── 1677240189427.png
│ │ ├── 1677982820781.jpeg
│ │ └── 1679146350134.jpeg
│ └── banner
│ │ ├── 1673963977440.jpeg
│ │ ├── 1673964384835.png
│ │ ├── 1673964652167.jpeg
│ │ ├── 1673965110189.jpeg
│ │ ├── 1673965198155.jpeg
│ │ ├── 1673965389141.jpeg
│ │ ├── 1673965574311.png
│ │ ├── 1673965709533.jpeg
│ │ ├── 1673965718720.png
│ │ └── 1673965728690.jpeg
├── requirements.txt
├── manage.py
└── readme.md
├── doc
└── python_shop.docx
├── 作者简介.md
├── .gitignore
└── Readme.md
/web/build/logo.png:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/static/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/myapp/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/myapp/auth/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/myapp/middlewares/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/myapp/permission/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/表结构.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/表结构.png
--------------------------------------------------------------------------------
/web/.eslintignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /config/
3 | /dist/
4 | /*.js
5 | /test/unit/coverage/
6 |
--------------------------------------------------------------------------------
/web/test/unit/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | },
4 | "globals": {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/server/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/.DS_Store
--------------------------------------------------------------------------------
/server/myapp/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/doc/python_shop.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/doc/python_shop.docx
--------------------------------------------------------------------------------
/server/myapp/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/myapp/.DS_Store
--------------------------------------------------------------------------------
/server/myapp/views/__init__.py:
--------------------------------------------------------------------------------
1 | from myapp.views.admin import *
2 | from myapp.views.index import *
3 |
--------------------------------------------------------------------------------
/web/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"'
4 | }
5 |
--------------------------------------------------------------------------------
/server/server/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/server/.DS_Store
--------------------------------------------------------------------------------
/server/upload/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/.DS_Store
--------------------------------------------------------------------------------
/server/upload/cover/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1.jpg
--------------------------------------------------------------------------------
/server/upload/cover/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/2.jpg
--------------------------------------------------------------------------------
/server/upload/cover/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/3.jpg
--------------------------------------------------------------------------------
/server/upload/cover/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/4.jpg
--------------------------------------------------------------------------------
/server/upload/cover/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/5.jpg
--------------------------------------------------------------------------------
/server/upload/cover/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/6.jpg
--------------------------------------------------------------------------------
/server/upload/cover/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/7.jpg
--------------------------------------------------------------------------------
/server/upload/cover/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/8.jpg
--------------------------------------------------------------------------------
/server/upload/cover/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/9.jpg
--------------------------------------------------------------------------------
/server/upload/img/a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/img/a.png
--------------------------------------------------------------------------------
/server/upload/img/b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/img/b.png
--------------------------------------------------------------------------------
/server/myapp/auth/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/myapp/auth/.DS_Store
--------------------------------------------------------------------------------
/server/upload/cover/1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/10.jpg
--------------------------------------------------------------------------------
/server/upload/cover/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/11.jpg
--------------------------------------------------------------------------------
/server/upload/cover/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/12.jpg
--------------------------------------------------------------------------------
/server/upload/cover/13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/13.jpg
--------------------------------------------------------------------------------
/server/upload/cover/14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/14.jpg
--------------------------------------------------------------------------------
/server/upload/cover/15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/15.jpg
--------------------------------------------------------------------------------
/server/upload/cover/16.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/16.jpg
--------------------------------------------------------------------------------
/server/upload/cover/17.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/17.jpg
--------------------------------------------------------------------------------
/server/upload/cover/18.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/18.jpg
--------------------------------------------------------------------------------
/server/upload/cover/19.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/19.jpg
--------------------------------------------------------------------------------
/server/upload/cover/20.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/20.jpg
--------------------------------------------------------------------------------
/server/upload/cover/21.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/21.jpg
--------------------------------------------------------------------------------
/server/upload/cover/22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/22.jpg
--------------------------------------------------------------------------------
/server/upload/cover/23.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/23.jpg
--------------------------------------------------------------------------------
/server/upload/cover/24.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/24.jpg
--------------------------------------------------------------------------------
/server/upload/cover/25.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/25.jpg
--------------------------------------------------------------------------------
/server/upload/cover/26.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/26.jpg
--------------------------------------------------------------------------------
/server/upload/cover/27.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/27.jpg
--------------------------------------------------------------------------------
/server/upload/cover/28.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/28.jpg
--------------------------------------------------------------------------------
/server/upload/cover/29.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/29.jpg
--------------------------------------------------------------------------------
/server/upload/cover/30.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/30.jpg
--------------------------------------------------------------------------------
/server/myapp/views/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/myapp/views/.DS_Store
--------------------------------------------------------------------------------
/server/upload/img/Wechat.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/img/Wechat.jpeg
--------------------------------------------------------------------------------
/server/upload/img/weixin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/img/weixin.png
--------------------------------------------------------------------------------
/web/src/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/web/src/assets/images/logo.png
--------------------------------------------------------------------------------
/web/src/assets/images/avatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/web/src/assets/images/avatar.jpg
--------------------------------------------------------------------------------
/web/src/assets/images/login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/web/src/assets/images/login.png
--------------------------------------------------------------------------------
/server/myapp/middlewares/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/myapp/middlewares/.DS_Store
--------------------------------------------------------------------------------
/server/myapp/permission/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/myapp/permission/.DS_Store
--------------------------------------------------------------------------------
/server/upload/ad/1674045266113.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/ad/1674045266113.jpeg
--------------------------------------------------------------------------------
/server/upload/ad/1674045282581.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/ad/1674045282581.jpeg
--------------------------------------------------------------------------------
/server/upload/ad/1674045308177.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/ad/1674045308177.png
--------------------------------------------------------------------------------
/server/upload/ad/1674045324510.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/ad/1674045324510.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1676186872895.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1676186872895.png
--------------------------------------------------------------------------------
/server/upload/cover/1676186935002.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1676186935002.png
--------------------------------------------------------------------------------
/server/upload/cover/1676188277099.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1676188277099.png
--------------------------------------------------------------------------------
/server/upload/cover/1676188355688.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1676188355688.png
--------------------------------------------------------------------------------
/server/upload/cover/1676381084256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1676381084256.png
--------------------------------------------------------------------------------
/server/upload/cover/1676381091144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1676381091144.png
--------------------------------------------------------------------------------
/server/upload/cover/1676381097051.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1676381097051.png
--------------------------------------------------------------------------------
/server/upload/cover/1676381103032.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1676381103032.png
--------------------------------------------------------------------------------
/server/upload/cover/1676381110015.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1676381110015.png
--------------------------------------------------------------------------------
/server/upload/cover/1679056528013.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679056528013.png
--------------------------------------------------------------------------------
/web/src/assets/images/front-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/web/src/assets/images/front-logo.png
--------------------------------------------------------------------------------
/web/src/style/index.less:
--------------------------------------------------------------------------------
1 | @import "~ant-design-vue/dist/antd.less";
2 | @import "scrollbar.less";
3 | @import "_var.less";
4 |
5 |
--------------------------------------------------------------------------------
/作者简介.md:
--------------------------------------------------------------------------------
1 | ### 源码地址
2 |
3 | https://github.com/geeeeeeeek/python_shop
4 |
5 | ### 联系方式
6 |
7 | - lengqin1024(微信)
8 | - 285126081(QQ)
--------------------------------------------------------------------------------
/server/server/__init__.py:
--------------------------------------------------------------------------------
1 | import pymysql
2 | pymysql.install_as_MySQLdb()
3 |
4 | print("===============install pymysql==============")
--------------------------------------------------------------------------------
/server/upload/avatar/1676553050529.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/avatar/1676553050529.png
--------------------------------------------------------------------------------
/server/upload/avatar/1676553366217.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/avatar/1676553366217.png
--------------------------------------------------------------------------------
/server/upload/avatar/1676553498600.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/avatar/1676553498600.jpeg
--------------------------------------------------------------------------------
/server/upload/avatar/1676553815688.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/avatar/1676553815688.jpeg
--------------------------------------------------------------------------------
/server/upload/avatar/1677240189427.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/avatar/1677240189427.png
--------------------------------------------------------------------------------
/server/upload/avatar/1677982820781.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/avatar/1677982820781.jpeg
--------------------------------------------------------------------------------
/server/upload/avatar/1679146350134.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/avatar/1679146350134.jpeg
--------------------------------------------------------------------------------
/server/upload/banner/1673963977440.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/banner/1673963977440.jpeg
--------------------------------------------------------------------------------
/server/upload/banner/1673964384835.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/banner/1673964384835.png
--------------------------------------------------------------------------------
/server/upload/banner/1673964652167.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/banner/1673964652167.jpeg
--------------------------------------------------------------------------------
/server/upload/banner/1673965110189.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/banner/1673965110189.jpeg
--------------------------------------------------------------------------------
/server/upload/banner/1673965198155.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/banner/1673965198155.jpeg
--------------------------------------------------------------------------------
/server/upload/banner/1673965389141.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/banner/1673965389141.jpeg
--------------------------------------------------------------------------------
/server/upload/banner/1673965574311.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/banner/1673965574311.png
--------------------------------------------------------------------------------
/server/upload/banner/1673965709533.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/banner/1673965709533.jpeg
--------------------------------------------------------------------------------
/server/upload/banner/1673965718720.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/banner/1673965718720.png
--------------------------------------------------------------------------------
/server/upload/banner/1673965728690.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/banner/1673965728690.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1672749055571.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1672749055571.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1674044230851.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1674044230851.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1676186518276.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1676186518276.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677500674281.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677500674281.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677501266461.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677501266461.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677501470234.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677501470234.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677501544737.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677501544737.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505180730.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505180730.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505298772.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505298772.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505357042.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505357042.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505364969.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505364969.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505380921.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505380921.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505393025.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505393025.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505410960.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505410960.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505421920.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505421920.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505436478.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505436478.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505452753.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505452753.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505579480.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505579480.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505616285.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505616285.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505626565.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505626565.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505637425.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505637425.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505648826.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505648826.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505659291.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505659291.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505667178.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505667178.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505685641.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505685641.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505695894.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505695894.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505706333.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505706333.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505876732.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505876732.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505884200.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505884200.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505890616.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505890616.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505897079.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505897079.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505910282.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505910282.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505919134.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505919134.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505928898.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505928898.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505937048.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505937048.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505945207.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505945207.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677505953782.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677505953782.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677588447622.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677588447622.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1677677497401.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1677677497401.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1678529114670.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1678529114670.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679056479437.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679056479437.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679056561868.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679056561868.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679056587496.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679056587496.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679058036014.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679058036014.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679058043365.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679058043365.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679229610791.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679229610791.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679229780971.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679229780971.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679229853940.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679229853940.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679229963230.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679229963230.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679230045590.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679230045590.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679230092657.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679230092657.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679230147996.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679230147996.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679230364390.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679230364390.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679230543572.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679230543572.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679230586243.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679230586243.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679230641879.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679230641879.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679230894621.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679230894621.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679230935716.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679230935716.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679230989243.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679230989243.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679231022326.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679231022326.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679231052822.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679231052822.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679231084420.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679231084420.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679231113572.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679231113572.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679231151929.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679231151929.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679231184020.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679231184020.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679231221940.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679231221940.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679231465845.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679231465845.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232418133.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232418133.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232448857.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232448857.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232480948.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232480948.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232514230.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232514230.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232543082.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232543082.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232587234.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232587234.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232615578.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232615578.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232650073.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232650073.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232676818.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232676818.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232717023.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232717023.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679232756075.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679232756075.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315151478.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315151478.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315191893.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315191893.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315240787.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315240787.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315276060.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315276060.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315310720.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315310720.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315343720.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315343720.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315365210.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315365210.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315396953.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315396953.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315437571.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315437571.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315478327.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315478327.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315749022.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315749022.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315761797.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315761797.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315803245.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315803245.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315842977.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315842977.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315883620.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315883620.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315915467.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315915467.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315954931.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315954931.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679315985852.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679315985852.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316037517.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316037517.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316072493.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316072493.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316422812.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316422812.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316453474.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316453474.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316484842.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316484842.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316513693.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316513693.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316533369.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316533369.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316566135.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316566135.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316605104.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316605104.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316637185.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316637185.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316666891.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316666891.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679316698087.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679316698087.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403034316.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403034316.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403102225.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403102225.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403138846.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403138846.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403158073.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403158073.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403193320.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403193320.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403239138.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403239138.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403285129.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403285129.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403331202.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403331202.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403370669.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403370669.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403403756.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403403756.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403503106.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403503106.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403631942.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403631942.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403697740.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403697740.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679403736341.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679403736341.jpeg
--------------------------------------------------------------------------------
/server/upload/cover/1679488092121.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geeeeeeeek/python_shop/HEAD/server/upload/cover/1679488092121.jpeg
--------------------------------------------------------------------------------
/web/src/views/index/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
--------------------------------------------------------------------------------
/server/requirements.txt:
--------------------------------------------------------------------------------
1 | Django==3.2.11
2 | PyMySQL==1.0.2
3 | djangorestframework==3.14.0
4 | django-cors-headers==3.13.0
5 | Pillow==9.1.1
6 | psutil==5.9.4
--------------------------------------------------------------------------------
/server/myapp/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class MyappConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'myapp'
7 |
--------------------------------------------------------------------------------
/web/config/test.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const devEnv = require('./dev.env')
4 |
5 | module.exports = merge(devEnv, {
6 | NODE_ENV: '"testing"'
7 | })
8 |
--------------------------------------------------------------------------------
/web/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"'
7 | })
8 |
--------------------------------------------------------------------------------
/web/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
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 |
--------------------------------------------------------------------------------
/web/src/style/_var.less:
--------------------------------------------------------------------------------
1 | @import url('~ant-design-vue/es/style/themes/default.less');
2 | //@primary-color: #00C2CE;
3 | //@success-color: #0EC885;
4 | //@error-color: #EF5615;
5 | //@warning-color: #F1a716;
6 |
--------------------------------------------------------------------------------
/web/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "baseUrl": ".",
5 | "paths": {
6 | "@/*": ["src/*"]
7 | }
8 | },
9 | "exclude": ["node_modules", "dist"],
10 | "include": ["src/**/*"]
11 | }
12 |
--------------------------------------------------------------------------------
/web/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | /dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | /test/unit/coverage/
8 |
9 | # Editor directories and files
10 | .idea
11 | .vscode
12 | *.suo
13 | *.ntvs*
14 | *.njsproj
15 | *.sln
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /server/myapp/migrations
2 | /server/myapp/views/__pycache__/
3 | /server/.idea
4 | /web/.idea
5 | /web/dist
6 | /web/node_modules
7 | /server/.idea/
8 | /.idea/
9 | __pycache__
10 | .idea
11 | server/.idea
12 | .DS_Store
13 | server/.DS_Store
14 | web/.DS_Store
--------------------------------------------------------------------------------
/web/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | "postcss-import": {},
6 | "postcss-url": {},
7 | // to edit target browsers: use "browserslist" field in package.json
8 | "autoprefixer": {}
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/server/myapp/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 | from myapp.models import Classification, Thing, Tag, User, Comment
5 |
6 | admin.site.register(Classification)
7 | admin.site.register(Tag)
8 | admin.site.register(Thing)
9 | admin.site.register(User)
10 | admin.site.register(Comment)
11 |
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | web app
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/web/src/store/constants.js:
--------------------------------------------------------------------------------
1 | export const TOKEN = 'Token'
2 | export const USERNAME = 'UserName'
3 | export const USERID = 'UserId'
4 |
5 | export const ADMIN_TOKEN = 'Admin-Token'
6 | export const ADMIN_USERNAME = 'Admin-UserName'
7 |
8 | export const BASE_URL = 'http://127.0.0.1:8000'
9 | // export const BASE_URL = 'http://1.117.171.66:9003'
10 |
--------------------------------------------------------------------------------
/web/src/api/index/tag.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/index/tag/list'
8 | }
9 |
10 | /**
11 | * 列表
12 | */
13 | export const listApi = function (data) {
14 | return axios({
15 | url: api.listApi,
16 | method: 'get',
17 | params: data
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/web/src/api/admin/op-log.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/opLog/list',
8 | }
9 |
10 | /**
11 | * 列表
12 | */
13 | export const listApi = function (data) {
14 | return axios({
15 | url: api.listApi,
16 | method: 'get',
17 | params: data
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/web/src/api/admin/error-log.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/errorLog/list'
8 | }
9 |
10 | /**
11 | * 列表
12 | */
13 | export const listApi = function (data) {
14 | return axios({
15 | url: api.listApi,
16 | method: 'get',
17 | params: data
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/web/src/api/index/notice.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/index/notice/list_api',
8 | }
9 |
10 | /**
11 | * 列表
12 | */
13 | export const listApi = function (data) {
14 | return axios({
15 | url: api.listApi,
16 | method: 'get',
17 | params: data
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/server/myapp/views/index/__init__.py:
--------------------------------------------------------------------------------
1 | from myapp.views.index.classification import *
2 | from myapp.views.index.tag import *
3 | from myapp.views.index.user import *
4 | from myapp.views.index.thing import *
5 | from myapp.views.index.comment import *
6 | from myapp.views.index.order import *
7 | from myapp.views.index.notice import *
8 | from myapp.views.index.address import *
9 |
--------------------------------------------------------------------------------
/web/src/api/index/classification.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/index/classification/list',
8 | }
9 |
10 | /**
11 | * 列表
12 | */
13 | export const listApi = function (data) {
14 | return axios({
15 | url: api.listApi,
16 | method: 'get',
17 | params: data
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/web/src/utils/global.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import {BASE_URL} from '@/store/constants'
3 | switch (process.env.NODE_ENV) {
4 | case 'development':
5 | Vue.prototype.$BASE_URL = BASE_URL
6 | break
7 | case 'production':
8 | Vue.prototype.$BASE_URL = BASE_URL
9 | break
10 | default:
11 | Vue.prototype.$BASE_URL = BASE_URL
12 | break
13 | }
14 |
--------------------------------------------------------------------------------
/web/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7 | }
8 | }],
9 | "stage-2"
10 | ],
11 | "plugins": ["transform-vue-jsx", "transform-runtime"],
12 | "env": {
13 | "test": {
14 | "presets": ["env", "stage-2"]
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/web/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | // import {listApi} from '@/api/admin'
4 |
5 | import user from './modules/user'
6 |
7 | Vue.use(Vuex)
8 |
9 | export default new Vuex.Store({
10 | state: {}, // 存放数据
11 | getters: {}, // 计算属性
12 | mutations: {}, // 修改state中数据的一些方法
13 | actions: {}, // 异步方法
14 | modules: {
15 | user
16 | }
17 | })
18 |
--------------------------------------------------------------------------------
/web/test/unit/specs/HelloWorld.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import HelloWorld from '@/components/HelloWorld'
3 |
4 | describe('HelloWorld.vue', () => {
5 | it('should render correct contents', () => {
6 | const Constructor = Vue.extend(HelloWorld)
7 | const vm = new Constructor().$mount()
8 | expect(vm.$el.querySelector('.hello h1').textContent)
9 |
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/server/myapp/permission/permission.py:
--------------------------------------------------------------------------------
1 | from myapp.models import User
2 |
3 |
4 | def isDemoAdminUser(request):
5 | adminToken = request.META.get("HTTP_ADMINTOKEN")
6 | users = User.objects.filter(admin_token=adminToken)
7 | if len(users) > 0:
8 | user = users[0]
9 | if user.role == '3': # (角色3)表示演示帐号
10 | print('演示帐号===>')
11 | return True
12 | return False
13 |
--------------------------------------------------------------------------------
/server/server/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for server project.
3 |
4 | It exposes the ASGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.asgi import get_asgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings')
15 |
16 | application = get_asgi_application()
17 |
--------------------------------------------------------------------------------
/server/server/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for server project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings')
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/server/myapp/views/index/tag.py:
--------------------------------------------------------------------------------
1 | # Create your views here.
2 | from rest_framework.decorators import api_view
3 |
4 | from myapp.handler import APIResponse
5 | from myapp.models import Tag
6 | from myapp.serializers import TagSerializer
7 |
8 |
9 | @api_view(['GET'])
10 | def list_api(request):
11 | if request.method == 'GET':
12 | tags = Tag.objects.all().order_by('-create_time')
13 | serializer = TagSerializer(tags, many=True)
14 | return APIResponse(code=0, msg='查询成功', data=serializer.data)
15 |
16 |
--------------------------------------------------------------------------------
/web/src/assets/images/tel-icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/server/myapp/views/index/notice.py:
--------------------------------------------------------------------------------
1 | # Create your views here.
2 | from rest_framework.decorators import api_view
3 |
4 | from myapp.handler import APIResponse
5 | from myapp.models import Notice
6 | from myapp.serializers import NoticeSerializer
7 |
8 |
9 | @api_view(['GET'])
10 | def list_api(request):
11 | if request.method == 'GET':
12 | notices = Notice.objects.all().order_by('-create_time')
13 | serializer = NoticeSerializer(notices, many=True)
14 | return APIResponse(code=0, msg='查询成功', data=serializer.data)
15 |
16 |
--------------------------------------------------------------------------------
/web/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
21 |
22 |
30 |
--------------------------------------------------------------------------------
/web/src/assets/images/address-right-icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/src/style/scrollbar.less:
--------------------------------------------------------------------------------
1 | //@scroll-bar-size: 6px;
2 |
3 | //// 定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸
4 | //::-webkit-scrollbar {
5 | // width: @scroll-bar-size;
6 | // height: @scroll-bar-size;
7 | // background-color: transparent;
8 | //}
9 | //
10 | //// 定义滚动条轨道 内阴影+圆角
11 | //::-webkit-scrollbar-track {
12 | // border-radius:@scroll-bar-size / 2;
13 | // background-color: transparent;
14 | //}
15 | //
16 | //// 定义滑块 内阴影+圆角
17 | //::-webkit-scrollbar-thumb {
18 | // border-radius: @scroll-bar-size / 2;
19 | // background-color: rgba(0, 0, 0, .3)
20 | //}
21 |
--------------------------------------------------------------------------------
/server/myapp/handler.py:
--------------------------------------------------------------------------------
1 | from rest_framework.response import Response
2 |
3 |
4 | class APIResponse(Response):
5 | def __init__(self, code=0, msg='', data=None, status=200, headers=None, content_type=None, **kwargs):
6 | dic = {'code': code, 'msg': msg}
7 | if data is not None:
8 | dic['data'] = data
9 |
10 | dic.update(kwargs) # 这里使用update
11 | super().__init__(data=dic, status=status,
12 | template_name=None, headers=headers,
13 | exception=False, content_type=content_type)
14 |
--------------------------------------------------------------------------------
/web/src/views/index/portal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
25 |
28 |
--------------------------------------------------------------------------------
/web/src/api/admin/overview.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/overview/count',
8 | sysInfoApi: '/myapp/admin/overview/sysInfo'
9 | }
10 |
11 | /**
12 | * @des 列表
13 | */
14 | export const listApi = function (params) {
15 | return axios({
16 | url: api.listApi,
17 | method: 'get',
18 | params: params
19 | })
20 | }
21 |
22 | /**
23 | * @des 系统信息
24 | */
25 | export const sysInfoApi = function (params) {
26 | return axios({
27 | url: api.sysInfoApi,
28 | method: 'get',
29 | params: params
30 | })
31 | }
32 |
--------------------------------------------------------------------------------
/web/src/assets/images/search-icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/src/assets/images/searchIcon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/src/core/bootstrap.js:
--------------------------------------------------------------------------------
1 | import store from '@/store'
2 | import storage from 'store'
3 | import {
4 | ADMIN_TOKEN, ADMIN_USERNAME, TOKEN, USERID, USERNAME
5 | } from '@/store/constants'
6 |
7 | export default function Initializer () {
8 | // storage.remove('Show-header')
9 | store.commit('SET_ADMIN_TOKEN', storage.get(ADMIN_TOKEN))
10 | store.commit('SET_ADMIN_USERNAME', storage.get(ADMIN_USERNAME))
11 |
12 | store.commit('SET_TOKEN', storage.get(TOKEN))
13 | store.commit('SET_USERNAME', storage.get(USERNAME))
14 | store.commit('SET_USERID', storage.get(USERID))
15 |
16 | // store.dispatch('setLang', storage.get(APP_LANGUAGE, 'zh-CN'))
17 | }
18 |
--------------------------------------------------------------------------------
/web/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 | const sourceMapEnabled = isProduction
6 | ? config.build.productionSourceMap
7 | : config.dev.cssSourceMap
8 |
9 | module.exports = {
10 | loaders: utils.cssLoaders({
11 | sourceMap: sourceMapEnabled,
12 | extract: isProduction
13 | }),
14 | cssSourceMap: sourceMapEnabled,
15 | cacheBusting: config.dev.cacheBusting,
16 | transformToRequire: {
17 | video: ['src', 'poster'],
18 | source: 'src',
19 | img: 'src',
20 | image: 'xlink:href'
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/web/src/assets/images/add.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/web/src/assets/images/order-point-icon.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/web/src/assets/images/pwd-icon.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/web/src/assets/images/setting-msg-icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/src/views/index/search.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
28 |
35 |
--------------------------------------------------------------------------------
/web/src/assets/images/register-name.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/server/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Django's command-line utility for administrative tasks."""
3 | import os
4 | import sys
5 |
6 |
7 | def main():
8 | """Run administrative tasks."""
9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings')
10 | try:
11 | from django.core.management import execute_from_command_line
12 | except ImportError as exc:
13 | raise ImportError(
14 | "Couldn't import Django. Are you sure it's installed and "
15 | "available on your PYTHONPATH environment variable? Did you "
16 | "forget to activate a virtual environment?"
17 | ) from exc
18 | execute_from_command_line(sys.argv)
19 |
20 |
21 | if __name__ == '__main__':
22 | main()
23 |
--------------------------------------------------------------------------------
/web/src/assets/images/clear-search.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/web/src/assets/images/mail-icon.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/web/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import store from './store/'
5 | import App from './App'
6 | import router from './router'
7 | import Antd from 'ant-design-vue'
8 | import 'ant-design-vue/dist/antd.less'
9 | import '@/utils/global.js'
10 | import bootstrap from './core/bootstrap'
11 | import Dialog from '@/components/Dialog'
12 | import './permission'
13 | import './style/index.less' // 全局样式
14 | import moment from 'moment'
15 | import 'moment/locale/zh-cn'
16 | moment.locale('zh-cn')
17 | Vue.prototype.$moment = moment
18 |
19 | Vue.config.productionTip = true
20 | Vue.use(Antd)
21 | Vue.use(Dialog)
22 |
23 | new Vue({
24 | router,
25 | store,
26 | created: bootstrap,
27 | render: h => h(App)
28 | }).$mount('#app')
29 |
--------------------------------------------------------------------------------
/web/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parserOptions: {
6 | parser: 'babel-eslint'
7 | },
8 | env: {
9 | browser: true,
10 | },
11 | extends: [
12 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
13 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
14 | 'plugin:vue/essential',
15 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
16 | 'standard'
17 | ],
18 | // required to lint *.vue files
19 | plugins: [
20 | 'vue'
21 | ],
22 | // add your custom rules here
23 | rules: {
24 | // allow async-await
25 | 'generator-star-spacing': 'off',
26 | // allow debugger during development
27 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/server/server/urls.py:
--------------------------------------------------------------------------------
1 | """server URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/4.1/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: path('', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.urls import include, path
14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 | """
16 | from django.conf.urls.static import static
17 | from django.contrib import admin
18 | from django.urls import path, include
19 |
20 | from server import settings
21 |
22 | urlpatterns = [
23 | path('admin/', admin.site.urls),
24 | path('myapp/', include('myapp.urls')),
25 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
26 |
--------------------------------------------------------------------------------
/web/src/assets/images/order-address-icon.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/web/README.md:
--------------------------------------------------------------------------------
1 | # 说明文档
2 |
3 | > web前端代码,前端风格借鉴了豆瓣、图灵、亚马逊、ant等多种网站风格。 学习过程中,遇到问题可以咨询作者:lengqin1024(微信)
4 |
5 |
6 |
7 | ### 部署步骤
8 |
9 | 1. 安装node,本人用的是15.14.0
10 |
11 | 2. 安装依赖
12 | ```
13 | npm install
14 | ```
15 | 3. 修改配置
16 | 修改constants.js文件,将BASE_URL改为你自己的后端接口地址
17 |
18 | 4. 打包
19 | ```
20 | npm run build
21 | ```
22 |
23 | 打包后,修改index.html里面的title成你自己的网站名称,然后将dist文件夹放到nginx服务器配置目录中
24 |
25 | 5. 安装nginx,并修改nginx.conf
26 | ```
27 | server {
28 | listen 8001;
29 | server_name localhost;
30 |
31 | location / {
32 | root E:\dist;
33 | index index.html index.htm;
34 | }
35 | }
36 |
37 | ```
38 | 5. 访问你的域名即可
39 |
40 | ### 联系作者
41 |
42 | 微信:lengqin1024
43 |
44 |
45 |
46 |
47 | ## 参考链接
48 |
49 | - https://blog.csdn.net/C_ZhangSir/article/details/100989902
50 | - https://blog.csdn.net/weixin_45748897/article/details/103701003
51 | - https://blog.csdn.net/itzhongzi/article/details/73330681
52 | - https://www.jianshu.com/p/ef348d1c8f2b
53 | - https://juejin.cn/post/7013325675129995272
54 | - http://idea.94goo.com/key
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/web/src/assets/images/message-icon.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/web/src/assets/images/delete-icon.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/web/src/assets/images/ebook-download-icon.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/web/src/assets/images/code-icon.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/web/src/assets/images/read-online-icon.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/web/src/assets/images/share-icon.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/web/src/api/index/address.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/index/address/list',
8 | createApi: '/myapp/index/address/create',
9 | deleteApi: '/myapp/index/address/delete',
10 | updateApi: '/myapp/index/address/update'
11 | }
12 |
13 | export const listApi = function (data) {
14 | return axios({
15 | url: api.listApi,
16 | method: 'get',
17 | params: data
18 | })
19 | }
20 |
21 | export const createApi = function (data) {
22 | return axios({
23 | url: api.createApi,
24 | method: 'post',
25 | headers: {
26 | 'Content-Type': 'multipart/form-data;charset=utf-8'
27 | },
28 | data: data
29 | })
30 | }
31 |
32 | export const deleteApi = function (data) {
33 | return axios({
34 | url: api.deleteApi,
35 | method: 'post',
36 | params: data
37 | })
38 | }
39 |
40 | export const updateApi = function (params,data) {
41 | return axios({
42 | url: api.updateApi,
43 | method: 'post',
44 | headers: {
45 | 'Content-Type': 'multipart/form-data;charset=utf-8'
46 | },
47 | params: params,
48 | data: data
49 | })
50 | }
51 |
--------------------------------------------------------------------------------
/web/src/assets/images/ali-pay-icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/src/views/index/user.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
37 |
59 |
--------------------------------------------------------------------------------
/web/src/assets/images/wx-pay-icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/src/assets/images/order-thing-icon.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/web/src/api/admin/thing.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/thing/list',
8 | createApi: '/myapp/admin/thing/create',
9 | deleteApi: '/myapp/admin/thing/delete',
10 | updateApi: '/myapp/admin/thing/update'
11 | }
12 |
13 | /**
14 | * 列表
15 | */
16 | export const listApi = function (data) {
17 | return axios({
18 | url: api.listApi,
19 | method: 'get',
20 | params: data
21 | })
22 | }
23 |
24 | /**
25 | * 新建
26 | */
27 | export const createApi = function (data) {
28 | return axios({
29 | url: api.createApi,
30 | method: 'post',
31 | headers: {
32 | 'Content-Type': 'application/form-data'
33 | },
34 | data: data
35 | })
36 | }
37 |
38 | /**
39 | * 删除
40 | */
41 | export const deleteApi = function (params) {
42 | return axios({
43 | url: api.deleteApi,
44 | method: 'post',
45 | params: params
46 | })
47 | }
48 | /**
49 | * 更新
50 | */
51 | export const updateApi = function (params, data) {
52 | return axios({
53 | url: api.updateApi,
54 | method: 'post',
55 | headers: {
56 | 'Content-Type': 'application/form-data'
57 | },
58 | params: params,
59 | data: data
60 | })
61 | }
62 |
--------------------------------------------------------------------------------
/web/src/api/admin/ad.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/ad/list',
8 | createApi: '/myapp/admin/ad/create',
9 | deleteApi: '/myapp/admin/ad/delete',
10 | updateApi: '/myapp/admin/ad/update'
11 | }
12 |
13 | /**
14 | * 列表
15 | */
16 | export const listApi = function (data) {
17 | return axios({
18 | url: api.listApi,
19 | method: 'get',
20 | params: data
21 | })
22 | }
23 |
24 | /**
25 | * 新建
26 | */
27 | export const createApi = function (data) {
28 | return axios({
29 | url: api.createApi,
30 | method: 'post',
31 | headers: {
32 | 'Content-Type': 'multipart/form-data;charset=utf-8'
33 | },
34 | data: data
35 | })
36 | }
37 |
38 | /**
39 | * 删除
40 | */
41 | export const deleteApi = function (params) {
42 | return axios({
43 | url: api.deleteApi,
44 | method: 'post',
45 | params: params
46 | })
47 | }
48 | /**
49 | * 更新
50 | */
51 | export const updateApi = function (params, data) {
52 | return axios({
53 | url: api.updateApi,
54 | method: 'post',
55 | headers: {
56 | 'Content-Type': 'multipart/form-data;charset=utf-8'
57 | },
58 | params: params,
59 | data: data
60 | })
61 | }
62 |
--------------------------------------------------------------------------------
/web/src/api/admin/tag.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/tag/list',
8 | createApi: '/myapp/admin/tag/create',
9 | deleteApi: '/myapp/admin/tag/delete',
10 | updateApi: '/myapp/admin/tag/update'
11 | }
12 |
13 | /**
14 | * 列表
15 | */
16 | export const listApi = function (data) {
17 | return axios({
18 | url: api.listApi,
19 | method: 'get',
20 | params: data
21 | })
22 | }
23 |
24 | /**
25 | * 新建
26 | */
27 | export const createApi = function (data) {
28 | return axios({
29 | url: api.createApi,
30 | method: 'post',
31 | headers: {
32 | 'Content-Type': 'multipart/form-data;charset=utf-8'
33 | },
34 | data: data
35 | })
36 | }
37 |
38 | /**
39 | * 删除
40 | */
41 | export const deleteApi = function (params) {
42 | return axios({
43 | url: api.deleteApi,
44 | method: 'post',
45 | params: params
46 | })
47 | }
48 | /**
49 | * 更新
50 | */
51 | export const updateApi = function (params, data) {
52 | return axios({
53 | url: api.updateApi,
54 | method: 'post',
55 | headers: {
56 | 'Content-Type': 'multipart/form-data;charset=utf-8'
57 | },
58 | params: params,
59 | data: data
60 | })
61 | }
62 |
--------------------------------------------------------------------------------
/web/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const buildDate = JSON.stringify(new Date().toLocaleString())
4 |
5 | function resolve (dir) {
6 | return path.join(__dirname, dir)
7 | }
8 |
9 | const isProd = process.env.NODE_ENV === 'production'
10 |
11 | const assetsCDN = {
12 | }
13 |
14 | // vue.config.js
15 | const vueConfig = {
16 | runtimeCompiler: true,
17 | publicPath: './',
18 | configureWebpack: {
19 | // webpack plugins
20 | plugins: [
21 | ],
22 | // if prod, add externals
23 | externals: isProd ? assetsCDN.externals : {}
24 | },
25 |
26 | chainWebpack: config => {
27 | config.resolve.alias.set('@$', resolve('src'))
28 | },
29 |
30 |
31 | css: {
32 | loaderOptions: {
33 | less: {
34 | modifyVars: {
35 | // less vars,customize ant design theme
36 | // 'primary-color': '#F5222D',
37 | },
38 | // DO NOT REMOVE THIS LINE
39 | javascriptEnabled: true
40 | }
41 | }
42 | },
43 |
44 | // disable source map in production
45 | productionSourceMap: false,
46 | lintOnSave: undefined,
47 | // babel-loader no-ignore node_modules/*
48 | transpileDependencies: []
49 | }
50 |
51 | module.exports = vueConfig
52 |
--------------------------------------------------------------------------------
/web/src/api/admin/role.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/role/list',
8 | createApi: '/myapp/admin/role/create',
9 | deleteApi: '/myapp/admin/role/delete',
10 | updateApi: '/myapp/admin/role/update'
11 | }
12 |
13 | /**
14 | * 列表
15 | */
16 | export const listApi = function (data) {
17 | return axios({
18 | url: api.listApi,
19 | method: 'get',
20 | params: data
21 | })
22 | }
23 |
24 | /**
25 | * 新建
26 | */
27 | export const createApi = function (data) {
28 | return axios({
29 | url: api.createApi,
30 | method: 'post',
31 | headers: {
32 | 'Content-Type': 'multipart/form-data;charset=utf-8'
33 | },
34 | data: data
35 | })
36 | }
37 |
38 | /**
39 | * 删除
40 | */
41 | export const deleteApi = function (params) {
42 | return axios({
43 | url: api.deleteApi,
44 | method: 'post',
45 | params: params
46 | })
47 | }
48 | /**
49 | * 更新
50 | */
51 | export const updateApi = function (params, data) {
52 | return axios({
53 | url: api.updateApi,
54 | method: 'post',
55 | headers: {
56 | 'Content-Type': 'multipart/form-data;charset=utf-8'
57 | },
58 | params: params,
59 | data: data
60 | })
61 | }
62 |
--------------------------------------------------------------------------------
/web/src/api/admin/banner.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/banner/list',
8 | createApi: '/myapp/admin/banner/create',
9 | deleteApi: '/myapp/admin/banner/delete',
10 | updateApi: '/myapp/admin/banner/update'
11 | }
12 |
13 | /**
14 | * 列表
15 | */
16 | export const listApi = function (data) {
17 | return axios({
18 | url: api.listApi,
19 | method: 'get',
20 | params: data
21 | })
22 | }
23 |
24 | /**
25 | * 新建
26 | */
27 | export const createApi = function (data) {
28 | return axios({
29 | url: api.createApi,
30 | method: 'post',
31 | headers: {
32 | 'Content-Type': 'multipart/form-data;charset=utf-8'
33 | },
34 | data: data
35 | })
36 | }
37 |
38 | /**
39 | * 删除
40 | */
41 | export const deleteApi = function (params) {
42 | return axios({
43 | url: api.deleteApi,
44 | method: 'post',
45 | params: params
46 | })
47 | }
48 | /**
49 | * 更新
50 | */
51 | export const updateApi = function (params, data) {
52 | return axios({
53 | url: api.updateApi,
54 | method: 'post',
55 | headers: {
56 | 'Content-Type': 'multipart/form-data;charset=utf-8'
57 | },
58 | params: params,
59 | data: data
60 | })
61 | }
62 |
--------------------------------------------------------------------------------
/web/src/api/admin/notice.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/notice/list',
8 | createApi: '/myapp/admin/notice/create',
9 | deleteApi: '/myapp/admin/notice/delete',
10 | updateApi: '/myapp/admin/notice/update'
11 | }
12 |
13 | /**
14 | * 列表
15 | */
16 | export const listApi = function (data) {
17 | return axios({
18 | url: api.listApi,
19 | method: 'get',
20 | params: data
21 | })
22 | }
23 |
24 | /**
25 | * 新建
26 | */
27 | export const createApi = function (data) {
28 | return axios({
29 | url: api.createApi,
30 | method: 'post',
31 | headers: {
32 | 'Content-Type': 'multipart/form-data;charset=utf-8'
33 | },
34 | data: data
35 | })
36 | }
37 |
38 | /**
39 | * 删除
40 | */
41 | export const deleteApi = function (params) {
42 | return axios({
43 | url: api.deleteApi,
44 | method: 'post',
45 | params: params
46 | })
47 | }
48 | /**
49 | * 更新
50 | */
51 | export const updateApi = function (params, data) {
52 | return axios({
53 | url: api.updateApi,
54 | method: 'post',
55 | headers: {
56 | 'Content-Type': 'multipart/form-data;charset=utf-8'
57 | },
58 | params: params,
59 | data: data
60 | })
61 | }
62 |
--------------------------------------------------------------------------------
/web/src/api/admin/comment.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/comment/list',
8 | createApi: '/myapp/admin/comment/create',
9 | deleteApi: '/myapp/admin/comment/delete',
10 | updateApi: '/myapp/admin/comment/update'
11 | }
12 |
13 | /**
14 | * 列表
15 | */
16 | export const listApi = function (data) {
17 | return axios({
18 | url: api.listApi,
19 | method: 'get',
20 | params: data
21 | })
22 | }
23 |
24 | /**
25 | * 新建
26 | */
27 | export const createApi = function (data) {
28 | return axios({
29 | url: api.createApi,
30 | method: 'post',
31 | headers: {
32 | 'Content-Type': 'multipart/form-data;charset=utf-8'
33 | },
34 | data: data
35 | })
36 | }
37 |
38 | /**
39 | * 删除
40 | */
41 | export const deleteApi = function (params) {
42 | return axios({
43 | url: api.deleteApi,
44 | method: 'post',
45 | params: params
46 | })
47 | }
48 | /**
49 | * 更新
50 | */
51 | export const updateApi = function (params, data) {
52 | return axios({
53 | url: api.updateApi,
54 | method: 'post',
55 | headers: {
56 | 'Content-Type': 'multipart/form-data;charset=utf-8'
57 | },
58 | params: params,
59 | data: data
60 | })
61 | }
62 |
--------------------------------------------------------------------------------
/web/src/api/admin/login-log.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/loginLog/list',
8 | createApi: '/myapp/admin/loginLog/create',
9 | deleteApi: '/myapp/admin/loginLog/delete',
10 | updateApi: '/myapp/admin/loginLog/update'
11 | }
12 |
13 | /**
14 | * 列表
15 | */
16 | export const listApi = function (data) {
17 | return axios({
18 | url: api.listApi,
19 | method: 'get',
20 | params: data
21 | })
22 | }
23 |
24 | /**
25 | * 新建
26 | */
27 | export const createApi = function (data) {
28 | return axios({
29 | url: api.createApi,
30 | method: 'post',
31 | headers: {
32 | 'Content-Type': 'multipart/form-data;charset=utf-8'
33 | },
34 | data: data
35 | })
36 | }
37 |
38 | /**
39 | * 删除
40 | */
41 | export const deleteApi = function (params) {
42 | return axios({
43 | url: api.deleteApi,
44 | method: 'post',
45 | params: params
46 | })
47 | }
48 | /**
49 | * 更新
50 | */
51 | export const updateApi = function (params, data) {
52 | return axios({
53 | url: api.updateApi,
54 | method: 'post',
55 | headers: {
56 | 'Content-Type': 'multipart/form-data;charset=utf-8'
57 | },
58 | params: params,
59 | data: data
60 | })
61 | }
62 |
--------------------------------------------------------------------------------
/web/src/api/admin/classification.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/classification/list',
8 | createApi: '/myapp/admin/classification/create',
9 | deleteApi: '/myapp/admin/classification/delete',
10 | updateApi: '/myapp/admin/classification/update'
11 | }
12 |
13 | /**
14 | * 列表
15 | */
16 | export const listApi = function (data) {
17 | return axios({
18 | url: api.listApi,
19 | method: 'get',
20 | params: data
21 | })
22 | }
23 |
24 | /**
25 | * 新建
26 | */
27 | export const createApi = function (data) {
28 | return axios({
29 | url: api.createApi,
30 | method: 'post',
31 | headers: {
32 | 'Content-Type': 'multipart/form-data;charset=utf-8'
33 | },
34 | data: data
35 | })
36 | }
37 |
38 | /**
39 | * 删除
40 | */
41 | export const deleteApi = function (params) {
42 | return axios({
43 | url: api.deleteApi,
44 | method: 'post',
45 | params: params
46 | })
47 | }
48 | /**
49 | * 更新
50 | */
51 | export const updateApi = function (params, data) {
52 | return axios({
53 | url: api.updateApi,
54 | method: 'post',
55 | headers: {
56 | 'Content-Type': 'multipart/form-data;charset=utf-8'
57 | },
58 | params: params,
59 | data: data
60 | })
61 | }
62 |
--------------------------------------------------------------------------------
/web/src/assets/images/order-icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/src/assets/images/want-read-hover.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/web/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, (err, stats) => {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/web/src/views/admin/layout/adminLayout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
32 |
54 |
--------------------------------------------------------------------------------
/web/src/api/index/order.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/index/order/list',
8 | createApi: '/myapp/index/order/create',
9 | cancelOrderApi: '/myapp/index/order/cancel_order',
10 | delayApi: '/myapp/index/order/delay'
11 | }
12 |
13 | /**
14 | * 列表
15 | */
16 | export const listApi = function (params) {
17 | return axios({
18 | url: api.listApi,
19 | method: 'get',
20 | params: params
21 | })
22 | }
23 |
24 | /**
25 | * 新建
26 | */
27 | export const createApi = function (data) {
28 | return axios({
29 | url: api.createApi,
30 | method: 'post',
31 | headers: {
32 | 'Content-Type': 'multipart/form-data;charset=utf-8'
33 | },
34 | data: data
35 | })
36 | }
37 |
38 | /**
39 | * 取消
40 | */
41 | export const cancelOrderApi = function (params) {
42 | return axios({
43 | url: api.cancelOrderApi,
44 | method: 'post',
45 | headers: {
46 | 'Content-Type': 'multipart/form-data;charset=utf-8'
47 | },
48 | params: params,
49 | })
50 | }
51 | /**
52 | * 延期
53 | */
54 | export const delayApi = function (params, data) {
55 | return axios({
56 | url: api.delayApi,
57 | method: 'post',
58 | headers: {
59 | 'Content-Type': 'multipart/form-data;charset=utf-8'
60 | },
61 | params: params,
62 | data: data
63 | })
64 | }
65 |
--------------------------------------------------------------------------------
/web/src/views/admin/components/header.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
31 |
62 |
--------------------------------------------------------------------------------
/web/src/assets/images/pwd-hidden.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/web/src/api/index/user.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | registerApi: '/myapp/index/user/register',
8 | loginApi: '/myapp/index/user/login',
9 | infoApi: '/myapp/index/user/info',
10 | updateApi: '/myapp/index/user/update',
11 | updatePwdApi: '/myapp/index/user/updatePwd',
12 | }
13 |
14 | export const registerApi = function (data) {
15 | return axios({
16 | url: api.registerApi,
17 | method: 'post',
18 | data: data
19 | })
20 | }
21 |
22 | export const loginApi = function (data) {
23 | return axios({
24 | url: api.loginApi,
25 | method: 'post',
26 | data: data
27 | })
28 | }
29 |
30 | export const infoApi = function (params) {
31 | return axios({
32 | url: api.infoApi,
33 | method: 'get',
34 | params: params
35 | })
36 | }
37 |
38 | export const updateApi = function (params, data) {
39 | return axios({
40 | url: api.updateApi,
41 | method: 'post',
42 | headers: {
43 | 'Content-Type': 'multipart/form-data;charset=utf-8'
44 | },
45 | params: params,
46 | data: data
47 | })
48 | }
49 |
50 | export const updatePwdApi = function (params, data) {
51 | return axios({
52 | url: api.updatePwdApi,
53 | method: 'post',
54 | headers: {
55 | 'Content-Type': 'multipart/form-data;charset=utf-8'
56 | },
57 | params: params,
58 | data: data
59 | })
60 | }
61 |
--------------------------------------------------------------------------------
/web/src/api/index/comment.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/index/comment/list',
8 | listMyCommentsApi: '/myapp/index/comment/listMyComments',
9 | createApi: '/myapp/index/comment/create',
10 | deleteApi: '/myapp/index/comment/delete',
11 | likeApi: '/myapp/index/comment/like',
12 | }
13 |
14 | /**
15 | * 列表
16 | */
17 | export const listApi = function (params) {
18 | return axios({
19 | url: api.listApi,
20 | method: 'get',
21 | params: params
22 | })
23 | }
24 |
25 | /**
26 | * 新建
27 | */
28 | export const createApi = function (data) {
29 | return axios({
30 | url: api.createApi,
31 | method: 'post',
32 | headers: {
33 | 'Content-Type': 'multipart/form-data;charset=utf-8'
34 | },
35 | data: data
36 | })
37 | }
38 |
39 | /**
40 | * 删除
41 | */
42 | export const deleteApi = function (params) {
43 | return axios({
44 | url: api.deleteApi,
45 | method: 'post',
46 | params: params
47 | })
48 | }
49 |
50 | /**
51 | * like
52 | */
53 | export const likeApi = function (params) {
54 | return axios({
55 | url: api.likeApi,
56 | method: 'post',
57 | params: params
58 | })
59 | }
60 |
61 | /**
62 | * listMyCommentsApi
63 | */
64 | export const listMyCommentsApi = function (params) {
65 | return axios({
66 | url: api.listMyCommentsApi,
67 | method: 'get',
68 | params: params
69 | })
70 | }
71 |
--------------------------------------------------------------------------------
/web/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 |
7 | function exec (cmd) {
8 | return require('child_process').execSync(cmd).toString().trim()
9 | }
10 |
11 | const versionRequirements = [
12 | {
13 | name: 'node',
14 | currentVersion: semver.clean(process.version),
15 | versionRequirement: packageConfig.engines.node
16 | }
17 | ]
18 |
19 | if (shell.which('npm')) {
20 | versionRequirements.push({
21 | name: 'npm',
22 | currentVersion: exec('npm --version'),
23 | versionRequirement: packageConfig.engines.npm
24 | })
25 | }
26 |
27 | module.exports = function () {
28 | const warnings = []
29 |
30 | for (let i = 0; i < versionRequirements.length; i++) {
31 | const mod = versionRequirements[i]
32 |
33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
34 | warnings.push(mod.name + ': ' +
35 | chalk.red(mod.currentVersion) + ' should be ' +
36 | chalk.green(mod.versionRequirement)
37 | )
38 | }
39 | }
40 |
41 | if (warnings.length) {
42 | console.log('')
43 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
44 | console.log()
45 |
46 | for (let i = 0; i < warnings.length; i++) {
47 | const warning = warnings[i]
48 | console.log(' ' + warning)
49 | }
50 |
51 | console.log()
52 | process.exit(1)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/web/src/assets/images/setting-icon.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/web/src/assets/images/setting-safe-icon.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/web/src/permission.js:
--------------------------------------------------------------------------------
1 | import router from './router'
2 | import store from './store'
3 | import storage from 'store'
4 | import { ADMIN_TOKEN, TOKEN } from '@/store/constants'
5 |
6 | // 路由权限白名单
7 | const allowList = ['admin-login', 'login', 'register', 'portal', 'search', 'detail', '403', '404']
8 | // 前台登录地址
9 | const loginRoutePath = '/index/login'
10 | // 后台登录地址
11 | const adminLoginRoutePath = '/admin-login'
12 |
13 | router.beforeEach((to, from, next) => {
14 | console.log(to, from)
15 | /* has token */
16 |
17 | /** 后台路由 **/
18 | if (to.path.startsWith('/admin')) {
19 | if (storage.get(ADMIN_TOKEN)) {
20 | if (to.path === adminLoginRoutePath) {
21 | next({ path: '/' })
22 | } else {
23 | next()
24 | }
25 | } else {
26 | if (allowList.includes(to.name)) {
27 | // 在免登录名单,直接进入
28 | next()
29 | } else {
30 | next({ path: adminLoginRoutePath, query: { redirect: to.fullPath } })
31 | }
32 | }
33 | }
34 |
35 | /** 前台路由 **/
36 | if (to.path.startsWith('/index')) {
37 | if (storage.get(TOKEN)) {
38 | if (to.path === loginRoutePath) {
39 | next({ path: '/' })
40 | } else {
41 | next()
42 | }
43 | } else {
44 | if (allowList.includes(to.name)) {
45 | // 在免登录名单,直接进入
46 | next()
47 | } else {
48 | next({ path: loginRoutePath, query: { redirect: to.fullPath } })
49 | }
50 | }
51 | }
52 | })
53 | //
54 | // router.afterEach(() => {
55 | // NProgress.done() // finish progress bar
56 | // })
57 |
--------------------------------------------------------------------------------
/web/src/views/index/user/score-view.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
41 |
74 |
--------------------------------------------------------------------------------
/server/myapp/middlewares/LogMiddleware.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import time
3 | import json
4 |
5 | from django.utils.deprecation import MiddlewareMixin
6 |
7 | from myapp import utils
8 | from myapp.serializers import OpLogSerializer
9 |
10 |
11 | class OpLogs(MiddlewareMixin):
12 |
13 | def __init__(self, *args):
14 | super(OpLogs, self).__init__(*args)
15 |
16 | self.start_time = None # 开始时间
17 | self.end_time = None # 响应时间
18 | self.data = {} # dict数据
19 |
20 | def process_request(self, request):
21 |
22 | self.start_time = time.time() # 开始时间
23 |
24 | re_ip = utils.get_ip(request)
25 | re_method = request.method
26 | re_content = request.GET if re_method == 'GET' else request.POST
27 | if re_content:
28 | re_content = json.dumps(re_content)
29 | else:
30 | re_content = None
31 |
32 | self.data.update(
33 | {
34 | 're_url': request.path,
35 | 're_method': re_method,
36 | 're_ip': re_ip,
37 | # 're_content': re_content,
38 | }
39 | )
40 | # print(self.data)
41 |
42 | def process_response(self, request, response):
43 |
44 | # 耗时毫秒/ms
45 | self.end_time = time.time() # 响应时间
46 | access_time = self.end_time - self.start_time
47 | self.data['access_time'] = round(access_time * 1000)
48 |
49 | # 入库
50 | serializer = OpLogSerializer(data=self.data)
51 | if serializer.is_valid():
52 | serializer.save()
53 |
54 | return response
55 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | > 学习过程中,遇到问题可以咨询作者,如需完整源码,可联系客服微信购买:lengqin1024
2 |
3 |
4 | ### 功能介绍
5 |
6 | 平台采用B/S结构,后端采用主流的Python语言进行开发,前端采用主流的Vue.js进行开发。
7 |
8 | 整个平台包括前台和后台两个部分。
9 |
10 | - 前台功能包括:首页、商品详情页、用户中心模块。
11 | - 后台功能包括:总览、订单管理、商品管理、分类管理、标签管理、评论管理、用户管理、运营管理、日志管理、系统信息模块。
12 |
13 |
14 | ### 演示地址
15 |
16 | 前台地址: http://shop.gitapp.cn
17 |
18 | 后台地址:http://shop.gitapp.cn/admin
19 |
20 | 后台管理帐号:
21 |
22 | 用户名:admin123
23 | 密码:admin123
24 |
25 | ### 代码结构
26 |
27 | - server目录是后端代码
28 | - web目录是前端代码
29 |
30 | ### 部署运行
31 |
32 | #### 后端运行步骤
33 |
34 | (1) 安装python 3.8
35 |
36 | (2) 安装依赖。进入server目录下,执行 pip install -r requirements.txt
37 |
38 | (3) 安装mysql 5.7数据库,并创建数据库,命名为shop,创建SQL如下:
39 | ```
40 | CREATE DATABASE IF NOT EXISTS shop DEFAULT CHARSET utf8 COLLATE utf8_general_ci
41 | ```
42 | (4) 恢复shop.sql数据。在mysql下依次执行如下命令:
43 |
44 | ```
45 | mysql> use shop;
46 | mysql> source D:/xxx/xxx/shop.sql;
47 | ```
48 |
49 | (5) 启动django服务。在server目录下执行:
50 | ```
51 | python manage.py runserver
52 | ```
53 |
54 | #### 前端运行步骤
55 |
56 | (1) 安装node 16.14
57 |
58 | (2) 进入web目录下,安装依赖,执行:
59 | ```
60 | npm install
61 | ```
62 | (3) 运行项目
63 | ```
64 | npm run dev
65 | ```
66 |
67 |
68 | ### 界面预览
69 |
70 | 首页
71 |
72 | 
73 |
74 |
75 | 后台页面
76 |
77 | 
78 |
79 |
80 |
81 | ### 参考论文
82 |
83 | [点击查看](doc/python_shop.docx)
84 |
85 | ### 付费咨询
86 |
87 | 微信(lengqin1024)
88 |
89 |
90 |
91 | ### 打赏作者
92 |
93 | 
94 |
95 |
--------------------------------------------------------------------------------
/server/myapp/auth/authentication.py:
--------------------------------------------------------------------------------
1 | from rest_framework import exceptions
2 | from rest_framework.authentication import BaseAuthentication
3 |
4 | from myapp.models import User
5 |
6 |
7 | # 后台接口认证
8 | class AdminTokenAuthtication(BaseAuthentication):
9 | def authenticate(self, request):
10 | adminToken = request.META.get("HTTP_ADMINTOKEN")
11 | print("检查adminToken==>" + adminToken)
12 | users = User.objects.filter(admin_token=adminToken)
13 | """
14 | 判定条件:
15 | 1. 传了adminToken
16 | 2. 查到了该帐号
17 | 3. 该帐号是管理员或演示帐号
18 | """
19 | if not adminToken or users.count == 0 or users[0].role == '2':
20 | raise exceptions.AuthenticationFailed("AUTH_FAIL_END")
21 | else:
22 | print('adminToken验证通过')
23 |
24 |
25 | # 前台接口认证
26 | class TokenAuthtication(BaseAuthentication):
27 | def authenticate(self, request):
28 | token = request.META.get("HTTP_TOKEN", "")
29 | if token is not None:
30 | print("检查token==>" + token)
31 | users = User.objects.filter(token=token)
32 | # print(users)
33 | """
34 | 判定条件:
35 | 1. 传了token
36 | 2. 查到了该帐号
37 | 3. 该帐号是普通用户
38 | """
39 | if not token or users.count == 0 or (users[0].role in ['1', '3']):
40 | raise exceptions.AuthenticationFailed("AUTH_FAIL_FRONT")
41 | else:
42 | print('token验证通过')
43 | else:
44 | print("检查token==>token 为空")
45 | raise exceptions.AuthenticationFailed("AUTH_FAIL_FRONT")
46 |
--------------------------------------------------------------------------------
/web/src/assets/images/cart-icon.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/server/readme.md:
--------------------------------------------------------------------------------
1 | ### 后端部署步骤
2 |
3 | > 部署过程中,如遇问题可咨询作者:lengqin1024(微信)
4 |
5 | 1. 安装mysql数据库,启动服务
6 | 2. 打开cmd命令行,进入mysql,并新建数据库
7 | ```
8 | mysql -u root -p
9 | CREATE DATABASE IF NOT EXISTS shop DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
10 | ```
11 | 3. 恢复sql数据
12 | ```
13 | use shop
14 | source xxxx.sql
15 | ```
16 | 4. 复制资源,将upload文件夹复制到server目录下
17 | 5. 安装python 3.8
18 | 6. 安装依赖包
19 | ```
20 | pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
21 | ```
22 | 运行项目
23 | ```
24 | python manage.py runserver 0.0.0.0:9003
25 | ```
26 | 7. 后期维护改动
27 |
28 | 将修改的py文件覆盖服务器的py文件即可,重启django
29 |
30 | ### 删除数据库
31 |
32 | drop database if exists shop;
33 |
34 | ### 创建数据库
35 |
36 | CREATE DATABASE IF NOT EXISTS shop DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
37 |
38 |
39 | ### 迁移数据库表
40 |
41 | ```
42 | python manage.py makemigrations;
43 |
44 | python manage.py migrate;
45 |
46 | python manage.py makemigrations myapp;
47 |
48 | python manage.py migrate myapp;
49 | ```
50 |
51 | ### 跨域配置
52 |
53 | django-cors-headers
54 |
55 | ### 多对多技术参考
56 |
57 | https://www.cnblogs.com/SunshineKimi/p/14140900.html
58 |
59 | ### 二级分类设计
60 | https://blog.csdn.net/weixin_47971206/article/details/124199978
61 |
62 | ### 常见问题
63 |
64 | 多对多的查询可通过related_name别名查询
65 | join查询
66 | ForeignKey的时候字段会自动加_id后缀
67 | 学习SerializerMethodField
68 | 跨域配置 django-cors-headers
69 | 数据库备份命令:
70 | mysqldump -u root -p --databases 数据库名称 > xxx.sql
71 | 数据库还原命令:
72 | source D:/xxx/xxx/shop.sql;
73 | 创建管理员命令:
74 | insert into b_user(username,password,role,status) values('admin111',md5('admin111'),1,'0');
75 |
76 | 接口请求频次限制
77 |
78 | 借书逻辑:库存减1
79 | 还书逻辑:库存加1, 积分加1
80 |
81 | ### 登录接口
82 |
83 | 调login -> 生成token
84 |
85 | ### 注意
86 |
87 | update接口的时候,如果model里面存在多对多字段,则需要设置explode
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/web/src/assets/images/recommend-hover.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/web/src/views/admin/model/edit-comment.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
67 |
68 |
71 |
--------------------------------------------------------------------------------
/web/src/api/admin/order.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/admin/order/list',
8 | createApi: '/myapp/admin/order/create',
9 | cancelOrderApi: '/myapp/admin/order/cancel_order',
10 | deleteApi: '/myapp/admin/order/delete',
11 | updateApi: '/myapp/admin/order/update',
12 | delayApi: '/myapp/admin/order/delay'
13 | }
14 |
15 | /**
16 | * 列表
17 | */
18 | export const listApi = function (data) {
19 | return axios({
20 | url: api.listApi,
21 | method: 'get',
22 | params: data
23 | })
24 | }
25 |
26 | /**
27 | * 新建
28 | */
29 | export const createApi = function (data) {
30 | return axios({
31 | url: api.createApi,
32 | method: 'post',
33 | headers: {
34 | 'Content-Type': 'multipart/form-data;charset=utf-8'
35 | },
36 | data: data
37 | })
38 | }
39 |
40 | /**
41 | * 删除
42 | */
43 | export const deleteApi = function (params) {
44 | return axios({
45 | url: api.deleteApi,
46 | method: 'post',
47 | params: params
48 | })
49 | }
50 | /**
51 | * 更新
52 | */
53 | export const updateApi = function (params, data) {
54 | return axios({
55 | url: api.updateApi,
56 | method: 'post',
57 | headers: {
58 | 'Content-Type': 'multipart/form-data;charset=utf-8'
59 | },
60 | params: params,
61 | data: data
62 | })
63 | }
64 | /**
65 | * 取消
66 | */
67 | export const cancelOrderApi = function (params) {
68 | return axios({
69 | url: api.cancelOrderApi,
70 | method: 'post',
71 | headers: {
72 | 'Content-Type': 'multipart/form-data;charset=utf-8'
73 | },
74 | params: params
75 | })
76 | }
77 | /**
78 | * 延期
79 | */
80 | export const delayApi = function (params, data) {
81 | return axios({
82 | url: api.delayApi,
83 | method: 'post',
84 | headers: {
85 | 'Content-Type': 'multipart/form-data;charset=utf-8'
86 | },
87 | params: params,
88 | data: data
89 | })
90 | }
91 |
--------------------------------------------------------------------------------
/web/src/utils/request.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import store from '@/store'
3 | import storage from 'store'
4 | import notification from 'ant-design-vue/es/notification'
5 | import {ADMIN_TOKEN, BASE_URL, TOKEN} from '@/store/constants'
6 |
7 | // 创建 axios 实例
8 | const request = axios.create({
9 | baseURL: BASE_URL,
10 | timeout: 180000
11 | })
12 |
13 | // 异常拦截处理器
14 | const errorHandler = (error) => {
15 | if (error.response) {
16 | const data = error.response.data
17 | console.log(data)
18 | // 从 localstorage 获取 token
19 | if (error.response.status === 403) {
20 | notification.error({
21 | message: '未登录',
22 | description: '登录验证失败'
23 | })
24 |
25 | // 后台认证失败
26 | if (data.detail === 'AUTH_FAIL_END') {
27 | store.dispatch('AdminLogout').then(() => {
28 | setTimeout(() => {
29 | window.location.reload()
30 | }, 500)
31 | })
32 | }
33 |
34 | // 前台认证失败
35 | if (data.detail === 'AUTH_FAIL_FRONT') {
36 | store.dispatch('Logout').then(() => {
37 | setTimeout(() => {
38 | window.location.reload()
39 | }, 500)
40 | })
41 | }
42 | }
43 | }
44 | return Promise.reject(error)
45 | }
46 |
47 | // request interceptor
48 | request.interceptors.request.use(config => {
49 | const adminToken = storage.get(ADMIN_TOKEN)
50 | const token = storage.get(TOKEN)
51 |
52 | config.headers['Access-Control-Allow-Headers'] = 'adminToken, token,Content-Type'
53 |
54 | // config.headers['Authorization'] = ''
55 | config.headers['ADMINTOKEN'] = adminToken
56 | config.headers['TOKEN'] = token
57 | return config
58 | }, errorHandler)
59 |
60 | // response interceptor
61 | request.interceptors.response.use((response) => {
62 | if (response.data.code !== 200 && response.data.code !== 0) {
63 | return Promise.reject(response.data)
64 | } else {
65 | return response.data
66 | }
67 | }, errorHandler)
68 |
69 | export default request
70 |
--------------------------------------------------------------------------------
/web/src/views/admin/model/edit-tag.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
79 |
80 |
83 |
--------------------------------------------------------------------------------
/server/myapp/utils.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import hashlib
3 | import time
4 |
5 | from rest_framework.views import exception_handler
6 |
7 | from myapp.serializers import ErrorLogSerializer
8 |
9 | def get_timestamp():
10 | return int(round(time.time() * 1000))
11 |
12 | def md5value(key):
13 | input_name = hashlib.md5()
14 | input_name.update(key.encode("utf-8"))
15 | md5str = (input_name.hexdigest()).lower()
16 | print('计算md5:', md5str)
17 | return md5str
18 |
19 |
20 | def dict_fetchall(cursor): # cursor是执行sql_str后的记录,作入参
21 | columns = [col[0] for col in cursor.description] # 得到域的名字col[0],组成List
22 | return [
23 | dict(zip(columns, row)) for row in cursor.fetchall()
24 | ]
25 |
26 |
27 | def get_ip(request):
28 | """
29 | 获取请求者的IP信息
30 | """
31 | x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
32 | if x_forwarded_for:
33 | ip = x_forwarded_for.split(',')[0]
34 | else:
35 | ip = request.META.get('REMOTE_ADDR')
36 | return ip
37 |
38 |
39 | def get_ua(request):
40 | """
41 | 获取请求者的IP信息
42 | """
43 | ua = request.META.get('HTTP_USER_AGENT')
44 | return ua[0:200]
45 |
46 |
47 | def getWeekDays():
48 | """
49 | 获取近一周的日期
50 | """
51 | week_days = []
52 | now = datetime.datetime.now()
53 | for i in range(7):
54 | day = now - datetime.timedelta(days=i)
55 | week_days.append(day.strftime('%Y-%m-%d %H:%M:%S.%f')[:10])
56 | week_days.reverse() # 逆序
57 | return week_days
58 |
59 |
60 | def get_monday():
61 | """
62 | 获取本周周一日期
63 | """
64 | now = datetime.datetime.now()
65 | monday = now - datetime.timedelta(now.weekday())
66 | return monday.strftime('%Y-%m-%d %H:%M:%S.%f')[:10]
67 |
68 |
69 | def log_error(request, content):
70 | """
71 | 记录错误日志
72 | """
73 | ip = get_ip(request)
74 | method = request.method
75 | url = request.path
76 |
77 | data = {
78 | 'ip': ip,
79 | 'method': method,
80 | 'url': url,
81 | 'content': content
82 | }
83 |
84 | # 入库
85 | serializer = ErrorLogSerializer(data=data)
86 | if serializer.is_valid():
87 | serializer.save()
88 |
--------------------------------------------------------------------------------
/web/src/views/index/components/footer.vue:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
29 |
30 |
84 |
--------------------------------------------------------------------------------
/web/src/api/admin/user.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | adminLogin: '/myapp/admin/adminLogin',
8 | listApi: '/myapp/admin/user/list',
9 | createApi: '/myapp/admin/user/create',
10 | deleteApi: '/myapp/admin/user/delete',
11 | updateApi: '/myapp/admin/user/update',
12 | updatePwdApi: '/myapp/admin/user/updatePwd',
13 | infoApi: '/myapp/admin/user/info'
14 | }
15 |
16 | /**
17 | * 管理员登录
18 | */
19 | export const adminLogin = function (data) {
20 | return axios({
21 | url: api.adminLogin,
22 | method: 'post',
23 | headers: {
24 | 'Content-Type': 'multipart/form-data;charset=utf-8'
25 | },
26 | data: data
27 | })
28 | }
29 |
30 | /**
31 | * 列表
32 | */
33 | export const listApi = function (data) {
34 | return axios({
35 | url: api.listApi,
36 | method: 'get',
37 | params: data
38 | })
39 | }
40 |
41 | /**
42 | * 基本信息
43 | */
44 | export const infoApi = function (data) {
45 | return axios({
46 | url: api.infoApi,
47 | method: 'get',
48 | params: data
49 | })
50 | }
51 |
52 | /**
53 | * 新建
54 | */
55 | export const createApi = function (data) {
56 | return axios({
57 | url: api.createApi,
58 | method: 'post',
59 | headers: {
60 | 'Content-Type': 'multipart/form-data;charset=utf-8'
61 | },
62 | data: data
63 | })
64 | }
65 |
66 | /**
67 | * 删除
68 | */
69 | export const deleteApi = function (params) {
70 | return axios({
71 | url: api.deleteApi,
72 | method: 'post',
73 | params: params
74 | })
75 | }
76 | /**
77 | * 更新
78 | */
79 | export const updateApi = function (params, data) {
80 | return axios({
81 | url: api.updateApi,
82 | method: 'post',
83 | headers: {
84 | 'Content-Type': 'multipart/form-data;charset=utf-8'
85 | },
86 | params: params,
87 | data: data
88 | })
89 | }
90 | /**
91 | * 更新密码
92 | */
93 | export const updatePwdApi = function (params, data) {
94 | return axios({
95 | url: api.updatePwdApi,
96 | method: 'post',
97 | headers: {
98 | 'Content-Type': 'multipart/form-data;charset=utf-8'
99 | },
100 | params: params,
101 | data: data
102 | })
103 | }
104 |
--------------------------------------------------------------------------------
/web/src/assets/images/setting-card-icon.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/server/myapp/views/index/classification.py:
--------------------------------------------------------------------------------
1 | # Create your views here.
2 | from django.db import connection
3 | from rest_framework.decorators import api_view
4 |
5 | from myapp.handler import APIResponse
6 | from myapp.utils import dict_fetchall
7 |
8 |
9 | @api_view(['GET'])
10 | def list_api(request):
11 | if request.method == 'GET':
12 | sql_str = 'SELECT x.id AS parentId, x.title AS parentTitle, y.id AS childId ,y.title AS childTitle FROM ' \
13 | 'b_classification AS x LEFT JOIN b_classification AS y ON y.pid = x.id WHERE x.pid = -1 order by ' \
14 | 'x.create_time desc '
15 | data = [{
16 | 'key': -1,
17 | 'title': '全部',
18 | 'isParent': True,
19 | 'children': []
20 | }]
21 | with connection.cursor() as cursor:
22 | cursor.execute(sql_str)
23 | join_data = dict_fetchall(cursor)
24 | # print(join_data)
25 | for item1 in join_data:
26 | found = False
27 | for item2 in data:
28 | if item2['key'] == item1['parentId']:
29 | found = True
30 | if item1['childId']:
31 | item2['children'].append({
32 | 'key': item1['childId'],
33 | 'title': item1['childTitle'],
34 | 'isParent': False,
35 | # 'children': []
36 | })
37 | break
38 | if not found:
39 | k = {
40 | 'key': item1['parentId'],
41 | 'title': item1['parentTitle'],
42 | 'isParent': True,
43 | 'children': []
44 | }
45 | if item1['childId']:
46 | k['children'].append({
47 | 'key': item1['childId'],
48 | 'title': item1['childTitle'],
49 | 'isParent': False,
50 | # 'children': []
51 | })
52 | data.append(k)
53 | return APIResponse(code=0, msg='查询成功', data=data)
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/web/src/assets/images/wb-share.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/web/src/views/admin/model/edit-role.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
84 |
85 |
88 |
--------------------------------------------------------------------------------
/web/src/api/index/thing.js:
--------------------------------------------------------------------------------
1 | /**
2 | * api
3 | */
4 | import axios from '@/utils/request.js'
5 |
6 | const api = {
7 | listApi: '/myapp/index/thing/list',
8 | detailApi: '/myapp/index/thing/detail',
9 | addWishUserApi: '/myapp/index/thing/addWishUser',
10 | removeWishUserApi: '/myapp/index/thing/removeWishUser',
11 | getWishThingListApi: '/myapp/index/thing/getWishThingList',
12 | addCollectUserApi: '/myapp/index/thing/addCollectUser',
13 | removeCollectUserApi: '/myapp/index/thing/removeCollectUser',
14 | getCollectThingListApi: '/myapp/index/thing/getCollectThingList',
15 | // increaseRecommendCountApi: '/myapp/index/thing/increaseRecommendCount',
16 | }
17 |
18 | /**
19 | * list
20 | */
21 | export const listApi = function (data) {
22 | return axios({
23 | url: api.listApi,
24 | method: 'get',
25 | params: data
26 | })
27 | }
28 | /**
29 | * detail
30 | */
31 | export const detailApi = function (data) {
32 | return axios({
33 | url: api.detailApi,
34 | method: 'get',
35 | params: data
36 | })
37 | }
38 |
39 | export const addWishUserApi = function (data) {
40 | return axios({
41 | url: api.addWishUserApi,
42 | method: 'post',
43 | params: data
44 | })
45 | }
46 |
47 | export const removeWishUserApi = function (data) {
48 | return axios({
49 | url: api.removeWishUserApi,
50 | method: 'post',
51 | params: data
52 | })
53 | }
54 |
55 | export const getWishThingListApi = function (params) {
56 | return axios({
57 | url: api.getWishThingListApi,
58 | method: 'get',
59 | params: params
60 | })
61 | }
62 |
63 | export const addCollectUserApi = function (data) {
64 | return axios({
65 | url: api.addCollectUserApi,
66 | method: 'post',
67 | params: data
68 | })
69 | }
70 |
71 | export const removeCollectUserApi = function (data) {
72 | return axios({
73 | url: api.removeCollectUserApi,
74 | method: 'post',
75 | params: data
76 | })
77 | }
78 |
79 | export const getCollectThingListApi = function (params) {
80 | return axios({
81 | url: api.getCollectThingListApi,
82 | method: 'get',
83 | params: params
84 | })
85 | }
86 |
87 | // export const increaseRecommendCountApi = function (data) {
88 | // return axios({
89 | // url: api.increaseRecommendCountApi,
90 | // method: 'post',
91 | // params: data
92 | // })
93 | // }
94 |
--------------------------------------------------------------------------------
/web/src/views/admin/model/edit-password.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
77 |
78 |
81 |
--------------------------------------------------------------------------------
/web/src/views/admin/model/edit-classification.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
88 |
89 |
92 |
--------------------------------------------------------------------------------
/web/src/views/admin/login-log.vue:
--------------------------------------------------------------------------------
1 |
2 |
25 |
26 |
27 |
93 |
94 |
110 |
--------------------------------------------------------------------------------
/web/src/views/index/user/fans-view.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
我的粉丝
4 |
5 |
6 |
7 |
![]()
8 |
9 |
Python_C
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
27 |
104 |
--------------------------------------------------------------------------------
/web/src/views/index/user/follow-view.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
我的关注
4 |
5 |
6 |
7 |
![]()
8 |
9 |
Python_C
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
28 |
105 |
--------------------------------------------------------------------------------
/web/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "web",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "",
6 | "private": true,
7 | "scripts": {
8 | "serve": "vue-cli-service serve",
9 | "build": "vue-cli-service build"
10 | },
11 | "dependencies": {
12 | "ant-design-vue": "^1.7.8",
13 | "axios": "^1.2.1",
14 | "echarts": "^4.9.0",
15 | "moment": "^2.29.4",
16 | "store": "^2.0.12",
17 | "vue": "^2.5.2",
18 | "vue-router": "^3.0.1",
19 | "vuex": "^3.6.2"
20 | },
21 | "devDependencies": {
22 | "@vue/cli-service": "^4.5.17",
23 | "autoprefixer": "^7.1.2",
24 | "babel-core": "^6.22.1",
25 | "babel-eslint": "^8.2.1",
26 | "babel-helper-vue-jsx-merge-props": "^2.0.3",
27 | "babel-loader": "^7.1.1",
28 | "babel-plugin-syntax-jsx": "^6.18.0",
29 | "babel-plugin-transform-runtime": "^6.22.0",
30 | "babel-plugin-transform-vue-jsx": "^3.5.0",
31 | "babel-preset-env": "^1.3.2",
32 | "babel-preset-stage-2": "^6.22.0",
33 | "chalk": "^2.0.1",
34 | "copy-webpack-plugin": "^4.0.1",
35 | "css-loader": "^0.28.0",
36 | "eslint": "^4.15.0",
37 | "eslint-config-standard": "^10.2.1",
38 | "eslint-friendly-formatter": "^3.0.0",
39 | "eslint-loader": "^1.7.1",
40 | "eslint-plugin-import": "^2.7.0",
41 | "eslint-plugin-node": "^5.2.0",
42 | "eslint-plugin-promise": "^3.4.0",
43 | "eslint-plugin-standard": "^3.0.1",
44 | "eslint-plugin-vue": "^4.0.0",
45 | "extract-text-webpack-plugin": "^3.0.0",
46 | "file-loader": "^1.1.4",
47 | "friendly-errors-webpack-plugin": "^1.6.1",
48 | "html-webpack-plugin": "^2.30.1",
49 | "less": "^3.13.1",
50 | "less-loader": "^5.0.0",
51 | "node-notifier": "^5.1.2",
52 | "optimize-css-assets-webpack-plugin": "^3.2.0",
53 | "ora": "^1.2.0",
54 | "portfinder": "^1.0.13",
55 | "postcss-import": "^11.0.0",
56 | "postcss-loader": "^2.0.8",
57 | "postcss-url": "^7.2.1",
58 | "rimraf": "^2.6.0",
59 | "semver": "^5.3.0",
60 | "shelljs": "^0.7.6",
61 | "uglifyjs-webpack-plugin": "^1.1.1",
62 | "url-loader": "^0.5.8",
63 | "vue-loader": "^13.3.0",
64 | "vue-style-loader": "^3.0.1",
65 | "vue-template-compiler": "^2.5.2",
66 | "webpack": "^3.6.0",
67 | "webpack-bundle-analyzer": "^2.9.0",
68 | "webpack-dev-server": "^2.9.1",
69 | "webpack-merge": "^4.1.0"
70 | },
71 | "engines": {
72 | "node": ">= 6.0.0",
73 | "npm": ">= 3.0.0"
74 | },
75 | "browserslist": [
76 | "> 1%",
77 | "last 2 versions",
78 | "not ie <= 8"
79 | ]
80 | }
81 |
--------------------------------------------------------------------------------
/web/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.3.1
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 |
10 | // Paths
11 | assetsSubDirectory: 'static',
12 | assetsPublicPath: '/',
13 | proxyTable: {},
14 |
15 | // Various Dev Server settings
16 | host: 'localhost', // can be overwritten by process.env.HOST
17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18 | autoOpenBrowser: false,
19 | errorOverlay: true,
20 | notifyOnErrors: true,
21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22 |
23 | // Use Eslint Loader?
24 | // If true, your code will be linted during bundling and
25 | // linting errors and warnings will be shown in the console.
26 | useEslint: true,
27 | // If true, eslint errors and warnings will also be shown in the error overlay
28 | // in the browser.
29 | showEslintErrorsInOverlay: false,
30 |
31 | /**
32 | * Source Maps
33 | */
34 |
35 | // https://webpack.js.org/configuration/devtool/#development
36 | devtool: 'cheap-module-eval-source-map',
37 |
38 | // If you have problems debugging vue-files in devtools,
39 | // set this to false - it *may* help
40 | // https://vue-loader.vuejs.org/en/options.html#cachebusting
41 | cacheBusting: true,
42 |
43 | cssSourceMap: true
44 | },
45 |
46 | build: {
47 | // Template for index.html
48 | index: path.resolve(__dirname, '../dist/index.html'),
49 |
50 | // Paths
51 | assetsRoot: path.resolve(__dirname, '../dist'),
52 | assetsSubDirectory: 'static',
53 | assetsPublicPath: '/',
54 |
55 | /**
56 | * Source Maps
57 | */
58 |
59 | productionSourceMap: true,
60 | // https://webpack.js.org/configuration/devtool/#production
61 | devtool: '#source-map',
62 |
63 | // Gzip off by default as many popular static hosts such as
64 | // Surge or Netlify already gzip all static assets for you.
65 | // Before setting to `true`, make sure to:
66 | // npm install --save-dev compression-webpack-plugin
67 | productionGzip: false,
68 | productionGzipExtensions: ['js', 'css'],
69 |
70 | // Run the build command with an extra argument to
71 | // View the bundle analyzer report after build finishes:
72 | // `npm run build --report`
73 | // Set to `true` or `false` to always turn it on or off
74 | bundleAnalyzerReport: process.env.npm_config_report
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/web/src/utils/util.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * 触发 window.resize
4 | */
5 | export function triggerWindowResizeEvent () {
6 | const event = document.createEvent('HTMLEvents')
7 | event.initEvent('resize', true, true)
8 | event.eventType = 'message'
9 | window.dispatchEvent(event)
10 | }
11 |
12 | export function handleScrollHeader (callback) {
13 | let timer = 0
14 |
15 | let beforeScrollTop = window.pageYOffset
16 | callback = callback || function () {}
17 | window.addEventListener(
18 | 'scroll',
19 | event => {
20 | clearTimeout(timer)
21 | timer = setTimeout(() => {
22 | let direction = 'up'
23 | const afterScrollTop = window.pageYOffset
24 | const delta = afterScrollTop - beforeScrollTop
25 | if (delta === 0) {
26 | return false
27 | }
28 | direction = delta > 0 ? 'down' : 'up'
29 | callback(direction)
30 | beforeScrollTop = afterScrollTop
31 | }, 50)
32 | },
33 | false
34 | )
35 | }
36 |
37 | export function isIE () {
38 | const bw = window.navigator.userAgent
39 | const compare = (s) => bw.indexOf(s) >= 0
40 | const ie11 = (() => 'ActiveXObject' in window)()
41 | return compare('MSIE') || ie11
42 | }
43 |
44 | /**
45 | * Remove loading animate
46 | * @param id parent element id or class
47 | * @param timeout
48 | */
49 | export function removeLoadingAnimate (id = '', timeout = 1500) {
50 | if (id === '') {
51 | return
52 | }
53 | setTimeout(() => {
54 | document.body.removeChild(document.getElementById(id))
55 | }, timeout)
56 | }
57 |
58 | export function scorePassword (pass) {
59 | let score = 0
60 | if (!pass) {
61 | return score
62 | }
63 | // award every unique letter until 5 repetitions
64 | const letters = {}
65 | for (let i = 0; i < pass.length; i++) {
66 | letters[pass[i]] = (letters[pass[i]] || 0) + 1
67 | score += 5.0 / letters[pass[i]]
68 | }
69 |
70 | // bonus points for mixing it up
71 | const variations = {
72 | digits: /\d/.test(pass),
73 | lower: /[a-z]/.test(pass),
74 | upper: /[A-Z]/.test(pass),
75 | nonWords: /\W/.test(pass)
76 | }
77 |
78 | let variationCount = 0
79 | for (var check in variations) {
80 | variationCount += (variations[check] === true) ? 1 : 0
81 | }
82 | score += (variationCount - 1) * 10
83 |
84 | return parseInt(score)
85 | }
86 |
87 | /**
88 | * 数组格式化
89 | * @param value
90 | * @returns {string}
91 | */
92 | export function numberFormat (value) {
93 | if (!value) {
94 | return '0'
95 | }
96 | const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断
97 | return intPartFormat
98 | }
99 |
--------------------------------------------------------------------------------
/web/src/views/admin/model/edit-notice.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
92 |
93 |
96 |
--------------------------------------------------------------------------------
/web/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 |
7 | function resolve (dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 | const createLintingRule = () => ({
12 | test: /\.(js|vue)$/,
13 | loader: 'eslint-loader',
14 | enforce: 'pre',
15 | include: [resolve('src'), resolve('test')],
16 | options: {
17 | formatter: require('eslint-friendly-formatter'),
18 | emitWarning: !config.dev.showEslintErrorsInOverlay
19 | }
20 | })
21 |
22 | module.exports = {
23 | context: path.resolve(__dirname, '../'),
24 | entry: {
25 | app: './src/main.js'
26 | },
27 | output: {
28 | path: config.build.assetsRoot,
29 | filename: '[name].js',
30 | publicPath: process.env.NODE_ENV === 'production'
31 | ? config.build.assetsPublicPath
32 | : config.dev.assetsPublicPath
33 | },
34 | resolve: {
35 | extensions: ['.js', '.vue', '.json'],
36 | alias: {
37 | 'vue$': 'vue/dist/vue.esm.js',
38 | '@': resolve('src'),
39 | }
40 | },
41 | module: {
42 | rules: [
43 | ...(config.dev.useEslint ? [createLintingRule()] : []),
44 | {
45 | test: /\.vue$/,
46 | loader: 'vue-loader',
47 | options: vueLoaderConfig
48 | },
49 | {
50 | test: /\.js$/,
51 | loader: 'babel-loader',
52 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
53 | },
54 | {
55 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
56 | loader: 'url-loader',
57 | options: {
58 | limit: 10000,
59 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
60 | }
61 | },
62 | {
63 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
64 | loader: 'url-loader',
65 | options: {
66 | limit: 10000,
67 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
68 | }
69 | },
70 | {
71 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
72 | loader: 'url-loader',
73 | options: {
74 | limit: 10000,
75 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
76 | }
77 | }
78 | ]
79 | },
80 | node: {
81 | // prevent webpack from injecting useless setImmediate polyfill because Vue
82 | // source contains it (although only uses it if it's native).
83 | setImmediate: false,
84 | // prevent webpack from injecting mocks to Node native modules
85 | // that does not make sense for the client
86 | dgram: 'empty',
87 | fs: 'empty',
88 | net: 'empty',
89 | tls: 'empty',
90 | child_process: 'empty'
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/web/src/views/admin/error-log.vue:
--------------------------------------------------------------------------------
1 |
2 |
30 |
31 |
32 |
106 |
107 |
123 |
--------------------------------------------------------------------------------
/server/myapp/views/index/address.py:
--------------------------------------------------------------------------------
1 | # Create your views here.
2 | from rest_framework.decorators import api_view, authentication_classes
3 |
4 | from myapp import utils
5 | from myapp.auth.authentication import TokenAuthtication
6 | from myapp.handler import APIResponse
7 | from myapp.models import Address
8 | from myapp.serializers import AddressSerializer
9 |
10 |
11 | @api_view(['GET'])
12 | def list_api(request):
13 | if request.method == 'GET':
14 | userId = request.GET.get('userId', -1)
15 |
16 | if userId != -1:
17 | addresses = Address.objects.filter(user=userId).order_by('-create_time')
18 | serializer = AddressSerializer(addresses, many=True)
19 | return APIResponse(code=0, msg='查询成功', data=serializer.data)
20 | else:
21 | return APIResponse(code=1, msg='userId不能为空')
22 |
23 |
24 | @api_view(['POST'])
25 | @authentication_classes([TokenAuthtication])
26 | def create(request):
27 |
28 | address_content = request.POST.get('desc', None)
29 | user = request.POST.get('user', None)
30 | default = request.POST.get('default', False)
31 |
32 | if address_content is None or user is None:
33 | return APIResponse(code=1, msg='不能为空')
34 |
35 | if default:
36 | # 其他置为false
37 | Address.objects.filter(user=user).update(default=False)
38 |
39 | serializer = AddressSerializer(data=request.data)
40 | if serializer.is_valid():
41 | serializer.save()
42 | return APIResponse(code=0, msg='创建成功', data=serializer.data)
43 | else:
44 | utils.log_error(request, '参数错误')
45 |
46 | return APIResponse(code=1, msg='创建失败')
47 |
48 |
49 | @api_view(['POST'])
50 | @authentication_classes([TokenAuthtication])
51 | def update(request):
52 |
53 | try:
54 | pk = request.GET.get('id', -1)
55 | addresses = Address.objects.get(pk=pk)
56 | except Address.DoesNotExist:
57 | return APIResponse(code=1, msg='对象不存在')
58 |
59 | user = request.data['user']
60 | default = request.data['default']
61 |
62 | if default:
63 | # 其他置为false
64 | Address.objects.filter(user=user).update(default=False)
65 |
66 | serializer = AddressSerializer(addresses, data=request.data)
67 | if serializer.is_valid():
68 | serializer.save()
69 | return APIResponse(code=0, msg='更新成功', data=serializer.data)
70 | else:
71 | utils.log_error(request, '参数错误')
72 |
73 | return APIResponse(code=1, msg='更新失败')
74 |
75 |
76 | @api_view(['POST'])
77 | @authentication_classes([TokenAuthtication])
78 | def delete(request):
79 |
80 | try:
81 | ids = request.GET.get('ids')
82 | ids_arr = ids.split(',')
83 | Address.objects.filter(id__in=ids_arr).delete()
84 | except Address.DoesNotExist:
85 | return APIResponse(code=1, msg='对象不存在')
86 |
87 | return APIResponse(code=0, msg='删除成功')
88 |
--------------------------------------------------------------------------------
/server/myapp/views/index/order.py:
--------------------------------------------------------------------------------
1 | # Create your views here.
2 | import datetime
3 |
4 | from rest_framework.decorators import api_view, authentication_classes
5 |
6 | from myapp import utils
7 | from myapp.auth.authentication import TokenAuthtication
8 | from myapp.handler import APIResponse
9 | from myapp.models import Order, Thing
10 | from myapp.serializers import OrderSerializer
11 |
12 |
13 | @api_view(['GET'])
14 | def list_api(request):
15 | if request.method == 'GET':
16 | userId = request.GET.get('userId', -1)
17 | orderStatus = request.GET.get('orderStatus', '')
18 |
19 | orders = Order.objects.all().filter(user=userId).filter(status__contains=orderStatus).order_by('-order_time')
20 | serializer = OrderSerializer(orders, many=True)
21 | return APIResponse(code=0, msg='查询成功', data=serializer.data)
22 |
23 |
24 | @api_view(['POST'])
25 | @authentication_classes([TokenAuthtication])
26 | def create(request):
27 |
28 | data = request.data.copy()
29 | if data['user'] is None or data['thing'] is None or data['count'] is None:
30 | return APIResponse(code=1, msg='参数错误')
31 |
32 | thing = Thing.objects.get(pk=data['thing'])
33 | count = data['count']
34 | if thing.repertory < int(count):
35 | return APIResponse(code=1, msg='库存不足')
36 |
37 | create_time = datetime.datetime.now()
38 | data['create_time'] = create_time
39 | data['order_number'] = str(utils.get_timestamp())
40 | data['status'] = '1'
41 | serializer = OrderSerializer(data=data)
42 | if serializer.is_valid():
43 | serializer.save()
44 | # 减库存(支付后)
45 | # thing.repertory = thing.repertory - int(count)
46 | # thing.save()
47 |
48 | return APIResponse(code=0, msg='创建成功', data=serializer.data)
49 | else:
50 | print(serializer.errors)
51 | return APIResponse(code=1, msg='创建失败')
52 |
53 |
54 | @api_view(['POST'])
55 | @authentication_classes([TokenAuthtication])
56 | def cancel_order(request):
57 | """
58 | cancal
59 | """
60 | try:
61 | pk = request.GET.get('id', -1)
62 | order = Order.objects.get(pk=pk)
63 | except Order.DoesNotExist:
64 | return APIResponse(code=1, msg='对象不存在')
65 |
66 | data = {
67 | 'status': 7
68 | }
69 | serializer = OrderSerializer(order, data=data)
70 | if serializer.is_valid():
71 | serializer.save()
72 | # 加库存
73 | # thingId = request.data['thing']
74 | # thing = Thing.objects.get(pk=thingId)
75 | # thing.repertory = thing.repertory + 1
76 | # thing.save()
77 |
78 | # 加积分
79 | # order.user.score = order.user.score + 1
80 | # order.user.save()
81 |
82 | return APIResponse(code=0, msg='取消成功', data=serializer.data)
83 | else:
84 | print(serializer.errors)
85 | return APIResponse(code=1, msg='更新失败')
86 |
--------------------------------------------------------------------------------
/web/src/views/admin/sys-info.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 | {{ data.sysName }}
11 |
12 |
13 | {{ data.versionName }}
14 |
15 |
16 | {{ data.osName }}
17 |
18 |
19 | {{ data.pf }}
20 |
21 |
22 | {{ data.cpuCount }}
23 |
24 |
25 | {{ data.processor }}
26 |
27 |
28 | {{ data.cpuLoad }}%
29 |
30 |
31 | {{ data.memory }}G
32 |
33 |
34 | {{ data.usedMemory }}G
35 |
36 |
37 | {{ data.percentMemory }}%
38 |
39 |
40 | {{ data.sysLan }}
41 |
42 |
43 | {{ data.pyVersion }}
44 |
45 |
46 | {{ data.pyComp }}
47 |
48 |
49 | {{ data.sysZone }}
50 |
51 |
52 |
53 |
54 |
55 |
56 |
84 |
85 |
103 |
--------------------------------------------------------------------------------
/server/myapp/views/index/comment.py:
--------------------------------------------------------------------------------
1 | # Create your views here.
2 | from rest_framework.decorators import api_view, authentication_classes
3 |
4 | from myapp.auth.authentication import AdminTokenAuthtication
5 | from myapp.handler import APIResponse
6 | from myapp.models import Comment
7 | from myapp.permission.permission import isDemoAdminUser
8 | from myapp.serializers import CommentSerializer
9 |
10 |
11 | @api_view(['GET'])
12 | def list_api(request):
13 | if request.method == 'GET':
14 | thingId = request.GET.get("thingId", None)
15 | order = request.GET.get("order", 'recent')
16 |
17 | if thingId:
18 | if order == 'recent':
19 | orderBy = '-comment_time'
20 | else:
21 | orderBy = '-like_count'
22 |
23 | comments = Comment.objects.select_related("thing").filter(thing=thingId).order_by(orderBy)
24 | # print(comments)
25 | serializer = CommentSerializer(comments, many=True)
26 | return APIResponse(code=0, msg='查询成功', data=serializer.data)
27 | else:
28 | return APIResponse(code=1, msg='thingId不能为空')
29 |
30 | @api_view(['GET'])
31 | def list_my_comment(request):
32 | if request.method == 'GET':
33 | userId = request.GET.get("userId", None)
34 | order = request.GET.get("order", 'recent')
35 |
36 | if userId:
37 | if order == 'recent':
38 | orderBy = '-comment_time'
39 | else:
40 | orderBy = '-like_count'
41 |
42 | comments = Comment.objects.select_related("thing").filter(user=userId).order_by(orderBy)
43 | # print(comments)
44 | serializer = CommentSerializer(comments, many=True)
45 | return APIResponse(code=0, msg='查询成功', data=serializer.data)
46 | else:
47 | return APIResponse(code=1, msg='userId不能为空')
48 |
49 | @api_view(['POST'])
50 | def create(request):
51 | serializer = CommentSerializer(data=request.data)
52 | if serializer.is_valid():
53 | serializer.save()
54 | return APIResponse(code=0, msg='创建成功', data=serializer.data)
55 | else:
56 | print(serializer.errors)
57 |
58 | return APIResponse(code=1, msg='创建失败')
59 |
60 |
61 | @api_view(['POST'])
62 | def delete(request):
63 | try:
64 | ids = request.GET.get('ids')
65 | ids_arr = ids.split(',')
66 | Comment.objects.filter(id__in=ids_arr).delete()
67 | except Comment.DoesNotExist:
68 | return APIResponse(code=1, msg='对象不存在')
69 |
70 | return APIResponse(code=0, msg='删除成功')
71 |
72 |
73 | @api_view(['POST'])
74 | def like(request):
75 | try:
76 | commentId = request.GET.get('commentId')
77 | comment = Comment.objects.get(pk=commentId)
78 | comment.like_count += 1
79 | comment.save()
80 | except Comment.DoesNotExist:
81 | return APIResponse(code=1, msg='对象不存在')
82 |
83 | return APIResponse(code=0, msg='推荐成功')
84 |
--------------------------------------------------------------------------------
/web/src/views/index/modal/add-address.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
99 |
100 |
103 |
--------------------------------------------------------------------------------
/web/src/views/admin/op-log.vue:
--------------------------------------------------------------------------------
1 |
2 |
30 |
31 |
32 |
114 |
115 |
131 |
--------------------------------------------------------------------------------