first init
|
@ -0,0 +1,11 @@
|
|||
.DS_Store
|
||||
frontend/node_modules
|
||||
/dist
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
# django
|
||||
db.sqlite3
|
||||
Pipfile.lock
|
|
@ -0,0 +1,151 @@
|
|||
"""
|
||||
Django settings for BookingService project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 2.1.7.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/2.1/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/2.1/ref/settings/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'l%o*o21h_a5^f+3xblzzfch*&2k_4pcak(o#t2@vymeb_mcy3$'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'rest_framework',
|
||||
'django_filters',
|
||||
'user',
|
||||
'booking',
|
||||
'utils',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'BookingService.urls'
|
||||
|
||||
AUTH_USER_MODEL = 'user.User'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [os.path.join(BASE_DIR, 'frontend', 'dist')],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'BookingService.wsgi.application'
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/2.1/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'zh-hans'
|
||||
|
||||
TIME_ZONE = 'Asia/Shanghai'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = False
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/2.1/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, "static")
|
||||
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, 'frontend', 'dist', 'static'),
|
||||
]
|
||||
|
||||
# Django Restfull Framework
|
||||
REST_FRAMEWORK = {
|
||||
'EXCEPTION_HANDLER': 'utils.handler.custom_exception_handler',
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework.authentication.SessionAuthentication',
|
||||
),
|
||||
'PAGE_SIZE': 10,
|
||||
'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S',
|
||||
'DATETIME_INPUT_FORMATS': ['%Y-%m-%d %H:%M:%S'],
|
||||
'DATE_FORMAT': '%Y-%m-%d',
|
||||
'DATE_INPUT_FORMATS': ['%Y-%m-%d'],
|
||||
'TIME_FORMAT': '%H:%M:%S',
|
||||
'TIME_INPUT_FORMATS': ['%H:%M:%S']
|
||||
}
|
||||
|
||||
# ERROR
|
||||
SILENCED_SYSTEM_CHECKS = [
|
||||
'rest_framework.W001'
|
||||
]
|
||||
|
||||
SESSION_COOKIE_HTTPONLY = False
|
||||
|
||||
APPEND_SLASH = True
|
|
@ -0,0 +1,26 @@
|
|||
"""BookingService URL Configuration
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/2.1/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from django.views.generic.base import TemplateView
|
||||
|
||||
urlpatterns = [
|
||||
path('', TemplateView.as_view(template_name='index.html')),
|
||||
path('api-auth/', include('rest_framework.urls')),
|
||||
path('admin/', admin.site.urls),
|
||||
path('api/user/', include('user.urls', namespace='user')),
|
||||
path('api/booking/', include('booking.urls', namespace='booking')),
|
||||
]
|
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
WSGI config for BookingService project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'BookingService.settings')
|
||||
|
||||
application = get_wsgi_application()
|
|
@ -0,0 +1,14 @@
|
|||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[packages]
|
||||
django = "*"
|
||||
djangorestframework = "*"
|
||||
django-filter = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.7"
|
|
@ -0,0 +1 @@
|
|||
default_app_config = 'booking.apps.BookingConfig'
|
|
@ -0,0 +1,19 @@
|
|||
from django.contrib import admin
|
||||
from . import models
|
||||
|
||||
|
||||
@admin.register(models.Setting)
|
||||
class SettingAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
@admin.register(models.Room)
|
||||
class RoomAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
@admin.register(models.Seat)
|
||||
class SeatAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
@admin.register(models.Booking)
|
||||
class BookingAdmin(admin.ModelAdmin):
|
||||
pass
|
|
@ -0,0 +1,6 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class BookingConfig(AppConfig):
|
||||
name = 'booking'
|
||||
verbose_name = '预约'
|
|
@ -0,0 +1,16 @@
|
|||
from django_filters import rest_framework as filters
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
class BookingFilter(filters.FilterSet):
|
||||
min_date = filters.DateFilter(field_name="date", lookup_expr='gte', label='开始日期')
|
||||
max_date = filters.DateFilter(field_name="date", lookup_expr='lte', label='结束日期')
|
||||
min_time = filters.TimeFilter(field_name='start_time', lookup_expr='gte', label='开始时间')
|
||||
max_time = filters.TimeFilter(field_name='end_time', lookup_expr='lte', label='结束时间')
|
||||
room = filters.UUIDFilter(field_name='room')
|
||||
status = filters.CharFilter(field_name='status')
|
||||
|
||||
class Meta:
|
||||
model = models.Booking
|
||||
fields = ['min_date', 'max_date', 'min_time', 'max_time', 'room', 'status']
|
|
@ -0,0 +1,100 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-19 21:07
|
||||
|
||||
import datetime
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Booking',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_datetime', models.DateTimeField(auto_now_add=True, verbose_name='预约日期时间')),
|
||||
('start_time', models.TimeField(verbose_name='开始时间')),
|
||||
('end_time', models.TimeField(verbose_name='结束时间')),
|
||||
('date', models.DateField(verbose_name='日期')),
|
||||
('arrive_time', models.TimeField(blank=True, null=True, verbose_name='到达时间')),
|
||||
('leave_time', models.TimeField(blank=True, null=True, verbose_name='离开时间')),
|
||||
('is_valid', models.BooleanField(default=True, verbose_name='是否有效')),
|
||||
('is_cancel', models.BooleanField(default=False, verbose_name='是否取消')),
|
||||
('cancel_datetime', models.DateTimeField(blank=True, null=True, verbose_name='取消日期时间')),
|
||||
('cancel_reason', models.CharField(max_length=512, verbose_name='取消理由')),
|
||||
('cancel_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cancel_by', to=settings.AUTH_USER_MODEL, verbose_name='取消人')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '预约',
|
||||
'verbose_name_plural': '预约',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Room',
|
||||
fields=[
|
||||
('id', models.CharField(default=uuid.uuid1, max_length=36, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(blank=True, max_length=128, verbose_name='名称')),
|
||||
('decription', models.CharField(blank=True, max_length=512, verbose_name='说明')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '房间',
|
||||
'verbose_name_plural': '房间',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Seat',
|
||||
fields=[
|
||||
('id', models.CharField(default=uuid.uuid1, max_length=36, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('creaeted_datetime', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
('room', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='booking.Room', verbose_name='房间')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '座位',
|
||||
'verbose_name_plural': '座位',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Setting',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('pre_booking_interval_day', models.IntegerField(default=30, verbose_name='提前预约时间间隔(天)')),
|
||||
('booking_interval', models.IntegerField(default=30, verbose_name='预约间隔(分钟)')),
|
||||
('start_time', models.TimeField(default=datetime.time(8, 0), verbose_name='开始时间')),
|
||||
('end_time', models.TimeField(default=datetime.time(21, 0), verbose_name='结束时间')),
|
||||
('punish_point', models.IntegerField(default=5, verbose_name='惩罚积分数')),
|
||||
('reward_point', models.IntegerField(default=10, verbose_name='奖励积分数')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '预约设置',
|
||||
'verbose_name_plural': '预约设置',
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='booking',
|
||||
name='room',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='booking.Room', verbose_name='房间'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='booking',
|
||||
name='seat',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='booking.Seat', verbose_name='座位'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='booking',
|
||||
name='seats',
|
||||
field=models.ManyToManyField(related_name='seats', to='booking.Seat', verbose_name='多个座位'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='booking',
|
||||
name='user',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user', to=settings.AUTH_USER_MODEL, verbose_name='预约人'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-22 15:05
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='room',
|
||||
name='decription',
|
||||
field=models.TextField(blank=True, max_length=512, verbose_name='说明'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-22 15:36
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0002_auto_20190422_1505'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='booking',
|
||||
name='is_valid',
|
||||
),
|
||||
]
|
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-22 15:56
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0003_remove_booking_is_valid'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='booking',
|
||||
name='cancel_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='cancel_by', to=settings.AUTH_USER_MODEL, verbose_name='取消人'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='booking',
|
||||
name='cancel_reason',
|
||||
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='取消理由'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-22 15:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0004_auto_20190422_1556'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='booking',
|
||||
name='seats',
|
||||
field=models.ManyToManyField(blank=True, null=True, related_name='seats', to='booking.Seat', verbose_name='多个座位'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-22 16:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0005_auto_20190422_1556'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='booking',
|
||||
name='room',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='booking.Room', verbose_name='房间'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-22 16:36
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0006_auto_20190422_1636'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='booking',
|
||||
name='seats',
|
||||
field=models.ManyToManyField(blank=True, related_name='seats', to='booking.Seat', verbose_name='多个座位'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-22 16:49
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0007_auto_20190422_1636'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='booking',
|
||||
name='seat',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='booking',
|
||||
name='seats',
|
||||
field=models.ManyToManyField(related_name='seats', to='booking.Seat', verbose_name='多个座位'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-22 17:34
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0008_auto_20190422_1649'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='seat',
|
||||
old_name='creaeted_datetime',
|
||||
new_name='created_datetime',
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-26 19:47
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0009_auto_20190422_1734'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='room',
|
||||
old_name='decription',
|
||||
new_name='description',
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-27 10:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0010_auto_20190426_1947'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='seat',
|
||||
name='name',
|
||||
field=models.CharField(blank=True, max_length=128, verbose_name='名称'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 2.1.7 on 2019-04-30 09:25
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('booking', '0011_seat_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='booking',
|
||||
name='is_cancel',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='booking',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('PENDING', '正在申请'), ('SUCCESS', '申请成功'), ('FAILED', '申请失败'), ('CANCELED', '被取消')], default='PENDING', max_length=10, verbose_name='状态'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,79 @@
|
|||
import datetime
|
||||
import uuid
|
||||
|
||||
from django.db import models
|
||||
|
||||
from user.models import User
|
||||
|
||||
|
||||
class Setting(models.Model):
|
||||
pre_booking_interval_day = models.IntegerField('提前预约时间间隔(天)', default=30)
|
||||
booking_interval = models.IntegerField('预约间隔(分钟)', default=30)
|
||||
start_time = models.TimeField('开始时间', default=datetime.time(8, 0))
|
||||
end_time = models.TimeField('结束时间', default=datetime.time(21, 0))
|
||||
punish_point = models.IntegerField('惩罚积分数', default=5)
|
||||
reward_point = models.IntegerField('奖励积分数', default=10)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '预约设置'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.start_time}-{self.end_time}'
|
||||
|
||||
|
||||
class Room(models.Model):
|
||||
id = models.CharField('ID', max_length=36, default=uuid.uuid1, primary_key=True)
|
||||
name = models.CharField('名称', max_length=128, blank=True)
|
||||
description = models.TextField('说明', max_length=512, blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '房间'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.name}'
|
||||
|
||||
|
||||
class Seat(models.Model):
|
||||
id = models.CharField('ID', max_length=36, default=uuid.uuid1, primary_key=True)
|
||||
name = models.CharField('名称', max_length=128, blank=True)
|
||||
room = models.ForeignKey(verbose_name='房间', to=Room, on_delete=models.CASCADE)
|
||||
created_datetime = models.DateTimeField('创建时间', auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '座位'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.room.id}-{self.room.name}-{self.id}'
|
||||
|
||||
|
||||
class Booking(models.Model):
|
||||
STATUS_CHIOCE = [
|
||||
('PENDING', '正在申请'),
|
||||
('SUCCESS', '申请成功'),
|
||||
('FAILED', '申请失败'),
|
||||
('CANCELED', '被取消'),
|
||||
]
|
||||
user = models.ForeignKey(verbose_name='预约人', to=User, on_delete=models.CASCADE, related_name='user')
|
||||
room = models.ForeignKey(verbose_name='房间', to=Room, on_delete=models.CASCADE)
|
||||
seats = models.ManyToManyField(verbose_name='多个座位', to=Seat, related_name='seats')
|
||||
created_datetime = models.DateTimeField('预约日期时间', auto_now_add=True)
|
||||
start_time = models.TimeField('开始时间')
|
||||
end_time = models.TimeField('结束时间')
|
||||
date = models.DateField('日期')
|
||||
arrive_time = models.TimeField('到达时间', blank=True, null=True)
|
||||
leave_time = models.TimeField('离开时间', blank=True, null=True)
|
||||
status = models.CharField('状态', choices=STATUS_CHIOCE, max_length=10, default='PENDING')
|
||||
cancel_datetime = models.DateTimeField('取消日期时间', blank=True, null=True)
|
||||
cancel_reason = models.CharField('取消理由', max_length=512, blank=True, null=True)
|
||||
cancel_by = models.ForeignKey(verbose_name='取消人', to=User, on_delete=models.CASCADE, related_name='cancel_by',
|
||||
blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '预约'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.user.username}-{self.date}'
|
|
@ -0,0 +1,55 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
from user.serializers import UserSerializer
|
||||
from . import models
|
||||
|
||||
|
||||
class SettingSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.Setting
|
||||
fields = '__all__'
|
||||
extra_kwargs = {
|
||||
'pre_booking_interval_day': {
|
||||
'min_value': 1
|
||||
},
|
||||
'punish_point': {
|
||||
'min_value': 1
|
||||
},
|
||||
'reward_point': {
|
||||
'min_value': 1
|
||||
},
|
||||
}
|
||||
|
||||
# TODO
|
||||
def validate_booking_interval(self, value):
|
||||
if (not value in [30, 60]):
|
||||
raise serializers.ValidationError('请确保该值等于30或者60。')
|
||||
return value
|
||||
|
||||
|
||||
class RoomSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.Room
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class SeatSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.Seat
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class BookingSerializer(serializers.ModelSerializer):
|
||||
user = UserSerializer()
|
||||
room = RoomSerializer()
|
||||
seats = SeatSerializer(many=True)
|
||||
|
||||
class Meta:
|
||||
model = models.Booking
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class BookingCreateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.Booking
|
||||
fields = '__all__'
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -0,0 +1,18 @@
|
|||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = 'booking'
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.Booking.as_view()),
|
||||
path('<uuid:pk>/', views.BookingDetail.as_view()),
|
||||
path('statusList/', views.BookingStatusList.as_view()),
|
||||
path('setting/<int:pk>/', views.SettingDetail.as_view()),
|
||||
path('room/', views.Room.as_view()),
|
||||
path('room/bookingStatus/', views.RoomBookingStatus.as_view()),
|
||||
path('room/<uuid:pk>/', views.RoomDetail.as_view()),
|
||||
path('room/<uuid:pk>/bookingStatus/', views.RoomBookingStatusDetail.as_view()),
|
||||
path('seat/', views.Seat.as_view()),
|
||||
path('seat/<uuid:pk>/', views.SeatDetail.as_view()),
|
||||
]
|
|
@ -0,0 +1,241 @@
|
|||
import datetime
|
||||
|
||||
from django.db.models import QuerySet
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from rest_framework import generics
|
||||
from rest_framework import permissions
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.filters import SearchFilter, OrderingFilter
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
from rest_framework.response import Response
|
||||
|
||||
from . import models, serializers, filters
|
||||
|
||||
|
||||
class SettingDetail(generics.RetrieveUpdateAPIView):
|
||||
"""
|
||||
获得设置
|
||||
更新设置
|
||||
"""
|
||||
queryset = models.Setting.objects.all()
|
||||
serializer_class = serializers.SettingSerializer
|
||||
permission_classes = (permissions.IsAdminUser,)
|
||||
|
||||
|
||||
class Room(generics.ListAPIView):
|
||||
"""
|
||||
获得room列表
|
||||
"""
|
||||
queryset = models.Room.objects.all().order_by('name')
|
||||
serializer_class = serializers.RoomSerializer
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
|
||||
class RoomDetail(generics.RetrieveUpdateAPIView):
|
||||
"""
|
||||
获得指定room
|
||||
更新指定room
|
||||
"""
|
||||
queryset = models.Room.objects.all()
|
||||
serializer_class = serializers.RoomSerializer
|
||||
permission_classes = (permissions.IsAdminUser,)
|
||||
|
||||
|
||||
class Seat(generics.ListCreateAPIView):
|
||||
"""
|
||||
获得seat列表
|
||||
新建seat
|
||||
"""
|
||||
queryset = models.Seat.objects.all().order_by('-created_datetime')
|
||||
serializer_class = serializers.SeatSerializer
|
||||
permission_classes = (permissions.IsAdminUser,)
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filterset_fields = ['room__id']
|
||||
|
||||
def perform_create(self, serializer):
|
||||
name = serializer.validated_data.get('name')
|
||||
r = serializer.validated_data.get('room')
|
||||
room = models.Room.objects.get(id=r.id)
|
||||
models.Seat.objects.create(room=room, name=name)
|
||||
|
||||
|
||||
class SeatDetail(generics.DestroyAPIView):
|
||||
"""
|
||||
删除指定seat
|
||||
"""
|
||||
queryset = models.Seat.objects.all()
|
||||
serializer_class = serializers.SeatSerializer
|
||||
permission_classes = (permissions.IsAdminUser,)
|
||||
|
||||
|
||||
class Booking(generics.ListCreateAPIView):
|
||||
"""
|
||||
获得booking列表
|
||||
新建booking
|
||||
"""
|
||||
queryset = models.Booking.objects.all().order_by('id')
|
||||
# serializer_class = serializers.BookingSerializer
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
pagination_class = PageNumberPagination
|
||||
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
|
||||
filterset_class = filters.BookingFilter
|
||||
search_fields = [
|
||||
'user__username',
|
||||
'room__name',
|
||||
'date'
|
||||
]
|
||||
ordering_fields = [
|
||||
'id',
|
||||
'date',
|
||||
'start_time',
|
||||
'end_time',
|
||||
]
|
||||
|
||||
def perform_create(self, serializer):
|
||||
print(serializer.data)
|
||||
return Response('')
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.request.stream and self.request.stream.method == 'POST':
|
||||
return serializers.BookingCreateSerializer
|
||||
else:
|
||||
return serializers.BookingSerializer
|
||||
|
||||
|
||||
class BookingDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
"""
|
||||
获得指定booking
|
||||
更新指定booking
|
||||
删除指定booking
|
||||
"""
|
||||
queryset = models.Booking.objects.all()
|
||||
serializer_class = serializers.BookingSerializer
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
|
||||
class BookingStatusList(generics.GenericAPIView):
|
||||
"""
|
||||
获得预约状态列表
|
||||
"""
|
||||
queryset = QuerySet()
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def get(self, request):
|
||||
status_list = []
|
||||
for status in models.Booking.STATUS_CHIOCE:
|
||||
status_list.append({
|
||||
'id': status[0],
|
||||
'name': status[1]
|
||||
})
|
||||
return Response(status_list)
|
||||
|
||||
|
||||
class RoomBookingStatus(generics.GenericAPIView):
|
||||
"""
|
||||
获得房间预约信息
|
||||
"""
|
||||
queryset = QuerySet()
|
||||
serializer_class = (serializers.RoomSerializer)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def get(self, request):
|
||||
try:
|
||||
date = datetime.datetime.strptime(request.query_params.get('date'), '%Y-%m-%d').date()
|
||||
except Exception as e:
|
||||
raise ValidationError(e)
|
||||
setting = models.Setting.objects.get(id=1)
|
||||
start_datetime = datetime.datetime.combine(date, setting.start_time)
|
||||
end_datetime = datetime.datetime.combine(date, setting.end_time)
|
||||
step = datetime.timedelta(minutes=setting.booking_interval)
|
||||
count_per_seat = int((end_datetime - start_datetime) / step)
|
||||
count_total = 0
|
||||
booked_count_total = 0
|
||||
booking_count_total = 0
|
||||
room_booking_status_list = []
|
||||
for room in models.Room.objects.all():
|
||||
seat_list = room.seat_set.all()
|
||||
count_per_room = 0
|
||||
booked_count = 0
|
||||
booking_count = 0
|
||||
for seat in seat_list:
|
||||
count_per_room += count_per_seat
|
||||
booking_list = models.Booking.objects.filter(date=date, room=room, seats__id=seat.id, status='SUCCESS')
|
||||
for booking in booking_list:
|
||||
s_datetime = datetime.datetime.combine(date, booking.start_time)
|
||||
e_datetime = datetime.datetime.combine(date, booking.end_time)
|
||||
s = int((s_datetime - start_datetime) / step)
|
||||
e = int((e_datetime - start_datetime) / step)
|
||||
booked_count += e - s
|
||||
booking_count += 1
|
||||
count_total += count_per_room
|
||||
booked_count_total += booked_count
|
||||
booking_count_total += booking_count
|
||||
room_booking_status_list.append({
|
||||
**self.get_serializer(room).data,
|
||||
'count': count_per_room,
|
||||
'booked_count': booked_count,
|
||||
'booking_count': booking_count
|
||||
})
|
||||
return Response({
|
||||
'count_total': count_total,
|
||||
'booked_count_total': booked_count_total,
|
||||
'booking_count_total': booking_count_total,
|
||||
'results': room_booking_status_list
|
||||
})
|
||||
|
||||
|
||||
class RoomBookingStatusDetail(generics.GenericAPIView):
|
||||
"""
|
||||
获得指定房间的预约信息
|
||||
"""
|
||||
queryset = QuerySet()
|
||||
serializer_class = (serializers.RoomSerializer)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def get(self, request, pk):
|
||||
try:
|
||||
date = datetime.datetime.strptime(request.query_params.get('date'), '%Y-%m-%d').date()
|
||||
except Exception as e:
|
||||
raise ValidationError(e)
|
||||
room = get_object_or_404(models.Room, id=pk)
|
||||
setting = models.Setting.objects.get(id=1)
|
||||
count_total = 0
|
||||
booked_count_total = 0
|
||||
seat_list = []
|
||||
for seat in room.seat_set.all():
|
||||
# 初始化数组
|
||||
step = datetime.timedelta(minutes=setting.booking_interval)
|
||||
booking_status_list = []
|
||||
start_datetime = datetime.datetime.combine(date, setting.start_time)
|
||||
end_datetime = start_datetime + step
|
||||
while end_datetime <= datetime.datetime.combine(date, setting.end_time):
|
||||
booking_status_list.append({
|
||||
'start_time': start_datetime.strftime('%H:%M:%S'),
|
||||
'end_time': end_datetime.strftime('%H:%M:%S'),
|
||||
'booking': None
|
||||
})
|
||||
count_total += 1
|
||||
start_datetime = end_datetime
|
||||
end_datetime += step
|
||||
# 检查预约记录
|
||||
for booking in models.Booking.objects.filter(date=date, room=room, seats__id=seat.id, status='SUCCESS'):
|
||||
s_datetime = datetime.datetime.combine(date, booking.start_time)
|
||||
e_datetime = datetime.datetime.combine(date, booking.end_time)
|
||||
s = int((s_datetime - start_datetime) / step)
|
||||
e = int((e_datetime - start_datetime) / step)
|
||||
booked_count_total += e - s
|
||||
for i in range(s, e):
|
||||
booking_status_list[i]['booking'] = serializers.BookingSerializer(booking).data
|
||||
seat_list.append({
|
||||
'id': seat.id,
|
||||
'name': seat.name,
|
||||
'booking_status_list': booking_status_list
|
||||
})
|
||||
return Response({
|
||||
**self.get_serializer(room).data,
|
||||
'date': date,
|
||||
'count_total': count_total,
|
||||
'booked_count_total': booked_count_total,
|
||||
'seat_list': seat_list
|
||||
})
|
|
@ -0,0 +1,61 @@
|
|||
### `200`
|
||||
|
||||
正确返回信息,有返回追
|
||||
|
||||
## `201`
|
||||
|
||||
创建成功,有返回值
|
||||
|
||||
## `400`
|
||||
|
||||
验证失败,有返回值,返回错误
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": Object
|
||||
}
|
||||
```
|
||||
|
||||
## `401`
|
||||
|
||||
|
||||
|
||||
## `402`
|
||||
|
||||
|
||||
|
||||
## `403`
|
||||
|
||||
访问被拒绝,用户没有登录或没有权限,有返回值,返回错误
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": Object
|
||||
}
|
||||
```
|
||||
|
||||
## `404`
|
||||
|
||||
找不到请求的对象,有返回值,返回错误
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": Object
|
||||
}
|
||||
```
|
||||
|
||||
## `405`
|
||||
|
||||
请求方法错误,有返回值,返回错误
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": Object
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## `500`
|
||||
|
||||
服务器错误,无返回值
|
|
@ -0,0 +1,155 @@
|
|||
`GET` /api/collection/
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
`post` /api/collection/
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
`get` /api/collection/:id
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
`put` /api/collection/:id
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
`delete` /api/collection/:id
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
## Model
|
||||
|
||||
```json
|
||||
{
|
||||
"id": Number,
|
||||
"password": "", // wirte_only
|
||||
"last_login": "", // "2019-04-20 13:23:53"
|
||||
"is_superuser": Boolean,
|
||||
"username": "",
|
||||
"email": "",
|
||||
"is_staff": Boolean,
|
||||
"is_active": Boolean,
|
||||
"date_joined": "", // "2019-04-19 21:08:29"
|
||||
"role": "",
|
||||
"point": Number,
|
||||
"groups": [],
|
||||
"user_permissions": []
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Rest
|
||||
|
||||
### `GET` /api/user/
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
### `post` /api/user/
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
### `get` /api/user/:id/
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
### `put` /api/user/:id/
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
### `delete` /api/user/:id/
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
## Action
|
||||
|
||||
### `post` /api/user/login/
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
"username": "",
|
||||
"password": ""
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
<model>
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
### `get` /api/user/logout/
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
### `get` /api/user/getInfo/
|
||||
|
||||
parameters:
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
response:
|
||||
|
||||
```json
|
||||
{
|
||||
<model>
|
||||
}
|
||||
```
|
||||
|
||||
error:
|
||||
|
||||
```json
|
||||
{
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
[*]
|
||||
charset=utf-8
|
||||
end_of_line=crlf
|
||||
insert_final_newline=false
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{*.ng,*.sht,*.html,*.shtm,*.shtml,*.htm}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{.babelrc,.stylelintrc,jest.config,.eslintrc,.prettierrc,*.json,*.jsb3,*.jsb2,*.bowerrc}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.svg]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.js.map]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.less]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.vue]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{.analysis_options,*.yml,*.yaml}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
|
@ -0,0 +1 @@
|
|||
public/* linguist-vendored
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"printWidth": 120,
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
'@vue/app'
|
||||
]
|
||||
// ,
|
||||
// plugins: [
|
||||
// [ 'import', {
|
||||
// 'libraryName': 'ant-design-vue',
|
||||
// 'libraryDirectory': 'es',
|
||||
// 'style': true // `style: true` 会加载 less 文件
|
||||
// } ]
|
||||
// ]
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<!DOCTYPE html><html lang=zh-cmn-Hans><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/logo.png><title>建筑咨询管理系统</title><style>#preloadingAnimation{position:fixed;left:0;top:0;height:100%;width:100%;background:#ffffff;user-select:none;z-index: 9999;overflow: hidden}.lds-roller{display:inline-block;position:relative;left:50%;top:50%;transform:translate(-50%,-50%);width:64px;height:64px;}.lds-roller div{animation:lds-roller 1.2s cubic-bezier(0.5,0,0.5,1) infinite;transform-origin:32px 32px;}.lds-roller div:after{content:" ";display:block;position:absolute;width:6px;height:6px;border-radius:50%;background:#13c2c2;margin:-3px 0 0 -3px;}.lds-roller div:nth-child(1){animation-delay:-0.036s;}.lds-roller div:nth-child(1):after{top:50px;left:50px;}.lds-roller div:nth-child(2){animation-delay:-0.072s;}.lds-roller div:nth-child(2):after{top:54px;left:45px;}.lds-roller div:nth-child(3){animation-delay:-0.108s;}.lds-roller div:nth-child(3):after{top:57px;left:39px;}.lds-roller div:nth-child(4){animation-delay:-0.144s;}.lds-roller div:nth-child(4):after{top:58px;left:32px;}.lds-roller div:nth-child(5){animation-delay:-0.18s;}.lds-roller div:nth-child(5):after{top:57px;left:25px;}.lds-roller div:nth-child(6){animation-delay:-0.216s;}.lds-roller div:nth-child(6):after{top:54px;left:19px;}.lds-roller div:nth-child(7){animation-delay:-0.252s;}.lds-roller div:nth-child(7):after{top:50px;left:14px;}.lds-roller div:nth-child(8){animation-delay:-0.288s;}.lds-roller div:nth-child(8):after{top:45px;left:10px;}#preloadingAnimation .load-tips{color: #13c2c2;font-size:2rem;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:80px;text-align:center;width:400px;height:64px;} @keyframes lds-roller{0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);}}</style><link href=/static/css/fail.4c41990b.css rel=prefetch><link href=/static/css/user.d3b41a87.css rel=prefetch><link href=/static/js/asider.0aaae6b5.js rel=prefetch><link href=/static/js/chunk-2d209ade.3e698d10.js rel=prefetch><link href=/static/js/fail.40be6fc6.js rel=prefetch><link href=/static/js/user.d638c020.js rel=prefetch><link href=/static/css/app.c99c38d5.css rel=preload as=style><link href=/static/css/chunk-vendors.cc2a8f53.css rel=preload as=style><link href=/static/js/app.c3c48851.js rel=preload as=script><link href=/static/js/chunk-vendors.cd3c5264.js rel=preload as=script><link href=/static/css/chunk-vendors.cc2a8f53.css rel=stylesheet><link href=/static/css/app.c99c38d5.css rel=stylesheet></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app><div id=preloadingAnimation><div class=lds-roller><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div><div class=load-tips>Loading</div></div></div><script src=/static/js/chunk-vendors.cd3c5264.js></script><script src=/static/js/app.c3c48851.js></script></body></html>
|
|
@ -0,0 +1 @@
|
|||
#preloadingAnimation{position:fixed;left:0;top:0;height:100%;width:100%;background:#ffffff;user-select:none;z-index: 9999;overflow: hidden}.lds-roller{display:inline-block;position:relative;left:50%;top:50%;transform:translate(-50%,-50%);width:64px;height:64px;}.lds-roller div{animation:lds-roller 1.2s cubic-bezier(0.5,0,0.5,1) infinite;transform-origin:32px 32px;}.lds-roller div:after{content:" ";display:block;position:absolute;width:6px;height:6px;border-radius:50%;background:#13c2c2;margin:-3px 0 0 -3px;}.lds-roller div:nth-child(1){animation-delay:-0.036s;}.lds-roller div:nth-child(1):after{top:50px;left:50px;}.lds-roller div:nth-child(2){animation-delay:-0.072s;}.lds-roller div:nth-child(2):after{top:54px;left:45px;}.lds-roller div:nth-child(3){animation-delay:-0.108s;}.lds-roller div:nth-child(3):after{top:57px;left:39px;}.lds-roller div:nth-child(4){animation-delay:-0.144s;}.lds-roller div:nth-child(4):after{top:58px;left:32px;}.lds-roller div:nth-child(5){animation-delay:-0.18s;}.lds-roller div:nth-child(5):after{top:57px;left:25px;}.lds-roller div:nth-child(6){animation-delay:-0.216s;}.lds-roller div:nth-child(6):after{top:54px;left:19px;}.lds-roller div:nth-child(7){animation-delay:-0.252s;}.lds-roller div:nth-child(7):after{top:50px;left:14px;}.lds-roller div:nth-child(8){animation-delay:-0.288s;}.lds-roller div:nth-child(8):after{top:45px;left:10px;}#preloadingAnimation .load-tips{color: #13c2c2;font-size:2rem;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:80px;text-align:center;width:400px;height:64px;} @keyframes lds-roller{0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);}}
|
|
@ -0,0 +1 @@
|
|||
<div id="preloadingAnimation"><div class=lds-roller><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div><div class=load-tips>Loading</div></div>
|
|
@ -0,0 +1,5 @@
|
|||
<div class="preloading-animate">
|
||||
<div class="preloading-wrapper">
|
||||
<svg class="preloading-balls" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="67.802" cy="59.907" r="6" fill="#51CACC"><animate attributeName="cx" values="75;57.72542485937369" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="50;73.77641290737884" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#51CACC;#9DF871" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="46.079" cy="69.992" r="6" fill="#9DF871"><animate attributeName="cx" values="57.72542485937369;29.774575140626318" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="73.77641290737884;64.69463130731182" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#9DF871;#E0FF77" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="29.775" cy="52.449" r="6" fill="#E0FF77"><animate attributeName="cx" values="29.774575140626318;29.774575140626315" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="64.69463130731182;35.30536869268818" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#E0FF77;#DE9DD6" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="41.421" cy="31.521" r="6" fill="#DE9DD6"><animate attributeName="cx" values="29.774575140626315;57.72542485937368" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="35.30536869268818;26.22358709262116" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#DE9DD6;#FF708E" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="64.923" cy="36.13" r="6" fill="#FF708E"><animate attributeName="cx" values="57.72542485937368;75" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="26.22358709262116;49.99999999999999" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#FF708E;#51CACC" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle></svg>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
.preloading-animate{background:#ffffff;width:100%;height:100%;position:fixed;left:0;top:0;z-index:299;}.preloading-animate .preloading-wrapper{position:absolute;width:5rem;height:5rem;left:50%;top:50%;transform:translate(-50%,-50%);}.preloading-animate .preloading-wrapper .preloading-balls{font-size:5rem;}
|
|
@ -0,0 +1 @@
|
|||
<svg class="preloading-balls" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="67.802" cy="59.907" r="6" fill="#51CACC"><animate attributeName="cx" values="75;57.72542485937369" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="50;73.77641290737884" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#51CACC;#9DF871" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="46.079" cy="69.992" r="6" fill="#9DF871"><animate attributeName="cx" values="57.72542485937369;29.774575140626318" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="73.77641290737884;64.69463130731182" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#9DF871;#E0FF77" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="29.775" cy="52.449" r="6" fill="#E0FF77"><animate attributeName="cx" values="29.774575140626318;29.774575140626315" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="64.69463130731182;35.30536869268818" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#E0FF77;#DE9DD6" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="41.421" cy="31.521" r="6" fill="#DE9DD6"><animate attributeName="cx" values="29.774575140626315;57.72542485937368" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="35.30536869268818;26.22358709262116" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#DE9DD6;#FF708E" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="64.923" cy="36.13" r="6" fill="#FF708E"><animate attributeName="cx" values="57.72542485937368;75" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="26.22358709262116;49.99999999999999" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#FF708E;#51CACC" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle></svg>
|
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1 @@
|
|||
.exception[data-v-e85f82bc]{min-height:500px;height:80%;-webkit-box-align:center;-ms-flex-align:center;align-items:center;text-align:center;margin-top:150px}.exception .img[data-v-e85f82bc]{display:inline-block;padding-right:52px;zoom:1}.exception .img img[data-v-e85f82bc]{height:360px;max-width:430px}.exception .content[data-v-e85f82bc]{display:inline-block;-webkit-box-flex:1;-ms-flex:auto;flex:auto}.exception .content h1[data-v-e85f82bc]{color:#434e59;font-size:72px;font-weight:600;line-height:72px;margin-bottom:24px}.exception .content .desc[data-v-e85f82bc]{color:rgba(0,0,0,.45);font-size:20px;line-height:28px;margin-bottom:16px}.mobile .exception[data-v-e85f82bc]{margin-top:30px}.mobile .exception .img[data-v-e85f82bc]{padding-right:unset}.mobile .exception .img img[data-v-e85f82bc]{height:40%;max-width:80%}
|
|
@ -0,0 +1 @@
|
|||
.user-layout-login label[data-v-38784526]{font-size:14px}.user-layout-login button.login-button[data-v-38784526]{padding:0 15px;font-size:16px;height:40px;width:100%}
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="1361px" height="609px" viewBox="0 0 1361 609" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Group 21</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)">
|
||||
<g id="Group-21" transform="translate(77.000000, 73.000000)">
|
||||
<g id="Group-18" opacity="0.8" transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
|
||||
<ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367" rx="21.7830479" ry="21.766008"></ellipse>
|
||||
<ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601" rx="5.2173913" ry="5.21330997"></ellipse>
|
||||
<path d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z" id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"></path>
|
||||
<path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6" stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7" stroke-width="0.702678964" opacity="0.7" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9" stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<g id="Group-17" transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)" fill="#CFDAE6">
|
||||
<ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653" ry="9.12768076"></ellipse>
|
||||
<path d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z" id="Oval-4" transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-14" transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439" rx="29.1176471" ry="29.1402439"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439" rx="21.5686275" ry="21.5853659"></ellipse>
|
||||
<ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341" rx="23.7254902" ry="23.7439024"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439" rx="10.7843137" ry="10.7926829"></ellipse>
|
||||
<path d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z" id="Oval-2" fill="#BACAD9"></path>
|
||||
<g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)" fill="#E6A1A6">
|
||||
<ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824" ry="6.47560976"></ellipse>
|
||||
<path d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z" id="Oval-2-Copy-2" transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "></path>
|
||||
</g>
|
||||
<ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488" rx="2.15686275" ry="2.15853659"></ellipse>
|
||||
<path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6" opacity="0.8"></path>
|
||||
</g>
|
||||
<g id="Group-10" opacity="0.799999952" transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
|
||||
<ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32" rx="11.1864407" ry="11.2941176"></ellipse>
|
||||
<g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
|
||||
<ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627" ry="8.55614973"></ellipse>
|
||||
<path d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z" id="Oval-7"></path>
|
||||
</g>
|
||||
<path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
<ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186" cy="3.29411765" rx="3.26271186" ry="3.29411765"></ellipse>
|
||||
<ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017" ry="2.82352941"></ellipse>
|
||||
<path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
</g>
|
||||
<g id="Group-19" opacity="0.33" transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
|
||||
<g id="Group-17" transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)" fill="#BACAD9">
|
||||
<circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"></circle>
|
||||
<path d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z" id="Oval-4" transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "></path>
|
||||
</g>
|
||||
<circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"></circle>
|
||||
<path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667" points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"></polyline>
|
||||
<path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7" stroke-width="1.16666667" opacity="0.6"></path>
|
||||
<path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6" stroke-width="1.16666667"></path>
|
||||
<circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"></circle>
|
||||
<circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333" cy="30.3333333" r="5.83333333"></circle>
|
||||
<circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.7 KiB |
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="200px" height="200px" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Group 28 Copy 5</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="62.1023273%" y1="0%" x2="108.19718%" y2="37.8635764%" id="linearGradient-1">
|
||||
<stop stop-color="#4285EB" offset="0%"></stop>
|
||||
<stop stop-color="#2EC7FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="69.644116%" y1="0%" x2="54.0428975%" y2="108.456714%" id="linearGradient-2">
|
||||
<stop stop-color="#29CDFF" offset="0%"></stop>
|
||||
<stop stop-color="#148EFF" offset="37.8600687%"></stop>
|
||||
<stop stop-color="#0A60FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="69.6908165%" y1="-12.9743587%" x2="16.7228981%" y2="117.391248%" id="linearGradient-3">
|
||||
<stop stop-color="#FA816E" offset="0%"></stop>
|
||||
<stop stop-color="#F74A5C" offset="41.472606%"></stop>
|
||||
<stop stop-color="#F51D2C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="68.1279872%" y1="-35.6905737%" x2="30.4400914%" y2="114.942679%" id="linearGradient-4">
|
||||
<stop stop-color="#FA8E7D" offset="0%"></stop>
|
||||
<stop stop-color="#F74A5C" offset="51.2635191%"></stop>
|
||||
<stop stop-color="#F51D2C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="logo" transform="translate(-20.000000, -20.000000)">
|
||||
<g id="Group-28-Copy-5" transform="translate(20.000000, 20.000000)">
|
||||
<g id="Group-27-Copy-3">
|
||||
<g id="Group-25" fill-rule="nonzero">
|
||||
<g id="2">
|
||||
<path d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C99.2571609,26.9692191 101.032305,26.9692191 102.20193,28.1378823 L129.985225,55.8983314 C134.193707,60.1033528 141.017005,60.1033528 145.225487,55.8983314 C149.433969,51.69331 149.433969,44.8756232 145.225487,40.6706018 L108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z" id="Shape" fill="url(#linearGradient-1)"></path>
|
||||
<path d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C100.999864,25.6271836 105.751642,20.541824 112.729652,19.3524487 C117.915585,18.4685261 123.585219,20.4140239 129.738554,25.1889424 C125.624663,21.0784292 118.571995,14.0340304 108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z" id="Shape" fill="url(#linearGradient-2)"></path>
|
||||
</g>
|
||||
<path d="M153.685633,135.854579 C157.894115,140.0596 164.717412,140.0596 168.925894,135.854579 L195.959977,108.842726 C200.659183,104.147384 200.659183,96.5636133 195.960527,91.8688194 L168.690777,64.7181159 C164.472332,60.5180858 157.646868,60.5241425 153.435895,64.7316526 C149.227413,68.936674 149.227413,75.7543607 153.435895,79.9593821 L171.854035,98.3623765 C173.02366,99.5310396 173.02366,101.304724 171.854035,102.473387 L153.685633,120.626849 C149.47715,124.83187 149.47715,131.649557 153.685633,135.854579 Z" id="Shape" fill="url(#linearGradient-3)"></path>
|
||||
</g>
|
||||
<ellipse id="Combined-Shape" fill="url(#linearGradient-4)" cx="100.519339" cy="100.436681" rx="23.6001926" ry="23.580786"></ellipse>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
|
@ -0,0 +1,2 @@
|
|||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["asider","chunk-2d209ade"],{a9a1:function(e,t,n){"use strict";n.r(t);var a=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("a-card",[e._v("\n 123\n")])},r=[],u={name:"Implement"},l=u,c=n("2877"),o=Object(c["a"])(l,a,r,!1,null,null,null);t["default"]=o.exports},b7bc:function(e,t,n){"use strict";n.r(t);var a=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("page-layout",{attrs:{title:"项目"}})},r=[],u=n("b445"),l={name:"Project",components:{PageLayout:u["a"]},data:function(){return{}}},c=l,o=n("2877"),s=Object(o["a"])(c,a,r,!1,null,null,null);t["default"]=s.exports}}]);
|
||||
//# sourceMappingURL=asider.0aaae6b5.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["webpack:///./src/views/implement/Implement.vue?ad18","webpack:///src/views/implement/Implement.vue","webpack:///./src/views/implement/Implement.vue?6e80","webpack:///./src/views/implement/Implement.vue","webpack:///./src/views/project/Project.vue?7a17","webpack:///src/views/project/Project.vue","webpack:///./src/views/project/Project.vue?27a9","webpack:///./src/views/project/Project.vue"],"names":["render","_vm","this","_h","$createElement","_c","_self","_v","staticRenderFns","Implementvue_type_script_lang_js_","name","implement_Implementvue_type_script_lang_js_","component","Object","componentNormalizer","__webpack_exports__","attrs","title","Projectvue_type_script_lang_js_","components","PageLayout","data","project_Projectvue_type_script_lang_js_"],"mappings":"gIAAA,IAAAA,EAAA,WAA0B,IAAAC,EAAAC,KAAaC,EAAAF,EAAAG,eAA0BC,EAAAJ,EAAAK,MAAAD,IAAAF,EAAwB,OAAAE,EAAA,UAAAJ,EAAAM,GAAA,gBACzFC,EAAA,GCMAC,EAAA,CACAC,KAAA,aCRkWC,EAAA,cCOlWC,EAAgBC,OAAAC,EAAA,KAAAD,CACdF,EACAX,EACAQ,GACF,EACA,KACA,KACA,MAIeO,EAAA,WAAAH,oDClBf,IAAAZ,EAAA,WAA0B,IAAAC,EAAAC,KAAaC,EAAAF,EAAAG,eAA0BC,EAAAJ,EAAAK,MAAAD,IAAAF,EAAwB,OAAAE,EAAA,eAAyBW,MAAA,CAAOC,MAAA,SACzHT,EAAA,eCOAU,EAAA,CACAR,KAAA,UACAS,WAAA,CACAC,aAAA,MAEAC,KALA,WAMA,WCdgWC,EAAA,cCOhWV,EAAgBC,OAAAC,EAAA,KAAAD,CACdS,EACAtB,EACAQ,GACF,EACA,KACA,KACA,MAIeO,EAAA,WAAAH","file":"static/js/asider.0aaae6b5.js","sourcesContent":["var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('a-card',[_vm._v(\"\\n 123\\n\")])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","<template>\r\n <a-card>\r\n 123\r\n </a-card>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n name: 'Implement'\r\n}\r\n</script>\r\n\r\n<style lang=\"stylus\">\r\n\r\n</style>\r\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Implement.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Implement.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./Implement.vue?vue&type=template&id=23cbbf94&\"\nimport script from \"./Implement.vue?vue&type=script&lang=js&\"\nexport * from \"./Implement.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('page-layout',{attrs:{\"title\":'项目'}})}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","<template>\r\n <page-layout :title=\"'项目'\">\r\n </page-layout>\r\n</template>\r\n\r\n<script>\r\nimport PageLayout from '../../components/page/PageLayout'\r\n\r\nexport default {\r\n name: 'Project',\r\n components: {\r\n PageLayout\r\n },\r\n data () {\r\n return {\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"stylus\">\r\n\r\n</style>\r\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Project.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Project.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./Project.vue?vue&type=template&id=55f65630&\"\nimport script from \"./Project.vue?vue&type=script&lang=js&\"\nexport * from \"./Project.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports"],"sourceRoot":""}
|
|
@ -0,0 +1,2 @@
|
|||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d209ade"],{a9a1:function(n,e,a){"use strict";a.r(e);var t=function(){var n=this,e=n.$createElement,a=n._self._c||e;return a("a-card",[n._v("\n 123\n")])},c=[],l={name:"Implement"},u=l,r=a("2877"),s=Object(r["a"])(u,t,c,!1,null,null,null);e["default"]=s.exports}}]);
|
||||
//# sourceMappingURL=chunk-2d209ade.3e698d10.js.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["webpack:///./src/views/implement/Implement.vue?ad18","webpack:///src/views/implement/Implement.vue","webpack:///./src/views/implement/Implement.vue?6e80","webpack:///./src/views/implement/Implement.vue"],"names":["render","_vm","this","_h","$createElement","_c","_self","_v","staticRenderFns","Implementvue_type_script_lang_js_","name","implement_Implementvue_type_script_lang_js_","component","Object","componentNormalizer","__webpack_exports__"],"mappings":"uHAAA,IAAAA,EAAA,WAA0B,IAAAC,EAAAC,KAAaC,EAAAF,EAAAG,eAA0BC,EAAAJ,EAAAK,MAAAD,IAAAF,EAAwB,OAAAE,EAAA,UAAAJ,EAAAM,GAAA,gBACzFC,EAAA,GCMAC,EAAA,CACAC,KAAA,aCRkWC,EAAA,cCOlWC,EAAgBC,OAAAC,EAAA,KAAAD,CACdF,EACAX,EACAQ,GACF,EACA,KACA,KACA,MAIeO,EAAA,WAAAH","file":"static/js/chunk-2d209ade.3e698d10.js","sourcesContent":["var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('a-card',[_vm._v(\"\\n 123\\n\")])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","<template>\r\n <a-card>\r\n 123\r\n </a-card>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n name: 'Implement'\r\n}\r\n</script>\r\n\r\n<style lang=\"stylus\">\r\n\r\n</style>\r\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Implement.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Implement.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./Implement.vue?vue&type=template&id=23cbbf94&\"\nimport script from \"./Implement.vue?vue&type=script&lang=js&\"\nexport * from \"./Implement.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports"],"sourceRoot":""}
|
|
@ -0,0 +1,2 @@
|
|||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["fail"],{"790e":function(t,e,s){"use strict";var c=s("b449"),i=s.n(c);i.a},b449:function(t,e,s){},cc89:function(t,e,s){"use strict";s.r(e);var c=function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("exception-page",{attrs:{type:"404"}})},i=[],n=function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("div",{staticClass:"exception"},[s("div",{staticClass:"img"},[s("img",{attrs:{src:t.config[t.type].img}})]),s("div",{staticClass:"content"},[s("h1",[t._v(t._s(t.config[t.type].title))]),s("div",{staticClass:"desc"},[t._v(t._s(t.config[t.type].desc))]),s("div",{staticClass:"action"},[s("a-button",{attrs:{type:"primary"},on:{click:t.handleToHome}},[t._v("返回首页")])],1)])])},a=[],o={403:{img:"https://gw.alipayobjects.com/zos/rmsportal/wZcnGqRDyhPOEYFcZDnb.svg",title:"403",desc:"抱歉,你无权访问该页面"},404:{img:"https://gw.alipayobjects.com/zos/rmsportal/KpnpchXsobRgLElEozzI.svg",title:"404",desc:"抱歉,你访问的页面不存在或仍在开发中"},500:{img:"https://gw.alipayobjects.com/zos/rmsportal/RVRUAYdCGeYNBWoKiIwB.svg",title:"500",desc:"抱歉,服务器出错了"}},p=o,l={name:"Exception",props:{type:{type:String,default:"404"}},data:function(){return{config:p}},methods:{handleToHome:function(){this.$router.push({name:"dashboard"})}}},r=l,d=(s("790e"),s("2877")),u=Object(d["a"])(r,n,a,!1,null,"e85f82bc",null),m=u.exports,g={components:{ExceptionPage:m}},f=g,h=Object(d["a"])(f,c,i,!1,null,"4ff23dea",null);e["default"]=h.exports}}]);
|
||||
//# sourceMappingURL=fail.40be6fc6.js.map
|
|
@ -0,0 +1,2 @@
|
|||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["user"],{"4c5b":function(t,e,a){},"698e":function(t,e,a){"use strict";var r=a("4c5b"),i=a.n(r);i.a},ac2a:function(t,e,a){"use strict";a.r(e);var r=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"main"},[a("a-form",{ref:"formLogin",staticClass:"user-layout-login",attrs:{id:"formLogin",form:t.form},on:{submit:t.handleSubmit}},[a("a-form-item",{staticStyle:{"margin-top":"24px","text-align":"center","font-size":"20px"}},[t._v("\n 用户登录\n ")]),a("a-form-item",{staticStyle:{"margin-top":"40px"}},[a("a-input",{directives:[{name:"decorator",rawName:"v-decorator",value:["username",{rules:[{required:!0,message:"请输入用户名"}],validateTrigger:"blur"}],expression:"[\n 'username',\n {rules: [{ required: true, message: '请输入用户名' }], validateTrigger: 'blur'}\n ]"}],attrs:{size:"large",type:"text",autocomplete:"true",placeholder:"用户名"}},[a("a-icon",{style:{color:"rgba(0,0,0,.25)"},attrs:{slot:"prefix",type:"user"},slot:"prefix"})],1)],1),a("a-form-item",[a("a-input",{directives:[{name:"decorator",rawName:"v-decorator",value:["password",{rules:[{required:!0,message:"请输入密码"}],validateTrigger:"blur"}],expression:"[\n 'password',\n {rules: [{ required: true, message: '请输入密码' }], validateTrigger: 'blur'}\n ]"}],attrs:{size:"large",type:"password",autocomplete:"true",placeholder:"密码"}},[a("a-icon",{style:{color:"rgba(0,0,0,.25)"},attrs:{slot:"prefix",type:"lock"},slot:"prefix"})],1)],1),a("a-form-item",{staticStyle:{"margin-top":"24px"}},[a("a-button",{staticClass:"login-button",attrs:{size:"large",type:"primary",htmlType:"submit",loading:t.state.loginBtn,disabled:t.state.loginBtn}},[t._v("\n 登陆\n ")])],1)],1)],1)},i=[],n=a("cebc"),o=a("2f62"),s=a("ca00"),l={name:"Login",data:function(){return{form:this.$form.createForm(this),state:{loginBtn:!1}}},methods:Object(n["a"])({},Object(o["b"])(["Login","Logout"]),{handleSubmit:function(t){var e=this;t.preventDefault(),this.form.validateFields(function(t,a){t?(e.state.loginBtn=!0,setTimeout(function(){e.state.loginBtn=!1},500)):e.Login(a).then(function(t){e.state.loginBtn=!0,e.loginSuccess(t)}).catch(function(t){e.loginFail(t),e.state.loginBtn=!1})})},loginSuccess:function(t){var e=this;this.$router.push({name:"project"}),setTimeout(function(){e.$notification.success({message:"欢迎",description:"".concat(Object(s["a"])()," ").concat(t.username,",欢迎回来")})},1e3)},loginFail:function(t){this.$notification.error({message:"错误",description:t,duration:4})}})},c=l,u=(a("698e"),a("2877")),m=Object(u["a"])(c,r,i,!1,null,"38784526",null);e["default"]=m.exports}}]);
|
||||
//# sourceMappingURL=user.d638c020.js.map
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"include": ["src/**/*"]
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
{
|
||||
"name": "ConstructionConsultationSystem",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"test:unit": "vue-cli-service test:unit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/data-set": "^0.10.1",
|
||||
"ant-design-vue": "~1.3.2",
|
||||
"axios": "^0.18.0",
|
||||
"enquire.js": "^2.1.6",
|
||||
"js-cookie": "^2.2.0",
|
||||
"lodash": "^4.17.11",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.pick": "^4.4.0",
|
||||
"md5": "^2.2.1",
|
||||
"moment": "^2.24.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"viser-vue": "^2.3.3",
|
||||
"vue": "^2.5.22",
|
||||
"vue-clipboard2": "^0.2.1",
|
||||
"vue-cropper": "^0.4.4",
|
||||
"vue-ls": "^3.2.0",
|
||||
"vue-router": "^3.0.1",
|
||||
"vuex": "^3.1.0",
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^3.3.0",
|
||||
"@vue/cli-plugin-eslint": "^3.3.0",
|
||||
"@vue/cli-plugin-unit-jest": "^3.3.0",
|
||||
"@vue/cli-service": "^3.5.3",
|
||||
"@vue/eslint-config-standard": "^4.0.0",
|
||||
"@vue/test-utils": "^1.0.0-beta.20",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-jest": "^23.6.0",
|
||||
"babel-plugin-import": "^1.11.0",
|
||||
"eslint": "^5.8.0",
|
||||
"eslint-plugin-html": "^5.0.0",
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
"less": "^3.8.1",
|
||||
"less-loader": "^4.1.0",
|
||||
"vue-template-compiler": "^2.5.22"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/strongly-recommended",
|
||||
"@vue/standard"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"rules": {
|
||||
"generator-star-spacing": "off",
|
||||
"no-mixed-operators": 0,
|
||||
"vue/max-attributes-per-line": [
|
||||
2,
|
||||
{
|
||||
"singleline": 5,
|
||||
"multiline": {
|
||||
"max": 1,
|
||||
"allowFirstLine": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"vue/attribute-hyphenation": 0,
|
||||
"vue/html-self-closing": 0,
|
||||
"vue/component-name-in-template-casing": 0,
|
||||
"vue/html-closing-bracket-spacing": 0,
|
||||
"vue/singleline-html-element-content-newline": 0,
|
||||
"vue/no-unused-components": 0,
|
||||
"vue/multiline-html-element-content-newline": 0,
|
||||
"vue/no-use-v-if-with-v-for": 0,
|
||||
"vue/html-closing-bracket-newline": 0,
|
||||
"vue/no-parsing-error": 0,
|
||||
"no-console": 0,
|
||||
"no-tabs": 0,
|
||||
"quotes": [
|
||||
2,
|
||||
"single",
|
||||
{
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true
|
||||
}
|
||||
],
|
||||
"semi": [
|
||||
2,
|
||||
"never",
|
||||
{
|
||||
"beforeStatementContinuationChars": "never"
|
||||
}
|
||||
],
|
||||
"no-delete-var": 2,
|
||||
"prefer-const": [
|
||||
2,
|
||||
{
|
||||
"ignoreReadBeforeAssign": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"plugins": {
|
||||
"autoprefixer": {}
|
||||
}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-cmn-Hans">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>logo.png">
|
||||
<title>Booking Admin</title>
|
||||
<style>#preloadingAnimation{position:fixed;left:0;top:0;height:100%;width:100%;background:#ffffff;user-select:none;z-index: 9999;overflow: hidden}.lds-roller{display:inline-block;position:relative;left:50%;top:50%;transform:translate(-50%,-50%);width:64px;height:64px;}.lds-roller div{animation:lds-roller 1.2s cubic-bezier(0.5,0,0.5,1) infinite;transform-origin:32px 32px;}.lds-roller div:after{content:" ";display:block;position:absolute;width:6px;height:6px;border-radius:50%;background:#13c2c2;margin:-3px 0 0 -3px;}.lds-roller div:nth-child(1){animation-delay:-0.036s;}.lds-roller div:nth-child(1):after{top:50px;left:50px;}.lds-roller div:nth-child(2){animation-delay:-0.072s;}.lds-roller div:nth-child(2):after{top:54px;left:45px;}.lds-roller div:nth-child(3){animation-delay:-0.108s;}.lds-roller div:nth-child(3):after{top:57px;left:39px;}.lds-roller div:nth-child(4){animation-delay:-0.144s;}.lds-roller div:nth-child(4):after{top:58px;left:32px;}.lds-roller div:nth-child(5){animation-delay:-0.18s;}.lds-roller div:nth-child(5):after{top:57px;left:25px;}.lds-roller div:nth-child(6){animation-delay:-0.216s;}.lds-roller div:nth-child(6):after{top:54px;left:19px;}.lds-roller div:nth-child(7){animation-delay:-0.252s;}.lds-roller div:nth-child(7):after{top:50px;left:14px;}.lds-roller div:nth-child(8){animation-delay:-0.288s;}.lds-roller div:nth-child(8):after{top:45px;left:10px;}#preloadingAnimation .load-tips{color: #13c2c2;font-size:2rem;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:80px;text-align:center;width:400px;height:64px;} @keyframes lds-roller{0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);}}</style>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app">
|
||||
<div id="preloadingAnimation"><div class=lds-roller><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div><div class=load-tips>Loading</div></div>
|
||||
</div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
#preloadingAnimation{position:fixed;left:0;top:0;height:100%;width:100%;background:#ffffff;user-select:none;z-index: 9999;overflow: hidden}.lds-roller{display:inline-block;position:relative;left:50%;top:50%;transform:translate(-50%,-50%);width:64px;height:64px;}.lds-roller div{animation:lds-roller 1.2s cubic-bezier(0.5,0,0.5,1) infinite;transform-origin:32px 32px;}.lds-roller div:after{content:" ";display:block;position:absolute;width:6px;height:6px;border-radius:50%;background:#13c2c2;margin:-3px 0 0 -3px;}.lds-roller div:nth-child(1){animation-delay:-0.036s;}.lds-roller div:nth-child(1):after{top:50px;left:50px;}.lds-roller div:nth-child(2){animation-delay:-0.072s;}.lds-roller div:nth-child(2):after{top:54px;left:45px;}.lds-roller div:nth-child(3){animation-delay:-0.108s;}.lds-roller div:nth-child(3):after{top:57px;left:39px;}.lds-roller div:nth-child(4){animation-delay:-0.144s;}.lds-roller div:nth-child(4):after{top:58px;left:32px;}.lds-roller div:nth-child(5){animation-delay:-0.18s;}.lds-roller div:nth-child(5):after{top:57px;left:25px;}.lds-roller div:nth-child(6){animation-delay:-0.216s;}.lds-roller div:nth-child(6):after{top:54px;left:19px;}.lds-roller div:nth-child(7){animation-delay:-0.252s;}.lds-roller div:nth-child(7):after{top:50px;left:14px;}.lds-roller div:nth-child(8){animation-delay:-0.288s;}.lds-roller div:nth-child(8):after{top:45px;left:10px;}#preloadingAnimation .load-tips{color: #13c2c2;font-size:2rem;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:80px;text-align:center;width:400px;height:64px;} @keyframes lds-roller{0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);}}
|
|
@ -0,0 +1 @@
|
|||
<div id="preloadingAnimation"><div class=lds-roller><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div><div class=load-tips>Loading</div></div>
|
|
@ -0,0 +1,5 @@
|
|||
<div class="preloading-animate">
|
||||
<div class="preloading-wrapper">
|
||||
<svg class="preloading-balls" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="67.802" cy="59.907" r="6" fill="#51CACC"><animate attributeName="cx" values="75;57.72542485937369" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="50;73.77641290737884" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#51CACC;#9DF871" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="46.079" cy="69.992" r="6" fill="#9DF871"><animate attributeName="cx" values="57.72542485937369;29.774575140626318" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="73.77641290737884;64.69463130731182" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#9DF871;#E0FF77" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="29.775" cy="52.449" r="6" fill="#E0FF77"><animate attributeName="cx" values="29.774575140626318;29.774575140626315" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="64.69463130731182;35.30536869268818" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#E0FF77;#DE9DD6" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="41.421" cy="31.521" r="6" fill="#DE9DD6"><animate attributeName="cx" values="29.774575140626315;57.72542485937368" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="35.30536869268818;26.22358709262116" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#DE9DD6;#FF708E" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="64.923" cy="36.13" r="6" fill="#FF708E"><animate attributeName="cx" values="57.72542485937368;75" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="26.22358709262116;49.99999999999999" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#FF708E;#51CACC" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle></svg>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
.preloading-animate{background:#ffffff;width:100%;height:100%;position:fixed;left:0;top:0;z-index:299;}.preloading-animate .preloading-wrapper{position:absolute;width:5rem;height:5rem;left:50%;top:50%;transform:translate(-50%,-50%);}.preloading-animate .preloading-wrapper .preloading-balls{font-size:5rem;}
|
|
@ -0,0 +1 @@
|
|||
<svg class="preloading-balls" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="67.802" cy="59.907" r="6" fill="#51CACC"><animate attributeName="cx" values="75;57.72542485937369" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="50;73.77641290737884" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#51CACC;#9DF871" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="46.079" cy="69.992" r="6" fill="#9DF871"><animate attributeName="cx" values="57.72542485937369;29.774575140626318" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="73.77641290737884;64.69463130731182" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#9DF871;#E0FF77" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="29.775" cy="52.449" r="6" fill="#E0FF77"><animate attributeName="cx" values="29.774575140626318;29.774575140626315" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="64.69463130731182;35.30536869268818" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#E0FF77;#DE9DD6" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="41.421" cy="31.521" r="6" fill="#DE9DD6"><animate attributeName="cx" values="29.774575140626315;57.72542485937368" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="35.30536869268818;26.22358709262116" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#DE9DD6;#FF708E" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="64.923" cy="36.13" r="6" fill="#FF708E"><animate attributeName="cx" values="57.72542485937368;75" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="26.22358709262116;49.99999999999999" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#FF708E;#51CACC" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle></svg>
|
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1,45 @@
|
|||
<template>
|
||||
<a-locale-provider :locale="locale">
|
||||
<div id="app">
|
||||
<router-view/>
|
||||
</div>
|
||||
</a-locale-provider>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
|
||||
import { deviceEnquire, DEVICE_TYPE } from '@/utils/device'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
locale: zhCN
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
const { $store } = this
|
||||
deviceEnquire(deviceType => {
|
||||
switch (deviceType) {
|
||||
case DEVICE_TYPE.DESKTOP:
|
||||
$store.commit('TOGGLE_DEVICE', 'desktop')
|
||||
$store.dispatch('setSidebar', true)
|
||||
break
|
||||
case DEVICE_TYPE.TABLET:
|
||||
$store.commit('TOGGLE_DEVICE', 'tablet')
|
||||
$store.dispatch('setSidebar', false)
|
||||
break
|
||||
case DEVICE_TYPE.MOBILE:
|
||||
default:
|
||||
$store.commit('TOGGLE_DEVICE', 'mobile')
|
||||
$store.dispatch('setSidebar', true)
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
#app {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,25 @@
|
|||
import fetchAPI from '../utils/fetch'
|
||||
|
||||
export default {
|
||||
getRoleList () {
|
||||
return fetchAPI('user/roleList/', 'get')
|
||||
},
|
||||
getUserList (params) {
|
||||
return fetchAPI('user/', 'get', null, params)
|
||||
},
|
||||
createUser (user) {
|
||||
return fetchAPI('user/', 'post', user)
|
||||
},
|
||||
getUser (id) {
|
||||
return fetchAPI(`user/${id}/`, 'get')
|
||||
},
|
||||
updateUser (id, user) {
|
||||
return fetchAPI(`user/${id}/`, 'put', user)
|
||||
},
|
||||
deleteUser (id) {
|
||||
return fetchAPI(`user/${id}/`, 'delete')
|
||||
},
|
||||
checkUsername (username) {
|
||||
return fetchAPI('user/checkUsername/', 'get', null, { username })
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import fetchAPI from '../utils/fetch'
|
||||
|
||||
export default {
|
||||
getBookingList (params) {
|
||||
return fetchAPI('booking/', 'get', null, params)
|
||||
},
|
||||
createBooking (booking) {
|
||||
return fetchAPI('booking/', 'post', booking)
|
||||
},
|
||||
getStatusList () {
|
||||
return fetchAPI('booking/statusList/', 'get')
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import fetchAPI from '../utils/fetch'
|
||||
|
||||
export default {
|
||||
getRoomBookingStatus (params) {
|
||||
return fetchAPI('booking/room/bookingStatus/', 'get', null, params)
|
||||
},
|
||||
getRoomBookingStatusDetail (id, params) {
|
||||
return fetchAPI(`booking/room/${id}/bookingStatus/`, 'get', null, params)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import fetchAPI from '../utils/fetch'
|
||||
|
||||
export default {
|
||||
getRoomList (params) {
|
||||
return fetchAPI('booking/room/', 'get', null, params)
|
||||
},
|
||||
getRoom (id) {
|
||||
return fetchAPI(`booking/room/${id}/`, 'get')
|
||||
},
|
||||
updateRoom (id, room) {
|
||||
return fetchAPI(`booking/room/${id}/`, 'put', room)
|
||||
},
|
||||
getSeatList (params) {
|
||||
return fetchAPI('booking/seat/', 'get', null, params)
|
||||
},
|
||||
createSeat (seat) {
|
||||
return fetchAPI('booking/seat/', 'post', seat)
|
||||
},
|
||||
deleteSeat (id) {
|
||||
return fetchAPI(`booking/seat/${id}`, 'delete')
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import fetchAPI from '../utils/fetch'
|
||||
|
||||
export default {
|
||||
getSettingDetail() {
|
||||
return fetchAPI('booking/setting/1/', 'get')
|
||||
},
|
||||
updateSettingDetail(setting) {
|
||||
return fetchAPI('booking/setting/1/', 'put', setting)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import fetchAPI from '../utils/fetch'
|
||||
|
||||
export default {
|
||||
login (username, password) {
|
||||
return fetchAPI('user/login/', 'post', {
|
||||
username,
|
||||
password
|
||||
})
|
||||
},
|
||||
logout () {
|
||||
return fetchAPI('user/logout/', 'get')
|
||||
},
|
||||
getUser () {
|
||||
return fetchAPI('user/getInfo/', 'get')
|
||||
},
|
||||
resetPassword (new_password) {
|
||||
return fetchAPI('user/resetPassword/', 'post', {
|
||||
new_password
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="1361px" height="609px" viewBox="0 0 1361 609" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Group 21</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)">
|
||||
<g id="Group-21" transform="translate(77.000000, 73.000000)">
|
||||
<g id="Group-18" opacity="0.8" transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
|
||||
<ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367" rx="21.7830479" ry="21.766008"></ellipse>
|
||||
<ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601" rx="5.2173913" ry="5.21330997"></ellipse>
|
||||
<path d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z" id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"></path>
|
||||
<path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6" stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7" stroke-width="0.702678964" opacity="0.7" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9" stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<g id="Group-17" transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)" fill="#CFDAE6">
|
||||
<ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653" ry="9.12768076"></ellipse>
|
||||
<path d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z" id="Oval-4" transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-14" transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439" rx="29.1176471" ry="29.1402439"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439" rx="21.5686275" ry="21.5853659"></ellipse>
|
||||
<ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341" rx="23.7254902" ry="23.7439024"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439" rx="10.7843137" ry="10.7926829"></ellipse>
|
||||
<path d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z" id="Oval-2" fill="#BACAD9"></path>
|
||||
<g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)" fill="#E6A1A6">
|
||||
<ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824" ry="6.47560976"></ellipse>
|
||||
<path d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z" id="Oval-2-Copy-2" transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "></path>
|
||||
</g>
|
||||
<ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488" rx="2.15686275" ry="2.15853659"></ellipse>
|
||||
<path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6" opacity="0.8"></path>
|
||||
</g>
|
||||
<g id="Group-10" opacity="0.799999952" transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
|
||||
<ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32" rx="11.1864407" ry="11.2941176"></ellipse>
|
||||
<g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
|
||||
<ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627" ry="8.55614973"></ellipse>
|
||||
<path d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z" id="Oval-7"></path>
|
||||
</g>
|
||||
<path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
<ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186" cy="3.29411765" rx="3.26271186" ry="3.29411765"></ellipse>
|
||||
<ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017" ry="2.82352941"></ellipse>
|
||||
<path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
</g>
|
||||
<g id="Group-19" opacity="0.33" transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
|
||||
<g id="Group-17" transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)" fill="#BACAD9">
|
||||
<circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"></circle>
|
||||
<path d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z" id="Oval-4" transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "></path>
|
||||
</g>
|
||||
<circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"></circle>
|
||||
<path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667" points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"></polyline>
|
||||
<path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7" stroke-width="1.16666667" opacity="0.6"></path>
|
||||
<path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6" stroke-width="1.16666667"></path>
|
||||
<circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"></circle>
|
||||
<circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333" cy="30.3333333" r="5.83333333"></circle>
|
||||
<circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="200px" height="200px" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Group 28 Copy 5</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="62.1023273%" y1="0%" x2="108.19718%" y2="37.8635764%" id="linearGradient-1">
|
||||
<stop stop-color="#4285EB" offset="0%"></stop>
|
||||
<stop stop-color="#2EC7FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="69.644116%" y1="0%" x2="54.0428975%" y2="108.456714%" id="linearGradient-2">
|
||||
<stop stop-color="#29CDFF" offset="0%"></stop>
|
||||
<stop stop-color="#148EFF" offset="37.8600687%"></stop>
|
||||
<stop stop-color="#0A60FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="69.6908165%" y1="-12.9743587%" x2="16.7228981%" y2="117.391248%" id="linearGradient-3">
|
||||
<stop stop-color="#FA816E" offset="0%"></stop>
|
||||
<stop stop-color="#F74A5C" offset="41.472606%"></stop>
|
||||
<stop stop-color="#F51D2C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="68.1279872%" y1="-35.6905737%" x2="30.4400914%" y2="114.942679%" id="linearGradient-4">
|
||||
<stop stop-color="#FA8E7D" offset="0%"></stop>
|
||||
<stop stop-color="#F74A5C" offset="51.2635191%"></stop>
|
||||
<stop stop-color="#F51D2C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="logo" transform="translate(-20.000000, -20.000000)">
|
||||
<g id="Group-28-Copy-5" transform="translate(20.000000, 20.000000)">
|
||||
<g id="Group-27-Copy-3">
|
||||
<g id="Group-25" fill-rule="nonzero">
|
||||
<g id="2">
|
||||
<path d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C99.2571609,26.9692191 101.032305,26.9692191 102.20193,28.1378823 L129.985225,55.8983314 C134.193707,60.1033528 141.017005,60.1033528 145.225487,55.8983314 C149.433969,51.69331 149.433969,44.8756232 145.225487,40.6706018 L108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z" id="Shape" fill="url(#linearGradient-1)"></path>
|
||||
<path d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C100.999864,25.6271836 105.751642,20.541824 112.729652,19.3524487 C117.915585,18.4685261 123.585219,20.4140239 129.738554,25.1889424 C125.624663,21.0784292 118.571995,14.0340304 108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z" id="Shape" fill="url(#linearGradient-2)"></path>
|
||||
</g>
|
||||
<path d="M153.685633,135.854579 C157.894115,140.0596 164.717412,140.0596 168.925894,135.854579 L195.959977,108.842726 C200.659183,104.147384 200.659183,96.5636133 195.960527,91.8688194 L168.690777,64.7181159 C164.472332,60.5180858 157.646868,60.5241425 153.435895,64.7316526 C149.227413,68.936674 149.227413,75.7543607 153.435895,79.9593821 L171.854035,98.3623765 C173.02366,99.5310396 173.02366,101.304724 171.854035,102.473387 L153.685633,120.626849 C149.47715,124.83187 149.47715,131.649557 153.685633,135.854579 Z" id="Shape" fill="url(#linearGradient-3)"></path>
|
||||
</g>
|
||||
<ellipse id="Combined-Shape" fill="url(#linearGradient-4)" cx="100.519339" cy="100.436681" rx="23.6001926" ry="23.580786"></ellipse>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<tooltip v-if="tips !== ''">
|
||||
<template slot="title">{{ tips }}</template>
|
||||
<avatar :size="avatarSize" :src="src" />
|
||||
</tooltip>
|
||||
<avatar v-else :size="avatarSize" :src="src" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Avatar from 'ant-design-vue/es/avatar'
|
||||
import Tooltip from 'ant-design-vue/es/tooltip'
|
||||
|
||||
export default {
|
||||
name: 'AvatarItem',
|
||||
components: {
|
||||
Avatar,
|
||||
Tooltip
|
||||
},
|
||||
props: {
|
||||
tips: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
src: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
size: this.$parent.size
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
avatarSize () {
|
||||
return this.size !== 'mini' && this.size || 20
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$parent.size' (val) {
|
||||
this.size = val
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,99 @@
|
|||
<!--
|
||||
<template>
|
||||
<div :class="[prefixCls]">
|
||||
<ul>
|
||||
<slot></slot>
|
||||
<template v-for="item in filterEmpty($slots.default).slice(0, 3)"></template>
|
||||
|
||||
<template v-if="maxLength > 0 && filterEmpty($slots.default).length > maxLength">
|
||||
<avatar-item :size="size">
|
||||
<avatar :size="size !== 'mini' && size || 20" :style="excessItemsStyle">{{ `+${maxLength}` }}</avatar>
|
||||
</avatar-item>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
-->
|
||||
|
||||
<script>
|
||||
import Avatar from 'ant-design-vue/es/avatar'
|
||||
import AvatarItem from './Item'
|
||||
import { filterEmpty } from '@/components/_util/util'
|
||||
|
||||
export default {
|
||||
AvatarItem,
|
||||
name: 'AvatarList',
|
||||
components: {
|
||||
Avatar,
|
||||
AvatarItem
|
||||
},
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-avatar-list'
|
||||
},
|
||||
/**
|
||||
* 头像大小 类型: large、small 、mini, default
|
||||
* 默认值: default
|
||||
*/
|
||||
size: {
|
||||
type: [String, Number],
|
||||
default: 'default'
|
||||
},
|
||||
/**
|
||||
* 要显示的最大项目
|
||||
*/
|
||||
maxLength: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
/**
|
||||
* 多余的项目风格
|
||||
*/
|
||||
excessItemsStyle: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
color: '#f56a00',
|
||||
backgroundColor: '#fde3cf'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
getItems (items) {
|
||||
const classString = {
|
||||
[`${this.prefixCls}-item`]: true,
|
||||
[`${this.size}`]: true
|
||||
}
|
||||
|
||||
if (this.maxLength > 0) {
|
||||
items = items.slice(0, this.maxLength)
|
||||
items.push((<Avatar size={ this.size } style={ this.excessItemsStyle }>{`+${this.maxLength}`}</Avatar>))
|
||||
}
|
||||
const itemList = items.map((item) => (
|
||||
<li class={ classString }>{ item }</li>
|
||||
))
|
||||
return itemList
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { prefixCls, size } = this.$props
|
||||
const classString = {
|
||||
[`${prefixCls}`]: true,
|
||||
[`${size}`]: true
|
||||
}
|
||||
const items = filterEmpty(this.$slots.default)
|
||||
const itemsDom = items && items.length ? <ul class={`${prefixCls}-items`}>{ this.getItems(items) }</ul> : null
|
||||
|
||||
return (
|
||||
<div class={ classString }>
|
||||
{ itemsDom }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,4 @@
|
|||
import AvatarList from './List'
|
||||
import './index.less'
|
||||
|
||||
export default AvatarList
|
|
@ -0,0 +1,60 @@
|
|||
@import "../index";
|
||||
|
||||
@avatar-list-prefix-cls: ~"@{ant-pro-prefix}-avatar-list";
|
||||
@avatar-list-item-prefix-cls: ~"@{ant-pro-prefix}-avatar-list-item";
|
||||
|
||||
.@{avatar-list-prefix-cls} {
|
||||
display: inline-block;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
margin: 0 0 0 8px;
|
||||
font-size: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.@{avatar-list-item-prefix-cls} {
|
||||
display: inline-block;
|
||||
font-size: @font-size-base;
|
||||
margin-left: -8px;
|
||||
width: @avatar-size-base;
|
||||
height: @avatar-size-base;
|
||||
|
||||
:global {
|
||||
.ant-avatar {
|
||||
border: 1px solid #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&.large {
|
||||
width: @avatar-size-lg;
|
||||
height: @avatar-size-lg;
|
||||
}
|
||||
|
||||
&.small {
|
||||
width: @avatar-size-sm;
|
||||
height: @avatar-size-sm;
|
||||
}
|
||||
|
||||
&.mini {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
:global {
|
||||
.ant-avatar {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
|
||||
.ant-avatar-string {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
# AvatarList 用户头像列表
|
||||
|
||||
|
||||
一组用户头像,常用在项目/团队成员列表。可通过设置 `size` 属性来指定头像大小。
|
||||
|
||||
|
||||
|
||||
引用方式:
|
||||
|
||||
```javascript
|
||||
import AvatarList from '@/components/AvatarList'
|
||||
const AvatarListItem = AvatarList.AvatarItem
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AvatarList,
|
||||
AvatarListItem
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 代码演示 [demo](https://pro.loacg.com/test/home)
|
||||
|
||||
```html
|
||||
<avatar-list size="mini">
|
||||
<avatar-list-item tips="Jake" src="https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png" />
|
||||
<avatar-list-item tips="Andy" src="https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
</avatar-list>
|
||||
```
|
||||
或
|
||||
```html
|
||||
<avatar-list :max-length="3">
|
||||
<avatar-list-item tips="Jake" src="https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png" />
|
||||
<avatar-list-item tips="Andy" src="https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
</avatar-list>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### AvatarList
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| ---------------- | -------- | ---------------------------------- | --------- |
|
||||
| size | 头像大小 | `large`、`small` 、`mini`, `default` | `default` |
|
||||
| maxLength | 要显示的最大项目 | number | - |
|
||||
| excessItemsStyle | 多余的项目风格 | CSSProperties | - |
|
||||
|
||||
### AvatarList.Item
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| ---- | ------ | --------- | --- |
|
||||
| tips | 头像展示文案 | string | - |
|
||||
| src | 头像图片连接 | string | - |
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<span>
|
||||
{{ lastTime | format }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
function fixedZero (val) {
|
||||
return val * 1 < 10 ? `0${val}` : val
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'CountDown',
|
||||
props: {
|
||||
format: {
|
||||
type: Function,
|
||||
default: undefined
|
||||
},
|
||||
target: {
|
||||
type: [Date, Number],
|
||||
required: true
|
||||
},
|
||||
onEnd: {
|
||||
type: Function,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dateTime: '0',
|
||||
originTargetTime: 0,
|
||||
lastTime: 0,
|
||||
timer: 0,
|
||||
interval: 1000
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
format (time) {
|
||||
const hours = 60 * 60 * 1000
|
||||
const minutes = 60 * 1000
|
||||
|
||||
const h = Math.floor(time / hours)
|
||||
const m = Math.floor((time - h * hours) / minutes)
|
||||
const s = Math.floor((time - h * hours - m * minutes) / 1000)
|
||||
return `${fixedZero(h)}:${fixedZero(m)}:${fixedZero(s)}`
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.initTime()
|
||||
this.tick()
|
||||
},
|
||||
methods: {
|
||||
initTime () {
|
||||
let lastTime = 0
|
||||
let targetTime = 0
|
||||
this.originTargetTime = this.target
|
||||
try {
|
||||
if (Object.prototype.toString.call(this.target) === '[object Date]') {
|
||||
targetTime = this.target
|
||||
} else {
|
||||
targetTime = new Date(this.target).getTime()
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error('invalid target prop')
|
||||
}
|
||||
|
||||
lastTime = targetTime - new Date().getTime()
|
||||
|
||||
this.lastTime = lastTime < 0 ? 0 : lastTime
|
||||
},
|
||||
tick () {
|
||||
const { onEnd } = this
|
||||
|
||||
this.timer = setTimeout(() => {
|
||||
if (this.lastTime < this.interval) {
|
||||
clearTimeout(this.timer)
|
||||
this.lastTime = 0
|
||||
if (typeof onEnd === 'function') {
|
||||
onEnd()
|
||||
}
|
||||
} else {
|
||||
this.lastTime -= this.interval
|
||||
this.tick()
|
||||
}
|
||||
}, this.interval)
|
||||
}
|
||||
},
|
||||
beforeUpdate () {
|
||||
if (this.originTargetTime !== this.target) {
|
||||
this.initTime()
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearTimeout(this.timer)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,3 @@
|
|||
import CountDown from './CountDown'
|
||||
|
||||
export default CountDown
|
|
@ -0,0 +1,34 @@
|
|||
# CountDown 倒计时
|
||||
|
||||
倒计时组件。
|
||||
|
||||
|
||||
|
||||
引用方式:
|
||||
|
||||
```javascript
|
||||
import CountDown from '@/components/CountDown/CountDown'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CountDown
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 代码演示 [demo](https://pro.loacg.com/test/home)
|
||||
|
||||
```html
|
||||
<count-down :target="new Date().getTime() + 3000000" :on-end="onEndHandle" />
|
||||
```
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------|------------------------------------------|-------------|-------|
|
||||
| target | 目标时间 | Date | - |
|
||||
| onEnd | 倒计时结束回调 | funtion | -|
|
|
@ -0,0 +1,64 @@
|
|||
<script>
|
||||
import Tooltip from 'ant-design-vue/es/tooltip'
|
||||
import { cutStrByFullLength, getStrFullLength } from '@/components/_util/StringUtil'
|
||||
/*
|
||||
const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined;
|
||||
|
||||
const TooltipOverlayStyle = {
|
||||
overflowWrap: 'break-word',
|
||||
wordWrap: 'break-word',
|
||||
};
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'Ellipsis',
|
||||
components: {
|
||||
Tooltip
|
||||
},
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-ellipsis'
|
||||
},
|
||||
tooltip: {
|
||||
type: Boolean
|
||||
},
|
||||
length: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
lines: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
fullWidthRecognition: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getStrDom (str, fullLength) {
|
||||
return (
|
||||
<span>{ cutStrByFullLength(str, this.length) + (fullLength > this.length ? '...' : '') }</span>
|
||||
)
|
||||
},
|
||||
getTooltip (fullStr, fullLength) {
|
||||
return (
|
||||
<Tooltip>
|
||||
<template slot="title">{ fullStr }</template>
|
||||
{ this.getStrDom(fullStr, fullLength) }
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { tooltip, length } = this.$props
|
||||
const str = this.$slots.default.map(vNode => vNode.text).join('')
|
||||
const fullLength = getStrFullLength(str)
|
||||
const strDom = tooltip && fullLength > length ? this.getTooltip(str, fullLength) : this.getStrDom(str, fullLength)
|
||||
return (
|
||||
strDom
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,3 @@
|
|||
import Ellipsis from './Ellipsis'
|
||||
|
||||
export default Ellipsis
|
|
@ -0,0 +1,38 @@
|
|||
# Ellipsis 文本自动省略号
|
||||
|
||||
文本过长自动处理省略号,支持按照文本长度和最大行数两种方式截取。
|
||||
|
||||
|
||||
|
||||
引用方式:
|
||||
|
||||
```javascript
|
||||
import Ellipsis from '@/components/Ellipsis'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Ellipsis
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 代码演示 [demo](https://pro.loacg.com/test/home)
|
||||
|
||||
```html
|
||||
<ellipsis :length="100" tooltip>
|
||||
There were injuries alleged in three cases in 2015, and a
|
||||
fourth incident in September, according to the safety recall report. After meeting with US regulators in October, the firm decided to issue a voluntary recall.
|
||||
</ellipsis>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
|
||||
参数 | 说明 | 类型 | 默认值
|
||||
----|------|-----|------
|
||||
tooltip | 移动到文本展示完整内容的提示 | boolean | -
|
||||
length | 在按照长度截取下的文本最大字符数,超过则截取省略 | number | -
|
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<div :class="prefixCls">
|
||||
<div style="float: left">
|
||||
<slot name="extra">{{ extra }}</slot>
|
||||
</div>
|
||||
<div style="float: right">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FooterToolBar',
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-footer-toolbar'
|
||||
},
|
||||
extra: {
|
||||
type: [String, Object],
|
||||
default: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,4 @@
|
|||
import FooterToolBar from './FooterToolBar'
|
||||
import './index.less'
|
||||
|
||||
export default FooterToolBar
|
|
@ -0,0 +1,23 @@
|
|||
@import "../index";
|
||||
|
||||
@footer-toolbar-prefix-cls: ~"@{ant-pro-prefix}-footer-toolbar";
|
||||
|
||||
.@{footer-toolbar-prefix-cls} {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.03);
|
||||
background: #fff;
|
||||
border-top: 1px solid #e8e8e8;
|
||||
padding: 0 24px;
|
||||
z-index: 9;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
# FooterToolbar 底部工具栏
|
||||
|
||||
固定在底部的工具栏。
|
||||
|
||||
|
||||
|
||||
## 何时使用
|
||||
|
||||
固定在内容区域的底部,不随滚动条移动,常用于长页面的数据搜集和提交工作。
|
||||
|
||||
|
||||
|
||||
引用方式:
|
||||
|
||||
```javascript
|
||||
import FooterToolBar from '@/components/FooterToolbar'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FooterToolBar
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 代码演示
|
||||
|
||||
```html
|
||||
<footer-tool-bar>
|
||||
<a-button type="primary" @click="validate" :loading="loading">提交</a-button>
|
||||
</footer-tool-bar>
|
||||
```
|
||||
或
|
||||
```html
|
||||
<footer-tool-bar extra="扩展信息提示">
|
||||
<a-button type="primary" @click="validate" :loading="loading">提交</a-button>
|
||||
</footer-tool-bar>
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
参数 | 说明 | 类型 | 默认值
|
||||
----|------|-----|------
|
||||
children (slot) | 工具栏内容,向右对齐 | - | -
|
||||
extra | 额外信息,向左对齐 | String, Object | -
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
<template>
|
||||
<div style="margin: -23px -24px 24px -24px">
|
||||
<a-tabs
|
||||
hideAdd
|
||||
v-model="activeKey"
|
||||
type="editable-card"
|
||||
:tabBarStyle="{ background: '#FFF', margin: 0, paddingLeft: '16px', paddingTop: '1px' }"
|
||||
@edit="onEdit"
|
||||
>
|
||||
<a-tab-pane v-for="page in pages" :style="{ height: 0 }" :tab="page.meta.title" :key="page.fullPath" :closable="pages.length > 1">
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MultiTab',
|
||||
data () {
|
||||
return {
|
||||
fullPathList: [],
|
||||
pages: [],
|
||||
activeKey: '',
|
||||
newTabIndex: 0
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.pages.push(this.$route)
|
||||
this.fullPathList.push(this.$route.fullPath)
|
||||
},
|
||||
methods: {
|
||||
onEdit (targetKey, action) {
|
||||
this[action](targetKey)
|
||||
},
|
||||
remove (targetKey) {
|
||||
if (this.pages.length === 1) {
|
||||
return
|
||||
}
|
||||
this.pages = this.pages.filter(page => page.fullPath !== targetKey)
|
||||
this.fullPathList = this.fullPathList.filter(path => path !== targetKey)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$route': function (newVal) {
|
||||
this.activeKey = newVal.fullPath
|
||||
if (this.fullPathList.indexOf(newVal.fullPath) < 0) {
|
||||
this.fullPathList.push(newVal.fullPath)
|
||||
this.pages.push(newVal)
|
||||
}
|
||||
},
|
||||
activeKey: function (newPathKey) {
|
||||
this.$router.push({ path: newPathKey })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|