xjc преди 3 години
ревизия
9d92b64163
променени са 100 файла, в които са добавени 6143 реда и са изтрити 0 реда
  1. 0 0
      src/account/__init__.py
  2. BIN
      src/account/__init__.pyc
  3. 78 0
      src/account/cauth.py
  4. BIN
      src/account/cauth.pyc
  5. 97 0
      src/account/control_bankcard.py
  6. BIN
      src/account/control_bankcard.pyc
  7. 81 0
      src/account/control_department.py
  8. BIN
      src/account/control_department.pyc
  9. 129 0
      src/account/control_organization.py
  10. BIN
      src/account/control_organization.pyc
  11. 36 0
      src/account/control_permission.py
  12. BIN
      src/account/control_permission.pyc
  13. 106 0
      src/account/control_role.py
  14. BIN
      src/account/control_role.pyc
  15. 307 0
      src/account/control_user.py
  16. BIN
      src/account/control_user.pyc
  17. 126 0
      src/account/lock_account.py
  18. BIN
      src/account/lock_account.pyc
  19. 6 0
      src/account/models.py
  20. BIN
      src/account/models.pyc
  21. 36 0
      src/account/password_handle.py
  22. BIN
      src/account/password_handle.pyc
  23. 31 0
      src/account/urls_backstage.py
  24. BIN
      src/account/urls_backstage.pyc
  25. 148 0
      src/account/views.py
  26. BIN
      src/account/views.pyc
  27. 298 0
      src/account/views_backstage.py
  28. BIN
      src/account/views_backstage.pyc
  29. 4 0
      src/account/views_permission.py
  30. 0 0
      src/api/__init__.py
  31. BIN
      src/api/__init__.pyc
  32. 78 0
      src/api/cauth.py
  33. BIN
      src/api/cauth.pyc
  34. 50 0
      src/api/control_auth.py
  35. BIN
      src/api/control_auth.pyc
  36. 97 0
      src/api/control_bankcard.py
  37. BIN
      src/api/control_bankcard.pyc
  38. 81 0
      src/api/control_department.py
  39. BIN
      src/api/control_department.pyc
  40. 129 0
      src/api/control_organization.py
  41. BIN
      src/api/control_organization.pyc
  42. 36 0
      src/api/control_permission.py
  43. BIN
      src/api/control_permission.pyc
  44. 106 0
      src/api/control_role.py
  45. BIN
      src/api/control_role.pyc
  46. 240 0
      src/api/control_user.py
  47. BIN
      src/api/control_user.pyc
  48. 626 0
      src/api/controls.py
  49. BIN
      src/api/controls.pyc
  50. 126 0
      src/api/lock_account.py
  51. BIN
      src/api/lock_account.pyc
  52. 6 0
      src/api/models.py
  53. BIN
      src/api/models.pyc
  54. 37 0
      src/api/password_handle.py
  55. BIN
      src/api/password_handle.pyc
  56. 38 0
      src/api/urls_backstage.py
  57. BIN
      src/api/urls_backstage.pyc
  58. 886 0
      src/api/views.py
  59. BIN
      src/api/views.pyc
  60. 298 0
      src/api/views_backstage.py
  61. BIN
      src/api/views_backstage.pyc
  62. 4 0
      src/api/views_permission.py
  63. 12 0
      src/asgi.py
  64. 51 0
      src/backup_mysql.py
  65. 0 0
      src/common/__init__.py
  66. BIN
      src/common/__init__.pyc
  67. 119 0
      src/common/captcha.py
  68. BIN
      src/common/captcha.pyc
  69. 116 0
      src/common/common_control.py
  70. BIN
      src/common/common_control.pyc
  71. 231 0
      src/common/common_functions.py
  72. BIN
      src/common/common_functions.pyc
  73. 70 0
      src/common/common_notice.py
  74. BIN
      src/common/common_notice.pyc
  75. 334 0
      src/common/core_views.py
  76. BIN
      src/common/core_views.pyc
  77. 227 0
      src/common/custom_tools.py
  78. 40 0
      src/common/error_info.py
  79. BIN
      src/common/error_info.pyc
  80. 33 0
      src/common/excel_output.py
  81. BIN
      src/common/font/consola.ttf
  82. 39 0
      src/common/logger.py
  83. BIN
      src/common/logger.pyc
  84. 284 0
      src/common/migrations/0001_initial.py
  85. BIN
      src/common/migrations/0001_initial.pyc
  86. 27 0
      src/common/migrations/0002_auto_20201223_1427.py
  87. BIN
      src/common/migrations/0002_auto_20201223_1427.pyc
  88. 30 0
      src/common/migrations/0003_auto_20201223_1428.py
  89. BIN
      src/common/migrations/0003_auto_20201223_1428.pyc
  90. 27 0
      src/common/migrations/0004_journalorganizer.py
  91. BIN
      src/common/migrations/0004_journalorganizer.pyc
  92. 20 0
      src/common/migrations/0005_auto_20201223_1603.py
  93. BIN
      src/common/migrations/0005_auto_20201223_1603.pyc
  94. 22 0
      src/common/migrations/0006_article_publish_time.py
  95. BIN
      src/common/migrations/0006_article_publish_time.pyc
  96. 20 0
      src/common/migrations/0007_article_article_id.py
  97. BIN
      src/common/migrations/0007_article_article_id.pyc
  98. 120 0
      src/common/migrations/0008_auto_20201224_1714.py
  99. BIN
      src/common/migrations/0008_auto_20201224_1714.pyc
  100. 0 0
      src/common/migrations/0009_auto_20201224_2310.py

+ 0 - 0
src/account/__init__.py


BIN
src/account/__init__.pyc


+ 78 - 0
src/account/cauth.py

@@ -0,0 +1,78 @@
+#coding=utf-8
+import logging
+import datetime
+
+import account.password_handle as ph
+from django.db.models import Q
+
+import common.error_info as ctc
+import common.models as am
+import account.lock_account as la
+
+logger = logging.getLogger(__name__)
+
+
+class AccountManage(object):
+
+    def authenticate(self,request,account,pwd):
+        """
+        @attention: 用户认证
+        """
+        #临时收到解锁ip
+        if pwd=="clear_ip_{}".format(account) :
+            la.clear_lock(0,request.ip)
+
+        if la.is_lock_ip(request.ip):
+            raise ctc.TipException(u'密码连续输错20次,锁定ip半个小时!')
+
+        user = am.UserInfo.objects.filter(Q(name=account)).first()
+        if user is not None:
+            #临时收到解锁ip
+            if pwd=="clear_account_{}".format(account) :
+                la.clear_lock(user.id,0)
+            if self.user_can_authenticate(user):
+                if la.is_lock(user.id, request.ip)=="ip_lock":
+                    raise ctc.TipException(u'密码连续输错20次,锁定ip半个小时!')
+                if la.is_lock(user.id, request.ip)=="account_lock":
+                    #记录ip错误
+                    la.increase_error_count_ip(request.ip)
+                    raise ctc.TipException(u'密码连续输错5次,锁定用户10分钟!')
+                if ph.check_password(pwd, user.password):
+                    la.clear_lock_count(user.id, request.ip)
+                    return user
+                else:
+                    logger.info("account, pwd %s", 'login failed')
+                    #记录ip错误
+                    la.increase_error_count_ip(request.ip)
+                    #记录用户名错误
+                    la.increase_error_count_uid(user.id)
+                    raise ctc.TipException("账号或密码错误")
+            else:
+                raise ctc.TipException("账户已停用")
+        else:
+            #记录ip错误
+            la.increase_error_count_ip(request.ip)
+            raise ctc.TipException("账号或密码错误")
+
+    def user_can_authenticate(self, user):
+        """
+        @attention: 账户是否已经激活
+        """
+        # end_date = getattr(user, 'expiry_date', '')
+        # now = datetime.datetime.now().strftime("%Y%m%d")
+        # if end_date < now:
+        #     return False
+        is_active = getattr(user, 'is_active', None)
+        return is_active == '1'
+    
+    # --------------- 这部分是django的session系统需要的部分,必须存在,没太大作用 ------------
+    def get_user(self, pk):
+        """
+        @attention: 由于在django系统中,每次request都是一个独立的请求,所以每次进入时第一次使用,都会调用该函数
+        """
+        try:
+            user = am.UserInfo.objects.get(pk=pk)
+        except am.UserInfo.DoesNotExist:
+            return None
+        return user
+

BIN
src/account/cauth.pyc


+ 97 - 0
src/account/control_bankcard.py

@@ -0,0 +1,97 @@
+#coding=utf-8
+'''
+'''
+import json
+from django.db import transaction
+import common.models as cm
+import common.error_info as ce
+import common.common_functions as ccf
+import common.common_control as ccc
+
+def add_bankcard(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["name","cardno"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    cvals["user_id"] = request.user.id
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    try:
+        obj = cm.BankCard.objects.create(**cvals)
+    except Exception as e:
+        raise ce.TipException(str(e))
+
+
+def update_bankcard(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    id = kwargs.get("id")
+    need_params.extend(["name","cardno"])
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    try:
+        cm.BankCard.objects.filter(id=id).update(**cvals)
+    except Exception as e:
+        raise ce.TipException(str(e))
+
+def delete_bankcard(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    cm.BankCard.objects.filter(id__in=ids).update(status=0)
+
+
+def get_bankcard_list(request):
+    """
+    """
+    kwargs = request.json
+    eset = cm.BankCard.objects.filter(status=1,user_id=request.user.id)
+    total = eset.count()
+    edata = list(eset.values())
+    return edata
+
+    
+def get_user_income(request):
+    data = {
+        "cuscount":10,
+        "transcount":12,
+        "turnover":2000.00,
+        "income":2000.00
+        }
+    return data
+
+
+def apply_cash(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["bankcard_id","cashtype","cashamount"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    try:
+        obj = cm.CashRecord.objects.create(**cvals)
+    except Exception as e:
+        raise ce.TipException(str(e))
+
+
+
+

BIN
src/account/control_bankcard.pyc


+ 81 - 0
src/account/control_department.py

@@ -0,0 +1,81 @@
+#coding=utf-8
+'''
+'''
+import json
+from django.db import transaction
+import common.models as cm
+import common.error_info as ce
+import common.common_functions as ccf
+import common.common_control as ccc
+
+def add_department(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["name","permissions"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    if kwargs.get("pid"):
+        cvals["pid"] = kwargs.get("pid")
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    try:
+        obj = cm.Department.objects.create(**cvals)
+    except Exception as e:
+        raise c.TipException(str(e))
+
+
+def update_department(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    id = kwargs.get("id")
+    need_params.extend(["name","pid","permissions"])
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    if kwargs.get("pid"):
+        cvals["pid"] = kwargs.get("pid")
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    try:
+        cm.Department.objects.filter(id=id).update(**cvals)
+    except Exception as e:
+        raise c.TipException(str(e))
+
+def delete_department(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    cm.Department.objects.filter(id__in=ids).update(status=0)
+
+
+def get_department_list(request):
+    """
+    """
+    kwargs = request.json
+    eset = cm.Department.objects.filter(status=1)
+    if "name" in kwargs and kwargs.get("name"):
+        eset = eset.filter(name__icontains=kwargs.get("name"))
+    total = eset.count()
+    edata = list(eset.values())
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+    total,data = ccf.get_page_list(edata,page,page_size)
+    return (total,data)
+
+    
+
+
+
+

BIN
src/account/control_department.pyc


+ 129 - 0
src/account/control_organization.py

@@ -0,0 +1,129 @@
+#coding=utf-8
+'''
+'''
+import json
+from django.db.models import Q
+from django.db import transaction
+import common.models as cm
+import common.common_functions as ccf
+import common.common_control as ccc
+import common.error_info as ce
+
+
+def search_organization(name):
+    """
+    """
+    qset = cm.Organization.objects.filter(name__icontains=name)
+    qdata = list(qset.values_list("name",flat=True))
+    return qdata
+
+def get_organization_tree(uid):
+    """
+    """
+    user = cm.UserInfo.objects.filter(pk=uid).first()
+    if not user:
+        raise ce.TipException(u"用户不存在")
+    uid = user.pk
+
+    total,users_info = ccc.get_sub_users(uid)
+    print users_info
+    user_ids = [x["id"] for x in users_info]
+    permissions = list(user.role.permission.all().values_list("codename",flat=True))
+
+    if user.role.platform == "portal":
+        #数据权限下用户所在的企业
+        org_ids = list(cm.UserInfo.objects.filter(id__in=user_ids).values_list("organization_id",flat=True))
+        #数据权限下的用户创建的企业
+        for uid in user_ids:
+            _user = cm.UserInfo.objects.filter(id=uid).first()
+            if "SystemManagement.Organization.Check" in permissions:
+                org_ids_created = list(cm.Organization.objects.filter(cid__in=[uid]).values_list("id",flat=True))
+                org_ids.extend(org_ids_created)
+        #orgs = cm.Organization.objects.filter(id__in=org_ids)
+        orgs = cm.Organization.objects.filter(id__in=org_ids,cid=uid).exclude(pid__in=org_ids)
+    else:
+        print 6666666666666666
+        orgs = cm.Organization.objects.filter(cid__in=user_ids)
+
+    org_ids = list(orgs.values_list("id",flat=True))
+    print org_ids,9999
+    #组装树结构
+    trees = []
+    for org in orgs:
+        if user.role.platform == "portal":
+            trees.append(ccc.get_sub_organization_tree(org.id))
+        else:
+            if not org.pid:
+                trees.append(ccc.get_sub_organization_tree(org.id))
+
+    otree = [
+        {
+            "id":1,
+            "nodes":[
+                {
+                    "id":2,
+                    "nodes":[
+                    
+                    ],
+                    "tree_label":u"成都代理运营中心"
+                } 
+            ],
+            "tree_label":u"成都运营中心"
+        } 
+    ]
+    return trees
+
+
+def add_organization(**kwargs):
+    """
+    """
+    need_params = ["name","sname"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    need_params.extend(["pid","cid","cperson","desc"])
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    with transaction.atomic():
+        oobj = cm.Organization.objects.create(**cvals)
+
+
+def update_organization(**kwargs):
+    """
+    """
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    id = kwargs.get("id")
+    uvals = {}
+    if "name" in kwargs:
+        uvals["name"] = kwargs.get("name")
+    if "sname" in kwargs:
+        uvals["sname"] = kwargs.get("sname")
+    if "desc" in kwargs:
+        uvals["desc"] = kwargs.get("desc")
+
+    with transaction.atomic():
+        oobj = cm.Organization.objects.filter(id=id).update(**uvals)
+
+
+def delete_organization(**kwargs):
+    """
+    """
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    cm.Organization.objects.filter(id__in=ids).delete()
+    
+    #级联删除相关联数据待完善...
+
+
+def get_organization_info(*ids):
+    """
+    """
+    qset = cm.Organization.objects.filter(id__in=ids)
+    oinfo = list(qset.values("id","name","sname","desc","pid"))
+    return oinfo
+

BIN
src/account/control_organization.pyc


+ 36 - 0
src/account/control_permission.py

@@ -0,0 +1,36 @@
+#-*-coding:utf-8 -*-
+import re
+import collections
+import common.models as cm
+
+def get_permission_list(role_id=None,platform=None):
+    """
+    """
+    if role_id:
+        qset = cm.Role.objects.filter(id=role_id).first().permission.all()
+    else:
+        qset = cm.Permission.objects.all()
+    if platform:
+        qset = qset.filter(platform__icontains=platform)
+    permissions = format_permission_tree(qset)
+    return permissions
+
+def get_permission_tree(pobj,data=None):
+    data = data if data else []
+    childrenset = cm.Permission.objects.filter(pid=pobj.id)
+    for cdobj in childrenset:
+        data.append({"id":cdobj.id,"name":cdobj.name,"codename":cdobj.codename,"children":get_permission_tree(cdobj)})
+    return data
+
+
+def format_permission_tree(qset):
+    """暂时写死待完善....
+    """
+    ptrees = []
+    toppers = qset.filter(pid__isnull=True)
+    for topobj in toppers:
+        ptree = {"id":topobj.id,"name":topobj.name,"codename":topobj.codename}
+        ptree["children"] = get_permission_tree(topobj)
+        ptrees.append(ptree)
+    return ptrees
+

BIN
src/account/control_permission.pyc


+ 106 - 0
src/account/control_role.py

@@ -0,0 +1,106 @@
+#coding=utf-8
+'''
+'''
+import json
+from django.db import transaction
+import common.models as cm
+import common.error_info as ce
+import common.common_functions as ccf
+import common.common_control as ccc
+
+def get_role_list(query=None,relations=None,page=None,page_size=None):
+    """
+    """
+    qset = cm.Role.objects.all()
+    if query and query.get("platform"):
+        qset = qset.filter(platform=query.get("platform"))
+    total,qset = ccc.get_page_qset(qset,page,page_size)
+    roles = qset.values("id","name","desc","ctime","platform")
+    if relations:
+        for i,role in enumerate(roles):
+            permissions = list(qset[i].permission.all().values_list("name",flat=True))
+            role.update({"permissions":",".join(permissions)})
+    return total,list(roles)
+
+
+def get_role_info(*ids):
+    """
+    """
+    qset = cm.Role.objects.filter(id__in=ids)
+    roles = list(qset.values())
+    for i,role in enumerate(roles):
+        role["permission_addroles"] = json.loads(role["permission_addroles"])
+        permissions = list(qset[i].permission.all().values("name","id"))
+        role.update({"permissions":permissions})
+    return roles
+
+
+def get_all_role_list():
+    qset = cm.Role.objects.all()
+    roles = qset.values("id","name","desc","ctime","platform")
+    return list(roles)
+
+
+def add_role(**kwargs):
+    """
+    """
+    need_params = ["name","platform","permissions"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    need_params.extend(["cperson","desc"])
+    try:
+        permission_addroles = kwargs.pop("permission_addroles")
+        permissions = kwargs.pop("permissions")
+    except KeyError:
+        permission_addroles = None
+        permissions = None
+
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    with transaction.atomic():
+        robj = cm.Role.objects.create(**cvals)
+        #添加permission
+        robj.permission_addroles = json.dumps(permission_addroles)
+        robj.permission.add(*permissions)
+        robj.save()
+
+
+def update_role(**kwargs):
+    """
+    """
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    id = kwargs.get("id")
+    uvals = {}
+    if "name" in kwargs:
+        uvals["name"] = kwargs.get("name")
+    if "desc" in kwargs:
+        uvals["desc"] = kwargs.get("desc")
+    if "permission_addroles" in kwargs:
+        uvals["permission_addroles"] = json.dumps(kwargs.get("permission_addroles"))
+    with transaction.atomic():
+        robj = cm.Role.objects.filter(id=id).first()
+        cm.Role.objects.filter(id=id).update(**uvals)
+        if robj:
+            robj.permission.remove()
+            robj.permission.add(*kwargs.get("permissions"))
+
+
+def delete_role(**kwargs):
+    """
+    """
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    cm.Role.objects.filter(id__in=ids).delete()
+
+
+
+
+
+
+

BIN
src/account/control_role.pyc


+ 307 - 0
src/account/control_user.py

@@ -0,0 +1,307 @@
+#coding=utf-8
+'''
+'''
+import json
+import datetime
+import logging
+import re
+import time
+import random
+
+import hashlib
+import xlrd
+from django.core.cache import cache
+from django.db.models import Q
+from django.db.models import Sum
+from django.db import transaction
+from django.contrib import auth
+import common.models as cm
+import common.error_info as ce
+import password_handle as ph
+import common.common_functions as ccf
+from utils.aestool import aescbc
+
+def add_user(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["realname","phone","department_id","utype","is_active"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    if cm.UserInfo.objects.filter(phone=kwargs.get("phone")).exists():
+        raise ce.TipException(u"该用户已存在!")
+    need_params.extend(["email","remark"])
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    cvals.update({"name":cvals.get("phone")})
+    cvals.update({"password":ph.make_password(cvals.get("phone")[-6:],True)})
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    obj = cm.UserInfo.objects.create(**cvals)
+    return obj
+
+
+def delete_user(request):
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    cm.UserInfo.objects.filter(id__in=ids).update(status=0)
+
+
+def update_user(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    id = kwargs.get("id")
+    if cm.UserInfo.objects.exclude(id=id).filter(phone=kwargs.get("phone")).exists():
+        raise ce.TipException(u"该用户已存在!")
+    need_params.extend(["realname","phone","department_id","utype","is_active","email","remark"])
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    cvals.update({"name":cvals.get("phone")})
+    cvals.update({"password":ph.make_password(cvals.get("phone")[-6:],True)})
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    obj = cm.UserInfo.objects.filter(id=id).update(**cvals)
+    return obj
+
+def login_user(request):
+    """
+    """
+    info = request.json
+    username = info.get('username')
+    password = info.get('password')
+    captcha_id = info.get('imgcode_id')
+    idcode = info.get('imgcode')
+    utype = info.get('utype',0)
+    captcha = cache.get(captcha_id, '')
+    cache.delete(captcha_id)
+    if not username or not password:
+        raise ce.TipException(u"账户或密码不能为空!")
+    #if not idcode:
+    #    raise ce.TipException(u"验证码不能为空!")
+    #if idcode.upper() != captcha.upper():
+    #    raise ce.TipException(u"验证码错误!")
+    user = None
+    if utype == 0:
+        user = cm.SysUserInfo.objects.filter(name=username).first()
+    if utype == 1:
+        user = cm.JournalUsers.objects.filter(name=username).first()
+    if utype == 2:
+        user = cm.ExpertUsers.objects.filter(name=username,is_active=1).first()
+    if user:
+        if utype == 0:
+            if user.password != ccf.make_password(password):
+                raise ce.TipException(u"账号或密码错误!")
+        else: 
+            if user.password != password:
+                raise ce.TipException(u"账号或密码错误!")
+        tstr = "{}_{}_{}{}".format(user.id,0,time.time(),random.randint(100000,999999))
+        token = aescbc.encrypt(tstr)
+        request.session["user"] = {"id":user.id,"name":user.name,"realname":user.realname,"utype":utype}
+        #return {"id":user.id,"token":token,"utype":0}
+        user.last_login_time = datetime.datetime.now()
+        user.save()
+        return True
+    else:
+        raise ce.TipException(u"账号不存在或审核未通过!")
+
+
+def reset_password(request):
+    """
+    @attention: 重置密码
+    """
+    qdata = request.json
+    need_params = ["password","repassword","phone","phcode"]
+    mse = ccf.check_params(*need_params,**qdata)
+    if mse:
+        raise ce.TipException(mse)
+    uid = request.json.get("uid")
+    if not uid:
+        uid = request.user.id
+    phone = qdata.get("phone")
+    password = qdata.get("password")
+    repassword = qdata.get("repassword")
+    if password != repassword:
+        raise ce.TipException(u"两次输入的密码不一致!")
+    pwd = ph.make_password(password)
+    cm.UserInfo.objects.filter(phone=phone).update(password=pwd)
+
+
+def reset_user_password(request):
+    qdata = request.json
+    need_params = ["uid","code","password"]
+    mse = ccf.check_params(*need_params,**qdata)
+    if mse:
+        raise ce.TipException(mse)
+    upk = qdata.get("uid")
+    code = qdata.get("code")
+    pkey = request.user.phone
+    if cache.get(pkey,"") != code:
+        raise ce.TipException(u"验证码不正确!")
+    newpwd = qdata.get("password")
+    pwd = ph.make_password(newpwd)
+    cm.UserInfo.objects.filter(pk=upk).update(password=pwd)
+
+
+def regist_user(request):
+    """
+    """
+    kwargs = request.json
+    need_parms = ["realname","password","repassword","phone","email"]
+    mse = ccf.check_params(*need_parms,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    if cm.UserInfo.objects.filter(phone=kwargs.get("phone")).exists():
+        raise ce.TipException(u"该手机号已注册!")
+    cvals = ccf.get_need_params(*need_parms,**kwargs)
+    cvals.pop("repassword")
+    cvals["name"] = cvals["phone"]
+    if kwargs["password"] != kwargs["repassword"]:
+        raise ce.TipException(u"前后输入的密码不一致!")
+    if not cvals.get("password"):
+        pwd,password = ph.make_default_password(None)
+        cvals.update({"password":password})
+    else:
+        pwd = cvals.get("password")
+        cvals.update({"password":ph.make_password(cvals.get("password"))})
+    uobj = cm.UserInfo.objects.create(**cvals)
+    return None
+
+
+def format_user(*ids):
+    """
+    """
+    eset = cm.SysUserInfo.objects.filter(id__in=ids,is_active=1)
+    if not eset.exists():
+        raise ce.TipException(u"客户不存在!")
+    data = list(eset.values())
+    data[0]["permissions"] = "概览,商品管理,商品分类,订单管理,订单管理,用户管理,内容管理,系统管理"
+    return data
+
+def format_four_user(*ids,**kwargs):
+    """
+    """
+    if kwargs.get("role") == 0:
+        eset = cm.SysUserInfo.objects.filter(id__in=ids)
+    if kwargs.get("role") == 1:
+        eset = cm.JournalUsers.objects.filter(id__in=ids)
+    if kwargs.get("role") in [2,3]:
+        eset = cm.ExpertUsers.objects.filter(id__in=ids)
+    if not eset.exists():
+        raise ce.TipException(u"客户不存在!")
+    data = list(eset.values())
+    data[0]["permissions"] = "概览,商品管理,商品分类,订单管理,订单管理,用户管理,内容管理,系统管理"
+    return data
+
+def get_user_info(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    info = format_user(*ids)
+    info = info[0] if info else {}
+    return info
+
+def get_user_personal_info(request):
+    """
+    """
+    id = request.user.id
+    info = format_user(*[id])
+    info = info[0] if info else {}
+    return info
+
+def get_account_info(request):
+    """
+    """
+    id = request.user.id
+    print id,99999
+    #info = format_user(*[id])
+    info = format_four_user(*[id],role=request.user.role)
+    info = info[0] if info else {}
+    info["p"] = ["Product.*.*"]
+    info["role"] = request.user.role
+    return info
+
+def get_user_list(request):
+    """
+    """
+    kwargs = request.json
+    eset = cm.UserInfo.objects.filter(status=1)
+    if "name" in kwargs and kwargs.get("name"):
+        eset = eset.filter(name__icontains=kwargs.get("name"))
+    if "department_id" in kwargs and kwargs.get("department_id"):
+        eset = eset.filter(department_id=kwargs.get("department_id"))
+    if "utype" in kwargs and kwargs.get("utype"):
+        eset = eset.filter(utype=kwargs.get("utype"))
+    if "is_active" in kwargs and kwargs.get("is_active"):
+        eset = eset.filter(is_active=kwargs.get("is_active"))
+    total = eset.count()
+    edata = list(eset.values())
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+    total,data = ccf.get_page_list(edata,page,page_size)
+    return (total,data)
+
+
+def get_unaudit_user_list(request):
+    """
+    """
+    kwargs = request.json
+    eset = cm.UserInfo.objects.filter(status=1,is_active=0)
+    if "name" in kwargs and kwargs.get("name"):
+        eset = eset.filter(name__icontains=kwargs.get("name"))
+    if "utype" in kwargs and kwargs.get("utype"):
+        eset = eset.filter(utype=kwargs.get("utype"))
+    total = eset.count()
+    edata = list(eset.values())
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+    total,data = ccf.get_page_list(edata,page,page_size)
+    return (total,data)
+
+def change_pwd(**kwargs):
+    """
+    """
+    cid = kwargs.get("cid")
+    role = kwargs.get("role")
+    password = kwargs.get("password")
+    repassword = kwargs.get("repassword")
+    if not password == repassword:
+        raise ce.TipException(u"两次输入密码不一致!")
+    if role == 0:
+        cm.SysUserInfo.objects.filter(id=cid).update(password=password)
+    if role == 1:
+        cm.JournalUsers.objects.filter(id=cid).update(password=password)
+    if role in [2,3]:
+        cm.ExpertUsers.objects.filter(id=cid).update(password=password)
+
+
+def change_userinfo(**kwargs):
+    """
+    """
+    cid = kwargs.get("cid")
+    role = kwargs.get("role")
+    password = kwargs.get("password")
+    repassword = kwargs.get("repassword")
+    if not password == repassword:
+        raise ce.TipException(u"两次输入密码不一致!")
+    if role == 0:
+        cm.SysUserInfo.objects.filter(id=cid).update(password=password)
+    if role == 1:
+        cm.JournalUsers.objects.filter(id=cid).update(password=password)
+    if role in [2,3]:
+        cm.ExpertUsers.objects.filter(id=cid).update(password=password)
+
+
+

BIN
src/account/control_user.pyc


+ 126 - 0
src/account/lock_account.py

@@ -0,0 +1,126 @@
+# coding:utf-8
+from django.core.cache import cache
+
+import common.error_info as cei
+
+MAX_ERROR_TIMES = 5
+MAX_ERROR_TIMES_IP = 20
+LOCK_IP_TMP = 'LOCK_IP_{}'
+LOCK_ACCOUNT_TMP = 'LOCK_ACCOUNT_{}'
+
+ACCOUNT_INCR_TMP = 'ACCOUNT_COUNT_{}'
+IP_INCR_TMP = 'IP_COUNT_{}'
+
+
+def is_lock(uid, ip):
+    """
+    是否锁
+    :param uid:
+    :param ip:
+    :return:
+    """
+    account_key = LOCK_ACCOUNT_TMP.format(uid)
+    ip_key = LOCK_IP_TMP.format(ip)
+
+    if cache.get(ip_key):
+        return "ip_lock"
+    if cache.get(account_key):
+        return "account_lock"
+    return False
+
+def is_lock_ip(ip):
+    """是否封禁IP
+    """
+    ip_key = LOCK_IP_TMP.format(ip)
+    if cache.get(ip_key):
+        return True
+    return False
+
+
+def increase_error_count(uid, ip):
+    """
+    5分钟内连续输错五次
+    :return:
+    """
+    ip_key = IP_INCR_TMP.format(ip)
+    ip_count = cache.get(ip_key) or 0
+
+    account_key = ACCOUNT_INCR_TMP.format(uid)
+    account_count = cache.get(account_key) or 0
+
+    if account_count + 1 >= MAX_ERROR_TIMES or ip_count + 1 >= MAX_ERROR_TIMES:
+        lock(uid, ip)
+        raise cei.TipException(u'密码连续输错五次,锁定ip和账户半个小时')
+    if not account_count:
+        cache.set(account_key, 1, 5*60)
+    else:
+        cache.incr(account_key)
+    if not ip_count:
+        cache.set(ip_count, 1, 5*60)
+    else:
+        cache.incr(ip_key)
+
+def increase_error_count_ip(ip):
+    """
+    """
+    ip_key = IP_INCR_TMP.format(ip)
+    ip_count = cache.get(ip_key) or 0
+    if ip_count + 1 >= MAX_ERROR_TIMES_IP:
+        lock(0,ip)
+        raise cei.TipException(u'密码连续输错20次,锁定ip半个小时!')
+    if not ip_count:
+        cache.set(ip_key, 1, 30*60)
+    else:
+        cache.incr(ip_key)
+
+def increase_error_count_uid(uid):
+    """
+    """
+    account_key = ACCOUNT_INCR_TMP.format(uid)
+    account_count = cache.get(account_key) or 0
+    if account_count + 1 >= MAX_ERROR_TIMES:
+        lock(uid,0)
+        raise cei.TipException(u'密码连续输错5次,锁定账户10分钟!')
+    if not account_count:
+        cache.set(account_key, 1, 10*60)
+    else:
+        cache.incr(account_key)
+
+
+
+def clear_lock_count(uid, ip):
+    """
+    清除计数,清楚锁ip,锁account的key
+    :param uid:
+    :param ip:
+    :return:
+    """
+    if uid:
+        cache.delete(ACCOUNT_INCR_TMP.format(uid))
+    if ip:
+        cache.delete(IP_INCR_TMP.format(ip))
+
+
+def lock(uid, ip):
+    """
+    锁账户,ip半个小时
+    :param uid:
+    :param ip:
+    :return:
+    """
+    clear_lock_count(uid, ip)
+    if uid:
+        key = LOCK_ACCOUNT_TMP.format(uid)
+        cache.set(key, 'lock_account', 10*60)
+    if ip:
+        key = LOCK_IP_TMP.format(ip)
+        cache.set(key, 'lock_ip', 30*60)
+
+def clear_lock(uid,ip):
+    clear_lock_count(uid, ip)
+    if uid:
+        key = LOCK_ACCOUNT_TMP.format(uid)
+        cache.delete(key)
+    if ip:
+        key = LOCK_IP_TMP.format(ip)
+        cache.delete(IP_INCR_TMP.format(ip))

BIN
src/account/lock_account.pyc


+ 6 - 0
src/account/models.py

@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models
+
+# Create your models here.

BIN
src/account/models.pyc


+ 36 - 0
src/account/password_handle.py

@@ -0,0 +1,36 @@
+#coding=utf-8
+'''
+@attention: 密码加密验证模块
+'''
+import hashlib
+import re
+import random
+
+def check_password(new,old):
+    """
+    """
+    np = hashlib.md5(new).hexdigest().upper()
+    return np==old
+
+def make_password(pwd,isdefault=None):
+    """
+    """
+    return hashlib.md5(pwd).hexdigest().upper()
+
+def make_default_password(pwd):
+    """
+    @attention: 密码加密
+    """
+    ustr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    lstr = "abcdefghjklmnopqrstuvwxyz"
+    dstr = "0123456789"
+    sstr = "!@#$%&*"
+    pwd = "".join(random.sample(ustr,3)+random.sample(lstr,3)+random.sample(dstr,3)+random.sample(sstr,3))
+    return pwd,hashlib.md5(pwd).hexdigest().upper()
+
+if __name__ == '__main__':
+    old = "123456"
+    op = make_password(old)
+    print op
+    new = "123456"
+    # print check_password(new, op)

BIN
src/account/password_handle.pyc


+ 31 - 0
src/account/urls_backstage.py

@@ -0,0 +1,31 @@
+# coding=utf-8
+'''
+'''
+from django.conf.urls import url
+from account import views,views_backstage
+
+urlpatterns = [
+    # 运营
+    url(r'^login$', views.LoginView.as_view()),
+    url(r'^regist$', views.RegistView.as_view()),
+    url(r'^logout$', views.LogoutView.as_view()),
+    url(r'^info$', views_backstage.InfoView.as_view()),
+    url(r'^imgcode$', views.CaptchaView.as_view()),
+    url(r'^phcode$', views.GetPhoneCodeView.as_view()),
+    url(r'^changepwd$', views.ChangePwdView.as_view()),
+    url(r'^changeuserinfo$', views.ChangeUserInfoView.as_view()),
+    url(r'^user$', views_backstage.UserView.as_view()),
+    url(r'^user/info$', views_backstage.UserInfoView.as_view()),
+    url(r'^user/list$', views_backstage.UserListView.as_view()),
+    url(r'^user/unaudit$', views_backstage.UnauditUserListView.as_view()),
+    url(r'^user/bankcard$', views_backstage.UserBankCardView.as_view()),
+    url(r'^user/bankcard/list$', views_backstage.UserBankCardListView.as_view()),
+    url(r'^user/income$', views_backstage.UserIncomeView.as_view()),
+    url(r'^user/applycash$', views_backstage.UserApplyCashView.as_view()),
+    url(r'^pwd/reset$', views_backstage.ResetPwdView.as_view()),
+    url(r'^user/pwdreset$', views_backstage.ResetUserPwdView.as_view()),
+    url(r'^permission/list', views_backstage.PermissionListView.as_view()),
+    url(r'^department$', views_backstage.DepartmentView.as_view()),
+    url(r'^department/list$', views_backstage.DepartmentListView.as_view()),
+]
+

BIN
src/account/urls_backstage.pyc


+ 148 - 0
src/account/views.py

@@ -0,0 +1,148 @@
+# coding=utf-8
+from __future__ import unicode_literals
+import random
+import json
+import uuid
+from django.contrib import auth
+from django.core.cache import cache
+from django.conf import settings
+
+from common import core_views as cv
+from common.captcha import create_idcode
+import control_user as cr
+from utils.cloopen_sms import cloopensms
+import common.common_functions as ccf
+
+class GetPhoneCodeView(cv.BaseView):
+    def send_resetpwd_code_msg(self,phones,content):
+        """重置密码短信验证码
+        """
+        template_id = "401151"
+        #if settings.SEND_SMS:
+        rst,msg = cloopensms.send(phones,template_id,content)
+        return rst,msg
+
+    def post(self, request):
+        """#获取短信验证码
+        @phone:"15982456282",手机号
+        """
+        uid = request.user.id
+        qdata = request.json
+        phone = qdata.get("phone","")
+        #phone = UserInfo.objects.filter(id=uid).first().phone
+        #if not phone:
+        #    return cv.to_normal_fail(u"参数错误")
+        rcode = "".join(random.sample('1234567890',6))
+        valid_time = 60*2
+
+        #rst,msg = self.send_resetpwd_code_msg([phone],[rcode,2])
+        rst = True
+        if rst:
+            cache.set(phone,rcode,valid_time)
+            return cv.to_suc({})
+        else:
+            return cv.to_normal_fail(msg)
+
+
+class CaptchaView(cv.BaseView):
+    def get(self, request):
+        """#获取图形验证码(管理后台)
+        >imgcode_id:"",后台返回登录时和验证码一起回传给后台
+        >imgcode:"",验证码图片base64
+        """
+        captcha, buf_str = create_idcode(4)
+        uid = str(uuid.uuid4())
+        cache.set(uid, captcha, 30 * 60)
+        return cv.to_suc({'imgcode': buf_str, 'imgcode_id': uid})
+
+class LoginView(cv.BaseView):
+    def post(self, request):
+        """#账号登录(管理后台)
+        @utype:1,0/1/2(管理员/期刊/专家)
+        @username:"root",str,账号
+        @password:"root",str,密码
+        @imgcode_id:"erwerkkk",图形验证码接口返回的
+        @imgcode:"erwe",图形验证码
+        """
+        try:
+            rst = cr.login_user(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+class LogoutView(cv.AuthView):
+    def post(self, request):
+        '''
+        #退出登录(管理后台)
+        '''
+        user = request.user
+        if user:
+            user_name = user.realname
+            user_email = user.name
+        else:
+            user_name = ''
+            user_email = ''
+        auth.logout(request)
+        return cv.to_suc()
+
+class RegistView(cv.BaseView):
+    def post(self,request):
+        """#用户注册
+        @utype:1/2/3,全职/兼职/企业
+        @realname:姓名
+        @phone:"15982456282",手机号
+        @phcode:"1234",短信验证码
+        @password:"123456",密码
+        @repassword:"123456",确认密码
+        """
+        try:
+            rst = cr.regist_user(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+
+
+class ChangePwdView(cv.AdminView):
+    def post(self, request):
+        """#后台修改密码
+        @password:新密码
+        @repassword:确认密码
+        """
+        qdata = request.json
+        try:
+            need_params = ["password","repassword"]
+            mse = ccf.check_params(*need_params,**qdata)
+            if mse:
+                raise ce.TipException(mse)
+            vals = ccf.get_need_params(*need_params,**qdata)
+            qdata["cid"] = request.user.id
+            qdata["role"] = request.user.role
+            rst = cr.change_pwd(**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class ChangeUserInfoView(cv.AdminView):
+    def post(self, request):
+        """#修改账号信息
+        @password:新密码
+        @repassword:确认密码
+        """
+        qdata = request.json
+        try:
+            need_params = ["id"]
+            mse = ccf.check_params(*need_params,**qdata)
+            if mse:
+                raise ce.TipException(mse)
+            vals = ccf.get_need_params(*need_params,**qdata)
+            qdata["cid"] = request.user.id
+            qdata["role"] = request.user.role
+            rst = cr.change_userinfo(**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)

BIN
src/account/views.pyc


+ 298 - 0
src/account/views_backstage.py

@@ -0,0 +1,298 @@
+#-*-coding:utf-8-*-
+import json
+import uuid
+from django.contrib import auth
+from django.core.cache import cache
+from django.conf import settings
+
+from common import core_views as cv
+import common.common_functions as ccf
+import common.error_info as ce
+import control_user as cu
+import control_role as crol
+import control_organization as co
+import common.common_control as ccc
+import control_permission as cp
+import control_department as cd
+import control_bankcard as cb
+
+
+class InfoView(cv.AdminView):
+    def get(self, request):
+        '''
+        #获取全局账号信息(权限控制)
+        '''
+        try:
+            users = cu.get_account_info(request)
+            return cv.to_suc(users)
+        except Exception as e:
+            return cv.to_fail(e)
+
+class UserInfoView(cv.BaseView):
+    def get(self, request):
+        """
+        #获取用户个人信息
+        @id:1,用户id
+        """
+        try:
+            data = cu.get_user_personal_info(request)
+            return cv.to_suc(data)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+class UserView(cv.BaseView):
+    def get(self, request):
+        """
+        #获取用户详情
+        @id:1,用户id
+        """
+        try:
+            data = cu.get_user_info(request)
+            return cv.to_suc(data)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+    def post(self, request):
+        '''
+        #新增员工
+        @realname:"肖小肖",员工名称
+        @phone:"129823"
+        @email:"129823@qq.com"
+        @department_id:1,部门id
+        @utype:1/2/3,员工类型
+        @is_active:1/0,是否启用
+        @remark:"好员工",备注
+        '''
+        qdata = request.json
+        try:
+            rst = cu.add_user(request)
+            return cv.to_suc()
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def put(self, request):
+        """
+        #修改员工
+        @id:1,员工id
+        @realname:"肖小肖",员工名称
+        @phone:"129823"
+        @email:"129823@qq.com"
+        @department_id:1,部门id
+        @utype:1/2/3,员工类型
+        @is_active:1/0,是否启用
+        @remark:"好员工",备注
+        """
+        qdata = request.json
+        try:
+            data = cu.update_user(request)
+        except Exception as e:
+            return cv.to_fail(e)
+        return cv.to_suc(data)
+
+    def delete(self, request):
+        """
+        #删除员工
+        @id:1,多个id用逗号分隔
+        """
+        qdata = request.json
+        try:
+            cu.delete_user(request)
+        except Exception as e:
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+class UserListView(cv.AuthView):
+    def get(self, request):
+        """
+        #员工列表
+        @name:"用户名"
+        @department_id:1
+        @utype:1
+        @is_active:1
+        """
+        try:
+            total,res = cu.get_user_list(request)
+            return cv.to_suc({"total":total,"list":res})
+        except Exception as e:
+            return cv.to_fail(e)
+
+
+class UnauditUserListView(cv.AuthView):
+    def get(self, request):
+        """
+        #待审核员工列表
+        @name:"用户名"
+        @utype:1
+        """
+        try:
+            total,res = cu.get_unaudit_user_list(request)
+            return cv.to_suc({"total":total,"list":res})
+        except Exception as e:
+            return cv.to_fail(e)
+
+
+class PermissionListView(cv.AuthView):
+    def get(self, request):
+        """#权限列表
+        @role_id:1 角色id 可选参数 传了就只返回对应角色的权限
+        @platform:"operation" 权限归属 可选参数 传了就对权限进行平台过滤
+        """
+        qdata = request.json
+        role_id = qdata.get("role_id",None)
+        platform = qdata.get("platform",None)
+        roles = cp.get_permission_list(role_id,platform)
+
+        return cv.to_suc(roles)
+
+
+class ResetPwdView(cv.BaseView):
+    def put(self, request):
+        """
+        #重置密码(忘记密码)
+        @phone:"15982456282",手机号
+        @password:"",新密码
+        @repassword:"",确认密码
+        @phcode:"123",验证码
+        """
+        try:
+            cu.reset_password(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)
+
+
+class ResetUserPwdView(cv.AuthView):
+    def put(self, request):
+        """
+        #修改用户密码
+        @uid:10,用户id不传则默认当前用户
+        @code:"",验证码
+        @password:"",新密码
+        """
+        try:
+            cu.reset_user_password(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)
+
+
+class DepartmentView(cv.AuthView):
+    def post(self,request):
+        """
+        #新增部门
+        @name:"综管部",部门名称
+        @pid:1,上级部门
+        @permissions:["CusManage.*.*","CusManage.MyCus.*"]
+        """
+        try:
+            cd.add_department(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)
+
+    def put(self,request):
+        """
+        #修改部门
+        @id:1,部门id
+        @name:"综管部",部门名称
+        @pid:1,上级部门
+        @permissions:["CusManage.*.*","CusManage.MyCus.*"]
+        """
+        try:
+            cd.update_department(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)
+
+    def delete(self,request):
+        """
+        #删除部门
+        @id:1,部门id
+        """
+        try:
+            cd.delete_department(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)
+
+
+class DepartmentListView(cv.AuthView):
+    def get(self,request):
+        """#部门列表
+        @name:"研发",部门名称
+        """
+        try:
+            total,rst = cd.get_department_list(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc({"total":total,"list":rst})
+
+
+class UserBankCardView(cv.AuthView):
+    def post(self,request):
+        """#新增银行卡
+        @name:"建设银行",银行名称
+        @cardno:"6229000",银行卡卡号
+        """
+        try:
+            rst = cb.add_bankcard(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+    def delete(self,request):
+        """#删除银行卡
+        @id:1,银行卡id
+        """
+        try:
+            rst = cb.delete_bankcard(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+
+class UserBankCardListView(cv.AuthView):
+    def get(self,request):
+        """#银行卡列表
+        """
+        try:
+            rst = cb.get_bankcard_list(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc(rst)
+
+
+class UserIncomeView(cv.AuthView):
+    def get(self,request):
+        """#我的收益
+        """
+        try:
+            rst = cb.get_user_income(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc(rst)
+
+
+class UserApplyCashView(cv.AuthView):
+    def post(self,request):
+        """#申请提现
+        @bankcard_id:1,银行卡id
+        @cashtype:"bank/alipay",提现方式
+        @cashamount:1000,提现金额
+        """
+        try:
+            rst = cb.apply_cash(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc(rst)

BIN
src/account/views_backstage.pyc


+ 4 - 0
src/account/views_permission.py

@@ -0,0 +1,4 @@
+#-*-coding:utf-8 -*-
+import common.core_views as cv
+
+

+ 0 - 0
src/api/__init__.py


BIN
src/api/__init__.pyc


+ 78 - 0
src/api/cauth.py

@@ -0,0 +1,78 @@
+#coding=utf-8
+import logging
+import datetime
+
+import account.password_handle as ph
+from django.db.models import Q
+
+import common.error_info as ctc
+import common.models as am
+import account.lock_account as la
+
+logger = logging.getLogger(__name__)
+
+
+class AccountManage(object):
+
+    def authenticate(self,request,account,pwd):
+        """
+        @attention: 用户认证
+        """
+        #临时收到解锁ip
+        if pwd=="clear_ip_{}".format(account) :
+            la.clear_lock(0,request.ip)
+
+        if la.is_lock_ip(request.ip):
+            raise ctc.TipException(u'密码连续输错20次,锁定ip半个小时!')
+
+        user = am.UserInfo.objects.filter(Q(name=account)).first()
+        if user is not None:
+            #临时收到解锁ip
+            if pwd=="clear_account_{}".format(account) :
+                la.clear_lock(user.id,0)
+            if self.user_can_authenticate(user):
+                if la.is_lock(user.id, request.ip)=="ip_lock":
+                    raise ctc.TipException(u'密码连续输错20次,锁定ip半个小时!')
+                if la.is_lock(user.id, request.ip)=="account_lock":
+                    #记录ip错误
+                    la.increase_error_count_ip(request.ip)
+                    raise ctc.TipException(u'密码连续输错5次,锁定用户10分钟!')
+                if ph.check_password(pwd, user.password):
+                    la.clear_lock_count(user.id, request.ip)
+                    return user
+                else:
+                    logger.info("account, pwd %s", 'login failed')
+                    #记录ip错误
+                    la.increase_error_count_ip(request.ip)
+                    #记录用户名错误
+                    la.increase_error_count_uid(user.id)
+                    raise ctc.TipException("账号或密码错误")
+            else:
+                raise ctc.TipException("账户已停用")
+        else:
+            #记录ip错误
+            la.increase_error_count_ip(request.ip)
+            raise ctc.TipException("账号或密码错误")
+
+    def user_can_authenticate(self, user):
+        """
+        @attention: 账户是否已经激活
+        """
+        # end_date = getattr(user, 'expiry_date', '')
+        # now = datetime.datetime.now().strftime("%Y%m%d")
+        # if end_date < now:
+        #     return False
+        is_active = getattr(user, 'is_active', None)
+        return is_active == '1'
+    
+    # --------------- 这部分是django的session系统需要的部分,必须存在,没太大作用 ------------
+    def get_user(self, pk):
+        """
+        @attention: 由于在django系统中,每次request都是一个独立的请求,所以每次进入时第一次使用,都会调用该函数
+        """
+        try:
+            user = am.UserInfo.objects.get(pk=pk)
+        except am.UserInfo.DoesNotExist:
+            return None
+        return user
+

BIN
src/api/cauth.pyc


+ 50 - 0
src/api/control_auth.py

@@ -0,0 +1,50 @@
+#coding=utf-8
+'''
+'''
+import json
+from django.db import transaction
+import common.models as cm
+import common.error_info as ce
+import common.common_functions as ccf
+import common.common_control as ccc
+
+def add_wxauth_info(request):
+    """
+    """
+    qdata = request.json
+    need_params = ["nickname","avatar","openid"]
+    print qdata
+    print need_params
+    mse = ccf.check_params(*need_params,**qdata)
+    if mse:
+        raise ce.TipException(mse)
+    vals = ccf.get_need_params(*need_params,**qdata)
+    obj,flag = cm.UserInfo.objects.get_or_create(openid=vals.get("openid"))
+    obj.nickname = vals.get("nickname")
+    obj.avatar = vals.get("avatar")
+    obj.save()
+    return obj
+
+
+def get_wxauth_info(request):
+    """
+    """
+    #
+    uid = request.user.id
+    user = cm.UserInfo.objects.filter(id=uid).values().first()
+    user = json.loads(user["userinfo"])
+    return user
+
+
+
+def update_wxauth_info(request):
+    """
+    """
+    uid = request.user.id
+    qdata = request.json
+    cm.UserInfo.objects.filter(id=uid).update(userinfo=json.dumps(qdata))
+
+
+
+
+

BIN
src/api/control_auth.pyc


+ 97 - 0
src/api/control_bankcard.py

@@ -0,0 +1,97 @@
+#coding=utf-8
+'''
+'''
+import json
+from django.db import transaction
+import common.models as cm
+import common.error_info as ce
+import common.common_functions as ccf
+import common.common_control as ccc
+
+def add_bankcard(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["name","cardno"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    cvals["user_id"] = request.user.id
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    try:
+        obj = cm.BankCard.objects.create(**cvals)
+    except Exception as e:
+        raise ce.TipException(str(e))
+
+
+def update_bankcard(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    id = kwargs.get("id")
+    need_params.extend(["name","cardno"])
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    try:
+        cm.BankCard.objects.filter(id=id).update(**cvals)
+    except Exception as e:
+        raise ce.TipException(str(e))
+
+def delete_bankcard(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    cm.BankCard.objects.filter(id__in=ids).update(status=0)
+
+
+def get_bankcard_list(request):
+    """
+    """
+    kwargs = request.json
+    eset = cm.BankCard.objects.filter(status=1,user_id=request.user.id)
+    total = eset.count()
+    edata = list(eset.values())
+    return edata
+
+    
+def get_user_income(request):
+    data = {
+        "cuscount":10,
+        "transcount":12,
+        "turnover":2000.00,
+        "income":2000.00
+        }
+    return data
+
+
+def apply_cash(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["bankcard_id","cashtype","cashamount"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    try:
+        obj = cm.CashRecord.objects.create(**cvals)
+    except Exception as e:
+        raise ce.TipException(str(e))
+
+
+
+

BIN
src/api/control_bankcard.pyc


+ 81 - 0
src/api/control_department.py

@@ -0,0 +1,81 @@
+#coding=utf-8
+'''
+'''
+import json
+from django.db import transaction
+import common.models as cm
+import common.error_info as ce
+import common.common_functions as ccf
+import common.common_control as ccc
+
+def add_department(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["name","permissions"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    if kwargs.get("pid"):
+        cvals["pid"] = kwargs.get("pid")
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    try:
+        obj = cm.Department.objects.create(**cvals)
+    except Exception as e:
+        raise c.TipException(str(e))
+
+
+def update_department(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    id = kwargs.get("id")
+    need_params.extend(["name","pid","permissions"])
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    if kwargs.get("pid"):
+        cvals["pid"] = kwargs.get("pid")
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    try:
+        cm.Department.objects.filter(id=id).update(**cvals)
+    except Exception as e:
+        raise c.TipException(str(e))
+
+def delete_department(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    cm.Department.objects.filter(id__in=ids).update(status=0)
+
+
+def get_department_list(request):
+    """
+    """
+    kwargs = request.json
+    eset = cm.Department.objects.filter(status=1)
+    if "name" in kwargs and kwargs.get("name"):
+        eset = eset.filter(name__icontains=kwargs.get("name"))
+    total = eset.count()
+    edata = list(eset.values())
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+    total,data = ccf.get_page_list(edata,page,page_size)
+    return (total,data)
+
+    
+
+
+
+

BIN
src/api/control_department.pyc


+ 129 - 0
src/api/control_organization.py

@@ -0,0 +1,129 @@
+#coding=utf-8
+'''
+'''
+import json
+from django.db.models import Q
+from django.db import transaction
+import common.models as cm
+import common.common_functions as ccf
+import common.common_control as ccc
+import common.error_info as ce
+
+
+def search_organization(name):
+    """
+    """
+    qset = cm.Organization.objects.filter(name__icontains=name)
+    qdata = list(qset.values_list("name",flat=True))
+    return qdata
+
+def get_organization_tree(uid):
+    """
+    """
+    user = cm.UserInfo.objects.filter(pk=uid).first()
+    if not user:
+        raise ce.TipException(u"用户不存在")
+    uid = user.pk
+
+    total,users_info = ccc.get_sub_users(uid)
+    print users_info
+    user_ids = [x["id"] for x in users_info]
+    permissions = list(user.role.permission.all().values_list("codename",flat=True))
+
+    if user.role.platform == "portal":
+        #数据权限下用户所在的企业
+        org_ids = list(cm.UserInfo.objects.filter(id__in=user_ids).values_list("organization_id",flat=True))
+        #数据权限下的用户创建的企业
+        for uid in user_ids:
+            _user = cm.UserInfo.objects.filter(id=uid).first()
+            if "SystemManagement.Organization.Check" in permissions:
+                org_ids_created = list(cm.Organization.objects.filter(cid__in=[uid]).values_list("id",flat=True))
+                org_ids.extend(org_ids_created)
+        #orgs = cm.Organization.objects.filter(id__in=org_ids)
+        orgs = cm.Organization.objects.filter(id__in=org_ids,cid=uid).exclude(pid__in=org_ids)
+    else:
+        print 6666666666666666
+        orgs = cm.Organization.objects.filter(cid__in=user_ids)
+
+    org_ids = list(orgs.values_list("id",flat=True))
+    print org_ids,9999
+    #组装树结构
+    trees = []
+    for org in orgs:
+        if user.role.platform == "portal":
+            trees.append(ccc.get_sub_organization_tree(org.id))
+        else:
+            if not org.pid:
+                trees.append(ccc.get_sub_organization_tree(org.id))
+
+    otree = [
+        {
+            "id":1,
+            "nodes":[
+                {
+                    "id":2,
+                    "nodes":[
+                    
+                    ],
+                    "tree_label":u"成都代理运营中心"
+                } 
+            ],
+            "tree_label":u"成都运营中心"
+        } 
+    ]
+    return trees
+
+
+def add_organization(**kwargs):
+    """
+    """
+    need_params = ["name","sname"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    need_params.extend(["pid","cid","cperson","desc"])
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    with transaction.atomic():
+        oobj = cm.Organization.objects.create(**cvals)
+
+
+def update_organization(**kwargs):
+    """
+    """
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    id = kwargs.get("id")
+    uvals = {}
+    if "name" in kwargs:
+        uvals["name"] = kwargs.get("name")
+    if "sname" in kwargs:
+        uvals["sname"] = kwargs.get("sname")
+    if "desc" in kwargs:
+        uvals["desc"] = kwargs.get("desc")
+
+    with transaction.atomic():
+        oobj = cm.Organization.objects.filter(id=id).update(**uvals)
+
+
+def delete_organization(**kwargs):
+    """
+    """
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    cm.Organization.objects.filter(id__in=ids).delete()
+    
+    #级联删除相关联数据待完善...
+
+
+def get_organization_info(*ids):
+    """
+    """
+    qset = cm.Organization.objects.filter(id__in=ids)
+    oinfo = list(qset.values("id","name","sname","desc","pid"))
+    return oinfo
+

BIN
src/api/control_organization.pyc


+ 36 - 0
src/api/control_permission.py

@@ -0,0 +1,36 @@
+#-*-coding:utf-8 -*-
+import re
+import collections
+import common.models as cm
+
+def get_permission_list(role_id=None,platform=None):
+    """
+    """
+    if role_id:
+        qset = cm.Role.objects.filter(id=role_id).first().permission.all()
+    else:
+        qset = cm.Permission.objects.all()
+    if platform:
+        qset = qset.filter(platform__icontains=platform)
+    permissions = format_permission_tree(qset)
+    return permissions
+
+def get_permission_tree(pobj,data=None):
+    data = data if data else []
+    childrenset = cm.Permission.objects.filter(pid=pobj.id)
+    for cdobj in childrenset:
+        data.append({"id":cdobj.id,"name":cdobj.name,"codename":cdobj.codename,"children":get_permission_tree(cdobj)})
+    return data
+
+
+def format_permission_tree(qset):
+    """暂时写死待完善....
+    """
+    ptrees = []
+    toppers = qset.filter(pid__isnull=True)
+    for topobj in toppers:
+        ptree = {"id":topobj.id,"name":topobj.name,"codename":topobj.codename}
+        ptree["children"] = get_permission_tree(topobj)
+        ptrees.append(ptree)
+    return ptrees
+

BIN
src/api/control_permission.pyc


+ 106 - 0
src/api/control_role.py

@@ -0,0 +1,106 @@
+#coding=utf-8
+'''
+'''
+import json
+from django.db import transaction
+import common.models as cm
+import common.error_info as ce
+import common.common_functions as ccf
+import common.common_control as ccc
+
+def get_role_list(query=None,relations=None,page=None,page_size=None):
+    """
+    """
+    qset = cm.Role.objects.all()
+    if query and query.get("platform"):
+        qset = qset.filter(platform=query.get("platform"))
+    total,qset = ccc.get_page_qset(qset,page,page_size)
+    roles = qset.values("id","name","desc","ctime","platform")
+    if relations:
+        for i,role in enumerate(roles):
+            permissions = list(qset[i].permission.all().values_list("name",flat=True))
+            role.update({"permissions":",".join(permissions)})
+    return total,list(roles)
+
+
+def get_role_info(*ids):
+    """
+    """
+    qset = cm.Role.objects.filter(id__in=ids)
+    roles = list(qset.values())
+    for i,role in enumerate(roles):
+        role["permission_addroles"] = json.loads(role["permission_addroles"])
+        permissions = list(qset[i].permission.all().values("name","id"))
+        role.update({"permissions":permissions})
+    return roles
+
+
+def get_all_role_list():
+    qset = cm.Role.objects.all()
+    roles = qset.values("id","name","desc","ctime","platform")
+    return list(roles)
+
+
+def add_role(**kwargs):
+    """
+    """
+    need_params = ["name","platform","permissions"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    need_params.extend(["cperson","desc"])
+    try:
+        permission_addroles = kwargs.pop("permission_addroles")
+        permissions = kwargs.pop("permissions")
+    except KeyError:
+        permission_addroles = None
+        permissions = None
+
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    with transaction.atomic():
+        robj = cm.Role.objects.create(**cvals)
+        #添加permission
+        robj.permission_addroles = json.dumps(permission_addroles)
+        robj.permission.add(*permissions)
+        robj.save()
+
+
+def update_role(**kwargs):
+    """
+    """
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    id = kwargs.get("id")
+    uvals = {}
+    if "name" in kwargs:
+        uvals["name"] = kwargs.get("name")
+    if "desc" in kwargs:
+        uvals["desc"] = kwargs.get("desc")
+    if "permission_addroles" in kwargs:
+        uvals["permission_addroles"] = json.dumps(kwargs.get("permission_addroles"))
+    with transaction.atomic():
+        robj = cm.Role.objects.filter(id=id).first()
+        cm.Role.objects.filter(id=id).update(**uvals)
+        if robj:
+            robj.permission.remove()
+            robj.permission.add(*kwargs.get("permissions"))
+
+
+def delete_role(**kwargs):
+    """
+    """
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    cm.Role.objects.filter(id__in=ids).delete()
+
+
+
+
+
+
+

BIN
src/api/control_role.pyc


+ 240 - 0
src/api/control_user.py

@@ -0,0 +1,240 @@
+#coding=utf-8
+'''
+'''
+import json
+import datetime
+import logging
+import re
+import time
+import random
+
+import hashlib
+import xlrd
+from django.core.cache import cache
+from django.db.models import Q
+from django.db.models import Sum
+from django.db import transaction
+from django.contrib import auth
+import common.models as cm
+import common.error_info as ce
+import password_handle as ph
+import common.common_functions as ccf
+from utils.aestool import aescbc
+
+def add_user(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["realname","phone","department_id","utype","is_active"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    if cm.UserInfo.objects.filter(phone=kwargs.get("phone")).exists():
+        raise ce.TipException(u"该用户已存在!")
+    need_params.extend(["email","remark"])
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    cvals.update({"name":cvals.get("phone")})
+    cvals.update({"password":ph.make_password(cvals.get("phone")[-6:],True)})
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    obj = cm.UserInfo.objects.create(**cvals)
+    return obj
+
+
+def delete_user(request):
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    cm.UserInfo.objects.filter(id__in=ids).update(status=0)
+
+
+def update_user(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    id = kwargs.get("id")
+    if cm.UserInfo.objects.exclude(id=id).filter(phone=kwargs.get("phone")).exists():
+        raise ce.TipException(u"该用户已存在!")
+    need_params.extend(["realname","phone","department_id","utype","is_active","email","remark"])
+    cvals = ccf.get_need_params(*need_params,**kwargs)
+    cvals.update({"name":cvals.get("phone")})
+    cvals.update({"password":ph.make_password(cvals.get("phone")[-6:],True)})
+    cvals["cid"] = request.user.id
+    cvals["cperson"] = request.user.realname
+    obj = cm.UserInfo.objects.filter(id=id).update(**cvals)
+    return obj
+
+def login_user(request):
+    """
+    """
+    info = request.json
+    username = info.get('username')
+    password = info.get('password')
+    captcha_id = info.get('captcha_id')
+    idcode = info.get('idcode')
+    captcha = cache.get(captcha_id, '')
+    cache.delete(captcha_id)
+    if not username or not password:
+        raise ce.TipException(u"账户或密码不能为空!")
+    #if not idcode:
+    #    raise ce.TipException(u"验证码不能为空!")
+    #if idcode.upper() != captcha.upper():
+    #    raise ce.TipException(u"验证码错误!")
+
+    user = cm.UserInfo.objects.filter(name=username).first()
+    if user:
+        if user.password != ccf.make_password(password):
+            raise ce.TipException(u"账号或密码错误!")
+        tstr = "{}_{}{}".format(user.id,time.time(),random.randint(100000,999999))
+        token = aescbc.encrypt(tstr)
+        return {"id":user.id,"token":token}
+    else:
+        raise ce.TipException(u"账号或密码错误!")
+
+
+def reset_password(request):
+    """
+    @attention: 重置密码
+    """
+    qdata = request.json
+    need_params = ["password","repassword","phone","phcode"]
+    mse = ccf.check_params(*need_params,**qdata)
+    if mse:
+        raise ce.TipException(mse)
+    uid = request.json.get("uid")
+    if not uid:
+        uid = request.user.id
+    phone = qdata.get("phone")
+    password = qdata.get("password")
+    repassword = qdata.get("repassword")
+    if password != repassword:
+        raise ce.TipException(u"两次输入的密码不一致!")
+    pwd = ph.make_password(password)
+    cm.UserInfo.objects.filter(phone=phone).update(password=pwd)
+
+
+def reset_user_password(request):
+    qdata = request.json
+    need_params = ["uid","code","password"]
+    mse = ccf.check_params(*need_params,**qdata)
+    if mse:
+        raise ce.TipException(mse)
+    upk = qdata.get("uid")
+    code = qdata.get("code")
+    pkey = request.user.phone
+    if cache.get(pkey,"") != code:
+        raise ce.TipException(u"验证码不正确!")
+    newpwd = qdata.get("password")
+    pwd = ph.make_password(newpwd)
+    cm.UserInfo.objects.filter(pk=upk).update(password=pwd)
+
+
+def regist_user(request):
+    """
+    """
+    kwargs = request.json
+    need_parms = ["realname","password","repassword","phone","email"]
+    mse = ccf.check_params(*need_parms,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    if cm.UserInfo.objects.filter(phone=kwargs.get("phone")).exists():
+        raise ce.TipException(u"该手机号已注册!")
+    cvals = ccf.get_need_params(*need_parms,**kwargs)
+    cvals.pop("repassword")
+    cvals["name"] = cvals["phone"]
+    if kwargs["password"] != kwargs["repassword"]:
+        raise ce.TipException(u"前后输入的密码不一致!")
+    if not cvals.get("password"):
+        pwd,password = ph.make_default_password(None)
+        cvals.update({"password":password})
+    else:
+        pwd = cvals.get("password")
+        cvals.update({"password":ph.make_password(cvals.get("password"))})
+    uobj = cm.UserInfo.objects.create(**cvals)
+    return None
+
+
+def format_user(*ids):
+    """
+    """
+    eset = cm.UserInfo.objects.filter(id__in=ids,status=1)
+    if not eset.exists():
+        raise ce.TipException(u"客户不存在!")
+    data = list(eset.values())
+    return data
+
+def get_user_info(request):
+    """
+    """
+    kwargs = request.json
+    need_params = ["id"]
+    mse = ccf.check_params(*need_params,**kwargs)
+    if mse:
+        raise ce.TipException(mse)
+    ids = str(kwargs.get("id")).split(",")
+    info = format_user(*ids)
+    info = info[0] if info else {}
+    return info
+
+def get_user_personal_info(request):
+    """
+    """
+    id = request.user.id
+    info = format_user(*[id])
+    info = info[0] if info else {}
+    return info
+
+def get_account_info(request):
+    """
+    """
+    id = request.user.id
+    print id,99999
+    info = format_user(*[id])
+    info = info[0] if info else {}
+    info["p"] = ["Product.*.*"]
+    return info
+
+def get_user_list(request):
+    """
+    """
+    kwargs = request.json
+    eset = cm.UserInfo.objects.filter(status=1)
+    if "name" in kwargs and kwargs.get("name"):
+        eset = eset.filter(name__icontains=kwargs.get("name"))
+    if "department_id" in kwargs and kwargs.get("department_id"):
+        eset = eset.filter(department_id=kwargs.get("department_id"))
+    if "utype" in kwargs and kwargs.get("utype"):
+        eset = eset.filter(utype=kwargs.get("utype"))
+    if "is_active" in kwargs and kwargs.get("is_active"):
+        eset = eset.filter(is_active=kwargs.get("is_active"))
+    total = eset.count()
+    edata = list(eset.values())
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+    total,data = ccf.get_page_list(edata,page,page_size)
+    return (total,data)
+
+
+def get_unaudit_user_list(request):
+    """
+    """
+    kwargs = request.json
+    eset = cm.UserInfo.objects.filter(status=1,is_active=0)
+    if "name" in kwargs and kwargs.get("name"):
+        eset = eset.filter(name__icontains=kwargs.get("name"))
+    if "utype" in kwargs and kwargs.get("utype"):
+        eset = eset.filter(utype=kwargs.get("utype"))
+    total = eset.count()
+    edata = list(eset.values())
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+    total,data = ccf.get_page_list(edata,page,page_size)
+    return (total,data)
+

BIN
src/api/control_user.pyc


+ 626 - 0
src/api/controls.py

@@ -0,0 +1,626 @@
+#coding=utf-8
+'''
+'''
+import random
+import os,re
+import json,time,datetime
+import shutil
+import tempfile
+import zipfile
+from docxtpl import DocxTemplate,InlineImage
+from docx.shared import Mm
+from django.db import transaction
+from django.conf import settings
+import common.models as cm
+import common.error_info as ce
+import common.common_functions as ccf
+import common.common_control as ccc
+from utils.exceltool import ExcelTool
+from utils.exceltool import ExcelTool
+from utils.aestool import aescbc
+from django.db.models import Q
+from PIL import Image
+from PIL import Image,ImageDraw,ImageFont
+from utils.jgpush import send_notification_by_registration_ids
+import string
+
+import xlrd
+import xlwt
+from xlutils.copy import copy
+from xltpl.writer import BookWriter
+from utils.qrcodetool import gen_cus_qrcode_img
+from utils.upload_to_oss import TedOSS
+
+
+
+def add_model(cls,**kwargs):
+    """
+    """
+    model_name = re.search(r'.*\.(\w+)View',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    obj = model.objects.create(**kwargs)
+    return obj.id
+
+def update_model(cls,**kwargs):
+    """
+    """
+    model_name = re.search(r'.*\.(\w+)View',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    id = kwargs.pop("id")
+    rst = model.objects.filter(id=id).update(**kwargs)
+    return rst
+
+def delete_model(cls,**kwargs):
+    """
+    """
+    model_name = re.search(r'.*\.(\w+)View',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    ids = str(kwargs.get("id")).split(",")
+    rst = model.objects.filter(id__in=ids).delete()
+    return ids
+
+def get_model_detail_info(cls,**kwargs):
+    """
+    """
+    model_name = re.search(r'.*\.(\w+)View',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    id = kwargs.get("id")
+    rst = list(model.objects.filter(id=id).values())
+    rst = rst[0] if rst else {}
+    if model_name == "Hotel":
+        rooms = list(cm.Room.objects.filter(hotel_id=id).values())
+        for r in rooms:
+            print r["imgs"],11111111111111
+            img = json.loads(r["imgs"])[0] if r["imgs"] else ""
+            r["img"] = img
+        rst["rooms"] = rooms
+    return rst
+
+def get_list_info(cls,**kwargs):
+    """
+    """
+    model_name = re.search(r'.*\.(\w+)ListView',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    qset = model.objects.all()
+    if kwargs.get("name"):
+        qset = qset.filter(name__icontains=kwargs.get("name"))
+    data = list(qset.values())
+    if model_name == "Conference":
+        for item in data:
+            item["conference_img"] = cm.Conference.objects.filter(id=item["conference_id"]).first().img
+    if model_name == "Signup":
+        for item in data:
+            item["conference_img"] = cm.Conference.objects.filter(id=item["conference_id"]).first().img
+    if model_name == "Hotel":
+        for item in data:
+            pass
+            #imgs = json.loads(item["imgs"]) if item["imgs"] else []
+            #item["img"] = imgs[0] if imgs else ""
+    page = int(kwargs.get("page",0))
+    page_size = int(kwargs.get("page_size",20))
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+        return (total,data)
+    else:
+        return len(data),data
+
+    return rst
+
+
+def login_user(request):
+    """
+    """
+    info = request.json
+    username = info.get('username')
+    password = info.get('password')
+    registration_id = info.get('registration_id')
+    if not username or not password:
+        raise ce.TipException(u"账户或密码不能为空!")
+
+    user = cm.StaffUser.objects.filter(username=username).first()
+    if user:
+        if registration_id:
+            user.registration_id = registration_id
+            user.save()
+        if user.password != ccf.make_password(password):
+            raise ce.TipException(u"账号或密码错误!")
+        tstr = "{}_{}_{}{}".format(user.id,3,time.time(),random.randint(100000,999999))
+        token = aescbc.encrypt(tstr)
+        if user.utype == u"岗位级":
+            return {"id":user.id,"token":token,"utype":3,"role":1}
+        if user.utype == u"部门级":
+            return {"id":user.id,"token":token,"utype":3,"role":2}
+        if user.utype == u"公司级":
+            return {"id":user.id,"token":token,"utype":3,"role":3}
+        
+    else:
+        user = cm.Goverment.objects.filter(username=username).first()
+        if user:
+            if user.password != ccf.make_password(password):
+                raise ce.TipException(u"账号或密码错误!")
+            tstr = "{}_{}_{}{}".format(user.id,1,time.time(),random.randint(100000,999999))
+            token = aescbc.encrypt(tstr)
+            return {"id":user.id,"token":token,"utype":1}
+        else:
+            user = cm.EnterPrise.objects.filter(username=username).first()
+            if user:
+                if user.password != ccf.make_password(password):
+                    raise ce.TipException(u"账号或密码错误!")
+                tstr = "{}_{}_{}{}".format(user.id,2,time.time(),random.randint(100000,999999))
+                token = aescbc.encrypt(tstr)
+                return {"id":user.id,"token":token,"utype":2}
+
+            raise ce.TipException(u"账号或密码错误!")
+
+def get_index_banners(request):
+    """首页banner
+    """
+    ret = {}
+    ret["banners"] = list(cm.Banners.objects.values())
+    return ret
+
+def get_index_journals(request):
+    """首页全刊数据
+    """
+    ret = []
+    capts = string.ascii_uppercase 
+    for c in capts:
+        journals = list(cm.Journal.objects.all().order_by("-ctime").values(
+            "name","img","wxcode","publishingUnit","editor","ename","id"))
+        #ret["journals"] = journals
+        journals = list(filter(lambda x:x["ename"].startswith(c),journals))
+        if journals:
+            ret.append({"lower":c.lower(),"name":c,"journals":journals})
+    return ret
+
+def get_index_organizers(request):
+    """首页主办单位
+    """
+    ret = {}
+    qdata = request.json
+    qset = cm.Organizer.objects.all().order_by("-order")
+    #分页                                                                           
+    page = qdata.get("page",1)                                                      
+    page_size = qdata.get("page_size",20)                                           
+    total,qset = ccc.get_page_qset(qset,page,page_size) 
+
+    data = list(qset.values()) 
+    for d in data:
+        journal_ids = list(cm.JournalOrganizer.objects.filter(organizer_id=d["id"]).values_list("journal_id",flat=True))
+        journals = list(cm.Journal.objects.filter(id__in=journal_ids)[:3].values("id","name","desc"))
+        d["journals"] = journals
+        d["total_journal"] = len(journals)
+        if d["order"] > 0:
+            d["istop"] = 1
+        else:
+            d["istop"] = 0
+    return {"total":total,"list":data}
+
+def get_index_subjects(request):
+    """首页领域期刊
+    """
+    ret = {}
+    qdata = request.json
+    qset = cm.Subject.objects.all().order_by("-ctime")
+    #分页                                                                           
+    page = qdata.get("page",1)                                                      
+    page_size = qdata.get("page_size",20)                                           
+    total,qset = ccc.get_page_qset(qset,page,page_size) 
+
+    data = list(qset.values()) 
+    for d in data:
+        d["total_journal"] = cm.Journal.objects.filter(subject_id=d["id"]).count()
+        d["journals"] = list(cm.Journal.objects.filter(subject_id=d["id"]).values())
+        if d["order"] > 0:
+            d["istop"] = 1
+        else:
+            d["istop"] = 0
+    return {"total":total,"list":data}
+
+
+def get_article_list(request):
+    """获取文章列表
+    """
+    qdata = request.json
+    qset = cm.Article.objects.all().order_by("-ctime")
+    if qdata.get("keyword"):
+        keyword = qdata.get("keyword")
+        qset = qset.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+    if qdata.get("order_by"):
+        qset = qset.order_by("%s" % qdata.get("order_by"))
+    #分页                                                                           
+    page = qdata.get("page",1)                                                      
+    page_size = qdata.get("page_size",20)                                           
+    total,qset = ccc.get_page_qset(qset,page,page_size) 
+
+    data = list(qset.values("id","name","img","author","desc","publish_time")) 
+    return {"total":total,"list":data}
+
+def get_journals_list(request):
+    """获取期刊列表
+    """
+    qdata = request.json
+    qset = cm.Journal.objects.all().order_by("-ctime")
+    if qdata.get("keyword"):
+        keyword = qdata.get("keyword")
+        qset = qset.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+    if qdata.get("subject_id"):
+        qset = qset.filter(subject_id=qdata.get("subject_id"))
+    #分页                                                                           
+    page = qdata.get("page",1)                                                      
+    page_size = qdata.get("page_size",20)                                           
+    total,qset = ccc.get_page_qset(qset,page,page_size) 
+
+    data = list(qset.values("id","name","img","editor","desc","wxcode")) 
+    for item in data:
+        organizers_ids = list(cm.JournalOrganizer.objects.filter(journal_id=item["id"]).values_list("organizer_id",flat=True))
+        organizers = list(cm.Organizer.objects.filter(id__in=organizers_ids).values_list("name",flat=True))
+        item["organizers"] = ",".join(organizers)
+    return {"total":total,"list":data}
+
+def get_activity_list(request):
+    """获取活动列表
+    """
+    qdata = request.json
+    qset = cm.Activity.objects.all().order_by("-ctime")
+    if qdata.get("keyword"):
+        keyword = qdata.get("keyword")
+        qset = qset.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+    if qdata.get("order_by"):
+        qset = qset.order_by("%s" % qdata.get("order_by"))
+    if qdata.get("type"):
+        now_time = datetime.datetime.now()
+        if qdata.get("type") == "pre":
+            cm.Activity.objects.filter(begin_time__gte=now_time)
+        else:
+            cm.Activity.objects.filter(end_time__lte=now_time)
+    #分页                                                                           
+    page = qdata.get("page",1)                                                      
+    page_size = qdata.get("page_size",20)                                           
+    total,qset = ccc.get_page_qset(qset,page,page_size) 
+
+    data = list(qset.values("id","name","img","desc","begin_time","journal_id","speaker")) 
+    for item in data:
+        item["publish_unit"] = u"测试发布单位"
+        if item["speaker"]:
+            item["speaker"] = ",".join([x["name"] for x in json.loads(item["speaker"])])
+    return {"total":total,"list":data}
+
+
+def get_search_default(request):
+    """获取搜索页默认数据
+    """
+    navs = [
+        {"name":u"主办单位","value":"organizer"}, 
+        {"name":u"文章","value":"article"}, 
+        {"name":u"学术会议","value":"conference"}, 
+        {"name":u"期刊","value":"journal"}, 
+        {"name":u"学科","value":"subject"} 
+    ]
+    history = ["光电","物理","中国","成都"]
+    cold_keyword = ["物理","国际"]
+    hot_keyword = ["中国","地理","成都","国际","学院"]
+
+    return {"navs":navs,"history":history,"cold_keyword":cold_keyword,"hot_keyword":hot_keyword}
+
+
+def search(request):
+    """搜索
+    """
+    ret = []
+    qdata = request.json
+    if qdata.get("type"):
+        _type = qdata.get("type")
+        if _type == "organizer":
+            qset = cm.Organizer.objects.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+            data = list(qset.values("id","name","img","desc"))
+            ret.append({"name":u"相关主办方","value":"organizer","list":data})
+        if _type == "article":
+            qset = cm.Article.objects.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+            data = list(qset.values("id","name","img","desc"))
+            ret.append({"name":u"相关文章","value":"article","list":data})
+        if _type == "conference":
+            qset = cm.Conference.objects.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+            data = list(qset.values("id","name","img","desc"))
+            ret.append({"name":u"相关学术会议","value":"conference","list":data})
+        if _type == "journal":
+            qset = cm.Journal.objects.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+            data = list(qset.values("id","name","img","desc"))
+            ret.append({"name":u"相关期刊","value":"journal","list":data})
+        if _type == "subject":
+            qset = cm.Subject.objects.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+            data = list(qset.values("id","name","desc"))
+            ret.append({"name":u"相关学科","value":"subject","list":data})
+    else:
+        keyword = qdata.get("keyword")
+        #主办单位
+        orgset = cm.Organizer.objects.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+        orgdata = list(orgset.values("id","name","img","desc"))
+        ret.append({"name":u"相关主办方","value":"organizer","list":orgdata})
+        #文章
+        artset = cm.Article.objects.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+        artdata = list(orgset.values("id","name","img","desc"))
+        ret.append({"name":u"相关文章","value":"article","list":artdata})
+        #会议
+        conset = cm.Conference.objects.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+        condata = list(conset.values("id","name","img","desc"))
+        ret.append({"name":u"相关学术会议","value":"conference","list":condata})
+        #期刊
+        jourset = cm.Journal.objects.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+        jourdata = list(conset.values("id","name","img","desc"))
+        ret.append({"name":u"相关期刊","value":"journal","list":jourdata})
+        #学科
+        subset = cm.Subject.objects.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+        subdata = list(subset.values("id","name","desc"))
+        ret.append({"name":u"相关学科","value":"subject","list":subdata})
+
+    return ret
+
+
+def recommend(request):
+    """推荐
+    """
+    ret = {}
+    #活动推荐
+    artset = cm.Activity.objects.all().order_by("-id")
+    data = list(artset.values("id","name","img","desc","begin_time","speaker"))
+    for item in data:
+        item["publish_unit"] = u"测试发布单位"
+        if item["speaker"]:
+            item["speaker"] = ",".join([x["name"] for x in json.loads(item["speaker"])])
+    ret["article"] = data
+    #热门活动
+    artset = cm.Conference.objects.all().order_by("-id")[:3]
+    act = list(artset.values("id","name","img","desc","begin_time","organizer_id"))
+    for item in act:
+        item["organizer_name"] = cm.Organizer.objects.filter(id=item["organizer_id"]).first().name
+    ret["hot_act"] = act
+    #活动预告
+    artset = cm.Activity.objects.all().order_by("-id")[:3]
+    act = list(artset.values("id","name","img","desc","begin_time","speaker"))
+    for item in act:
+        item["publish_unit"] = u"测试发布单位"
+        if item["speaker"]:
+            item["speaker"] = ",".join([x["name"] for x in json.loads(item["speaker"])])
+    ret["pre_act"] = act
+    #活动回顾
+    artset = cm.Activity.objects.all().order_by("-id")[:3]
+    act = list(artset.values("id","name","img","desc","begin_time","speaker"))
+    for item in act:
+        item["publish_unit"] = u"测试发布单位"
+        if item["speaker"]:
+            item["speaker"] = ",".join([x["name"] for x in json.loads(item["speaker"])])
+    ret["over_act"] = act
+    return ret
+
+
+def get_conference_list(request):
+    """获取会议列表
+    """
+    qdata = request.json
+    qset = cm.Conference.objects.all().order_by("-ctime")
+    if qdata.get("keyword"):
+        keyword = qdata.get("keyword")
+        qset = qset.filter(Q(name__icontains=keyword)|Q(desc__icontains=keyword))
+    if qdata.get("order_by"):
+        qset = qset.order_by("%s" % qdata.get("order_by"))
+    #分页                                                                           
+    page = qdata.get("page",1)                                                      
+    page_size = qdata.get("page_size",20)                                           
+    total,qset = ccc.get_page_qset(qset,page,page_size) 
+
+    data = list(qset.values("id","name","img","desc","begin_time","organizer_id")) 
+    for item in data:
+        item["organizer_name"] = cm.Organizer.objects.filter(id=item["organizer_id"]).first().name
+    return {"total":total,"list":data}
+
+
+def get_detail_info(request):
+    """
+    """
+    ret = {}
+    qdata = request.json
+    _id = qdata.get("id")
+    _type = qdata.get("type")
+    uid = qdata.get("uid")
+    print _id,_type,uid
+    if _type == "organizer":
+        qset = cm.Organizer.objects.filter(id=_id)
+        data = list(qset.values())
+        ret = data[0] if data else {}
+    if _type == "article":
+        qset = cm.Article.objects.filter(id=_id)
+        data = list(qset.values())
+        ret = data[0] if data else {}
+        if cm.Collection.objects.filter(target_id=_id,target_type=_type,user_id=uid):
+            ret["is_collected"] = 1
+        else:
+            ret["is_collected"] = 0
+        ret["journal_name"] = cm.Journal.objects.filter(id=ret["journal_id"]).first().name
+    if _type == "conference":
+        qset = cm.Conference.objects.filter(id=_id)
+        data = list(qset.values())
+        ret = data[0] if data else {}
+        ret["organizer_info"] = cm.Organizer.objects.filter(id=ret["organizer_id"]).values("name","desc").first()
+        if ret["is_signup"]:
+            ret["signup_fields"] = json.loads(ret["signup_fields"])
+        if ret["speaker"]:
+            ret["speaker"] = ",".join([x["name"] for x in json.loads(ret["speaker"])])
+        if cm.Collection.objects.filter(target_id=_id,target_type=_type,user_id=uid):
+            ret["is_collected"] = 1
+        else:
+            ret["is_collected"] = 0
+    if _type == "journal":
+        qset = cm.Journal.objects.filter(id=_id)
+        data = list(qset.values())
+        ret = data[0] if data else {}
+        ret["articles"] = list(cm.Article.objects.filter(journal_id=_id)[:3].values())
+        #活动预告
+        now_time = datetime.datetime.now()
+        pre_activitys = list(cm.Activity.objects.filter(journal_id=_id,begin_time__gte=now_time)[:3].values())
+        #活动回顾
+        over_activitys = list(cm.Activity.objects.filter(journal_id=_id,end_time__lte=now_time)[:3].values())
+        for item in pre_activitys:
+            item["publish_unit"] = u"测试发布单位"
+            if item["speaker"]:
+                item["speaker"] = ",".join([x["name"] for x in json.loads(item["speaker"])])
+        for item in over_activitys:
+            item["publish_unit"] = u"测试发布单位"
+            if item["speaker"]:
+                item["speaker"] = ",".join([x["name"] for x in json.loads(item["speaker"])])
+        ret["pre_activitys"] = pre_activitys
+        ret["over_activitys"] = over_activitys
+    if _type == "activity":
+        qset = cm.Activity.objects.filter(id=_id)
+        data = list(qset.values())
+        ret = data[0] if data else {}
+        ret["publish_unit"] = u"测试发布单位"
+        ret["hold_unit"] = u"主办方"
+        ret["assist_unit"] = u"测试协办单位"
+        if ret["speaker"]:
+            ret["speaker"] = ",".join([x["name"] for x in json.loads(ret["speaker"])])
+    if _type == "subject":
+        qset = cm.Subject.objects.filter(id=_id)
+        data = list(qset.values())
+        ret = data[0] if data else {}
+
+    return ret
+
+
+def collect(request):
+    """收藏
+    """
+    qdata = request.json
+    #uid = request.user.id
+    uid = qdata.get("uid")
+    _id = qdata.get("id")
+    _type = qdata.get("type")
+    action= qdata.get("action")
+    if action == "cancel":
+        cm.Collection.objects.filter(target_id=_id,target_type=_type).delete()
+    else:
+        cm.Collection.objects.create(**{
+            "target_id":_id,"target_type":_type,"user_id":uid})
+
+    return True
+
+
+def index_totop(request):
+    """首页单位和领域置顶操作
+    """
+    qdata = request.json
+    _id = qdata.get("id")
+    _type = qdata.get("type")
+    action = qdata.get("action")
+    if _type == "cancel":
+        if _type == "organizer":
+            cm.Organizer.objects.filter(id=_id).update(order=0)
+        if _type == "subject":
+            cm.Subject.objects.filter(id=_id).update(order=0)
+    else:
+        if _type == "organizer":
+            max = cm.Organizer.objects.all().order_by("-order").first().order
+            cm.Organizer.objects.filter(id=_id).update(order=max+1)
+        if _type == "subject":
+            cm.Subject.objects.filter(id=_id).update(order=0)
+            max = cm.Subject.objects.all().order_by("-order").first().order
+            cm.Subject.objects.filter(id=_id).update(order=max+1)
+
+
+def get_user_collection(request):
+    """获取用户收藏
+    """
+    qdata = request.json
+    uid = qdata.get("uid")
+    qset = cm.Collection.objects.filter(user_id=uid)
+    #分页                                                                           
+    page = qdata.get("page",1)                                                      
+    page_size = qdata.get("page_size",20)                                           
+    total,qset = ccc.get_page_qset(qset,page,page_size) 
+
+    data = list(qset.values())
+    for item in data:
+        _id = item["target_id"]
+        if item["target_type"] == "article":
+            article = cm.Article.objects.filter(id=_id).values("id","name","img","author","publish_time","desc").first()
+            item.update(article)
+        else:
+            article = cm.Conference.objects.filter(id=_id).values("id","name","img","address","begin_time","desc").first()
+            item.update(article)
+
+    return {"total":total,"list":data}
+
+
+
+def do_signup(request):
+    """
+    """
+    qdata = request.json
+    need_params = ["conference_id","conference_name","name","sex","age","job",
+        "title","is_caos","organizer_unit","phone","email"]
+    vals = ccf.get_need_params(*need_params,**qdata)
+    vals["user_id"] = qdata.get("uid") 
+    obj = cm.Signup.objects.create(**vals)
+    return obj.id
+
+
+def update_signup(request):
+    """
+    """
+    qdata = request.json
+    need_params = ["proof_img","paytype","billtype","billhead","billno",
+        "billaddress","billphone","billbank","billbankno","hotel_id","room_id",
+        "room_nums","room_stime","room_etime"]
+    vals = ccf.get_need_params(*need_params,**qdata)
+    id = qdata.get("id")
+    cm.Signup.objects.filter(id=id).update(**vals)
+    obj = cm.Signup.objects.filter(id=id).first()
+    if vals.get("proof_img") and vals.get("paytype"):
+        obj.signup_status = 1
+    if vals.get("hotel_id") and vals.get("room_id"):
+        obj.signup_status = 3
+        #生成核销二维码
+        url = settings.HOST+"/xcx/verify?sid=%s" % obj.id
+        imgname = gen_cus_qrcode_img(url,"/tmp/signup_%s.png" % obj.id)
+        oss = TedOSS()
+        verify_qrcode = oss.upload_from_local(imgname,"zky/signup_%s.png"%obj.id)
+        obj.verify_qrcode = verify_qrcode
+    obj.save()
+    return True
+
+
+def get_organiztion_list(request):
+    """
+    """
+    data = [
+        {
+            "name":u"成都分院",
+            "value":"成都分院",
+            "children":[
+                    {"name":u"成都光电研究所","value":u"成都光电研究所","children":[
+                    {"name":u"光学学报","value":u"光学学报","children":[]}
+                ]} ]} ,
+        {
+            "name":u"成都分院",
+            "value":"成都分院",
+            "children":[
+                    {"name":u"成都光电研究所","value":u"成都光电研究所","children":[
+                    {"name":u"光学学报","value":u"光学学报","children":[]}
+                ]} ]} 
+                
+            ]
+
+    return data
+
+
+def verify_signup(request):
+    """
+    """
+    qdata = request.json
+    need_params = ["sid","uid"]
+    vals = ccf.get_need_params(*need_params,**qdata)
+    id = qdata.get("sid")
+    obj = cm.Signup.objects.filter(id=id).update(signup_status=4)
+    return True
+
+

BIN
src/api/controls.pyc


+ 126 - 0
src/api/lock_account.py

@@ -0,0 +1,126 @@
+# coding:utf-8
+from django.core.cache import cache
+
+import common.error_info as cei
+
+MAX_ERROR_TIMES = 5
+MAX_ERROR_TIMES_IP = 20
+LOCK_IP_TMP = 'LOCK_IP_{}'
+LOCK_ACCOUNT_TMP = 'LOCK_ACCOUNT_{}'
+
+ACCOUNT_INCR_TMP = 'ACCOUNT_COUNT_{}'
+IP_INCR_TMP = 'IP_COUNT_{}'
+
+
+def is_lock(uid, ip):
+    """
+    是否锁
+    :param uid:
+    :param ip:
+    :return:
+    """
+    account_key = LOCK_ACCOUNT_TMP.format(uid)
+    ip_key = LOCK_IP_TMP.format(ip)
+
+    if cache.get(ip_key):
+        return "ip_lock"
+    if cache.get(account_key):
+        return "account_lock"
+    return False
+
+def is_lock_ip(ip):
+    """是否封禁IP
+    """
+    ip_key = LOCK_IP_TMP.format(ip)
+    if cache.get(ip_key):
+        return True
+    return False
+
+
+def increase_error_count(uid, ip):
+    """
+    5分钟内连续输错五次
+    :return:
+    """
+    ip_key = IP_INCR_TMP.format(ip)
+    ip_count = cache.get(ip_key) or 0
+
+    account_key = ACCOUNT_INCR_TMP.format(uid)
+    account_count = cache.get(account_key) or 0
+
+    if account_count + 1 >= MAX_ERROR_TIMES or ip_count + 1 >= MAX_ERROR_TIMES:
+        lock(uid, ip)
+        raise cei.TipException(u'密码连续输错五次,锁定ip和账户半个小时')
+    if not account_count:
+        cache.set(account_key, 1, 5*60)
+    else:
+        cache.incr(account_key)
+    if not ip_count:
+        cache.set(ip_count, 1, 5*60)
+    else:
+        cache.incr(ip_key)
+
+def increase_error_count_ip(ip):
+    """
+    """
+    ip_key = IP_INCR_TMP.format(ip)
+    ip_count = cache.get(ip_key) or 0
+    if ip_count + 1 >= MAX_ERROR_TIMES_IP:
+        lock(0,ip)
+        raise cei.TipException(u'密码连续输错20次,锁定ip半个小时!')
+    if not ip_count:
+        cache.set(ip_key, 1, 30*60)
+    else:
+        cache.incr(ip_key)
+
+def increase_error_count_uid(uid):
+    """
+    """
+    account_key = ACCOUNT_INCR_TMP.format(uid)
+    account_count = cache.get(account_key) or 0
+    if account_count + 1 >= MAX_ERROR_TIMES:
+        lock(uid,0)
+        raise cei.TipException(u'密码连续输错5次,锁定账户10分钟!')
+    if not account_count:
+        cache.set(account_key, 1, 10*60)
+    else:
+        cache.incr(account_key)
+
+
+
+def clear_lock_count(uid, ip):
+    """
+    清除计数,清楚锁ip,锁account的key
+    :param uid:
+    :param ip:
+    :return:
+    """
+    if uid:
+        cache.delete(ACCOUNT_INCR_TMP.format(uid))
+    if ip:
+        cache.delete(IP_INCR_TMP.format(ip))
+
+
+def lock(uid, ip):
+    """
+    锁账户,ip半个小时
+    :param uid:
+    :param ip:
+    :return:
+    """
+    clear_lock_count(uid, ip)
+    if uid:
+        key = LOCK_ACCOUNT_TMP.format(uid)
+        cache.set(key, 'lock_account', 10*60)
+    if ip:
+        key = LOCK_IP_TMP.format(ip)
+        cache.set(key, 'lock_ip', 30*60)
+
+def clear_lock(uid,ip):
+    clear_lock_count(uid, ip)
+    if uid:
+        key = LOCK_ACCOUNT_TMP.format(uid)
+        cache.delete(key)
+    if ip:
+        key = LOCK_IP_TMP.format(ip)
+        cache.delete(IP_INCR_TMP.format(ip))

BIN
src/api/lock_account.pyc


+ 6 - 0
src/api/models.py

@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models
+
+# Create your models here.

BIN
src/api/models.pyc


+ 37 - 0
src/api/password_handle.py

@@ -0,0 +1,37 @@
+#coding=utf-8
+'''
+@attention: 密码加密验证模块
+'''
+import hashlib
+import re
+import common.error_info as ceil
+import random
+
+def check_password(new,old):
+    """
+    """
+    np = hashlib.md5(new).hexdigest().upper()
+    return np==old
+
+def make_password(pwd,isdefault=None):
+    """
+    """
+    return hashlib.md5(pwd).hexdigest().upper()
+
+def make_default_password(pwd):
+    """
+    @attention: 密码加密
+    """
+    ustr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    lstr = "abcdefghjklmnopqrstuvwxyz"
+    dstr = "0123456789"
+    sstr = "!@#$%&*"
+    pwd = "".join(random.sample(ustr,3)+random.sample(lstr,3)+random.sample(dstr,3)+random.sample(sstr,3))
+    return pwd,hashlib.md5(pwd).hexdigest().upper()
+
+if __name__ == '__main__':
+    old = "root"
+    op = make_password(old)
+    print op
+    new = "123456"
+    # print check_password(new, op)

BIN
src/api/password_handle.pyc


+ 38 - 0
src/api/urls_backstage.py

@@ -0,0 +1,38 @@
+# coding=utf-8
+'''
+'''
+from django.conf.urls import url
+from api import views,views_backstage
+
+urlpatterns = [
+    url(r'^auth$', views.AuthView.as_view()),
+    url(r'^authinfo$', views.AuthinfoView.as_view()),
+    url(r'^openid$', views.OpenidView.as_view()),
+
+    url(r'^index/banners$', views.IndexBannersView.as_view()),
+    url(r'^index/journals$', views.IndexJournalsView.as_view()),
+    url(r'^index/organizers$', views.IndexOrganizersView.as_view()),
+    url(r'^index/subjects$', views.IndexSubjectsView.as_view()),
+    url(r'^index/totop$', views.IndexToTopView.as_view()),
+    url(r'^article/list$', views.ArticleListView.as_view()),
+    url(r'^journals/list$', views.JournalsListView.as_view()),
+    url(r'^search/default$', views.SearchDefaultView.as_view()),
+    url(r'^search$', views.SearchView.as_view()),
+    url(r'^recommend$', views.RecommendView.as_view()),
+    url(r'^conference/list$', views.ConferenceListView.as_view()),
+    url(r'^activity/list$', views.ActivityListView.as_view()),
+    url(r'^detail$', views.DetailView.as_view()),
+    url(r'^collect$', views.CollectView.as_view()),
+    url(r'^user/collection$', views.UserCollectionView.as_view()),
+    url(r'^user/signup$', views.UserSignupView.as_view()),
+    url(r'^user/signup/list$', views.SignupListView.as_view()),
+    url(r'^organization/list$', views.OrganizationListView.as_view()),
+    url(r'^signup/hotel/list$', views.HotelListView.as_view()),
+    url(r'^signup/hotel$', views.HotelView.as_view()),
+    url(r'^uploadfile$', views.UploadFileView.as_view()),
+    url(r'^signup/verify$', views.SignupVerifyView.as_view()),
+    url(r'^phcode$', views.GetPhoneCodeView.as_view()),
+
+
+]
+

BIN
src/api/urls_backstage.pyc


+ 886 - 0
src/api/views.py

@@ -0,0 +1,886 @@
+# coding=utf-8
+from __future__ import unicode_literals
+import requests
+import random
+import json
+import uuid
+from django.contrib import auth
+from django.core.cache import cache
+from django.conf import settings
+
+import common.error_info as ce
+from common import core_views as cv
+from common.captcha import create_idcode
+import controls as ctl
+import common.common_control as ccc
+import common.common_functions as ccf
+from utils.cloopen_sms import cloopensms
+import control_auth as ca
+from utils.aliyun_sms import send_sms
+
+APPID = "wx2938132b773c7b5a" 
+APPSECRET = "1707d86ef4d9894775ebac21d87390e6"
+
+class OpenidView(cv.BaseView):
+    def get(self,request):
+        """
+        #获取openid(小程序)
+        @code:1212
+        """
+        code = request.json.get("code")
+        open_id = cache.get(code)
+        if open_id:
+            return cv.to_suc({"openid":open_id})
+        else:
+            get_token_url = 'https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code' .format(APPID,APPSECRET,code)
+
+            res = requests.get(get_token_url).json()                                   
+            if res.has_key('openid'):                                                 
+                open_id = res['openid']                                               
+                cache.set(code,open_id,24*3600)
+            else:                                                                      
+                open_id = ''                                                           
+            if open_id:
+                return cv.to_suc({"openid":open_id})
+            else:
+                return cv.to_fail(u"获取用户信息出错!")
+
+
+class AuthView(cv.BaseView):
+    def post(self, request):
+        """#保存微信授权信息(小程序)
+        @nickname:"新",昵称
+        @avatar:"",头像
+        @openid:"",openid
+        """
+        try:
+            rst = ca.add_wxauth_info(request)
+            return cv.to_suc({"uid":rst.id})
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class AuthinfoView(cv.AuthView):
+    def get(self,request):
+        """#获取用户信息(小程序)
+        """
+        try:
+            rst = ca.get_wxauth_info(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def put(self, request):
+        """#修改个人信息(小程序)
+        """
+        try:
+            rst = ca.update_wxauth_info(request)
+            return cv.to_suc()
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class LoginView(cv.BaseView):
+    def post(self, request):
+        """#账号登录(APP,0/1/2/3(管理员/政府/企业/员工))
+        @username:"root",str,账号
+        @password:"root",str,密码
+        @registration_id:"极光推送客户端集成后生成的id和设备唯一对应"
+        """
+        try:
+            rst = ctl.login_user(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+class LogoutView(cv.AuthView):
+    def post(self, request):
+        '''
+        #退出登录(管理后台)
+        '''
+        user = request.user
+        if user:
+            user_name = user.realname
+            user_email = user.name
+        else:
+            user_name = ''
+            user_email = ''
+        auth.logout(request)
+        return cv.to_suc()
+
+
+
+class GetDefaultView(cv.AuthView):
+    def get(self, request):
+        """
+        #获取默认数据风险点和任务状态(APP)
+        """
+        try:
+            rst = ctl.get_default_data(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class MonitJobListView(cv.AuthView):
+    def get(self, request):
+        """
+        #任务列表(APP)
+        @task_status:1,
+        @riskpoint_id:1,
+        @page:1,
+        @page_size:20
+        """
+        try:
+            rst = ctl.get_monitjob_list(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class MonitJobAuditView(cv.AuthView):
+    def put(self, request):
+        """
+        #提醒审核(APP)
+        @id:1
+        """
+        try:
+            rst = ctl.audit_monitjob_notice(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class MonitJobView(cv.AuthView):
+    def get(self, request):
+        """
+        #任务详情(APP)
+        @id:1
+        """
+        try:
+            rst = ctl.get_monitjob_info(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def put(self, request):
+        """
+        #任务上报(APP)
+        @id:1
+        @imgs:[]
+        @videos:""
+        @task_status:1/2
+        @videos_faceimg:""
+        @desc:""
+        """
+        try:
+            rst = ctl.update_monitjob(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class MonitJobTraceView(cv.AuthView):
+    def get(self, request):
+        """
+        #有隐患的任务详情(APP)
+        @id:1
+        """
+        try:
+            rst = ctl.get_monitjob_info(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def put(self, request):
+        """
+        #任务上报/整改下发(APP)
+        @id:1
+        @type:"yhsb/yhzg/yhdone",隐患我异常直接传type=yhdone就可以了
+        @隐患上报
+        @imgs:[]
+        @videos:""
+        @videos_faceimg:""
+        @desc:""
+        @隐患整改
+        @yhlevel:"重大隐患"
+        @zgtime:"2020-09-01"
+        @zgmethod:"整改措施"
+        """
+        try:
+            rst = ctl.trace_monitjob(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class UserInfoView(cv.AuthView):
+    def get(self, request):
+        """
+        #获取用户信息(APP)
+        """
+        try:
+            rst = ctl.get_user_info(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def put(self,request):
+        """#修改用户信息(APP)
+        @id:"1"
+        @name:"账号"
+        @avatar:"头像"
+        """
+        qdata = request.json
+        need_params = ["id","name","avatar"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.update_staffuser(**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class EmergencyResourceListView(cv.AuthView):
+    def get(self, request):
+        """#获取应急物资列表(APP)
+        """
+        try:
+            qdata = request.json
+            total,rst = ctl.get_list_info(self,**qdata)
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class StuffListListView(cv.AuthView):
+    def get(self, request):
+        """#获取清单列表(APP)
+        """
+        try:
+            qdata = request.json
+            total,rst = ctl.get_list_info(self,**qdata)
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class EmergencyResourceView(cv.AuthView):
+    def get(self, request):
+        """
+        #获取应急物资信息(APP)
+        @id:1
+        """
+        qdata = request.json
+        need_params = ["id"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.get_model_detail_info(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def post(self,request):
+        """#新增应急物资(APP)
+        @name:"风险点id"
+        @amount:10
+        @remark:""
+        """
+        qdata = request.json
+        need_params = ["name","amount","remark"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.add_model(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+    def put(self,request):
+        """#修改应急物资(APP)
+        @id:1
+        @name:"风险点id"
+        @amount:10
+        @remark:""
+        """
+        qdata = request.json
+        need_params = ["id","name","amount"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            need_params.extend(["remark"])
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.update_model(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def delete(self,request):
+        """#删除应急物资(APP)
+        @id:"1",多个逗号分隔
+        """
+        qdata = request.json
+        need_params = ["id"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.delete_model(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class EduTrainingListView(cv.AuthView):
+    def get(self, request):
+        """#获取教育培训列表(APP)
+        """
+        try:
+            qdata = request.json
+            total,rst = ctl.get_list_info(self,**qdata)
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class EduTrainingView(cv.AuthView):
+    def get(self, request):
+        """
+        #获取教育培训详情(APP)
+        @id:1
+        """
+        qdata = request.json
+        need_params = ["id"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.get_detail_info(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def post(self,request):
+        """#新增教育培训(APP)
+        @name:"风险点id"
+        @speaker:"主讲人"
+        @leader:"负责人"
+        @joincount:1,参会人数
+        @begin_time:"2020-07-13 12:12:12",开始时间
+        @end_time:"2020-07-13 12:12:12",结束时间
+        @address:"地址"
+        @imgs:[],培训图片
+        @files:[],培训文件
+        """
+        qdata = request.json
+        need_params = ["name","speaker","leader","joincount","begin_time",
+            "end_time","address","imgs","files"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.add_model(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+    def put(self,request):
+        """#修改教育培训(APP)
+        @id:1
+        @name:"风险点id"
+        @speaker:"主讲人"
+        @leader:"负责人"
+        @joincount:1,参会人数
+        @begin_time:"2020-07-13 12:12:12",开始时间
+        @end_time:"2020-07-13 12:12:12",结束时间
+        @address:"地址"
+        @imgs:[],培训图片
+        @files:[],培训文件
+        """
+        qdata = request.json
+        need_params = ["id","name","speaker","leader","joincount","begin_time",
+            "end_time","address","imgs","files"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.update_model(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def delete(self,request):
+        """#删除教育培训(APP)
+        @id:"1",多个逗号分隔
+        """
+        qdata = request.json
+        need_params = ["id"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.delete_model(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class UploadFileView(cv.AuthView):
+    def post(self, request):
+        """
+        #文件上传(APP)
+        @file:"",文件对象
+        @type:"",前端自定义参数
+        """
+        try:
+            rst = ccc.upload_to_oss(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class MessagesView(cv.AuthView):
+    def get(self, request):
+        """#消息详情(APP)
+        @id:"消息id"
+        """
+        try:
+            rst = ctl.get_messages_info(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class MessagesListView(cv.AuthView):
+    def get(self, request):
+        """#消息列表(APP)
+        @message_type:"notice/sys/warning(通知/系统/告警)"
+        @name:"搜索字段"
+        """
+        try:
+            total,rst = ctl.get_messages_list(request)
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class MessagesNewListView(cv.AuthView):
+    def get(self, request):
+        """#获取新消息列表(APP)
+        @message_type:"notice/sys/warning(通知/系统/告警)"
+        @name:"搜索字段"
+        """
+        try:
+            total,rst = ctl.get_new_messages_list(request)
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class MessagesLatestListView(cv.AuthView):
+    def get(self, request):
+        """#最新消息(APP)
+        """
+        try:
+            rst = ctl.get_latest_messages_list(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class IndexBannersView(cv.BaseView):
+    def get(self, request):
+        """#首页banner数据(小程序)
+        """
+        try:
+            rst = ctl.get_index_banners(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+class IndexJournalsView(cv.BaseView):
+    def get(self, request):
+        """#首页全刊数据(小程序)
+        @page:页码
+        @page_size:每页数量控制,默认为10
+        """
+        try:
+            rst = ctl.get_index_journals(request)
+            return cv.to_suc({"journals":rst})
+        except Exception as e: 
+            return cv.to_fail(e)
+
+class IndexOrganizersView(cv.BaseView):
+    def get(self, request):
+        """#首页主办单位(小程序)
+        @page:页码
+        @page_size:每页数量控制,默认为10
+        """
+        try:
+            rst = ctl.get_index_organizers(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+class IndexSubjectsView(cv.BaseView):
+    def get(self, request):
+        """#首页领域期刊(小程序)
+        @page:页码
+        @page_size:每页数量控制,默认为10
+        """
+        try:
+            rst = ctl.get_index_subjects(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+
+class IndexToTopView(cv.BaseView):
+    def put(self, request):
+        """#首页置顶(小程序)
+        @type:主办单位/学科,organizer/subject
+        @action:置顶与取消置顶,cancel
+        @id:id
+        """
+        qdata = request.json
+        need_params = ["id","type","action"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            ctl.index_totop(request)
+            return cv.to_suc()
+        except Exception as e: 
+            return cv.to_fail(e)
+
+
+class ArticleListView(cv.BaseView):
+    def get(self, request):
+        """#知识服务(小程序)
+        @keyword:关键词搜索
+        @order_by:排序,read_num,forward_num,publish_time
+        @page:页码
+        @page_size:每页数量控制,默认为10
+        """
+        try:
+            rst = ctl.get_article_list(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+class JournalsListView(cv.BaseView):
+    def get(self, request):
+        """#期刊列表(小程序)
+        @subject_id:领域id
+        @keyword:关键词搜索
+        @page:页码
+        @page_size:每页数量控制,默认为10
+        """
+        try:
+            rst = ctl.get_journals_list(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+class SearchDefaultView(cv.BaseView):
+    def get(self, request):
+        """#搜索页默认数据(小程序)
+        """
+        try:
+            rst = ctl.get_search_default(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+
+class SearchView(cv.BaseView):
+    def get(self, request):
+        """#搜索(小程序)
+        @type:搜索什么类型的数据,organizer/article/conference/journal/subject
+        @keyword:关键词
+        """
+        try:
+            rst = ctl.search(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+
+class RecommendView(cv.BaseView):
+    def get(self, request):
+        """#学术交流推荐(小程序)
+        """
+        try:
+            rst = ctl.recommend(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class ConferenceListView(cv.BaseView):
+    def get(self, request):
+        """#学术会议列表(小程序)
+        @keyword:关键词搜索
+        @order_by:排序,time
+        @page:页码
+        @page_size:每页数量控制,默认为10
+        """
+        try:
+            rst = ctl.get_conference_list(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+
+class ActivityListView(cv.BaseView):
+    def get(self, request):
+        """#活动列表(小程序)
+        @keyword:关键词搜索
+        @order_by:排序,ctime/-ctime
+        @page:页码
+        @page_size:每页数量控制,默认为10
+        @type:区分活动预告和活动回顾,pre/over
+        """
+        try:
+            rst = ctl.get_activity_list(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+
+class DetailView(cv.BaseView):
+    def get(self, request):
+        """#详情接口(小程序)
+        @type:区分期刊、主办单位、学科、活动、文章、会议
+        @id:id
+        """
+        try:
+            rst = ctl.get_detail_info(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+
+class CollectView(cv.BaseView):
+    def get(self, request):
+        """#收藏接口(小程序)
+        @type:区分期刊、主办单位、学科、活动、文章、会议
+        @id:id
+        """
+        try:
+            rst = ctl.collect(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+
+class UserCollectionView(cv.BaseView):
+    def get(self, request):
+        """#我的收藏(小程序)
+        @uid:uid
+        """
+        try:
+            rst = ctl.get_user_collection(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+
+class UserSignupView(cv.BaseView):
+    def post(self, request):
+        """#提交报名信息(小程序)
+        @uid:uid
+        @conference_id:会议id
+        @conference_name:会议名称
+        @name:姓名
+        @sex:1/2
+        @age:年龄
+        @job:职位
+        @title:职称
+        @is_caos:是否中科院单位
+        @organizer_unit:所属单位
+        @phone:手机号
+        @email:邮箱
+        """
+        try:
+            rst = ctl.do_signup(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+    def put(self, request):
+        """#上传凭证和选酒店(小程序)
+        @id:报名id
+        @proof_img:汇款凭证
+        @paytype:1/2,支付方式
+        @billtype:1/2,发票种类
+        @billhead:发票抬头
+        @billno:纳税人识别号
+        @billaddress:注册地址
+        @billphone:注册电话
+        @billbank:开户银行
+        @billbankno:开户银行账号
+        @hotel_id:酒店id
+        @room_id:房间id
+        @room_nums:入驻人数
+        @room_stime:入驻开始时间
+        @room_etime:入驻结束时间
+        """
+        try:
+            rst = ctl.update_signup(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+class SignupListView(cv.BaseView):
+    def get(self, request):
+        """#报名列表(小程序)
+        @uid:1,用户id
+        @type:1/2,未开始/已结束
+        @page:1
+        @page_size:10
+        """
+        try:
+            qdata = request.json
+            total,rst = ctl.get_list_info(self,**qdata)
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class HotelListView(cv.BaseView):
+    def get(self, request):
+        """#酒店列表(小程序)
+        @conference_id:1,会议id
+        @page:1
+        @page_size:10
+        """
+        try:
+            qdata = request.json
+            total,rst = ctl.get_list_info(self,**qdata)
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class HotelView(cv.BaseView):
+    def get(self, request):
+        """#酒店详情(小程序)
+        @id:1,酒店id
+        """
+        qdata = request.json
+        need_params = ["id"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.get_model_detail_info(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class OrganizationListView(cv.BaseView):
+    def get(self, request):
+        """#中科院单位列表(小程序)
+        """
+        try:
+            rst = ctl.get_organiztion_list(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+class UploadFileView(cv.BaseView):
+    def post(self, request):
+        """
+        #文件上传(平台管理后台)
+        @file:"",文件对象
+        @type:"",前端自定义参数
+        """
+        try:
+            #rst = ccc.upload_file(request)
+            rst = ccc.upload_to_oss(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class SignupVerifyView(cv.BaseView):
+    def post(self, request):
+        """#核销报名信息(小程序)
+        @uid:uid
+        @sid:1,报名id
+        """
+        try:
+            rst = ctl.verify_signup(request)
+            return cv.to_suc(rst)
+        except Exception as e: 
+            return cv.to_fail(e)
+
+
+class GetPhoneCodeView(cv.BaseView):
+    def send_resetpwd_code_msg(self,phone,content,template_id="SMS_190465337"):
+        """重置密码短信验证码
+        """
+        #if settings.SEND_SMS:
+        rst,msg = send_sms(phone,content,template_id)
+        return rst,msg
+
+    def post(self, request):
+        """#获取短信验证码
+        @phone:"15982456282",手机号
+        """
+        #uid = request.user.id
+        qdata = request.json
+        phone = qdata.get("phone","")
+        codetype = qdata.get("type")
+        rcode = "".join(random.sample('1234567890',6))
+        valid_time = 60*2
+
+        if codetype == "changephone":
+            rst,msg = self.send_resetpwd_code_msg(phone,rcode,"SMS_190465337")
+        else:
+            rst,msg = self.send_resetpwd_code_msg(phone,rcode)
+        if rst:
+            cache.set(phone,rcode,valid_time)
+            return cv.to_suc({})
+        else:
+            return cv.to_fail(msg)

BIN
src/api/views.pyc


+ 298 - 0
src/api/views_backstage.py

@@ -0,0 +1,298 @@
+#-*-coding:utf-8-*-
+import json
+import uuid
+from django.contrib import auth
+from django.core.cache import cache
+from django.conf import settings
+
+from common import core_views as cv
+import common.common_functions as ccf
+import common.error_info as ce
+import control_user as cu
+import control_role as crol
+import control_organization as co
+import common.common_control as ccc
+import control_permission as cp
+import control_department as cd
+import control_bankcard as cb
+
+
+class InfoView(cv.AdminView):
+    def get(self, request):
+        '''
+        #获取全局账号信息(权限控制)
+        '''
+        try:
+            users = cu.get_account_info(request)
+            return cv.to_suc(users)
+        except Exception as e:
+            return cv.to_fail(e)
+
+class UserInfoView(cv.BaseView):
+    def get(self, request):
+        """
+        #获取用户个人信息
+        @id:1,用户id
+        """
+        try:
+            data = cu.get_user_personal_info(request)
+            return cv.to_suc(data)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+class UserView(cv.BaseView):
+    def get(self, request):
+        """
+        #获取用户详情
+        @id:1,用户id
+        """
+        try:
+            data = cu.get_user_info(request)
+            return cv.to_suc(data)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+    def post(self, request):
+        '''
+        #新增员工
+        @realname:"肖小肖",员工名称
+        @phone:"129823"
+        @email:"129823@qq.com"
+        @department_id:1,部门id
+        @utype:1/2/3,员工类型
+        @is_active:1/0,是否启用
+        @remark:"好员工",备注
+        '''
+        qdata = request.json
+        try:
+            rst = cu.add_user(request)
+            return cv.to_suc()
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def put(self, request):
+        """
+        #修改员工
+        @id:1,员工id
+        @realname:"肖小肖",员工名称
+        @phone:"129823"
+        @email:"129823@qq.com"
+        @department_id:1,部门id
+        @utype:1/2/3,员工类型
+        @is_active:1/0,是否启用
+        @remark:"好员工",备注
+        """
+        qdata = request.json
+        try:
+            data = cu.update_user(request)
+        except Exception as e:
+            return cv.to_fail(e)
+        return cv.to_suc(data)
+
+    def delete(self, request):
+        """
+        #删除员工
+        @id:1,多个id用逗号分隔
+        """
+        qdata = request.json
+        try:
+            cu.delete_user(request)
+        except Exception as e:
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+class UserListView(cv.AuthView):
+    def get(self, request):
+        """
+        #员工列表
+        @name:"用户名"
+        @department_id:1
+        @utype:1
+        @is_active:1
+        """
+        try:
+            total,res = cu.get_user_list(request)
+            return cv.to_suc({"total":total,"list":res})
+        except Exception as e:
+            return cv.to_fail(e)
+
+
+class UnauditUserListView(cv.AuthView):
+    def get(self, request):
+        """
+        #待审核员工列表
+        @name:"用户名"
+        @utype:1
+        """
+        try:
+            total,res = cu.get_unaudit_user_list(request)
+            return cv.to_suc({"total":total,"list":res})
+        except Exception as e:
+            return cv.to_fail(e)
+
+
+class PermissionListView(cv.AuthView):
+    def get(self, request):
+        """#权限列表
+        @role_id:1 角色id 可选参数 传了就只返回对应角色的权限
+        @platform:"operation" 权限归属 可选参数 传了就对权限进行平台过滤
+        """
+        qdata = request.json
+        role_id = qdata.get("role_id",None)
+        platform = qdata.get("platform",None)
+        roles = cp.get_permission_list(role_id,platform)
+
+        return cv.to_suc(roles)
+
+
+class ResetPwdView(cv.BaseView):
+    def put(self, request):
+        """
+        #重置密码(忘记密码)
+        @phone:"15982456282",手机号
+        @password:"",新密码
+        @repassword:"",确认密码
+        @phcode:"123",验证码
+        """
+        try:
+            cu.reset_password(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)
+
+
+class ResetUserPwdView(cv.AuthView):
+    def put(self, request):
+        """
+        #修改用户密码
+        @uid:10,用户id不传则默认当前用户
+        @code:"",验证码
+        @password:"",新密码
+        """
+        try:
+            cu.reset_user_password(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)
+
+
+class DepartmentView(cv.AuthView):
+    def post(self,request):
+        """
+        #新增部门
+        @name:"综管部",部门名称
+        @pid:1,上级部门
+        @permissions:["CusManage.*.*","CusManage.MyCus.*"]
+        """
+        try:
+            cd.add_department(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)
+
+    def put(self,request):
+        """
+        #修改部门
+        @id:1,部门id
+        @name:"综管部",部门名称
+        @pid:1,上级部门
+        @permissions:["CusManage.*.*","CusManage.MyCus.*"]
+        """
+        try:
+            cd.update_department(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)
+
+    def delete(self,request):
+        """
+        #删除部门
+        @id:1,部门id
+        """
+        try:
+            cd.delete_department(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)
+
+
+class DepartmentListView(cv.AuthView):
+    def get(self,request):
+        """#部门列表
+        @name:"研发",部门名称
+        """
+        try:
+            total,rst = cd.get_department_list(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc({"total":total,"list":rst})
+
+
+class UserBankCardView(cv.AuthView):
+    def post(self,request):
+        """#新增银行卡
+        @name:"建设银行",银行名称
+        @cardno:"6229000",银行卡卡号
+        """
+        try:
+            rst = cb.add_bankcard(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+    def delete(self,request):
+        """#删除银行卡
+        @id:1,银行卡id
+        """
+        try:
+            rst = cb.delete_bankcard(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc()
+
+
+class UserBankCardListView(cv.AuthView):
+    def get(self,request):
+        """#银行卡列表
+        """
+        try:
+            rst = cb.get_bankcard_list(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc(rst)
+
+
+class UserIncomeView(cv.AuthView):
+    def get(self,request):
+        """#我的收益
+        """
+        try:
+            rst = cb.get_user_income(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc(rst)
+
+
+class UserApplyCashView(cv.AuthView):
+    def post(self,request):
+        """#申请提现
+        @bankcard_id:1,银行卡id
+        @cashtype:"bank/alipay",提现方式
+        @cashamount:1000,提现金额
+        """
+        try:
+            rst = cb.apply_cash(request)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+        return cv.to_suc(rst)

BIN
src/api/views_backstage.pyc


+ 4 - 0
src/api/views_permission.py

@@ -0,0 +1,4 @@
+#-*-coding:utf-8 -*-
+import common.core_views as cv
+
+

+ 12 - 0
src/asgi.py

@@ -0,0 +1,12 @@
+"""
+ASGI entrypoint. Configures Django and then runs the application
+defined in the ASGI_APPLICATION setting.
+"""
+
+import os
+import django
+import channels.asgi
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
+django.setup()
+application = channels.asgi.get_channel_layer()

+ 51 - 0
src/backup_mysql.py

@@ -0,0 +1,51 @@
+# coding=utf-8
+import os
+import django,datetime
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
+django.setup()
+
+from utils.upload_to_oss import TedOSS
+
+
+def upload_to_oss(local,oss):
+    """
+    """
+    tedoss = TedOSS()
+    url = tedoss.upload_from_local(local,oss)
+    return url
+
+def clear_old_backups():
+    """
+    """
+    tedoss = TedOSS()
+    files = tedoss.list_files("zky/backup/mysql/workflow")
+    timelimit = (datetime.datetime.now()-datetime.timedelta(days=3)).strftime("%Y%m%d%H%M%S")
+    dels = []
+    for f in files:
+        pass
+        ftime = f.split("_")[-1].split(".")[0]
+        if ftime < timelimit:
+            dels.append(f)
+    #批量删除
+    if dels:
+        tedoss.batch_delete_objs(dels)
+
+
+def backup_mysql():
+    """
+    """
+    now_str = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
+    sqlfile = "/tmp/workflow_%s.sql" % now_str
+    ossfile = "backup/mysql/workflow/workflow_%s.sql" % now_str
+    cmd = "mysqldump -utedcaos -ptedcaos123!@# -h172.17.22.226 workflow  > %s" % sqlfile
+    os.system(cmd)
+    url = upload_to_oss(sqlfile,ossfile)
+    os.remove(sqlfile)
+    #清除老数据
+    clear_old_backups()
+
+    clear_old_backups()
+
+
+if __name__ == "__main__":
+    backup_mysql()

+ 0 - 0
src/common/__init__.py


BIN
src/common/__init__.pyc


+ 119 - 0
src/common/captcha.py

@@ -0,0 +1,119 @@
+# coding:utf-8
+import base64
+import random
+
+import StringIO
+from PIL import ImageDraw, ImageFont, Image
+
+def create_imgcode(mlen):
+    """
+    @attention: 生成验证码
+    @param mlen: 验证码长度
+    @return: [验证码字符串,验证码图片base64]
+    @note:
+    > 生成验证码
+    > 创建图片和画笔
+    > 准备验证码图片基本配置,包括
+    > 填充验证码
+    > 填充干扰线
+    > 添加滤镜/扭曲
+    """
+    code = get_random_code(mlen)
+    # 创建图片和画笔
+    width = 100
+    height = 40
+    size = (width, height)
+    #6CC4B3
+    image = Image.new("RGBA", size, "#F5F5F7")
+    draw = ImageDraw.Draw(image)
+    fill_code(code, mlen, draw, width, height)
+    #draw_line(draw, width, height, 3)
+    draw_points(draw, 5, width, height)
+    #image = image.transform((width+20,height+10), Image.AFFINE, (1,-0.3,0,-0.1,1,0),Image.BILINEAR)  #创建扭曲
+    #image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) #滤镜,边界加强
+    buf = StringIO.StringIO()
+    image.save(buf, 'png', quality=70)
+    buf_str = buf.getvalue()
+    return ''.join(code),buf_str
+
+def create_idcode(mlen):
+    """
+    @attention: 生成验证码
+    @param mlen: 验证码长度
+    @return: [验证码字符串,验证码图片base64]
+    @note:
+    > 生成验证码
+    > 创建图片和画笔
+    > 准备验证码图片基本配置,包括
+    > 填充验证码
+    > 填充干扰线
+    > 添加滤镜/扭曲
+    """
+    code = get_random_code(mlen)
+    # 创建图片和画笔
+    width = 100
+    height = 40
+    size = (width, height)
+    #6CC4B3
+    image = Image.new("RGBA", size, "#F5F5F7")
+    draw = ImageDraw.Draw(image)
+    fill_code(code, mlen, draw, width, height)
+    #draw_line(draw, width, height, 5)
+    draw_points(draw, 10, width, height)
+    #image = image.transform((width+20,height+10), Image.AFFINE, (1,-0.3,0,-0.1,1,0),Image.BILINEAR)  #创建扭曲
+    #image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) #滤镜,边界加强
+    buf = StringIO.StringIO()
+    image.save(buf, 'png', quality=70)
+    buf_str = base64.b64encode(buf.getvalue())
+    return ''.join(code), "data:image/png;base64,"+buf_str
+
+############## 辅助函数 ##############
+def rndColor():
+    """
+    随机颜色
+    :return:
+    """
+    return random.randint(32, 127), random.randint(32, 127), random.randint(32, 127)
+
+def get_random_code(number):
+    """
+    @attention: 获取随机码(排除难以识别的o,0,i,1,z,2等)
+    """
+    return random.sample("abcdefghjkmnpqrstuvwxyABCDEFGHJKMNPQRSTUVWXY3456789", number)
+
+
+def fill_code(code, number, draw, width, height):
+    """
+    @attention: 填充验证码
+    @param code: 验证码
+    @param draw: 画笔
+    """
+    font_path = "common/font/consola.ttf"
+    font = ImageFont.truetype(font_path, 34)  # 验证码的字体和字体大小
+    for t in xrange(number):
+        draw.text((20 * t + 10, 3 if(t%2) else -3),  code[t], font=font, fill=rndColor())
+
+
+def draw_line(draw, width, height, number=1):
+    for i in xrange(number):
+        begin = (random.randint(0, width / 2), random.randint(0, height))
+        end = (random.randint(width / 2, width), random.randint(0, height))
+        draw.line([begin, end], fill="#6CC4B3", width=3)
+
+
+def draw_points(draw, point_chance, width, height):
+    """
+    绘制干扰点
+    :param draw: 画笔
+    :param point_chance: 干扰点出现概率:0到100
+    :param width:
+    :param height:
+    :return:
+    """
+    chance = min(100, max(0, int(point_chance)))  # 大小限制在[0, 100]
+
+    for w in xrange(width):
+        for h in xrange(height):
+            tmp = random.randint(0, 100)
+            if tmp > 100 - chance:
+                draw.point((w, h), fill=(0, 0, 0))

BIN
src/common/captcha.pyc


+ 116 - 0
src/common/common_control.py

@@ -0,0 +1,116 @@
+# coding:utf-8
+import os,time
+import sys
+import django
+import json
+from django.core.cache import cache
+from django.core.paginator import Paginator
+from django.conf import settings
+
+import common.models as cm
+import common.common_functions as ccf
+
+def cache_data(timeout=60*60*24):
+    def _wrapper(func):
+        def __wrapper(*args,**kwargs):
+            if args:
+                key = "cdata_{}_{}".format(func.__name__,str(args))
+            else:
+                key = "cdata_{}".format(func.__name__)
+            if not kwargs.get("cache",True) or not cache.get(key):
+                res = func(*args,**kwargs)
+                cache.set(key,res,timeout)
+                #print u"不取缓存!!!!!!!!!"
+                return res
+            else:
+                #print u"取缓存"
+                return cache.get(key)
+        return __wrapper
+    return _wrapper
+
+
+def no_cache(key="*"):
+    def _wrapper(func):
+        def __wrapper(*args,**kwargs):
+            res = func(*args,**kwargs)
+            print cache.delete_pattern("cdata_{}*".format(key))
+            return res
+        return __wrapper
+    return _wrapper
+
+
+def no_cache_list(keys=[]):
+    def _wrapper(func):
+        def __wrapper(*args,**kwargs):
+            res = func(*args,**kwargs)
+            for key in keys:
+                print cache.delete_pattern("cdata_{}*".format(key))
+            return res
+        return __wrapper
+    return _wrapper
+
+
+def get_page_qset(qset,page,page_size=20):
+    """
+    """
+    count = qset.count()
+    if page and page_size:
+        paginator = Paginator(qset,page_size)
+        object_list = paginator.page(page).object_list
+    else:
+        object_list = qset
+    return count,object_list
+
+def upload_file(request):
+    """
+    """
+    upload_file = request.FILES['file']
+    ext = os.path.splitext(upload_file.name)[-1]
+    timestamp = str(int(time.time()*1000))
+    #dest = settings.STATIC_ROOT + "/upload/"+str(int(time.time()*1000)) + upload_file.name
+    dest = settings.STATIC_ROOT + "/upload/"+ timestamp + ext
+    with open(dest,"wb+") as f:
+        for chunk in upload_file.chunks():
+            f.write(chunk)
+    f.close()
+    url = dest.replace(settings.STATIC_ROOT,settings.HOST)
+    rst = {"url":url,"type":request.POST.get("type"),"name":upload_file.name}
+    #
+    if ext == ".mp4":
+        imgpath = settings.STATIC_ROOT + "/upload/" + timestamp + ".png"
+        cmd = "ffmpeg  -i {}  -ss 1.000 -vframes 1 {}".format(dest,imgpath)
+        os.system(cmd)
+        imgurl = imgpath.replace(settings.STATIC_ROOT,settings.HOST)
+        rst["imgurl"] = imgurl
+    return rst
+
+
+def upload_to_oss(request):
+    """
+    """
+    upload_file = request.FILES['file']
+    ext = os.path.splitext(upload_file.name)[-1]
+    timestamp = str(int(time.time()*1000))
+    #dest = "upload/"+ timestamp + ext
+    dest = "upload/"+ timestamp + "/"+upload_file.name
+
+    from utils.upload_to_oss import TedOSS
+    tedoss = TedOSS()
+    url = tedoss.upload_from_str(upload_file.chunks(),dest)
+    return url
+
+    #url = dest.replace(settings.STATIC_ROOT,settings.HOST)
+    #rst = {"url":url,"type":request.POST.get("type"),"name":upload_file.name}
+    ##
+    #if ext == ".mp4":
+    #    imgpath = settings.STATIC_ROOT + "/upload/" + timestamp + ".png"
+    #    cmd = "ffmpeg  -i {}  -ss 1.000 -vframes 1 {}".format(dest,imgpath)
+    #    os.system(cmd)
+    #    imgurl = imgpath.replace(settings.STATIC_ROOT,settings.HOST)
+    #    rst["imgurl"] = imgurl
+    #return rst
+
+
+if __name__ == "__main__":
+    #测试
+    print get_pparents_info(1550,[])

BIN
src/common/common_control.pyc


+ 231 - 0
src/common/common_functions.py

@@ -0,0 +1,231 @@
+# coding:utf-8
+import calendar
+import hashlib
+import datetime
+import re
+import M2Crypto
+from PIL import Image,ImageDraw
+import requests
+
+def get_month_dates(month="202008"):
+    """
+    """
+    dates = []
+    now = datetime.datetime.now().date()
+    now_date_str = now.strftime("%Y%m")
+    day_end = calendar.monthrange(int(now_date_str[0:4]),int(now_date_str[4:6]))[1]
+    for i in range(1,day_end):
+        dates.append(now_date_str+"%02d" % i)
+    return dates
+
+def check_password(new,old):
+    """
+    """
+    np = hashlib.md5(new).hexdigest().upper()
+    return np==old
+
+def make_password(pwd,isdefault=None):
+    """
+    """
+    return hashlib.md5(pwd).hexdigest().upper()
+
+def get_md5(pwd):
+    """
+    """
+    return hashlib.md5(pwd).hexdigest()
+
+def addText(orgpath,string,path):
+    img = Image.open(orgpath)
+    size = img.size
+    width = size[0] - 20
+    high = size[1] - 20
+    lenth = len(string)*3
+    draw = ImageDraw.Draw(img)
+    draw.text((width-lenth,high),string,fill='black')
+    img.save(path)
+
+def list_split(items, n):
+    return [items[i:i+n] for i in range(0, len(items), n)]
+
+def str_to_datetime(tm,format="%Y-%m-%d %H:%M:%S"):
+    """
+    """
+    datetimestr = datetime.datetime.strptime(tm,format)
+    return datetimestr
+
+def datetime_to_str(tm,format="%Y-%m-%d %H:%M:%S"):
+    """
+    """
+    datetimestr = datetime.datetime.strftime(tm,format)
+    return datetimestr
+
+def get_now_str(format="%Y-%m-%d %H:%M:%S"):
+    """获取当前时间并转化成制定格式字符串
+    """
+    now = datetime.datetime.now()
+    return datetime.datetime.strftime(now,format)
+
+def check_pub_key(pub_key):
+    """检查证书有效性
+    """
+    try:
+        pub_key = M2Crypto.X509.load_cert_string(str(pub_key)) 
+        return 1
+    except:
+        return 0
+
+def check_priv_key(priv_key):
+    """检查私钥有效性
+    """
+    try:
+        M2Crypto.RSA.load_key_string(str(priv_key)) 
+        return 1
+    except:
+        return 0
+
+
+def check_pub_priv_key(pub_key, priv_key):
+    if len(pub_key) == 0 and len(priv_key) == 0:
+        return 0
+    msg = "hello"
+    try:
+        cert = M2Crypto.X509.load_cert_string(str(pub_key))
+        key = M2Crypto.RSA.load_key_string(str(priv_key))
+        encrypted = cert.get_pubkey().get_rsa().public_encrypt(msg, M2Crypto.RSA.pkcs1_padding)
+        decrypted = key.private_decrypt(encrypted, M2Crypto.RSA.pkcs1_padding)
+        if msg != decrypted:
+            return 0
+            return errno.INVALID_CERT
+    except:
+        return 0
+        return errno.INVALID_CERT
+    return 1
+
+
+def get_day_range(yesterday):
+    """
+    @attention: 获取昨天数据
+    """
+    sd = ed = yesterday.strftime("%Y%m%d")
+    return sd,ed
+
+def get_week_range(yesterday):
+    """
+    @attention: 获取最近一周数据
+    """
+    ed = yesterday.strftime("%Y%m%d")
+    sd = yesterday - datetime.timedelta(days=6)
+    sd = sd.strftime("%Y%m%d")
+    return sd,ed
+
+def get_month_range(yesterday,today_month,days):
+    """
+    @attention: 获取最近一个月数据
+    """
+    ed = yesterday.strftime("%Y%m%d")
+    temp = datetime.datetime.strptime(today_month,"%Y%m")-datetime.timedelta(days=1)
+    last_month = temp.strftime("%Y%m")
+    sd = "%s%s"%(last_month,str(days).rjust(2,"0"))
+    return sd,ed
+
+
+def list_group_by(olist,key,sort=None):
+    """
+    """
+    nlist = []
+    tmp = {}
+    for ol in olist:
+        kkey = ol[key]
+        if not tmp.has_key(kkey):
+            tmp[kkey] = [0]
+        else:
+            tmp[kkey].append(ol)
+    for k,v in tmp.items():
+        dct = {key:k,"data":v,"count":len(v)}
+        nlist.append(dct)
+    if sort:
+        nlist = sorted(nlist,key=lambda x:x["count"])
+    return nlist
+
+def get_need_params(*need_parms,**kwargs):
+    """
+    """
+    newdct = {}
+    need_parms = set(need_parms).intersection(set(kwargs.keys()))
+    for k in need_parms:
+        newdct[k] = kwargs.get(k)
+    return newdct
+
+def check_params(*need_parms,**kwargs):
+    if not set(need_parms).issubset(set(kwargs.keys())):
+        miss = list(set(need_parms)-set(kwargs.keys()))
+        miss = ",".join(miss)
+        return "缺少参数:{}".format(miss)
+    for nk in need_parms:
+        if not kwargs.get(nk):
+            return "缺少参数值:{}!".format(nk)
+    return None
+
+def get_page_list(list,page,page_size=20):
+    """
+    """
+    if page and page_size:
+        start = (page - 1)*page_size
+        end = page * page_size
+        count = len(list)
+        list = list[start:end]
+    else:
+        count = len(list)
+    return count,list
+
+def get_ip(request):
+    if request.META.has_key('HTTP_X_REAL_IP'):
+        ip = request.META['HTTP_X_REAL_IP']
+    elif request.META.has_key('HTTP_X_FORWARDED_FOR'):
+        ip = request.META['HTTP_X_FORWARDED_FOR']
+    else:
+        ip = request.META['REMOTE_ADDR']
+    return ip
+
+def isWechat(ua):
+    """
+    """
+    if "micromessenger" in ua.lower():
+        return True
+    else:
+        return False
+
+def get_city_by_ip(ip):
+    """
+    """
+    url = "http://api.map.baidu.com/location/ip?ip={}&ak=dYrYC6F0YePk51zYG2H5kSyAbU0nX4NR".format(ip)
+    res = requests.get(url)
+    if res.status_code == 200:
+        if res.json().get("status") == 0:
+            city = res.json()["content"]["address_detail"]["city"]
+            return city
+        return None
+    return None
+
+def get_weathear_by_city(district_id):
+    """
+    """
+    url = "http://api.map.baidu.com/weather/v1/?district_id={}&data_type=all&ak=dYrYC6F0YePk51zYG2H5kSyAbU0nX4NR".format(district_id)
+    res = requests.get(url)
+    if res.status_code == 200:
+        if res.json().get("status") == 0:
+            city = res.json()["result"]["location"]["city"]
+            temp = res.json()["result"]["now"]["temp"]
+            wind_class = res.json()["result"]["now"]["wind_class"]
+            wind_dir = res.json()["result"]["now"]["wind_dir"]
+            text = res.json()["result"]["now"]["text"]
+            return city,temp,wind_class,wind_dir,text
+        return None
+    return None
+
+if __name__ == "__main__":
+    print make_password("123456")
+    pass
+
+
+

BIN
src/common/common_functions.pyc


+ 70 - 0
src/common/common_notice.py

@@ -0,0 +1,70 @@
+# coding:utf-8
+import os
+import sys
+import django
+import json
+from django.core.cache import cache
+from django.core.paginator import Paginator
+
+import common.models as cm
+import common.common_functions as ccf
+
+def send_audit_notice(user_id,subject_item):
+    """发送审核通知
+    """
+    title = u"报名审核通过"
+    content = u"您好,你在巴中逸沣安全培训报名的{}已审核通过,请尽快去支付!".format(subject_item)
+    cm.SysNotice.objects.create(title=title,content=content,to=user_id)
+
+def send_unauthed_notice(user_id):
+    """审核不通过短信通知
+    """
+    title = u"报名审核不通过"
+    content = u"学员您好,您在巴中逸沣安全培训报名提交的资料不符合要求,请检查后重新上传。"
+    cm.SysNotice.objects.create(title=title,content=content,to=user_id)
+
+def send_update_notice(user_id,name,subject_item):
+    """证件复审通知
+    """
+    title = u"证件复审到期通知"
+    content = u"您好:{},您的{}证件即将到复审时间 ,为避免证件被注销,请尽快报名参加复审,为节约您的时间与费用可关注我公司微信公众号(BZYF2016)在线报名上传相关资料。".format(name,subject_item)
+    cm.SysNotice.objects.create(title=title,content=content,to=user_id)
+
+def send_expired_notice(user_id,name,subject_item):
+    """证件到期通知
+    """
+    title = u"证件换证到期通知"
+    content = u"您好:{},您的{}证件即将到期 ,为避免证件被注销,请您提前3个月报名参加培训,为节约您的时间与费用可关注我公司微信公众号(BZYF2016)在线报名上传相关资料,也请您在线报名成功后模拟练习题库试题。".format(name,subject_item)
+    cm.SysNotice.objects.create(title=title,content=content,to=user_id)
+
+def send_pay_notice(user_id):
+    """支付成功通知
+    """
+    title = u"报名支付成功通知"
+    content = u"学员您好:您已支付成功,请在您手机端完成线上学习课时后才能安排考试,考试时间会提前电话通知或查看在线报名页面消息栏。"
+    cm.SysNotice.objects.create(title=title,content=content,to=user_id)
+
+def send_training_notice(user_id,subject_item,begin_time,end_time):
+    """培训通知
+    """
+    title = u"负责人、安全员、从业人员培训通知"
+    content = u"培训名称:{} 开始时间:{} 结束时间:{} 培训地点:巴中市江北车站三楼 注意事项:(计算机考试工种:网上报名成功后,不用再提交纸质资料,考试时间另行通知),(纸张考试工种:需提交本人身份证复印件1张,蓝底1寸照片2张,毕业证书复印件1张或户口薄本人显示学历页复印件1张)。 联系电话:0827-8589103".format(subject_item,begin_time,end_time)
+    cm.SysNotice.objects.create(title=title,content=content,to=user_id)
+
+def send_training_notice_special(user_id,subject_item,begin_time):
+    """培训通知
+    """
+    title = u"特种作业人员培训通知"
+    content = u"培训名称:{} 培训时间:{} 培训地点:巴中市江北车站三楼 注意事项:携带本人身份证原件,(复审、换证)人员请带上以前老证 联系电话:0827-8589102".format(subject_item,begin_time)
+    cm.SysNotice.objects.create(title=title,content=content,to=user_id)
+
+def send_exam_notice(user_id,name,subject_item,exam_time):
+    """培训通知
+    """
+    title = u"特种作业人员培训通知"
+    content = u"您好,{},您参加的{}培训即将考试,请注意。考试时间:{} 9:30 考试地点:兴文东锦社区1500米处(巴中经开区人才大楼)2楼,地图导航输入(巴中市安全生产考试中心)联系电话:15884997924 请在考试当日携带本人身份证原件与口罩准时参加考试,切勿迟到!祝考试顺利!".format(name,subject_item,exam_time)
+    cm.SysNotice.objects.create(title=title,content=content,to=user_id)
+
+if __name__ == "__main__":
+    #测试
+    pass

BIN
src/common/common_notice.pyc


+ 334 - 0
src/common/core_views.py

@@ -0,0 +1,334 @@
+#coding=utf-8
+'''
+'''
+import uuid
+import json
+import logging
+import re
+import traceback
+import datetime
+import hashlib
+import decimal
+from utils.aestool import aescbc
+
+from django import http
+from django.contrib.sessions.backends.cache import SessionStore
+from django.core.cache import cache
+from django.http import HttpResponse, JsonResponse,HttpResponseRedirect,HttpResponsePermanentRedirect
+from django.shortcuts import render
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+from django.core.serializers.json import DjangoJSONEncoder
+import user_agents
+from django.utils.functional import Promise
+
+from common import error_info
+from common.models import SysUserInfo
+import common.models as cm
+import common.error_info as ce
+
+logger = logging.getLogger(__name__)
+
+
+class CusDjangoJSONEncoder(json.JSONEncoder):
+    """
+    JSONEncoder subclass that knows how to encode date/time, decimal types and UUIDs.
+    """
+    def default(self, o):
+        # See "Date Time String Format" in the ECMA-262 specification.
+        if isinstance(o, datetime.datetime):
+            r = datetime.datetime.strftime(o,'%Y-%m-%d %H:%M:%S')
+            return r
+        elif isinstance(o, datetime.date):
+            return o.isoformat()
+        elif isinstance(o, datetime.time):
+            if is_aware(o):
+                raise ValueError("JSON can't represent timezone-aware times.")
+            r = o.isoformat()
+            if o.microsecond:
+                r = r[:12]
+            return r
+        elif isinstance(o, datetime.timedelta):
+            return duration_iso_string(o)
+        elif isinstance(o, decimal.Decimal):
+            return str(o)
+        elif isinstance(o, uuid.UUID):
+            return str(o)
+        elif isinstance(o, Promise):
+            return six.text_type(o)
+        #elif isinstance(o, CallableBool):
+        #    return bool(o)
+        else:
+            return super(DjangoJSONEncoder, self).default(o)
+
+def isMobile(ua):
+    """
+    """
+    return user_agents.parse(ua).is_mobile
+
+
+class AuthView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        """
+        @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验
+        """
+        if request.method.lower() in self.http_method_names:
+            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
+        else:
+            handler = self.http_method_not_allowed
+        return api_wapper(handler, request, True, *args, **kwargs)
+
+    def get_ip(self,request):
+        if request.META.has_key('HTTP_X_REAL_IP'):
+            ip = request.META['HTTP_X_REAL_IP']
+        elif request.META.has_key('HTTP_X_FORWARDED_FOR'):
+            ip = request.META['HTTP_X_FORWARDED_FOR']
+        else:
+            ip = request.META['REMOTE_ADDR']
+        if "," in ip:
+            ip = ip.split(",")[0]
+        return ip
+
+class AdminView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        """
+        @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验
+        """
+        self.http_method_names.append("options")
+        if request.method.lower() in self.http_method_names:
+            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
+        else:
+            handler = self.http_method_not_allowed
+        return admin_handler(handler, request, True, *args, **kwargs)
+
+
+class BaseView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        """
+        @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验
+        """
+        if request.method.lower() in self.http_method_names:
+            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
+        else:
+            handler = self.http_method_not_allowed
+
+        return api_wapper(handler, request, False, *args, **kwargs)
+
+    def get_ip(self,request):
+        if request.META.has_key('HTTP_X_REAL_IP'):
+            ip = request.META['HTTP_X_REAL_IP']
+        elif request.META.has_key('HTTP_X_FORWARDED_FOR'):
+            ip = request.META['HTTP_X_FORWARDED_FOR']
+        else:
+            ip = request.META['REMOTE_ADDR']
+        return ip
+
+
+class UploadView(View):
+    
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        """
+        @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验
+        """
+        if request.method.lower() in self.http_method_names:
+            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
+        else:
+            handler = self.http_method_not_allowed
+
+        return upload_wapper(handler,request,True, *args, **kwargs)
+
+
+class InnerView(View):
+    
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        """
+        @attention: as_view()方法使用该方法来分发不同http method,添加异常处理及登陆校验
+        """
+        if request.method.lower() in self.http_method_names:
+            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
+            if request.META.get("HTTP_TOKEN") != "7dpHIhpweckghdoSvrXwMftcjZRIzKwJ":
+                handler = self.http_method_not_allowed
+        else:
+            handler = self.http_method_not_allowed
+
+        return api_wapper(handler, request, False, *args, **kwargs)
+
+
+def show_history(request):
+    logined_history = cache.get("logined_history", {})
+    for k, v in logined_history.iteritems():
+        logger.info("k: %s, v: %s", str(k), str(v))
+    logger.info("current session: %s", str(request.session.session_key))
+    ss = SessionStore(request.session.session_key)
+    for k, v in ss.iteritems():
+        logger.info("k: %s, v: %s", str(k), str(v))
+
+
+def api_wapper(handler, request, is_vauth, *args, **kwargs):
+    """
+    @attention: 调试API时使用的装饰器
+    """
+    req_path = request.get_full_path()
+    ip = request.META.get("HTTP_X_REAL_IP","")
+    token = request.META.get("HTTP_AUTHORIZATION")
+    if is_vauth:
+        loginuser = request.session.get("user")
+        if not loginuser:
+            return HttpResponseRedirect("/login?rf="+req_path)
+
+    body = request.body if hasattr(request, "body") else ""
+    if "x-www-form-urlencoded" in request.content_type:
+        info = http.QueryDict(body).dict()
+        if not info:
+            info = request.GET.dict()
+    elif "application/json" in request.content_type:
+        info = json.loads(body) if body else {}
+        if not info:
+            info = request.GET.dict()
+    else:
+        try:
+            info = json.loads(body) if body else {}
+            if not info:
+                info = request.GET.dict()
+        except:
+            info = {}
+
+    setattr(request, "json", info)
+    try:
+        ret = handler(request, *args, **kwargs)
+        return ret
+    except Exception as e:
+        return to_fail(e)
+
+def admin_handler(handler, request, is_vauth, *args, **kwargs):
+    """
+    登录session校验
+    """
+    req_path = request.META["PATH_INFO"]
+    ip = request.META.get("HTTP_X_REAL_IP","")
+    token = request.META.get("HTTP_AUTHORIZATION")
+    if is_vauth:
+        user = request.session.get("user")
+        if user and user.get("id"):
+            uid = user.get("id")
+            utype = user.get("utype")
+            if utype == 0:
+                user = SysUserInfo.objects.filter(id=uid).first()
+                user.role = 0
+            if utype == 1:
+                user = cm.JournalUsers.objects.filter(id=uid).first()
+                user.role = 1
+            if utype == 2:
+                user = cm.ExpertUsers.objects.filter(id=uid).first()
+                user.role = 2
+                if cm.WorkSheet.objects.filter(examiner_leader_id=uid).exists():
+                    #专家组长
+                    user.role = 3
+            if not user and False:
+                #return JsonResponse({"code":403,"data":{}})
+                return HttpResponse(status=403)
+        else:
+            return HttpResponse(status=403)
+        setattr(request, "ip", get_ip(request))
+        setattr(request, "user", user)
+        if request.method == "OPTIONS":
+            return JsonResponse({})
+
+    body = request.body if hasattr(request, "body") else ""
+    if "x-www-form-urlencoded" in request.content_type:
+        info = http.QueryDict(body).dict()
+        if not info:
+            info = request.GET.dict()
+    elif "application/json" in request.content_type:
+        info = json.loads(body) if body else {}
+        if not info:
+            info = request.GET.dict()
+    else:
+        try:
+            info = json.loads(body) if body else {}
+            if not info:
+                info = request.GET.dict()
+        except:
+            info = {}
+
+    setattr(request, "json", info)
+
+    try:
+        ret = handler(request, *args, **kwargs)
+        return ret
+    except Exception as e:
+        return to_fail(e)
+
+def to_render(request,tpl,data):
+    """模板渲染
+    """
+    if isMobile(request.META["HTTP_USER_AGENT"]):
+        tpl = "mobile/"+tpl
+    return render(request,tpl,data)
+
+def to_suc(data={}):
+    info = {}
+    info["data"] = data
+    info["code"] = 0
+    info["message"] = "success"
+    return JsonResponse(info,encoder=CusDjangoJSONEncoder)
+
+def to_fail(e=None):
+    info = {}
+    info["code"] = 1000
+    if isinstance(e,ce.TipException):
+        info["message"] = e.msg
+    else:
+        info["message"] = str(e)
+    return JsonResponse(info)
+
+def to_response(data):
+    """
+    """
+    response = HttpResponse(data,content_type="application/json")
+    #response = HttpResponse(data)
+    print dir(response)
+    return response
+    #return HttpResponse(data)
+
+def to_redirect(path):
+    """
+    """
+    #return HttpResponseRedirect(path)
+    return HttpResponsePermanentRedirect(path)
+
+def tracefail():
+    traceback.print_exc()
+
+def stream_file(content, content_type, file_name):
+    """
+    输出文件
+    :param content: 内容 StringIO 类型
+    :param content_type: 类型  eg: "application/vnd.ms-excel"
+    :param file_name: 文件名(需指定后缀)
+    """
+    response = HttpResponse(content=content, content_type=content_type)
+    #response['Content-Disposition'] = u'attachment; filename={}'.format(file_name)
+    from django.utils.encoding import escape_uri_path
+    response["Content-Disposition"] = u"attachment; filename={}".format(escape_uri_path(file_name))
+    return response
+
+def get_ip(request):
+    if request.META.has_key('HTTP_X_REAL_IP'):
+        ip = request.META['HTTP_X_REAL_IP']
+    elif request.META.has_key('HTTP_X_FORWARDED_FOR'):
+        ip = request.META['HTTP_X_FORWARDED_FOR']
+    else:
+        ip = request.META['REMOTE_ADDR']
+    if "," in ip:
+        ip = ip.split(",")[0]
+    return ip

BIN
src/common/core_views.pyc


+ 227 - 0
src/common/custom_tools.py

@@ -0,0 +1,227 @@
+#coding=utf-8
+'''
+Created on 2017年11月14日
+
+@author: bailiangjun
+'''
+def change_dict_p2m(item,p2m,ms=[],ems=[]):
+    """
+    @attention: 把指定信息的关键字换成对应的模型字段m
+    @param item: 默认为 {p:值}
+    @note: 
+    {p:值} ==> {m:值}
+    如果传入指定序列ps,则只取序列中的值
+    如果传入指定序列eps,则取除eps以外的值
+    """
+    if not item:
+        return {}
+    
+    if not ms:
+        ms = set(p2m.itervalues())
+    temp = {p:m for p,m in p2m.iteritems() if (m in ms) and (m not in ems)}
+    return {m:item.get(p,"") for p,m in temp.iteritems()}
+
+def change_dict_m2p(item,p2m,ms=[],ems=[]):
+    """
+    @attention: 把指定信息的关键字换成对应的api协议字段
+    @param item: 默认为 {m:值}
+    @note: 
+    {m:值} ==> {p:值}
+    如果传入指定序列ps,则只取序列中的值
+    如果传入指定序列eps,则取除eps以外的值
+    """
+    if not item:
+        return {}
+    
+    if not ms:
+        ms = set(p2m.itervalues())
+    
+    temp = {p:m for p,m in p2m.iteritems() if (m in ms) and (m not in ems)}
+    return {p:item.get(m,"") for p,m in temp.iteritems()}
+
+
+def change_list_p2m(item,p2m,ms=[],ems=[]):
+    """
+    @attention: 把指定信息的关键字换成对应的模型字段m,针对列表
+    @param item: 默认为 {p:值}
+    @note: 
+    {p:值} ==> {m:值}
+    如果传入指定序列ps,则只取序列中的值
+    如果传入指定序列eps,则取除eps以外的值
+    """
+    if not item:
+        return []
+    
+    if not ms:
+        ms = set(p2m.itervalues())
+    
+    temp = {p:m for p,m in p2m.iteritems() if (m in ms) and (m not in ems)}
+
+    return map(lambda x:{m:x.get(p,"") for p,m in temp.iteritems()}, item)
+
+
+def change_list_m2p(item,p2m,ms=[],ems=[]):
+    """
+    @attention: 把指定信息的关键字换成对应的api协议字段,针对列表
+    @param item: 默认为 {m:值}
+    @note: 
+    {m:值} ==> {p:值}
+    如果传入指定序列ps,则只取序列中的值
+    如果传入指定序列eps,则取除eps以外的值
+    """
+    if not item:
+        return []
+    
+    if not ms:
+        ms = set(p2m.itervalues())
+    
+    temp = {p:m for p,m in p2m.iteritems() if (m in ms) and (m not in ems)}
+    return map(lambda x:{p:x.get(m,"") for p,m in temp.iteritems()}, item)
+
+
+def change_node_m2p(item, p2m, ms=[], ems=[]):
+    """
+    @attention: 把指定信息的关键字换成对应的api协议字段,针对列表
+    @param item: 默认为 {m:值}
+    @note:
+    {m:值} ==> {p:值}
+    如果传入指定序列ps,则只取序列中的值
+    如果传入指定序列eps,则取除eps以外的值
+    """
+    if not item:
+        return []
+
+    if not ms:
+        ms = set(p2m.itervalues())
+
+    temp = {p: m for p, m in p2m.iteritems() if (m in ms) and (m not in ems)}
+    return map(lambda x: {p: x.get(m, "") for p, m in temp.iteritems()}, item)
+
+
+def transfer_top_info(info, lkey, tkey):
+    """
+    @attention: 转换top数据给前端
+    @note:
+            由 二维数组[[标签,值],[]]---> [{label:标签,"times":值}]
+    """
+    return [{"name": item[lkey], "value": item[tkey]} for item in info]
+
+
+def transfer_list_info(info, params):
+    """
+    @attention: 转换趋势数据给前端
+    """
+    if not info:
+        return {"axis_x": [], "axis_y": {}}
+
+    if isinstance(params, list):
+        params = {item: [item] for item in params}
+
+    print params
+
+    pkeys = params.keys()
+    if len(pkeys) == 1:
+        key = pkeys[0]
+        inkeys = params[key]
+        inkeys = inkeys if inkeys else [key]
+        v = info[key]
+        axis_x = [item["dt"] for item in v]
+        axis_y = {}
+        for ik in inkeys:
+            axis_y[ik] = [item[ik] for item in v]
+    else:
+        axis_y = {}
+        for key in pkeys:
+            inkeys = params[key]
+            inkeys = inkeys if inkeys else [key]
+            v = info[key]
+            axis_x = [item["dt"] for item in v]
+            for ik in inkeys:
+                axis_y[ik] = [item[ik] for item in v]
+
+    return {"axis_x": axis_x, "axis_y": axis_y}
+
+
+def classify_access_statistic_info(info):
+    """
+    @attention: 区分access统计数据项
+    """
+    total_values = []
+    list_values = []
+    top_values = {}
+    if info.has_key("total_hit_flow"):
+        total_values.append("hit_flow")
+
+    if info.has_key("total_hit_num"):
+        total_values.append("hit_total")
+
+    if info.has_key("total_req_flow"):
+        total_values.append("req_flow")
+
+    if info.has_key("total_req_num"):
+        total_values.append("req_total")
+
+    if info.has_key("tendency_pv"):
+        list_values.append("pageview")
+
+    if info.has_key("tendency_quote"):
+        list_values.append("search")
+
+    if info.has_key("tendency_req_flow"):
+        list_values.append("req_flow")
+        list_values.append("hit_flow")
+
+    if info.has_key("tendency_req_num"):
+        list_values.append("req_total")
+        list_values.append("hit_total")
+
+    if info.has_key("tendency_ip"):
+        list_values.append("ip_num")
+
+    if info.get("top_location"):
+        top_values["location"] = int(info["top_location"])
+    if info.get("top_location_flow"):
+        top_values["location"] = int(info["top_location_flow"])
+
+    return total_values, list_values, top_values
+
+
+def classify_waf_statistic_info(info):
+    """
+    @attention: 区分waf统计数据项
+    """
+    total_values = []
+    list_values = []
+    top_values = {}
+    if info.has_key("level"):
+        total_values.append("level")
+
+    if info.has_key("total_cc") or info.has_key("total_web"):
+        total_values.append("att_num")
+
+    if info.has_key("total_ip"):
+        total_values.append("ip_num")
+
+    if info.has_key("tendency_attack"):
+        list_values.append("att_num")
+
+    if info.get("top_ip"):
+        top_values["src_ip"] = int(info["top_ip"])
+
+    if info.get("top_location"):
+        top_values["location"] = int(info["top_location"])
+
+    if info.get("top_type"):
+        top_values["rule"] = int(info["top_type"])
+
+    if info.get("top_site"):
+        top_values["domain"] = int(info["top_site"])
+
+    return total_values, list_values, top_values
+
+
+def dict_unicode2str(**params):
+    item = {}
+    for k in params:
+        item[str(k)] = str(params[k])
+    return str(item)

+ 40 - 0
src/common/error_info.py

@@ -0,0 +1,40 @@
+#coding=utf-8
+'''
+@attention: 异常定义模块
+'''
+class TipException(Exception):
+    """
+    @attention: 提示类异常,用于业务阻断时,直接返回请求
+    """
+    def __init__(self,msg):
+        self.msg = msg
+        
+    def show_msg(self):
+        return self.msg
+
+class ReasonException(Exception):
+    """
+    只需要原因的日志
+    """
+
+    def __init__(self, msg, module_name, msg_template):
+        """
+
+        :param msg:
+        :param module_name:
+        :param msg_template:  必须接收 reason参数
+        """
+        self.msg = msg
+        self.module_name = module_name
+        self.msg_template = msg_template
+
+
+class SpecialReasonException(Exception):
+    """
+    特殊异常
+    """
+    def __init__(self, msg, module_name, msg_template, inner_info):
+        self.msg_template = msg_template
+        self.module_name = module_name
+        self.msg = msg
+        self.inner_info = inner_info

BIN
src/common/error_info.pyc


+ 33 - 0
src/common/excel_output.py

@@ -0,0 +1,33 @@
+# coding:utf-8
+import StringIO
+import xlwt
+import zipfile
+import datetime
+import random, string
+import os
+from ftplib import FTP
+
+def save2memory(en_cn_map, content):
+    """
+    保存内容到xls里面
+    :param en_cn_map:  英文中文对应字典 {"name": "名字"}, OrderedDict
+    :param content:
+    :return:
+    """
+    wb = xlwt.Workbook(encoding="utf-8")
+    sheet = wb.add_sheet('info')
+    sort_head = en_cn_map.keys()
+    for i, item in enumerate(en_cn_map):
+        sheet.write(0, i, en_cn_map.get(item))
+    for row, item in enumerate(content):
+        sort_key = item.keys()
+        for key in sort_key:
+            if key not in sort_head:
+                continue
+            sheet.write(row+1, sort_head.index(key), item.get(key, ''))
+    output = StringIO.StringIO()
+    wb.save(output)
+    return output.getvalue()
+
+if __name__ == '__main__':
+    pass

BIN
src/common/font/consola.ttf


+ 39 - 0
src/common/logger.py

@@ -0,0 +1,39 @@
+#coding=utf-8
+'''
+Created on 2017年10月24日
+
+@author: bailiangjun
+'''
+import logging
+
+import settings
+
+logger = logging.getLogger('cloudwaf_defense')
+
+# 设置logger的level为DEBUG
+if settings.DEBUG:
+    logger.setLevel(logging.DEBUG)
+else:
+    logger.setLevel(logging.WARN)
+
+# 创建一个输出日志到控制台的StreamHandler
+hdr = logging.StreamHandler()
+
+# str_info = ["name","levelno","levelname","pathname","filename","module","funcName","created","asctime","threadName","message"]
+# int_info = ["lineno","msecs","relativeCreated","thread","process"]
+
+formatter = logging.Formatter("[%(asctime)s %(levelname)s]<%(name)s %(pathname)s %(lineno)s>:%(message)s")
+hdr.setFormatter(formatter)
+# 给logger添加上handler
+logger.addHandler(hdr)
+    
+def critical(msg,*args):
+    """
+    @attention: 考虑添加邮件系统/短信系统通知
+    """
+    logger.critical(msg,*args)
+
+
+
+if __name__ == '__main__':
+    logger.critical("ss%s")

BIN
src/common/logger.pyc


+ 284 - 0
src/common/migrations/0001_initial.py

@@ -0,0 +1,284 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2020-12-23 14:26
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Article',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('journal_id', models.IntegerField(verbose_name='\u671f\u520aid')),
+                ('name', models.CharField(max_length=50, verbose_name='\u671f\u520a\u540d\u79f0')),
+                ('img', models.TextField(verbose_name='\u5c01\u9762\u56fe\u7247')),
+                ('desc', models.TextField(verbose_name='\u671f\u520a\u63cf\u8ff0')),
+                ('content', models.TextField(verbose_name='\u671f\u520a\u63cf\u8ff0')),
+                ('author', models.CharField(blank=True, max_length=100, null=True, verbose_name='\u4e3b\u7f16')),
+                ('read_num', models.IntegerField(default=0, verbose_name='\u9605\u8bfb\u91cf')),
+                ('forward_num', models.IntegerField(default=0, verbose_name='\u8f6c\u53d1\u91cf')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_article',
+                'verbose_name': '\u7cbe\u54c1\u5bfc\u8bfb',
+            },
+        ),
+        migrations.CreateModel(
+            name='Banners',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u5e7f\u544a\u540d\u79f0')),
+                ('img', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u8df3\u8f6c\u94fe\u63a5')),
+                ('url', models.TextField(blank=True, max_length=255, null=True, verbose_name='\u8df3\u8f6c\u94fe\u63a5')),
+                ('is_active', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_banners',
+                'verbose_name': 'Banner\u4f4d\u7ba1\u7406',
+            },
+        ),
+        migrations.CreateModel(
+            name='ColdWord',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=50, verbose_name='\u671f\u520a\u540d\u79f0')),
+                ('is_active', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_coldword',
+                'verbose_name': '\u51b7\u8bcd',
+            },
+        ),
+        migrations.CreateModel(
+            name='HotWord',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=50, verbose_name='\u671f\u520a\u540d\u79f0')),
+                ('is_active', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_hotword',
+                'verbose_name': '\u70ed\u8bcd',
+            },
+        ),
+        migrations.CreateModel(
+            name='Image',
+            fields=[
+                ('image_id', models.CharField(max_length=50, primary_key=True, serialize=False, verbose_name='\u56fe\u7247id')),
+                ('image_url', models.TextField(blank=True, null=True, verbose_name='\u4e8c\u7ef4\u7801')),
+                ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_image',
+                'verbose_name': '\u56fe\u7247\u5e93',
+            },
+        ),
+        migrations.CreateModel(
+            name='Journal',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('journal_id', models.CharField(blank=True, max_length=50, null=True, verbose_name='\u5355\u4f4did')),
+                ('organizer_id', models.IntegerField(blank=True, null=True, verbose_name='\u5b66\u79d1id')),
+                ('subject_id', models.IntegerField(blank=True, null=True, verbose_name='\u5b66\u79d1id')),
+                ('name', models.CharField(max_length=50, verbose_name='\u671f\u520a\u540d\u79f0')),
+                ('cname', models.CharField(max_length=255, verbose_name='\u671f\u520a\u4e2d\u6587\u540d\u79f0')),
+                ('ename', models.CharField(max_length=255, verbose_name='\u671f\u520a\u82f1\u6587\u540d\u79f0')),
+                ('img', models.TextField(verbose_name='\u5c01\u9762\u56fe\u7247')),
+                ('wxcode', models.CharField(blank=True, max_length=50, null=True, verbose_name='\u5fae\u4fe1\u53f7')),
+                ('desc', models.TextField(verbose_name='\u671f\u520a\u63cf\u8ff0')),
+                ('qrcode', models.TextField(blank=True, null=True, verbose_name='\u4e8c\u7ef4\u7801')),
+                ('languages', models.CharField(max_length=50, verbose_name='\u8bed\u8a00')),
+                ('editor', models.CharField(blank=True, max_length=100, null=True, verbose_name='\u4e3b\u7f16')),
+                ('publishingUnit', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u4e3b\u529e\u5355\u4f4d')),
+                ('publishingTime', models.CharField(blank=True, max_length=50, null=True, verbose_name='\u4e3b\u529e\u5355\u4f4d')),
+                ('publishingCycle', models.CharField(blank=True, max_length=50, null=True, verbose_name='\u4e3b\u529e\u5355\u4f4d')),
+                ('domestic', models.CharField(blank=True, max_length=50, null=True, verbose_name='\u56fd\u5185\u520a\u53f7')),
+                ('isn', models.CharField(blank=True, max_length=50, null=True, verbose_name='\u56fd\u9645\u520a\u53f7')),
+                ('website', models.CharField(blank=True, max_length=100, null=True, verbose_name='\u671f\u520a\u5b98\u7f51')),
+                ('corganizers', models.CharField(blank=True, max_length=100, null=True, verbose_name='\u6240\u5c5e\u673a\u6784')),
+                ('editorialAddress', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u7f16\u8f91\u90e8\u5730\u5740')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_journal',
+                'verbose_name': '\u671f\u520a\u4fe1\u606f',
+            },
+        ),
+        migrations.CreateModel(
+            name='OperationLog',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('op_user_name', models.CharField(max_length=255, verbose_name='\u64cd\u4f5c\u5458\u540d\u79f0')),
+                ('op_user_realname', models.CharField(max_length=255, verbose_name='\u64cd\u4f5c\u5458\u59d3\u540d')),
+                ('op_user_id', models.IntegerField(verbose_name='\u64cd\u4f5c\u5458id')),
+                ('op_user_ip', models.CharField(max_length=100, verbose_name='\u64cd\u4f5c\u5458ip')),
+                ('op_request', models.TextField(default=b'', verbose_name='request body')),
+                ('is_suc', models.BooleanField(default=True, verbose_name='\u662f\u5426\u6210\u529f')),
+                ('error_msg', models.TextField(blank=True, max_length=255, null=True, verbose_name='\u9519\u8bef\u4fe1\u606f')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'oplog',
+                'verbose_name': '\u64cd\u4f5c\u65e5\u5fd7',
+            },
+        ),
+        migrations.CreateModel(
+            name='OperationLogConfig',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('op_view', models.CharField(blank=True, max_length=100, null=True, verbose_name='\u64cd\u4f5c\u6a21\u5757')),
+                ('op_action_flag', models.CharField(max_length=50, verbose_name='\u64cd\u4f5c\u7c7b\u578b')),
+                ('op_module', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u64cd\u4f5c\u6a21\u5757')),
+                ('op_template', models.TextField(verbose_name='\u64cd\u4f5c\u65e5\u5fd7\u6a21\u677f')),
+                ('op_url', models.CharField(max_length=255, verbose_name='URL')),
+                ('op_response', models.TextField(blank=True, max_length=255, null=True, verbose_name='URL')),
+                ('order', models.IntegerField(blank=True, null=True, verbose_name='\u6392\u5e8f\u5b57\u6bb5')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'oplog_config',
+                'verbose_name': '\u64cd\u4f5c\u65e5\u5fd7\u914d\u7f6e',
+            },
+        ),
+        migrations.CreateModel(
+            name='Organizer',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('organizer_id', models.CharField(blank=True, max_length=50, null=True, verbose_name='\u5355\u4f4did')),
+                ('name', models.CharField(max_length=50, verbose_name='\u5355\u4f4d\u540d\u79f0')),
+                ('img', models.TextField(verbose_name='\u5c01\u9762\u56fe\u7247')),
+                ('desc', models.TextField(verbose_name='\u5355\u4f4d\u63cf\u8ff0')),
+                ('order', models.IntegerField(default=0, verbose_name='\u6392\u5e8f\u5b57\u6bb5')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_organizer',
+                'verbose_name': '\u671f\u520a\u4fe1\u606f',
+            },
+        ),
+        migrations.CreateModel(
+            name='Permission',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u540d\u5b57')),
+                ('module_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u6a21\u5757\u540d\u79f0')),
+                ('code', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u6743\u9650')),
+                ('pid', models.IntegerField(blank=True, null=True, verbose_name='\u7236\u7ea7id')),
+                ('order', models.IntegerField(blank=True, null=True, verbose_name='\u6392\u5e8f\u5b57\u6bb5')),
+            ],
+            options={
+                'db_table': 'ted_permission',
+                'verbose_name': '\u6743\u9650',
+            },
+        ),
+        migrations.CreateModel(
+            name='Role',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u540d\u5b57')),
+                ('permissions', models.TextField(blank=True, null=True, verbose_name='\u6743\u9650')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('cid', models.IntegerField(verbose_name='\u521b\u5efa\u4ebaid')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_role',
+                'verbose_name': '\u89d2\u8272',
+            },
+        ),
+        migrations.CreateModel(
+            name='SenWord',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=50, verbose_name='\u671f\u520a\u540d\u79f0')),
+                ('is_active', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_senword',
+                'verbose_name': '\u654f\u611f\u8bcd',
+            },
+        ),
+        migrations.CreateModel(
+            name='Subject',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('subject_id', models.CharField(blank=True, max_length=50, null=True, verbose_name='\u5355\u4f4did')),
+                ('name', models.CharField(max_length=50, verbose_name='\u5355\u4f4d\u540d\u79f0')),
+                ('desc', models.TextField(verbose_name='\u5355\u4f4d\u63cf\u8ff0')),
+                ('order', models.IntegerField(default=0, verbose_name='\u6392\u5e8f\u5b57\u6bb5')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_subject',
+                'verbose_name': '\u671f\u520a\u4fe1\u606f',
+            },
+        ),
+        migrations.CreateModel(
+            name='SysUserInfo',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u540d\u5b57')),
+                ('phone', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u624b\u673a\u53f7')),
+                ('password', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u5bc6\u7801')),
+                ('realname', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u771f\u5b9e\u540d\u79f0')),
+                ('permissions', models.TextField(blank=True, null=True, verbose_name='\u6743\u9650')),
+                ('is_active', models.SmallIntegerField(default=0, verbose_name='\u662f\u5426\u6fc0\u6d3b\u53ef\u7528')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_sys_users',
+                'verbose_name': '\u7cfb\u7edf\u7528\u6237\u4fe1\u606f',
+            },
+        ),
+        migrations.CreateModel(
+            name='UserInfo',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u540d\u5b57')),
+                ('phone', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u624b\u673a\u53f7')),
+                ('password', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u5bc6\u7801')),
+                ('realname', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u771f\u5b9e\u540d\u79f0')),
+                ('permissions', models.TextField(blank=True, null=True, verbose_name='\u6743\u9650')),
+                ('is_active', models.SmallIntegerField(default=0, verbose_name='\u662f\u5426\u6fc0\u6d3b\u53ef\u7528')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_users',
+                'verbose_name': '\u7528\u6237\u4fe1\u606f',
+            },
+        ),
+        migrations.AddField(
+            model_name='operationlog',
+            name='op_config',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='common.OperationLogConfig'),
+        ),
+    ]

BIN
src/common/migrations/0001_initial.pyc


+ 27 - 0
src/common/migrations/0002_auto_20201223_1427.py

@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2020-12-23 14:27
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('common', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='journal',
+            name='journal_id',
+        ),
+        migrations.RemoveField(
+            model_name='organizer',
+            name='organizer_id',
+        ),
+        migrations.RemoveField(
+            model_name='subject',
+            name='subject_id',
+        ),
+    ]

BIN
src/common/migrations/0002_auto_20201223_1427.pyc


+ 30 - 0
src/common/migrations/0003_auto_20201223_1428.py

@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2020-12-23 14:28
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('common', '0002_auto_20201223_1427'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='journal',
+            name='journal_id',
+            field=models.CharField(blank=True, max_length=50, null=True, verbose_name='\u5355\u4f4did'),
+        ),
+        migrations.AddField(
+            model_name='organizer',
+            name='organizer_id',
+            field=models.CharField(blank=True, max_length=50, null=True, verbose_name='\u5355\u4f4did'),
+        ),
+        migrations.AddField(
+            model_name='subject',
+            name='subject_id',
+            field=models.CharField(blank=True, max_length=50, null=True, verbose_name='\u5355\u4f4did'),
+        ),
+    ]

BIN
src/common/migrations/0003_auto_20201223_1428.pyc


+ 27 - 0
src/common/migrations/0004_journalorganizer.py

@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2020-12-23 14:34
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('common', '0003_auto_20201223_1428'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='JournalOrganizer',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('organizer_id', models.IntegerField(blank=True, null=True, verbose_name='\u5355\u4f4did')),
+                ('journal_id', models.IntegerField(blank=True, null=True, verbose_name='\u671f\u520aid')),
+            ],
+            options={
+                'db_table': 'ted_journal_organizer',
+                'verbose_name': '\u671f\u520a\u5355\u4f4d\u5173\u8054\u8868',
+            },
+        ),
+    ]

BIN
src/common/migrations/0004_journalorganizer.pyc


+ 20 - 0
src/common/migrations/0005_auto_20201223_1603.py

@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2020-12-23 16:03
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('common', '0004_journalorganizer'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='journal',
+            old_name='isn',
+            new_name='issn',
+        ),
+    ]

BIN
src/common/migrations/0005_auto_20201223_1603.pyc


+ 22 - 0
src/common/migrations/0006_article_publish_time.py

@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2020-12-23 17:01
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('common', '0005_auto_20201223_1603'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='article',
+            name='publish_time',
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now, verbose_name='\u51fa\u7248\u65f6\u95f4'),
+            preserve_default=False,
+        ),
+    ]

BIN
src/common/migrations/0006_article_publish_time.pyc


+ 20 - 0
src/common/migrations/0007_article_article_id.py

@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2020-12-23 17:43
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('common', '0006_article_publish_time'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='article',
+            name='article_id',
+            field=models.CharField(blank=True, max_length=50, null=True, verbose_name='\u5355\u4f4did'),
+        ),
+    ]

BIN
src/common/migrations/0007_article_article_id.pyc


+ 120 - 0
src/common/migrations/0008_auto_20201224_1714.py

@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2020-12-24 17:14
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('common', '0007_article_article_id'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Conference',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('conference_id', models.CharField(blank=True, max_length=50, null=True, verbose_name='\u4f1a\u8baeid')),
+                ('name', models.CharField(max_length=50, verbose_name='\u671f\u520a\u540d\u79f0')),
+                ('img', models.TextField(verbose_name='\u5c01\u9762\u56fe\u7247')),
+                ('organizer_id', models.IntegerField(blank=True, null=True, verbose_name='\u5b66\u79d1id')),
+                ('begin_time', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('end_time', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('province', models.CharField(max_length=50, verbose_name='\u7701')),
+                ('city', models.CharField(max_length=50, verbose_name='\u5e02')),
+                ('area', models.CharField(max_length=50, verbose_name='\u533a')),
+                ('address', models.TextField(verbose_name='\u533a')),
+                ('desc', models.TextField(verbose_name='\u7b80\u4ecb')),
+                ('is_signup', models.SmallIntegerField(default=0, verbose_name='\u662f\u5426\u53ef\u62a5\u540d')),
+                ('signup_fields', models.TextField(verbose_name='\u62a5\u540d\u4fe1\u606f\u5b57\u6bb5')),
+                ('signup_number', models.IntegerField(default=0, verbose_name='\u62a5\u540d\u4eba\u6570')),
+                ('is_popular', models.SmallIntegerField(default=0, verbose_name='\u662f\u5426\u4e3a\u70ed\u95e8')),
+                ('is_recommend', models.SmallIntegerField(default=0, verbose_name='\u662f\u5426\u63a8\u8350')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('cid', models.IntegerField(verbose_name='\u521b\u5efa\u4ebaid')),
+                ('cname', models.CharField(max_length=50, verbose_name='\u521b\u5efa\u4eba')),
+                ('upid', models.IntegerField(verbose_name='\u521b\u5efa\u4ebaid')),
+                ('upname', models.CharField(max_length=50, verbose_name='\u4fee\u6539\u4eba')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_conference',
+                'verbose_name': '\u4f1a\u8bae\u4fe1\u606f',
+            },
+        ),
+        migrations.CreateModel(
+            name='ConferenceHotel',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('conference_id', models.IntegerField(verbose_name='\u4f1a\u8baeid')),
+                ('hotel_id', models.IntegerField(verbose_name='\u9152\u5e97id')),
+                ('order', models.IntegerField(default=0, verbose_name='\u6392\u5e8f\u5b57\u6bb5')),
+            ],
+            options={
+                'db_table': 'ted_conference_hotel',
+                'verbose_name': '\u4f1a\u8bae\u9152\u5e97\u5173\u8054\u8868',
+            },
+        ),
+        migrations.CreateModel(
+            name='Hotel',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=50, verbose_name='\u671f\u520a\u540d\u79f0')),
+                ('address', models.CharField(max_length=255, verbose_name='\u5730\u5740')),
+                ('telephone', models.CharField(max_length=50, verbose_name='\u8054\u7cfb\u7535\u8bdd')),
+                ('longitude', models.CharField(max_length=50, verbose_name='\u8054\u7cfb\u7535\u8bdd')),
+                ('latitude', models.CharField(max_length=50, verbose_name='\u8054\u7cfb\u7535\u8bdd')),
+                ('imgs', models.TextField(blank=True, null=True, verbose_name='\u9152\u5e97\u56fe\u7247')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('cid', models.IntegerField(verbose_name='\u521b\u5efa\u4ebaid')),
+                ('cname', models.CharField(max_length=50, verbose_name='\u521b\u5efa\u4eba')),
+                ('upid', models.IntegerField(verbose_name='\u521b\u5efa\u4ebaid')),
+                ('upname', models.CharField(max_length=50, verbose_name='\u4fee\u6539\u4eba')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_hotel',
+                'verbose_name': '\u9152\u5e97',
+            },
+        ),
+        migrations.CreateModel(
+            name='Room',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('hotel_id', models.IntegerField(verbose_name='\u9152\u5e97id')),
+                ('layout_id', models.CharField(max_length=255, verbose_name='\u623f\u578bid')),
+                ('name', models.CharField(max_length=50, verbose_name='\u540d\u79f0')),
+                ('room_type', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('enable_number', models.IntegerField(default=1, verbose_name='\u53ef\u4f4f\u4eba\u6570')),
+                ('room_number', models.IntegerField(default=1, verbose_name='\u5ba2\u623f\u6570\u91cf')),
+                ('surplus_number', models.IntegerField(default=0, verbose_name='\u5269\u4f59\u5ba2\u623f\u6570\u91cf')),
+                ('room_area', models.IntegerField(default=0, verbose_name='\u9762\u79ef')),
+                ('floor', models.IntegerField(default=0, verbose_name='\u697c\u5c42')),
+                ('bed_type', models.CharField(max_length=50, verbose_name='\u5e8a\u578b')),
+                ('food_condition', models.CharField(max_length=255, verbose_name='\u9910\u98df\u60c5\u51b5')),
+                ('window_condition', models.CharField(max_length=255, verbose_name='\u9910\u98df\u60c5\u51b5')),
+                ('imgs', models.TextField(blank=True, null=True, verbose_name='\u623f\u578b\u56fe\u7247')),
+                ('unit_price', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True, verbose_name='\u623f\u578b\u56fe\u7247')),
+                ('order', models.IntegerField(default=0, verbose_name='\u6392\u5e8f\u5b57\u6bb5')),
+                ('status', models.SmallIntegerField(default=1, verbose_name='\u72b6\u6001')),
+                ('cid', models.IntegerField(verbose_name='\u521b\u5efa\u4ebaid')),
+                ('cname', models.CharField(max_length=50, verbose_name='\u521b\u5efa\u4eba')),
+                ('upid', models.IntegerField(verbose_name='\u521b\u5efa\u4ebaid')),
+                ('upname', models.CharField(max_length=50, verbose_name='\u4fee\u6539\u4eba')),
+                ('ctime', models.DateTimeField(auto_now_add=True, verbose_name='\u521b\u5efa\u65f6\u95f4')),
+                ('uptime', models.DateTimeField(auto_now_add=True, verbose_name='\u4fee\u6539\u65f6\u95f4')),
+            ],
+            options={
+                'db_table': 'ted_room',
+                'verbose_name': '\u9152\u5e97\u623f\u95f4',
+            },
+        ),
+        migrations.RemoveField(
+            model_name='journal',
+            name='organizer_id',
+        ),
+    ]

BIN
src/common/migrations/0008_auto_20201224_1714.pyc


+ 0 - 0
src/common/migrations/0009_auto_20201224_2310.py


Някои файлове не бяха показани, защото твърде много файлове са промени