├── .gitignore ├── Readme.md ├── doc └── python_shop.docx ├── python_shop.sql ├── server ├── .DS_Store ├── manage.py ├── myapp │ ├── .DS_Store │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── auth │ │ ├── .DS_Store │ │ ├── __init__.py │ │ └── authentication.py │ ├── handler.py │ ├── middlewares │ │ ├── .DS_Store │ │ ├── LogMiddleware.py │ │ └── __init__.py │ ├── models.py │ ├── permission │ │ ├── .DS_Store │ │ ├── __init__.py │ │ └── permission.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ ├── utils.py │ └── views │ │ ├── .DS_Store │ │ ├── __init__.py │ │ └── index │ │ ├── __init__.py │ │ ├── address.py │ │ ├── classification.py │ │ ├── comment.py │ │ ├── notice.py │ │ ├── order.py │ │ ├── tag.py │ │ ├── thing.py │ │ └── user.py ├── readme.md ├── requirements.txt ├── server │ ├── .DS_Store │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── upload │ ├── .DS_Store │ ├── 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 │ ├── cover │ │ ├── 1.jpeg │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 11.jpg │ │ ├── 12.jpg │ │ ├── 13.jpg │ │ ├── 14.jpg │ │ ├── 15.jpg │ │ ├── 16.jpg │ │ ├── 1672749055571.jpeg │ │ ├── 1674044230851.jpeg │ │ ├── 1676186518276.jpeg │ │ ├── 1676186872895.png │ │ ├── 1676186935002.png │ │ ├── 1676188277099.png │ │ ├── 1676188355688.png │ │ ├── 1676381084256.png │ │ ├── 1676381091144.png │ │ ├── 1676381097051.png │ │ ├── 1676381103032.png │ │ ├── 1676381110015.png │ │ ├── 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 │ │ ├── 1679056528013.png │ │ ├── 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 │ │ ├── 17.jpg │ │ ├── 18.jpg │ │ ├── 19.jpg │ │ ├── 2.jpg │ │ ├── 20.jpg │ │ ├── 21.jpg │ │ ├── 22.jpg │ │ ├── 23.jpg │ │ ├── 24.jpg │ │ ├── 25.jpg │ │ ├── 26.jpg │ │ ├── 27.jpg │ │ ├── 28.jpg │ │ ├── 29.jpg │ │ ├── 3.jpg │ │ ├── 30.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg │ └── img │ │ ├── Wechat.jpeg │ │ ├── a.png │ │ ├── b.png │ │ └── weixin.png └── 表结构.png ├── web ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── README.md ├── build │ ├── build.js │ ├── check-versions.js │ ├── logo.png │ ├── utils.js │ ├── vue-loader.conf.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── config │ ├── dev.env.js │ ├── index.js │ ├── prod.env.js │ └── test.env.js ├── index.html ├── jsconfig.json ├── package-lock.json ├── package.json ├── src │ ├── App.vue │ ├── api │ │ ├── admin │ │ │ ├── ad.js │ │ │ ├── banner.js │ │ │ ├── classification.js │ │ │ ├── comment.js │ │ │ ├── error-log.js │ │ │ ├── login-log.js │ │ │ ├── notice.js │ │ │ ├── op-log.js │ │ │ ├── order.js │ │ │ ├── overview.js │ │ │ ├── role.js │ │ │ ├── tag.js │ │ │ ├── thing.js │ │ │ └── user.js │ │ └── index │ │ │ ├── address.js │ │ │ ├── classification.js │ │ │ ├── comment.js │ │ │ ├── notice.js │ │ │ ├── order.js │ │ │ ├── tag.js │ │ │ ├── thing.js │ │ │ └── user.js │ ├── assets │ │ └── images │ │ │ ├── add.svg │ │ │ ├── address-right-icon.svg │ │ │ ├── ali-pay-icon.svg │ │ │ ├── avatar.jpg │ │ │ ├── cart-icon.svg │ │ │ ├── clear-search.svg │ │ │ ├── code-icon.svg │ │ │ ├── delete-icon.svg │ │ │ ├── ebook-download-icon.svg │ │ │ ├── front-logo.png │ │ │ ├── login.png │ │ │ ├── logo.png │ │ │ ├── mail-icon.svg │ │ │ ├── message-icon.svg │ │ │ ├── order-address-icon.svg │ │ │ ├── order-icon.svg │ │ │ ├── order-point-icon.svg │ │ │ ├── order-thing-icon.svg │ │ │ ├── pwd-hidden.svg │ │ │ ├── pwd-icon.svg │ │ │ ├── read-online-icon.svg │ │ │ ├── recommend-hover.svg │ │ │ ├── register-name.svg │ │ │ ├── search-icon.svg │ │ │ ├── searchIcon.svg │ │ │ ├── setting-card-icon.svg │ │ │ ├── setting-icon.svg │ │ │ ├── setting-msg-icon.svg │ │ │ ├── setting-push-icon.svg │ │ │ ├── setting-safe-icon.svg │ │ │ ├── share-icon.svg │ │ │ ├── tel-icon.svg │ │ │ ├── want-read-hover.svg │ │ │ ├── wb-share.svg │ │ │ └── wx-pay-icon.svg │ ├── components │ │ └── Dialog.js │ ├── core │ │ └── bootstrap.js │ ├── main.js │ ├── permission.js │ ├── router │ │ └── index.js │ ├── store │ │ ├── constants.js │ │ ├── index.js │ │ └── modules │ │ │ └── user.js │ ├── style │ │ ├── _var.less │ │ ├── index.less │ │ └── scrollbar.less │ ├── utils │ │ ├── global.js │ │ ├── request.js │ │ └── util.js │ └── views │ │ ├── admin │ │ ├── ad.vue │ │ ├── admin-login.vue │ │ ├── banner.vue │ │ ├── classification.vue │ │ ├── comment.vue │ │ ├── components │ │ │ ├── header.vue │ │ │ └── siderBar.vue │ │ ├── error-log.vue │ │ ├── layout │ │ │ └── adminLayout.vue │ │ ├── login-log.vue │ │ ├── model │ │ │ ├── edit-ad.vue │ │ │ ├── edit-banner.vue │ │ │ ├── edit-classification.vue │ │ │ ├── edit-comment.vue │ │ │ ├── edit-notice.vue │ │ │ ├── edit-order.vue │ │ │ ├── edit-password.vue │ │ │ ├── edit-role.vue │ │ │ ├── edit-tag.vue │ │ │ ├── edit-thing.vue │ │ │ └── edit-user.vue │ │ ├── notice.vue │ │ ├── op-log.vue │ │ ├── order.vue │ │ ├── overview.vue │ │ ├── role.vue │ │ ├── sys-info.vue │ │ ├── tag.vue │ │ ├── thing.vue │ │ └── user.vue │ │ └── index │ │ ├── components │ │ ├── content.vue │ │ ├── footer.vue │ │ ├── header.vue │ │ └── search-content-view.vue │ │ ├── confirm.vue │ │ ├── detail.vue │ │ ├── index.vue │ │ ├── login.vue │ │ ├── modal │ │ ├── add-address.vue │ │ └── select-address.vue │ │ ├── pay.vue │ │ ├── portal.vue │ │ ├── register.vue │ │ ├── search.vue │ │ ├── user.vue │ │ └── user │ │ ├── address-view.vue │ │ ├── collect-thing-view.vue │ │ ├── comment-view.vue │ │ ├── fans-view.vue │ │ ├── follow-view.vue │ │ ├── message-view.vue │ │ ├── mine-infos-view.vue │ │ ├── modal │ │ └── edit-address.vue │ │ ├── order-view.vue │ │ ├── push-view.vue │ │ ├── score-view.vue │ │ ├── security-view.vue │ │ ├── userinfo-edit-view.vue │ │ └── wish-thing-view.vue ├── static │ └── .gitkeep ├── test │ └── unit │ │ ├── .eslintrc │ │ └── specs │ │ └── HelloWorld.spec.js ├── vue.config.js └── yarn.lock └── 作者简介.md /.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 -------------------------------------------------------------------------------- /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 | ![](https://raw.githubusercontent.com/geeeeeeeek/shop/master/server/upload/img/a.png) 73 | 74 | 75 | 后台页面 76 | 77 | ![](https://raw.githubusercontent.com/geeeeeeeek/shop/master/server/upload/img/b.png) 78 | 79 | 80 | 81 | ### 参考论文 82 | 83 | [点击查看](doc/python_shop.docx) 84 | 85 | ### 付费咨询 86 | 87 | 微信(lengqin1024) 88 | 89 | 90 | 91 | ### 打赏作者 92 | 93 | ![](https://raw.githubusercontent.com/geeeeeeeek/shop/master/server/upload/img/Wechat.jpeg) 94 | 95 | -------------------------------------------------------------------------------- /doc/python_shop.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/doc/python_shop.docx -------------------------------------------------------------------------------- /server/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/.DS_Store -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /server/myapp/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/myapp/.DS_Store -------------------------------------------------------------------------------- /server/myapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/myapp/__init__.py -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /server/myapp/auth/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/myapp/auth/.DS_Store -------------------------------------------------------------------------------- /server/myapp/auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/myapp/auth/__init__.py -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /server/myapp/middlewares/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/myapp/middlewares/.DS_Store -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /server/myapp/middlewares/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/myapp/middlewares/__init__.py -------------------------------------------------------------------------------- /server/myapp/permission/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/myapp/permission/.DS_Store -------------------------------------------------------------------------------- /server/myapp/permission/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/myapp/permission/__init__.py -------------------------------------------------------------------------------- /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/myapp/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /server/myapp/views/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/myapp/views/.DS_Store -------------------------------------------------------------------------------- /server/myapp/views/__init__.py: -------------------------------------------------------------------------------- 1 | from myapp.views.admin import * 2 | from myapp.views.index import * 3 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/server/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/server/.DS_Store -------------------------------------------------------------------------------- /server/server/__init__.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | pymysql.install_as_MySQLdb() 3 | 4 | print("===============install pymysql==============") -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/upload/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/.DS_Store -------------------------------------------------------------------------------- /server/upload/ad/1674045266113.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/ad/1674045266113.jpeg -------------------------------------------------------------------------------- /server/upload/ad/1674045282581.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/ad/1674045282581.jpeg -------------------------------------------------------------------------------- /server/upload/ad/1674045308177.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/ad/1674045308177.png -------------------------------------------------------------------------------- /server/upload/ad/1674045324510.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/ad/1674045324510.jpeg -------------------------------------------------------------------------------- /server/upload/avatar/1676553050529.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/avatar/1676553050529.png -------------------------------------------------------------------------------- /server/upload/avatar/1676553366217.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/avatar/1676553366217.png -------------------------------------------------------------------------------- /server/upload/avatar/1676553498600.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/avatar/1676553498600.jpeg -------------------------------------------------------------------------------- /server/upload/avatar/1676553815688.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/avatar/1676553815688.jpeg -------------------------------------------------------------------------------- /server/upload/avatar/1677240189427.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/avatar/1677240189427.png -------------------------------------------------------------------------------- /server/upload/avatar/1677982820781.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/avatar/1677982820781.jpeg -------------------------------------------------------------------------------- /server/upload/avatar/1679146350134.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/avatar/1679146350134.jpeg -------------------------------------------------------------------------------- /server/upload/banner/1673963977440.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/banner/1673963977440.jpeg -------------------------------------------------------------------------------- /server/upload/banner/1673964384835.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/banner/1673964384835.png -------------------------------------------------------------------------------- /server/upload/banner/1673964652167.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/banner/1673964652167.jpeg -------------------------------------------------------------------------------- /server/upload/banner/1673965110189.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/banner/1673965110189.jpeg -------------------------------------------------------------------------------- /server/upload/banner/1673965198155.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/banner/1673965198155.jpeg -------------------------------------------------------------------------------- /server/upload/banner/1673965389141.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/banner/1673965389141.jpeg -------------------------------------------------------------------------------- /server/upload/banner/1673965574311.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/banner/1673965574311.png -------------------------------------------------------------------------------- /server/upload/banner/1673965709533.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/banner/1673965709533.jpeg -------------------------------------------------------------------------------- /server/upload/banner/1673965718720.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/banner/1673965718720.png -------------------------------------------------------------------------------- /server/upload/banner/1673965728690.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/banner/1673965728690.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1.jpg -------------------------------------------------------------------------------- /server/upload/cover/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/10.jpg -------------------------------------------------------------------------------- /server/upload/cover/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/11.jpg -------------------------------------------------------------------------------- /server/upload/cover/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/12.jpg -------------------------------------------------------------------------------- /server/upload/cover/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/13.jpg -------------------------------------------------------------------------------- /server/upload/cover/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/14.jpg -------------------------------------------------------------------------------- /server/upload/cover/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/15.jpg -------------------------------------------------------------------------------- /server/upload/cover/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/16.jpg -------------------------------------------------------------------------------- /server/upload/cover/1672749055571.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1672749055571.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1674044230851.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1674044230851.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1676186518276.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1676186518276.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1676186872895.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1676186872895.png -------------------------------------------------------------------------------- /server/upload/cover/1676186935002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1676186935002.png -------------------------------------------------------------------------------- /server/upload/cover/1676188277099.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1676188277099.png -------------------------------------------------------------------------------- /server/upload/cover/1676188355688.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1676188355688.png -------------------------------------------------------------------------------- /server/upload/cover/1676381084256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1676381084256.png -------------------------------------------------------------------------------- /server/upload/cover/1676381091144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1676381091144.png -------------------------------------------------------------------------------- /server/upload/cover/1676381097051.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1676381097051.png -------------------------------------------------------------------------------- /server/upload/cover/1676381103032.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1676381103032.png -------------------------------------------------------------------------------- /server/upload/cover/1676381110015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1676381110015.png -------------------------------------------------------------------------------- /server/upload/cover/1677500674281.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677500674281.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677501266461.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677501266461.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677501470234.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677501470234.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677501544737.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677501544737.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505180730.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505180730.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505298772.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505298772.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505357042.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505357042.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505364969.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505364969.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505380921.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505380921.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505393025.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505393025.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505410960.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505410960.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505421920.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505421920.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505436478.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505436478.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505452753.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505452753.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505579480.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505579480.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505616285.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505616285.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505626565.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505626565.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505637425.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505637425.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505648826.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505648826.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505659291.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505659291.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505667178.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505667178.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505685641.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505685641.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505695894.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505695894.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505706333.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505706333.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505876732.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505876732.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505884200.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505884200.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505890616.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505890616.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505897079.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505897079.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505910282.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505910282.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505919134.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505919134.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505928898.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505928898.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505937048.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505937048.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505945207.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505945207.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677505953782.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677505953782.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677588447622.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677588447622.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1677677497401.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1677677497401.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1678529114670.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1678529114670.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679056479437.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679056479437.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679056528013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679056528013.png -------------------------------------------------------------------------------- /server/upload/cover/1679056561868.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679056561868.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679056587496.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679056587496.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679058036014.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679058036014.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679058043365.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679058043365.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679229610791.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679229610791.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679229780971.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679229780971.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679229853940.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679229853940.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679229963230.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679229963230.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679230045590.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679230045590.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679230092657.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679230092657.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679230147996.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679230147996.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679230364390.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679230364390.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679230543572.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679230543572.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679230586243.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679230586243.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679230641879.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679230641879.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679230894621.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679230894621.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679230935716.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679230935716.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679230989243.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679230989243.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679231022326.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679231022326.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679231052822.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679231052822.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679231084420.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679231084420.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679231113572.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679231113572.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679231151929.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679231151929.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679231184020.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679231184020.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679231221940.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679231221940.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679231465845.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679231465845.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232418133.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232418133.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232448857.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232448857.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232480948.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232480948.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232514230.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232514230.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232543082.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232543082.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232587234.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232587234.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232615578.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232615578.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232650073.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232650073.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232676818.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232676818.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232717023.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232717023.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679232756075.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679232756075.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315151478.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315151478.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315191893.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315191893.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315240787.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315240787.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315276060.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315276060.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315310720.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315310720.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315343720.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315343720.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315365210.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315365210.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315396953.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315396953.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315437571.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315437571.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315478327.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315478327.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315749022.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315749022.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315761797.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315761797.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315803245.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315803245.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315842977.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315842977.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315883620.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315883620.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315915467.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315915467.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315954931.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315954931.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679315985852.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679315985852.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316037517.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316037517.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316072493.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316072493.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316422812.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316422812.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316453474.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316453474.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316484842.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316484842.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316513693.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316513693.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316533369.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316533369.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316566135.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316566135.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316605104.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316605104.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316637185.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316637185.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316666891.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316666891.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679316698087.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679316698087.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403034316.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403034316.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403102225.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403102225.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403138846.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403138846.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403158073.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403158073.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403193320.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403193320.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403239138.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403239138.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403285129.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403285129.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403331202.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403331202.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403370669.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403370669.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403403756.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403403756.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403503106.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403503106.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403631942.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403631942.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403697740.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403697740.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679403736341.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679403736341.jpeg -------------------------------------------------------------------------------- /server/upload/cover/1679488092121.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/1679488092121.jpeg -------------------------------------------------------------------------------- /server/upload/cover/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/17.jpg -------------------------------------------------------------------------------- /server/upload/cover/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/18.jpg -------------------------------------------------------------------------------- /server/upload/cover/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/19.jpg -------------------------------------------------------------------------------- /server/upload/cover/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/2.jpg -------------------------------------------------------------------------------- /server/upload/cover/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/20.jpg -------------------------------------------------------------------------------- /server/upload/cover/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/21.jpg -------------------------------------------------------------------------------- /server/upload/cover/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/22.jpg -------------------------------------------------------------------------------- /server/upload/cover/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/23.jpg -------------------------------------------------------------------------------- /server/upload/cover/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/24.jpg -------------------------------------------------------------------------------- /server/upload/cover/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/25.jpg -------------------------------------------------------------------------------- /server/upload/cover/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/26.jpg -------------------------------------------------------------------------------- /server/upload/cover/27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/27.jpg -------------------------------------------------------------------------------- /server/upload/cover/28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/28.jpg -------------------------------------------------------------------------------- /server/upload/cover/29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/29.jpg -------------------------------------------------------------------------------- /server/upload/cover/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/3.jpg -------------------------------------------------------------------------------- /server/upload/cover/30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/30.jpg -------------------------------------------------------------------------------- /server/upload/cover/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/4.jpg -------------------------------------------------------------------------------- /server/upload/cover/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/5.jpg -------------------------------------------------------------------------------- /server/upload/cover/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/6.jpg -------------------------------------------------------------------------------- /server/upload/cover/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/7.jpg -------------------------------------------------------------------------------- /server/upload/cover/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/8.jpg -------------------------------------------------------------------------------- /server/upload/cover/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/cover/9.jpg -------------------------------------------------------------------------------- /server/upload/img/Wechat.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/img/Wechat.jpeg -------------------------------------------------------------------------------- /server/upload/img/a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/img/a.png -------------------------------------------------------------------------------- /server/upload/img/b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/img/b.png -------------------------------------------------------------------------------- /server/upload/img/weixin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/upload/img/weixin.png -------------------------------------------------------------------------------- /server/表结构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/server/表结构.png -------------------------------------------------------------------------------- /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/.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/.eslintignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /config/ 3 | /dist/ 4 | /*.js 5 | /test/unit/coverage/ 6 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/web/build/logo.png -------------------------------------------------------------------------------- /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/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/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/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/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /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/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | web app 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /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/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/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | 30 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/assets/images/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/assets/images/address-right-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/src/assets/images/ali-pay-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/src/assets/images/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/web/src/assets/images/avatar.jpg -------------------------------------------------------------------------------- /web/src/assets/images/cart-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /web/src/assets/images/clear-search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/assets/images/code-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/assets/images/delete-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /web/src/assets/images/ebook-download-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/assets/images/front-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/web/src/assets/images/front-logo.png -------------------------------------------------------------------------------- /web/src/assets/images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/web/src/assets/images/login.png -------------------------------------------------------------------------------- /web/src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/web/src/assets/images/logo.png -------------------------------------------------------------------------------- /web/src/assets/images/mail-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/assets/images/message-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /web/src/assets/images/order-address-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/assets/images/order-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/src/assets/images/order-point-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/assets/images/order-thing-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /web/src/assets/images/pwd-hidden.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /web/src/assets/images/pwd-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/assets/images/read-online-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /web/src/assets/images/recommend-hover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /web/src/assets/images/register-name.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /web/src/assets/images/search-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/src/assets/images/searchIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/src/assets/images/setting-card-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /web/src/assets/images/setting-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/src/assets/images/setting-msg-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/src/assets/images/setting-safe-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/assets/images/share-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/src/assets/images/tel-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/src/assets/images/want-read-hover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /web/src/assets/images/wb-share.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /web/src/assets/images/wx-pay-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 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/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/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/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/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/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/src/style/index.less: -------------------------------------------------------------------------------- 1 | @import "~ant-design-vue/dist/antd.less"; 2 | @import "scrollbar.less"; 3 | @import "_var.less"; 4 | 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/components/header.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 31 | 62 | -------------------------------------------------------------------------------- /web/src/views/admin/error-log.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 106 | 107 | 123 | -------------------------------------------------------------------------------- /web/src/views/admin/layout/adminLayout.vue: -------------------------------------------------------------------------------- 1 | 17 | 32 | 54 | -------------------------------------------------------------------------------- /web/src/views/admin/login-log.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 93 | 94 | 110 | -------------------------------------------------------------------------------- /web/src/views/admin/model/edit-classification.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 88 | 89 | 92 | -------------------------------------------------------------------------------- /web/src/views/admin/model/edit-comment.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 67 | 68 | 71 | -------------------------------------------------------------------------------- /web/src/views/admin/model/edit-notice.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 92 | 93 | 96 | -------------------------------------------------------------------------------- /web/src/views/admin/model/edit-password.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 77 | 78 | 81 | -------------------------------------------------------------------------------- /web/src/views/admin/model/edit-role.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 84 | 85 | 88 | -------------------------------------------------------------------------------- /web/src/views/admin/model/edit-tag.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 79 | 80 | 83 | -------------------------------------------------------------------------------- /web/src/views/admin/sys-info.vue: -------------------------------------------------------------------------------- 1 | 55 | 56 | 84 | 85 | 103 | -------------------------------------------------------------------------------- /web/src/views/index/components/footer.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 29 | 30 | 84 | -------------------------------------------------------------------------------- /web/src/views/index/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | -------------------------------------------------------------------------------- /web/src/views/index/portal.vue: -------------------------------------------------------------------------------- 1 | 8 | 25 | 28 | -------------------------------------------------------------------------------- /web/src/views/index/search.vue: -------------------------------------------------------------------------------- 1 | 10 | 28 | 35 | -------------------------------------------------------------------------------- /web/src/views/index/user.vue: -------------------------------------------------------------------------------- 1 | 19 | 37 | 59 | -------------------------------------------------------------------------------- /web/src/views/index/user/fans-view.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 27 | 104 | -------------------------------------------------------------------------------- /web/src/views/index/user/follow-view.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 28 | 105 | -------------------------------------------------------------------------------- /web/src/views/index/user/score-view.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 41 | 74 | -------------------------------------------------------------------------------- /web/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geeeeeeeek/python_shop/facf1bb1a590466c0d631657ff26d5c14412ea98/web/static/.gitkeep -------------------------------------------------------------------------------- /web/test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | }, 4 | "globals": { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /作者简介.md: -------------------------------------------------------------------------------- 1 | ### 源码地址 2 | 3 | https://github.com/geeeeeeeek/python_shop 4 | 5 | ### 联系方式 6 | 7 | - lengqin1024(微信) 8 | - 285126081(QQ) --------------------------------------------------------------------------------