Gogs 5 лет назад
Родитель
Сommit
5bfc87cd2c
100 измененных файлов с 4324 добавлено и 3215 удалено
  1. 1 0
      src/account/control_user.py
  2. 2 2
      src/account/password_handle.py
  3. 2 13
      src/account/urls_backstage.py
  4. 4 36
      src/account/views.py
  5. 1 181
      src/account/views_backstage.py
  6. 181 0
      src/bzyifeng/templates/apidoc.html.bk
  7. 10 6
      src/bzyifeng/views.py
  8. 0 127
      src/common/common_control.py
  9. 22 0
      src/common/common_functions.py
  10. 70 0
      src/common/common_notice.py
  11. 66 50
      src/common/core_views.py
  12. 134 3
      src/common/models.py
  13. 0 7
      src/dashboard/control_dashboard.py
  14. 0 52
      src/dashboard/test_case/test_control_dashboard.py
  15. 0 19
      src/dashboard/urls_backstage.py
  16. 0 97
      src/dashboard/views_backstage.py
  17. 0 0
      src/manage/__init__.py
  18. 78 0
      src/manage/cauth.py
  19. 82 0
      src/manage/control_auth.py
  20. 0 0
      src/manage/control_bankcard.py
  21. 0 0
      src/manage/control_department.py
  22. 0 0
      src/manage/control_organization.py
  23. 0 0
      src/manage/control_permission.py
  24. 0 0
      src/manage/control_role.py
  25. 3 2
      src/weixin/control_user.py
  26. 1603 0
      src/manage/controls.py
  27. 0 0
      src/manage/lock_account.py
  28. 6 0
      src/manage/models.py
  29. 41 0
      src/manage/password_handle.py
  30. 39 0
      src/manage/urls_backstage.py
  31. 1066 0
      src/manage/views.py
  32. 0 0
      src/manage/views_backstage.py
  33. 0 0
      src/manage/views_permission.py
  34. 342 0
      src/manage/wzhifuSDK.py
  35. 5 2
      src/operation_log/OpLogMiddleware.py
  36. 0 0
      src/script/__init__.py
  37. 0 36
      src/script/start_collect_mtask_result.py
  38. 0 78
      src/script/start_collect_mtask_result_available.py
  39. 0 93
      src/script/start_collect_mtask_result_bug.py
  40. 0 76
      src/script/start_collect_mtask_result_content.py
  41. 0 54
      src/script/start_collect_mtask_result_poc.py
  42. 0 74
      src/script/start_collect_mtask_result_webshell.py
  43. 2 2
      src/settings/base.py
  44. 0 80
      src/settings/settings_online.py
  45. 1 10
      src/settings/settings_test.py
  46. BIN
      src/templates/157883436884.docx
  47. BIN
      src/templates/18920987654.docx
  48. BIN
      src/templates/24.docx
  49. BIN
      src/templates/9.docx
  50. BIN
      src/templates/apply_template.docx
  51. BIN
      src/templates/apply_template_aqxy.docx
  52. BIN
      src/templates/apply_template_cyry.docx
  53. BIN
      src/templates/apply_template_tzzy.docx
  54. BIN
      src/templates/classhour.png
  55. BIN
      src/templates/font/consola.ttf
  56. BIN
      src/templates/font/simkai.ttf
  57. BIN
      src/templates/font/simsun.ttc
  58. BIN
      src/templates/kqqd.xls
  59. BIN
      src/templates/kqqd.xlsx
  60. BIN
      src/templates/ksqd.xls
  61. BIN
      src/templates/pxqd.xls
  62. BIN
      src/templates/qtcy.xls
  63. BIN
      src/templates/szksqd.xls
  64. BIN
      src/templates/test.xlsx
  65. BIN
      src/templates/tzzy.xls
  66. BIN
      src/templates/tzzy_bk.xls
  67. BIN
      src/templates/tzzykssbb.xls
  68. BIN
      src/templates/xxkqqd.xls
  69. BIN
      src/templates/zyfzr.xls
  70. BIN
      src/templates/肖小肖_低压电工.docx
  71. BIN
      src/templates/谭燕飞.docx
  72. 0 0
      src/tools/__init__.py
  73. 32 0
      src/tools/check_update_change_time.py
  74. 1 4
      src/urls.py
  75. 0 97
      src/utils/aliyun_email.py
  76. 158 0
      src/utils/aliyun_sms.py
  77. 0 164
      src/utils/cloopen_sms.py
  78. 0 29
      src/utils/constant.py
  79. 0 134
      src/utils/email_client.py
  80. 14 1
      src/utils/exceltool.py
  81. 0 163
      src/utils/website_info_collect/Logger.py
  82. 0 45
      src/utils/website_info_collect/Readme.md
  83. 0 0
      src/utils/website_info_collect/__init__.py
  84. 0 377
      src/utils/website_info_collect/beian.py
  85. 0 60
      src/utils/website_info_collect/config.py
  86. BIN
      src/utils/website_info_collect/ipip.ipdb
  87. 0 89
      src/utils/website_info_collect/ipip.py
  88. 0 377
      src/utils/website_info_collect/main.py
  89. 0 3
      src/utils/website_info_collect/requirements.txt
  90. 0 4
      src/utils/website_info_collect/test.py
  91. 10 34
      src/weixin/control_auth.py
  92. 0 97
      src/weixin/control_bankcard.py
  93. 0 81
      src/weixin/control_department.py
  94. 0 129
      src/weixin/control_organization.py
  95. 0 36
      src/weixin/control_permission.py
  96. 271 155
      src/weixin/controls.py
  97. 5 1
      src/weixin/urls_backstage.py
  98. 72 31
      src/weixin/views.py
  99. 0 4
      src/weixin/views_permission.py
  100. 0 0
      src/weixin/wzhifuSDK.py

+ 1 - 0
src/account/control_user.py

@@ -189,6 +189,7 @@ 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.*.*"]

+ 2 - 2
src/account/password_handle.py

@@ -34,8 +34,8 @@ def make_default_password(pwd):
     return pwd,hashlib.md5(pwd).hexdigest().upper()
 
 if __name__ == '__main__':
-    old = "123456"
+    old = "root"
     op = make_password(old)
-    # print op
+    print op
     new = "123456"
     # print check_password(new, op)

+ 2 - 13
src/account/urls_backstage.py

@@ -6,24 +6,13 @@ from account import views,views_backstage
 
 urlpatterns = [
     # 运营
-    url(r'^auth$', views.LoginView.as_view()),
+    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'^idcode$', views.CaptchaView.as_view()),
-    url(r'^phcode$', views.GetPhoneCodeView.as_view()),
+    url(r'^imgcode$', views.CaptchaView.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()),
 ]
 

+ 4 - 36
src/account/views.py

@@ -11,38 +11,6 @@ from common import core_views as cv
 from common.captcha import create_idcode
 from common.models import UserInfo
 import control_user as cr
-from utils.cloopen_sms import cloopensms
-
-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):
@@ -59,10 +27,10 @@ class LoginView(cv.BaseView):
     def post(self, request):
         """
         #账号登录
-        @username:"root",用户名
-        @pwd:"",密码
-        @captcha_id:"erwerkkk",图形验证码接口返回的
-        @idcode:"erwe",图形验证码
+        @username:"root",str,账号
+        @password:"root",str,密码
+        @imgcode_id:"erwerkkk",图形验证码接口返回的
+        @imgcode:"erwe",图形验证码
         """
         try:
             cr.login_user(request)

+ 1 - 181
src/account/views_backstage.py

@@ -10,15 +10,9 @@ from common.models import UserInfo
 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.AuthView):
+class InfoView(cv.AdminView):
     def get(self, request):
         '''
         #获取全局账号信息(权限控制)
@@ -123,177 +117,3 @@ class UserListView(cv.AuthView):
             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)

+ 181 - 0
src/bzyifeng/templates/apidoc.html.bk

@@ -0,0 +1,181 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title></title>
+	<style type="text/css">
+		.container{
+			width: 100%;
+		}
+		.left{
+			position:fixed;
+			width: 20%;
+			float: left;
+			border-right:1px solid #ccc;
+			height: 100%;
+            overflow:scroll;
+		}
+		.right{
+			width:79%;
+			float: right;
+			height: 100%;
+			padding-top:5px;
+		}
+		.clear{
+			clear: both;
+		}
+		label{
+			display: block;
+			margin:10px 0px;
+		}
+		a{
+			text-decoration: none;
+		}
+		.delapi{
+			float: right;
+			margin-right: 10px;
+			cursor: pointer;
+		}
+	</style>
+</head>
+<body>
+	<div class="container">
+		<div class="left">
+            {% if project_name %}
+            <h3>{{project_name}}接口文档</h3>
+            {% endif %}
+			<ol>
+				<input id="search" type="text" style="width: 95%;margin-bottom: 10px;height: 25px;border-radius: 3px;border: 1px solid #ccc;" placeholder="请输入接口名称">
+				{% for api in apis %}
+				<li draggable="true" id="{{api.id}}"><a href="#{{api.url}}{{api.method}}" >{{api.title}}</a>
+					{% if isroot %}
+					<button class="delapi">x</button>
+					{% endif %}
+				</li>
+				{% endfor %}
+			</ol>
+		</div>
+		<div class="right">
+			{% for api in apis %}
+				<div id="{{api.url}}{{api.method}}">
+					<div style="background: #ccc;margin-top:20px;">
+						<b><font class="url">{{api.url}}</font> &nbsp;&nbsp;&nbsp;&nbsp;<font class="method">{{api.method}}</font></b>
+						<button style="margin-left:50px;padding:0px;">发送请求</button>
+					</div>
+					<label>参数:</label>
+					<div style="margin-left:25px;">
+						{% if api.params %}
+                            <textarea class="request" cols="80" rows="20">{{api.request}}</textarea>
+						{% else %}
+						无
+						{% endif %}
+					</div>
+					<label>响应:</label>
+					<div style="margin-left:25px;">
+						{% if api.response %}
+						<textarea class="response" cols="80" rows="20">{{api.response}}</textarea>
+							{% if api.response_note %}
+								<label>说明:</label>
+								<div>{{api.response_note|safe}}</div>
+							{% endif %}
+						{% else %}
+						无
+						{% endif %}
+					</div>
+				</div>
+			{% endfor %}
+		</div>
+		<div class="clear"></div>
+	</div>
+</body>
+<script
+  src="https://code.jquery.com/jquery-1.12.4.min.js"
+  integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
+  crossorigin="anonymous"></script>
+<script type="text/javascript">
+    function insertAfter(newEl, targetEl)
+        {
+            var parentEl = targetEl.parentNode;
+            if(parentEl.lastChild == targetEl)
+                {
+                    parentEl.appendChild(newEl);
+                }else
+                {
+                    parentEl.insertBefore(newEl,targetEl.nextSibling);
+                }            
+        }
+    //
+    //var res = document.getElementsByClassName("request")
+    //for(var i=0;i<res.length;i++){
+    //    res[i].innerHTML = JSON.stringify(JSON.parse(res[i].value),undefined,4) 
+    //}
+    //
+    var res = document.getElementsByClassName("response")
+    for(var i=0;i<res.length;i++){
+        res[i].innerHTML = JSON.stringify(JSON.parse(res[i].value),undefined,4) 
+    }
+
+	//
+	let parent = document.getElementsByTagName("ol")[0]
+	let div = document.getElementsByTagName("li")
+    let container = null
+    for(let i = 0; i < div.length; i++) {
+        div[i].ondragstart = function() {
+            // 当拖动其中一个元素时,this的指向便是你所拖动的元素,将它存在container
+            container = this
+        }
+        // 默认的当你dragover的时候会阻止你做drop的操作,所以需要取消这个默认
+        div[i].ondragover = function() {
+            event.preventDefault()
+        }
+        // 当拖动结束时,给拖动div所在位置下面的div做drop事件,注意drop时this的指向发生改变
+        div[i].ondrop = function()
+        {
+            if(container != null && container != this)
+            {
+                insertAfter(container,this)
+                //let temp = document.createElement("li")
+                //parent.replaceChild(temp,this)
+                //parent.replaceChild(this,container)
+                //parent.replaceChild(container,temp)
+				//
+				let dataobj = []
+				for(var i=0;i<div.length;i++){
+					console.log(div[i].id)
+					let id = div[i].id
+					dataobj.push({"id":id,"order":i})
+				}
+				$(function(){
+					$.ajax({
+						type:"POST",
+						url:"/api/doc/",
+						contentType:"application/json",
+						data:JSON.stringify({"ids":dataobj}),
+						success:function(){
+							window.location.reload();
+						}
+					})
+				})
+            }
+        }
+    }
+	$(function(){
+		$(".delapi").click(function(e){
+			let id = e.target.parentNode.id;
+			$.ajax({
+				type:"DELETE",
+				url:"/api/doc/",
+				contentType:"application/json",
+				data:JSON.stringify({"id":id}),
+				success:function(){
+					window.location.reload();
+				}
+			})
+		});
+	});
+	//
+	$("#search").input(function(){
+		console.log($(this).val());
+	})
+
+</script>
+</html>

+ 10 - 6
src/bzyifeng/views.py

@@ -19,7 +19,8 @@ class DocView(cv.BaseView):
     def get(self,request):
         """
         """
-        modules = list(cm.OperationLogConfig.objects.order_by("order").values("id","op_view","op_action_flag","op_url","op_response"))
+        modules = list(cm.OperationLogConfig.objects.order_by("order").values())
+        print modules
         apis = []
         for mo in modules:
             docstr = None
@@ -43,14 +44,17 @@ class DocView(cv.BaseView):
                     params = "\n".join([x.lstrip("@") for x in re.findall(r'@.*',docstr)]).strip()
                     request_note = "<br>".join([x.lstrip("<") for x in re.findall(r'<.*',docstr)]).strip()
                     response_note = "<br>".join([x.lstrip(">") for x in re.findall(r'>.*',docstr)]).strip()
-                    apis.append({"id":mo["id"],"url":op_url,"title":title,"method":op_action_flag,
-                                 "params":params,"response":response,"response_note":response_note,
-                                "request_note":request_note
-                                })
+                    if u"小程序" not in title or True:
+                        apis.append({"id":mo["id"],"url":op_url,"title":title,"method":op_action_flag,
+                                     "params":params,"response":response,"response_note":response_note,
+                                    "request":mo["op_request"]
+                                    })
             except Exception as e:
-                continue
                 cv.tracefail()
+                continue
         isroot = request.GET.get("root",0)
+        if request.GET.get("json"):
+            return cv.to_suc(apis)
         return render(request,"apidoc.html",{"apis":apis,"isroot":isroot,"project_name":settings.PROJECT_NAME})
 
     def post(self,request):

+ 0 - 127
src/common/common_control.py

@@ -9,125 +9,6 @@ from django.core.paginator import Paginator
 import common.models as cm
 import common.common_functions as ccf
 
-def get_sub_users_info_operation(user_ids,data=None):
-    """
-    运营平台的角色通过创建与被创建,关系来获取,
-    门户平台通过当前用户所属机构及其下属机构来确定
-    """
-    data = data if data else []
-    for user_id in user_ids:
-        user = cm.UserInfo.objects.filter(id=user_id).first()
-        data.append({"id":user.id,"name":user.name,"email":user.email,"phone":user.phone,
-                     "realname":user.realname,"parent_id":user.parent_id,"role__id":user.role.id,"ctime":user.ctime})
-        #获取下一级
-        sub_users = cm.UserInfo.objects.filter(parent_id=user.id)
-        if sub_users:
-            sub_users_ids = list(sub_users.values_list("id",flat=True))
-            get_sub_users_info_operation(sub_users_ids,data)
-    return data
-
-
-def get_sub_organization_tree(oid,data=None):
-    """通过org_id获取组织机构树结构
-    """
-    data = data if data else {}
-    org = cm.Organization.objects.filter(id=oid).first()
-
-    #获取下一级
-    sub_orgs = list(cm.Organization.objects.filter(pid=oid).values("id","sname"))
-    data["id"] = org.id
-    data["tree_label"] = org.sname
-    data["nodes"] = sub_orgs
-    for i,sorg in enumerate(sub_orgs):
-        get_sub_organization_tree(sorg["id"],data["nodes"][i])
-
-    return data
-
-def get_sub_organizations(oids,data=None):
-    """获取当前机构下的所有机构,不返回树形结构
-    """
-    data = data if data else []
-    org = cm.Organization.objects.filter(id__in=oids).first()
-    data.append({"id":org.id,"sname":org.sname})
-    #获取下一级
-    sub_orgs = list(cm.Organization.objects.filter(pid__in=oids).values("id","sname"))
-    if sub_orgs:
-        for sub_org in sub_orgs:
-            get_sub_organizations([sub_org["id"]],data)
-    return data
-
-def get_sub_users(uid,page=None,page_size=None,query=None):
-    """
-    运营平台的角色通过创建与被创建,关系来获取,
-    门户平台通过当前用户所属机构及其下属机构来确定
-    """
-    user = cm.UserInfo.objects.filter(id=uid).first()
-    if not user:
-        return []
-
-    permissions = list(user.role.permission.all().values_list("codename",flat=True))
-    #门户平台 
-    if user.role.platform == "portal":
-        #拥有组织查看权限相当于原来的企业管理员
-        if "SystemManagement.Organization.Check" in permissions:
-            #通过机构查询所以下级机构所有用户包括不是自己创建的
-            org_id = user.organization.id
-            sub_org_ids = get_sub_organizations([org_id])
-            sub_org_ids = map(lambda x:x["id"],sub_org_ids)
-            users = list(cm.UserInfo.objects.filter(
-                organization__id__in=sub_org_ids).values("id","name","email","phone","realname","parent_id","role__id","ctime"))
-        else:
-            #普通用户
-            users = [{"id":user.id,"name":user.name,"email":user.email,"phone":user.phone,
-                      "realname":user.realname,"parent_id":user.parent_id,"role__id":user.role.id,"ctime":user.ctime}]
-    else:
-        users = get_sub_users_info_operation([uid],[])
-    print users,99999
-    if query and query.get("realname"):
-        users = filter(lambda x:query.get("realname") in x["realname"],users)
-    total = len(users)
-    total,users = ccf.get_page_list(users,page,page_size)
-    for user in users:
-        urole = cm.Role.objects.filter(id=user["role__id"]).first()
-        user["role_name"] = urole.name if urole else ""
-
-    return total,users
-
-
-def get_org_root_id(org_id,data=None):
-    """
-    """
-    data = data if data else None
-    org = cm.Organization.objects.filter(id=org_id).first()
-    if not org.pid:
-        data = org.id
-        return data
-    else:
-        return get_org_root_id(org.pid,data)
-
-
-def get_country_list(query={}):
-    """获取国家列表信息
-    """
-    qset = cm.Country.objects.exclude(name=u"中国")
-    if "name" in query:
-        qset = qset.filter(name__icontains=query.get("name"))
-    country_data = list(qset.values())
-    return country_data
-
-def get_city_list(query={}):
-    """获取国家列表信息
-    """
-    qset = City.objects.all()
-    if "name" in query:
-        qset = qset.filter(province__icontains=query.get("name"))
-    city_data = list(qset.values("country","province","province_ename"))
-    new_city_data = []
-    for cd in city_data:
-        if cd not in new_city_data:
-            new_city_data.append(cd)
-    return new_city_data
-
 def cache_data(timeout=60*60):
     def _wrapper(func):
         def __wrapper(*args,**kwargs):
@@ -180,14 +61,6 @@ def get_page_qset(qset,page,page_size=20):
     return count,object_list
 
 
-def get_websites_by_group(group_ids):
-    """
-    """
-    wset = cm.WebSite.objects.filter(group__id__in=group_ids)
-    wdata = list(wset.values_list("id",flat=True))
-    return wdata
-
-
 if __name__ == "__main__":
     #测试
     print get_pparents_info(1550,[])

+ 22 - 0
src/common/common_functions.py

@@ -2,6 +2,28 @@
 import datetime
 import re
 import M2Crypto
+from PIL import Image,ImageDraw
+
+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')
+    #oriImg.show()
+    img.save(path)
+    #Image.open(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"):
     """

+ 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

+ 66 - 50
src/common/core_views.py

@@ -73,14 +73,6 @@ class SignView(View):
             ip = request.META['REMOTE_ADDR']
         return ip
 
-    #def gen_sign(self,timestamp):
-    #    """
-    #    """
-    #    signstr = "client_id={}client_key={}timestamp={}"\
-    #        .format(self.client_id,self.client_key,timestamp)
-    #    md5 = hashlib.md5(signstr).hexdigest().upper()
-    #    return md5
-
     def gen_sign(self,params):
         """
         """
@@ -137,10 +129,21 @@ class AuthView(View):
             handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
         else:
             handler = self.http_method_not_allowed
-        if request.META.get("HTTP_TOKEN") == "7dpHIhpweckghdoSvrXwMftcjZRIzKwJ":
-            return api_wapper(handler, request, False, *args, **kwargs)
+        return api_wapper(handler, request, True, *args, **kwargs)
+
+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:
-            return api_wapper(handler, request, True, *args, **kwargs)
+            handler = self.http_method_not_allowed
+        return admin_handler(handler, request, True, *args, **kwargs)
 
 
 class BaseView(View):
@@ -206,18 +209,11 @@ def api_wapper(handler, request, is_vauth, *args, **kwargs):
     """
     req_path = request.META["PATH_INFO"]
     ip = request.META.get("HTTP_X_REAL_IP","")
-    #if is_vauth and not request.user.is_authenticated() and not ip in ["10.10.19.98","10.10.19.97","10.10.19.84"] and not "/report/data" in req_path:
-    if is_vauth and not request.user.is_authenticated():
+    openid = request.META.get("HTTP_OPENID")
+    user = UserInfo.objects.filter(openid=openid).first()
+    #if is_vauth and not request.user.is_authenticated():
+    if is_vauth and not user:
         return HttpResponse(status=403)
-        return to_redirect("/")
-#     logger.info("request user: %s", str(request.user))
-#     if request.method == "GET":
-#         logger.info("request.GET: %s", str(request.GET))
-# 
-#     if request.method == "POST" or request.method == "PUT":
-#         logger.info("request.body: %s", str(request.body))
-
-    print "request.content_type: ", request.content_type
 
     body = request.body if hasattr(request, "body") else ""
     if "x-www-form-urlencoded" in request.content_type:
@@ -236,35 +232,55 @@ def api_wapper(handler, request, is_vauth, *args, **kwargs):
         except:
             info = {}
 
+    print 66666666666666666666666
     setattr(request, "json", info)
     setattr(request, "ip", get_ip(request))
-#     if request.method == "POST" or request.method == "PUT":
-#         logger.info("request.json: %s", str(request.json))
-
-    # import operation_log.op_log_exception as le
+    setattr(request, "user", user)
+    if request.method == "OPTIONS":
+        return JsonResponse({})
     try:
         ret = handler(request, *args, **kwargs)
-#         logger.info("ret: %s", str(ret.content))
         return ret
-    except error_info.TipException as e:
-        return to_normal_fail(e.msg)
-    except ce.ReasonException as e:
-        # operation log here
-        user = request.user
-        name = user.realname
-        email = user.name
-        return to_normal_fail(e.msg)
-    except ce.SpecialReasonException as e:
-        user = request.user
-        name = user.realname
-        email = user.name
-        e.inner_info.update({'reason': e.msg})
-        return to_normal_fail(e.msg)
-    except:
-        logger.info("request.json: %s", str(request.json))
-        traceback.print_exc()
-        return to_normal_fail("system error!")
+    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","")
+    print request.META,9999
+    openid = request.META.get("HTTP_OPENID")
+    user = UserInfo.objects.filter(openid=openid).first()
+    if is_vauth and not request.user.is_authenticated():
+        return HttpResponse(status=403)
+
+    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)
+    setattr(request, "ip", get_ip(request))
+    #setattr(request, "user", user)
+    try:
+        ret = handler(request, *args, **kwargs)
+        return ret
+    except Exception as e:
+        return to_fail(e)
 
 def upload_wapper(handler,request,is_vauth, *args, **kwargs):
     """
@@ -299,13 +315,13 @@ def upload_wapper(handler,request,is_vauth, *args, **kwargs):
         return to_normal_fail("system error!")
 
 
-def to_suc(data=""):
+def to_suc(data={}):
     info = {}
     info["data"] = data
-    info["status"] = "suc"
+    info["code"] = 0
     return JsonResponse(info,encoder=CusDjangoJSONEncoder)
 
-def to_suc_msg(data="",msg=""):
+def to_suc_msg(data={},msg=""):
     info = {}
     info["data"] = data
     info["msg"] = msg
@@ -315,13 +331,13 @@ def to_suc_msg(data="",msg=""):
 
 def to_normal_fail(msg=""):
     info = {}
-    info["status"] = "error"
+    info["code"] = 1000
     info["message"] = msg
     return JsonResponse(info)
 
 def to_fail(e=None):
     info = {}
-    info["status"] = "error"
+    info["code"] = 1000
     if isinstance(e,ce.TipException):
         info["message"] = e.msg
     else:

+ 134 - 3
src/common/models.py

@@ -1,7 +1,6 @@
 # coding=utf-8
 '''
 '''
-import utils.constant as uconst
 from django.db import models
 
 
@@ -9,11 +8,16 @@ from django.db import models
 class Subject(models.Model):
     name = models.CharField(u"组织名称",max_length=256,blank=True)
     intro = models.TextField(u"科目介绍",max_length=256,blank=True,null=True)
+    device_cats = models.TextField(u"设备种类",max_length=256,blank=True,null=True)
     price_new = models.FloatField(u"新考费用",max_length=256,blank=True,null=True)
     price_re = models.FloatField(u"复审费用",max_length=256,blank=True,null=True)
     price_change = models.FloatField(u"换证费用",max_length=256,blank=True,null=True)
     pid = models.CharField(u"父节点ID",max_length=16,blank=True,null=True)
     status = models.SmallIntegerField(u"状态(0删除)",default=1)
+    order = models.IntegerField(u"培训科目",blank=True,null=True)
+    class_hour = models.IntegerField(u"学时",blank=True,null=True)
+    update_class_hour = models.IntegerField(u"复审学时",blank=True,null=True)
+    change_class_hour = models.IntegerField(u"换证学时",blank=True,null=True)
 
     cid = models.IntegerField(u"创建人ID",blank=True)
     cperson = models.CharField(u"创建人",max_length=255,blank=True)
@@ -27,6 +31,7 @@ class Subject(models.Model):
 class Class(models.Model):
     subject_id = models.IntegerField(u"培训科目",blank=True,null=True)
     subject_name = models.CharField(u"培训科目",blank=True,null=True,max_length=100)
+    subject_item = models.CharField(u"培训科目",blank=True,null=True,max_length=255)
     name = models.CharField(u"名称",max_length=256,blank=True)
     signup_time = models.CharField(u"报名时间",max_length=100,blank=True,null=True)
     signup_limit = models.IntegerField(u"招生人数",blank=True,null=True)
@@ -35,6 +40,7 @@ class Class(models.Model):
     class_status = models.SmallIntegerField(u"班级状态",default=1)
     price = models.FloatField(u"价格信息",blank=True,null=True)
     status = models.SmallIntegerField(u"状态(0删除)",default=1)
+    remark = models.CharField(u"备注",max_length=256,blank=True,null=True)
 
     cid = models.IntegerField(u"创建人ID",blank=True)
     cperson = models.CharField(u"创建人",max_length=255,blank=True)
@@ -64,14 +70,34 @@ class SignupOrders(models.Model):
     idnoimg_back = models.CharField(u"身份证正面照",max_length=256,blank=True,null=True)
     halfbody_img = models.CharField(u"上半身照",max_length=256,blank=True,null=True)
     education_img = models.CharField(u"学历证书",max_length=256,blank=True,null=True)
+    oldcard_img = models.CharField(u"学历证书",max_length=256,blank=True,null=True)
     remark = models.CharField(u"备注",max_length=256,blank=True,null=True)
+    admin_remark = models.CharField(u"后台备注",max_length=256,blank=True,null=True)
 
     price = models.FloatField(u"价格信息",blank=True,null=True)
-    order_status = models.SmallIntegerField(u"订单状态",default=1)
+    out_trade_no = models.CharField(u"订单号",max_length=256,blank=True,null=True)
+    order_status = models.SmallIntegerField(u"订单状态",default=-1)
+    pay_status = models.SmallIntegerField(u"支付状态",default=0)
+    pay_time = models.CharField(u"支付时间",max_length=256,blank=True,null=True)
+    transaction_id = models.CharField(u"交易单号",max_length=256,blank=True,null=True)
+    bill_type = models.SmallIntegerField(u"发票类型",default=0,blank=True,null=True)
+    bill_mat = models.SmallIntegerField(u"发票材料",default=1,blank=True,null=True)
+    bill_no = models.CharField(u"发票税号",max_length=256,blank=True,null=True)
+    bill_name = models.CharField(u"发票公司名",max_length=256,blank=True,null=True)
     signup_status = models.SmallIntegerField(u"报名状态",default=1)
+    classhour_cert_status = models.SmallIntegerField(u"生成学时证明状态",default=0)
+    classhour_cert_url = models.CharField(u"发票税号",max_length=256,blank=True,null=True)
     classhour_total = models.IntegerField(u"总学时",blank=True,null=True,default=0)
     classhour_finish = models.IntegerField(u"已完成学时",blank=True,null=True,default=0)
     status = models.SmallIntegerField(u"状态(0删除)",default=1)
+    exam_time = models.DateTimeField(u"考试时间",blank=True,null=True)
+    train_time_start = models.DateTimeField(u"培训开始时间",blank=True,null=True)
+    train_time_end = models.DateTimeField(u"培训结束时间",blank=True,null=True)
+    update_time = models.DateField(u"复审时间",blank=True,null=True)
+    change_time = models.DateField(u"换证时间",blank=True,null=True)
+    send_update_notice = models.IntegerField(u"已完成学时",blank=True,null=True,default=0)
+    send_change_notice = models.IntegerField(u"已完成学时",blank=True,null=True,default=0)
+    device_cats = models.TextField(u"设备种类",max_length=256,blank=True,null=True)
 
     cid = models.IntegerField(u"创建人ID",blank=True)
     cperson = models.CharField(u"创建人",max_length=255,blank=True)
@@ -106,6 +132,10 @@ class Article(models.Model):
     content = models.TextField(u"内容",blank=True,null=True)
     order = models.IntegerField(u"排序",default=1)
     status = models.SmallIntegerField(u"状态(0删除)",default=1)
+    imgs = models.TextField(u"多图",blank=True,null=True)
+    address = models.CharField(u"地址信息",blank=True,null=True,max_length=255)
+    point = models.CharField(u"经纬度",blank=True,null=True,max_length=255)
+    phone = models.CharField(u"联系方式",blank=True,null=True,max_length=255)
 
     cid = models.IntegerField(u"创建人ID",blank=True)
     cperson = models.CharField(u"创建人",max_length=255,blank=True)
@@ -131,12 +161,16 @@ class UserInfo(models.Model):
     vcard = models.TextField(u"电子名片", blank=True,null=True)
     utype = models.SmallIntegerField(u"用户类型", blank=True,null=True,default=1)
     status = models.SmallIntegerField(u"状态(0删除)",default=1)
+    verify = models.SmallIntegerField(u"是否实名认证(0/1)",default=0,blank=True,null=True)
+    permissions = models.TextField(u"权限", blank=True,null=True)
+    userinfo = models.TextField(u"权限", blank=True,null=True)
 
     last_login = models.CharField(u"上次登录时间", max_length=128, blank=True,null=True,db_column='last_login_time')
     last_login_ip = models.CharField(u"上次登录IP", max_length=128, blank=True,null=True)
     is_active = models.CharField(u"是否激活可用", max_length=4, default="1")
     # 功能权限及数据权限
     #department = models.ForeignKey("Department", verbose_name=u"所属部门", blank=True, null=True)
+    user_wx_id = models.IntegerField(u"老系统用户id",blank=True,null=True)
 
     cid = models.IntegerField(u"创建人ID",blank=True,null=True)
     cperson = models.CharField(u"创建人", max_length=255, blank=True,null=True)
@@ -165,6 +199,7 @@ class OperationLogConfig(models.Model):
     op_module = models.CharField(u"操作模块",max_length=255,blank=True,null=True)
     op_template = models.TextField(u"操作日志模板")
     op_url = models.CharField(u"URL", max_length=255)
+    op_request = models.TextField(u"请求参数", max_length=255, blank=True, null=True)
     op_response = models.TextField(u"URL", max_length=255, blank=True, null=True)
     order = models.IntegerField(u"排序字段",blank=True,null=True)
 
@@ -222,7 +257,6 @@ class SysNotice(models.Model):
     to = models.TextField(u"接收人", max_length=32, blank=True,null=True)
 
     cid = models.IntegerField(u"创建人ID",blank=True,null=True)
-    cperson = models.CharField(u'邮件主题', blank=True, max_length=128,null=True)
     ctime = models.DateTimeField(u"创建时间(发送时间)", auto_now_add=True)
 
     class Meta:
@@ -275,3 +309,100 @@ class Lessons(models.Model):
         db_table = 'lessons'
         verbose_name = u'视频管理'
         verbose_name_plural = u'视频管理'
+
+class Questions(models.Model):
+    """试题
+    """
+    qtype = models.IntegerField(u"题型")
+    title = models.TextField(u"试题标题",default="")  
+    options = models.TextField(u"选项",blank=True,null=True)  
+    answer = models.TextField(u"选项",blank=True,null=True)  
+    analysis = models.TextField(u"题目解析",blank=True,null=True)  
+    score = models.IntegerField(u"分数",blank=True,null=True)
+
+    ctime = models.DateTimeField(u"创建时间",auto_now=True)
+    
+    def __unicode__(self):
+        return self.title
+
+    class Meta:
+        db_table = 'questions'
+        verbose_name = u'试题'
+        verbose_name_plural = u'试题'
+
+
+class Papers(models.Model):
+    """试卷
+    """
+    title = models.CharField(u"标题",max_length=100,default="")  
+    subject_id = models.IntegerField(u"科目id",blank=True,null=True)  
+    subject_item = models.CharField(u"培训科目",max_length=255,default="")  
+    train_type = models.CharField(u"培训类型",max_length=255,default="")  
+    total_score = models.IntegerField(u"总分",blank=True,null=True)
+    total_time = models.IntegerField(u"总时间",blank=True,null=True)
+    questions = models.ManyToManyField(Questions,blank=True,null=True)
+
+    ctime = models.DateTimeField(u"创建时间",auto_now=True)
+
+    def __unicode__(self):
+        return self.title
+
+    class Meta:
+        db_table = 'paper'
+        verbose_name = u'试卷管理'
+        verbose_name_plural = u'试卷管理'
+
+class PostPapers(models.Model):
+    """试卷
+    """
+    title = models.CharField(u"标题",max_length=100,default="")  
+    paper_id = models.IntegerField(u"试卷id",blank=True,null=True)  
+    user_id = models.IntegerField(u"用户id",blank=True,null=True)  
+    questions = models.TextField(u"答案",blank=True,null=True)
+    score = models.FloatField(u"得分",blank=True,null=True)
+
+    ctime = models.DateTimeField(u"创建时间",auto_now=True)
+
+    def __unicode__(self):
+        return self.title
+
+    class Meta:
+        db_table = 'post_paper'
+        verbose_name = u'答题记录'
+        verbose_name_plural = u'答题记录'
+
+
+class Videos(models.Model):
+    """视频
+    """
+    subject_id = models.IntegerField(u"科目id",blank=True,null=True)  
+    subject_item = models.CharField(u"培训科目",max_length=255,default="")  
+    train_type = models.CharField(u"培训类型",max_length=255,default="")  
+    title = models.CharField(u"标题",max_length=100,default="")  
+    img = models.ImageField(u"封面图",default="")  
+    url = models.FileField(u"视频地址",default="")  
+    enc_url = models.TextField(u"视频地址",default="",blank=True,null=True)  
+
+    ctime = models.DateTimeField(u"创建时间",auto_now=True)
+    def __unicode__(self):
+        return self.title
+
+    class Meta:
+        db_table = 'videos'
+        verbose_name = u'视频管理'
+        verbose_name_plural = u'视频管理'
+
+class Docs(models.Model):
+    """视频
+    """
+    name = models.CharField(u"资料名称",max_length=100,default="")  
+    url = models.FileField(u"视频地址",default="")  
+
+    ctime = models.DateTimeField(u"创建时间",auto_now=True)
+    def __unicode__(self):
+        return self.name
+
+    class Meta:
+        db_table = 'docs'
+        verbose_name = u'资料管理'
+        verbose_name_plural = u'资料管理'

+ 0 - 7
src/dashboard/control_dashboard.py

@@ -1,7 +0,0 @@
-# -*-coding:utf-8-*-
-import datetime
-import json
-
-import common.error_info as ce
-import common.models as cm
-import utils.constant as const

+ 0 - 52
src/dashboard/test_case/test_control_dashboard.py

@@ -1,52 +0,0 @@
-# -*-coding:utf-8-*-
-
-import django
-import os
-
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
-django.setup()
-
-import dashboard.control_dashboard as ctd
-
-
-def test_get_website_statisic():
-    ret = ctd.get_nssa_website_statistics(18)
-    print ret
-
-
-def test_get_website_available():
-    ret = ctd.get_nssa_website_available(18)
-    print ret
-
-
-def test_get_website_risk():
-    ret = ctd.get_nssa_website_risk(18)
-    print ret
-
-
-def test_get_website_rist_latest():
-    ret = ctd.get_nssa_website_risk_latest(18)
-    print ret
-
-
-def test_get_website_bug():
-    ret = ctd.get_nssa_website_bug(18)
-    print ret
-
-
-def test_get_nssa_website_tendency():
-    ret = ctd.get_nssa_website_tendency(18)
-    print ret
-
-
-if __name__ == '__main__':
-    print "=========================开始============================"
-
-    # test_get_website_statisic()
-    # test_get_website_available()
-    # test_get_website_risk()
-    # test_get_website_rist_latest()
-    # test_get_website_bug()
-    test_get_nssa_website_tendency()
-
-    print "=========================结束============================"

+ 0 - 19
src/dashboard/urls_backstage.py

@@ -1,19 +0,0 @@
-# coding=utf-8
-'''
-'''
-from django.conf.urls import url
-from dashboard import views_backstage
-
-urlpatterns = [
-    # # 首页或其他
-    # url(r'^info$', views_backstage.WebsiteView.as_view()),
-
-
-    #态势接口
-    url(r'^nssa/website$', views_backstage.WebsiteStatisticsView.as_view()),
-    url(r'^nssa/available$', views_backstage.WebsiteAvailableAlertView.as_view()),
-    url(r'^nssa/risk$', views_backstage.WebsiteRiskView.as_view()),
-    url(r'^nssa/risk/latest$', views_backstage.WebsiteRiskLatestView.as_view()),
-    url(r'^nssa/bug$', views_backstage.WebsiteBugView.as_view()),
-    url(r'^nssa/tendency$', views_backstage.WebsiteTendencyView.as_view()),
-]

+ 0 - 97
src/dashboard/views_backstage.py

@@ -1,97 +0,0 @@
-# -*-coding:utf-8-*-
-
-
-import common.common_functions as ccf
-import common.error_info as ce
-from common import core_views as cv
-from dashboard import control_dashboard as ctd
-
-
-class WebsiteStatisticsView(cv.AuthView):
-    def get(self, request):
-        """
-        #态势网站监测基本统计
-        参数:无
-        """
-        user = request.user
-        uid = user.id
-        try:
-            ret = ctd.get_nssa_website_statistics(uid)
-            return cv.to_suc(ret)
-        except Exception as e:
-            return cv.to_fail(e)
-
-
-class WebsiteAvailableAlertView(cv.AuthView):
-    def get(self, request):
-        """
-        #态势网站可用性告警
-        参数:无
-        """
-        user = request.user
-        uid = user.id
-        try:
-            ret = ctd.get_nssa_website_available(uid)
-            return cv.to_suc(ret)
-        except Exception as e:
-            return cv.to_fail(e)
-
-
-class WebsiteRiskView(cv.AuthView):
-    def get(self, request):
-        """
-        #态势风险网站TOP10
-        参数:无
-        """
-        user = request.user
-        uid = user.id
-        try:
-            ret = ctd.get_nssa_website_risk(uid)
-            return cv.to_suc(ret)
-        except Exception as e:
-            return cv.to_fail(e)
-
-
-class WebsiteRiskLatestView(cv.AuthView):
-    def get(self, request):
-        """
-        #态势最新威胁信息
-        参数:无
-        """
-        user = request.user
-        uid = user.id
-        try:
-            ret = ctd.get_nssa_website_risk(uid)
-            return cv.to_suc(ret)
-        except Exception as e:
-            return cv.to_fail(e)
-
-
-class WebsiteBugView(cv.AuthView):
-    def get(self, request):
-        """
-        #态势网站漏洞信息
-        参数:无
-        """
-        user = request.user
-        uid = user.id
-        try:
-            ret = ctd.get_nssa_website_bug(uid)
-            return cv.to_suc(ret)
-        except Exception as e:
-            return cv.to_fail(e)
-
-
-class WebsiteTendencyView(cv.AuthView):
-    def get(self, request):
-        """
-        #态势风险趋势
-        参数:无
-        """
-        user = request.user
-        uid = user.id
-        try:
-            ret = ctd.get_nssa_website_tendency(uid)
-            return cv.to_suc(ret)
-        except Exception as e:
-            return cv.to_fail(e)

src/dashboard/__init__.py → src/manage/__init__.py


+ 78 - 0
src/manage/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
+

+ 82 - 0
src/manage/control_auth.py

@@ -0,0 +1,82 @@
+#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):
+    """
+    """
+    #qdata = request.json
+    #need_params = ["nickname","avatar","openid"]
+    #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()
+    #
+    data = {
+        "id":1,
+        "name":"肖小肖",
+        "sex":1,
+        "idno":"12321312312",
+        "education":"本科",
+        "phone":"15982456282",
+        "class_id":12,
+        "company":"网安",
+        "subject_id":12,
+        "subject_item":"特种人员|电工作业|准操项目|培训类型",
+        "train_type":1,
+        "receive_card":"邮寄",
+        "area":"四川|巴中|巴州区",
+        "address":"回风大道15号",
+        "remark":"备注1",
+        "idnoimg_face":"https://www.scxjc.club/test.png",
+        "idnoimg_back":"https://www.scxjc.club/test2.png",
+        "halfbody_img":"https://www.scxjc.club/tes3.png",
+        "education_img":"https://www.scxjc.club/test4.png",
+        "oldcard_img":"https://www.scxjc.club/test4.png",
+        "price":1800,
+        "classhour_imgs":["https://www.scxjc.club/test4.png","https://www.scxjc.club/test4.png"]
+    }
+    uid = request.user.id
+    user = cm.UserInfo.objects.filter(id=uid).values().first()
+    print type(user)
+    signinfo = cm.SignupOrders.objects.filter(user_id=uid).values().first()
+    if signinfo:
+        signinfo["sex"] = {u"男":1,u"女":2}.get(signinfo["sex"])
+        user.update(signinfo)
+    return user
+
+
+
+
+
+
+
+

src/account/control_bankcard.py → src/manage/control_bankcard.py


src/account/control_department.py → src/manage/control_department.py


src/account/control_organization.py → src/manage/control_organization.py


src/account/control_permission.py → src/manage/control_permission.py


src/weixin/control_role.py → src/manage/control_role.py


+ 3 - 2
src/weixin/control_user.py

@@ -198,8 +198,8 @@ def get_user_list(request):
     """
     """
     kwargs = request.json
-    eset = cm.UserInfo.objects.filter(status=1)
-    if "name" in kwargs and kwargs.get("name"):
+    eset = cm.UserInfo.objects.filter(status=1).order_by("-id")
+    if "name" in kwargs and kwargs.get("name").strip():
         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"))
@@ -212,6 +212,7 @@ def get_user_list(request):
     page = int(kwargs.get("page",1))
     page_size = int(kwargs.get("page_size",20))
     total,data = ccf.get_page_list(edata,page,page_size)
+    data = sorted(data,key=lambda x:x["id"],reverse=True)
     return (total,data)
 
 

Разница между файлами не показана из-за своего большого размера
+ 1603 - 0
src/manage/controls.py


src/weixin/lock_account.py → src/manage/lock_account.py


+ 6 - 0
src/manage/models.py

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

+ 41 - 0
src/manage/password_handle.py

@@ -0,0 +1,41 @@
+#coding=utf-8
+'''
+@attention: 密码加密验证模块
+'''
+import hashlib
+import re
+import common.error_info as ceil
+import random
+
+def check_password(new,old):
+    """
+    @attention: 验证密码
+    """
+    np = hashlib.md5(new).hexdigest().upper()
+    return np==old
+
+def make_password(pwd,isdefault=None):
+    """
+    @attention: 密码加密
+    """
+    #if not re.search(r'^.*(?=.{6,15})(?=.*\d)(?=.*[A-Z]{1,})(?=.*[a-z]{1,})(?=.*[!@#$%^&*?\(\)]).*$',pwd) and not isdefault:
+    #    raise ceil.TipException(u"密码不符合符号要求!")
+    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)

+ 39 - 0
src/manage/urls_backstage.py

@@ -0,0 +1,39 @@
+# coding=utf-8
+'''
+'''
+from django.conf.urls import url
+from . import views,views_backstage
+
+urlpatterns = [
+    # 运营
+    url(r'^subject$', views.SubjectView.as_view()),
+    url(r'^subject/list$', views.SubjectListView.as_view()),
+    url(r'^signup$', views.SignupView.as_view()),
+    url(r'^signup/list$', views.SignupListView.as_view()),
+    url(r'^signup/upstate$', views.SignupUpstateView.as_view()),
+    url(r'^signup/download$', views.SignupDownloadView.as_view()),
+    url(r'^signup/downloadzip$', views.SignupDownloadZipView.as_view()),
+    url(r'^uploadfile$', views.UploadFileView.as_view()),
+    url(r'^class$', views.ClassView.as_view()),
+    url(r'^class/list$', views.ClassListView.as_view()),
+    url(r'^class/downloadstu$', views.DownloadStuView.as_view()),
+    url(r'^category$', views.CategoryView.as_view()),
+    url(r'^category/list$', views.CategoryListView.as_view()),
+    url(r'^article$', views.ArticleView.as_view()),
+    url(r'^article/list$', views.ArticleListView.as_view()),
+    url(r'^account$', views.AccountView.as_view()),
+    url(r'^account/list$', views.AccountListView.as_view()),
+    url(r'^user$', views.UserView.as_view()),
+    url(r'^user/list$', views.UserListView.as_view()),
+    url(r'^permission/list$', views.PermissionListView.as_view()),
+    url(r'^paper$', views.PaperView.as_view()),
+    url(r'^paper/upload$', views.PaperUploadView.as_view()),
+    url(r'^paper/list$', views.PaperListView.as_view()),
+    url(r'^video$', views.VideoView.as_view()),
+    url(r'^video/list$', views.VideoListView.as_view()),
+    url(r'^docs$', views.DocsView.as_view()),
+    url(r'^docs/list$', views.DocsListView.as_view()),
+    url(r'^img/rotate$', views.ImageRotateView.as_view()),
+    url(r'^index$', views.IndexView.as_view()),
+]
+

Разница между файлами не показана из-за своего большого размера
+ 1066 - 0
src/manage/views.py


src/weixin/views_backstage.py → src/manage/views_backstage.py


src/account/views_permission.py → src/manage/views_permission.py


+ 342 - 0
src/manage/wzhifuSDK.py

@@ -0,0 +1,342 @@
+#coding:utf-8
+"""
+Created on 2014-11-24
+
+@author: http://blog.csdn.net/yueguanghaidao,yihaibo@longtugame.com
+
+ * 微信支付帮助库
+ * ====================================================
+ * 接口分三种类型:
+ * 【请求型接口】--Wxpay_client_
+ *      统一支付接口类--UnifiedOrder
+ *      订单查询接口--OrderQuery
+ *      退款申请接口--Refund
+ *      退款查询接口--RefundQuery
+ *      对账单接口--DownloadBill
+ *      短链接转换接口--ShortUrl
+ * 【响应型接口】--Wxpay_server_
+ *      通用通知接口--Notify
+ *      Native支付——请求商家获取商品信息接口--NativeCall
+ * 【其他】
+ *      静态链接二维码--NativeLink
+ *      JSAPI支付--JsApi
+ * =====================================================
+ * 【CommonUtil】常用工具:
+ *      trimString(),设置参数时需要用到的字符处理函数
+ *      createNoncestr(),产生随机字符串,不长于32位
+ *      formatBizQueryParaMap(),格式化参数,签名过程需要用到
+ *      getSign(),生成签名
+ *      arrayToXml(),array转xml
+ *      xmlToArray(),xml转 array
+ *      postXmlCurl(),以post方式提交xml到对应的接口url
+ *      postXmlSSLCurl(),使用证书,以post方式提交xml到对应的接口url
+
+"""
+
+import json
+import time
+import random
+import urllib2
+import hashlib
+import threading
+import urllib
+from urllib import quote
+import xml.etree.ElementTree as ET
+
+try:
+    import pycurl
+    from cStringIO import StringIO
+except ImportError:
+    pycurl = None
+
+
+class WxPayConf_pub(object):
+    """配置账号信息"""
+
+    ##=======【基本信息设置】=====================================
+    #微信公众号身份的唯一标识。审核通过后,在微信发送的邮件中查看
+    APPID = "wx2938132b773c7b5a"
+    #JSAPI接口中获取openid,审核后在公众平台开启开发模式后可查看
+    APPSECRET = "b32b08a8757cc34b1ee5490af897b065"
+    #受理商ID,身份标识
+    MCHID = "1590893081"
+    #商户支付密钥Key。审核通过后,在微信发送的邮件中查看
+    KEY = "kAHuCc2g4MINcLRk3o0lxT6J1Z04WuZq"
+
+   
+
+    #=======【异步通知url设置】===================================
+    #异步通知url,商户根据实际开发过程设定
+    NOTIFY_URL = "http://baoming.siyusai.com/wxjspay/weixin_qrcode_notify/"
+
+    #=======【JSAPI路径设置】===================================
+    #获取access_token过程中的跳转uri,通过跳转将code传入jsapi支付页面
+    #JS_API_CALL_URL = "http://www.huodongjia.com/pay/?showwxpaytitle=1"
+    JS_API_CALL_URL = "http://baoming.siyusai.com/wxjspay/forwxjspay/"
+
+    #=======【证书路径设置】=====================================
+    #证书路径,注意应该填写绝对路径
+    SSLCERT_PATH = "/data/web/m_website_dev/m_web/weixinpay/cert/apiclient_cert.pem"
+    SSLKEY_PATH = "/data/web/m_website_dev/m_web/weixinpay/cert/apiclient_key.pem"
+
+    #=======【curl超时设置】===================================
+    CURL_TIMEOUT = 30
+
+    #=======【HTTP客户端设置】===================================
+    HTTP_CLIENT = "URLLIB"  # ("URLLIB", "CURL")
+
+
+class Singleton(object):
+    """单例模式"""
+
+    _instance_lock = threading.Lock()
+
+    def __new__(cls, *args, **kwargs):
+        if not hasattr(cls, "_instance"):
+            with cls._instance_lock:
+                if not hasattr(cls, "_instance"):
+                    impl = cls.configure() if hasattr(cls, "configure") else cls
+                    instance = super(Singleton, cls).__new__(impl, *args, **kwargs)
+                    if not isinstance(instance, cls):
+                        instance.__init__(*args, **kwargs)
+                    cls._instance = instance
+        return cls._instance
+
+
+class UrllibClient(object):
+    """使用urlib2发送请求"""
+
+    def get(self, url, second=30):
+        return self.postXml(None, url, second)
+
+    def post(self,url,data):
+        req = urllib2.Request(url)
+        data = urllib.urlencode(data)
+        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
+        response = opener.open(req, data) 
+        return response.read()
+
+    def postXml(self, xml, url, second=30):
+        """不使用证书"""
+        data = urllib2.urlopen(url, xml, timeout=second).read()
+        return data
+
+    def postXmlSSL(self, xml, url, second=30):
+        """使用证书"""
+        raise TypeError("please use CurlClient")
+
+
+class CurlClient(object):
+    """使用Curl发送请求"""
+    def __init__(self):
+        self.curl = pycurl.Curl()
+        self.curl.setopt(pycurl.SSL_VERIFYHOST, False)
+        self.curl.setopt(pycurl.SSL_VERIFYPEER, False)
+        #设置不输出header
+        self.curl.setopt(pycurl.HEADER, False)
+
+    def get(self, url, second=30):
+        return self.postXmlSSL(None, url, second=second, cert=False, post=False)
+
+    def postXml(self, xml, url, second=30):
+        """不使用证书"""
+        return self.postXmlSSL(xml, url, second=second, cert=False, post=True)
+        
+
+    def postXmlSSL(self, xml, url, second=30, cert=True, post=True):
+        """使用证书"""
+        self.curl.setopt(pycurl.URL, url)
+        self.curl.setopt(pycurl.TIMEOUT, second)
+        #设置证书
+        #使用证书:cert 与 key 分别属于两个.pem文件
+        #默认格式为PEM,可以注释
+        if cert:
+            self.curl.setopt(pycurl.SSLKEYTYPE, "PEM")
+            self.curl.setopt(pycurl.SSLKEY, WxPayConf_pub.SSLKEY_PATH)
+            self.curl.setopt(pycurl.SSLCERTTYPE, "PEM")
+            self.curl.setopt(pycurl.SSLCERT, WxPayConf_pub.SSLCERT_PATH)
+        #post提交方式
+        if post:
+            self.curl.setopt(pycurl.POST, True)
+            self.curl.setopt(pycurl.POSTFIELDS, xml)
+        buff = StringIO()
+        self.curl.setopt(pycurl.WRITEFUNCTION, buff.write)
+
+        self.curl.perform()
+        return buff.getvalue()
+
+
+class HttpClient(Singleton):
+    @classmethod
+    def configure(cls):
+        if pycurl is not None and WxPayConf_pub.HTTP_CLIENT != "URLLIB":
+            return CurlClient
+        else:
+            return UrllibClient
+            
+
+class Common_util_pub(object):
+    """所有接口的基类"""
+
+    def trimString(self, value):
+        if value is not None and len(value) == 0:
+            value = None
+        return value
+
+    def createNoncestr(self, length = 32):
+        """产生随机字符串,不长于32位"""
+        chars = "abcdefghijklmnopqrstuvwxyz0123456789"
+        strs = []
+        for x in range(length):
+            strs.append(chars[random.randrange(0, len(chars))])
+        return "".join(strs)
+
+    def formatBizQueryParaMap(self, paraMap, urlencode):
+        """格式化参数,签名过程需要使用"""
+        slist = sorted(paraMap)
+        buff = []
+        for k in slist:
+            v = quote(paraMap[k]) if urlencode else paraMap[k]
+            buff.append("{0}={1}".format(k, v))
+
+        return "&".join(buff)
+
+    def getSign(self, obj):
+        """生成签名"""
+        #签名步骤一:按字典序排序参数,formatBizQueryParaMap已做
+        String = self.formatBizQueryParaMap(obj, False)
+        #签名步骤二:在string后加入KEY
+        String = "{0}&key={1}".format(String,WxPayConf_pub.KEY)
+        #签名步骤三:MD5加密
+        String = hashlib.md5(String).hexdigest()
+        #签名步骤四:所有字符转为大写
+        result_ = String.upper()
+        return result_
+
+    def arrayToXml(self, arr):
+        """array转xml"""
+        xml = ["<xml>"]
+        for k, v in arr.iteritems():
+            if v.isdigit():
+                xml.append("<{0}>{1}</{0}>".format(k, v))
+            else:
+                xml.append("<{0}>{1}</{0}>".format(k, v))
+        xml.append("</xml>")
+        return "".join(xml)
+
+    def xmlToArray(self, xml):
+        """将xml转为array"""
+        array_data = {}
+        root = ET.fromstring(xml)
+        for child in root:
+            value = child.text
+            array_data[child.tag] = value
+        return array_data
+
+    def postXmlCurl(self, xml, url, second=30):
+        """以post方式提交xml到对应的接口url"""
+        return HttpClient().postXml(xml, url, second=second)
+
+    def postXmlSSLCurl(self, xml, url, second=30):
+        """使用证书,以post方式提交xml到对应的接口url"""
+        return HttpClient().postXmlSSL(xml, url, second=second)
+
+
+class Wxpay_client_pub(Common_util_pub):
+    """请求型接口的基类"""
+    response = None  #微信返回的响应
+    url = None       #接口链接
+    curl_timeout = None #curl超时时间
+
+    def __init__(self):
+        self.parameters = {} #请求参数,类型为关联数组
+        self.result = {}     #返回参数,类型为关联数组
+
+
+    def setParameter(self, parameter, parameterValue):
+        """设置请求参数"""
+        self.parameters[self.trimString(parameter)] = self.trimString(parameterValue)
+
+    def createXml(self):
+        """设置标配的请求参数,生成签名,生成接口参数xml"""
+        return  self.arrayToXml(self.parameters)
+
+    def postXml(self):
+        """post请求xml"""
+        xml = self.createXml()
+        self.response = self.postXmlCurl(xml, self.url, self.curl_timeout)
+        return self.response
+
+    def postXmlSSL(self):
+        """使用证书post请求xml"""
+        xml = self.createXml()
+        self.response = self.postXmlSSLCurl(xml, self.url, self.curl_timeout)
+        return self.response
+
+    def getResult(self):
+        """获取结果,默认不使用证书"""
+        self.postXml()
+        self.result = self.xmlToArray(self.response)
+        return self.result
+
+
+class UnifiedOrder_pub(Wxpay_client_pub):
+    """统一支付接口类"""
+
+    def __init__(self, timeout=WxPayConf_pub.CURL_TIMEOUT):
+        #设置接口链接
+        self.url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
+        #设置curl超时时间
+        self.curl_timeout = timeout
+        super(UnifiedOrder_pub, self).__init__()
+
+
+    def createXml(self):
+        """生成接口参数xml"""
+        #检测必填参数
+        if any(self.parameters[key] is None for key in ("out_trade_no", "total_fee")):
+            raise ValueError("missing parameter")
+        if self.parameters["trade_type"] == "JSAPI" and self.parameters["openid"] is None:
+            raise ValueError("JSAPI need openid parameters")
+
+        self.parameters["appid"] = WxPayConf_pub.APPID  #公众账号ID
+        self.parameters["mch_id"] = WxPayConf_pub.MCHID  #商户号
+        self.parameters["spbill_create_ip"] = "127.0.0.1"  #终端ip      
+        self.parameters["nonce_str"] = self.createNoncestr()  #随机字符串
+        self.parameters["notify_url"] = WxPayConf_pub.NOTIFY_URL  #随机字符串
+        self.parameters["body"] = "培训报名费"  #随机字符串
+        if self.parameters.has_key("sign"):
+            self.parameters.pop("sign")
+        sign = self.getSign(self.parameters)
+        print self.parameters
+        self.parameters["sign"] = sign  #签名
+        return  self.arrayToXml(self.parameters)
+
+    def getPrepayId(self):
+        """获取prepay_id"""
+        self.postXml()
+        self.result = self.xmlToArray(self.response)
+        print self.result
+        return self.result
+
+    def geth5url(self):
+        """获取prepay_id"""
+        self.postXml()
+        self.result = self.xmlToArray(self.response)
+        prepay_id = self.result["mweb_url"]
+        return prepay_id
+
+def get_wx_unifiedorder(out_trade_no,total_fee,openid,trade_type="JSAPI"):
+    par_obj = UnifiedOrder_pub()
+    par_obj.setParameter('out_trade_no',out_trade_no)
+    par_obj.setParameter('total_fee',total_fee)
+    par_obj.setParameter('openid',openid)
+    par_obj.setParameter('trade_type',trade_type)
+    par_obj.createXml()
+    return par_obj.getPrepayId()
+
+
+
+
+if __name__ == "__main__":
+    pass

+ 5 - 2
src/operation_log/OpLogMiddleware.py

@@ -54,7 +54,7 @@ class OpLogMiddleware(object):
             response_data = json.loads(response.getvalue())
         except:
             response_data = {}
-        if response_data.get("status") == "suc":
+        if response_data.get("status") == "suc" or response_data.get("code") == 0:
             is_suc = 1
             error_msg = ""
         else:
@@ -68,9 +68,12 @@ class OpLogMiddleware(object):
         if flag:
             obj.order = last_order
         if not obj.op_response:
-            if response_data.get("status") == "suc":
+            if response_data.get("status") == "suc" or response_data.get("code") == 0:
                 obj.op_response = json.dumps(response_data)
                 obj.save()
+        #if not obj.op_request:
+        #        obj.op_request = json.dumps(request.json)
+        #        obj.save()
         cm.OperationLog.objects.create(
             op_user_name = op_user_name,
             op_user_realname = op_user_realname,

+ 0 - 0
src/script/__init__.py


+ 0 - 36
src/script/start_collect_mtask_result.py

@@ -1,36 +0,0 @@
-#-*-coding:utf-8 -*-
-import time
-import os,sys
-import django
-
-sys.path.append(os.path.join("..",os.path.dirname(__file__)))
-os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
-django.setup()
-
-from start_collect_mtask_result_available import collect_results_available
-from start_collect_mtask_result_bug import collect_results_bug
-from start_collect_mtask_result_content import collect_results_content
-from start_collect_mtask_result_webshell import collect_results_webshell
-from start_collect_mtask_result_poc import collect_results_poc
-
-
-
-def main():
-    """
-    """
-    while True:
-        #可用性
-        collect_results_available()
-        #漏洞检测
-        collect_results_bug()
-        #事件检测
-        collect_results_content()
-        #webshell
-        collect_results_webshell()
-        #专项检测
-        collect_results_poc()
-        time.sleep(60)
-
-
-if __name__ == "__main__":
-    main()

+ 0 - 78
src/script/start_collect_mtask_result_available.py

@@ -1,78 +0,0 @@
-#-*-coding:utf-8 -*-
-import json
-import os,sys
-import django
-
-sys.path.append(os.path.join("..",os.path.dirname(__file__)))
-os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
-django.setup()
-
-import common.models as cm
-import webray_service.control_webray as cwr
-
-
-def get_available_tasks():
-    """
-    """
-    wrtask = cm.WebRayTasks.objects.filter(type=1)
-    return wrtask
-
-
-def collect_results_available():
-    tasks = get_available_tasks()
-    for task in tasks:
-        siteid = task.siteid
-        task_id = task.id
-        website_id = task.website_id
-        wajob_res = cwr.get_wajob(siteid)
-        wa_rst_http_list = wajob_res.get("wa_rst_http_list")
-        wa_rst_http_list = sorted(wa_rst_http_list,key=lambda x:x["received_at"],reverse=True)
-        for rst in wa_rst_http_list:
-            taskid = rst.get("taskid")
-            jobid = rst.get("jobid")
-            logtype = rst.get("logtype")
-            httptime = rst.get("httptime")
-            received_at = rst.get("received_at")
-            isalert = rst.get("isalert")
-            trobj,flag = cm.AvailableTasksResult.objects.get_or_create(
-                    task_id = task_id, 
-                    taskid = taskid,
-                    siteid = siteid,
-                    jobid = jobid,
-                    isalert = isalert,
-                    website_id = website_id
-                )
-            trobj.logtype = logtype
-            trobj.httptime = httptime
-            trobj.received_at = received_at
-            trobj.save()
-            if trobj.isalert:
-                #生成可用性告警事件
-                cm.WarningEvent.objects.create(**{"event_type":"avaible",
-                        "task_type":1,
-                        "task_id":task_id,
-                        "taskid":taskid,
-                        "jobid":jobid,
-                        "taskname":task.name,
-                        "domain":task.site.split("//")[1].split(":")[0],
-                        "label":task.website_name,
-                        "organization":cm.WebSite.objects.filter(id=website_id).first().organization_name,
-                        "result":json.dumps([{"isalert":1,"httptime":httptime}])
-                        })
-        
-def main():
-    collect_results_available()
-
-if __name__ == "__main__":
-    main()
-
-
-
-
-
-
-
-
-
-
-

+ 0 - 93
src/script/start_collect_mtask_result_bug.py

@@ -1,93 +0,0 @@
-#-*-coding:utf-8 -*-
-import json
-import os,sys
-import django
-
-sys.path.append(os.path.join("..",os.path.dirname(__file__)))
-os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
-django.setup()
-
-import common.models as cm
-import webray_service.control_webray as cwr
-
-
-def get_available_tasks():
-    """
-    """
-    wrtask = cm.WebRayTasks.objects.filter(type=2)
-    return wrtask
-
-
-def collect_results_bug():
-    tasks = get_available_tasks()
-    for task in tasks:
-        print task,11111111111
-        siteid = task.siteid
-        task_id = task.id
-        taskid = task.taskid
-        website_id = task.website_id
-        print taskid,siteid,3333333333333
-        try:
-            wvjob_res = cwr.get_wvjob(siteid,taskid)
-            print wvjob_res,2222
-            if isinstance(wvjob_res,type({})):
-                jobreport = wvjob_res.get("jobreport")
-                vuln_list = wvjob_res.get("vuln_list")
-                taskid = jobreport.get("taskid")
-                jobid = jobreport.get("jobid")
-                logtype = jobreport.get("logtype")
-                received_at = jobreport.get("received_at")
-                starttime = jobreport.get("starttime")
-                endtime = jobreport.get("endtime")
-                total = jobreport.get("total")
-                high = jobreport.get("high")
-                mid = jobreport.get("mid")
-                low = jobreport.get("low")
-                info = jobreport.get("info")
-                isalert = jobreport.get("isalert")
-
-                trobj,flag = cm.BugTasksResult.objects.get_or_create(
-                        task_id = task_id, 
-                        taskid = taskid,
-                        siteid = siteid,
-                        jobid = jobid,
-                        website_id = website_id
-                    )
-                trobj.logtype = logtype
-                trobj.received_at = received_at
-                trobj.starttime = starttime
-                trobj.endtime = endtime
-                trobj.total = total
-                trobj.high = high
-                trobj.mid = mid
-                trobj.low = low
-                trobj.info = info
-                trobj.isalert = isalert
-                trobj.vuln_list = json.dumps(vuln_list)
-                trobj.save()
-                #生成漏洞告警事件
-                if trobj.vuln_list:
-                    cm.WarningEvent.objects.create(**{"event_type":"bug",
-                            "task_type":1,
-                            "task_id":task_id,
-                            "taskid":taskid,
-                            "jobid":jobid,
-                            "taskname":task.name,
-                            "domain":task.site.split("//")[1].split(":")[0],
-                            "label":task.website_name,
-                            "organization":cm.WebSite.objects.filter(id=website_id).first().organization_name,
-                            "result":trobj.vuln_list
-                            })
-
-        except Exception as e:
-            continue
-        
-
-def main():
-    """
-    """
-    collect_results()
-
-
-if __name__ == "__main__":
-    main()

+ 0 - 76
src/script/start_collect_mtask_result_content.py

@@ -1,76 +0,0 @@
-#-*-coding:utf-8 -*-
-import json
-import os,sys
-import django
-
-sys.path.append(os.path.join("..",os.path.dirname(__file__)))
-os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
-django.setup()
-
-import common.models as cm
-import webray_service.control_webray as cwr
-
-
-def get_available_tasks():
-    """
-    """
-    wrtask = cm.WebRayTasks.objects.filter(type=3)
-    return wrtask
-
-
-def collect_results_content():
-    tasks = get_available_tasks()
-    for task in tasks:
-        siteid = task.siteid
-        task_id = task.id
-        taskid = task.taskid
-        website_id = task.website_id
-        try:
-            wcjob_res = cwr.get_wcjob(siteid,taskid)
-            print wcjob_res
-            if isinstance(wcjob_res,type({})):
-                jobreport = wcjob_res.get("jobreport")
-                wc_rst_list = wcjob_res.get("wc_rst_list")
-                taskid = jobreport.get("taskid")
-                jobid = jobreport.get("jobid")
-                logtype = jobreport.get("logtype")
-                received_at = jobreport.get("received_at")
-                starttime = jobreport.get("starttime")
-                endtime = jobreport.get("endtime")
-                total = jobreport.get("total")
-                isalert = jobreport.get("isalert")
-                pagecount = jobreport.get("pagecount")
-                keywordcount = jobreport.get("keywordcount")
-                hiddencount = jobreport.get("hiddencount")
-                tampcount = jobreport.get("tampcount")
-
-                trobj,flag = cm.ContentTasksResult.objects.get_or_create(
-                        task_id = task_id, 
-                        taskid = taskid,
-                        siteid = siteid,
-                        jobid = jobid,
-                        website_id = website_id
-                    )
-                trobj.logtype = logtype
-                trobj.received_at = received_at
-                trobj.starttime = starttime
-                trobj.endtime = endtime
-                trobj.total = total
-                trobj.isalert = isalert
-                trobj.keywordcount = keywordcount
-                trobj.hiddencount = hiddencount
-                trobj.tampcount = tampcount
-                trobj.wc_rst_list = json.dumps(wc_rst_list)
-                trobj.save()
-        except:
-            continue
-        
-
-def main():
-    """
-    """
-    collect_results()
-
-
-if __name__ == "__main__":
-    main()

+ 0 - 54
src/script/start_collect_mtask_result_poc.py

@@ -1,54 +0,0 @@
-#-*-coding:utf-8 -*-
-import os,sys
-import django
-
-sys.path.append(os.path.join("..",os.path.dirname(__file__)))
-os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
-django.setup()
-
-import common.models as cm
-import webray_service.control_wshellpoc as cwsp
-
-
-def get_available_tasks():
-    """
-    """
-    wrtask = cm.WebRayTasks.objects.filter(type=100)
-    return wrtask
-
-
-def collect_results_poc():
-    tasks = get_available_tasks()
-    for task in tasks:
-        siteid = task.siteid
-        task_id = str(task.id)
-        website_id = task.website_id
-        wajob_res = cwsp.get_webshellpoc_results([{"task_id":task_id,"job_id":0}])
-        print wajob_res,44444444444444
-        #wa_rst_http_list = wajob_res.get("wa_rst_http_list")
-        #wa_rst_http_list = sorted(wa_rst_http_list,key=lambda x:x["received_at"],reverse=True)
-        #for rst in wa_rst_http_list:
-        #    taskid = rst.get("taskid")
-        #    jobid = rst.get("jobid")
-        #    logtype = rst.get("logtype")
-        #    httptime = rst.get("httptime")
-        #    received_at = rst.get("received_at")
-        #    isalert = rst.get("isalert")
-        #    trobj,flag = cm.AvailableTasksResult.objects.get_or_create(
-        #            task_id = task_id, 
-        #            taskid = taskid,
-        #            siteid = siteid,
-        #            jobid = jobid,
-        #            isalert = isalert,
-        #            website_id = website_id
-        #        )
-        #    trobj.logtype = logtype
-        #    trobj.httptime = httptime
-        #    trobj.received_at = received_at
-        #    trobj.save()
-        
-def main():
-    collect_results_poc()
-
-if __name__ == "__main__":
-    main()

+ 0 - 74
src/script/start_collect_mtask_result_webshell.py

@@ -1,74 +0,0 @@
-#-*-coding:utf-8 -*-
-import json
-import os,sys
-import django
-
-sys.path.append(os.path.join("..",os.path.dirname(__file__)))
-os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
-django.setup()
-
-import common.models as cm
-import webray_service.control_wshellpoc as cwsp
-
-
-def get_available_tasks():
-    """
-    """
-    wrtask = cm.WebRayTasks.objects.filter(type=3)
-    return wrtask
-
-
-def collect_results_webshell():
-    tasks = get_available_tasks()
-    for task in tasks:
-        siteid = task.siteid
-        task_id = str(task.id)
-        website_id = task.website_id
-        wstrobj = cm.WebShellTasksResult.objects.filter(task_id=task.id).order_by("-jobid").first()
-        jobid = wstrobj.jobid if wstrobj else -1
-        if task.excute_type == "once":
-            if jobid > -1:
-                continue
-            else:
-                jobid = 0
-        else:
-            jobid = jobid + 1
-        wajob_res = cwsp.get_webshellpoc_results([{"task_id":task_id,"job_id":jobid}])
-        print wajob_res,2222222222
-        if wajob_res.get("message") == "ok":
-            if wajob_res.get("data"):
-                data = wajob_res.get("data")[0]
-                trobj,flag = cm.WebShellTasksResult.objects.get_or_create(
-                        task_type = 4,
-                        task_id = task.id, 
-                        website_id = website_id, 
-                        taskid = task.id,
-                        jobid = jobid,
-                        task_status = data.get("task_status"),
-                        starttime = data.get("task_begintime"),
-                        endtime = data.get("task_endtime"),
-                        task_executing_engine_id = data.get("task_executing_engine_id"),
-                        task_executing_enginevendor_id = data.get("task_executing_enginevendor_id"),
-                        task_result = json.dumps(data.get("task_result")),
-                        total = len(data.get("task_result",[]))
-                    )
-                trobj.save()
-                #生成webshell告警事件
-                if json.loads(trobj.task_result):
-                    cm.WarningEvent.objects.create(**{"event_type":"webshell",
-                            "task_type":1,
-                            "task_id":task_id,
-                            "taskid":task_id,
-                            "jobid":jobid,
-                            "taskname":task.name,
-                            "domain":task.site.split("//")[1].split(":")[0],
-                            "label":task.website_name,
-                            "organization":cm.WebSite.objects.filter(id=website_id).first().organization_name,
-                            "result":trobj.task_result
-                            })
-        
-def main():
-    collect_results_webshell()
-
-if __name__ == "__main__":
-    main()

+ 2 - 2
src/settings/base.py

@@ -42,9 +42,9 @@ INSTALLED_APPS = [
     'django.contrib.staticfiles',
     'common',
     'account',
-    'operation_log',
     'bzyifeng',
-    'weixin'
+    'weixin',
+    'manage'
 ]
 
 MIDDLEWARE = [

+ 0 - 80
src/settings/settings_online.py

@@ -1,80 +0,0 @@
-# coding=utf-8
-from base import *
-
-# redis配置
-CACHES = {
-    'default': {
-        'BACKEND': 'django_redis.cache.RedisCache',
-        'LOCATION': 'redis://127.0.0.1:6379/0',
-        "OPTIONS": {
-            "CLIENT_CLASS": "django_redis.client.default.DefaultClient",
-        },
-    },
-}
-
-
-DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.mysql',
-        'NAME': 'xeshop',
-        'USER': 'root',
-        'PASSWORD': 'xjc890*()',
-        'HOST': '127.0.0.1',
-        'PORT': '3306',
-    }
-}
-
-# 短信配置  common.sms.py使用
-SMS_ACCOUNT_SID = "8a216da8588b296f01588ecd0a0001ab"
-SMS_AUTH_TOKEN = "f0d2b53782374ebc8a76fa8dd06bb4d2"
-SMS_APP_ID = "8a216da8589ae4840158a89b5c8f0272"
-SMS_URL = "https://app.cloopen.com:8883/2013-12-26/Accounts/%s/SMS/TemplateSMS" % SMS_ACCOUNT_SID
-SMS_LOG_PATH = os.path.join(BASE_DIR, "../logs", "sms")
-SEND_SMS = False
-
-# 验证码字体库位置
-FONT_PATH = os.path.join(BASE_DIR, "../static/font", "consola.ttf")
-
-AUTHENTICATION_BACKENDS = [
-    "account.cauth.AccountManage",
-]
-
-# session 过期设置
-SESSION_COOKIE_AGE = 60 * 30
-SESSION_SAVE_EVERY_REQUEST = True
-SESSION_COOKIE_HTTPONLY = False
-
-LOGGING = {
-    'version': 1,
-    'disable_existing_loggers': False,
-    'formatters': {
-        'standard': {
-            'format': '%(asctime)s [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s'
-        }
-    },
-    'handlers': {
-        'console': {
-            'class': 'logging.StreamHandler',
-            'level': 'INFO',
-            'formatter': 'standard'
-        },
-    },
-    'loggers': {
-        '': {
-            'handlers': ['console'],
-            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
-        }
-    },
-}
-
-
-#channels                                                                          
-CHANNEL_LAYERS = {                                                                 
-    "default": {                                                                   
-        "BACKEND": "asgi_redis.RedisChannelLayer",                                     
-        "CONFIG": {                                                                    
-                    "hosts": [os.environ.get('REDIS_URL', 'redis://localhost:6379')],          
-                },                                                                             
-            "ROUTING": "dashboard.routings.channel_routing",                         
-        },                                                                             
-} 

+ 1 - 10
src/settings/settings_test.py

@@ -68,13 +68,4 @@ LOGGING = {
 }
 
 
-#channels                                                                          
-CHANNEL_LAYERS = {                                                                 
-    "default": {                                                                   
-        "BACKEND": "asgi_redis.RedisChannelLayer",                                     
-        "CONFIG": {                                                                    
-                    "hosts": [os.environ.get('REDIS_URL', 'redis://localhost:6379')],          
-                },                                                                             
-            "ROUTING": "dashboard.routings.channel_routing",                         
-        },                                                                             
-} 
+HOST = "https://www.scxjc.club"

BIN
src/templates/157883436884.docx


BIN
src/templates/18920987654.docx


BIN
src/templates/24.docx


BIN
src/templates/9.docx


BIN
src/templates/apply_template.docx


BIN
src/templates/apply_template_aqxy.docx


BIN
src/templates/apply_template_cyry.docx


BIN
src/templates/apply_template_tzzy.docx


BIN
src/templates/classhour.png


BIN
src/templates/font/consola.ttf


BIN
src/templates/font/simkai.ttf


BIN
src/templates/font/simsun.ttc


BIN
src/templates/kqqd.xls


BIN
src/templates/kqqd.xlsx


BIN
src/templates/ksqd.xls


BIN
src/templates/pxqd.xls


BIN
src/templates/qtcy.xls


BIN
src/templates/szksqd.xls


BIN
src/templates/test.xlsx


BIN
src/templates/tzzy.xls


BIN
src/templates/tzzy_bk.xls


BIN
src/templates/tzzykssbb.xls


BIN
src/templates/xxkqqd.xls


BIN
src/templates/zyfzr.xls


BIN
src/templates/肖小肖_低压电工.docx


BIN
src/templates/谭燕飞.docx


src/dashboard/test_case/__init__.py → src/tools/__init__.py


+ 32 - 0
src/tools/check_update_change_time.py

@@ -0,0 +1,32 @@
+#coding:utf-8
+import datetime
+import sys
+import django
+
+sys.path.append('/mnt/bzyifeng/src')
+os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
+django.setup()
+
+import common.models as cm
+from utils.aliyun_sms import send_update_notice,send_expired_notice
+
+def check_update_change_time():
+    """
+    """
+    now = datetime.datetime.now().date()
+    qset = cm.SignupOrders.objects.filter(order_status=7,update_time__isnull=False)
+    for so in qset:
+        phone = so.phone
+        subject_item = so.subject_item.split("|")[0]
+        update_time = so.update_time
+        change_time = so.change_time
+        #发送复审通知
+        if now > update_time + datetime.timedelta(days=-30) and so.send_update_notice < 3:
+            send_update_notice(phone,subject_item)
+        #发送换证通知
+        if now > update_time + datetime.timedelta(days=-90) and so.send_change_notice < 3:
+            send_expired_notice(phone,subject_item)
+
+
+if __name__ == "__main__":
+    check_update_change_time()

+ 1 - 4
src/urls.py

@@ -27,11 +27,8 @@ import bzyifeng.views as wview
 
 urlpatterns = [
     url(r'^api/account/', include('account.urls_backstage')),
-    url(r'^api/doc/', wview.DocView.as_view()),
-    url(r'^api/hook/$', wview.HookView.as_view()),
-    url(r'^api/dashboard/', include('dashboard.urls_backstage')),
-    url(r'^api/oplog/', include('operation_log.urls_backstage')),
     url(r'^api/wx/', include('weixin.urls_backstage')),
+    url(r'^api/admin/', include('manage.urls_backstage')),
 ]
 
 urlpatterns += [

+ 0 - 97
src/utils/aliyun_email.py

@@ -1,97 +0,0 @@
-#-*-coding:utf-8 -*-
-import hmac
-import base64
-import requests
-import datetime,time
-import urllib
-import uuid
-from hashlib import sha1
-
-class AliEmailClient(object):
-    """阿里云邮件推送
-    """
-    def __init__(self):
-        self.url = "http://dm.aliyuncs.com"
-        self.AccessKeyId = "LTAI6puCBe6A1lOa"
-        self.AccessKeySecret = "VeWxSWEWM8xULzbnbCHDkSn7QPvasO"
-
-    def percent_encode(self,encodeStr):
-        """
-        """
-        encodeStr = str(encodeStr)
-        res = urllib.quote(encodeStr.decode("utf-8").encode("utf-8"),"")
-        res = res.replace("+","%20")
-        res = res.replace("*","%2A")
-        res = res.replace("%7E","~")
-
-        return res
-
-    def gen_signature(self,params):
-        """
-        """
-        sortedParams = sorted(params.items(),key=lambda x:x[0])
-        canonicalizedQueryString = ''
-        for k,v in sortedParams:
-            canonicalizedQueryString += '&' + self.percent_encode(k) \
-                + '=' + self.percent_encode(v)
-        stringToSign = 'GET&%2F&' + self.percent_encode(canonicalizedQueryString[1:])
-        hmc = hmac.new(self.AccessKeySecret + "&",stringToSign,sha1)
-        signature = base64.encodestring(hmc.digest()).strip()
-        
-        return signature
-
-    def gen_params(self,params={}):
-        """
-        """
-        pub_param = {
-            "Format":"JSON", 
-            "Version":"2015-11-23",
-            "AccessKeyId":self.AccessKeyId,
-            "SignatureMethod":"HMAC-SHA1",
-            "Timestamp":time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()),
-            "SignatureVersion":"1.0",
-            "SignatureNonce":str(uuid.uuid1()),
-        }
-        for key in pub_param:
-            params.update({key:pub_param[key]})
-        signature = self.gen_signature(params)
-        params["Signature"] = signature
-
-        return params
-        
-
-    def send_mail(self,to,subject,content):
-        """
-        """
-        params = {
-            "Action":"SingleSendMail",
-            "AccountName":"swad-services@mail.365gcd.com",
-            "ReplyToAddress":True,
-            "AddressType":1,
-            "ToAddress":to,
-            "FromAlias":"中国网安云安全".decode("utf-8").encode("utf-8"),
-            "Subject":unicode(subject).encode("utf-8"),
-            "HtmlBody":unicode(content).encode("utf-8")
-        }
-        url = self.url + "/?" + urllib.urlencode(self.gen_params(params))
-        res = requests.get(url)
-        print res
-        return res.json() if res else {}
-
-    def batch_send_mail(self,to,subject,content):
-        """批量发送
-        """
-if __name__ == "__main__":
-    aliemail_client = AliEmailClient()
-    to = "scxiaojincai@163.com"
-    to = "496498291@qq.com"
-    subject = u"测试"
-    content = u"测试"
-    res = aliemail_client.send_mail(to,subject,content)
-    print res
-
-
-
-
-
-

+ 158 - 0
src/utils/aliyun_sms.py

@@ -0,0 +1,158 @@
+#!/usr/bin/env python
+#coding=utf-8
+import json
+from aliyunsdkcore.client import AcsClient
+from aliyunsdkcore.request import CommonRequest
+client = AcsClient('LTAIbY5V8m3zBjrT', 'H0UrXv6cVYoQLRUdD9ZR7DvF2Sr0FX', 'cn-hangzhou')
+
+def send_audit_notice(phone,subject_item):
+    """发送审核通知
+    """
+    request = CommonRequest()
+    request.set_accept_format('json')
+    request.set_domain('dysmsapi.aliyuncs.com')
+    request.set_method('POST')
+    request.set_protocol_type('https') # https | http
+    request.set_version('2017-05-25')
+    request.set_action_name('SendSms')
+
+    request.add_query_param('RegionId', "cn-hangzhou")
+    request.add_query_param('PhoneNumbers', phone)
+    request.add_query_param('SignName', "逸沣安全培训")
+    request.add_query_param('TemplateCode', "SMS_192150140")
+    request.add_query_param('TemplateParam', json.dumps({"subject_item":subject_item}))
+    response = client.do_action(request)
+    return True,u"success"
+
+def send_unauthed_notice(phone):
+    """审核不通过短信通知
+    """
+    request = CommonRequest()
+    request.set_accept_format('json')
+    request.set_domain('dysmsapi.aliyuncs.com')
+    request.set_method('POST')
+    request.set_protocol_type('https') # https | http
+    request.set_version('2017-05-25')
+    request.set_action_name('SendSms')
+
+    request.add_query_param('RegionId', "cn-hangzhou")
+    request.add_query_param('PhoneNumbers', phone)
+    request.add_query_param('SignName', "逸沣安全培训")
+    request.add_query_param('TemplateCode', "SMS_192770033")
+    response = client.do_action(request)
+    return True,u"success"
+
+def send_update_notice(phone,name,subject_item):
+    """证件复审通知
+    """
+    request = CommonRequest()
+    request.set_accept_format('json')
+    request.set_domain('dysmsapi.aliyuncs.com')
+    request.set_method('POST')
+    request.set_protocol_type('https') # https | http
+    request.set_version('2017-05-25')
+    request.set_action_name('SendSms')
+
+    request.add_query_param('RegionId', "cn-hangzhou")
+    request.add_query_param('PhoneNumbers', phone)
+    request.add_query_param('SignName', "逸沣安全培训")
+    request.add_query_param('TemplateCode', "SMS_192820850")
+    request.add_query_param('TemplateParam', json.dumps({"subject_item":subject_item,"name":name}))
+    response = client.do_action(request)
+    return True,u"success"
+
+def send_expired_notice(phone,name,subject_item):
+    """证件到期通知
+    """
+    request = CommonRequest()
+    request.set_accept_format('json')
+    request.set_domain('dysmsapi.aliyuncs.com')
+    request.set_method('POST')
+    request.set_protocol_type('https') # https | http
+    request.set_version('2017-05-25')
+    request.set_action_name('SendSms')
+
+    request.add_query_param('RegionId', "cn-hangzhou")
+    request.add_query_param('PhoneNumbers', phone)
+    request.add_query_param('SignName', "逸沣安全培训")
+    request.add_query_param('TemplateCode', "SMS_192820847")
+    request.add_query_param('TemplateParam', json.dumps({"subject_item":subject_item,"name":name}))
+    response = client.do_action(request)
+    return True,u"success"
+
+def send_pay_notice(phone):
+    """支付成功通知
+    """
+    request = CommonRequest()
+    request.set_accept_format('json')
+    request.set_domain('dysmsapi.aliyuncs.com')
+    request.set_method('POST')
+    request.set_protocol_type('https') # https | http
+    request.set_version('2017-05-25')
+    request.set_action_name('SendSms')
+
+    request.add_query_param('RegionId', "cn-hangzhou")
+    request.add_query_param('PhoneNumbers', phone)
+    request.add_query_param('SignName', "逸沣安全培训")
+    request.add_query_param('TemplateCode', "SMS_193240726")
+    response = client.do_action(request)
+    return True,u"success"
+
+def send_training_notice(phone,subject_item,begin_time,end_time):
+    """培训通知
+    """
+    request = CommonRequest()
+    request.set_accept_format('json')
+    request.set_domain('dysmsapi.aliyuncs.com')
+    request.set_method('POST')
+    request.set_protocol_type('https') # https | http
+    request.set_version('2017-05-25')
+    request.set_action_name('SendSms')
+
+    request.add_query_param('RegionId', "cn-hangzhou")
+    request.add_query_param('PhoneNumbers', phone)
+    request.add_query_param('SignName', "逸沣安全培训")
+    request.add_query_param('TemplateCode', "SMS_193240727")
+    request.add_query_param('TemplateParam', json.dumps({"subject_item":subject_item,"begin_time":begin_time,"end_time":end_time}))
+    response = client.do_action(request)
+    return True,u"success"
+
+def send_training_notice_special(phone,subject_item,begin_time):
+    """特种作业培训通知
+    """
+    request = CommonRequest()
+    request.set_accept_format('json')
+    request.set_domain('dysmsapi.aliyuncs.com')
+    request.set_method('POST')
+    request.set_protocol_type('https') # https | http
+    request.set_version('2017-05-25')
+    request.set_action_name('SendSms')
+
+    request.add_query_param('RegionId', "cn-hangzhou")
+    request.add_query_param('PhoneNumbers', phone)
+    request.add_query_param('SignName', "逸沣安全培训")
+    request.add_query_param('TemplateCode', "SMS_193230747")
+    request.add_query_param('TemplateParam', json.dumps({"subject_item":subject_item,"begin_time":begin_time}))
+    response = client.do_action(request)
+    return True,u"success"
+
+
+def send_exam_notice(phone,name,subject_item,exam_time):
+    """考试通知
+    """
+    request = CommonRequest()
+    request.set_accept_format('json')
+    request.set_domain('dysmsapi.aliyuncs.com')
+    request.set_method('POST')
+    request.set_protocol_type('https') # https | http
+    request.set_version('2017-05-25')
+    request.set_action_name('SendSms')
+
+    request.add_query_param('RegionId', "cn-hangzhou")
+    request.add_query_param('PhoneNumbers', phone)
+    request.add_query_param('SignName', "逸沣安全培训")
+    request.add_query_param('TemplateCode', "SMS_193235744")
+    request.add_query_param('TemplateParam', json.dumps({"name":name,"subject_item":subject_item,
+        "exam_time":exam_time,"phone":"15884997924"}))
+    response = client.do_action(request)
+    return True,u"success"

+ 0 - 164
src/utils/cloopen_sms.py

@@ -1,164 +0,0 @@
-#coding=utf-8
-'''
-Created on 2018年12月11日
-@author: xiaojincai
-'''
-import os
-import json
-import random
-import datetime
-from hashlib import md5
-import threading
-import logging
-
-import base64
-import requests
-
-logger = logging.getLogger(__name__)
-
-SMS_TEMPLATE_DCT = {
-    "version":"v2.4",
-    "sign":u"【网安云防御】",
-    "396732":{
-        "template_id":"396732",
-        "title":u"用户信息邮件变更通知",
-        "content":u"您的注册邮箱地址在{}由{}变更为{}。如有疑问,请及时与运营人员联系!" 
-    },
-    "400033":{
-        "template_id":"400033",
-        "title":u"用户信息手机号变更通知", 
-        "content":u"您的注册手机号码在{}由{}变更为{}。如有疑问,请及时与运营人员联系!" 
-    },
-    "396735":{
-        "template_id":"396735",
-        "title":u"账号到期提醒通知", 
-        "content":u"您的账号{}将于{}到期,届时该账号下的网站将被停止安全防护服务,请及时与运营人员联系!" 
-    },
-    "396737":{
-        "template_id":"396737",
-        "title":u"账号到期提醒通知(运营)", 
-        "content":u"{}账号将于{}到期,请及时处理!" 
-    },
-    "396739":{
-        "template_id":"396739",
-        "title":u"网站迁出提醒通知(用户)", 
-        "content":u"经检测发现,您的网站{}在{}已迁出云防御系统,处于未防御状态,请予以关注!" 
-    },
-    "396740":{
-        "template_id":"396740",
-        "title":u"网站迁出提醒通知(运营)", 
-        "content":u"经检测发现,网站{}在{}已迁出云防御系统,处于未防御状态,请及时处理!" 
-    },
-    "396742":{
-        "template_id":"396742",
-        "title":u"防御状态变更通知(用户)", 
-        "content":u"您的网站{}在{}变更为{}状态,请予以关注!" 
-    },
-    "396744":{
-        "template_id":"396744",
-        "title":u"防御状态变更通知(运营)", 
-        "content":u"网站{}在{}变更为{}状态,请及时处理!" 
-    },
-    "396746":{
-        "template_id":"396746",
-        "title":u"网站删除通知", 
-        "content":u"网站{}在{}被用户{}删除,云防御系统将无法继续提供安全防护服务,请予以关注!" 
-    },
-    "397198":{
-        "template_id":"397198",
-        "title":u"网站防护策略修改通知", 
-        "content":u"网站{}在{}被用户{}修改了{}策略,请予以关注!" 
-    },
-    "400981":{
-        "template_id":"400981",
-        "title":u"网站到期提醒", 
-        "content":u"您的网站{}将于{}到期,届时该网站将会被自动回源,停止安全防护服务,请及时与运营人员联系!" 
-    },
-    "400984":{
-        "template_id":"400984",
-        "title":u"网站到期提醒(运营)", 
-        "content":u"{}网站将于{}到期,请及时处理!" 
-    },
-    "401151":{
-        "template_id":"401151",
-        "title":u"重置密码短信验证码", 
-        "content":u"您正在进行重置密码操作,验证码是{},请于{}分钟内正确输入!" 
-    },
-    "423122":{
-        "template_id":"423122",
-        "title":u"网站可用状态变更", 
-        "content":u"您的网站{}在{}{}为{}状态,请予以关注!" 
-    }
-}
-
-class CloopenSMS(object):
-    """融联短信接口
-    """
-    def __init__(self):
-        self.sid = "8a216da8588b296f01588ecd0a0001ab"
-        self.token = "f0d2b53782374ebc8a76fa8dd06bb4d2"
-        self.appId = "8a216da8589ae4840158a89b5c8f0272"
-        self.base_url = "https://app.cloopen.com:8883/2013-12-26/Accounts/%s/SMS/TemplateSMS" % self.sid
-         
-    def send(self,phones,template_id,content):
-        """
-        @attention: 发送短信
-        @param content: 短信内容模板变量数组
-        @param phones: 电话号码集合,格式为数组
-        """
-        #构造url
-        now = datetime.datetime.now()
-        batch = now.strftime("%Y%m%d%H%M%S")
-        signature = self.sid + self.token + batch
-        sig = md5(signature).hexdigest().upper()
-        url = self.base_url + "?sig=" + sig
-        
-        #构造header
-        src = "%s:%s"%(self.sid,batch)
-        auth = base64.encodestring(src).strip()
-        headers = {"Accept": "application/json",
-                   "Content-Type": "application/json;charset=utf-8",
-                   "Authorization": auth}
-        
-        #构造body
-        content = map(lambda x:x if isinstance(x, unicode) else str(x).decode("utf8"), content)
-
-        print "send sms >>>:",phones,template_id,content
-        body = {"to": ','.join(phones),
-                "appId": self.appId,
-                "templateId": template_id,
-                "datas": content
-                }
-            
-        #成功直接返回1,失败记录日志,并返回0
-        status_code = ""
-        status_msg = ""
-        response = requests.post(url, headers=headers, data=json.dumps(body))
-        response_code = response.status_code
-        if response_code==200:
-            data = response.json()
-            if data["statusCode"]=="000000":
-                return 1,data
-            else:
-                status_code = data["statusCode"]
-                status_msg = data["statusMsg"]
-                return 0,data
-                
-        #内容,模板ID,号码,http错误码,定义的错误码,操作时间,url
-        now_time = now.strftime("%Y-%m-%d %H:%M:%S")
-        msg = "<<(%s_%s_%s) %s>>:url=%s;\n"%(response_code,status_code,status_msg,now_time,url)
-        sc = ",".join(content)
-        sp = ",".join(phones)
-        msg += "content=[%s];template_id=%s;phones=[%s]\n"%(sc,template_id,sp)
-        return 0,u"未知错误(短信接口报错)"
-
-cloopensms = CloopenSMS()
-
-if __name__ == '__main__':
-    #测试
-    phones = ['15982456282']
-    template_id = '396732'
-    content = ["2018-12-11 14:00:00","496498291@qq.com","496498291@qq.com"]
-
-    cloopensms.send(phones,template_id,content)
-

+ 0 - 29
src/utils/constant.py

@@ -1,29 +0,0 @@
-# coding:utf-8
-# 常用的常量
-DATETIME_FORMAT = "%Y%m%d%H%M%S"
-DATE_FORMAT = "%Y%m%d"
-TIME_FORMAT = "%H%M%S"
-
-DATETIME_FORMAT_DEFAULT = "%Y-%m-%d %H:%M:%S"
-DATE_FORMAT_DEFAULT = "%Y-%m-%d"
-TIME_FORMAT_DEFAULT = "%H:%M:%S"
-
-DATE_FORMAT_SPOT = "%Y.%m.%d"
-
-EVENT_TYPE_CHO = (
-    (1,u"可用性事件"),
-    (2,u"篡改事件"),
-    (3,u"敏感词事件"),
-    (4,u"非法外链事件"),
-    (5,u"非法外链事件"),
-    (6,u"漏洞事件")
-)
-
-EVENT_TYPE_DCT = {
-    "avaible":u"可用性事件",
-    "tamp":u"篡改事件",
-    "keyword":u"敏感词事件",
-    "hidden":u"非法外链事件",
-    "bug":u"漏洞事件",
-    "webshell":u"webshell"
-}

+ 0 - 134
src/utils/email_client.py

@@ -1,134 +0,0 @@
-# coding:utf-8
-# !/user/bin/python2
-"""
-邮件发送模块
-"""
-import time
-import json
-import logging
-from functools import partial
-import threading
-import requests
-import traceback
-
-from email.header import Header
-from email.MIMEText import MIMEText
-from email.utils import parseaddr,formataddr
-import smtplib,time,os
-
-from aliyun_email import AliEmailClient
-
-
-logger = logging.getLogger(__name__)
-
-
-
-Settings = type('Settings', (object, ), 
-                {'EMAIL_URL': 'https://182.138.102.104/push-gateway/v1/push', 
-                 'EMAIL_USER': 'mail.cetcsc.com',
-                 'EMAIL_PASSWD': '30sanpush'})
-
-
-class EmailClient(object):
-    """
-    邮件客户端
-    """
-
-    def __init__(self, url, user, passwd):
-        self.url = url
-        self.user = user
-        self.passwd = passwd
-
-    #def send(self, to, subject, content):
-    #    """
-    #    发送邮件
-    #    :params
-    #    to:   邮件列表 
-    #    subject: 主题
-    #    content: 内容
-    #    """
-    #    auth = requests.auth.HTTPDigestAuth(self.user, self.passwd)
-    #    data = self._gen_content(to, subject, content)
-    #    logger.info("send email, raw data: %s", str(data))
-    #    try:
-    #        r = requests.post(self.url, json=data, auth=auth, verify=False)
-    #        print r.json()
-    #    except Exception as e:
-    #        print e
-    #        return False,str(e)
-    #    if r.status_code != requests.codes.OK:
-    #        return False,r.json()
-    #    try:
-    #        logger.info('send email response: %s', str(r.text))
-    #        ret = r.json()
-    #        if ret['mail']['code'] != '0':
-    #            logger.error("send email failed, reason: %s ", str(ret))
-    #            return False,ret
-    #    except Exception as e:
-    #        return False,str(e)
-    #    return True,"success"
-
-    #def send(self,to,subject,content):
-    #    """
-    #    """
-    #    from_addr = "cetcsc_swad@163.com"
-    #    password = "AXN4zwIoCd"
-    #    smtp_server = "smtp.163.com"
-    #    #自定义处理邮件收发地址的显示内容
-    #    def _format_addr(s):
-    #        name,addr = parseaddr(s)
-    #        #将邮件的name转换成utf-8格式,addr如果是unicode,则转换utf-8输出,否则直接输出addr
-    #        return formataddr((\
-    #            Header(name,'utf-8').encode(),\
-    #            addr.encode("utf-8") if isinstance(addr,unicode) else addr))
-
-    #    #邮件正文是MIMEText
-    #    msg = MIMEText(content,'html','utf-8')
-    #    #邮件对象
-    #    msg['From'] = _format_addr(u'网络监测预警事业部 <%s>'%from_addr)
-    #    #msg['to'] = _format_addr(u'管理员<%s>'%to)
-    #    msg['Subject'] = Header(subject,'utf-8').encode()
-    #    msg['date'] = time.strftime("%a,%d %b %Y %H:%M:%S %z")
-    #    #发送邮件
-    #    try:
-    #        server = smtplib.SMTP(smtp_server,25)
-    #        #server.set_debuglevel(1)
-    #        server.login(from_addr,password)
-    #        server.sendmail(from_addr,to,msg.as_string())
-    #        server.quit()
-    #    except Exception as e:
-    #        return False,str(e)
-    #    return True,"success"
-
-    def send(self,to,subject,content):
-        """
-        """
-        aliemail_client = AliEmailClient()
-        to = to[0] if isinstance(to,type([])) else to
-        res = aliemail_client.send_mail(to,subject,content)
-        if res and res.get("RequestId") and res.get("EnvId"):
-            return True,"success"
-        else:
-            return False,res.get("Message","fail") if res else "fail"
-
-
-    def _gen_content(self, to, subject, content):
-        data = {
-                    "emails": to,
-                    "title": subject,
-                    "body": {
-                        "textHTML": content
-                    }
-                }
-        return data
-
-
-email_client = EmailClient(Settings.EMAIL_URL, Settings.EMAIL_USER, Settings.EMAIL_PASSWD)
-
-if __name__ == '__main__':
-    #测试
-    to = ["scxiaojincai@163.com"]
-    to = "496498291@qq.com"
-    subject = u"删除提醒"
-    content = u"网站{www.test1.com}在2018-08-30 15:30:10 被用户{xxx}删除,云防御系统将无法继续提供安全防护服务,请予以关注!"
-    email_client.send(to,subject,content)

+ 14 - 1
src/utils/exceltool.py

@@ -1,6 +1,7 @@
 #-*-coding:utf-8 -*-
 import StringIO
 import xlwt
+import xlrd
 
 class ExcelTool(object):
     """
@@ -8,6 +9,8 @@ class ExcelTool(object):
     def __init__(self,filename=None):
         self.filename = filename
         self.book = xlwt.Workbook(encoding="utf-8",style_compression=0)
+        self.rbook = xlrd.open_workbook(filename)
+        self.sheet = self.rbook.sheet_by_index(0)
 
     def save_data(self,sheet,header,data):
         """
@@ -15,7 +18,7 @@ class ExcelTool(object):
         sheet = self.book.add_sheet(sheet,cell_overwrite_ok=True)
         #添加表头
         for i in range(0,len(header)):
-            sheet.write(0,i,header[0])
+            sheet.write(0,i,header[i])
 
         #添加数据
         for i in range(0,len(data)):
@@ -26,6 +29,16 @@ class ExcelTool(object):
         self.book.save("/tmp/demo.xls")
         return output.getvalue()
 
+    def get_data(self):
+        """
+        """
+        dct = {}
+        data = []
+        for i in range(1, self.sheet.nrows):
+            row_list = self.sheet.row_values(i)
+            data.append(row_list)
+        return data
+
 
 #if __name__ == "__main__":
 #    mexcel = ExcelTool("/tmp/demo.xls")

+ 0 - 163
src/utils/website_info_collect/Logger.py

@@ -1,163 +0,0 @@
-#!/usr/bin/env python
-# -*- coding:utf-8 -*-
-# author: liangbo
-# date:2014-03-18
-
-#
-# GLOBAL IMPORTS
-#
-import string, logging, os
-import logging
-#from logging.handlers import SysLogHandler
-
-# syslogger = logging.getLogger('syslog')
-# syslogger.setLevel(logging.INFO)
-#
-# syslog_fmt = "365GCD: "
-# fomatter = logging.Formatter(syslog_fmt)
-# syslog_handler = SysLogHandler(('10.10.19.82', 514), facility='local7')
-# syslog_handler.setFormatter(fomatter)
-# syslogger.addHandler(syslog_handler)
-#
-#
-# logger = logging.getLogger('machine_learn_detect')
-# logger.setLevel(logging.INFO)
-# stream_fmt = "%(asctime)s %(module)s %(funcName)s [%(levelname)s]: %(message)s"
-# fomatter = logging.Formatter(stream_fmt)
-# streamhandler = logging.StreamHandler()
-# streamhandler.setFormatter(fomatter)
-# logger.addHandler(streamhandler)
-
-class Logger:
-    '''
-        Static class for logging purposes
-         Use from other classes:
-
-           from Logger import Logger
-           logger = Logger.logger
-
-           logger.debug("Some debug")
-           logger.info("Some info")
-           logger.error("Error")
-        More info at http://docs.python.org/lib/module-logging.html
-    '''
-
-    logger = logging.getLogger('machine_learn_detect')
-    logger.setLevel(logging.INFO)
-
-    DEFAULT_FORMAT = '%(asctime)s %(module)s %(funcName)s [%(levelname)s]: %(message)s'
-    SYSLOG_FORMAT = '%(message)s'
-    __formatter = logging.Formatter(DEFAULT_FORMAT)
-    __streamhandler = None
-
-    # load the console handler by default
-    # it will be removed in daemon mode
-    __streamhandler = logging.StreamHandler()
-    __streamhandler.setFormatter(__formatter)
-    logger.addHandler(__streamhandler)
-
-    # Removes the stream handler
-    # (Useful when agent starts in daemon mode)
-    def remove_console_handler():
-        if Logger.__streamhandler:
-            Logger.logger.removeHandler(Logger.__streamhandler)
-
-    remove_console_handler = staticmethod(remove_console_handler)
-
-    # log to file (file should be log->file in configuration)
-    @staticmethod
-    def _add_file_handler(file, log_level=None):
-
-        dir = file.rstrip(os.path.basename(file))
-        if not os.path.isdir(dir):
-            try:
-                os.makedirs(dir, 0755)
-            except OSError, e:
-                print "Logger: Error adding file handler,", \
-                    "can not create log directory (%s): %s" % (dir, e)
-                return
-
-        try:
-            handler = logging.FileHandler(file)
-        except IOError, e:
-            print "Logger: Error adding file handler: %s" % (e)
-            return
-
-        handler.setFormatter(Logger.__formatter)
-
-        if log_level:  # modify log_level
-            handler.setLevel(log_level)
-        Logger.logger.addHandler(handler)
-
-
-    @staticmethod
-    def add_file_handler(file):
-        Logger._add_file_handler(file)
-
-
-    # Error file handler
-    # the purpouse of this handler is to only log error and critical messages
-    @staticmethod
-    def add_error_file_handler(file):
-        Logger._add_file_handler(file, logging.ERROR)
-
-
-    # send events to a remote syslog
-    @staticmethod
-    def add_syslog_handler(address):
-        from logging.handlers import SysLogHandler
-        handler = SysLogHandler(address, facility='local7')
-        handler.setFormatter(logging.Formatter(Logger.SYSLOG_FORMAT))
-        Logger.logger.addHandler(handler)
-
-
-
-    # show DEBUG messages or not
-    # modifying the global (logger, not handler) threshold level
-    def set_verbose(verbose='info'):
-        if verbose.lower() == 'debug':
-            Logger.logger.setLevel(logging.DEBUG)
-        elif verbose.lower() == 'info':
-            Logger.logger.setLevel(logging.INFO)
-        elif verbose.lower() == 'warning':
-            Logger.logger.setLevel(logging.WARNING)
-        elif verbose.lower() == 'error':
-            Logger.logger.setLevel(logging.ERROR)
-        elif verbose.lower() == 'critical':
-            Logger.logger.setLevel(logging.CRITICAL)
-        else:
-            Logger.logger.setLevel(logging.INFO)
-
-    set_verbose = staticmethod(set_verbose)
-
-    def next_verbose_level(verbose):
-        levels = ['debug', 'info', 'warning', 'error', 'critical']
-        if verbose in levels:
-            index = levels.index(verbose)
-
-            if index > 0:
-                return levels[index - 1]
-
-        return verbose
-
-    next_verbose_level = staticmethod(next_verbose_level)
-
-
-if __name__ == "__main__":
-    logger = Logger.logger
-    Logger.set_verbose('debug')
-    Logger.add_syslog_handler(("10.4.5.86", 514))
-
-    # logs to console
-    logger.debug("Some debug text")
-    logger.info("365GCD: Some info text==============================")
-    logger.critical("Oppps, error")
-
-    # now logs to file and not to log
-    # Logger.add_file_handler('/tmp/agent.log')
-    # Logger.add_error_file_handler('/tmp/agent-error.log')
-    # Logger.remove_console_handler()
-    # logger.debug("log debug info to file")
-    # logger.warning("log warning info to file")
-    # logger.error("log error info to file")
-

+ 0 - 45
src/utils/website_info_collect/Readme.md

@@ -1,45 +0,0 @@
-网站信息查询工具
-=============================
-
-提供网站ICP备案信息查询,网站子域名及IP、IP地域、IP接入商、CDN/WAF检测、虚拟空间检测等信息。
-
---------------------------------
-# 运行环境
-python==2.7,其它依赖库见requirements.txt
-
-# 快速开始
-## 配置
-```bash
-config.py中
-配置ICP接口keys列表,初始key提供35183次查询
-配置'PROCESS_POOL_SIZE',设置进程池大小,默认8
-```
-## 命令
-```bash
-python main.py -n 365gcd.com #单域名方式、365gcd.com为要查询的域名 
-python main.py -f domains.txt  #批量域名方式、domain.txt为域名列表,一行一个域名,输出为outfile_时间.csv
-```
-# 功能指标
-## 功能概览
-* 已完成的信息:主办单位性质、是否备案、ICP备案号、
-* 部分完成的信息:虚拟空间识别、安全设备判断、安全设备识别、CDN判断、CDN识别
-* 未完成的信息:网站负责人
-
-## CDN详情
-* 已收录:百度云加速
-* 计划收录: Ucloud、 网宿、阿里云、腾讯云、金山云
-
-## WAF详情
-* 已收录: 创宇盾
-* 计划收录: 安全狗、 360安域、 阿里云WAF、 腾讯云WAF、安恒WAF、 有云WAF
-
-## 虚拟空间详情
-* 已收录: 新网虚拟主机、万网虚拟主机、西部数码虚拟主机、美橙科技、百度虚拟空间
-* 计划收录: 华为云、35互联、新网互联、华夏名网、联动天下、景安数据、中国数据
-
-# 注意
-* 目前不支持中文域名查询,因为chinaz的接口不支持。
-
-
-
-

+ 0 - 0
src/utils/website_info_collect/__init__.py


+ 0 - 377
src/utils/website_info_collect/beian.py

@@ -1,377 +0,0 @@
-# -*- coding:utf-8 -*-
-"""
--------------------------------------------------
-   File Name:     icp_check
-   Description :   网站信息查询
-   Author :       lihanrui
-   date:          2019/3/4
--------------------------------------------------
-   Change Activity:
-                   2019/3/4:
--------------------------------------------------
-"""
-import requests
-import json
-import socket
-import argparse
-import os
-import time
-import random
-import csv
-
-from multiprocessing import Pool
-socket.setdefaulttimeout(5)
-
-from ipip import ip_manager
-from config import *
-from Logger import Logger
-
-log = Logger.logger
-
-
-def read_file(fpath):
-    if not os.path.exists(fpath):
-        print "%s not exist!" % fpath
-        exit(1)
-    with open(fpath, 'r') as f:
-        return f.readlines()
-
-
-def save_file(filepath, content):
-    try:
-
-        with open(filepath, 'w') as f:
-            f.write(content)
-    except Exception as e:
-        log.debug("%s,%s" % (filepath, e))
-
-
-def http_get(url, headers={}):
-
-    retry = 0
-    headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0"})
-
-    while retry < 2:
-        try:
-            response = requests.get(url, headers=headers, timeout=3)
-            response.encoding = 'utf-8'
-            return response.status_code, response.text
-        except Exception as e:
-            retry += 1
-            time.sleep(0.1)
-
-    return 'except', 'except'
-
-
-def check_access_protect(ip, domain):
-
-    ret = dict()
-    if len(ip) == 0:
-        return ret
-
-    access_url = "http://%s/" % ip
-    reps = []
-    for template in ["http://%s/?id=1 or 1=1",
-                     "http://%s/?id=../../etc/passwd",
-                     "http://%s/?id=http://aewrae.aliff.com/1.txt?%%00"]:
-
-        attack_url = template % ip
-        content, code = http_get(attack_url, {"Host": domain})
-        reps.append((content, code))
-
-    ret["access_rep_code"], _ = http_get(access_url, {"Host": domain})
-
-    if ret["access_rep_code"] in [200, 206, 301, 302, 404]:
-        ret["access_rep"] = '是'
-        for code, content in reps:
-            if code != 200 and code != 404:
-                ret["attack_rep_code"] = code
-                ret["safe_device"] = '是'
-            else:
-                ret["attack_rep_code"] = code
-                ret["safe_device"] = '否'
-    else:
-        ret["access_rep"] = '否'
-        for code, content in reps:
-            if code != ret["access_rep_code"]:
-                ret["attack_rep_code"] = code
-                ret["safe_device"] = '是'
-            else:
-                ret["attack_rep_code"] = code
-                ret["safe_device"] = '否'
-
-    return ret
-
-
-def check_virtualspace(ip, domain):
-    ret = dict()
-    if len(ip) == 0:
-        return ret
-
-    url = "http://%s/" % ip
-    code, content = http_get(url)
-    for i in VIRTUAL_SPACE.keys():
-        if content.find(i) == NOT_FOUND:
-            if len(content) != 0:
-                file_name = "%s_%s.html" % (ip, domain)
-                file_path = os.path.join(vir_dir, file_name)
-                save_file(file_path, content)
-        else:
-            ret["virtualspace"] = VIRTUAL_SPACE[i].encode("utf-8")
-
-    for i in CDN.keys():
-        if content.find(i) == NOT_FOUND:
-            continue
-        else:
-            ret["cdn_name"] = CDN[i].encode("utf-8")
-
-    return ret
-
-
-def get_domain_whois(domain):
-
-    def _get(url):
-        try:
-            response = requests.get(url, timeout=3)
-            return response.json()
-        except Exception as e:
-            log.exception("Request whois interface exception:%s" % e)
-        return {}
-
-    ret = dict()
-    domain = domain.strip()
-    if len(domain) == 0:
-        return ret
-
-    url = whois_interface % (random.choice(keys), domain)
-    json_rep = _get(url)
-    if json_rep:
-        status_code = json_rep.get("StateCode", 0)
-        if status_code == 1:
-            data = json_rep.get("Result", "")
-            if not data:
-                log.info(u"%s 暂无Whois信息..." % domain)
-                return ret
-            ret["ExpirationDate"] = data["ExpirationDate"].encode("utf-8")
-        else:
-            log.info(json.dumps(json_rep, ensure_ascii=False))
-    return ret
-
-def get_ip_info(domain):
-
-    def _get_ip(domain):
-        try:
-            myaddr = socket.getaddrinfo(domain, 'http')
-            return myaddr[0][4][0]
-        except Exception as e:
-            log.exception("%s ,%s" % (domain, e))
-            return None
-
-    def _get_ipip_info(ip):
-        ipx_res = ip_manager.find(ip)
-        if len(ipx_res):
-            country = ipx_res[0]
-            province = ipx_res[1]
-            city = ipx_res[2]
-            # 运营商
-            operator = ipx_res[4]
-            return country, province, city, operator
-        else:
-            return ['']*4
-
-    ret = dict()
-    ip = _get_ip(domain)
-    if ip:
-        country, province, city, operator = _get_ipip_info(ip)
-
-        ret["ip"] = ip
-        ret["ip_location"] = ''.join([country, province, city]).encode("utf-8")
-        ret["operator"] = operator.encode("utf-8")
-
-    return ret
-
-
-def get_website_icpinfo(domain):
-
-    domain = domain.strip()
-
-    def _get(url):
-        try:
-            response = requests.get(url, timeout=3)
-            return response.json()
-        except Exception as e:
-            log.exception("Request icp interface exception:%s" % e)
-        return {}
-    ret = dict()
-
-    url = icp_interface % (random.choice(keys), domain)
-
-    json_rep = _get(url)
-
-    if json_rep:
-        status_code = json_rep.get("StateCode", 0)
-        if status_code == 1:
-            data = json_rep.get("Result", "")
-            if not data:
-                log.info(u"%s 暂无备案信息..." % domain)
-                return ret
-            ret["CompanyName"] = data["CompanyName"].encode("utf-8")
-            ret["CompanyType"] = data["CompanyType"].encode("utf-8")
-            ret["MainPage"] = data["MainPage"]
-            ret["SiteLicense"] = data["SiteLicense"].encode("utf-8")
-            ret["SiteName"] = data["SiteName"].encode("utf-8")
-            ret["VerifyTime"] = data["VerifyTime"]
-        else:
-            log.info(json.dumps(json_rep, ensure_ascii=False))
-    return ret
-
-
-def check_expire_date(str_time):
-    try:
-        expire_date = time.strptime(str_time, '%Y-%m-%d %H:%M:%S')
-    except Exception as e:
-        return '不定'
-
-    now = time.time()
-    str_expire = time.mktime(expire_date)
-    if str_expire - now > 0:
-        return '否'
-    else:
-        return '是'
-
-
-
-
-
-
-
-def get_website_info(domain):
-
-    ret_infos = []
-
-    domain = domain.strip()
-
-    #网站IPC信息查询,没有子域名直接返回
-    ipc_info = get_website_icpinfo(domain)
-    mainpage = ipc_info.pop("MainPage", '')
-    if len(mainpage) == 0:
-        info = ['不定']*21
-        info[0] = domain
-        ret_infos.append(info)
-        return ret_infos
-
-    for subdomain in mainpage.split(" "):
-        #网站IP信息查询
-        ip_info = get_ip_info(subdomain)
-        #网站是否可访问、是否存在安全设备
-        access_info = check_access_protect(ip_info.get("ip", ''), subdomain)#(icp_info["MainPage"])
-        #网站是否在虚拟空间
-        virtualspace = check_virtualspace(ip_info.get("ip", ''), subdomain)
-        #域名whois信息(过期时间)
-        whois_info = get_domain_whois(subdomain)
-
-        ret_infos.append(
-            [domain.encode('utf-8'), subdomain.encode('utf-8'),
-             whois_info.get("ExpirationDate", '不定').strip(), check_expire_date(whois_info.get("ExpirationDate", '不定').strip()),
-             ipc_info.get("SiteName", '不定'), access_info.get("access_rep", '否'),
-             ip_info.get("ip", '不定'), ip_info.get("ip_location", '不定'), ip_info.get("operator", '不定'),
-             ipc_info.get("CompanyType", '不定'), ipc_info.get("CompanyName", '不定'),
-
-             '是' if ipc_info.get("SiteLicense", '') != "" else '否', ipc_info.get("SiteLicense", '不定'),
-             '',
-             '是' if virtualspace.get("virtualspace", '') != "" else '不定', virtualspace.get("virtualspace", '不定'),
-              access_info.get("safe_device", '不定'),
-             '是' if virtualspace.get("cdn_name", '') != "" else '不定', virtualspace.get("cdn_name", '不定'),
-
-             time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), '']
-        )
-    return ret_infos
-
-
-def output_csv(infos):
-
-    localtime = time.localtime()
-    strtime = time.strftime("%Y%m%d%H%M%S", localtime)
-    fname = "outfile_%s.csv" % strtime
-
-    headers = ["根域名", "子域名枚举",
-               "域名到期时间","域名是否到期",
-               "网站名称", "是否正常访问",
-               "所属IP", "地理位置", "运营商",
-               "主办单位性质", "主办单位名称",
-
-               "是否备案", "ICP备案号",
-               "备案时间",
-               "是否虚拟空间接入", "虚拟空间服务商",
-               "是否有安全防护",
-               "是否有CDN","CDN厂商",
-
-               "检查时间", "备注"]
-    with open(fname, 'wb') as f:
-        writer = csv.writer(f)
-        writer.writerow(headers)
-        for info in infos:
-            try:
-                writer.writerow(info)
-            except Exception as e:
-                log.exception("%s" % e)
-
-
-def init():
-
-    if not os.path.exists(os.path.dirname(LOG_File)):
-        os.mkdir(os.path.dirname(LOG_File))
-
-    if not os.path.exists(vir_dir):
-        os.mkdir(vir_dir)
-
-    Logger.add_file_handler(LOG_File)
-
-if __name__ == "__main__":
-
-    parser = argparse.ArgumentParser(prog="icp_info_check", usage="%(prog)s [options] usage", description="Website Information (Incloud: ICP Record Information) Query Tool")
-    parser.add_argument("-n", "--name", help="The root domain name you want to find")
-    parser.add_argument("-f", "--filepath", help="The root domain name list path")
-    parser.add_argument('-v', '--version', action='version', version='version 0.0.1')
-
-    args = parser.parse_args()
-
-    init()
-    if args.filepath:
-
-        filepath = args.filepath
-        lines = read_file(filepath)
-        infos = list()
-        p = Pool(PROCESS_POOL_SIZE)
-        l_result = p.map(get_website_info, lines)
-        for r in l_result:
-            infos.extend(r)
-        if len(infos) != 0:
-            output_csv(infos)
-        else:
-            print "No website parsing success!"
-
-    elif args.name:
-        headers = ["根域名", "子域名枚举",
-                   "域名到期时间","域名是否到期",
-                   "网站名称", "是否正常访问",
-                   "所属IP", "地理位置", "运营商",
-                   "主办单位性质", "主办单位名称",
-                   "是否备案", "ICP备案号",
-                   "备案时间",
-                   "是否虚拟空间接入", "虚拟空间服务商",
-                   "是否有安全防护",
-                   "是否有CDN", "CDN厂商",
-                   "检查时间", "备注"]
-        domain = args.name.strip()
-        info = get_website_info(domain)
-        format_info = dict(zip(headers, info[0]))
-        print json.dumps(format_info, ensure_ascii=False, indent=4).decode("utf-8").encode("gbk")
-
-
-
-
-
-
-
-

+ 0 - 60
src/utils/website_info_collect/config.py

@@ -1,60 +0,0 @@
-# -*- coding:utf-8 -*-
-"""
--------------------------------------------------
-   File Name:     config
-   Description :
-   Author :       lihanrui
-   date:          2019/3/6
--------------------------------------------------
-   Change Activity:
-                   2019/3/6:
--------------------------------------------------
-"""
-
-
-NOT_FOUND = -1
-LOG_File = "./logs/error.log"
-PROCESS_POOL_SIZE = 8
-
-#虚拟空间页面标志
-XINWANG = u"www.xinnet.com"
-WANWANG = u"cp.hichina.com"
-XIBUSHUMA = u"www.myhostadmin.net"
-MEICHENGKEJI = u"static.websiteonline.cn"
-
-BAIDUCLOUD = u"cloud.baidu.com"
-
-VIRTUAL_SPACE = {
-    XINWANG: u"新网虚拟主机",
-    WANWANG: u"万网虚拟主机",
-    XIBUSHUMA: u"西部数码虚拟主机",
-    MEICHENGKEJI: u"美橙科技虚拟主机",
-
-    BAIDUCLOUD: u"百度云虚拟空间",
-}
-
-#虚拟空间页面目录
-vir_dir = "virtualspace_page_dir"
-
-#CDN页面标识
-BAIDUJIASU = u"su.baidu.com"
-
-CDN = {
-    BAIDUJIASU: u"百度云加速",
-}
-
-#WAF安全标识
-CYD = u"www.365cyd.com"
-
-WAF = {
-    CYD: u"创宇盾",
-
-}
-
-#chinaz站长工具查询接口
-icp_interface = "http://apidata.chinaz.com/CallAPI/Domain?key=%s&domainName=%s"
-whois_interface = "http://apidata.chinaz.com/CallAPI/Whois?key=%s&domainName=%s"
-keys = ["1b63b58928e643c8a7df7ada6236e3b8"]
-
-
-

BIN
src/utils/website_info_collect/ipip.ipdb


+ 0 - 89
src/utils/website_info_collect/ipip.py

@@ -1,89 +0,0 @@
-#coding=utf-8
-'''
-Created on 2017年9月13日
-
-@author: bailiangjun
-'''
-
-import struct
-from socket import inet_aton
-import os
-# import settings
-import ipdb
-
-_unpack_V = lambda b: struct.unpack("<L", b)
-_unpack_N = lambda b: struct.unpack(">L", b)
-_unpack_C = lambda b: struct.unpack("B", b)
-class IPX(object):
-    """
-    @attention: 老版本,解析IPV4,已弃用,可删除
-    """
-    binary = ""
-    index = 0
-    offset = 0
-    
-    def __init__(self,fl):
-        path = os.path.abspath(fl)
-        with open(path, "rb") as f:
-            IPX.binary = f.read()
-            IPX.offset, = _unpack_N(IPX.binary[:4])
-            IPX.index = IPX.binary[4:IPX.offset]
-
-    def find(self,ip):
-        """
-        @attention: 解析IP
-        @return: 国,省/州,市,街道,运营商,经度,纬度,时区,时区,行政区划代码,国际区号,顶级域名,未知
-        """
-        index = IPX.index
-        offset = IPX.offset
-        binary = IPX.binary
-        try:
-            nip = inet_aton(ip)
-        except Exception as e:
-            import settings.base_logger as bl
-            import traceback
-            print("%s, ip:%s" % (traceback.format_exc(), ip))
-            return []
-
-        ipdot = ip.split('.')
-        if int(ipdot[0]) < 0 or int(ipdot[0]) > 255 or len(ipdot) != 4:
-            return []
-        tmp_offset = (int(ipdot[0]) * 256 + int(ipdot[1])) * 4
-        start, = _unpack_V(index[tmp_offset:tmp_offset + 4])
-
-        index_offset = index_length = -1
-        max_comp_len = offset - 262144 - 4
-        start = start * 9 + 262144
-
-        while start < max_comp_len:
-            if index[start:start + 4] >= nip:
-                index_offset, = _unpack_V(index[start + 4:start + 7] + chr(0).encode('utf-8'))
-                index_length, = _unpack_C(index[start + 8:start + 9])
-                break
-            start += 9
-
-        if index_offset == 0:
-            return []
-
-        res_offset = offset + index_offset - 262144
-        res = binary[res_offset:res_offset + index_length].decode('utf-8').split("\t")
-        return [item.strip() for item in res]
-
-class IPV6(object):
-    """
-    @attention: 能同时解析IPV4和IPv6
-    """
-
-    def __init__(self,fl):
-        self.db = ipdb.database.Reader(fl)
-        
-    def find(self,ip):
-        try:
-            ip = unicode(ip)
-            info = self.db.find(ip, "CN")
-        except:
-            info = []
-        
-        return info
-#os.path.join("./","ipip.ipdb")
-ip_manager = IPV6("ipip.ipdb")

+ 0 - 377
src/utils/website_info_collect/main.py

@@ -1,377 +0,0 @@
-# -*- coding:utf-8 -*-
-"""
--------------------------------------------------
-   File Name:     icp_check
-   Description :   网站信息查询
-   Author :       lihanrui
-   date:          2019/3/4
--------------------------------------------------
-   Change Activity:
-                   2019/3/4:
--------------------------------------------------
-"""
-import requests
-import json
-import socket
-import argparse
-import os
-import time
-import random
-import csv
-
-from multiprocessing import Pool
-socket.setdefaulttimeout(5)
-
-from ipip import ip_manager
-from config import *
-from Logger import Logger
-
-log = Logger.logger
-
-
-def read_file(fpath):
-    if not os.path.exists(fpath):
-        print "%s not exist!" % fpath
-        exit(1)
-    with open(fpath, 'r') as f:
-        return f.readlines()
-
-
-def save_file(filepath, content):
-    try:
-
-        with open(filepath, 'w') as f:
-            f.write(content)
-    except Exception as e:
-        log.debug("%s,%s" % (filepath, e))
-
-
-def http_get(url, headers={}):
-
-    retry = 0
-    headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0"})
-
-    while retry < 2:
-        try:
-            response = requests.get(url, headers=headers, timeout=3)
-            response.encoding = 'utf-8'
-            return response.status_code, response.text
-        except Exception as e:
-            retry += 1
-            time.sleep(0.1)
-
-    return 'except', 'except'
-
-
-def check_access_protect(ip, domain):
-
-    ret = dict()
-    if len(ip) == 0:
-        return ret
-
-    access_url = "http://%s/" % ip
-    reps = []
-    for template in ["http://%s/?id=1 or 1=1",
-                     "http://%s/?id=../../etc/passwd",
-                     "http://%s/?id=http://aewrae.aliff.com/1.txt?%%00"]:
-
-        attack_url = template % ip
-        content, code = http_get(attack_url, {"Host": domain})
-        reps.append((content, code))
-
-    ret["access_rep_code"], _ = http_get(access_url, {"Host": domain})
-
-    if ret["access_rep_code"] in [200, 206, 301, 302, 404]:
-        ret["access_rep"] = '是'
-        for code, content in reps:
-            if code != 200 and code != 404:
-                ret["attack_rep_code"] = code
-                ret["safe_device"] = '是'
-            else:
-                ret["attack_rep_code"] = code
-                ret["safe_device"] = '否'
-    else:
-        ret["access_rep"] = '否'
-        for code, content in reps:
-            if code != ret["access_rep_code"]:
-                ret["attack_rep_code"] = code
-                ret["safe_device"] = '是'
-            else:
-                ret["attack_rep_code"] = code
-                ret["safe_device"] = '否'
-
-    return ret
-
-
-def check_virtualspace(ip, domain):
-    ret = dict()
-    if len(ip) == 0:
-        return ret
-
-    url = "http://%s/" % ip
-    code, content = http_get(url)
-    for i in VIRTUAL_SPACE.keys():
-        if content.find(i) == NOT_FOUND:
-            if len(content) != 0:
-                file_name = "%s_%s.html" % (ip, domain)
-                file_path = os.path.join(vir_dir, file_name)
-                save_file(file_path, content)
-        else:
-            ret["virtualspace"] = VIRTUAL_SPACE[i].encode("utf-8")
-
-    for i in CDN.keys():
-        if content.find(i) == NOT_FOUND:
-            continue
-        else:
-            ret["cdn_name"] = CDN[i].encode("utf-8")
-
-    return ret
-
-
-def get_domain_whois(domain):
-
-    def _get(url):
-        try:
-            response = requests.get(url, timeout=3)
-            return response.json()
-        except Exception as e:
-            log.exception("Request whois interface exception:%s" % e)
-        return {}
-
-    ret = dict()
-    domain = domain.strip()
-    if len(domain) == 0:
-        return ret
-
-    url = whois_interface % (random.choice(keys), domain)
-    json_rep = _get(url)
-    if json_rep:
-        status_code = json_rep.get("StateCode", 0)
-        if status_code == 1:
-            data = json_rep.get("Result", "")
-            if not data:
-                log.info(u"%s 暂无Whois信息..." % domain)
-                return ret
-            ret["ExpirationDate"] = data["ExpirationDate"].encode("utf-8")
-        else:
-            log.info(json.dumps(json_rep, ensure_ascii=False))
-    return ret
-
-def get_ip_info(domain):
-
-    def _get_ip(domain):
-        try:
-            myaddr = socket.getaddrinfo(domain, 'http')
-            return myaddr[0][4][0]
-        except Exception as e:
-            log.exception("%s ,%s" % (domain, e))
-            return None
-
-    def _get_ipip_info(ip):
-        ipx_res = ip_manager.find(ip)
-        if len(ipx_res):
-            country = ipx_res[0]
-            province = ipx_res[1]
-            city = ipx_res[2]
-            # 运营商
-            operator = ipx_res[4]
-            return country, province, city, operator
-        else:
-            return ['']*4
-
-    ret = dict()
-    ip = _get_ip(domain)
-    if ip:
-        country, province, city, operator = _get_ipip_info(ip)
-
-        ret["ip"] = ip
-        ret["ip_location"] = ''.join([country, province, city]).encode("utf-8")
-        ret["operator"] = operator.encode("utf-8")
-
-    return ret
-
-
-def get_website_icpinfo(domain):
-
-    domain = domain.strip()
-
-    def _get(url):
-        try:
-            response = requests.get(url, timeout=3)
-            return response.json()
-        except Exception as e:
-            log.exception("Request icp interface exception:%s" % e)
-        return {}
-    ret = dict()
-
-    url = icp_interface % (random.choice(keys), domain)
-
-    json_rep = _get(url)
-
-    if json_rep:
-        status_code = json_rep.get("StateCode", 0)
-        if status_code == 1:
-            data = json_rep.get("Result", "")
-            if not data:
-                log.info(u"%s 暂无备案信息..." % domain)
-                return ret
-            ret["CompanyName"] = data["CompanyName"].encode("utf-8")
-            ret["CompanyType"] = data["CompanyType"].encode("utf-8")
-            ret["MainPage"] = data["MainPage"]
-            ret["SiteLicense"] = data["SiteLicense"].encode("utf-8")
-            ret["SiteName"] = data["SiteName"].encode("utf-8")
-            ret["VerifyTime"] = data["VerifyTime"]
-        else:
-            log.info(json.dumps(json_rep, ensure_ascii=False))
-    return ret
-
-
-def check_expire_date(str_time):
-    try:
-        expire_date = time.strptime(str_time, '%Y-%m-%d %H:%M:%S')
-    except Exception as e:
-        return '不定'
-
-    now = time.time()
-    str_expire = time.mktime(expire_date)
-    if str_expire - now > 0:
-        return '否'
-    else:
-        return '是'
-
-
-
-
-
-
-
-def get_website_info(domain):
-
-    ret_infos = []
-
-    domain = domain.strip()
-
-    #网站IPC信息查询,没有子域名直接返回
-    ipc_info = get_website_icpinfo(domain)
-    mainpage = ipc_info.pop("MainPage", '')
-    if len(mainpage) == 0:
-        info = ['不定']*21
-        info[0] = domain
-        ret_infos.append(info)
-        return ret_infos
-
-    for subdomain in mainpage.split(" "):
-        #网站IP信息查询
-        ip_info = get_ip_info(subdomain)
-        #网站是否可访问、是否存在安全设备
-        access_info = check_access_protect(ip_info.get("ip", ''), subdomain)#(icp_info["MainPage"])
-        #网站是否在虚拟空间
-        virtualspace = check_virtualspace(ip_info.get("ip", ''), subdomain)
-        #域名whois信息(过期时间)
-        whois_info = get_domain_whois(subdomain)
-
-        ret_infos.append(
-            [domain.encode('utf-8'), subdomain.encode('utf-8'),
-             whois_info.get("ExpirationDate", '不定').strip(), check_expire_date(whois_info.get("ExpirationDate", '不定').strip()),
-             ipc_info.get("SiteName", '不定'), access_info.get("access_rep", '否'),
-             ip_info.get("ip", '不定'), ip_info.get("ip_location", '不定'), ip_info.get("operator", '不定'),
-             ipc_info.get("CompanyType", '不定'), ipc_info.get("CompanyName", '不定'),
-
-             '是' if ipc_info.get("SiteLicense", '') != "" else '否', ipc_info.get("SiteLicense", '不定'),
-             '',
-             '是' if virtualspace.get("virtualspace", '') != "" else '不定', virtualspace.get("virtualspace", '不定'),
-              access_info.get("safe_device", '不定'),
-             '是' if virtualspace.get("cdn_name", '') != "" else '不定', virtualspace.get("cdn_name", '不定'),
-
-             time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), '']
-        )
-    return ret_infos
-
-
-def output_csv(infos):
-
-    localtime = time.localtime()
-    strtime = time.strftime("%Y%m%d%H%M%S", localtime)
-    fname = "outfile_%s.csv" % strtime
-
-    headers = ["根域名", "子域名枚举",
-               "域名到期时间","域名是否到期",
-               "网站名称", "是否正常访问",
-               "所属IP", "地理位置", "运营商",
-               "主办单位性质", "主办单位名称",
-
-               "是否备案", "ICP备案号",
-               "备案时间",
-               "是否虚拟空间接入", "虚拟空间服务商",
-               "是否有安全防护",
-               "是否有CDN","CDN厂商",
-
-               "检查时间", "备注"]
-    with open(fname, 'wb') as f:
-        writer = csv.writer(f)
-        writer.writerow(headers)
-        for info in infos:
-            try:
-                writer.writerow(info)
-            except Exception as e:
-                log.exception("%s" % e)
-
-
-def init():
-
-    if not os.path.exists(os.path.dirname(LOG_File)):
-        os.mkdir(os.path.dirname(LOG_File))
-
-    if not os.path.exists(vir_dir):
-        os.mkdir(vir_dir)
-
-    Logger.add_file_handler(LOG_File)
-
-if __name__ == "__main__":
-
-    parser = argparse.ArgumentParser(prog="icp_info_check", usage="%(prog)s [options] usage", description="Website Information (Incloud: ICP Record Information) Query Tool")
-    parser.add_argument("-n", "--name", help="The root domain name you want to find")
-    parser.add_argument("-f", "--filepath", help="The root domain name list path")
-    parser.add_argument('-v', '--version', action='version', version='version 0.0.1')
-
-    args = parser.parse_args()
-
-    init()
-    if args.filepath:
-
-        filepath = args.filepath
-        lines = read_file(filepath)
-        infos = list()
-        p = Pool(PROCESS_POOL_SIZE)
-        l_result = p.map(get_website_info, lines)
-        for r in l_result:
-            infos.extend(r)
-        if len(infos) != 0:
-            output_csv(infos)
-        else:
-            print "No website parsing success!"
-
-    elif args.name:
-        headers = ["根域名", "子域名枚举",
-                   "域名到期时间","域名是否到期",
-                   "网站名称", "是否正常访问",
-                   "所属IP", "地理位置", "运营商",
-                   "主办单位性质", "主办单位名称",
-                   "是否备案", "ICP备案号",
-                   "备案时间",
-                   "是否虚拟空间接入", "虚拟空间服务商",
-                   "是否有安全防护",
-                   "是否有CDN", "CDN厂商",
-                   "检查时间", "备注"]
-        domain = args.name.strip()
-        info = get_website_info(domain)
-        format_info = dict(zip(headers, info[0]))
-        print json.dumps(format_info, ensure_ascii=False, indent=4).decode("utf-8").encode("gbk")
-
-
-
-
-
-
-
-

+ 0 - 3
src/utils/website_info_collect/requirements.txt

@@ -1,3 +0,0 @@
-requests==2.9.1
-ipip-ipdb==1.2.1
-gevent==1.1.1

+ 0 - 4
src/utils/website_info_collect/test.py

@@ -1,4 +0,0 @@
-#coding:utf-8
-import main
-
-print main.get_website_icpinfo("www.baidusdfs.com")

+ 10 - 34
src/weixin/control_auth.py

@@ -29,44 +29,20 @@ def add_wxauth_info(request):
 def get_wxauth_info(request):
     """
     """
-    #qdata = request.json
-    #need_params = ["nickname","avatar","openid"]
-    #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()
     #
-    data = {
-        "id":1,
-        "name":"肖小肖",
-        "sex":1,
-        "idno":"12321312312",
-        "education":"本科",
-        "phone":"15982456282",
-        "class_id":12,
-        "company":"网安",
-        "subject_id":12,
-        "subject_item":"特种人员|电工作业|准操项目|培训类型",
-        "train_type":1,
-        "receive_card":"邮寄",
-        "area":"四川|巴中|巴州区",
-        "address":"回风大道15号",
-        "remark":"备注1",
-        "idnoimg_face":"https://www.scxjc.club/test.png",
-        "idnoimg_back":"https://www.scxjc.club/test2.png",
-        "halfbody_img":"https://www.scxjc.club/tes3.png",
-        "education_img":"https://www.scxjc.club/test4.png",
-        "oldcard_img":"https://www.scxjc.club/test4.png",
-        "price":1800
-    }
-    return data
+    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))
 
 
 

+ 0 - 97
src/weixin/control_bankcard.py

@@ -1,97 +0,0 @@
-#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))
-
-
-
-

+ 0 - 81
src/weixin/control_department.py

@@ -1,81 +0,0 @@
-#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)
-
-    
-
-
-
-

+ 0 - 129
src/weixin/control_organization.py

@@ -1,129 +0,0 @@
-#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
-

+ 0 - 36
src/weixin/control_permission.py

@@ -1,36 +0,0 @@
-#-*-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
-

+ 271 - 155
src/weixin/controls.py

@@ -1,13 +1,17 @@
-#coding=utf-8
+# coding=utf-8
 '''
 '''
+import os
 import json,time
 from django.db import transaction
+from django.db.models import Q
 import common.models as cm
 import common.error_info as ce
 import common.common_functions as ccf
 import common.common_control as ccc
 import wzhifuSDK as wxpay
+from django.conf import settings
+from PIL import Image,ImageDraw,ImageFont
 
 def get_index_data(request):
     """
@@ -39,6 +43,7 @@ def get_article_info(request):
     id = qdata.get("id")
     data = list(cm.Article.objects.filter(id=id).values())
     data = data[0] if data else {}
+    data["imgs"] = json.loads(data["imgs"]) if data["imgs"] else []
     return data
 
 def get_intro_info(request):
@@ -57,26 +62,23 @@ def get_intro_info(request):
 def get_signup_list(request):
     """
     """
-    data = [
-        {"relaname":u"肖小肖",
-        "phone":"15982456282",
-        "class_name":u"一班",
-        "class_id":1,
-        "subject_item":u"安全生产管理|电工作业|高压电工",
-        "class_hour":30,
-        "class_hour_finished":10,
-        "train_type":u"新办",
-        "order_status":0,
-        "ctime":"2020-05-05 22:11:12",
-        "id":1
-        }
-    ]
-    qset = cm.SignupOrders.objects.filter(user_id=2)
+    uid = request.user.id
+    qset = cm.SignupOrders.objects.filter(user_id=uid).order_by("-id")
     qdata = list(qset.values())
     for qd in qdata:
-        qd["subject_item"] = u"特种作业|电工|高压电工"
-        qd["class_name"] = cm.Class.objects.filter(id=qd["class_id"]).first().name
-        qd["class_hour"] = cm.Class.objects.filter(id=qd["class_id"]).first().class_hour
+        try:
+            qd["class_name"] = cm.Class.objects.filter(id=qd["class_id"]).first().name
+        except:
+            qd["class_name"] = ""
+        try:
+            qd["signup_limit"] = cm.Class.objects.filter(id=qd["class_id"]).first().signup_limit
+        except:
+            qd["signup_limit"] = 0
+        try:
+            qd["class_hour"] = cm.Class.objects.filter(id=qd["class_id"]).first().class_hour
+        except:
+            qd["class_hour"] = 0
+        qd["signup_count"] = cm.SignupOrders.objects.filter(class_id=qd["class_id"]).count()
     return qdata
 
 def get_signup_info(request):
@@ -88,73 +90,82 @@ def get_signup_info(request):
     id = qdata.get("id")
     data = list(cm.SignupOrders.objects.filter(id=id).values())
     data = data[0] if data else {}
+    data["device_cats"] = json.loads(data["device_cats"]) if data["device_cats"] else []
     return data
 
 def get_class_list(request):
     """
     """
-    data = [{
-        "type":u"特种作业1",
-        "classes":[
-        {
-        "id":1,
-        "class_name":u"高压电一班",    
-        "price":1800.00,    
-        "class_time":"2020.04.01,2020.05.01",    
-        "thresh_count":100,
-        "signuped_count":10},
-        {
-        "id":1,
-        "class_name":u"高压电一班",    
-        "price":1800.00,    
-        "class_time":"2020.04.01,2020.05.01",    
-        "thresh_count":100,
-        "signuped_count":10}
-        ]
-    }]
+    qdata = request.json
     qset = cm.Class.objects.filter(status=1)
+    if qdata.get("subject_item0"):
+        qset = qset.filter(subject_item__icontains=qdata.get("subject_item0"))
+    if qdata.get("subject_item0") and qdata.get("subject_item1"):
+        subject_item = u"{}|{}".format(qdata.get("subject_item0"),qdata.get("subject_item1"))
+        qset = qset.filter(subject_item__icontains=subject_item)
+    if qdata.get("subject_item0") and qdata.get("subject_item1") and qdata.get("subject_item2"):
+        subject_item = u"{}|{}|{}".format(qdata.get("subject_item0"),qdata.get("subject_item1"),qdata.get("subject_item2"))
+        qset = qset.filter(subject_item__icontains=subject_item)
     qdata = list(qset.values())
     dct = {}
     data = []
-    print qdata,4444444444444
-    for qd in qdata:
-        qd["price_new"] = 1000.00
-        qd["price_re"] = 1000.00
-        qd["price_change"] = 2000.00
-        qd["class_time"] = qd["signup_time"]
-        qd["thresh_count"] = qd["signup_limit"]
-        if dct.has_key(qd["subject_name"]):
-            dct[qd["subject_name"]].append(qd)
-        else:
-            dct[qd["subject_name"]] = [qd]
-    for k,v in dct.items():
-        data.append({"type":k,"classes":v})
+    if request.json.get("signup"):
+        for qd in qdata:
+            qd["price_new"] = 1000.00
+            qd["price_re"] = 1000.00
+            qd["price_change"] = 2000.00
+            qd["class_time"] = qd["signup_time"]
+            qd["thresh_count"] = qd["signup_limit"]
+            qd["signuped_count"] = cm.SignupOrders.objects.filter(class_id=qd["id"]).count()
+            data.append(qd)
+    else:
+        for qd in qdata:
+            qd["price_new"] = 1000.00
+            qd["price_re"] = 1000.00
+            qd["price_change"] = 2000.00
+            qd["class_time"] = qd["signup_time"]
+            qd["thresh_count"] = qd["signup_limit"]
+            qd["signuped_count"] = cm.SignupOrders.objects.filter(class_id=qd["id"]).count()
+            if dct.has_key(qd["subject_name"]):
+                dct[qd["subject_name"]].append(qd)
+            else:
+                dct[qd["subject_name"]] = [qd]
+        for k,v in dct.items():
+            data.append({"type":k,"classes":v})
     return data
 
 
 def get_training_list(request):
     """
     """
-    data = {
-        "videos":[{
-            "title":u"高压电工实操课程",     
-            "image":u"https://www.scxjc.club/images/jgjj.png",     
-            "url":u"https://www.scxjc.club/demo.mp4",     
-            "class_hour":20,     
-            "total_time":"45:32",     
-            "finished_time":"30:32",
-            "status":1
-        }],     
-        "papers":[{
-            "id":1, 
-            "title":u"高压电工实操模拟试题",     
-            "class_hour":20,     
-            "full_mark":100,     
-            "time_limit":60,     
-            "mark":90,     
-            "status":1     
-        }]
-    }
+    #获取视频信息
+    uid = request.user.id
+    #获取已报科目
+    subject_ids = list(cm.SignupOrders.objects.filter(order_status=2,user_id=uid).values_list("subject_id",flat=True))
+    if subject_ids:
+        vset = cm.Videos.objects.filter(subject_id__in=subject_ids)
+        videos = list(vset.values())
+        for video in videos:
+            video["class_hour"] = 20
+            video["total_time"] = "45:32"
+            video["finished_time"] = "55:32"
+            video["image"] = video["img"]
+            video["status"] = 1
+        #获取试卷信息
+        pset = cm.Papers.objects.filter(subject_id__in=subject_ids)
+        papers = list(pset.values())
+        for paper in papers:
+            sub = cm.Subject.objects.filter(id=paper["subject_id"]).first()
+            class_hour = sub.class_hour if sub else 0
+            paper["class_hour"] = class_hour
+            paper["time_limit"] = paper["total_time"] 
+            paper["full_mark"] = paper["total_score"]
+            paper["mark"] = 0
+            paper["status"] = 1
+    else:
+        papers = []
+        videos = []
+    data = {"papers":papers,"videos":videos}
     return data
 
 
@@ -165,74 +176,78 @@ def get_paper_info(request):
     if mse:
         raise ce.TipException(mse)
     id = qdata.get("id")
-    data = {
-        "id":1, 
-        "title":u"高压电工实操模拟试题",     
-        "class_hour":20,     
-        "full_mark":100,     
-        "time_limit":60,     
-        "mark":90,     
-        "status":1,
-        "questions":[
-            {
-                "id":1,
-                "type":1,
-                "title":u"欧姆定律是什么",
-                "options":[u"A、电阻",u"B、电流"],
-                "stand_answer":"A",
-                "myanswer":"A"
-            },
-            {
-                "id":2,
-                "type":2,
-                "title":u"欧姆定律是什么",
-                "options":[u"A、电阻",u"B、电流"],
-                "stand_answer":["A","B"],
-                "myanswer":["A","B"]
-            },
-            {
-                "id":3,
-                "type":3,
-                "title":u"电流等于电压除电阻",
-                "options":[u"对",u"错"],
-                "stand_answer":[u"对"],
-                "myanswer":[u"对"]
-            } 
-        ]
-    }
-    return data
+    paperset = cm.Papers.objects.filter(id=id)
+    paper = paperset.values().first() if paperset else {}
+    paper["full_mark"] = paper.get("total_score")
+    paper["time_limit"] = paper.get("total_time")
+    questions = list(paperset.first().questions.all().values())
+    for que in questions:
+        que["options"] = filter(lambda x:x,que["options"].split(" "))
+    paper["questions"] = questions
+    return paper
 
 
 def add_signup(request):
     """
     """
+    uid = request.user.id
     qdata = request.json
     need_params = ["name","sex","idno","education","phone",
         "train_type","receive_card","price"]
     mse = ccf.check_params(*need_params,**qdata)
     if mse:
         raise ce.TipException(mse)
-    need_params.extend(["company","class_id","remark","idnoimg_face","idnoimg_back","halfbody_img","education_img","oldcard_img","area","address","subject_id","subject_item"])
+    need_params.extend(["company","class_id","remark","idnoimg_face","idnoimg_back",
+        "halfbody_img","education_img","oldcard_img","area","address","subject_id","subject_item","device_cats"])
     vals = ccf.get_need_params(*need_params,**qdata)
-    vals["cid"] = 1
-    vals["user_id"] = 2
+    if vals.get("device_cats"):
+        vals["device_cats"] = json.dumps(vals["device_cats"])
+    vals["cid"] = uid
+    vals["user_id"] = uid
+    vals["order_status"] = -1
+    if vals["class_id"]:
+        vals["subject_item"] = cm.Class.objects.filter(id=vals["class_id"]).first().subject_item
+    else:
+        vals["subject_item"] = vals["subject_item"]
     obj = cm.SignupOrders.objects.create(**vals)
+    #更新用户信息
+    userinfo = cm.UserInfo.objects.filter(id=uid).first().userinfo
+    userinfo = json.loads(userinfo) if userinfo else {}
+    #if userinfo:
+    #    vals.update(userinfo)
+    userinfo.update(vals)
+    cm.UserInfo.objects.filter(id=uid).update(userinfo=json.dumps(userinfo))
     return obj.id
 
 
 def update_signup(request):
     """
     """
+    uid = request.user.id
     qdata = request.json
     need_params = ["id"]
     mse = ccf.check_params(*need_params,**qdata)
     if mse:
         raise ce.TipException(mse)
-    id = qdata.pop("id")
-    need_params.extend(["name","sex","idno","education","phone","train_type","receive_card","area","price","company","class_id","remark","idnoimg_face","idnoimg_back","halfbody_img","education_img","oldcard_img","subject_item","subject_id","address"])
+    need_params.extend(["name","sex","idno","education","phone","train_type",
+        "receive_card","area","price","company","class_id","remark",
+        "idnoimg_face","idnoimg_back","halfbody_img","education_img","oldcard_img",
+        "subject_item","subject_id","address","device_cats"])
     vals = ccf.get_need_params(*need_params,**qdata)
-    vals["cid"] = 1
+    if vals.get("device_cats"):
+        vals["device_cats"] = json.dumps(vals["device_cats"])
+    id = vals.pop("id")
+    vals["cid"] = uid
+    if vals.get("idnoimg_face") and vals.get("idnoimg_back") and vals.get("halfbody_img"):
+        vals["order_status"] = 0
     obj = cm.SignupOrders.objects.filter(id=id).update(**vals)
+    #更新用户信息
+    userinfo = cm.UserInfo.objects.filter(id=uid).first().userinfo
+    userinfo = json.loads(userinfo) if userinfo else {}
+    #if userinfo:
+    #    vals.update(userinfo)
+    userinfo.update(vals)
+    cm.UserInfo.objects.filter(id=uid).update(userinfo=json.dumps(userinfo))
     return obj
 
 
@@ -292,51 +307,25 @@ def get_yrxdetail(request):
 def get_subject_tree(sub=None,data=None):
     """
     """
-    roots = list(cm.Subject.objects.filter(pid=0).values())
-    print roots,777777
+    roots = list(cm.Subject.objects.filter(Q(pid=0)|Q(pid__isnull=True)).values())
+    for citem in roots:
+        citem["device_cats"] = json.loads(citem["device_cats"]) if citem["device_cats"] else []
     for rn in roots:
-        rn["children"] = list(cm.Subject.objects.filter(pid=rn["id"]).values())
+        children = list(cm.Subject.objects.filter(pid=rn["id"]).values())
+        for citem in children:
+            citem["device_cats"] = json.loads(citem["device_cats"]) if citem["device_cats"] else []
+        rn["children"] = children
         for rnn in rn["children"]:
-            rnn["children"] = list(cm.Subject.objects.filter(pid=rnn["id"]).values())
+            children = list(cm.Subject.objects.filter(pid=rnn["id"]).values())
+            for citem in children:
+                citem["device_cats"] = json.loads(citem["device_cats"]) if citem["device_cats"] else []
+            rnn["children"] = children
     return roots
 
 
 def get_subjectitem_tree(request):
     """
     """
-    data = [{
-        "id":1,
-        "intro":u"说明",
-        "name":u"特种作业",     
-        "price_new":1200,     
-        "price_re":120,     
-        "price_change":120,     
-        "children":[{
-            "id":2,
-            "price_new":1200,     
-            "price_re":120,     
-            "price_change":120,     
-            "name":u"电工作业",    
-            "intro":u"说明",
-            "children":[{"id":3,"name":u"低压电工","children":[],"intro":u"说明"}]
-        }]},
-        {
-        "id":4,
-        "price_new":1200,     
-        "price_re":120,     
-        "price_change":120,     
-        "name":u"安全生产",     
-        "intro":u"说明",
-        "children":[{
-            "price_new":1200,     
-            "price_re":120,     
-            "price_change":120,     
-            "id":5,
-            "name":u"子分类1",    
-            "intro":u"说明",
-            "children":[{"id":6,"name":u"子分类2","children":[],"intro":u"说明"}]
-        }]}
-    ]
     data = get_subject_tree()
     return data
 
@@ -348,7 +337,25 @@ def post_paper(request):
     if mse:
         raise ce.TipException(mse)
     paper_id = qdata.get("paper_id")
-    return True
+    user_id = request.user.id
+    title = cm.Papers.objects.filter(id=paper_id).first().title
+    total_score = 0
+    questions = qdata.get("questions")
+    for ans in questions:
+        que = cm.Questions.objects.filter(id=ans["id"]).first()
+        std_ans = que.answer
+        std_score = que.score if que.score else 0
+        if ans["answer"] == std_ans:
+            total_score += std_score
+    obj,flag = cm.PostPapers.objects.get_or_create(
+        title=title,
+        paper_id=paper_id,
+        user_id=user_id,
+        )
+    obj.questions = json.dumps(questions)
+    obj.score = total_score
+    obj.save()
+    return total_score
 
 
 def save_video_time(request):
@@ -366,6 +373,8 @@ def get_docs_list(request):
         "name":u"报名表格",     
         "url":u"https://www.scxjc.club/test.docx"     
     }]
+    qset = cm.Docs.objects.all().order_by("-id")
+    data = list(qset.values())
     return data
 
 def do_signup_pay(request):
@@ -374,9 +383,116 @@ def do_signup_pay(request):
     mse = ccf.check_params(*need_params,**qdata)
     if mse:
         raise ce.TipException(mse)
-    signup_id = str(qdata.get("signup_id"))+str(int(time.time()))
-    total_fee = str(qdata.get("total_fee"))
-    openid = "ow7pX470Bl6IPeM188gNT8PjMBlw"
-    prepayinfo = wxpay.get_wx_unifiedorder(signup_id,total_fee,openid)
+    bill_mat = qdata.get("bill_mat")
+    bill_type = qdata.get("bill_type")
+    bill_no = qdata.get("bill_no")
+    bill_name = qdata.get("bill_name")
+    signup_order = cm.SignupOrders.objects.filter(id=qdata.get("signup_id")).first()
+    if not signup_order:
+        raise ce.TipException(u"订单不存在!")
+    signup_order.bill_mat = bill_mat
+    signup_order.bill_type = bill_type
+    signup_order.bill_no = bill_no
+    signup_order.bill_name = bill_name
+    if not signup_order.out_trade_no:
+        out_trade_no = str(qdata.get("signup_id"))+str(int(time.time()))
+        signup_order.out_trade_no = out_trade_no
+    else:
+        out_trade_no = signup_order.out_trade_no
+    signup_order.save()
+    total_fee = str(qdata.get("total_fee")*100)
+    openid = request.user.openid
+    prepayinfo = wxpay.get_wx_unifiedorder(out_trade_no,total_fee,openid)
+    prepayinfo["key"] = wxpay.WxPayConf_pub.KEY
     return prepayinfo
 
+def do_wxpay_notify(request):
+    qdata = request.json
+    flag,res = wxpay.check_notify_valid(request.body)
+    if flag:
+        out_trade_no = res.get("out_trade_no")
+        transaction_id = res.get("transaction_id")
+        pay_time = res.get("time_end")
+        cm.SignupOrders.objects.filter(out_trade_no=out_trade_no)\
+        .update(order_status=2,pay_status=1,pay_time=pay_time,transaction_id=transaction_id)
+        #发送支付成功通知
+        from utils.aliyun_sms import send_pay_notice
+        import common.common_notice as cn
+        sorder = cm.SignupOrders.objects.filter(out_trade_no=out_trade_no).first()
+        phone = sorder.phone if sorder else None
+        transaction_id = sorder.transaction_id
+        user_id = sorder.user_id
+        if phone and user_id and not transaction_id:
+            send_pay_notice(phone)
+            cn.send_pay_notice(user_id)
+        return True
+    return False
+
+def addText(img,orgpath,string,path,point=(100,100),size=32):
+    draw = ImageDraw.Draw(img)
+    fontpath = os.path.join(settings.BASE_DIR,"templates/font/simsun.ttc")
+    font = ImageFont.truetype(fontpath, size,encoding="unic")
+    draw.text(point,string,fill='black',font=font)
+    img.save(path)
+
+def gen_classhour(request):
+    """生成学时证明
+    """
+    uid = request.user.id
+    qdata = request.json
+    signup_id = qdata.get("signup_id")
+    userinfo = json.loads(request.user.userinfo) if request.user.userinfo else {}
+    realname = json.loads(request.user.userinfo).get("name") if request.user.userinfo else ""
+    subject_item = userinfo.get("subject_item")
+    subject_item0 = userinfo.get("subject_item").split("|")[0]
+    subject_item1 = userinfo.get("subject_item").split("|")[1]
+    subject_item2 = userinfo.get("subject_item").split("|")[2]
+    train_type = userinfo.get("train_type")
+    name = userinfo.get("name")
+    root_target = os.path.join(settings.BASE_DIR,"../static/upload")
+    root = os.path.join(settings.BASE_DIR,"templates")
+    class_hour_tpl = os.path.join(root,"classhour.png")
+    class_hour_file = os.path.join(root_target,str(int(time.time()))+"classhour{}.png".format(uid))
+    signup_order = cm.SignupOrders.objects.filter(id=signup_id).first()
+    subject = cm.Subject.objects.filter(id=signup_order.subject_id).first()
+    if train_type == u"新办":
+        total_classhour = subject.class_hour
+    elif train_type == u"复审":
+        total_classhour = subject.update_class_hour
+    else:
+        total_classhour = subject.change_class_hour
+    #
+    img = Image.open(class_hour_tpl)
+    addText(img,class_hour_tpl,unicode("巴中逸沣安全培训学时证明","utf-8"),class_hour_file,(160,65),24)
+    addText(img,class_hour_tpl,unicode("姓名:{}".format(name),"utf-8"),class_hour_file,(80,100),20)
+    addText(img,class_hour_tpl,unicode("工种:{}".format(subject_item0),"utf-8"),class_hour_file,(80,130),20)
+    addText(img,class_hour_tpl,unicode("操作类型:{}".format(subject_item1),"utf-8"),class_hour_file,(80,160),20)
+    addText(img,class_hour_tpl,unicode("准操项目:{}".format(subject_item2),"utf-8"),class_hour_file,(80,190),20)
+    addText(img,class_hour_tpl,unicode("培训类型:{}".format(train_type),"utf-8"),class_hour_file,(80,220),20)
+    addText(img,class_hour_tpl,unicode("总学时:{}".format(total_classhour),"utf-8"),class_hour_file,(80,250),20)
+    addText(img,class_hour_tpl,unicode("已完成学时:{}".format(170),"utf-8"),class_hour_file,(80,280),20)
+    #addText(class_hour_tpl,"请提供学时证明内容",class_hour_file)
+    url = settings.HOST+"/upload" + class_hour_file.replace(root_target,"")
+    cm.SignupOrders.objects.filter(id=signup_id).update(classhour_cert_url=url)
+    return url
+
+
+def get_classhour_card(request):
+    """获取学时证明
+    """
+    uid = request.user.id
+    sorders = cm.SignupOrders.objects.filter(user_id=uid,classhour_cert_url__isnull=False)
+    classhour_cards = list(sorders.values_list("classhour_cert_url",flat=True))
+    classhour_cards = [{"url":x} for x in classhour_cards]
+    return classhour_cards
+
+def get_notice_list(request):
+    """
+    """
+    uid = request.user.id
+    #uid = 21
+    qset = cm.SysNotice.objects.filter(to=uid).order_by("-id")
+    data = list(qset.values())
+    return data
+
+

+ 5 - 1
src/weixin/urls_backstage.py

@@ -2,10 +2,11 @@
 '''
 '''
 from django.conf.urls import url
-from . import views,views_backstage
+from . import views
 
 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$', views.IndexView.as_view()),
@@ -14,6 +15,7 @@ urlpatterns = [
     url(r'^signup/list$', views.SignUpListView.as_view()),
     url(r'^signup$', views.SignUpView.as_view()),
     url(r'^signup/pay$', views.SignUpPayView.as_view()),
+    url(r'^xcxzfnotify$', views.WxPayNotifyView.as_view()),
     url(r'^class/list$', views.ClassListView.as_view()),
     url(r'^training/list$', views.TrainingListView.as_view()),
     url(r'^paper/info$', views.PaperView.as_view()),
@@ -23,6 +25,8 @@ urlpatterns = [
     url(r'^savevtime$', views.SaveVideoTimeView.as_view()),
     url(r'^docs$', views.GetDocsListView.as_view()),
     url(r'^notice$', views.GetNoticeListView.as_view()),
+    url(r'^genclasshour$', views.GenClassHourView.as_view()),
+    url(r'^classhourcard$', views.ClassHourCardView.as_view()),
     #猿人学
     url(r'^yrxindex$', views.YuanrenxueIndexView.as_view()),
     url(r'^yrxlist$', views.YuanrenxueListView.as_view()),

+ 72 - 31
src/weixin/views.py

@@ -13,6 +13,7 @@ import common.common_control as ccc
 import common.common_functions as ccf
 import weixin.control_auth as ca
 import weixin.controls as ctl
+import weixin.wzhifuSDK as wzf
 
 class YuanrenxueIndexView(cv.BaseView):
     def get(self,request):
@@ -49,8 +50,22 @@ class YuanrenxueDetailView(cv.BaseView):
             return cv.to_fail(e)
 
 
+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.BaseView):
+class AuthinfoView(cv.AuthView):
     def get(self,request):
         """#获取用户信息(小程序)
         """
@@ -61,15 +76,12 @@ class AuthinfoView(cv.BaseView):
             cv.tracefail()
             return cv.to_fail(e)
 
-    def post(self, request):
-        """#保存微信授权信息(小程序)
-        @nickname:"新",昵称
-        @avatar:"",头像
-        @openid:"",openid
+    def put(self, request):
+        """#修改个人信息(小程序)
         """
         try:
-            rst = ca.add_wxauth_info(request)
-            return cv.to_suc({"uid":rst.id})
+            rst = ca.update_wxauth_info(request)
+            return cv.to_suc()
         except Exception as e:
             cv.tracefail()
             return cv.to_fail(e)
@@ -113,7 +125,7 @@ class IntroView(cv.BaseView):
             return cv.to_fail(e)
 
 
-class SignUpListView(cv.BaseView):
+class SignUpListView(cv.AuthView):
     def get(self, request):
         """#报名列表(小程序)
         """
@@ -125,7 +137,7 @@ class SignUpListView(cv.BaseView):
             return cv.to_fail(e)
 
 
-class ClassListView(cv.BaseView):
+class ClassListView(cv.AuthView):
     def get(self, request):
         """#班级列表(小程序)
         @subject_item0:"特种作业"
@@ -140,7 +152,7 @@ class ClassListView(cv.BaseView):
             return cv.to_fail(e)
 
 
-class TrainingListView(cv.BaseView):
+class TrainingListView(cv.AuthView):
     def get(self, request):
         """#在线培训列表(小程序)
         """
@@ -152,7 +164,7 @@ class TrainingListView(cv.BaseView):
             return cv.to_fail(e)
 
 
-class PaperView(cv.BaseView):
+class PaperView(cv.AuthView):
     def get(self, request):
         """#获取试题详情(小程序)
         """
@@ -164,7 +176,7 @@ class PaperView(cv.BaseView):
             return cv.to_fail(e)
 
 
-class PostPaperView(cv.BaseView):
+class PostPaperView(cv.AuthView):
     def post(self, request):
         """#交卷接口(小程序)
         @paper_id:1,试卷接口
@@ -172,7 +184,7 @@ class PostPaperView(cv.BaseView):
         """
         try:
             rst = ctl.post_paper(request)
-            return cv.to_suc({"score":90})
+            return cv.to_suc({"score":rst})
         except Exception as e:
             cv.tracefail()
             return cv.to_fail(e)
@@ -203,18 +215,18 @@ class GetDocsListView(cv.BaseView):
             cv.tracefail()
             return cv.to_fail(e)
 
-class GetNoticeListView(cv.BaseView):
+class GetNoticeListView(cv.AuthView):
     def get(self, request):
         """#我的消息(小程序)
         """
         try:
-            rst = ctl.get_docs_list(request)
+            rst = ctl.get_notice_list(request)
             data = [{
                     "id":"1", 
                     "title":u"标题", 
                     "content":u"消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容" 
                 }]
-            return cv.to_suc(data)
+            return cv.to_suc(rst)
         except Exception as e:
             cv.tracefail()
             return cv.to_fail(e)
@@ -232,7 +244,7 @@ class GetSubjectView(cv.BaseView):
             return cv.to_fail(e)
 
 
-class SignUpView(cv.BaseView):
+class SignUpView(cv.AuthView):
     def post(self, request):
         """#新增报名(小程序)
         @name:"肖小肖",姓名
@@ -305,7 +317,7 @@ class SignUpView(cv.BaseView):
 
 class SignUpPayView(cv.BaseView):
     def post(self,request):
-        """#支付接口
+        """#支付接口(小程序)
         """
         try:
             rst = ctl.do_signup_pay(request)
@@ -314,11 +326,50 @@ class SignUpPayView(cv.BaseView):
             cv.tracefail()
             return cv.to_fail(e)
 
+class WxPayNotifyView(cv.BaseView):
+    def post(self,request):
+        """#支付接口(小程序)
+        """
+        try:
+            rst = ctl.do_wxpay_notify(request)
+            if rst:
+                return cv.to_suc(rst)
+            else:
+                return cv.to_fail(u"回调失败")
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class GenClassHourView(cv.AuthView):
+    def post(self,request):
+        """#生成学时证明(小程序)
+        """
+        try:
+            rst = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4153527623,3062496634&fm=26&gp=0.jpg"
+            rst = ctl.gen_classhour(request)
+            return cv.to_suc({"url":rst})
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+class ClassHourCardView(cv.BaseView):
+    def get(self,request):
+        """#我的学时证明
+        """
+        try:
+            rst = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4153527623,3062496634&fm=26&gp=0.jpg"
+            rst = ctl.get_classhour_card(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
 
 class OpenidView(cv.BaseView):
     def get(self,request):
         """
-        #获取openid
+        #获取openid(小程序)
         @code:1212
         """
         code = request.json.get("code")
@@ -326,21 +377,11 @@ class OpenidView(cv.BaseView):
         if open_id:
             return cv.to_suc({"openid":open_id})
         else:
-
-            APPID = 'wxecaa5147d8564e89'                                               
-            SECRET='691bb4a9bb4cb30b0dd1e03a0bb2e6f6'                                  
-            APPID = 'wx2938132b773c7b5a'                                               
-            SECRET='b32b08a8757cc34b1ee5490af897b065'                                  
-
-            get_token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code' %(APPID,SECRET,code)
-            #get_token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code' %(APPID,SECRET,code)
-            get_token_url = 'https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code' .format(APPID,SECRET,code)
+            get_token_url = 'https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code' .format(wzf.WxPayConf_pub.APPID,wzf.WxPayConf_pub.APPSECRET,code)
 
             res = requests.get(get_token_url).json()                                   
-            print res,3333
             if res.has_key('openid'):                                                 
                 open_id = res['openid']                                               
-
                 cache.set(code,open_id,24*3600)
             else:                                                                      
                 open_id = ''                                                           

+ 0 - 4
src/weixin/views_permission.py

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

+ 0 - 0
src/weixin/wzhifuSDK.py


Некоторые файлы не были показаны из-за большого количества измененных файлов