├── book_shop ├── __init__.py ├── wsgi.py ├── urls.py └── settings.py ├── app ├── migrations │ ├── __init__.py │ ├── 0002_goods_add_datetime.py │ ├── 0004_auto_20190425_0251.py │ ├── 0003_auto_20190423_0835.py │ └── 0001_initial.py ├── templatetags │ ├── __init__.py │ └── tags.py ├── __init__.py ├── tests.py ├── apps.py ├── admin.py ├── utils.py ├── urls.py ├── models.py └── views.py ├── db.sqlite3 ├── media ├── 主页.png ├── 个人中心.png ├── 书籍详情页.png ├── 订单页面.png ├── 购物车页.png ├── goods │ ├── 简爱.jpg │ ├── 动物博物馆.jpg │ └── python.jpg └── images │ └── 简爱_20190423064841_720.jpg ├── static ├── images │ ├── book.jpg │ ├── down.png │ ├── fruit.jpg │ ├── goods.jpg │ ├── icons.png │ ├── logo.png │ ├── slide.jpg │ ├── slide.png │ ├── goods02.jpg │ ├── icons02.png │ ├── left_bg.jpg │ ├── logo02.png │ ├── slide02.jpg │ ├── slide02.png │ ├── slide03.jpg │ ├── slide03.png │ ├── slide04.jpg │ ├── pay_icons.png │ ├── shop_cart.png │ ├── goods_detail.jpg │ ├── interval_line.png │ ├── login_banner.png │ ├── goods │ │ ├── goods001.jpg │ │ ├── goods002.jpg │ │ ├── goods003.jpg │ │ ├── goods004.jpg │ │ ├── goods005.jpg │ │ ├── goods006.jpg │ │ ├── goods007.jpg │ │ ├── goods008.jpg │ │ ├── goods009.jpg │ │ ├── goods010.jpg │ │ ├── goods011.jpg │ │ ├── goods012.jpg │ │ ├── goods013.jpg │ │ ├── goods014.jpg │ │ ├── goods015.jpg │ │ ├── goods016.jpg │ │ ├── goods017.jpg │ │ ├── goods018.jpg │ │ ├── goods019.jpg │ │ ├── goods020.jpg │ │ └── goods021.jpg │ └── register_banner.png ├── css │ ├── reset.css │ └── main.css └── js │ ├── slide.js │ ├── register.js │ ├── jquery.cookie.js │ └── jquery-ui.min.js ├── DjangoUeditor3-master.zip ├── manage.py ├── templates ├── app │ ├── user │ │ ├── base_user.html │ │ ├── UserAddr.html │ │ ├── CreateOrder.html │ │ ├── UserOrder.html │ │ ├── UserInfo.html │ │ └── UserCar.html │ ├── login.html │ ├── register.html │ ├── index.html │ ├── base_site.html │ ├── shop_list.html │ └── detail.html └── Base.html └── README.md /book_shop/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- 1 | # import pymysql 2 | # 3 | # pymysql.install_as_MySQLdb() 4 | -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/db.sqlite3 -------------------------------------------------------------------------------- /media/主页.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/media/主页.png -------------------------------------------------------------------------------- /app/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /media/个人中心.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/media/个人中心.png -------------------------------------------------------------------------------- /media/书籍详情页.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/media/书籍详情页.png -------------------------------------------------------------------------------- /media/订单页面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/media/订单页面.png -------------------------------------------------------------------------------- /media/购物车页.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/media/购物车页.png -------------------------------------------------------------------------------- /media/goods/简爱.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/media/goods/简爱.jpg -------------------------------------------------------------------------------- /media/goods/动物博物馆.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/media/goods/动物博物馆.jpg -------------------------------------------------------------------------------- /media/goods/python.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/media/goods/python.jpg -------------------------------------------------------------------------------- /static/images/book.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/book.jpg -------------------------------------------------------------------------------- /static/images/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/down.png -------------------------------------------------------------------------------- /static/images/fruit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/fruit.jpg -------------------------------------------------------------------------------- /static/images/goods.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods.jpg -------------------------------------------------------------------------------- /static/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/icons.png -------------------------------------------------------------------------------- /static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/logo.png -------------------------------------------------------------------------------- /static/images/slide.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/slide.jpg -------------------------------------------------------------------------------- /static/images/slide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/slide.png -------------------------------------------------------------------------------- /DjangoUeditor3-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/DjangoUeditor3-master.zip -------------------------------------------------------------------------------- /static/images/goods02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods02.jpg -------------------------------------------------------------------------------- /static/images/icons02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/icons02.png -------------------------------------------------------------------------------- /static/images/left_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/left_bg.jpg -------------------------------------------------------------------------------- /static/images/logo02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/logo02.png -------------------------------------------------------------------------------- /static/images/slide02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/slide02.jpg -------------------------------------------------------------------------------- /static/images/slide02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/slide02.png -------------------------------------------------------------------------------- /static/images/slide03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/slide03.jpg -------------------------------------------------------------------------------- /static/images/slide03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/slide03.png -------------------------------------------------------------------------------- /static/images/slide04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/slide04.jpg -------------------------------------------------------------------------------- /app/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AppConfig(AppConfig): 5 | name = 'app' 6 | -------------------------------------------------------------------------------- /static/images/pay_icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/pay_icons.png -------------------------------------------------------------------------------- /static/images/shop_cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/shop_cart.png -------------------------------------------------------------------------------- /static/images/goods_detail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods_detail.jpg -------------------------------------------------------------------------------- /static/images/interval_line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/interval_line.png -------------------------------------------------------------------------------- /static/images/login_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/login_banner.png -------------------------------------------------------------------------------- /static/images/goods/goods001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods001.jpg -------------------------------------------------------------------------------- /static/images/goods/goods002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods002.jpg -------------------------------------------------------------------------------- /static/images/goods/goods003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods003.jpg -------------------------------------------------------------------------------- /static/images/goods/goods004.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods004.jpg -------------------------------------------------------------------------------- /static/images/goods/goods005.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods005.jpg -------------------------------------------------------------------------------- /static/images/goods/goods006.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods006.jpg -------------------------------------------------------------------------------- /static/images/goods/goods007.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods007.jpg -------------------------------------------------------------------------------- /static/images/goods/goods008.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods008.jpg -------------------------------------------------------------------------------- /static/images/goods/goods009.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods009.jpg -------------------------------------------------------------------------------- /static/images/goods/goods010.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods010.jpg -------------------------------------------------------------------------------- /static/images/goods/goods011.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods011.jpg -------------------------------------------------------------------------------- /static/images/goods/goods012.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods012.jpg -------------------------------------------------------------------------------- /static/images/goods/goods013.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods013.jpg -------------------------------------------------------------------------------- /static/images/goods/goods014.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods014.jpg -------------------------------------------------------------------------------- /static/images/goods/goods015.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods015.jpg -------------------------------------------------------------------------------- /static/images/goods/goods016.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods016.jpg -------------------------------------------------------------------------------- /static/images/goods/goods017.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods017.jpg -------------------------------------------------------------------------------- /static/images/goods/goods018.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods018.jpg -------------------------------------------------------------------------------- /static/images/goods/goods019.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods019.jpg -------------------------------------------------------------------------------- /static/images/goods/goods020.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods020.jpg -------------------------------------------------------------------------------- /static/images/goods/goods021.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/goods/goods021.jpg -------------------------------------------------------------------------------- /static/images/register_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/static/images/register_banner.png -------------------------------------------------------------------------------- /media/images/简爱_20190423064841_720.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaojie0202/BookShop/HEAD/media/images/简爱_20190423064841_720.jpg -------------------------------------------------------------------------------- /book_shop/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for book_shop 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/2.2/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', 'book_shop.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /app/migrations/0002_goods_add_datetime.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2 on 2019-04-23 07:12 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='goods', 15 | name='add_datetime', 16 | field=models.DateTimeField(auto_now=True, verbose_name='添加时间'), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /app/templatetags/tags.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.utils.safestring import mark_safe 3 | 4 | register = template.Library() 5 | 6 | 7 | @register.simple_tag 8 | def filter_handel(filter_data, t): 9 | ss = '' 10 | for k, v in filter_data.items(): 11 | if k != t: 12 | ss += '&%s=%s' % (k, v) 13 | return ss 14 | 15 | @register.simple_tag 16 | def chengfa(*args): 17 | b = 1 18 | 19 | for a in args: 20 | b = b * a 21 | print(args) 22 | return b 23 | -------------------------------------------------------------------------------- /app/migrations/0004_auto_20190425_0251.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2 on 2019-04-25 02:51 2 | 3 | from django.db import migrations, models 4 | import django.utils.timezone 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('app', '0003_auto_20190423_0835'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='goods', 16 | name='add_datetime', 17 | field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='添加时间'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /static/css/reset.css: -------------------------------------------------------------------------------- 1 | /* 把标签默认的间距设为0 */ 2 | body,ul,ol,p,h1,h2,h3,h4,h5,h6,dl,dd,select,input,textarea,form{margin:0;padding:0} 3 | 4 | /* 让h标签文字大小继承body的文字设置 */ 5 | h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;} 6 | 7 | /* 去掉列表默认的图标 */ 8 | ul,ol{list-style:none;} 9 | 10 | /* 去掉em默认的斜体 */ 11 | em{font-style: normal;} 12 | 13 | /* 去掉a标签默认的下划线 */ 14 | a{text-decoration:none;} 15 | 16 | 17 | /* 去掉加链接时产生的框线 */ 18 | img{border:0;} 19 | 20 | /* 清除浮动 */ 21 | .clearfix:before,.clearfix:after{content:"";display:table} 22 | .clearfix:after{clear:both;} 23 | .clearfix{zoom:1} 24 | 25 | /* 浮动 */ 26 | .fl{float:left} 27 | .fr{float:right} -------------------------------------------------------------------------------- /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 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'book_shop.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /app/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from app import models 3 | 4 | 5 | # Register your models here. 6 | 7 | 8 | @admin.register(models.Goods) 9 | class GoodsAdmin(admin.ModelAdmin): 10 | list_display = ['name', 'price', 'unite'] 11 | 12 | 13 | @admin.register(models.OrderInfo) 14 | class OrderInfoAdmin(admin.ModelAdmin): 15 | list_display = ['order_id', 'user', 'order_status', 'total_price'] 16 | search_fields = ['order_id'] 17 | list_editable = ['order_status'] 18 | 19 | 20 | @admin.register(models.OrderGoods) 21 | class OrderGoodsAdmin(admin.ModelAdmin): 22 | list_display = ['get_order_id', 'sku', 'count'] 23 | 24 | 25 | admin.site.site_header = '书籍屋' 26 | admin.site.site_title = '书籍屋' 27 | -------------------------------------------------------------------------------- /templates/app/user/base_user.html: -------------------------------------------------------------------------------- 1 | {% extends 'app/base_site.html' %} 2 | {% block meta %}{% endblock %} 3 | {% block title %}{% endblock title %} 4 | {% block style %}{% endblock style %} 5 | 6 | 7 | {% block user_base %} 8 | 9 | 20 | 21 | {% block contenr %}{% endblock contenr %} 22 | {% endblock user_base %} 23 | 24 | 25 | {% block script %}{% endblock script %} -------------------------------------------------------------------------------- /book_shop/urls.py: -------------------------------------------------------------------------------- 1 | """book_shop URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.2/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.contrib import admin 17 | from django.urls import path, re_path, include 18 | from django.views.static import serve 19 | from book_shop.settings import MEDIA_ROOT 20 | 21 | urlpatterns = [ 22 | path('admin/', admin.site.urls), 23 | path('ueditor/', include('DjangoUeditor.urls')), 24 | re_path(r'^media/(?P.*)', serve, {"document_root": MEDIA_ROOT}), 25 | path('', include(('app.urls', 'app'), namespace='home')), 26 | ] 27 | -------------------------------------------------------------------------------- /app/utils.py: -------------------------------------------------------------------------------- 1 | from django.core.paginator import Paginator 2 | 3 | 4 | # 分页专用 5 | class CustomPaginator(Paginator): 6 | 7 | def __init__(self, current_page, per_pager_num, *args, **kwargs): 8 | ''' 9 | :param current_page: 当前页 10 | :param per_pager_num: 总共需要显示几页 11 | ''' 12 | self.current_page = int(current_page) 13 | self.per_pager_num = int(per_pager_num) 14 | super(CustomPaginator, self).__init__(*args, **kwargs) 15 | 16 | def pager_num_range(self): 17 | ''' 18 | :return: 返回一个列表,页面显示这些页码 19 | ''' 20 | if self.num_pages < self.per_pager_num: 21 | return range(1, self.num_pages + 1) 22 | part = int(self.per_pager_num / 2) 23 | if self.current_page <= part: 24 | return range(1, self.per_pager_num + 1) 25 | if (self.current_page + part) > self.num_pages: 26 | return range( 27 | self.num_pages - 28 | self.per_pager_num + 29 | 1, 30 | self.num_pages + 31 | 1) 32 | return range(self.current_page - part, self.current_page + part + 1) 33 | 34 | -------------------------------------------------------------------------------- /templates/Base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {% block meta %}{% endblock meta %} 7 | {% block title %}{% endblock title %} 8 | 9 | 10 | {% block style %}{% endblock style %} 11 | 12 | 13 | {% block body %}{% endblock body %} 14 | 15 | 16 | 17 | 32 | {% block script %}{% endblock script %} 33 | 34 | -------------------------------------------------------------------------------- /app/migrations/0003_auto_20190423_0835.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2 on 2019-04-23 08:35 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('app', '0002_goods_add_datetime'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AlterField( 17 | model_name='orderinfo', 18 | name='order_status', 19 | field=models.SmallIntegerField(choices=[(1, '待支付'), (2, '待发货'), (3, '待收货'), (4, '已完成')], default=1, verbose_name='订单状态'), 20 | ), 21 | migrations.CreateModel( 22 | name='History', 23 | fields=[ 24 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 25 | ('show_datetime', models.DateTimeField(auto_now=True, verbose_name='浏览时间')), 26 | ('good', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.Goods', verbose_name='商品')), 27 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='用户')), 28 | ], 29 | ), 30 | ] 31 | -------------------------------------------------------------------------------- /templates/app/login.html: -------------------------------------------------------------------------------- 1 | {% extends 'app/base_site.html' %} 2 | {% block meta %}{% endblock %} 3 | {% block title %}书籍屋-登陆{% endblock title %} 4 | {% block style %}{% endblock style %} 5 | 6 | {% block exclude_footer %} 7 |
8 | 9 |
10 | 11 |
12 | 34 |
35 | 36 | {% endblock exclude_footer %} 37 | 38 | 39 | {% block script %}{% endblock script %} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 书籍屋电商网站 2 | 3 | ## 开发环境 4 | python3.7 5 | ## 依赖环境 6 | pip install Django==2.1.5 7 | pip install PyMySQL==0.9.3 8 | 9 | ``` 10 | # 安装 DjangoUeditor3(百度的富文本编辑器) 11 | 下载 12 | https://github.com/twz915/DjangoUeditor3 13 | (已经下载到项目根目录DjangoUeditor3-master.zip) 14 | 安装 15 | pip install DjangoUeditor3-master.zip 16 | 17 | 中途可能遇到的问题 18 | 19 | File "。。。。/book_shop/venv/lib/python3.7/site-packages/django/forms/boundfield.py", line 93, in as_widget 20 | renderer=self.form.renderer, 21 | TypeError: render() got an unexpected keyword argument 'renderer' 22 | 23 | 注释掉报错的代码即可 24 | 25 | ``` 26 | ## 配置数据库为Mysql 27 | 28 | ``` 29 | # settings.py 30 | 31 | 找到配置信息 32 | 33 | DATABASES = { 34 | 'default': { 35 | 'ENGINE': 'django.db.backends.mysql', 36 | 'NAME': '数据库名字', 37 | 'USER': '数据库用户名', 38 | 'PASSWORD': '数据库密码', 39 | 'HOST': '127.0.0.1', 40 | 'PORT': '3306', 41 | } 42 | } 43 | 44 | # app/__init__.py 45 | 46 | 增加以下两句代码: 47 | 48 | import pymysql 49 | pymysql.install_as_MySQLdb() 50 | 51 | ``` 52 | >- 迁移操作 53 | python manage.py makemigrations 54 | python manage.py migrate 55 | 56 | ## 运行 57 | python manage.py runserver 58 | 59 | ## 项目展示 60 | ![](https://github.com/xiaojie0202/BookShop/blob/master/media/%E4%B8%BB%E9%A1%B5.png) 61 | ![](https://github.com/xiaojie0202/BookShop/blob/master/media/%E4%B8%AA%E4%BA%BA%E4%B8%AD%E5%BF%83.png) 62 | ![](https://github.com/xiaojie0202/BookShop/blob/master/media/%E4%B9%A6%E7%B1%8D%E8%AF%A6%E6%83%85%E9%A1%B5.png) 63 | ![](https://github.com/xiaojie0202/BookShop/blob/master/media/%E8%AE%A2%E5%8D%95%E9%A1%B5%E9%9D%A2.png) 64 | ![](https://github.com/xiaojie0202/BookShop/blob/master/media/%E8%B4%AD%E7%89%A9%E8%BD%A6%E9%A1%B5.png) -------------------------------------------------------------------------------- /app/urls.py: -------------------------------------------------------------------------------- 1 | """book_shop URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.2/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.urls import path 17 | from app import views 18 | 19 | urlpatterns = [ 20 | path('', views.index, name='index'), # 主页 21 | path('Shop', views.shop, name='shop'), # 商城 22 | path('detail/', views.detail, name='detail'), # 商城 23 | path('place_order', views.create_order, name='create_order'), # 创建订单 24 | path('login', views.acc_login, name='login'), # 登陆 25 | path('register', views.acc_register, name='register'), # 注册 26 | path('logout', views.acc_logout, name='logout'), # 注销 27 | path('UserInfo', views.user_info, name='user_info'), # 用户中心 28 | path('UserOrder', views.user_order, name='user_order'), # 个人订单 29 | path('UserAddr', views.user_addr, name='user_addr'), # 地址管理 30 | path('set_default_addr', views.set_default_addr), # 用户地址 31 | path('UserCar', views.user_car, name='user_car'), # 购物车 32 | path('add_cart', views.add_cart), # 添加购物车 33 | path('remove_cart', views.remove_cart), # 删除购物车商品 34 | path('pay', views.pay), # 支付 35 | path('receiving', views.receiving), # 确认收货 36 | ] 37 | -------------------------------------------------------------------------------- /templates/app/register.html: -------------------------------------------------------------------------------- 1 | {% extends 'app/base_site.html' %} 2 | {% block meta %}{% endblock %} 3 | {% block title %}书籍屋-注册{% endblock title %} 4 | {% block style %}{% endblock style %} 5 | 6 | {% block exclude_footer %} 7 |
8 |
9 | 10 |
读万卷书 · 行万里路
11 |
12 |
13 | 14 |
15 |
16 |

用户注册

17 | 登录 18 |
19 |
20 |
21 |
    22 |
  • 23 | 24 | 25 | 提示信息 26 |
  • 27 |
  • 28 | 29 | 30 | 提示信息 31 |
  • 32 |
  • 33 | 34 | 35 | 提示信息 36 |
  • 37 |
  • 38 | 39 | 40 | 提示信息 41 |
  • 42 |
  • 43 | 44 | 45 | 提示信息 46 |
  • 47 |
  • 48 | 49 |
  • 50 |
51 |
52 |
53 | 54 |
55 | 56 |
57 | 58 | {% endblock exclude_footer %} 59 | 60 | 61 | {% block script %} 62 | 63 | {% endblock script %} -------------------------------------------------------------------------------- /templates/app/index.html: -------------------------------------------------------------------------------- 1 | {% extends 'app/base_site.html' %} 2 | 3 | {% block meta %}{% endblock %} 4 | 5 | {% block title %}书籍屋-首页{% endblock title %} 6 | 7 | {% block style %} 8 | 9 | {% endblock style %} 10 | 11 | {% block contenr %} 12 |
13 |
14 |
    15 |
  • 幻灯片
  • 16 |
  • 幻灯片
  • 17 |
  • 幻灯片
  • 18 |
19 | 20 | 21 |
    22 |
    23 | 24 |
    25 | 26 |
    27 |
    28 |

    最火书籍

    29 | 查看更多 > 30 |
    31 | 32 |
    33 |
      34 | {% for book in hot_book_obj %} 35 |
    • 36 |

      {{ book.name }}

      37 | 38 |
      ¥ {{ book.price }}
      39 |
    • 40 | {% endfor %} 41 | 42 |
    43 |
    44 |
    45 | 46 |
    47 |
    48 |

    最新书籍

    49 |
    50 | 51 |
    52 |
      53 | {% for book in new_book_obj %} 54 |
    • 55 |

      {{ book.name }}

      56 | 57 |
      ¥ {{ book.price }}
      58 |
    • 59 | {% endfor %} 60 | 61 |
    62 |
    63 |
    64 | {% endblock contenr %} 65 | 66 | {% block script %} 67 | 82 | {% endblock script %} -------------------------------------------------------------------------------- /static/js/slide.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | var $slides = $('.slide_pics li'); 3 | var len = $slides.length; 4 | var nowli = 0; 5 | var prevli = 0; 6 | var $prev = $('.prev'); 7 | var $next = $('.next'); 8 | var ismove = false; 9 | var timer = null; 10 | $slides.not(':first').css({left:1200}); 11 | $slides.each(function(index, el) { 12 | var $li = $('
  • '); 13 | 14 | if(index==0) 15 | { 16 | $li.addClass('active'); 17 | } 18 | 19 | $li.appendTo($('.points')); 20 | }); 21 | $points = $('.points li'); 22 | timer = setInterval(autoplay,4000); 23 | 24 | $('.slide').mouseenter(function() { 25 | clearInterval(timer); 26 | }); 27 | 28 | $('.slide').mouseleave(function() { 29 | timer = setInterval(autoplay,4000); 30 | }); 31 | 32 | function autoplay(){ 33 | nowli++; 34 | move(); 35 | $points.eq(nowli).addClass('active').siblings().removeClass('active'); 36 | } 37 | 38 | $points.click(function(event) { 39 | if(ismove) 40 | { 41 | return; 42 | } 43 | nowli = $(this).index(); 44 | 45 | if(nowli==prevli) 46 | { 47 | return; 48 | } 49 | 50 | $(this).addClass('active').siblings().removeClass('active'); 51 | move(); 52 | 53 | }); 54 | 55 | $prev.click(function() { 56 | if(ismove) 57 | { 58 | return; 59 | } 60 | nowli--; 61 | move(); 62 | $points.eq(nowli).addClass('active').siblings().removeClass('active'); 63 | 64 | }); 65 | 66 | $next.click(function() { 67 | if(ismove) 68 | { 69 | return; 70 | } 71 | nowli++; 72 | move(); 73 | $points.eq(nowli).addClass('active').siblings().removeClass('active'); 74 | 75 | }); 76 | 77 | 78 | function move(){ 79 | 80 | ismove = true; 81 | 82 | if(nowli<0) 83 | { 84 | nowli=len-1; 85 | prevli = 0 86 | $slides.eq(nowli).css({left:-1200}); 87 | $slides.eq(nowli).animate({left:0},800,'easeOutExpo'); 88 | $slides.eq(prevli).animate({left:1200},800,'easeOutExpo',function(){ 89 | ismove = false; 90 | }); 91 | prevli=nowli; 92 | return; 93 | } 94 | 95 | if(nowli>len-1) 96 | { 97 | nowli = 0; 98 | prevli = len-1; 99 | $slides.eq(nowli).css({left:1200}); 100 | $slides.eq(nowli).animate({left:0},800,'easeOutExpo'); 101 | $slides.eq(prevli).animate({left:-1200},800,'easeOutExpo',function(){ 102 | ismove = false; 103 | }); 104 | prevli=nowli; 105 | return; 106 | } 107 | 108 | 109 | if(prevli 9 |
    10 |

    用户中心

    11 | 16 |
    17 |
    18 |

    收货地址

    19 |
    20 |
    21 | {% for addr in addr_obj %} 22 |
    23 | {{ addr.addr }} ({{ addr.receiver }} 收) {{ addr.phone }} 24 | 25 | {% if not addr.is_default %} 26 | 27 | {% else %} 28 | 默认地址 29 | {% endif %} 30 |
    31 | {% endfor %} 32 |
    33 |
    34 |

    编辑地址

    35 |
    36 |
    37 |
    38 | 39 | 40 |
    41 |
    42 | 43 | 44 |
    45 |
    46 | 47 | 48 |
    49 |
    50 | 51 | 52 |
    53 | 54 | 55 |
    56 |
    57 |
    58 | 59 | 60 | {% endblock contenr %} 61 | 62 | 63 | {% block script %} 64 | 81 | {% endblock script %} -------------------------------------------------------------------------------- /static/js/register.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | var error_name = false; 4 | var error_password = false; 5 | var error_check_password = false; 6 | var error_email = false; 7 | var error_check = false; 8 | 9 | 10 | $('#user_name').blur(function () { 11 | check_user_name(); 12 | }); 13 | 14 | $('#pwd').blur(function () { 15 | check_pwd(); 16 | }); 17 | 18 | $('#cpwd').blur(function () { 19 | check_cpwd(); 20 | }); 21 | 22 | $('#email').blur(function () { 23 | check_email(); 24 | }); 25 | 26 | $('#allow').click(function () { 27 | if ($(this).is(':checked')) { 28 | error_check = false; 29 | $(this).siblings('span').hide(); 30 | } else { 31 | error_check = true; 32 | $(this).siblings('span').html('请勾选同意'); 33 | $(this).siblings('span').show(); 34 | } 35 | }); 36 | 37 | 38 | function check_user_name() { 39 | var len = $('#user_name').val().length; 40 | if (len < 2 || len > 20) { 41 | $('#user_name').next().html('请输入2-20个字符的用户名') 42 | $('#user_name').next().show(); 43 | error_name = true; 44 | } else { 45 | $('#user_name').next().hide(); 46 | error_name = false; 47 | } 48 | } 49 | 50 | function check_pwd() { 51 | var len = $('#pwd').val().length; 52 | if (len < 8 || len > 20) { 53 | $('#pwd').next().html('密码最少8位,最长20位') 54 | $('#pwd').next().show(); 55 | error_password = true; 56 | } else { 57 | $('#pwd').next().hide(); 58 | error_password = false; 59 | } 60 | } 61 | 62 | 63 | function check_cpwd() { 64 | var pass = $('#pwd').val(); 65 | var cpass = $('#cpwd').val(); 66 | 67 | if (pass != cpass) { 68 | $('#cpwd').next().html('两次输入的密码不一致') 69 | $('#cpwd').next().show(); 70 | error_check_password = true; 71 | } else { 72 | $('#cpwd').next().hide(); 73 | error_check_password = false; 74 | } 75 | 76 | } 77 | 78 | function check_email() { 79 | $('#email').next().hide(); 80 | error_email = false; 81 | } 82 | 83 | 84 | $('#reg_form').submit(function () { 85 | check_user_name(); 86 | check_pwd(); 87 | check_cpwd(); 88 | check_email(); 89 | 90 | if (error_name == false && error_password == false && error_check_password == false && error_email == false && error_check == false) { 91 | console.log($('#reg_form').serialize()) 92 | $.ajax( 93 | { 94 | url: '/register', 95 | type: 'POST', 96 | data: $('#reg_form').serialize(), 97 | dataType: 'JSON', 98 | success: function (data) { 99 | console.log(data) 100 | if (data.status) { 101 | window.location = '/login' 102 | } else { 103 | $('.error_tip2').html(data.erro).show() 104 | } 105 | } 106 | } 107 | ); 108 | return false; 109 | } else { 110 | return false; 111 | } 112 | 113 | }); 114 | 115 | 116 | }) -------------------------------------------------------------------------------- /templates/app/base_site.html: -------------------------------------------------------------------------------- 1 | {% extends 'Base.html' %} 2 | {% block meta %}{% endblock %} 3 | {% block title %}{% endblock title %} 4 | {% block style %}{% endblock style %} 5 | 6 | {% block body %} 7 | {% block exclude_footer %} 8 |
    9 |
    10 |
    欢迎来到书籍家!
    11 |
    12 | {% if request.user.is_authenticated %} 13 | 18 | {% else %} 19 | 24 | {% endif %} 25 | 26 | 27 | 35 |
    36 |
    37 |
    38 | {% block user_base %} 39 | 59 | 60 | 65 | 66 | 67 | 68 | {% block contenr %}{% endblock contenr %} 69 | {% endblock user_base %} 70 | 71 | 72 | {% endblock exclude_footer %} 73 | 86 | 87 | {% endblock body %} 88 | 89 | {% block script %}{% endblock script %} -------------------------------------------------------------------------------- /static/js/jquery.cookie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Cookie Plugin v1.4.1 3 | * https://github.com/carhartl/jquery-cookie 4 | * 5 | * Copyright 2013 Klaus Hartl 6 | * Released under the MIT license 7 | */ 8 | (function (factory) { 9 | if (typeof define === 'function' && define.amd) { 10 | // AMD 11 | define(['jquery'], factory); 12 | } else if (typeof exports === 'object') { 13 | // CommonJS 14 | factory(require('jquery')); 15 | } else { 16 | // Browser globals 17 | factory(jQuery); 18 | } 19 | }(function ($) { 20 | 21 | var pluses = /\+/g; 22 | 23 | function encode(s) { 24 | return config.raw ? s : encodeURIComponent(s); 25 | } 26 | 27 | function decode(s) { 28 | return config.raw ? s : decodeURIComponent(s); 29 | } 30 | 31 | function stringifyCookieValue(value) { 32 | return encode(config.json ? JSON.stringify(value) : String(value)); 33 | } 34 | 35 | function parseCookieValue(s) { 36 | if (s.indexOf('"') === 0) { 37 | // This is a quoted cookie as according to RFC2068, unescape... 38 | s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 39 | } 40 | 41 | try { 42 | // Replace server-side written pluses with spaces. 43 | // If we can't decode the cookie, ignore it, it's unusable. 44 | // If we can't parse the cookie, ignore it, it's unusable. 45 | s = decodeURIComponent(s.replace(pluses, ' ')); 46 | return config.json ? JSON.parse(s) : s; 47 | } catch(e) {} 48 | } 49 | 50 | function read(s, converter) { 51 | var value = config.raw ? s : parseCookieValue(s); 52 | return $.isFunction(converter) ? converter(value) : value; 53 | } 54 | 55 | var config = $.cookie = function (key, value, options) { 56 | 57 | // Write 58 | 59 | if (value !== undefined && !$.isFunction(value)) { 60 | options = $.extend({}, config.defaults, options); 61 | 62 | if (typeof options.expires === 'number') { 63 | var days = options.expires, t = options.expires = new Date(); 64 | t.setTime(+t + days * 864e+5); 65 | } 66 | 67 | return (document.cookie = [ 68 | encode(key), '=', stringifyCookieValue(value), 69 | options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 70 | options.path ? '; path=' + options.path : '', 71 | options.domain ? '; domain=' + options.domain : '', 72 | options.secure ? '; secure' : '' 73 | ].join('')); 74 | } 75 | 76 | // Read 77 | 78 | var result = key ? undefined : {}; 79 | 80 | // To prevent the for loop in the first place assign an empty array 81 | // in case there are no cookies at all. Also prevents odd result when 82 | // calling $.cookie(). 83 | var cookies = document.cookie ? document.cookie.split('; ') : []; 84 | 85 | for (var i = 0, l = cookies.length; i < l; i++) { 86 | var parts = cookies[i].split('='); 87 | var name = decode(parts.shift()); 88 | var cookie = parts.join('='); 89 | 90 | if (key && key === name) { 91 | // If second argument (value) is a function it's a converter... 92 | result = read(cookie, value); 93 | break; 94 | } 95 | 96 | // Prevent storing a cookie that we couldn't decode. 97 | if (!key && (cookie = read(cookie)) !== undefined) { 98 | result[name] = cookie; 99 | } 100 | } 101 | 102 | return result; 103 | }; 104 | 105 | config.defaults = {}; 106 | 107 | $.removeCookie = function (key, options) { 108 | if ($.cookie(key) === undefined) { 109 | return false; 110 | } 111 | 112 | // Must not alter options, thus extending a fresh object... 113 | $.cookie(key, '', $.extend({}, options, { expires: -1 })); 114 | return !$.cookie(key); 115 | }; 116 | 117 | })); 118 | -------------------------------------------------------------------------------- /templates/app/shop_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'app/base_site.html' %} 2 | {% load tags %} 3 | {% block meta %}{% endblock %} 4 | 5 | {% block title %}书籍屋-商城{% endblock title %} 6 | 7 | {% block style %} 8 | 9 | {% endblock style %} 10 | 11 | {% block contenr %} 12 |
    13 |
    14 |
    15 |
    16 | 类型 17 | 不限 19 | {% for v in book_type %} 20 | {{ v }} 22 | {% endfor %} 23 |
    24 |
    25 | 出版社 26 | 不限 28 | {% for v in publishing_house %} 29 | {{ v }} 31 | {% endfor %} 32 |
    33 | 34 |
      35 | {% for good in goods_obj %} 36 |
    • 37 | 38 |

      {{ good.name }}

      39 |
      40 | ¥{{ good.price }} 41 | {{ good.price }}/{{ good.unite }} 42 | {# #} 43 |
      44 |
    • 45 | {% endfor %} 46 |
    47 | 48 |
    49 | {% if goods_obj.paginator.num_pages > 1 %} 50 | {% if goods_obj.has_previous %} 51 | 52 | 上一页 53 | 54 | {% else %} 55 | 56 | 上一页 57 | 58 | {% endif %} 59 | 60 | {% for i in goods_obj.paginator.pager_num_range %} 61 | {% if i == goods_obj.number %} 62 | {{ i }} 63 | {% else %} 64 | {{ i }} 65 | {% endif %} 66 | {% endfor %} 67 | 68 | {% if goods_obj.has_next %} 69 | 70 | 下一页> 71 | 72 | {% else %} 73 | 下一页> 74 | {% endif %} 75 | 76 | {% endif %} 77 |
    78 |
    79 |
    80 | {% endblock contenr %} 81 | 82 | {% block script %}{% endblock script %} -------------------------------------------------------------------------------- /book_shop/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for book_shop project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.2. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.2/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.2/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | # Quick-start development settings - unsuitable for production 19 | # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ 20 | 21 | # SECURITY WARNING: keep the secret key used in production secret! 22 | SECRET_KEY = 'jj%&=!ro(m)4-$@_fgv&jz9+g_je1l^v^-ph%oi(66y7c@8l3$' 23 | 24 | # SECURITY WARNING: don't run with debug turned on in production! 25 | DEBUG = True 26 | 27 | ALLOWED_HOSTS = [] 28 | 29 | # Application definition 30 | 31 | INSTALLED_APPS = [ 32 | 'django.contrib.admin', 33 | 'django.contrib.auth', 34 | 'django.contrib.contenttypes', 35 | 'django.contrib.sessions', 36 | 'django.contrib.messages', 37 | 'django.contrib.staticfiles', 38 | 'app.apps.AppConfig', 39 | 'DjangoUeditor' 40 | ] 41 | 42 | MIDDLEWARE = [ 43 | 'django.middleware.security.SecurityMiddleware', 44 | 'django.contrib.sessions.middleware.SessionMiddleware', 45 | 'django.middleware.common.CommonMiddleware', 46 | # 'django.middleware.csrf.CsrfViewMiddleware', 47 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 48 | 'django.contrib.messages.middleware.MessageMiddleware', 49 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 50 | ] 51 | 52 | ROOT_URLCONF = 'book_shop.urls' 53 | 54 | TEMPLATES = [ 55 | { 56 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 57 | 'DIRS': [os.path.join(BASE_DIR, 'templates')] 58 | , 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | 'libraries': { 68 | 'tags': 'app.templatetags.tags' 69 | } 70 | }, 71 | }, 72 | ] 73 | 74 | WSGI_APPLICATION = 'book_shop.wsgi.application' 75 | 76 | # Database 77 | # https://docs.djangoproject.com/en/2.2/ref/settings/#databases 78 | 79 | DATABASES = { 80 | 'default': { 81 | 'ENGINE': 'django.db.backends.sqlite3', 82 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 83 | } 84 | } 85 | 86 | # Password validation 87 | # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators 88 | 89 | AUTH_PASSWORD_VALIDATORS = [ 90 | { 91 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 92 | }, 93 | { 94 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 95 | }, 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 98 | }, 99 | { 100 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 101 | }, 102 | ] 103 | 104 | # Internationalization 105 | # https://docs.djangoproject.com/en/2.2/topics/i18n/ 106 | 107 | LANGUAGE_CODE = 'en-us' 108 | 109 | TIME_ZONE = 'UTC' 110 | 111 | USE_I18N = True 112 | 113 | USE_L10N = True 114 | 115 | USE_TZ = True 116 | 117 | # Static files (CSS, JavaScript, Images) 118 | # https://docs.djangoproject.com/en/2.2/howto/static-files/ 119 | 120 | STATIC_URL = '/static/' 121 | STATICFILES_DIRS = [ 122 | os.path.join(BASE_DIR, 'static'), 123 | ] 124 | # STATIC_ROOT = STATICFILES_DIRS 125 | 126 | LOGIN_URL = '/login' 127 | 128 | MEDIA_URL = '/media/' 129 | 130 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 131 | -------------------------------------------------------------------------------- /templates/app/detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'app/base_site.html' %} 2 | 3 | {% block meta %}{% endblock %} 4 | 5 | {% block title %}书籍屋-商品详情{% endblock title %} 6 | 7 | {% block style %} 8 | 9 | {% endblock style %} 10 | 11 | {% block contenr %} 12 | 17 | 18 |
    19 |
    20 | 21 |
    22 |

    {{ good_obj.name }}

    23 |

    {{ good_obj.desc }}

    24 |
    25 | ¥{{ good_obj.price }} 26 | 单 位:{{ good_obj.unite }} 27 |
    28 |
    29 |
    数 量:
    30 |
    31 | 32 | + 33 | - 34 |
    35 |
    36 | {#
    总价:{{ good_obj.price }}元
    #} 37 |
    38 | 立即购买 39 | 加入购物车 40 |
    41 |
    42 |
    43 | 44 |
    45 |
    46 |
      47 |
    • 商品介绍
    • 48 |
    49 | 50 |
    51 | {{ good_obj.detail|safe }} 52 |
    53 | 54 |
    55 |
    56 | 57 | 58 | {% endblock contenr %} 59 | 60 | {% block script %} 61 |
    62 | 128 | {% endblock script %} -------------------------------------------------------------------------------- /templates/app/user/CreateOrder.html: -------------------------------------------------------------------------------- 1 | {% extends 'app/user/base_user.html' %} 2 | {% load tags %} 3 | {% block meta %}{% endblock %} 4 | {% block title %}书籍屋-提交订单{% endblock title %} 5 | {% block style %}{% endblock style %} 6 | 7 | {% block user_title %}提交订单{% endblock user_title %} 8 | {% block contenr %} 9 |

    确认收货地址

    10 | 11 |
    12 |
    13 |
    寄送到:
    14 | {% for addr in addrs %} 15 |
    {{ addr.addr }} ({{ addr.receiver }} 收) {{ addr.phone }}
    17 | {% endfor %} 18 | 19 | 20 |
    21 | 编辑收货地址 22 | 23 |
    24 | 25 |

    支付方式

    26 |
    27 |
    28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
    37 |
    38 | 39 |

    商品列表

    40 | 41 |
    42 |
      43 |
    • 商品名称
    • 44 |
    • 商品单位
    • 45 |
    • 商品价格
    • 46 |
    • 数量
    • 47 |
    • 小计
    • 48 |
    49 | {% for good in good_list %} 50 |
      51 | 52 |
    • {{ forloop.counter }}
    • 53 |
    • 54 |
    • {{ good.good.name }}
    • 55 |
    • {{ good.good.unite }}
    • 56 |
    • {{ good.good.price }}
    • 57 |
    • {{ good.count }}
    • 58 |
    • {% chengfa good.count good.good.price %}元
    • 59 |
    60 | {% endfor %} 61 |
    62 | 63 |

    总金额结算

    64 | 65 |
    66 |
    67 |
    {{ count }}件商品,总金额{{ all_price }}元
    68 |
    运费:10元
    69 |
    实付款:{{ all_price2 }}元
    70 |
    71 |
    72 | 73 |
    74 | 提交订单 75 |
    76 | 77 | {% endblock contenr %} 78 | 79 | 80 | {% block script %} 81 | 88 | 128 | {% endblock script %} -------------------------------------------------------------------------------- /app/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from DjangoUeditor.models import UEditorField 3 | from django.contrib.auth.models import User 4 | from django.utils import timezone 5 | 6 | 7 | # Create your models piphere. 8 | 9 | class Goods(models.Model): 10 | """商品信息表""" 11 | status_choices = ( 12 | (0, '下线'), 13 | (1, '上线'), 14 | ) 15 | 16 | name = models.CharField(max_length=20, verbose_name='书籍名称') 17 | desc = models.CharField(max_length=256, verbose_name='书籍简介') 18 | price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='书籍价格') 19 | unite = models.CharField(max_length=20, verbose_name='商品单位') 20 | image = models.ImageField(upload_to='goods', verbose_name='书籍主图') 21 | 22 | book_type = models.CharField(max_length=64, verbose_name='书籍类型') 23 | publishing_house = models.CharField(max_length=64, verbose_name='出版社') 24 | 25 | stock = models.IntegerField(default=1, verbose_name='商品库存') 26 | sales = models.IntegerField(default=0, verbose_name='商品销量') 27 | status = models.SmallIntegerField(default=1, choices=status_choices, verbose_name='商品状态') 28 | detail = UEditorField(width=600, height=300, toolbars="full", imagePath="images/", 29 | filePath="files/", upload_settings={"imageMaxSize": 1204000}, settings={}, 30 | verbose_name='商品详情') 31 | add_datetime = models.DateTimeField(verbose_name='添加时间', default=timezone.now) 32 | 33 | def __str__(self): 34 | return self.name 35 | 36 | class Meta: 37 | db_table = 'goods' 38 | verbose_name = '商品信息' 39 | verbose_name_plural = verbose_name 40 | 41 | 42 | class UserAddress(models.Model): 43 | """用户地址类""" 44 | user = models.ForeignKey(User, verbose_name='所属账户', on_delete=models.CASCADE) 45 | receiver = models.CharField(max_length=20, verbose_name='收件人') 46 | addr = models.CharField(max_length=256, verbose_name='收件地址') 47 | zip_code = models.CharField(max_length=6, null=True, verbose_name='邮政编码') 48 | phone = models.CharField(max_length=11, verbose_name='联系电话') 49 | is_default = models.BooleanField(default=False, verbose_name='是否默认') 50 | 51 | class Meta: 52 | db_table = 'user_address' 53 | verbose_name = '地址' 54 | verbose_name_plural = verbose_name 55 | 56 | 57 | class OrderInfo(models.Model): 58 | """用户订单信息类""" 59 | PAY_METHODS = { 60 | '1': "货到付款", 61 | '2': "微信支付", 62 | '3': "支付宝", 63 | '4': '银联支付' 64 | } 65 | 66 | PAY_METHODS_ENUM = { 67 | "CASH": 1, 68 | "ALIPAY": 2 69 | } 70 | 71 | ORDER_STATUS_ENUM = { 72 | "UNPAID": 1, 73 | "UNSEND": 2, 74 | "UNRECEIVED": 3, 75 | "UNCOMMENT": 4, 76 | "FINISHED": 5 77 | } 78 | 79 | PAY_METHOD_CHOICES = ( 80 | (1, '货到付款'), 81 | (2, '微信支付'), 82 | (3, '支付宝'), 83 | (4, '银联支付') 84 | ) 85 | 86 | ORDER_STATUS_CHOICES = ( 87 | (1, '待支付'), 88 | (2, '待发货'), 89 | (3, '待收货'), 90 | (4, '已完成') 91 | ) 92 | 93 | order_id = models.CharField(max_length=128, primary_key=True, verbose_name='订单id') 94 | user = models.ForeignKey(User, verbose_name='用户', on_delete=models.CASCADE) 95 | addr = models.ForeignKey('UserAddress', verbose_name='地址', on_delete=models.CASCADE) 96 | pay_method = models.SmallIntegerField(choices=PAY_METHOD_CHOICES, default=3, verbose_name='支付方式') 97 | total_count = models.IntegerField(default=1, verbose_name='商品数量') 98 | total_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='商品总价') 99 | transit_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='订单运费') 100 | order_status = models.SmallIntegerField(choices=ORDER_STATUS_CHOICES, default=1, verbose_name='订单状态') 101 | trade_no = models.CharField(max_length=128, default='', verbose_name='支付编号') 102 | create_datetime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') 103 | 104 | class Meta: 105 | db_table = 'df_order_info' 106 | verbose_name = '订单信息' 107 | verbose_name_plural = verbose_name 108 | 109 | 110 | class OrderGoods(models.Model): 111 | """用户订单商品类""" 112 | order = models.ForeignKey('OrderInfo', verbose_name='订单', on_delete=models.CASCADE) 113 | sku = models.ForeignKey('Goods', verbose_name='商品', on_delete=models.CASCADE) 114 | count = models.IntegerField(default=1, verbose_name='商品数目') 115 | price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='商品价格') 116 | 117 | def get_order_id(self): 118 | return self.order.order_id 119 | 120 | class Meta: 121 | db_table = 'df_order_goods' 122 | verbose_name = '订单商品' 123 | verbose_name_plural = verbose_name 124 | 125 | 126 | # 购物车 127 | class ShopCart(models.Model): 128 | """购物车""" 129 | user = models.ForeignKey(User, verbose_name='用户', on_delete=models.CASCADE) 130 | good = models.ForeignKey(Goods, verbose_name='商品', on_delete=models.CASCADE) 131 | good_count = models.IntegerField(verbose_name='商品数量') 132 | 133 | def __str__(self): 134 | return self.good.name 135 | 136 | class Meta: 137 | db_table = 'shop_cart' 138 | verbose_name = '购物车' 139 | verbose_name_plural = verbose_name 140 | 141 | 142 | # 浏览记录 143 | class History(models.Model): 144 | """浏览记录""" 145 | user = models.ForeignKey(User, verbose_name='用户', on_delete=models.CASCADE) 146 | good = models.ForeignKey(Goods, verbose_name='商品', on_delete=models.CASCADE) 147 | show_datetime = models.DateTimeField(auto_now=True, verbose_name='浏览时间') 148 | -------------------------------------------------------------------------------- /templates/app/user/UserOrder.html: -------------------------------------------------------------------------------- 1 | {% extends 'app/user/base_user.html' %} 2 | {% block meta %}{% endblock %} 3 | {% block title %}书籍屋-我的订单{% endblock title %} 4 | {% block style %} 5 | 10 | {% endblock style %} 11 | 12 | {% block user_title %}个人订单{% endblock user_title %} 13 | {% block contenr %} 14 |
    15 |
    16 |

    用户中心

    17 | 22 |
    23 |
    24 |

    全部订单

    25 | {% for order in order_obj %} 26 |
      27 |
    • {{ order.create_datetime|date:"Y-m-d H:i:s" }}
    • 28 |
    • 订单号:{{ order.order_id }}
    • 29 | 30 |
    • {{ order.get_order_status_display }}
    • 31 |
    32 | 33 | 34 | 35 | 36 | 47 | 48 | {% if order.order_status == 1 %} 49 | 50 | 51 | {% elif order.order_status == 2 %} 52 | 53 | 54 | {% elif order.order_status == 3 %} 55 | 56 | 58 | {% elif order.order_status == 4 %} 59 | 60 | 61 | {% endif %} 62 | 63 | 64 | 65 |
    37 | {% for good in order.ordergoods_set.all %} 38 |
      39 |
    • 40 |
    • {{ good.sku.name }}{{ good.sku.price }}元/{{ good.sku.unite }}g 41 |
    • 42 |
    • {{ good.count }}
    • 43 |
    • {{ good.price }}元
    • 44 |
    45 | {% endfor %} 46 |
    {{ order.total_price }}元待付款去付款待发货待发货待收货确认收货 57 | 已完成已完成
    66 | {% endfor %} 67 | 68 | 69 | {#
    #} 70 | {# #} 71 | {# <上一页#} 72 | {# #} 73 | {# 1#} 74 | {# 2#} 75 | {# 3#} 76 | {# 4#} 77 | {# 5#} 78 | {# 下一页>#} 79 | {#
    #} 80 |
    81 |
    82 | 89 | {% endblock contenr %} 90 | 91 | 92 | {% block script %} 93 | 140 | {% endblock script %} -------------------------------------------------------------------------------- /app/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2 on 2019-04-23 03:31 2 | 3 | import DjangoUeditor.models 4 | from django.conf import settings 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | initial = True 12 | 13 | dependencies = [ 14 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 15 | ] 16 | 17 | operations = [ 18 | migrations.CreateModel( 19 | name='Goods', 20 | fields=[ 21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 22 | ('name', models.CharField(max_length=20, verbose_name='书籍名称')), 23 | ('desc', models.CharField(max_length=256, verbose_name='书籍简介')), 24 | ('price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='书籍价格')), 25 | ('unite', models.CharField(max_length=20, verbose_name='商品单位')), 26 | ('image', models.ImageField(upload_to='goods', verbose_name='书籍主图')), 27 | ('book_type', models.CharField(max_length=64, verbose_name='书籍类型')), 28 | ('publishing_house', models.CharField(max_length=64, verbose_name='出版社')), 29 | ('stock', models.IntegerField(default=1, verbose_name='商品库存')), 30 | ('sales', models.IntegerField(default=0, verbose_name='商品销量')), 31 | ('status', models.SmallIntegerField(choices=[(0, '下线'), (1, '上线')], default=1, verbose_name='商品状态')), 32 | ('detail', DjangoUeditor.models.UEditorField(verbose_name='商品详情')), 33 | ], 34 | options={ 35 | 'verbose_name': '商品信息', 36 | 'verbose_name_plural': '商品信息', 37 | 'db_table': 'goods', 38 | }, 39 | ), 40 | migrations.CreateModel( 41 | name='UserAddress', 42 | fields=[ 43 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 44 | ('receiver', models.CharField(max_length=20, verbose_name='收件人')), 45 | ('addr', models.CharField(max_length=256, verbose_name='收件地址')), 46 | ('zip_code', models.CharField(max_length=6, null=True, verbose_name='邮政编码')), 47 | ('phone', models.CharField(max_length=11, verbose_name='联系电话')), 48 | ('is_default', models.BooleanField(default=False, verbose_name='是否默认')), 49 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='所属账户')), 50 | ], 51 | options={ 52 | 'verbose_name': '地址', 53 | 'verbose_name_plural': '地址', 54 | 'db_table': 'user_address', 55 | }, 56 | ), 57 | migrations.CreateModel( 58 | name='ShopCart', 59 | fields=[ 60 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 61 | ('good_count', models.IntegerField(verbose_name='商品数量')), 62 | ('good', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.Goods', verbose_name='商品')), 63 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='用户')), 64 | ], 65 | options={ 66 | 'verbose_name': '购物车', 67 | 'verbose_name_plural': '购物车', 68 | 'db_table': 'shop_cart', 69 | }, 70 | ), 71 | migrations.CreateModel( 72 | name='OrderInfo', 73 | fields=[ 74 | ('order_id', models.CharField(max_length=128, primary_key=True, serialize=False, verbose_name='订单id')), 75 | ('pay_method', models.SmallIntegerField(choices=[(1, '货到付款'), (2, '微信支付'), (3, '支付宝'), (4, '银联支付')], default=3, verbose_name='支付方式')), 76 | ('total_count', models.IntegerField(default=1, verbose_name='商品数量')), 77 | ('total_price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='商品总价')), 78 | ('transit_price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='订单运费')), 79 | ('order_status', models.SmallIntegerField(choices=[(1, '待支付'), (2, '待收货'), (3, '已完成')], default=1, verbose_name='订单状态')), 80 | ('trade_no', models.CharField(default='', max_length=128, verbose_name='支付编号')), 81 | ('create_datetime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), 82 | ('addr', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.UserAddress', verbose_name='地址')), 83 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='用户')), 84 | ], 85 | options={ 86 | 'verbose_name': '订单信息', 87 | 'verbose_name_plural': '订单信息', 88 | 'db_table': 'df_order_info', 89 | }, 90 | ), 91 | migrations.CreateModel( 92 | name='OrderGoods', 93 | fields=[ 94 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 95 | ('count', models.IntegerField(default=1, verbose_name='商品数目')), 96 | ('price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='商品价格')), 97 | ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.OrderInfo', verbose_name='订单')), 98 | ('sku', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.Goods', verbose_name='商品')), 99 | ], 100 | options={ 101 | 'verbose_name': '订单商品', 102 | 'verbose_name_plural': '订单商品', 103 | 'db_table': 'df_order_goods', 104 | }, 105 | ), 106 | ] 107 | -------------------------------------------------------------------------------- /templates/app/user/UserInfo.html: -------------------------------------------------------------------------------- 1 | {% extends 'app/user/base_user.html' %} 2 | {% block meta %}{% endblock %} 3 | {% block title %}书籍屋-个人中心{% endblock title %} 4 | {% block style %} 5 | 6 | {% endblock style %} 7 | 8 | {% block user_title %}用户中心{% endblock user_title %} 9 | {% block contenr %} 10 |
    11 |
    12 |

    用户中心

    13 | 18 |
    19 |
    20 |
    21 |

    基本信息

    22 |
    23 |
    24 | 28 |
    29 |
    30 |
    31 | 33 |
    34 |
    35 | 36 | 37 |
    38 | 39 |

    最近浏览

    40 |
    41 |
      42 | {% for his in history_obj %} 43 |
    • 44 | 45 |

      {{ his.good.name }}

      46 |
      47 | ¥{{ his.good.price }} 48 | {{ his.good.price }}/{{ his.good.unite }} 49 |
      50 |
    • 51 | {% endfor %} 52 |
    53 |
    54 |
    55 |
    56 | 57 | 58 | 59 | 107 | {% endblock contenr %} 108 | 109 | 110 | {% block script %} 111 | 113 | 114 | 115 | 118 | 119 | 137 | {% endblock script %} -------------------------------------------------------------------------------- /templates/app/user/UserCar.html: -------------------------------------------------------------------------------- 1 | {% extends 'app/user/base_user.html' %} 2 | {% load tags %} 3 | {% block meta %}{% endblock %} 4 | {% block title %}书籍屋-购物车{% endblock title %} 5 | {% block style %}{% endblock style %} 6 | 7 | {% block user_title %}购物车{% endblock user_title %} 8 | {% block contenr %} 9 |
    全部商品{{ shop_cart_obj.count }}
    10 |
      11 |
    • 商品名称
    • 12 |
    • 商品单位
    • 13 |
    • 商品价格
    • 14 |
    • 数量
    • 15 |
    • 小计
    • 16 |
    • 操作
    • 17 |
    18 | {% for car in shop_cart_obj %} 19 |
      20 |
    • 21 | 22 | 23 |
    • 24 |
    • 25 |
    • {{ car.good.name }}
      {{ car.good.price }}元/{{ car.good.unite }}
    • 26 |
    • {{ car.good.unite }}
    • 27 |
    • {{ car.good.price }}元
    • 28 |
    • 29 |
      30 | 31 | 33 | 34 |
      35 |
    • 36 |
    • {% chengfa car.good.price car.good_count %}
    • 37 |
    • 删除
    • 38 |
    39 | {% endfor %} 40 |
      41 |
    • 42 |
    • 全选
    • 43 |
    • 合计(不含运费):¥0
      共计0件商品
    • 44 |
    • 去结算
    • 45 |
    46 | {% endblock contenr %} 47 | 48 | 49 | {% block script %} 50 | 151 | {% endblock script %} -------------------------------------------------------------------------------- /app/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, redirect 2 | from django.http import JsonResponse 3 | from django.contrib.auth import authenticate, logout, login 4 | from django.contrib.auth.decorators import login_required 5 | from django.core.paginator import EmptyPage, PageNotAnInteger 6 | from app import models 7 | from app.utils import CustomPaginator 8 | import json 9 | from uuid import uuid4 10 | 11 | 12 | # Create your views here. 13 | # 登陆 14 | def acc_login(request): 15 | if request.method == 'GET': 16 | return render(request, 'app/login.html') 17 | elif request.method == 'POST': 18 | username = request.POST.get('username') 19 | password = request.POST.get('password') 20 | user = authenticate(username=username, password=password) 21 | if user: 22 | login(request, user) 23 | return redirect(request.GET.get('next', '/')) 24 | else: 25 | return render(request, 'app/login.html', {'erro': "用户名或密码错误"}) 26 | 27 | 28 | # 注册 29 | def acc_register(request): 30 | if request.method == 'GET': 31 | return render(request, 'app/register.html') 32 | elif request.method == 'POST': 33 | username = request.POST.get('username') 34 | password1 = request.POST.get('password1') 35 | password2 = request.POST.get('password2') 36 | first_name = request.POST.get('first_name') 37 | 38 | a = models.User.objects.filter(username=username).first() 39 | 40 | if password1 == password2: 41 | if a: 42 | return JsonResponse({'status': False, 'erro': '当前用户名已经存在!'}) 43 | user = models.User.objects.create_user(username=username, email='xxzzyy@qq.com', password=password2, 44 | first_name=first_name) 45 | return JsonResponse({'status': True}) 46 | 47 | 48 | # 注销 49 | def acc_logout(request): 50 | """注销视图函数""" 51 | logout(request) 52 | return redirect('/login') 53 | 54 | 55 | # 主页 56 | def index(request): 57 | # 最新书籍 58 | # 最火书籍 59 | good_obj = models.Goods.objects.filter(status=1) 60 | context = { 61 | 'new_book_obj': good_obj.order_by('-add_datetime')[:5], 62 | 'hot_book_obj': good_obj.order_by('-sales')[:5] 63 | } 64 | return render(request, 'app/index.html', context) 65 | 66 | 67 | # 商城 68 | def shop(request): 69 | goods_obj = models.Goods.objects.filter(status=1) 70 | 71 | temp_dict = { 72 | 'book_type': list(set([i[0] for i in goods_obj.values_list('book_type')])), 73 | 'publishing_house': list(set([i[0] for i in goods_obj.values_list('publishing_house')])), 74 | } 75 | # 过滤相关 76 | filter_dict = {} 77 | 78 | current_page = request.GET.get('page', 1) 79 | search = request.GET.get('search') 80 | book_type = request.GET.get('book_type') 81 | publishing_house = request.GET.get('publishing_house') 82 | if search: 83 | goods_obj = goods_obj.filter(name__icontains=search) 84 | filter_dict['search'] = search 85 | if book_type: 86 | goods_obj = goods_obj.filter(book_type=book_type) 87 | filter_dict['book_type'] = book_type 88 | if publishing_house: 89 | goods_obj = goods_obj.filter(publishing_house=publishing_house) 90 | filter_dict['publishing_house'] = publishing_house 91 | 92 | if current_page == 'all': 93 | paginator = CustomPaginator(1, 10, goods_obj, goods_obj.count()) 94 | else: 95 | paginator = CustomPaginator(current_page, 10, goods_obj, 60) 96 | 97 | try: 98 | data_list = paginator.page(current_page) # 分页 99 | except PageNotAnInteger: 100 | data_list = paginator.page(1) 101 | except EmptyPage: 102 | data_list = paginator.page(paginator.num_pages) 103 | 104 | context = { 105 | 'goods_obj': data_list, 106 | 'filter_dict': filter_dict, 107 | } 108 | context.update(temp_dict) 109 | 110 | return render(request, 'app/shop_list.html', context) 111 | 112 | 113 | # 商品详情 114 | @login_required 115 | def detail(request, good_id): 116 | good_obj = models.Goods.objects.filter(pk=good_id).first() 117 | if request.user.is_authenticated: 118 | history_obj = models.History.objects.filter(user=request.user) 119 | if not history_obj.filter(good=good_obj): 120 | if history_obj.count() <= 5: 121 | models.History.objects.create(user=request.user, good=good_obj) 122 | else: 123 | a = history_obj.last() 124 | a.good = good_obj 125 | a.save() 126 | return render(request, 'app/detail.html', {'good_obj': good_obj}) 127 | 128 | 129 | # 创建订单 130 | @login_required 131 | def create_order(request): 132 | if request.method == 'GET': 133 | # 获取用户传递过来的商品 134 | 135 | order = request.GET.get('order') 136 | # order = 1-3,3-3 商品ID-商品数量 137 | data = [] 138 | dd2 = [] 139 | all_price = 0 140 | for a in order.split(','): 141 | if a: 142 | good_id, good_count, *_ = a.split('-') 143 | good = models.Goods.objects.filter(pk=good_id).first() 144 | all_price += good.price * int(good_count) 145 | data.append({'good': good, 'count': int(good_count)}) 146 | dd2.append({'good_id': good.id, 'good_count': int(good_count)}) 147 | # 用户地址 148 | addrs = models.UserAddress.objects.filter(user=request.user) 149 | # 计算总金额额 150 | context = { 151 | 'good_list': data, 'count': len(data), 'all_price': all_price, 'all_price2': all_price + 10, 152 | 'addrs': addrs, 153 | 'dd2': dd2 154 | } 155 | return render(request, 'app/user/CreateOrder.html', context) 156 | elif request.method == 'POST': 157 | data = request.POST.get('data') 158 | data = json.loads(data) 159 | good_obj_list = [] # 存放所有商品对象 160 | sum_price = 0 # 总价 161 | 162 | # {'goods': [{'good_id': 1, 'good_count': 3}, {'good_id': 3, 'good_count': 3}], 'addr_id': '1', 'pay_type': '1'} 163 | for d in data['goods']: 164 | a = models.Goods.objects.filter(pk=d['good_id']).first() 165 | b = models.ShopCart.objects.filter(user=request.user, good_id=d['good_id']) 166 | if b: 167 | b.delete() 168 | if a: 169 | good_obj_list.append([a, int(d['good_count'])]) 170 | sum_price += a.price * int(d['good_count']) 171 | 172 | # 生成订单 173 | order_obj = models.OrderInfo.objects.create( 174 | order_id=str(uuid4()), 175 | user=request.user, 176 | addr_id=data['addr_id'], 177 | pay_method=int(data['pay_type']), 178 | total_count=len(good_obj_list), 179 | total_price=sum_price, 180 | transit_price=10, 181 | 182 | ) 183 | # 生成所有商品 184 | for good_obj, count in good_obj_list: 185 | models.OrderGoods.objects.create( 186 | order=order_obj, 187 | sku=good_obj, 188 | count=count, 189 | price=good_obj.price * count, 190 | ) 191 | 192 | print(data) 193 | return JsonResponse({'status': True}) 194 | 195 | 196 | # 用户中心 197 | @login_required 198 | def user_info(request): 199 | if request.method == 'GET': 200 | history_obj = models.History.objects.filter(user=request.user) 201 | 202 | context = { 203 | 'history_obj': history_obj 204 | } 205 | return render(request, 'app/user/UserInfo.html', context) 206 | elif request.method == 'POST': 207 | first_name = request.POST.get('first_name') 208 | old_password = request.POST.get('oldpassword') 209 | new_password1 = request.POST.get('newpassword1') 210 | new_password2 = request.POST.get('newpassword2') 211 | if new_password1 != new_password2: 212 | return JsonResponse({'status': False, 'erro': '两次输入密码不相同!'}) 213 | user = request.user 214 | 215 | if not user.check_password(old_password): 216 | return JsonResponse({'status': False, 'erro': '旧密码输入有误!'}) 217 | 218 | user.first_name = first_name 219 | user.set_password(new_password2) 220 | user.save() 221 | return JsonResponse({'status': True, 'erro': ''}) 222 | 223 | 224 | # 个人订单 225 | @login_required 226 | def user_order(request): 227 | # 查询用户所有订单 228 | order_obj = models.OrderInfo.objects.filter(user=request.user).order_by('-create_datetime') 229 | context = { 230 | 'order_obj': order_obj 231 | } 232 | return render(request, 'app/user/UserOrder.html', context) 233 | 234 | 235 | # 收货地址 236 | @login_required 237 | def user_addr(request): 238 | if request.method == 'GET': 239 | addr_obj = models.UserAddress.objects.filter(user=request.user) 240 | 241 | return render(request, 'app/user/UserAddr.html', {'addr_obj': addr_obj}) 242 | elif request.method == 'POST': 243 | receiver = request.POST.get('receiver') 244 | addr = request.POST.get('addr') 245 | zip_code = request.POST.get('zip_code') 246 | phone = request.POST.get('phone') 247 | if all([receiver, addr, zip_code, phone]): 248 | a = models.UserAddress.objects.create(receiver=receiver, addr=addr, zip_code=zip_code, phone=phone, 249 | user=request.user) 250 | return redirect('/UserAddr') 251 | 252 | 253 | # 设置用户默认地址 254 | def set_default_addr(request): 255 | addr_id = request.POST.get('addrID') 256 | addr_obj = models.UserAddress.objects.filter(user=request.user) 257 | addr_obj.update(is_default=False) 258 | addr_obj.filter(pk=addr_id).update(is_default=True) 259 | return JsonResponse({'status': True}) 260 | 261 | 262 | # 购物车 263 | @login_required 264 | def user_car(request): 265 | shop_cart_obj = models.ShopCart.objects.filter(user=request.user) 266 | 267 | # 总价 268 | price = 0 269 | for cart in shop_cart_obj: 270 | price += cart.good.price * cart.good_count 271 | return render(request, 'app/user/UserCar.html', {'shop_cart_obj': shop_cart_obj, 'price': price}) 272 | 273 | 274 | # 添加商品到购物车 275 | @login_required 276 | def add_cart(request): 277 | user = request.user 278 | good_id = request.POST.get('GoodID') 279 | good_count = request.POST.get('GoodCount') 280 | if good_id and good_count: 281 | car_obj = models.ShopCart.objects.filter(user=user, good=good_id).first() 282 | if car_obj: 283 | car_obj.good_count = car_obj.good_count + int(good_count) 284 | car_obj.save() 285 | return JsonResponse({'status': True, 'new': False}) 286 | else: 287 | models.ShopCart.objects.create(user=user, good_id=good_id, good_count=good_count) 288 | return JsonResponse({'status': True, 'new': True}) 289 | else: 290 | return JsonResponse({'status': False}) 291 | 292 | 293 | # 删除购物车 294 | @login_required 295 | def remove_cart(request): 296 | user = request.user 297 | car_id = request.POST.get('carID') 298 | car_obj = models.ShopCart.objects.filter(user=user, pk=car_id).first() 299 | if car_obj: 300 | car_obj.delete() 301 | return JsonResponse({'status': True}) 302 | return JsonResponse({'status': False}) 303 | 304 | 305 | # 支付 306 | @login_required 307 | def pay(request): 308 | order_id = request.POST.get('orderID') 309 | a = models.OrderInfo.objects.filter(order_id=order_id).first() 310 | a.order_status = 2 311 | a.trade_no = str(uuid4()) 312 | a.save() 313 | 314 | for good_order in models.OrderGoods.objects.filter(order=a): 315 | good = good_order.sku 316 | sales = good.sales 317 | good.sales = sales + 1 318 | good.save() 319 | 320 | return JsonResponse({'status': True}) 321 | 322 | 323 | # 确认收货 324 | @login_required 325 | def receiving(request): 326 | order_id = request.POST.get('orderID') 327 | a = models.OrderInfo.objects.filter(order_id=order_id).first() 328 | a.order_status = 4 329 | a.save() 330 | return JsonResponse({'status': True}) 331 | -------------------------------------------------------------------------------- /static/css/main.css: -------------------------------------------------------------------------------- 1 | body{font-family:'Microsoft Yahei';font-size:12px;color:#666;} 2 | html,body{height:100%} 3 | /* 顶部样式 */ 4 | .header_con{ 5 | background-color:#f7f7f7; 6 | height:29px; 7 | border-bottom:1px solid #dddddd 8 | } 9 | 10 | .header{ 11 | width:1200px; 12 | height:29px; 13 | margin:0 auto; 14 | } 15 | 16 | .welcome,.login_info,.login_btn,.user_link{ 17 | line-height:29px; 18 | } 19 | 20 | .login_info{ 21 | display:none; 22 | } 23 | 24 | .login_info em{color:#ff8800} 25 | 26 | .login_btn a,.user_link a{ 27 | color:#666; 28 | } 29 | 30 | .login_btn a:hover,.user_link a:hover{ 31 | color:#ff8800; 32 | } 33 | 34 | .login_btn span,.user_link span{ 35 | color:#cecece; 36 | margin:0 10px; 37 | } 38 | 39 | 40 | /* logo、搜索框、购物车样式 */ 41 | 42 | .search_bar{width:1200px;height:115px;margin:0 auto;} 43 | .logo{width:150px;height:59px;margin:29px 0 0 17px;} 44 | 45 | .search_con{width:616px;height:38px;border:1px solid #37ab40;margin:34px 0 0 124px;background:url(/static/images/icons.png) 10px -338px no-repeat;} 46 | .search_con .input_text{width:470px;height:34px;border:0px;margin:2px 0 0 36px;outline:none;font-size:12px;color:#737272;font-family:'Microsoft Yahei'} 47 | 48 | .search_con .input_btn{ 49 | width:100px;height:38px;background-color:#37ab40;border:0px;font-size:14px;color:#fff;font-family:'Microsoft Yahei';outline:none;cursor:pointer; 50 | } 51 | 52 | .guest_cart{ 53 | width:200px;height:40px;margin-top:34px; 54 | } 55 | 56 | .guest_cart .cart_name{ 57 | width:158px;height:38px;line-height:38px;border:1px solid #dddddd;display:block;background:url(/static/images/icons.png) 13px -300px no-repeat;font-size:14px;color:#37ab40;text-indent:56px; 58 | } 59 | 60 | .guest_cart .goods_count{ 61 | width:40px;height:40px;text-align:center;line-height:40px;font-size:18px; 62 | font-weight:bold;color:#fff;background-color:#ff8800; 63 | } 64 | 65 | 66 | /* 菜单、幻灯片样式 */ 67 | 68 | .navbar_con{height:40px;border-bottom:2px solid #39a93e} 69 | .navbar{width:1200px;margin:0 auto;} 70 | .navbar h1{width:200px;height:40px;line-height:40px;text-align: center;font-size:14px;color:#fff;background-color:#39a93e;} 71 | 72 | .navbar .subnav_con{width:200px;height:40px;background-color:#39a93e;position:relative;cursor:pointer;} 73 | 74 | .navbar .subnav_con h1{position:absolute;left:0;top:0;text-align:left;text-indent:40px} 75 | .navbar .subnav_con span{display:block;width:16px;height:9px;background:url(/static/images/down.png) no-repeat;position:absolute;right:27px;top:16px;transition:all 300ms ease-in; 76 | } 77 | 78 | .navbar .subnav_con:hover span{transform:rotateZ(180deg)} 79 | 80 | .navbar .subnav_con .subnav{position:absolute;left:0;top:40px;display:none;border-top:2px solid #39a93e;} 81 | .navbar .subnav_con:hover .subnav{display:block;} 82 | 83 | 84 | .navlist{margin-left:34px;} 85 | .navlist li{height:40px;float:left;line-height:40px;} 86 | .navlist li a{color:#666;font-size:14px} 87 | .navlist li a:hover{color:#ff8800} 88 | .navlist .interval{margin:0 15px;} 89 | 90 | 91 | .center_con{width:1200px;height:270px;margin:0 auto;} 92 | .subnav{width:198px;height:270px;border-left:1px solid #eee;border-right:1px solid #eee;} 93 | .subnav li{height:44px;border-bottom:1px solid #eee;background:url(/static/images/icons.png) 178px -257px no-repeat #fff;} 94 | 95 | .subnav li a{display:block;height:44px;line-height:44px;text-indent:71px;font-size:14px;color:#333} 96 | .subnav li a:hover{color:#ff8800} 97 | 98 | .subnav li .fruit{background:url(/static/images/icons.png) 28px 0px no-repeat;} 99 | .subnav li .seafood{background:url(/static/images/icons.png) 28px -43px no-repeat;} 100 | .subnav li .meet{background:url(/static/images/icons.png) 28px -86px no-repeat;} 101 | .subnav li .egg{background:url(/static/images/icons.png) 28px -132px no-repeat;} 102 | .subnav li .vegetables{background:url(../images/icons.png) 28px -174px no-repeat;} 103 | .subnav li .ice{background:url(/static/images/icons.png) 28px -220px no-repeat;} 104 | 105 | 106 | .slide{width:1200px;height:270px;position:relative;overflow:hidden;} 107 | .slide .slide_pics{position:relative;left:0;top:0;width:1200px;height:270px;} 108 | .slide .slide_pics li{width:760px;height:270px;position:absolute;left:0;top:0} 109 | .slide .prev,.slide .next{width:17px;height:23px;background:url(/static/images/icons.png) left -388px no-repeat;position:absolute;left:11px;top:122px;cursor:pointer;} 110 | .slide .next{background-position:left -428px;left:1170px;} 111 | .points{width:100%;height:11px;position:absolute;left:0;top:250px;text-align:center;} 112 | .points li{display:inline-block;width:11px;height:11px;margin:0 5px;background-color:#9f9f9f;border-radius:50%;cursor:pointer;} 113 | .points li.active{background-color:#cecece} 114 | 115 | .adv{width:240px;height:270px; overflow:hidden; background-color:gold;} 116 | .adv a{display:block;float:left;} 117 | 118 | 119 | /* 商品列表样式 */ 120 | 121 | .list_model{width:1200px;height:340px;margin:15px auto 0;} 122 | .list_title{height:40px;border-bottom:2px solid #42ad46} 123 | .list_title h3{height:40px;line-height:40px;font-size:16px;color:#37ab40;font-weight:bold;} 124 | .list_title .subtitle{height:20px;line-height:20px;margin-top:15px;} 125 | .list_title .subtitle span{color:#666;margin:0 10px 0 20px;} 126 | .list_title .subtitle a{color:#666;margin:0 5px;} 127 | .list_title .subtitle a:hover,.goods_more:hover{color:#ff8800} 128 | .goods_more{height:20px;margin-top:15px;color:#666} 129 | 130 | .goods_con{height:300px;} 131 | .goods_banner{width:200px;height:300px;} 132 | .goods_banner img{width:200px;height:300px;} 133 | 134 | .goods_list{width:1200px;height:299px;border-bottom:1px solid #ededed} 135 | .goods_list li{height:299px;width:235px;border-right:1px solid #ededed;float:left} 136 | .goods_list li:hover{width:248px;height:297px;border:1px solid gold;} 137 | .goods_list li:hover img{opacity:0.8} 138 | 139 | .goods_list li h4{width:200px;height:50px;margin:20px auto 0;text-align:center;} 140 | .goods_list li h4 a{font-size:14px;color:#666;font-weight:normal;line-height:24px;} 141 | .goods_list li h4 a:hover{color:#ff8800} 142 | 143 | .goods_list li img{display:block;width:180px;height:180px;margin:0 auto;} 144 | .goods_list li .prize{text-align:center;font-size:20px;color:#c40000;margin-top:5px;} 145 | 146 | /* 页面底部样式 */ 147 | .footer{ 148 | border-top:2px solid #42ad46; 149 | margin:30px 0; 150 | } 151 | 152 | .foot_link{text-align:center;margin-top:30px;} 153 | .foot_link a,.foot_link span{color:#4e4e4e;} 154 | .foot_link a:hover{color:#ff8800} 155 | .foot_link span{padding:0 10px} 156 | .footer p{text-align:center; margin-top:10px;} 157 | 158 | 159 | /* 二级页面面包屑导航 */ 160 | .breadcrumb{ 161 | width:1200px;height:40px;margin:0 auto; 162 | } 163 | .breadcrumb a{line-height:40px;color:#37ab40} 164 | .breadcrumb a:hover{color:#ff8800} 165 | .breadcrumb span{line-height:40px;color:#666;padding:0 5px;} 166 | 167 | 168 | .main_wrap{width:1200px;margin:0 auto;} 169 | .l_wrap{width:200px;} 170 | .r_wrap{width:1200px;} 171 | 172 | 173 | /* 新品推荐样式 */ 174 | 175 | .new_goods{ 176 | border:1px solid #ededed; 177 | border-top:2px solid #37ab40; 178 | padding-bottom:10px; 179 | } 180 | 181 | .new_goods h3{ 182 | height:33px;line-height:33px;background-color:#fcfcfc;border-bottom:1px solid #ededed;font-size:14px;font-weight:normal;text-indent:10px; 183 | } 184 | 185 | .new_goods ul{width:160px;margin:0 auto;overflow:hidden;} 186 | .new_goods li{border-bottom:1px solid #ededed;margin-bottom:-1px;} 187 | .new_goods li img{display:block;width:150px;height:150px;margin:10px auto;} 188 | .new_goods li h4{width:160px;margin:0 auto;} 189 | .new_goods li h4 a{font-weight:normal;color:#666;display:block;width:160px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;} 190 | .new_goods li .prize{font-size:14px;color:#da260e;margin:10px auto;} 191 | 192 | 193 | 194 | /* 商品列表样式 */ 195 | 196 | .sort_bar{height:30px;background-color:#f0fdec} 197 | .sort_bar a{display:block;height:30px;line-height:30px;padding:0 20px;float:left;color:#000} 198 | .sort_bar .active{background-color:#37ab40;color:#fff;} 199 | 200 | 201 | .goods_type_list{ 202 | margin:10px auto 0; 203 | } 204 | 205 | .goods_type_list li{ 206 | width:196px; 207 | float:left; 208 | margin-bottom:10px 209 | } 210 | 211 | .goods_type_list li img{width:160px;height:160px;display:block;margin:10px auto;} 212 | .goods_type_list li h4{width:160px;margin:0 auto;} 213 | .goods_type_list li h4 a{font-weight:normal;color:#666;display:block;width:160px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;} 214 | .operate{width:160px;margin:10px auto;position:relative;} 215 | .goods_type_list .operate .prize{color:#da260e; font-size:14px;} 216 | .goods_type_list .operate .unit{color:#999;padding-left:5px;} 217 | .goods_type_list .operate .add_goods{display:inline-block;width:15px;height:15px;background:url(/static/images/shop_cart.png);position:absolute;right:0;top:3px;} 218 | 219 | 220 | /* 分页样式 */ 221 | 222 | .pagenation{height:32px;text-align:center;font-size:0;margin:30px auto;} 223 | .pagenation a{display:inline-block;border:1px solid #d2d2d2;background-color:#f8f6f7;font-size:12px;padding:7px 10px;color:#666;margin:5px} 224 | 225 | .pagenation .active{background-color:#fff;color:#43a200} 226 | 227 | 228 | /* 商品详情样式 */ 229 | .goods_detail_con{ 230 | width:1198px; 231 | height:398px; 232 | border:1px solid #ededed; 233 | margin:0 auto 20px; 234 | } 235 | 236 | .goods_detail_pic{width:350px;height:350px;margin:24px 0 0 24px;} 237 | .goods_detail_pic img{width: 350px;height: 350px} 238 | .goods_detail_list{ 239 | width:730px;height:350px;margin:24px 24px 0 0; 240 | } 241 | .goods_detail_list h3{font-size:24px;line-height:24px;color:#666;font-weight:normal;} 242 | .goods_detail_list p{color:#666;line-height:40px;} 243 | .prize_bar{height:72px;background-color:#fff5f5;line-height:72px;} 244 | .prize_bar .show_pirze{font-size:20px;color:#ff3e3e;padding-left:20px} 245 | .prize_bar .show_pirze em{font-style:normal;font-size:36px;padding-left:10px} 246 | .prize_bar .show_unit{padding-left:150px} 247 | 248 | .goods_num{height:52px;margin-top:19px;} 249 | .goods_num .num_name{width:70px;height:52px;line-height:52px;} 250 | .goods_num .num_add{width:75px;height:50px;border:1px solid #dddddd} 251 | .goods_num .num_add input{width:49px;height:50px;text-align:center;line-height:50px;border:0px;outline:none;font-size:14px;color:#666} 252 | .goods_num .num_add .add,.goods_num .num_add .minus{width:25px;line-height:25px;text-align:center;border-left:1px solid #ddd;border-bottom:1px solid #ddd;color:#666;font-size:14px} 253 | .goods_num .num_add .minus{border-bottom:0px} 254 | 255 | .total{height:35px;line-height:35px;margin-top:25px;} 256 | .total em{font-style:normal;color:#ff3e3e;font-size:18px} 257 | 258 | .operate_btn{height:40px;margin-top:35px;font-size:0;position:relative;} 259 | .operate_btn .buy_btn,.operate_btn .add_cart{display:inline-block;width:178px;height:38px;border:1px solid #c40000;font-size:14px;color:#c40000;line-height:38px;text-align:center;background-color:#ffeded;} 260 | .operate_btn .add_cart{background-color:#c40000;color:#fff;margin-left:10px;position:relative;z-index:10;} 261 | 262 | .add_jump{width:20px;height:20px;background-color:#c40000;position:absolute;left:268px;top:10px;border-radius:50%;z-index:9;display:none;} 263 | 264 | .detail_tab{ 265 | height:35px; 266 | border-bottom:1px solid #37ab40 267 | } 268 | 269 | .detail_tab li{height:34px;line-height:34px;padding:0 30px;font-size:14px;color:#333333;float:left;border:1px solid #e8e8e8;border-bottom:0px;cursor:pointer;background-color:#faf8f8} 270 | 271 | .detail_tab li.active{border-top:2px solid #37ab40;position:relative;background-color:#fff;border-left:1px solid #37ab40;border-right:1px solid #37ab40;top:-1px;height:35px;} 272 | 273 | .tab_content dt{margin-top:10px;font-size:16px;color:#044d39} 274 | .tab_content dd{line-height:24px;margin-top:5px;} 275 | 276 | 277 | /* 登录页 */ 278 | 279 | .login_top{width:960px;height:130px;margin:0 auto;} 280 | .login_logo{display:block;width:193px;height:76px;margin-top:30px;} 281 | .login_form_bg{height:480px;background-color:#518e17} 282 | .no-mp{margin-top:0px;} 283 | .login_form_wrap{width:960px;height:480px;margin:0 auto;} 284 | .login_banner{width:381px;height:322px;background:url(/static/images/login_banner.png) no-repeat;margin-top:90px;} 285 | .slogan{width:40px;height:300px;font-size:30px;color:#f0f9e8;text-align:center;line-height:36px;margin:80px 0 0 120px} 286 | .login_form{width:368px;height:378px;border:1px solid #c6c6c5;background-color:#fff; margin-top:50px;} 287 | 288 | .login_title{height:60px;width:308px;margin:10px auto;border-bottom:1px solid #e0e0e0;} 289 | 290 | .login_title h1{font-size:24px;height:60px;line-height:60px;color:#a8a8a8;float:left;font-weight:bold;margin-left:44px;} 291 | .login_title a{width:100px;height:20px;display:block;font-size:16px;color:#5fb42a;text-indent:26px;background:url(/static/images/icons02.png) left 5px no-repeat;float:left;margin:20px 0 0 36px} 292 | 293 | .form_input{width:308px;height:250px;margin:20px auto;position:relative;} 294 | .name_input,.pass_input{width:306px;height:36px;border:1px solid #e0e0e0;background:url(/static/images/icons02.png) 280px -41px no-repeat #f8f8f8;outline:none;font-size:14px;text-indent:10px;position: absolute;left:0;top:0} 295 | .pass_input{top:65px;background-position:280px -95px;} 296 | 297 | .user_error,.pwd_error{color:#f00;position:absolute;left:0;top:43px;} 298 | 299 | .pwd_error{top:110px;} 300 | 301 | .more_input{position:absolute;left:0;top:130px;width:100%} 302 | 303 | .more_input input{float:left;margin-top:2px;} 304 | .more_input label{float:left;margin-left:10px;} 305 | .more_input a{float:right;color:#666} 306 | .more_input a:hover{color:#ff8800} 307 | 308 | .input_submit{width:100%;height:40px;position:absolute;left:0;top:180px;background-color:#47aa34;color:#fff;font-size:22px;border:0px;font-family:'Microsoft Yahei';cursor:pointer;} 309 | 310 | 311 | /* 注册页面 */ 312 | .register_con{ 313 | width:700px; 314 | height:560px; 315 | margin:50px auto 0; 316 | background:url(/static/images/interval_line.png) 300px top no-repeat; 317 | } 318 | 319 | .l_con{width:300px;} 320 | .reg_logo{width:200px;height:76px;float:right;margin-right:30px;} 321 | .reg_slogan{width:300px;height:30px;float:right;text-align:right;font-size:24px;color:#69a81e;margin:20px 30px 0 0;} 322 | .reg_banner{width:251px;height:329px;background:url(/static/images/register_banner.png) no-repeat;float:right; margin:20px 10px 0 0;opacity:0.5} 323 | 324 | 325 | .r_con{width:400px;} 326 | .reg_title{width:360px;height:50px;float:left;margin-left:30px;border-bottom:1px solid #e0e0e0} 327 | .reg_title h1{height:50px;line-height:50px;float:left;font-size:24px;color:#a8a8a8;font-weight:bold;} 328 | .reg_title a{float:right;height:20px;line-height:20px;font-size:16px;color:#5fb42a;padding-right:20px;background:url(/static/images/icons02.png) 35px 3px no-repeat;margin-top:15px} 329 | 330 | .reg_form{width:360px;margin:30px 0 0 30px;float:left;position:relative;} 331 | .reg_form li{height:70px;} 332 | .reg_form li label{width:70px;height:40px;line-height:40px;float:left;font-size:14px;color:#a8a8a8} 333 | .reg_form li input{width:288px;height:38px;border:1px solid #e0e0e0;float:left;outline:none;text-indent:10px;background-color:#f8f8f8} 334 | .reg_form li.agreement input{width:15px;height:15px;float:left;margin-top:13px} 335 | .reg_form li.agreement label{width:300px;float:left;margin-left:10px;} 336 | .reg_form li.reg_sub input{width:360px;height:40px;background-color:#47aa34;font-size:18px;color:#fff;font-family:'Microsoft Yahei';cursor:pointer;} 337 | .reg_form li .error_tip{float:left;height:30px;line-height:30px;margin-left:70px;color:#e62e2e;display:none;} 338 | .reg_form li .error_tip2{float:left;height:20px;line-height:20px;color:#e62e2e;} 339 | 340 | 341 | .sub_page_name{font-size:18px;color:#666;margin:50px 0 0 20px} 342 | 343 | .total_count{ 344 | width:1200px;margin:0 auto;height:40px;line-height:40px;font-size:14px; 345 | } 346 | .total_count em{ 347 | font-size:16px;color:#ff4200;margin:0 5px; 348 | } 349 | 350 | .cart_list_th{width:1198px;border:1px solid #ddd;background-color:#f7f7f7;margin:0 auto;} 351 | .cart_list_th li{height:40px;line-height:40px;float:left;text-align:center;} 352 | .cart_list_th .col01{width:26%;} 353 | .cart_list_th .col02{width:16%;} 354 | .cart_list_th .col03{width:13%;} 355 | .cart_list_th .col04{width:12%;} 356 | .cart_list_th .col05{width:15%;} 357 | .cart_list_th .col06{width:18%;} 358 | 359 | .cart_list_td{width:1198px;border:1px solid #ddd;background-color:#edfff9;margin:0 auto;margin-top:-1px;} 360 | .cart_list_td li{height:120px;line-height:120px;float:left;text-align:center;} 361 | 362 | .cart_list_td .col01{width:4%;} 363 | .cart_list_td .col02{width:12%;} 364 | .cart_list_td .col03{width:10%;} 365 | .cart_list_td .col04{width:16%;} 366 | .cart_list_td .col05{width:13%;} 367 | .cart_list_td .col06{width:12%;} 368 | .cart_list_td .col07{width:15%;} 369 | .cart_list_td .col08{width:18%;} 370 | 371 | .cart_list_td .col02 img{width:100px;height:100px;border:1px solid #ddd;display:block;margin:10px auto 0;} 372 | .cart_list_td .col03{height:48px;text-align:left;line-height:24px;margin-top:38px;} 373 | .cart_list_td .col03 em{color:#999} 374 | .cart_list_td .col08 a{color:#666} 375 | 376 | .cart_list_td .col06 .num_add{width:98px;height:28px;border:1px solid #ddd;margin:40px auto 0;} 377 | .cart_list_td .col06 .num_add a{width:29px;height:28px;line-height:28px;background-color:#f3f3f3;font-size:14px;color:#666} 378 | .cart_list_td .col06 .num_add input{width:38px;height:28px;text-align:center;line-height:30px;border:0px;display:block;float:left;outline:none;border-left:1px solid #ddd;border-right:1px solid #ddd;} 379 | 380 | 381 | .settlements{width:1198px;height:78px;border:1px solid #ddd;background-color:#fff4e8;margin:-1px auto 0;} 382 | .settlements li{line-height:78px;float:left;} 383 | .settlements .col01{width:4%;text-align:center} 384 | .settlements .col02{width:12%;} 385 | .settlements .col03{width:69%; height:48px; line-height:28px;text-align:right;margin-top:10px;} 386 | .settlements .col03 span{color:#ff0000;padding-right:5px} 387 | .settlements .col03 em{color:#ff3d3d;font-size:22px;font-weight:bold;} 388 | .settlements .col03 span{color:#ff0000;} 389 | .settlements .col03 b{color:#ff0000;font-size:14px;padding:0 5px;} 390 | 391 | .settlements .col04{width:14%;text-align:center;float:right;} 392 | .settlements .col04 a{display:block;height:78px;background-color:#ff3d3d;text-align:center;line-height:78px;color:#fff;font-size:24px} 393 | 394 | 395 | .common_title{width:1200px;margin:20px auto 0;font-size:14px;} 396 | 397 | .common_list_con{width:1200px;border:1px solid #dddddd;border-top:2px solid #00bc6f;margin:10px auto 0;background-color:#f7f7f7;position:relative;} 398 | 399 | .common_list_con dl{margin:20px;} 400 | .common_list_con dt{font-size:14px;font-weight:bold;margin-bottom:10px} 401 | .common_list_con dd input{vertical-align:bottom;margin-right:10px} 402 | 403 | .edit_site{position:absolute; right:20px;top:30px;width:100px;height:30px;background-color:#37ab40;text-align:center;line-height:30px;color:#fff} 404 | 405 | .pay_style_con{margin:20px;} 406 | .pay_style_con input{float:left;margin:14px 7px 0 0;} 407 | .pay_style_con label{float:left;border:1px solid #ccc;background-color:#fff;padding:10px 10px 10px 40px;margin-right:25px} 408 | 409 | .pay_style_con .cash{background:url(/static/images/pay_icons.png) 8px top no-repeat #fff;} 410 | .pay_style_con .weixin{background:url(/static/images/pay_icons.png) 6px -36px no-repeat #fff;} 411 | 412 | .pay_style_con .zhifubao{background:url(/static/images/pay_icons.png) 12px -72px no-repeat #fff;width:50px;height:16px} 413 | 414 | .pay_style_con .bank{background:url(/static/images/pay_icons.png) 6px -108px no-repeat #fff;} 415 | 416 | 417 | .goods_list_th{height:40px;border-bottom:1px solid #ccc} 418 | .goods_list_th li{float:left;line-height:40px;text-align:center;} 419 | .goods_list_th .col01{width:25%} 420 | .goods_list_th .col02{width:20%} 421 | .goods_list_th .col03{width:25%} 422 | .goods_list_th .col04{width:15%} 423 | .goods_list_th .col05{width:15%} 424 | 425 | .goods_list_td{height:80px;border-bottom:1px solid #eeeded} 426 | .goods_list_td li{float:left;line-height:80px;text-align:center;} 427 | .goods_list_td .col01{width:4%} 428 | .goods_list_td .col02{width:6%} 429 | .goods_list_td .col03{width:15%} 430 | .goods_list_td .col04{width:20%} 431 | .goods_list_td .col05{width:25%} 432 | .goods_list_td .col06{width:15%} 433 | .goods_list_td .col07{width:15%} 434 | 435 | .goods_list_td .col02{text-align:right} 436 | .goods_list_td .col02 img{width:63px;height:63px;border:1px solid #ddd;display:block;margin:7px 0;float:right;} 437 | .goods_list_td .col03{text-align:left;text-indent:20px} 438 | 439 | 440 | .settle_con{margin:10px} 441 | .total_goods_count,.transit,.total_pay{line-height:24px;text-align:right} 442 | .total_goods_count em,.total_goods_count b,.transit b,.total_pay b{font-size:14px;color:#ff4200;padding:0 5px;} 443 | 444 | .order_submit{width:1200px;margin:20px auto;} 445 | .order_submit a{width:160px;height:40px;line-height:40px;text-align:center;background-color:#47aa34;color:#fff;font-size:16px;display:block;float:right} 446 | 447 | 448 | .order_list_th{width:1198px;border:1px solid #ddd;background-color:#f7f7f7;margin:20px auto 0;} 449 | .order_list_th li{float:left;height:30px;line-height:30px} 450 | .order_list_th .col01{width:20%;margin-left:20px} 451 | .order_list_th .col02{width:20%} 452 | 453 | 454 | .order_list_table{ 455 | width:1200px; 456 | border-collapse:collapse; 457 | border-spacing:0px; 458 | border:1px solid #ddd; 459 | margin:-1px auto 0; 460 | } 461 | 462 | .order_list_table td{ 463 | border:1px solid #ddd; 464 | text-align:center; 465 | } 466 | 467 | .order_goods_list{border-bottom:1px solid #ddd;margin-bottom:-2px;} 468 | .order_goods_list li{float:left; height:80px;line-height:80px;} 469 | .order_goods_list .col01{width:20%} 470 | .order_goods_list .col01 img{width:60px;height:60px;border:1px solid #ddd;margin:10px auto;} 471 | .order_goods_list .col02{width:50%;text-align:left;} 472 | .order_goods_list .col02 em{color:#999;margin-left:10px} 473 | .order_goods_list .col03{width:10%} 474 | .order_goods_list .col04{width:20%} 475 | 476 | .oper_btn{display:inline-block;border:1px solid #ddd;color:#666;padding:5px 10px} 477 | 478 | .popup_con{display:none;} 479 | .popup{width:300px;height:150px;border:1px solid #dddddd;border-top:2px solid #00bc6f;background-color:#f7f7f7;position:fixed; 480 | left:50%; 481 | margin-left:-150px; 482 | top:50%; 483 | margin-top:-75px; 484 | z-index:1000; 485 | } 486 | 487 | .popup p{height:150px;line-height:150px;text-align:center;font-size:18px;} 488 | 489 | .mask{width:100%;height:100%;position:fixed;left:0;top:0;background-color:#000;opacity:0.3;z-index:999;} 490 | 491 | 492 | .main_con{ 493 | width:1200px; 494 | margin:0 auto; 495 | background:url(/static/images/left_bg.jpg) repeat-y; 496 | } 497 | 498 | .left_menu_con{ 499 | width:200px; 500 | float:left; 501 | } 502 | 503 | .left_menu_con h3{ 504 | font-size:16px; 505 | line-height:40px; 506 | border-bottom:1px solid #ddd; 507 | text-align:center; 508 | margin-bottom:10px; 509 | } 510 | 511 | .left_menu_con ul li{ 512 | line-height:40px; 513 | text-align:center; 514 | font-size:14px; 515 | } 516 | 517 | .left_menu_con ul li a{ 518 | color:#666; 519 | } 520 | 521 | .left_menu_con ul li .active{ 522 | color:#ff8800; 523 | font-weight:bold; 524 | } 525 | 526 | .right_content{ 527 | width:980px; 528 | float:right; 529 | min-height:500px; 530 | } 531 | 532 | .w980{ 533 | width:980px; 534 | } 535 | 536 | .w978{ 537 | width:978px; 538 | } 539 | 540 | 541 | .common_title2{height:20px;line-height:20px;font-size:16px;margin:10px 0;} 542 | .user_info_list{ 543 | background-color:#f9f9f9; 544 | margin:10px 0 15px; 545 | padding:10px 0; 546 | height:90px; 547 | } 548 | 549 | .user_info_list li{ 550 | line-height:30px; 551 | text-indent:30px; 552 | font-size:14px; 553 | } 554 | 555 | .user_info_list li span{ 556 | width:100px; 557 | float:left; 558 | text-align:right; 559 | } 560 | 561 | .info_con{ 562 | width:980px; 563 | } 564 | 565 | .info_l{ 566 | width:600px; 567 | float:left; 568 | } 569 | 570 | .info_r{ 571 | width:360px; 572 | float:right; 573 | } 574 | 575 | .site_con{ 576 | background-color:#f9f9f9; 577 | padding:10px 0; 578 | margin-bottom:20px; 579 | } 580 | 581 | .site_con dt{ 582 | font-size:14px; 583 | line-height:30px; 584 | text-indent:30px; 585 | font-weight:bold; 586 | } 587 | 588 | .site_con dd{ 589 | font-size:14px; 590 | line-height:30px; 591 | text-indent:30px; 592 | } 593 | 594 | .site_con .form_group{ 595 | height:40px; 596 | line-height:40px; 597 | margin-top:10px; 598 | } 599 | 600 | .site_con .form_group label{ 601 | width:100px; 602 | float:left; 603 | text-align:right; 604 | font-size:14px; 605 | height:40px; 606 | line-height:40px; 607 | } 608 | 609 | .site_con .form_group input{ 610 | width:300px; 611 | height:25px; 612 | border:1px solid #ddd; 613 | float:left; 614 | outline:none; 615 | margin-top:7px; 616 | text-indent:10px; 617 | } 618 | 619 | .site_con .form_group2{ 620 | height:90px; 621 | } 622 | 623 | .site_area{ 624 | width:280px; 625 | height:60px; 626 | border:1px solid #ddd; 627 | outline:none; 628 | padding:10px; 629 | } 630 | .info_submit{ 631 | width:80px; 632 | height:30px; 633 | background-color:#37ab40; 634 | border:0px; 635 | color:#fff; 636 | margin:10px 0 10px 100px; 637 | cursor:pointer; 638 | font-family:'Microsoft Yahei' 639 | } 640 | 641 | .stress{ 642 | color:#ff8800; 643 | } -------------------------------------------------------------------------------- /static/js/jquery-ui.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.12.1 - 2016-10-06 2 | * http://jqueryui.com 3 | * Includes: widget.js, position.js, data.js, keycode.js, scroll-parent.js, unique-id.js, widgets/draggable.js, widgets/autocomplete.js, widgets/menu.js, widgets/mouse.js, effect.js 4 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 5 | 6 | (function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){t.ui=t.ui||{},t.ui.version="1.12.1";var e=0,i=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},l=e.split(".")[0];e=e.split(".")[1];var h=l+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][h.toLowerCase()]=function(e){return!!t.data(e,h)},t[l]=t[l]||{},n=t[l][e],o=t[l][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:l,widgetName:e,widgetFullName:h}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var s,n,o=i.call(arguments,1),a=0,r=o.length;r>a;a++)for(s in o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void 0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,s){var n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=i.call(arguments,1),l=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):l=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new s(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var l=s.match(/^([\w:-]*)\s*(.*)$/),h=l[1]+o.eventNamespace,c=l[2];c?n.on(h,c,r):i.on(h,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,l=/top|center|bottom/,h=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
    "),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};h>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),l.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,l=n-r,h=r+e.collisionWidth-a-n;e.collisionWidth>a?l>0&&0>=h?(i=t.left+l+e.collisionWidth-a-n,t.left+=l-i):t.left=h>0&&0>=l?n:l>h?n+a-e.collisionWidth:n:l>0?t.left+=l:h>0?t.left-=h:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,l=n-r,h=r+e.collisionHeight-a-n;e.collisionHeight>a?l>0&&0>=h?(i=t.top+l+e.collisionHeight-a-n,t.top+=l-i):t.top=h>0&&0>=l?n:l>h?n+a-e.collisionHeight:n:l>0?t.top+=l:h>0?t.top-=h:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,l=n.isWindow?n.scrollLeft:n.offset.left,h=t.left-e.collisionPosition.marginLeft,c=h-l,u=h+e.collisionWidth-r-l,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-l,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,l=n.isWindow?n.scrollTop:n.offset.top,h=t.top-e.collisionPosition.marginTop,c=h-l,u=h+e.collisionHeight-r-l,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-l,(i>0||u>a(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var s=!1;t(document).on("mouseup",function(){s=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!s){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,n=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return n&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),s=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,s=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")},t.widget("ui.draggable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(this._blurActiveElement(e),this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var e=t(this);return t("
    ").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var i=t.ui.safeActiveElement(this.document[0]),s=t(e.target);s.closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp(new t.Event("mouseup",e)),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1},_mouseUp:function(e){return this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper),n=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options,o=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,t(o).width()-this.helperProportions.width-this.margins.left,(t(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0)},_convertPositionTo:function(t,e){e||(e=this.position);var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,n,o,a=this.options,r=this._isRootNode(this.scrollParent[0]),l=t.pageX,h=t.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.lefti[2]&&(l=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(h=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,h=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,l=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o),"y"===a.axis&&(l=this.originalPageX),"x"===a.axis&&(h=this.originalPageY)),{top:h-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var n=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,n))})},stop:function(e,i,s){var n=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,n))})},drag:function(e,i,s){t.each(s.sortables,function(){var n=!1,o=this;o.positionAbs=s.positionAbs,o.helperProportions=s.helperProportions,o.offset.click=s.offset.click,o._intersectsWith(o.containerCache)&&(n=!0,t.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==o&&this._intersectsWith(this.containerCache)&&t.contains(o.element[0],this.element[0])&&(n=!1),n})),n?(o.isOver||(o.isOver=1,s._parent=i.helper.parent(),o.currentItem=i.helper.appendTo(o.element).data("ui-sortable-item",!0),o.options._helper=o.options.helper,o.options.helper=function(){return i.helper[0]},e.target=o.currentItem[0],o._mouseCapture(e,!0),o._mouseStart(e,!0,!0),o.offset.click.top=s.offset.click.top,o.offset.click.left=s.offset.click.left,o.offset.parent.left-=s.offset.parent.left-o.offset.parent.left,o.offset.parent.top-=s.offset.parent.top-o.offset.parent.top,s._trigger("toSortable",e),s.dropped=o.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,o.fromOutside=s),o.currentItem&&(o._mouseDrag(e),i.position=o.position)):o.isOver&&(o.isOver=0,o.cancelHelperRemoval=!0,o.options._revert=o.options.revert,o.options.revert=!1,o._trigger("out",e,o._uiHash(o)),o._mouseStop(e,!0),o.options.revert=o.options._revert,o.options.helper=o.options._helper,o.placeholder&&o.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var n=t("body"),o=s.options; 7 | n.css("cursor")&&(o._cursor=n.css("cursor")),n.css("cursor",o.cursor)},stop:function(e,i,s){var n=s.options;n._cursor&&t("body").css("cursor",n._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("opacity")&&(o._opacity=n.css("opacity")),n.css("opacity",o.opacity)},stop:function(e,i,s){var n=s.options;n._opacity&&t(i.helper).css("opacity",n._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var n=s.options,o=!1,a=s.scrollParentNotHidden[0],r=s.document[0];a!==r&&"HTML"!==a.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+a.offsetHeight-e.pageY=0;d--)l=s.snapElements[d].left-s.margins.left,h=l+s.snapElements[d].width,c=s.snapElements[d].top-s.margins.top,u=c+s.snapElements[d].height,l-g>_||m>h+g||c-g>b||v>u+g||!t.contains(s.snapElements[d].item.ownerDocument,s.snapElements[d].item)?(s.snapElements[d].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=!1):("inner"!==f.snapMode&&(n=g>=Math.abs(c-b),o=g>=Math.abs(u-v),a=g>=Math.abs(l-_),r=g>=Math.abs(h-m),n&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left)),p=n||o||a||r,"outer"!==f.snapMode&&(n=g>=Math.abs(c-v),o=g>=Math.abs(u-b),a=g>=Math.abs(l-m),r=g>=Math.abs(h-_),n&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left)),!s.snapElements[d].snapping&&(n||o||a||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=n||o||a||r||p)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var n,o=s.options,a=t.makeArray(t(o.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});a.length&&(n=parseInt(t(a[0]).css("zIndex"),10)||0,t(a).each(function(e){t(this).css("zIndex",n+e)}),this.css("zIndex",n+a.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("zIndex")&&(o._zIndex=n.css("zIndex")),n.css("zIndex",o.zIndex)},stop:function(e,i,s){var n=s.options;n._zIndex&&t(i.helper).css("zIndex",n._zIndex)}}),t.ui.draggable,t.widget("ui.menu",{version:"1.12.1",defaultElement:"
      ",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var i=t(e.target),s=t(t.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var i=t(e.target).closest(".ui-menu-item"),s=t(e.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(e,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){var i=!t.contains(this.element[0],t.ui.safeActiveElement(this.document[0]));i&&this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var e=this.element.find(".ui-menu-item").removeAttr("role aria-disabled"),i=e.children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var e=t(this);e.data("ui-menu-submenu-caret")&&e.remove()})},_keydown:function(e){var i,s,n,o,a=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:a=!1,s=this.previousFilter||"",o=!1,n=e.keyCode>=96&&105>=e.keyCode?""+(e.keyCode-96):String.fromCharCode(e.keyCode),clearTimeout(this.filterTimer),n===s?o=!0:n=s+n,i=this._filterMenuItems(n),i=o&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(e.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(e,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}a&&e.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i,s,n,o,a=this,r=this.options.icons.submenu,l=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=l.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),i=e.prev(),s=t("").data("ui-menu-submenu-caret",!0);a._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),e.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),e=l.add(this.element),i=e.find(this.options.items),i.not(".ui-menu-item").each(function(){var e=t(this);a._isDivider(e)&&a._addClass(e,"ui-menu-divider","ui-widget-content")}),n=i.not(".ui-menu-item, .ui-menu-divider"),o=n.children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(o,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){if("icons"===t){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)}this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t+""),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.outerHeight(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this._removeClass(s.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(e){return!t(e.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(e),void 0)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items).first())),void 0):(this.next(e),void 0)},_hasScroll:function(){return this.element.outerHeight()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;this.isMultiLine=o||!a&&this._isContentEditable(this.element),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,void 0;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),void 0):(this._searchTimeout(t),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(t),this._change(t),void 0)}}),this._initSource(),this.menu=t("
        ").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,this.element[0]!==t.ui.safeActiveElement(this.document[0])&&this.element.trigger("focus")})},menufocus:function(e,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",e,{item:n})&&e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&t.trim(s).length&&(this.liveRegion.children().hide(),t("
        ").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,i){var s=i.item.data("ui-autocomplete-item"),n=this.previous;this.element[0]!==t.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=n,this._delay(function(){this.previous=n,this.selectedItem=s})),!1!==this._trigger("select",e,{item:s})&&this._value(s.value),this.term=this._value(),this.close(e),this.selectedItem=s}}),this.liveRegion=t("
        ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(e){var i=this.menu.element[0];return e.target===this.element[0]||e.target===i||t.contains(i,e.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){var e=this.term===this._value(),i=this.menu.element.is(":visible"),s=t.altKey||t.ctrlKey||t.metaKey||t.shiftKey;(!e||e&&!i&&!s)&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(t("
        ").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[t](e),void 0):(this.search(null,e),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.children().hide(),t("
        ").text(i).appendTo(this.liveRegion))}}),t.ui.autocomplete;var n="ui-effects-",o="ui-effects-style",a="ui-effects-animated",r=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=h(),n=s._rgba=[];return i=i.toLowerCase(),f(l,function(t,o){var a,r=o.re.exec(i),l=r&&o.parse(r),h=o.space||"rgba";return l?(a=s[h](l),s[c[h].cache]=a[c[h].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,l=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],h=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=h.support={},p=t("

        ")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),h.fn=t.extend(h.prototype,{parse:function(n,a,r,l){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,l],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof h?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=h(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=h(t),n=s._space(),o=c[n],a=0===this.alpha()?h("transparent"):this,r=a[o.cache]||o.to(a._rgba),l=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],h=s[o],c=u[n.type]||{};null!==h&&(null===a?l[o]=h:(c.mod&&(h-a>c.mod/2?a+=c.mod:a-h>c.mod/2&&(a-=c.mod)),l[o]=i((h-a)*e+a,n)))}),this[n](l)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=h(e)._rgba;return h(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),h.fn.parse.prototype=h.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),l=Math.min(s,n,o),h=r-l,c=r+l,u=.5*c;return e=l===r?0:s===r?60*(n-o)/h+360:n===r?60*(o-s)/h+120:60*(s-n)/h+240,i=0===h?0:.5>=u?h/c:h/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,l=n.to,c=n.from;h.fn[s]=function(s){if(l&&!this[a]&&(this[a]=l(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=h(c(d)),n[a]=d,n):h(d)},f(o,function(e,i){h.fn[e]||(h.fn[e]=function(n){var o,a=t.type(n),l="alpha"===e?this._hsla?"hsla":"rgba":s,h=this[l](),c=h[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),h[i.idx]=n,this[l](h)))})})}),h.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=h(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(l){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(l){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=h(e.elem,i),e.end=h(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},h.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(r),function(){function e(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function i(e,i){var s,o,a={};for(s in i)o=i[s],e[s]!==o&&(n[s]||(t.fx.step[s]||!isNaN(parseFloat(o)))&&(a[s]=o));return a}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(r.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(n,o,a,r){var l=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",h=l.children?a.find("*").addBack():a;h=h.map(function(){var i=t(this);return{el:i,start:e(this)}}),o=function(){t.each(s,function(t,e){n[e]&&a[e+"Class"](n[e])})},o(),h=h.map(function(){return this.end=e(this.el[0]),this.diff=i(this.start,this.end),this}),a.attr("class",r),h=h.map(function(){var e=this,i=t.Deferred(),s=t.extend({},l,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,h.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),l.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(e){return function(i,s,n,o,a){return"boolean"==typeof s||void 0===s?n?t.effects.animateClass.call(this,s?{add:i}:{remove:i},n,o,a):e.apply(this,arguments):t.effects.animateClass.call(this,{toggle:i},s,n,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function e(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function i(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}function s(t,e){var i=e.outerWidth(),s=e.outerHeight(),n=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,o=n.exec(t)||["",0,i,s,0];return{top:parseFloat(o[1])||0,right:"auto"===o[2]?i:parseFloat(o[2]),bottom:"auto"===o[3]?s:parseFloat(o[3]),left:parseFloat(o[4])||0}}t.expr&&t.expr.filters&&t.expr.filters.animated&&(t.expr.filters.animated=function(e){return function(i){return!!t(i).data(a)||e(i)}}(t.expr.filters.animated)),t.uiBackCompat!==!1&&t.extend(t.effects,{save:function(t,e){for(var i=0,s=e.length;s>i;i++)null!==e[i]&&t.data(n+e[i],t[0].style[e[i]]) 8 | },restore:function(t,e){for(var i,s=0,o=e.length;o>s;s++)null!==e[s]&&(i=t.data(n+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("

        ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,n="vertical"!==i?(e||100)/100:1;return{height:t.height()*n,width:t.width()*s,outerHeight:t.outerHeight()*n,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();e>1&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(o,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(o)||"",t.removeData(o)},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(e){var i,s=e.css("position"),o=e.position();return e.css({marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()),/^(static|relative)/.test(s)&&(s="absolute",i=t("<"+e[0].nodeName+">").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),"float":e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data(n+"placeholder",i)),e.css({position:s,left:o.left,top:o.top}),i},removePlaceholder:function(t){var e=n+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function i(e){function i(){l.removeData(a),t.effects.cleanUp(l),"hide"===s.mode&&l.hide(),r()}function r(){t.isFunction(h)&&h.call(l[0]),t.isFunction(e)&&e()}var l=t(this);s.mode=u.shift(),t.uiBackCompat===!1||o?"none"===s.mode?(l[c](),r()):n.call(l[0],s,i):(l.is(":hidden")?"hide"===c:"show"===c)?(l[c](),r()):n.call(l[0],s,r)}var s=e.apply(this,arguments),n=t.effects.effect[s.effect],o=n.mode,r=s.queue,l=r||"fx",h=s.complete,c=s.mode,u=[],d=function(e){var i=t(this),s=t.effects.mode(i,c)||o;i.data(a,!0),u.push(s),o&&("show"===s||s===o&&"hide"===s)&&i.show(),o&&"none"===s||t.effects.saveStyle(i),t.isFunction(e)&&e()};return t.fx.off||!n?c?this[c](s.duration,h):this.each(function(){h&&h.call(this)}):r===!1?this.each(d).each(i):this.queue(l,d).queue(l,i)},show:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="show",this.effect.call(this,n)}}(t.fn.show),hide:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(t.fn.hide),toggle:function(t){return function(s){if(i(s)||"boolean"==typeof s)return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):s(this.css("clip"),this)},transfer:function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,l=o?a.scrollLeft():0,h=n.offset(),c={top:h.top-r,left:h.left-l,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("
        ").appendTo("body").addClass(e.className).css({top:u.top-r,left:u.left-l,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}(),t.effects}); --------------------------------------------------------------------------------