# sales_views.py
# ————————47PerfectCRM实现CRM客户报名流程————————
from django.db import IntegrityError # 主动捕捉错误信息
from django.shortcuts import render # 页面返回
from crm import models # 数据库
from bpm.bpm_auxiliary import bpm_forms # 自定制 forms
from django.contrib.auth.decorators import login_required # 登陆后页面才能访问 # ————————47PerfectCRM实现CRM客户报名流程————————
from django.core.mail import send_mail
# send_mail的参数分别是 邮件标题,邮件内容,发件箱(settings.py中设置过的那个),收件箱列表(可以发送给多个人),失败静默(若发送失败,报错提示我们)
import random
import datetime # 获取时间#登陆过期 # 发送邮件的功能 #验证码#密码
class stmp():
def __init__(self):
self.emaillist = [] # 发送给谁
self.code = None # 验证码#密码 def stmps(self, request, email, msg_mail): # 传参数#页面,session #邮箱,发送给谁 #内容
self.emaillist.append(email) # 将邮箱地址添加到调用Django发送邮件功能
# ——————生成验证码——————
_letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z
_upper_cases = _letter_cases.upper() # 大写字母
_numbers = ''.join(map(str, range(3, 10))) # 数字
chars = ''.join((_letter_cases, _upper_cases, _numbers)) # 变成一条字符串
list = random.sample(chars, 4) # 从一条字符串随机选4个字符变成列表
self.code = ''.join(list) # 列表变字符串
# ——————生成验证码——————
# ——————调用Django发送邮件——————
title = 'PerfectCRM项目自动邮件:%s' % self.code # 邮件标题#防止一样的内容被邮箱屏蔽
send_mail(title, # 邮件标题
msg_mail, # 验证码内容
'perfectcrm@sina.cn', # 发送的邮箱 #根据情况重新配置
self.emaillist, # 接受的邮箱
fail_silently=False, # 静默,抛出异常
)
print('发送邮件成功!没收到要换标题!检查发送邮箱的配置!')
# ——————调用Django发送邮件—————— # ————————47PerfectCRM实现CRM客户报名流程————————
# ————————47PerfectCRM实现CRM客户报名流程————————
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
import random # 随机
import string # 字母 数字
from django.core.cache import cache # 缓存
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码———————— # 报名填写 销售
@login_required # 登陆后页面才能访问
def enrollment(request, customer_id):
msgs = {} # 错误信息
customer_obj = models.Customer.objects.get(id=customer_id) # 取到客户信息记录 #返回到页面#报名人
consultant_obj = models.UserProfile.objects.get(id=request.user.id) # 报名课程顾问 stmp_mail = {} # 邮件发送成功
stmpemail = stmp() # 实例化发送邮件的功能
email = request.POST.get('email') # 让页面POST提交的值,在页面GET后仍然存在显示
if request.method == "POST":
enroll_form = bpm_forms.EnrollmentForm(request.POST) # 获取数据
if enroll_form.is_valid(): # 表单验证 # ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# msg = "http://127.0.0.1:8000/bpm/customer/registration/{enroll_obj_id}/"
msg = "http://127.0.0.1:8000/bpm/customer/registration/{enroll_obj_id}/{random_str}/ "
random_str = ''.join(random.sample(string.ascii_lowercase + string.digits, 8)) # 生成8位随机字符串 #URL使用
url_str = '''customer/registration/{enroll_obj_id}/{random_str}/''' # 报名链接
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码———————— try:
enroll_form.cleaned_data['customer'] = customer_obj # 添加学员对象 记录 #报名人
enroll_form.cleaned_data['consultant'] = consultant_obj # 报名课程顾问
enroll_obj = models.Enrollment.objects.create(**enroll_form.cleaned_data) # 创建记录 # ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# msgs['msg']=msg.format(enroll_obj_id=enroll_obj.id)#报名记录对应的id,随机字符串,报名链接
sort_url = enroll_obj.id # 获取报名表对应的ID
cache.set(enroll_obj.id, random_str, 61000) # 加入过期时间 #URL使用 # cache缓存
msgs['msg'] = msg.format(enroll_obj_id=enroll_obj.id, random_str=random_str) # 报名记录对应的id,随机字符串,报名链接
url_str = url_str.format(enroll_obj_id=enroll_obj.id, random_str=random_str) # 报名链接
print(url_str)
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
except IntegrityError as e:
# 取到这条记录
enroll_obj = models.Enrollment.objects.get(customer_id=customer_obj.id,
enrolled_class_id=enroll_form.cleaned_data[
'enrolled_class'].id)
enroll_form.add_error('__all__', '记录已经存在,不能重复创建!') # ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# msgs['msg']=msg.format(enroll_obj_id=enroll_obj.id)#报名记录对应的id
cache.set(enroll_obj.id, random_str, 61000) # 加入过期时间 #URL使用 # cache缓存
msgs['msg'] = msg.format(enroll_obj_id=enroll_obj.id, random_str=random_str) # 报名记录对应的id
url_str = url_str.format(enroll_obj_id=enroll_obj.id, random_str=random_str) # 报名链接
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码———————— if email:
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# msg_mail = "http://127.0.0.1:8000/bpm/customer/registration/%s" %enroll_obj.id
msg_mail = "http://127.0.0.1:8000/bpm/customer/registration/%s/%s" %(enroll_obj.id,random_str)
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
stmpemail.stmps(request, email, msg_mail) # 发送邮件
stmp_mail['ok'] = "邮件已发送成功!" else:
enroll_form = bpm_forms.EnrollmentForm() # modelform表单
return render(request, 'bpm_sales/enrollment.html', locals())
# ————————47PerfectCRM实现CRM客户报名流程———————— # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
#学员合同签定 # ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————
import os
from PerfectCRM import settings
import json
# ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片———————— # ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
from django.shortcuts import HttpResponse #页面返回
# def stu_registration(request,enroll_id):
def stu_registration(request,enroll_id,random_str):
# enroll_obj=models.Enrollment.objects.get(id=enroll_id)#获取报名记录
if cache.get(enroll_id) == random_str: # 判断链接失效了没有
enroll_obj = models.Enrollment.objects.get(id=enroll_id) # 报名记录
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码———————— # ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————
enrolled_path='%s/%s/'%(settings.ENROLLED_DATA,enroll_id)#证件上传路径
img_file_len=0 #文件
if os.path.exists(enrolled_path):#判断目录是否存在
img_file_list=os.listdir(enrolled_path)#取目录 下的文件
img_file_len=len(img_file_list)
# ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片———————— # ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
if request.method == "POST": # ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————
ret=False
data=request.POST.get('data')
if data:#如果有删除动作
del_img_path="%s/%s/%s"%(settings.ENROLLED_DATA,enroll_id,data)#路径
print(del_img_path,'=-=-=-=-=-=')
os.remove(del_img_path)
ret=True
return HttpResponse(json.dumps(ret))
if request.is_ajax():#ajax上传图片 #异步提交
print('ajax上传图片 #异步提交中。。。 ',request.FILES)
enroll_data_dir="%s/%s"%(settings.ENROLLED_DATA,enroll_id)#路径 #重要信息不能放在静态文件中
if not os.path.exists(enroll_data_dir):#如果不存目录
os.makedirs(enroll_data_dir,exist_ok=True)#创建目录
for k,file_obj in request.FILES.items(): #循环字典 #上传的文件
with open("%s/%s"%(enroll_data_dir,file_obj.name),'wb') as f: #打开一个文件#路径#获取文件名
for chunk in file_obj.chunks():#循环写入文件 # chunks块
f.write(chunk) #保存文件
return HttpResponse('上传完成!')
# ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片———————— customer_form = bpm_forms.CustomerForm(request.POST, instance=enroll_obj.customer) # 生成表单验证
if customer_form.is_valid(): # 表单验证通过
customer_form.save() # 保存
enroll_obj.contract_agreed = True # 同意协议
enroll_obj.save() # 保存
status = 1 # 修改报名状态 # 1 已经报名
return render(request, 'bpm_sales/stu_registration.html', locals()) else:
if enroll_obj.contract_agreed == True: # 如果协议已经签订
status = 1 # 修改报名状态 # 1 已经报名
else:
status = 0
customer_form = bpm_forms.CustomerForm(instance=enroll_obj.customer) # 生成表单
# customer_form = bpm_forms.CustomerForm(instance=enroll_obj.customer) # 生成表单
# ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证———————— return render(request,'bpm_sales/stu_registration.html',locals())
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# ————————48PerfectCRM实现CRM客户报名流程学生合同————————
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
else:
return HttpResponse('链接失效,非法链接,请自重!')
# ————————50PerfectCRM实现CRM客户报名流程学生合同URL随机码————————
# sales_views.py
{#stu_registration.html#}
{## ————————48PerfectCRM实现CRM客户报名流程学生合同————————#}
{% extends 'bpm_master/bpm_sample.html' %}
{% load bpm_tags %}
{% block right-container-content %} {#自定义内容开始 右边页面内容#}
<div class="container col-lg-7 col-md-offset-2">
<div class="panel panel-warning">
<div class=" panel-heading">
<h3 class="panel-title container">报名入学|信息填写</h3>
</div>
<div class="panel-body "><!--返回提交函数-->
{## ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————#}
{% if status != 1 %}
<span class="errors">{{ customer_form.errors }}</span><!--错误提示-->
{## ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————#}
{## ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————#}
{# <form method="post" class="form-horizontal" role="form">{% csrf_token %}#}
<form method="post" class="form-horizontal" role="form"
onsubmit="return RegisterFormCheck()">{% csrf_token %}
{## ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————#}
{% for foo in customer_form %}
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">{{ foo.label }}</label>
<div class="col-sm-8">
{{ foo }}
</div>
</div>
{% endfor %}
<hr>
{#返回06学员报名信息表的数据#}
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">所报班级</label>
<div class="col-sm-8">
{{ enroll_obj.enrolled_class }}
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">课程费用</label>
<div class="col-sm-8">
{{ enroll_obj.enrolled_class.course.price }}
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">开课日期</label>
<div class="col-sm-8">
{{ enroll_obj.enrolled_class.start_date }}
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">合同</label>
<div class="col-sm-10">
<div style="width: 550px">
<pre style="height: 300px">{% render_enrolled_contract enroll_obj %} </pre>
</div> </div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="checkbox" value="{{ enroll_obj.contract_agreed }}" name="contract_agreed"
checked>
我已经认真阅读完协议并接受所有条款
</div>
</div>
<div class="text-center">
<input type="submit" class="btn btn-info" value="提交">
</div>
</form> {## ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————#}
<div class="row">
<div class="col-xs-6 col-md-3">
{% for img_file in img_file_list %}
<div class="right">
<a href="#" class="thumbnail" name="{{ img_file }}">
<img src="/static/enrolled_data/{{ enroll_id }}/{{ img_file }}" alt="...">
</a>
<a class="del_img">删除</a>
<span class="img_f hide">{{ img_file }}</span>
</div>
{% endfor %}
</div>
</div>
<p>请上传身份证反面照片</p>
<form action="{{ request.path }}" class="dropzone form-group" id="filerdropzone" method="post"
enctype="multipart/form-data">{% csrf_token %} <input type="hidden" name="file_id" ng-model="file_id" id="file_id"/>
</form>
{## ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————#} {## ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————#}
{% else %}
<h3>报名成功,同合进入审核流程,感谢您的选择!</h3>
{% endif %}
{## ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————#}
</div>
<div class="panel-footer">
<input type="button" class="btn btn-danger right" value="关闭" onclick="CloseWebPage()">
</div>
</div>
</div>
{% endblock %} {% block js %}
<script>
function CloseWebPage() {
if (confirm("您确定要关闭本页吗?")) {
window.opener = null;
window.open('', '_self');
window.close();
}
else {
}
} {## ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————#} function RegisterFormCheck() {
{## ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————#}
if (myDropzone.files.length < 2) {
alert('请上传身份证正反面!2张!)');
return false;
}
{## ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————#}
if ($('form :checkbox').prop("checked")) {
$("form").find("[disabled]").removeAttr("disabled");//移除不可修改 便于提交表单 #qq
return true;
} else {
alert('请认真阅读并且同意条款,才可以报名');
return false;
}
} {## ————————49PerfectCRM实现CRM客户报名流程学生合同表单验证————————#} {## ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————#}
{##————————cookies删除文件JS事件————————#}
$('.del_img').click(function () {
s = $(this);
texts = s.parent().children("span").text();
$.ajax({
url: "{{ request.path }}",
type: "post",
data: {"data": texts},
headers: {'X-CSRFtoken': $.cookie('csrftoken')},
success: function (arg) {
if (arg) {
alert('删除成功!');
s.parent('div').addClass('hide');
}
}
})
});
{##————————cookies删除文件JS事件————————#}
{##————————dropzone上传文件插件————————#}
Dropzone.autoDiscover = false;
appElement = document.querySelector('div .inmodal');
myDropzone = new Dropzone("#filerdropzone", {
url: '{{ request.path }}',//路径为 当前页
paramName: "file", //默认为file
method: "post",
maxFilesize: 1,//MB 兆# 1048576字节
addRemoveLinks: true,
maxFiles: 2,
acceptedFiles: ".jpg,.gif,.png,.jpeg", //上传的类型
uploadMultiple: true,
parallelUploads: 1,//一次上传的文件数量
dictDefaultMessage: '请将照片拖到这里或点击上传',
dictMaxFilesExceeded: "您最多只能上传2个文件!",
dictResponseError: '文件上传失败!',
dictInvalidFileType: "文件类型只能是*.zip,*.7z。",
dictFallbackMessage: "浏览器不受支持",
dictFileTooBig: "文件过大上传文件最大支持.",
dictRemoveLinks: "删除",
dictCancelUpload: "取消",
init: function () {
this.on("addedfile", function (file) {
//上传文件时触发的事件
document.querySelector('div .dz-default').style.display = 'none';
});
this.on("success", function (file, data) {
//上传成功触发的事件
console.log('ok');
// angular.element(appElement).scope().file_id = data.data.id;
});
this.on("error", function (file, data) {
//上传失败触发的事件
console.log('fail');
var message = '';
//lavarel框架有一个表单验证,
//对于ajax请求,JSON 响应会发送一个 422 HTTP 状态码,
//对应file.accepted的值是false,在这里捕捉表单验证的错误提示
if (file.accepted) {
$.each(data, function (key, val) {
message = message + val[0] + ';';
});
//控制器层面的错误提示,file.accepted = true的时候;
alert(message);
}
});
this.on("removedfile", function (file) {
//删除文件时触发的方法 document.querySelector('div .dz-default').style.display = 'block';
});
}
});
{##————————dropzone上传文件插件————————#}
{## ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————#}
</script> {% endblock %}
{## ————————48PerfectCRM实现CRM客户报名流程学生合同————————#}
{#stu_registration.html#}
/*!
* jQuery Cookie Plugin v1.4.1
* https://github.com/carhartl/jquery-cookie
*
* Copyright 2013 Klaus Hartl
* Released under the MIT license
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}(function ($) { var pluses = /\+/g; function encode(s) {
return config.raw ? s : encodeURIComponent(s);
} function decode(s) {
return config.raw ? s : decodeURIComponent(s);
} function stringifyCookieValue(value) {
return encode(config.json ? JSON.stringify(value) : String(value));
} function parseCookieValue(s) {
if (s.indexOf('"') === 0) {
// This is a quoted cookie as according to RFC2068, unescape...
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
} try {
// Replace server-side written pluses with spaces.
// If we can't decode the cookie, ignore it, it's unusable.
// If we can't parse the cookie, ignore it, it's unusable.
s = decodeURIComponent(s.replace(pluses, ' '));
return config.json ? JSON.parse(s) : s;
} catch(e) {}
} function read(s, converter) {
var value = config.raw ? s : parseCookieValue(s);
return $.isFunction(converter) ? converter(value) : value;
} var config = $.cookie = function (key, value, options) { // Write if (value !== undefined && !$.isFunction(value)) {
options = $.extend({}, config.defaults, options); if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setTime(+t + days * 864e+5);
} return (document.cookie = [
encode(key), '=', stringifyCookieValue(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
} // Read var result = key ? undefined : {}; // To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling $.cookie().
var cookies = document.cookie ? document.cookie.split('; ') : []; for (var i = 0, l = cookies.length; i < l; i++) {
var parts = cookies[i].split('=');
var name = decode(parts.shift());
var cookie = parts.join('='); if (key && key === name) {
// If second argument (value) is a function it's a converter...
result = read(cookie, value);
break;
} // Prevent storing a cookie that we couldn't decode.
if (!key && (cookie = read(cookie)) !== undefined) {
result[name] = cookie;
}
} return result;
}; config.defaults = {}; $.removeCookie = function (key, options) {
if ($.cookie(key) === undefined) {
return false;
} // Must not alter options, thus extending a fresh object...
$.cookie(key, '', $.extend({}, options, { expires: -1 }));
return !$.cookie(key);
}; }));
jQueryCookie.js
@-webkit-keyframes passing-through {
0% {
opacity:;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px); }
30%, 70% {
opacity:;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px); }
100% {
opacity:;
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
transform: translateY(-40px); } }
@-moz-keyframes passing-through {
0% {
opacity:;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px); }
30%, 70% {
opacity:;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px); }
100% {
opacity:;
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
transform: translateY(-40px); } }
@keyframes passing-through {
0% {
opacity:;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px); }
30%, 70% {
opacity:;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px); }
100% {
opacity:;
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
transform: translateY(-40px); } }
@-webkit-keyframes slide-in {
0% {
opacity:;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px); }
30% {
opacity:;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px); } }
@-moz-keyframes slide-in {
0% {
opacity:;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px); }
30% {
opacity:;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px); } }
@keyframes slide-in {
0% {
opacity:;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px); }
30% {
opacity:;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px); } }
@-webkit-keyframes pulse {
0% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1); }
10% {
-webkit-transform: scale(1.1);
-moz-transform: scale(1.1);
-ms-transform: scale(1.1);
-o-transform: scale(1.1);
transform: scale(1.1); }
20% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1); } }
@-moz-keyframes pulse {
0% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1); }
10% {
-webkit-transform: scale(1.1);
-moz-transform: scale(1.1);
-ms-transform: scale(1.1);
-o-transform: scale(1.1);
transform: scale(1.1); }
20% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1); } }
@keyframes pulse {
0% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1); }
10% {
-webkit-transform: scale(1.1);
-moz-transform: scale(1.1);
-ms-transform: scale(1.1);
-o-transform: scale(1.1);
transform: scale(1.1); }
20% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1); } }
.dropzone, .dropzone * {
box-sizing: border-box; } .dropzone {
min-height: 150px;
border: 2px solid rgba(0, 0, 0, 0.3);
background: white;
padding: 54px 54px; }
.dropzone.dz-clickable {
cursor: pointer; }
.dropzone.dz-clickable * {
cursor: default; }
.dropzone.dz-clickable .dz-message, .dropzone.dz-clickable .dz-message * {
cursor: pointer; }
.dropzone.dz-started .dz-message {
display: none; }
.dropzone.dz-drag-hover {
border-style: solid; }
.dropzone.dz-drag-hover .dz-message {
opacity: 0.5; }
.dropzone .dz-message {
text-align: center;
margin: 2em 0; }
.dropzone .dz-preview {
position: relative;
display: inline-block;
vertical-align: top;
margin: 16px;
min-height: 100px; }
.dropzone .dz-preview:hover {
z-index:; }
.dropzone .dz-preview:hover .dz-details {
opacity:; }
.dropzone .dz-preview.dz-file-preview .dz-image {
border-radius: 20px;
background: #999;
background: linear-gradient(to bottom, #eee, #ddd); }
.dropzone .dz-preview.dz-file-preview .dz-details {
opacity:; }
.dropzone .dz-preview.dz-image-preview {
background: white; }
.dropzone .dz-preview.dz-image-preview .dz-details {
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-ms-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear; }
.dropzone .dz-preview .dz-remove {
font-size: 14px;
text-align: center;
display: block;
cursor: pointer;
border: none; }
.dropzone .dz-preview .dz-remove:hover {
text-decoration: underline; }
.dropzone .dz-preview:hover .dz-details {
opacity:; }
.dropzone .dz-preview .dz-details {
z-index:;
position: absolute;
top:;
left:;
opacity:;
font-size: 13px;
min-width: 100%;
max-width: 100%;
padding: 2em 1em;
text-align: center;
color: rgba(0, 0, 0, 0.9);
line-height: 150%; }
.dropzone .dz-preview .dz-details .dz-size {
margin-bottom: 1em;
font-size: 16px; }
.dropzone .dz-preview .dz-details .dz-filename {
white-space: nowrap; }
.dropzone .dz-preview .dz-details .dz-filename:hover span {
border: 1px solid rgba(200, 200, 200, 0.8);
background-color: rgba(255, 255, 255, 0.8); }
.dropzone .dz-preview .dz-details .dz-filename:not(:hover) {
overflow: hidden;
text-overflow: ellipsis; }
.dropzone .dz-preview .dz-details .dz-filename:not(:hover) span {
border: 1px solid transparent; }
.dropzone .dz-preview .dz-details .dz-filename span, .dropzone .dz-preview .dz-details .dz-size span {
background-color: rgba(255, 255, 255, 0.4);
padding: 0 0.4em;
border-radius: 3px; }
.dropzone .dz-preview:hover .dz-image img {
-webkit-transform: scale(1.05, 1.05);
-moz-transform: scale(1.05, 1.05);
-ms-transform: scale(1.05, 1.05);
-o-transform: scale(1.05, 1.05);
transform: scale(1.05, 1.05);
-webkit-filter: blur(8px);
filter: blur(8px); }
.dropzone .dz-preview .dz-image {
border-radius: 20px;
overflow: hidden;
width: 120px;
height: 120px;
position: relative;
display: block;
z-index:; }
.dropzone .dz-preview .dz-image img {
display: block; }
.dropzone .dz-preview.dz-success .dz-success-mark {
-webkit-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
-moz-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
-ms-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
-o-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); }
.dropzone .dz-preview.dz-error .dz-error-mark {
opacity:;
-webkit-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
-moz-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
-ms-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
-o-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); }
.dropzone .dz-preview .dz-success-mark, .dropzone .dz-preview .dz-error-mark {
pointer-events: none;
opacity:;
z-index:;
position: absolute;
display: block;
top: 50%;
left: 50%;
margin-left: -27px;
margin-top: -27px; }
.dropzone .dz-preview .dz-success-mark svg, .dropzone .dz-preview .dz-error-mark svg {
display: block;
width: 54px;
height: 54px; }
.dropzone .dz-preview.dz-processing .dz-progress {
opacity:;
-webkit-transition: all 0.2s linear;
-moz-transition: all 0.2s linear;
-ms-transition: all 0.2s linear;
-o-transition: all 0.2s linear;
transition: all 0.2s linear; }
.dropzone .dz-preview.dz-complete .dz-progress {
opacity:;
-webkit-transition: opacity 0.4s ease-in;
-moz-transition: opacity 0.4s ease-in;
-ms-transition: opacity 0.4s ease-in;
-o-transition: opacity 0.4s ease-in;
transition: opacity 0.4s ease-in; }
.dropzone .dz-preview:not(.dz-processing) .dz-progress {
-webkit-animation: pulse 6s ease infinite;
-moz-animation: pulse 6s ease infinite;
-ms-animation: pulse 6s ease infinite;
-o-animation: pulse 6s ease infinite;
animation: pulse 6s ease infinite; }
.dropzone .dz-preview .dz-progress {
opacity:;
z-index:;
pointer-events: none;
position: absolute;
height: 16px;
left: 50%;
top: 50%;
margin-top: -8px;
width: 80px;
margin-left: -40px;
background: rgba(255, 255, 255, 0.9);
-webkit-transform: scale(1);
border-radius: 8px;
overflow: hidden; }
.dropzone .dz-preview .dz-progress .dz-upload {
background: #333;
background: linear-gradient(to bottom, #666, #444);
position: absolute;
top:;
left:;
bottom:;
width:;
-webkit-transition: width 300ms ease-in-out;
-moz-transition: width 300ms ease-in-out;
-ms-transition: width 300ms ease-in-out;
-o-transition: width 300ms ease-in-out;
transition: width 300ms ease-in-out; }
.dropzone .dz-preview.dz-error .dz-error-message {
display: block; }
.dropzone .dz-preview.dz-error:hover .dz-error-message {
opacity:;
pointer-events: auto; }
.dropzone .dz-preview .dz-error-message {
pointer-events: none;
z-index:;
position: absolute;
display: block;
display: none;
opacity:;
-webkit-transition: opacity 0.3s ease;
-moz-transition: opacity 0.3s ease;
-ms-transition: opacity 0.3s ease;
-o-transition: opacity 0.3s ease;
transition: opacity 0.3s ease;
border-radius: 8px;
font-size: 13px;
top: 130px;
left: -10px;
width: 140px;
background: #be2626;
background: linear-gradient(to bottom, #be2626, #a92222);
padding: 0.5em 1.2em;
color: white; }
.dropzone .dz-preview .dz-error-message:after {
content: '';
position: absolute;
top: -6px;
left: 64px;
width:;
height:;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #be2626; }
dropzone.css
/*
*
* More info at [www.dropzonejs.com](http://www.dropzonejs.com)
*
* Copyright (c) 2012, Matias Meno
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* *特此授予许可,免费的,任何的人获得一份
*这个软件和相关文档的文件(“软件”),交易
*在软件没有限制,包括但不限于权利
*使用、复制、修改、合并、出版、发行、有偿和/或出售
*软件的副本,并允许他们的软件
*提供,应当具备下列条件:
*
*上述版权声明和本许可声明应当包含在
*所有副本或实质性部分的软件。
*
*提供的软件是“是”,没有任何类型的保证,明示或
*暗示的保证,包括但不限于适销性的保证,
*健身为特定目的和无侵犯。在任何事件应当的
*作者或版权所有者承担任何索赔、损害或其他
*责任,无论是在一个动作的合同,侵权或否则,因,
*在连接或WI */ (function() {
var Dropzone, Emitter, ExifRestore, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without,
slice = [].slice,
extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty; noop = function() {}; Emitter = (function() {
function Emitter() {} Emitter.prototype.addEventListener = Emitter.prototype.on; Emitter.prototype.on = function(event, fn) {
this._callbacks = this._callbacks || {};
if (!this._callbacks[event]) {
this._callbacks[event] = [];
}
this._callbacks[event].push(fn);
return this;
}; Emitter.prototype.emit = function() {
var args, callback, callbacks, event, j, len;
event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
this._callbacks = this._callbacks || {};
callbacks = this._callbacks[event];
if (callbacks) {
for (j = 0, len = callbacks.length; j < len; j++) {
callback = callbacks[j];
callback.apply(this, args);
}
}
return this;
}; Emitter.prototype.removeListener = Emitter.prototype.off; Emitter.prototype.removeAllListeners = Emitter.prototype.off; Emitter.prototype.removeEventListener = Emitter.prototype.off; Emitter.prototype.off = function(event, fn) {
var callback, callbacks, i, j, len;
if (!this._callbacks || arguments.length === 0) {
this._callbacks = {};
return this;
}
callbacks = this._callbacks[event];
if (!callbacks) {
return this;
}
if (arguments.length === 1) {
delete this._callbacks[event];
return this;
}
for (i = j = 0, len = callbacks.length; j < len; i = ++j) {
callback = callbacks[i];
if (callback === fn) {
callbacks.splice(i, 1);
break;
}
}
return this;
}; return Emitter; })(); Dropzone = (function(superClass) {
var extend, resolveOption; extend1(Dropzone, superClass); Dropzone.prototype.Emitter = Emitter; /*
This is a list of all available events you can register on a dropzone object. You can register an event handler like this: dropzone.on("dragEnter", function() { });
*/ Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "addedfiles", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached", "queuecomplete"]; Dropzone.prototype.defaultOptions = {
url: null,
method: "post",
withCredentials: false,
timeout: 30000,
parallelUploads: 2,
uploadMultiple: false,
maxFilesize: 256,
paramName: "file",
createImageThumbnails: true,
maxThumbnailFilesize: 10,
thumbnailWidth: 120,
thumbnailHeight: 120,
thumbnailMethod: 'crop',
resizeWidth: null,
resizeHeight: null,
resizeMimeType: null,
resizeQuality: 0.8,
resizeMethod: 'contain',
filesizeBase: 1000,
maxFiles: null,
params: {},
headers: null,
clickable: true,
ignoreHiddenFiles: true,
acceptedFiles: null,
acceptedMimeTypes: null,
autoProcessQueue: true,
autoQueue: true,
addRemoveLinks: false,
previewsContainer: null,
hiddenInputContainer: "body",
capture: null,
renameFilename: null,
renameFile: null,
forceFallback: false,
dictDefaultMessage: "Drop files here to upload",
dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.",
dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.",
dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",
dictInvalidFileType: "You can't upload files of this type.",
dictResponseError: "Server responded with {{statusCode}} code.",
dictCancelUpload: "Cancel upload",
dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?",
dictRemoveFile: "Remove file",
dictRemoveFileConfirmation: null,
dictMaxFilesExceeded: "You can not upload any more files.",
dictFileSizeUnits: {
tb: "TB",
gb: "GB",
mb: "MB",
kb: "KB",
b: "b"
},
init: function() {
return noop;
},
accept: function(file, done) {
return done();
},
fallback: function() {
var child, j, len, messageElement, ref, span;
this.element.className = this.element.className + " dz-browser-not-supported";
ref = this.element.getElementsByTagName("div");
for (j = 0, len = ref.length; j < len; j++) {
child = ref[j];
if (/(^| )dz-message($| )/.test(child.className)) {
messageElement = child;
child.className = "dz-message";
continue;
}
}
if (!messageElement) {
messageElement = Dropzone.createElement("<div class=\"dz-message\"><span></span></div>");
this.element.appendChild(messageElement);
}
span = messageElement.getElementsByTagName("span")[0];
if (span) {
if (span.textContent != null) {
span.textContent = this.options.dictFallbackMessage;
} else if (span.innerText != null) {
span.innerText = this.options.dictFallbackMessage;
}
}
return this.element.appendChild(this.getFallbackForm());
},
resize: function(file, width, height, resizeMethod) {
var info, srcRatio, trgRatio;
info = {
srcX: 0,
srcY: 0,
srcWidth: file.width,
srcHeight: file.height
};
srcRatio = file.width / file.height;
if ((width == null) && (height == null)) {
width = info.srcWidth;
height = info.srcHeight;
} else if (width == null) {
width = height * srcRatio;
} else if (height == null) {
height = width / srcRatio;
}
width = Math.min(width, info.srcWidth);
height = Math.min(height, info.srcHeight);
trgRatio = width / height;
if (info.srcWidth > width || info.srcHeight > height) {
if (resizeMethod === 'crop') {
if (srcRatio > trgRatio) {
info.srcHeight = file.height;
info.srcWidth = info.srcHeight * trgRatio;
} else {
info.srcWidth = file.width;
info.srcHeight = info.srcWidth / trgRatio;
}
} else if (resizeMethod === 'contain') {
if (srcRatio > trgRatio) {
height = width / srcRatio;
} else {
width = height * srcRatio;
}
} else {
throw new Error("Unknown resizeMethod '" + resizeMethod + "'");
}
}
info.srcX = (file.width - info.srcWidth) / 2;
info.srcY = (file.height - info.srcHeight) / 2;
info.trgWidth = width;
info.trgHeight = height;
return info;
},
transformFile: function(file, done) {
if ((this.options.resizeWidth || this.options.resizeHeight) && file.type.match(/image.*/)) {
return this.resizeImage(file, this.options.resizeWidth, this.options.resizeHeight, this.options.resizeMethod, done);
} else {
return done(file);
}
},
previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-image\"><img data-dz-thumbnail /></div>\n <div class=\"dz-details\">\n <div class=\"dz-size\"><span data-dz-size></span></div>\n <div class=\"dz-filename\"><span data-dz-name></span></div>\n </div>\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n <div class=\"dz-success-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Check</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <path d=\"M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" stroke-opacity=\"0.198794158\" stroke=\"#747474\" fill-opacity=\"0.816519475\" fill=\"#FFFFFF\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </svg>\n </div>\n <div class=\"dz-error-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Error</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <g id=\"Check-+-Oval-2\" sketch:type=\"MSLayerGroup\" stroke=\"#747474\" stroke-opacity=\"0.198794158\" fill=\"#FFFFFF\" fill-opacity=\"0.816519475\">\n <path d=\"M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </g>\n </svg>\n </div>\n</div>", /*
Those functions register themselves to the events on init and handle all
the user interface specific stuff. Overwriting them won't break the upload
but can break the way it's displayed.
You can overwrite them if you don't like the default behavior. If you just
want to add an additional event handler, register it on the dropzone object
and don't overwrite those options.
*/
drop: function(e) {
return this.element.classList.remove("dz-drag-hover");
},
dragstart: noop,
dragend: function(e) {
return this.element.classList.remove("dz-drag-hover");
},
dragenter: function(e) {
return this.element.classList.add("dz-drag-hover");
},
dragover: function(e) {
return this.element.classList.add("dz-drag-hover");
},
dragleave: function(e) {
return this.element.classList.remove("dz-drag-hover");
},
paste: noop,
reset: function() {
return this.element.classList.remove("dz-started");
},
addedfile: function(file) {
var j, k, l, len, len1, len2, node, ref, ref1, ref2, removeFileEvent, removeLink, results;
if (this.element === this.previewsContainer) {
this.element.classList.add("dz-started");
}
if (this.previewsContainer) {
file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());
file.previewTemplate = file.previewElement;
this.previewsContainer.appendChild(file.previewElement);
ref = file.previewElement.querySelectorAll("[data-dz-name]");
for (j = 0, len = ref.length; j < len; j++) {
node = ref[j];
node.textContent = file.name;
}
ref1 = file.previewElement.querySelectorAll("[data-dz-size]");
for (k = 0, len1 = ref1.length; k < len1; k++) {
node = ref1[k];
node.innerHTML = this.filesize(file.size);
}
if (this.options.addRemoveLinks) {
file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>" + this.options.dictRemoveFile + "</a>");
file.previewElement.appendChild(file._removeLink);
}
removeFileEvent = (function(_this) {
return function(e) {
e.preventDefault();
e.stopPropagation();
if (file.status === Dropzone.UPLOADING) {
return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() {
return _this.removeFile(file);
});
} else {
if (_this.options.dictRemoveFileConfirmation) {
return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() {
return _this.removeFile(file);
});
} else {
return _this.removeFile(file);
}
}
};
})(this);
ref2 = file.previewElement.querySelectorAll("[data-dz-remove]");
results = [];
for (l = 0, len2 = ref2.length; l < len2; l++) {
removeLink = ref2[l];
results.push(removeLink.addEventListener("click", removeFileEvent));
}
return results;
}
},
removedfile: function(file) {
var ref;
if (file.previewElement) {
if ((ref = file.previewElement) != null) {
ref.parentNode.removeChild(file.previewElement);
}
}
return this._updateMaxFilesReachedClass();
},
thumbnail: function(file, dataUrl) {
var j, len, ref, thumbnailElement;
if (file.previewElement) {
file.previewElement.classList.remove("dz-file-preview");
ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]");
for (j = 0, len = ref.length; j < len; j++) {
thumbnailElement = ref[j];
thumbnailElement.alt = file.name;
thumbnailElement.src = dataUrl;
}
return setTimeout(((function(_this) {
return function() {
return file.previewElement.classList.add("dz-image-preview");
};
})(this)), 1);
}
},
error: function(file, message) {
var j, len, node, ref, results;
if (file.previewElement) {
file.previewElement.classList.add("dz-error");
if (typeof message !== "String" && message.error) {
message = message.error;
}
ref = file.previewElement.querySelectorAll("[data-dz-errormessage]");
results = [];
for (j = 0, len = ref.length; j < len; j++) {
node = ref[j];
results.push(node.textContent = message);
}
return results;
}
},
errormultiple: noop,
processing: function(file) {
if (file.previewElement) {
file.previewElement.classList.add("dz-processing");
if (file._removeLink) {
return file._removeLink.textContent = this.options.dictCancelUpload;
}
}
},
processingmultiple: noop,
uploadprogress: function(file, progress, bytesSent) {
var j, len, node, ref, results;
if (file.previewElement) {
ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]");
results = [];
for (j = 0, len = ref.length; j < len; j++) {
node = ref[j];
if (node.nodeName === 'PROGRESS') {
results.push(node.value = progress);
} else {
results.push(node.style.width = progress + "%");
}
}
return results;
}
},
totaluploadprogress: noop,
sending: noop,
sendingmultiple: noop,
success: function(file) {
if (file.previewElement) {
return file.previewElement.classList.add("dz-success");
}
},
successmultiple: noop,
canceled: function(file) {
return this.emit("error", file, "Upload canceled.");
},
canceledmultiple: noop,
complete: function(file) {
if (file._removeLink) {
file._removeLink.textContent = this.options.dictRemoveFile;
}
if (file.previewElement) {
return file.previewElement.classList.add("dz-complete");
}
},
completemultiple: noop,
maxfilesexceeded: noop,
maxfilesreached: noop,
queuecomplete: noop,
addedfiles: noop
}; extend = function() {
var j, key, len, object, objects, target, val;
target = arguments[0], objects = 2 <= arguments.length ? slice.call(arguments, 1) : [];
for (j = 0, len = objects.length; j < len; j++) {
object = objects[j];
for (key in object) {
val = object[key];
target[key] = val;
}
}
return target;
}; function Dropzone(element1, options) {
var elementOptions, fallback, ref;
this.element = element1;
this.version = Dropzone.version;
this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, "");
this.clickableElements = [];
this.listeners = [];
this.files = [];
if (typeof this.element === "string") {
this.element = document.querySelector(this.element);
}
if (!(this.element && (this.element.nodeType != null))) {
throw new Error("Invalid dropzone element.");
}
if (this.element.dropzone) {
throw new Error("Dropzone already attached.");
}
Dropzone.instances.push(this);
this.element.dropzone = this;
elementOptions = (ref = Dropzone.optionsForElement(this.element)) != null ? ref : {};
this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {});
if (this.options.forceFallback || !Dropzone.isBrowserSupported()) {
return this.options.fallback.call(this);
}
if (this.options.url == null) {
this.options.url = this.element.getAttribute("action");
}
if (!this.options.url) {
throw new Error("No URL provided.");
}
if (this.options.acceptedFiles && this.options.acceptedMimeTypes) {
throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.");
}
if (this.options.acceptedMimeTypes) {
this.options.acceptedFiles = this.options.acceptedMimeTypes;
delete this.options.acceptedMimeTypes;
}
if (this.options.renameFilename != null) {
this.options.renameFile = (function(_this) {
return function(file) {
return _this.options.renameFilename.call(_this, file.name, file);
};
})(this);
}
this.options.method = this.options.method.toUpperCase();
if ((fallback = this.getExistingFallback()) && fallback.parentNode) {
fallback.parentNode.removeChild(fallback);
}
if (this.options.previewsContainer !== false) {
if (this.options.previewsContainer) {
this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer");
} else {
this.previewsContainer = this.element;
}
}
if (this.options.clickable) {
if (this.options.clickable === true) {
this.clickableElements = [this.element];
} else {
this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable");
}
}
this.init();
} Dropzone.prototype.getAcceptedFiles = function() {
var file, j, len, ref, results;
ref = this.files;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
file = ref[j];
if (file.accepted) {
results.push(file);
}
}
return results;
}; Dropzone.prototype.getRejectedFiles = function() {
var file, j, len, ref, results;
ref = this.files;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
file = ref[j];
if (!file.accepted) {
results.push(file);
}
}
return results;
}; Dropzone.prototype.getFilesWithStatus = function(status) {
var file, j, len, ref, results;
ref = this.files;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
file = ref[j];
if (file.status === status) {
results.push(file);
}
}
return results;
}; Dropzone.prototype.getQueuedFiles = function() {
return this.getFilesWithStatus(Dropzone.QUEUED);
}; Dropzone.prototype.getUploadingFiles = function() {
return this.getFilesWithStatus(Dropzone.UPLOADING);
}; Dropzone.prototype.getAddedFiles = function() {
return this.getFilesWithStatus(Dropzone.ADDED);
}; Dropzone.prototype.getActiveFiles = function() {
var file, j, len, ref, results;
ref = this.files;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
file = ref[j];
if (file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED) {
results.push(file);
}
}
return results;
}; Dropzone.prototype.init = function() {
var eventName, j, len, noPropagation, ref, ref1, setupHiddenFileInput;
if (this.element.tagName === "form") {
this.element.setAttribute("enctype", "multipart/form-data");
}
if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) {
this.element.appendChild(Dropzone.createElement("<div class=\"dz-default dz-message\"><span>" + this.options.dictDefaultMessage + "</span></div>"));
}
if (this.clickableElements.length) {
setupHiddenFileInput = (function(_this) {
return function() {
if (_this.hiddenFileInput) {
_this.hiddenFileInput.parentNode.removeChild(_this.hiddenFileInput);
}
_this.hiddenFileInput = document.createElement("input");
_this.hiddenFileInput.setAttribute("type", "file");
if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) {
_this.hiddenFileInput.setAttribute("multiple", "multiple");
}
_this.hiddenFileInput.className = "dz-hidden-input";
if (_this.options.acceptedFiles != null) {
_this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles);
}
if (_this.options.capture != null) {
_this.hiddenFileInput.setAttribute("capture", _this.options.capture);
}
_this.hiddenFileInput.style.visibility = "hidden";
_this.hiddenFileInput.style.position = "absolute";
_this.hiddenFileInput.style.top = "0";
_this.hiddenFileInput.style.left = "0";
_this.hiddenFileInput.style.height = "0";
_this.hiddenFileInput.style.width = "0";
document.querySelector(_this.options.hiddenInputContainer).appendChild(_this.hiddenFileInput);
return _this.hiddenFileInput.addEventListener("change", function() {
var file, files, j, len;
files = _this.hiddenFileInput.files;
if (files.length) {
for (j = 0, len = files.length; j < len; j++) {
file = files[j];
_this.addFile(file);
}
}
_this.emit("addedfiles", files);
return setupHiddenFileInput();
});
};
})(this);
setupHiddenFileInput();
}
this.URL = (ref = window.URL) != null ? ref : window.webkitURL;
ref1 = this.events;
for (j = 0, len = ref1.length; j < len; j++) {
eventName = ref1[j];
this.on(eventName, this.options[eventName]);
}
this.on("uploadprogress", (function(_this) {
return function() {
return _this.updateTotalUploadProgress();
};
})(this));
this.on("removedfile", (function(_this) {
return function() {
return _this.updateTotalUploadProgress();
};
})(this));
this.on("canceled", (function(_this) {
return function(file) {
return _this.emit("complete", file);
};
})(this));
this.on("complete", (function(_this) {
return function(file) {
if (_this.getAddedFiles().length === 0 && _this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) {
return setTimeout((function() {
return _this.emit("queuecomplete");
}), 0);
}
};
})(this));
noPropagation = function(e) {
e.stopPropagation();
if (e.preventDefault) {
return e.preventDefault();
} else {
return e.returnValue = false;
}
};
this.listeners = [
{
element: this.element,
events: {
"dragstart": (function(_this) {
return function(e) {
return _this.emit("dragstart", e);
};
})(this),
"dragenter": (function(_this) {
return function(e) {
noPropagation(e);
return _this.emit("dragenter", e);
};
})(this),
"dragover": (function(_this) {
return function(e) {
var efct;
try {
efct = e.dataTransfer.effectAllowed;
} catch (undefined) {}
e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';
noPropagation(e);
return _this.emit("dragover", e);
};
})(this),
"dragleave": (function(_this) {
return function(e) {
return _this.emit("dragleave", e);
};
})(this),
"drop": (function(_this) {
return function(e) {
noPropagation(e);
return _this.drop(e);
};
})(this),
"dragend": (function(_this) {
return function(e) {
return _this.emit("dragend", e);
};
})(this)
}
}
];
this.clickableElements.forEach((function(_this) {
return function(clickableElement) {
return _this.listeners.push({
element: clickableElement,
events: {
"click": function(evt) {
if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) {
_this.hiddenFileInput.click();
}
return true;
}
}
});
};
})(this));
this.enable();
return this.options.init.call(this);
}; Dropzone.prototype.destroy = function() {
var ref;
this.disable();
this.removeAllFiles(true);
if ((ref = this.hiddenFileInput) != null ? ref.parentNode : void 0) {
this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);
this.hiddenFileInput = null;
}
delete this.element.dropzone;
return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);
}; Dropzone.prototype.updateTotalUploadProgress = function() {
var activeFiles, file, j, len, ref, totalBytes, totalBytesSent, totalUploadProgress;
totalBytesSent = 0;
totalBytes = 0;
activeFiles = this.getActiveFiles();
if (activeFiles.length) {
ref = this.getActiveFiles();
for (j = 0, len = ref.length; j < len; j++) {
file = ref[j];
totalBytesSent += file.upload.bytesSent;
totalBytes += file.upload.total;
}
totalUploadProgress = 100 * totalBytesSent / totalBytes;
} else {
totalUploadProgress = 100;
}
return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent);
}; Dropzone.prototype._getParamName = function(n) {
if (typeof this.options.paramName === "function") {
return this.options.paramName(n);
} else {
return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : "");
}
}; Dropzone.prototype._renameFile = function(file) {
if (typeof this.options.renameFile !== "function") {
return file.name;
}
return this.options.renameFile(file);
}; Dropzone.prototype.getFallbackForm = function() {
var existingFallback, fields, fieldsString, form;
if (existingFallback = this.getExistingFallback()) {
return existingFallback;
}
fieldsString = "<div class=\"dz-fallback\">";
if (this.options.dictFallbackText) {
fieldsString += "<p>" + this.options.dictFallbackText + "</p>";
}
fieldsString += "<input type=\"file\" name=\"" + (this._getParamName(0)) + "\" " + (this.options.uploadMultiple ? 'multiple="multiple"' : void 0) + " /><input type=\"submit\" value=\"Upload!\"></div>";
fields = Dropzone.createElement(fieldsString);
if (this.element.tagName !== "FORM") {
form = Dropzone.createElement("<form action=\"" + this.options.url + "\" enctype=\"multipart/form-data\" method=\"" + this.options.method + "\"></form>");
form.appendChild(fields);
} else {
this.element.setAttribute("enctype", "multipart/form-data");
this.element.setAttribute("method", this.options.method);
}
return form != null ? form : fields;
}; Dropzone.prototype.getExistingFallback = function() {
var fallback, getFallback, j, len, ref, tagName;
getFallback = function(elements) {
var el, j, len;
for (j = 0, len = elements.length; j < len; j++) {
el = elements[j];
if (/(^| )fallback($| )/.test(el.className)) {
return el;
}
}
};
ref = ["div", "form"];
for (j = 0, len = ref.length; j < len; j++) {
tagName = ref[j];
if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {
return fallback;
}
}
}; Dropzone.prototype.setupEventListeners = function() {
var elementListeners, event, j, len, listener, ref, results;
ref = this.listeners;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
elementListeners = ref[j];
results.push((function() {
var ref1, results1;
ref1 = elementListeners.events;
results1 = [];
for (event in ref1) {
listener = ref1[event];
results1.push(elementListeners.element.addEventListener(event, listener, false));
}
return results1;
})());
}
return results;
}; Dropzone.prototype.removeEventListeners = function() {
var elementListeners, event, j, len, listener, ref, results;
ref = this.listeners;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
elementListeners = ref[j];
results.push((function() {
var ref1, results1;
ref1 = elementListeners.events;
results1 = [];
for (event in ref1) {
listener = ref1[event];
results1.push(elementListeners.element.removeEventListener(event, listener, false));
}
return results1;
})());
}
return results;
}; Dropzone.prototype.disable = function() {
var file, j, len, ref, results;
this.clickableElements.forEach(function(element) {
return element.classList.remove("dz-clickable");
});
this.removeEventListeners();
ref = this.files;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
file = ref[j];
results.push(this.cancelUpload(file));
}
return results;
}; Dropzone.prototype.enable = function() {
this.clickableElements.forEach(function(element) {
return element.classList.add("dz-clickable");
});
return this.setupEventListeners();
}; Dropzone.prototype.filesize = function(size) {
var cutoff, i, j, len, selectedSize, selectedUnit, unit, units;
selectedSize = 0;
selectedUnit = "b";
if (size > 0) {
units = ['tb', 'gb', 'mb', 'kb', 'b'];
for (i = j = 0, len = units.length; j < len; i = ++j) {
unit = units[i];
cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10;
if (size >= cutoff) {
selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i);
selectedUnit = unit;
break;
}
}
selectedSize = Math.round(10 * selectedSize) / 10;
}
return "<strong>" + selectedSize + "</strong> " + this.options.dictFileSizeUnits[selectedUnit];
}; Dropzone.prototype._updateMaxFilesReachedClass = function() {
if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
if (this.getAcceptedFiles().length === this.options.maxFiles) {
this.emit('maxfilesreached', this.files);
}
return this.element.classList.add("dz-max-files-reached");
} else {
return this.element.classList.remove("dz-max-files-reached");
}
}; Dropzone.prototype.drop = function(e) {
var files, items;
if (!e.dataTransfer) {
return;
}
this.emit("drop", e);
files = e.dataTransfer.files;
this.emit("addedfiles", files);
if (files.length) {
items = e.dataTransfer.items;
if (items && items.length && (items[0].webkitGetAsEntry != null)) {
this._addFilesFromItems(items);
} else {
this.handleFiles(files);
}
}
}; Dropzone.prototype.paste = function(e) {
var items, ref;
if ((e != null ? (ref = e.clipboardData) != null ? ref.items : void 0 : void 0) == null) {
return;
}
this.emit("paste", e);
items = e.clipboardData.items;
if (items.length) {
return this._addFilesFromItems(items);
}
}; Dropzone.prototype.handleFiles = function(files) {
var file, j, len, results;
results = [];
for (j = 0, len = files.length; j < len; j++) {
file = files[j];
results.push(this.addFile(file));
}
return results;
}; Dropzone.prototype._addFilesFromItems = function(items) {
var entry, item, j, len, results;
results = [];
for (j = 0, len = items.length; j < len; j++) {
item = items[j];
if ((item.webkitGetAsEntry != null) && (entry = item.webkitGetAsEntry())) {
if (entry.isFile) {
results.push(this.addFile(item.getAsFile()));
} else if (entry.isDirectory) {
results.push(this._addFilesFromDirectory(entry, entry.name));
} else {
results.push(void 0);
}
} else if (item.getAsFile != null) {
if ((item.kind == null) || item.kind === "file") {
results.push(this.addFile(item.getAsFile()));
} else {
results.push(void 0);
}
} else {
results.push(void 0);
}
}
return results;
}; Dropzone.prototype._addFilesFromDirectory = function(directory, path) {
var dirReader, errorHandler, readEntries;
dirReader = directory.createReader();
errorHandler = function(error) {
return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0;
};
readEntries = (function(_this) {
return function() {
return dirReader.readEntries(function(entries) {
var entry, j, len;
if (entries.length > 0) {
for (j = 0, len = entries.length; j < len; j++) {
entry = entries[j];
if (entry.isFile) {
entry.file(function(file) {
if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') {
return;
}
file.fullPath = path + "/" + file.name;
return _this.addFile(file);
});
} else if (entry.isDirectory) {
_this._addFilesFromDirectory(entry, path + "/" + entry.name);
}
}
readEntries();
}
return null;
}, errorHandler);
};
})(this);
return readEntries();
}; Dropzone.prototype.accept = function(file, done) {
if (file.size > this.options.maxFilesize * 1024 * 1024) {
return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize));
} else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {
return done(this.options.dictInvalidFileType);
} else if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
return this.emit("maxfilesexceeded", file);
} else {
return this.options.accept.call(this, file, done);
}
}; Dropzone.prototype.addFile = function(file) {
file.upload = {
progress: 0,
total: file.size,
bytesSent: 0,
filename: this._renameFile(file)
};
this.files.push(file);
file.status = Dropzone.ADDED;
this.emit("addedfile", file);
this._enqueueThumbnail(file);
return this.accept(file, (function(_this) {
return function(error) {
if (error) {
file.accepted = false;
_this._errorProcessing([file], error);
} else {
file.accepted = true;
if (_this.options.autoQueue) {
_this.enqueueFile(file);
}
}
return _this._updateMaxFilesReachedClass();
};
})(this));
}; Dropzone.prototype.enqueueFiles = function(files) {
var file, j, len;
for (j = 0, len = files.length; j < len; j++) {
file = files[j];
this.enqueueFile(file);
}
return null;
}; Dropzone.prototype.enqueueFile = function(file) {
if (file.status === Dropzone.ADDED && file.accepted === true) {
file.status = Dropzone.QUEUED;
if (this.options.autoProcessQueue) {
return setTimeout(((function(_this) {
return function() {
return _this.processQueue();
};
})(this)), 0);
}
} else {
throw new Error("This file can't be queued because it has already been processed or was rejected.");
}
}; Dropzone.prototype._thumbnailQueue = []; Dropzone.prototype._processingThumbnail = false; Dropzone.prototype._enqueueThumbnail = function(file) {
if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {
this._thumbnailQueue.push(file);
return setTimeout(((function(_this) {
return function() {
return _this._processThumbnailQueue();
};
})(this)), 0);
}
}; Dropzone.prototype._processThumbnailQueue = function() {
var file;
if (this._processingThumbnail || this._thumbnailQueue.length === 0) {
return;
}
this._processingThumbnail = true;
file = this._thumbnailQueue.shift();
return this.createThumbnail(file, this.options.thumbnailWidth, this.options.thumbnailHeight, this.options.thumbnailMethod, true, (function(_this) {
return function(dataUrl) {
_this.emit("thumbnail", file, dataUrl);
_this._processingThumbnail = false;
return _this._processThumbnailQueue();
};
})(this));
}; Dropzone.prototype.removeFile = function(file) {
if (file.status === Dropzone.UPLOADING) {
this.cancelUpload(file);
}
this.files = without(this.files, file);
this.emit("removedfile", file);
if (this.files.length === 0) {
return this.emit("reset");
}
}; Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) {
var file, j, len, ref;
if (cancelIfNecessary == null) {
cancelIfNecessary = false;
}
ref = this.files.slice();
for (j = 0, len = ref.length; j < len; j++) {
file = ref[j];
if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {
this.removeFile(file);
}
}
return null;
}; Dropzone.prototype.resizeImage = function(file, width, height, resizeMethod, callback) {
return this.createThumbnail(file, width, height, resizeMethod, false, (function(_this) {
return function(dataUrl, canvas) {
var resizeMimeType, resizedDataURL;
if (canvas === null) {
return callback(file);
} else {
resizeMimeType = _this.options.resizeMimeType;
if (resizeMimeType == null) {
resizeMimeType = file.type;
}
resizedDataURL = canvas.toDataURL(resizeMimeType, _this.options.resizeQuality);
if (resizeMimeType === 'image/jpeg' || resizeMimeType === 'image/jpg') {
resizedDataURL = ExifRestore.restore(file.dataURL, resizedDataURL);
}
return callback(Dropzone.dataURItoBlob(resizedDataURL));
}
};
})(this));
}; Dropzone.prototype.createThumbnail = function(file, width, height, resizeMethod, fixOrientation, callback) {
var fileReader;
fileReader = new FileReader;
fileReader.onload = (function(_this) {
return function() {
file.dataURL = fileReader.result;
if (file.type === "image/svg+xml") {
if (callback != null) {
callback(fileReader.result);
}
return;
}
return _this.createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback);
};
})(this);
return fileReader.readAsDataURL(file);
}; Dropzone.prototype.createThumbnailFromUrl = function(file, width, height, resizeMethod, fixOrientation, callback, crossOrigin) {
var img;
img = document.createElement("img");
if (crossOrigin) {
img.crossOrigin = crossOrigin;
}
img.onload = (function(_this) {
return function() {
var loadExif;
loadExif = function(callback) {
return callback(1);
};
if ((typeof EXIF !== "undefined" && EXIF !== null) && fixOrientation) {
loadExif = function(callback) {
return EXIF.getData(img, function() {
return callback(EXIF.getTag(this, 'Orientation'));
});
};
}
return loadExif(function(orientation) {
var canvas, ctx, ref, ref1, ref2, ref3, resizeInfo, thumbnail;
file.width = img.width;
file.height = img.height;
resizeInfo = _this.options.resize.call(_this, file, width, height, resizeMethod);
canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
canvas.width = resizeInfo.trgWidth;
canvas.height = resizeInfo.trgHeight;
if (orientation > 4) {
canvas.width = resizeInfo.trgHeight;
canvas.height = resizeInfo.trgWidth;
}
switch (orientation) {
case 2:
ctx.translate(canvas.width, 0);
ctx.scale(-1, 1);
break;
case 3:
ctx.translate(canvas.width, canvas.height);
ctx.rotate(Math.PI);
break;
case 4:
ctx.translate(0, canvas.height);
ctx.scale(1, -1);
break;
case 5:
ctx.rotate(0.5 * Math.PI);
ctx.scale(1, -1);
break;
case 6:
ctx.rotate(0.5 * Math.PI);
ctx.translate(0, -canvas.height);
break;
case 7:
ctx.rotate(0.5 * Math.PI);
ctx.translate(canvas.width, -canvas.height);
ctx.scale(-1, 1);
break;
case 8:
ctx.rotate(-0.5 * Math.PI);
ctx.translate(-canvas.width, 0);
}
drawImageIOSFix(ctx, img, (ref = resizeInfo.srcX) != null ? ref : 0, (ref1 = resizeInfo.srcY) != null ? ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (ref2 = resizeInfo.trgX) != null ? ref2 : 0, (ref3 = resizeInfo.trgY) != null ? ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight);
thumbnail = canvas.toDataURL("image/png");
if (callback != null) {
return callback(thumbnail, canvas);
}
});
};
})(this);
if (callback != null) {
img.onerror = callback;
}
return img.src = file.dataURL;
}; Dropzone.prototype.processQueue = function() {
var i, parallelUploads, processingLength, queuedFiles;
parallelUploads = this.options.parallelUploads;
processingLength = this.getUploadingFiles().length;
i = processingLength;
if (processingLength >= parallelUploads) {
return;
}
queuedFiles = this.getQueuedFiles();
if (!(queuedFiles.length > 0)) {
return;
}
if (this.options.uploadMultiple) {
return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));
} else {
while (i < parallelUploads) {
if (!queuedFiles.length) {
return;
}
this.processFile(queuedFiles.shift());
i++;
}
}
}; Dropzone.prototype.processFile = function(file) {
return this.processFiles([file]);
}; Dropzone.prototype.processFiles = function(files) {
var file, j, len;
for (j = 0, len = files.length; j < len; j++) {
file = files[j];
file.processing = true;
file.status = Dropzone.UPLOADING;
this.emit("processing", file);
}
if (this.options.uploadMultiple) {
this.emit("processingmultiple", files);
}
return this.uploadFiles(files);
}; Dropzone.prototype._getFilesWithXhr = function(xhr) {
var file, files;
return files = (function() {
var j, len, ref, results;
ref = this.files;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
file = ref[j];
if (file.xhr === xhr) {
results.push(file);
}
}
return results;
}).call(this);
}; Dropzone.prototype.cancelUpload = function(file) {
var groupedFile, groupedFiles, j, k, len, len1, ref;
if (file.status === Dropzone.UPLOADING) {
groupedFiles = this._getFilesWithXhr(file.xhr);
for (j = 0, len = groupedFiles.length; j < len; j++) {
groupedFile = groupedFiles[j];
groupedFile.status = Dropzone.CANCELED;
}
file.xhr.abort();
for (k = 0, len1 = groupedFiles.length; k < len1; k++) {
groupedFile = groupedFiles[k];
this.emit("canceled", groupedFile);
}
if (this.options.uploadMultiple) {
this.emit("canceledmultiple", groupedFiles);
}
} else if ((ref = file.status) === Dropzone.ADDED || ref === Dropzone.QUEUED) {
file.status = Dropzone.CANCELED;
this.emit("canceled", file);
if (this.options.uploadMultiple) {
this.emit("canceledmultiple", [file]);
}
}
if (this.options.autoProcessQueue) {
return this.processQueue();
}
}; resolveOption = function() {
var args, option;
option = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
if (typeof option === 'function') {
return option.apply(this, args);
}
return option;
}; Dropzone.prototype.uploadFile = function(file) {
return this.uploadFiles([file]);
}; Dropzone.prototype.uploadFiles = function(files) {
var doneCounter, doneFunction, file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, j, k, key, l, len, len1, len2, len3, m, method, o, option, progressObj, ref, ref1, ref2, ref3, ref4, ref5, response, results, updateProgress, url, value, xhr;
xhr = new XMLHttpRequest();
for (j = 0, len = files.length; j < len; j++) {
file = files[j];
file.xhr = xhr;
}
method = resolveOption(this.options.method, files);
url = resolveOption(this.options.url, files);
xhr.open(method, url, true);
xhr.timeout = resolveOption(this.options.timeout, files);
xhr.withCredentials = !!this.options.withCredentials;
response = null;
handleError = (function(_this) {
return function() {
var k, len1, results;
results = [];
for (k = 0, len1 = files.length; k < len1; k++) {
file = files[k];
results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr));
}
return results;
};
})(this);
updateProgress = (function(_this) {
return function(e) {
var allFilesFinished, k, l, len1, len2, len3, m, progress, results;
if (e != null) {
progress = 100 * e.loaded / e.total;
for (k = 0, len1 = files.length; k < len1; k++) {
file = files[k];
file.upload.progress = progress;
file.upload.total = e.total;
file.upload.bytesSent = e.loaded;
}
} else {
allFilesFinished = true;
progress = 100;
for (l = 0, len2 = files.length; l < len2; l++) {
file = files[l];
if (!(file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) {
allFilesFinished = false;
}
file.upload.progress = progress;
file.upload.bytesSent = file.upload.total;
}
if (allFilesFinished) {
return;
}
}
results = [];
for (m = 0, len3 = files.length; m < len3; m++) {
file = files[m];
results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent));
}
return results;
};
})(this);
xhr.onload = (function(_this) {
return function(e) {
var error1, ref;
if (files[0].status === Dropzone.CANCELED) {
return;
}
if (xhr.readyState !== 4) {
return;
}
if (xhr.responseType !== 'arraybuffer' && xhr.responseType !== 'blob') {
response = xhr.responseText;
if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) {
try {
response = JSON.parse(response);
} catch (error1) {
e = error1;
response = "Invalid JSON response from server.";
}
}
}
updateProgress();
if (!((200 <= (ref = xhr.status) && ref < 300))) {
return handleError();
} else {
return _this._finished(files, response, e);
}
};
})(this);
xhr.onerror = (function(_this) {
return function() {
if (files[0].status === Dropzone.CANCELED) {
return;
}
return handleError();
};
})(this);
progressObj = (ref = xhr.upload) != null ? ref : xhr;
progressObj.onprogress = updateProgress;
headers = {
"Accept": "application/json",
"Cache-Control": "no-cache",
"X-Requested-With": "XMLHttpRequest"
};
if (this.options.headers) {
extend(headers, this.options.headers);
}
for (headerName in headers) {
headerValue = headers[headerName];
if (headerValue) {
xhr.setRequestHeader(headerName, headerValue);
}
}
formData = new FormData();
if (this.options.params) {
ref1 = this.options.params;
for (key in ref1) {
value = ref1[key];
formData.append(key, value);
}
}
for (k = 0, len1 = files.length; k < len1; k++) {
file = files[k];
this.emit("sending", file, xhr, formData);
}
if (this.options.uploadMultiple) {
this.emit("sendingmultiple", files, xhr, formData);
}
if (this.element.tagName === "FORM") {
ref2 = this.element.querySelectorAll("input, textarea, select, button");
for (l = 0, len2 = ref2.length; l < len2; l++) {
input = ref2[l];
inputName = input.getAttribute("name");
inputType = input.getAttribute("type");
if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
ref3 = input.options;
for (m = 0, len3 = ref3.length; m < len3; m++) {
option = ref3[m];
if (option.selected) {
formData.append(inputName, option.value);
}
}
} else if (!inputType || ((ref4 = inputType.toLowerCase()) !== "checkbox" && ref4 !== "radio") || input.checked) {
formData.append(inputName, input.value);
}
}
}
doneCounter = 0;
results = [];
for (i = o = 0, ref5 = files.length - 1; 0 <= ref5 ? o <= ref5 : o >= ref5; i = 0 <= ref5 ? ++o : --o) {
doneFunction = (function(_this) {
return function(file, paramName, fileName) {
return function(transformedFile) {
formData.append(paramName, transformedFile, fileName);
if (++doneCounter === files.length) {
return _this.submitRequest(xhr, formData, files);
}
};
};
})(this);
results.push(this.options.transformFile.call(this, files[i], doneFunction(files[i], this._getParamName(i), files[i].upload.filename)));
}
return results;
}; Dropzone.prototype.submitRequest = function(xhr, formData, files) {
return xhr.send(formData);
}; Dropzone.prototype._finished = function(files, responseText, e) {
var file, j, len;
for (j = 0, len = files.length; j < len; j++) {
file = files[j];
file.status = Dropzone.SUCCESS;
this.emit("success", file, responseText, e);
this.emit("complete", file);
}
if (this.options.uploadMultiple) {
this.emit("successmultiple", files, responseText, e);
this.emit("completemultiple", files);
}
if (this.options.autoProcessQueue) {
return this.processQueue();
}
}; Dropzone.prototype._errorProcessing = function(files, message, xhr) {
var file, j, len;
for (j = 0, len = files.length; j < len; j++) {
file = files[j];
file.status = Dropzone.ERROR;
this.emit("error", file, message, xhr);
this.emit("complete", file);
}
if (this.options.uploadMultiple) {
this.emit("errormultiple", files, message, xhr);
this.emit("completemultiple", files);
}
if (this.options.autoProcessQueue) {
return this.processQueue();
}
}; return Dropzone; })(Emitter); Dropzone.version = "5.1.1"; Dropzone.options = {}; Dropzone.optionsForElement = function(element) {
if (element.getAttribute("id")) {
return Dropzone.options[camelize(element.getAttribute("id"))];
} else {
return void 0;
}
}; Dropzone.instances = []; Dropzone.forElement = function(element) {
if (typeof element === "string") {
element = document.querySelector(element);
}
if ((element != null ? element.dropzone : void 0) == null) {
throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.");
}
return element.dropzone;
}; Dropzone.autoDiscover = true; Dropzone.discover = function() {
var checkElements, dropzone, dropzones, j, len, results;
if (document.querySelectorAll) {
dropzones = document.querySelectorAll(".dropzone");
} else {
dropzones = [];
checkElements = function(elements) {
var el, j, len, results;
results = [];
for (j = 0, len = elements.length; j < len; j++) {
el = elements[j];
if (/(^| )dropzone($| )/.test(el.className)) {
results.push(dropzones.push(el));
} else {
results.push(void 0);
}
}
return results;
};
checkElements(document.getElementsByTagName("div"));
checkElements(document.getElementsByTagName("form"));
}
results = [];
for (j = 0, len = dropzones.length; j < len; j++) {
dropzone = dropzones[j];
if (Dropzone.optionsForElement(dropzone) !== false) {
results.push(new Dropzone(dropzone));
} else {
results.push(void 0);
}
}
return results;
}; Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i]; Dropzone.isBrowserSupported = function() {
var capableBrowser, j, len, ref, regex;
capableBrowser = true;
if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {
if (!("classList" in document.createElement("a"))) {
capableBrowser = false;
} else {
ref = Dropzone.blacklistedBrowsers;
for (j = 0, len = ref.length; j < len; j++) {
regex = ref[j];
if (regex.test(navigator.userAgent)) {
capableBrowser = false;
continue;
}
}
}
} else {
capableBrowser = false;
}
return capableBrowser;
}; Dropzone.dataURItoBlob = function(dataURI) {
var ab, byteString, i, ia, j, mimeString, ref;
byteString = atob(dataURI.split(',')[1]);
mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
ab = new ArrayBuffer(byteString.length);
ia = new Uint8Array(ab);
for (i = j = 0, ref = byteString.length; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], {
type: mimeString
});
}; without = function(list, rejectedItem) {
var item, j, len, results;
results = [];
for (j = 0, len = list.length; j < len; j++) {
item = list[j];
if (item !== rejectedItem) {
results.push(item);
}
}
return results;
}; camelize = function(str) {
return str.replace(/[\-_](\w)/g, function(match) {
return match.charAt(1).toUpperCase();
});
}; Dropzone.createElement = function(string) {
var div;
div = document.createElement("div");
div.innerHTML = string;
return div.childNodes[0];
}; Dropzone.elementInside = function(element, container) {
if (element === container) {
return true;
}
while (element = element.parentNode) {
if (element === container) {
return true;
}
}
return false;
}; Dropzone.getElement = function(el, name) {
var element;
if (typeof el === "string") {
element = document.querySelector(el);
} else if (el.nodeType != null) {
element = el;
}
if (element == null) {
throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element.");
}
return element;
}; Dropzone.getElements = function(els, name) {
var e, el, elements, error1, j, k, len, len1, ref;
if (els instanceof Array) {
elements = [];
try {
for (j = 0, len = els.length; j < len; j++) {
el = els[j];
elements.push(this.getElement(el, name));
}
} catch (error1) {
e = error1;
elements = null;
}
} else if (typeof els === "string") {
elements = [];
ref = document.querySelectorAll(els);
for (k = 0, len1 = ref.length; k < len1; k++) {
el = ref[k];
elements.push(el);
}
} else if (els.nodeType != null) {
elements = [els];
}
if (!((elements != null) && elements.length)) {
throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those.");
}
return elements;
}; Dropzone.confirm = function(question, accepted, rejected) {
if (window.confirm(question)) {
return accepted();
} else if (rejected != null) {
return rejected();
}
}; Dropzone.isValidFile = function(file, acceptedFiles) {
var baseMimeType, j, len, mimeType, validType;
if (!acceptedFiles) {
return true;
}
acceptedFiles = acceptedFiles.split(",");
mimeType = file.type;
baseMimeType = mimeType.replace(/\/.*$/, "");
for (j = 0, len = acceptedFiles.length; j < len; j++) {
validType = acceptedFiles[j];
validType = validType.trim();
if (validType.charAt(0) === ".") {
if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {
return true;
}
} else if (/\/\*$/.test(validType)) {
if (baseMimeType === validType.replace(/\/.*$/, "")) {
return true;
}
} else {
if (mimeType === validType) {
return true;
}
}
}
return false;
}; if (typeof jQuery !== "undefined" && jQuery !== null) {
jQuery.fn.dropzone = function(options) {
return this.each(function() {
return new Dropzone(this, options);
});
};
} if (typeof module !== "undefined" && module !== null) {
module.exports = Dropzone;
} else {
window.Dropzone = Dropzone;
} Dropzone.ADDED = "added"; Dropzone.QUEUED = "queued"; Dropzone.ACCEPTED = Dropzone.QUEUED; Dropzone.UPLOADING = "uploading"; Dropzone.PROCESSING = Dropzone.UPLOADING; Dropzone.CANCELED = "canceled"; Dropzone.ERROR = "error"; Dropzone.SUCCESS = "success"; /* Bugfix for iOS 6 and 7
Source: http://*.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios
based on the work of https://github.com/stomita/ios-imagefile-megapixel
*/ detectVerticalSquash = function(img) {
var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy;
iw = img.naturalWidth;
ih = img.naturalHeight;
canvas = document.createElement("canvas");
canvas.width = 1;
canvas.height = ih;
ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
data = ctx.getImageData(1, 0, 1, ih).data;
sy = 0;
ey = ih;
py = ih;
while (py > sy) {
alpha = data[(py - 1) * 4 + 3];
if (alpha === 0) {
ey = py;
} else {
sy = py;
}
py = (ey + sy) >> 1;
}
ratio = py / ih;
if (ratio === 0) {
return 1;
} else {
return ratio;
}
}; drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
var vertSquashRatio;
vertSquashRatio = detectVerticalSquash(img);
return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
}; ExifRestore = (function() {
function ExifRestore() {} ExifRestore.KEY_STR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; ExifRestore.encode64 = function(input) {
var chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, output;
output = '';
chr1 = void 0;
chr2 = void 0;
chr3 = '';
enc1 = void 0;
enc2 = void 0;
enc3 = void 0;
enc4 = '';
i = 0;
while (true) {
chr1 = input[i++];
chr2 = input[i++];
chr3 = input[i++];
enc1 = chr1 >> 2;
enc2 = (chr1 & 3) << 4 | chr2 >> 4;
enc3 = (chr2 & 15) << 2 | chr3 >> 6;
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + this.KEY_STR.charAt(enc1) + this.KEY_STR.charAt(enc2) + this.KEY_STR.charAt(enc3) + this.KEY_STR.charAt(enc4);
chr1 = chr2 = chr3 = '';
enc1 = enc2 = enc3 = enc4 = '';
if (!(i < input.length)) {
break;
}
}
return output;
}; ExifRestore.restore = function(origFileBase64, resizedFileBase64) {
var image, rawImage, segments;
if (!origFileBase64.match('data:image/jpeg;base64,')) {
return resizedFileBase64;
}
rawImage = this.decode64(origFileBase64.replace('data:image/jpeg;base64,', ''));
segments = this.slice2Segments(rawImage);
image = this.exifManipulation(resizedFileBase64, segments);
return 'data:image/jpeg;base64,' + this.encode64(image);
}; ExifRestore.exifManipulation = function(resizedFileBase64, segments) {
var aBuffer, exifArray, newImageArray;
exifArray = this.getExifArray(segments);
newImageArray = this.insertExif(resizedFileBase64, exifArray);
aBuffer = new Uint8Array(newImageArray);
return aBuffer;
}; ExifRestore.getExifArray = function(segments) {
var seg, x;
seg = void 0;
x = 0;
while (x < segments.length) {
seg = segments[x];
if (seg[0] === 255 & seg[1] === 225) {
return seg;
}
x++;
}
return [];
}; ExifRestore.insertExif = function(resizedFileBase64, exifArray) {
var array, ato, buf, imageData, mae, separatePoint;
imageData = resizedFileBase64.replace('data:image/jpeg;base64,', '');
buf = this.decode64(imageData);
separatePoint = buf.indexOf(255, 3);
mae = buf.slice(0, separatePoint);
ato = buf.slice(separatePoint);
array = mae;
array = array.concat(exifArray);
array = array.concat(ato);
return array;
}; ExifRestore.slice2Segments = function(rawImageArray) {
var endPoint, head, length, seg, segments;
head = 0;
segments = [];
while (true) {
if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 218) {
break;
}
if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 216) {
head += 2;
} else {
length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3];
endPoint = head + length + 2;
seg = rawImageArray.slice(head, endPoint);
segments.push(seg);
head = endPoint;
}
if (head > rawImageArray.length) {
break;
}
}
return segments;
}; ExifRestore.decode64 = function(input) {
var base64test, buf, chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, output;
output = '';
chr1 = void 0;
chr2 = void 0;
chr3 = '';
enc1 = void 0;
enc2 = void 0;
enc3 = void 0;
enc4 = '';
i = 0;
buf = [];
base64test = /[^A-Za-z0-9\+\/\=]/g;
if (base64test.exec(input)) {
console.warning('There were invalid base64 characters in the input text.\n' + 'Valid base64 characters are A-Z, a-z, 0-9, \'+\', \'/\',and \'=\'\n' + 'Expect errors in decoding.');
}
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
while (true) {
enc1 = this.KEY_STR.indexOf(input.charAt(i++));
enc2 = this.KEY_STR.indexOf(input.charAt(i++));
enc3 = this.KEY_STR.indexOf(input.charAt(i++));
enc4 = this.KEY_STR.indexOf(input.charAt(i++));
chr1 = enc1 << 2 | enc2 >> 4;
chr2 = (enc2 & 15) << 4 | enc3 >> 2;
chr3 = (enc3 & 3) << 6 | enc4;
buf.push(chr1);
if (enc3 !== 64) {
buf.push(chr2);
}
if (enc4 !== 64) {
buf.push(chr3);
}
chr1 = chr2 = chr3 = '';
enc1 = enc2 = enc3 = enc4 = '';
if (!(i < input.length)) {
break;
}
}
return buf;
}; return ExifRestore; })(); /*
* contentloaded.js
*
* Author: Diego Perini (diego.perini at gmail.com)
* Summary: cross-browser wrapper for DOMContentLoaded
* Updated: 20101020
* License: MIT
* Version: 1.2
*
* URL:
* http://javascript.nwbox.com/ContentLoaded/
* http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
*/ contentLoaded = function(win, fn) {
var add, doc, done, init, poll, pre, rem, root, top;
done = false;
top = true;
doc = win.document;
root = doc.documentElement;
add = (doc.addEventListener ? "addEventListener" : "attachEvent");
rem = (doc.addEventListener ? "removeEventListener" : "detachEvent");
pre = (doc.addEventListener ? "" : "on");
init = function(e) {
if (e.type === "readystatechange" && doc.readyState !== "complete") {
return;
}
(e.type === "load" ? win : doc)[rem](pre + e.type, init, false);
if (!done && (done = true)) {
return fn.call(win, e.type || e);
}
};
poll = function() {
var e, error1;
try {
root.doScroll("left");
} catch (error1) {
e = error1;
setTimeout(poll, 50);
return;
}
return init("poll");
};
if (doc.readyState !== "complete") {
if (doc.createEventObject && root.doScroll) {
try {
top = !win.frameElement;
} catch (undefined) {}
if (top) {
poll();
}
}
doc[add](pre + "DOMContentLoaded", init, false);
doc[add](pre + "readystatechange", init, false);
return win[add](pre + "load", init, false);
}
}; Dropzone._autoDiscoverFunction = function() {
if (Dropzone.autoDiscover) {
return Dropzone.discover();
}
}; contentLoaded(window, Dropzone._autoDiscoverFunction); }).call(this);
dropzone.js
{#bpm_base.html#}
{## # ————————47PerfectCRM实现CRM客户报名流程————————#}
{#模板文件 #}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
{# <meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。#}
{# <meta> 标签位于文档的头部,不包含任何内容。<meta> 标签的属性定义了与文档相关联的名称/值对。#}
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="/static/bpm_img/bpm_logo.jpg">{# icon,指的是图标 #}
<title>业务流程</title> {# 页面头部显示#}
{# 使用link来调用外部的css文件#}
<link rel="stylesheet" href="/static/bpm_css/bootstrap.css" /> {#导航栏样式#}
<link rel="stylesheet" href="/static/bpm_css/dashboard.css" /> {#指示板样式#} {##————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————#}
<link rel="stylesheet" href="/static/bpm_plugins/dropzone/dropzone.css" /> {#上传文件的插件#}
{##————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————#} </head>
<body>
{% block body %}{#自定义内容 body#}{% endblock %}
{# 将纯JavaScript的语句另外保存在一个"*.js"的文件中,需要时再调用。#}
<script src="/static/bpm_js/jquery.js"></script> {# jQuery 是一个 JavaScript库,极大地简化了 JavaScript 编程。#}
<script src="/static/bpm_js/bootstrap.js"></script> {#指示板JS事件#} {##————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————#}
<script src="/static/bpm_js/jquery.cookie.js"></script> {#删除文件JS事件#}
<script src="/static/bpm_plugins/dropzone/dropzone.js"></script> {#上传文件的插件#}
{##————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————#} {% block js %}{#自定义内容 JS#}{% endblock %} </body>
</html>
{## # ————————47PerfectCRM实现CRM客户报名流程————————#}
{#bpm_base.html#}
# settings.py """
Django settings for PerfectCRM project. Generated by 'django-admin startproject' using Django 2.0.3. For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/ For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/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.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'atkhzsd7emv4_okn@ynhji)p)qbpuvhq+a7@yx5=chaa0$l_br' # 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', # ————————04PerfectCRM实现King_admin注册功能————————
# 'crm.apps.CrmConfig',
'crm',
# ————————04PerfectCRM实现King_admin注册功能———————— # ————————02PerfectCRM创建ADMIN页面————————
'king_admin',
# ————————02PerfectCRM创建ADMIN页面————————
# ————————38PerfectCRM实现全局账号登录注销————————
'gbacc',
# ————————38PerfectCRM实现全局账号登录注销———————— # ————————48PerfectCRM实现CRM客户报名流程学生合同————————
'bpm',
# ————————48PerfectCRM实现CRM客户报名流程学生合同————————
] 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 = 'PerfectCRM.urls' TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# ————————02PerfectCRM创建ADMIN页面————————
'DIRS': [os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'king_admin/king_templates'), # ————————03PerfectCRM创建基本数据————————
os.path.join(BASE_DIR, 'DBadd/DBadd_templates'),
# ————————03PerfectCRM创建基本数据————————
# ————————38PerfectCRM实现全局账号登录注销————————
os.path.join(BASE_DIR, 'gbacc/gbacc_templates'),
# ————————38PerfectCRM实现全局账号登录注销———————— # ————————47PerfectCRM实现CRM客户报名流程————————
os.path.join(BASE_DIR, 'bpm/bpm_templates'), ]
# ————————47PerfectCRM实现CRM客户报名流程———————— ,
# ————————02PerfectCRM创建ADMIN页面————————
'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 = 'PerfectCRM.wsgi.application' # Database
# https://docs.djangoproject.com/en/2.0/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.0/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.0/topics/i18n/ # ————————01PerfectCRM基本配置ADMIN————————
#LANGUAGE_CODE = 'en-us' #英文转中文方法
LANGUAGE_CODE = 'zh-Hans'
# ————————01PerfectCRM基本配置ADMIN———————— TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' # ————————01PerfectCRM基本配置ADMIN————————
STATICFILES_DIRS = [os.path.join(BASE_DIR,'king_admin/static'),
# ————————01PerfectCRM基本配置ADMIN————————
# ————————38PerfectCRM实现全局账号登录注销————————
os.path.join(BASE_DIR, 'gbacc/static'),
# ————————38PerfectCRM实现全局账号登录注销———————— # ————————47PerfectCRM实现CRM客户报名流程————————
os.path.join(BASE_DIR, 'bpm/static'),]
# ————————47PerfectCRM实现CRM客户报名流程———————— # ————————34PerfectCRM实现CRM自定义用户————————
AUTH_USER_MODEL = 'crm.UserProfile'#使用自定的admin 表单
# ————————34PerfectCRM实现CRM自定义用户———————— # ————————44PerfectCRM实现账号快速注册登陆————————
# send e-mail
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' #email后端
EMAIL_USE_TLS = False #是否使用TLS安全传输协议
EMAIL_USE_SSL = True #是否使用SSL加密,qq企业邮箱要求使用
EMAIL_HOST = 'smtp.sina.cn' #发送邮件的邮箱 的 SMTP服务器 #根据情况重新配置
EMAIL_PORT = 465 #发件箱的SMTP服务器端口 #一般不需要修改465
EMAIL_HOST_USER = 'perfectcrm@sina.cn' #发送邮件的邮箱账号 #根据情况重新配置 #perfectcrm@sina.cn pydjango@sina.cn
EMAIL_HOST_PASSWORD = 'admin123456' #发送邮件的邮箱密码 #根据情况重新配置 # ————————44PerfectCRM实现账号快速注册登陆———————— # ————————46PerfectCRM实现登陆后页面才能访问————————
LOGIN_URL = '/gbacc/gbacc_login/'# login_url 配置 #默认 /accounts/login/ #注意: / (绝对路径)
# ————————46PerfectCRM实现登陆后页面才能访问———————— # ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————
ENROLLED_DATA='%s/bpm/static/enrolled_data'%BASE_DIR#证件上传 # 上传路径
# ————————51PerfectCRM实现CRM客户报名流程学生合同上传照片————————
# settings.py