Gogs 4 lat temu
rodzic
commit
d9f9e30378
100 zmienionych plików z 6297 dodań i 2493 usunięć
  1. 2 2
      src/account/control_user.py
  2. 1 0
      src/account/urls_backstage.py
  3. 13 0
      src/account/views.py
  4. 7 12
      src/common/core_views.py
  5. 10 0
      src/common/models.py
  6. 27 0
      src/manage/3864628_test.scxjc.club.key
  7. 61 0
      src/manage/3864628_test.scxjc.club.pem
  8. 368 984
      src/manage/controls.py
  9. BIN
      src/manage/dump.rdb
  10. 19 28
      src/manage/urls_backstage.py
  11. 203 756
      src/manage/views.py
  12. 30 0
      src/nohup.out
  13. 1 1
      src/settings/base.py
  14. 1 1
      src/settings/settings_dev.py
  15. 0 0
      src/tools/__init__.py
  16. 107 0
      src/tools/autocomplete_record.py
  17. 1 0
      src/urls.py
  18. 8 10
      src/utils/upload_to_oss.py
  19. 32 2
      src/weixin/control_auth.py
  20. 483 454
      src/weixin/controls.py
  21. 13 17
      src/weixin/urls_backstage.py
  22. 157 223
      src/weixin/views.py
  23. 2 2
      src/weixin/wzhifuSDK.py
  24. 139 0
      src/wzbapi/templates/canvas.html
  25. BIN
      src/wzbapi/templates/media/1517533995690XZB2018RJYYB01021_1.jpg
  26. BIN
      src/wzbapi/templates/media/1517534005179XZB2018RJYYB01021_2.jpg
  27. BIN
      src/wzbapi/templates/media/XZB2018RJYWB01001_1.jpg
  28. 55 0
      src/wzbapi/templates/static/handle.js
  29. 370 0
      src/wzbapi/templates/static/iconfont/demo.css
  30. 202 0
      src/wzbapi/templates/static/iconfont/demo_fontclass.html
  31. 279 0
      src/wzbapi/templates/static/iconfont/demo_symbol.html
  32. 240 0
      src/wzbapi/templates/static/iconfont/demo_unicode.html
  33. 71 0
      src/wzbapi/templates/static/iconfont/iconfont.css
  34. BIN
      src/wzbapi/templates/static/iconfont/iconfont.eot
  35. 1 0
      src/wzbapi/templates/static/iconfont/iconfont.js
  36. 114 0
      src/wzbapi/templates/static/iconfont/iconfont.svg
  37. BIN
      src/wzbapi/templates/static/iconfont/iconfont.ttf
  38. BIN
      src/wzbapi/templates/static/iconfont/iconfont.woff
  39. 173 0
      src/wzbapi/templates/static/index.css
  40. 718 0
      src/wzbapi/templates/static/index.js
  41. 2369 0
      src/wzbapi/templates/static/jquery.pureCanvas.js
  42. 2 0
      src/wzbapi/templates/static/layer/layer.js
  43. 2 0
      src/wzbapi/templates/static/layer/mobile/layer.js
  44. 1 0
      src/wzbapi/templates/static/layer/mobile/need/layer.css
  45. BIN
      src/wzbapi/templates/static/layer/theme/default/icon-ext.png
  46. BIN
      src/wzbapi/templates/static/layer/theme/default/icon.png
  47. 1 0
      src/wzbapi/templates/static/layer/theme/default/layer.css
  48. BIN
      src/wzbapi/templates/static/layer/theme/default/loading-0.gif
  49. BIN
      src/wzbapi/templates/static/layer/theme/default/loading-1.gif
  50. BIN
      src/wzbapi/templates/static/layer/theme/default/loading-2.gif
  51. 14 1
      src/wzbapi/views.py
  52. BIN
      static/upload/1627651115avatar.jpg
  53. BIN
      static/upload/1627651211696.jpg
  54. BIN
      static/upload/1627709312570.png
  55. BIN
      static/upload/1627709513870.png
  56. BIN
      static/upload/1627709639287.png
  57. BIN
      static/upload/1627709699418.png
  58. BIN
      static/upload/1627709710436.png
  59. BIN
      static/upload/1627709906546.png
  60. BIN
      static/upload/1627710028763.png
  61. BIN
      static/upload/1627710033814.png
  62. BIN
      static/upload/1627710066268.png
  63. BIN
      static/upload/1627711038264.png
  64. BIN
      static/upload/1627721412065.jpg
  65. BIN
      static/upload/1627721951930.jpg
  66. BIN
      static/upload/1627722019678.jpg
  67. BIN
      static/upload/1627735531wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.NK79UQIogbBj972864c4400d0d2cd6758af218cfa843.png
  68. BIN
      static/upload/1627735745wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.pMLTM9YqBb9M972864c4400d0d2cd6758af218cfa843.png
  69. BIN
      static/upload/1627735791wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.tgep9xOorenY972864c4400d0d2cd6758af218cfa843.png
  70. BIN
      static/upload/1627735838wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.H4S8cstZ2mKL972864c4400d0d2cd6758af218cfa843.png
  71. BIN
      static/upload/1627735895wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.wbe7bQn8ca4x4937eb3d39d8d2dea41120630a599ec4.png
  72. BIN
      static/upload/1627735965wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.8s834l54thAa972864c4400d0d2cd6758af218cfa843.png
  73. BIN
      static/upload/1627735996wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.pLDXb15gLr3r402382246a2065cee3c3007b24c5c58b.png
  74. BIN
      static/upload/1627736021wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.pYTgp6IyEMCe401b2930b2e029af60026d7086792265.png
  75. BIN
      static/upload/1627736104wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.162lsN5XrDQW972864c4400d0d2cd6758af218cfa843.png
  76. BIN
      static/upload/1627736115wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.H3oH0etdLBroe64d82b4c534154fd7dd596bf3b48923.png
  77. BIN
      static/upload/1627736248wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.Lqc3At7s75FJ972864c4400d0d2cd6758af218cfa843.png
  78. BIN
      static/upload/1627736254wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.6lUqK0btk8QCe64d82b4c534154fd7dd596bf3b48923.png
  79. BIN
      static/upload/1627736316wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.OdsMMx21C6Dw972864c4400d0d2cd6758af218cfa843.png
  80. BIN
      static/upload/1627736323wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.to9s9oFwBODHe64d82b4c534154fd7dd596bf3b48923.png
  81. BIN
      static/upload/1627736618wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.DMQkGT1NplCK972864c4400d0d2cd6758af218cfa843.png
  82. BIN
      static/upload/1627736701wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.RJ7uEnPuLTmBe64d82b4c534154fd7dd596bf3b48923.png
  83. BIN
      static/upload/1627736971wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.JLyn4C4BtJYc972864c4400d0d2cd6758af218cfa843.png
  84. BIN
      static/upload/1627737199tmp_d9b8dff98c757f955c00483b4e61ec43.jpg
  85. BIN
      static/upload/1627775046644.jpg
  86. BIN
      static/upload/1627776851436.jpg
  87. BIN
      static/upload/1627776945261.jpg
  88. BIN
      static/upload/1627777070703.jpg
  89. BIN
      static/upload/1627777192640.jpg
  90. BIN
      static/upload/1627777303573.jpg
  91. BIN
      static/upload/1627777473334.jpg
  92. BIN
      static/upload/1627777516142.jpg
  93. BIN
      static/upload/1627777705009.jpg
  94. BIN
      static/upload/1627778327562.jpg
  95. BIN
      static/upload/1627778849040.jpg
  96. BIN
      static/upload/1627778946208.jpg
  97. BIN
      static/upload/1627779063259.jpg
  98. BIN
      static/upload/1627779182578.jpg
  99. BIN
      static/upload/1627779337782.jpg
  100. 0 0
      static/upload/1627780708202.jpg

+ 2 - 2
src/account/control_user.py

@@ -102,7 +102,7 @@ def reset_password(request):
     @attention: 重置密码
     @attention: 重置密码
     """
     """
     qdata = request.json
     qdata = request.json
-    need_params = ["password","repassword","phone","phcode"]
+    need_params = ["password","repassword"]
     mse = ccf.check_params(*need_params,**qdata)
     mse = ccf.check_params(*need_params,**qdata)
     if mse:
     if mse:
         raise ce.TipException(mse)
         raise ce.TipException(mse)
@@ -115,7 +115,7 @@ def reset_password(request):
     if password != repassword:
     if password != repassword:
         raise ce.TipException(u"两次输入的密码不一致!")
         raise ce.TipException(u"两次输入的密码不一致!")
     pwd = ph.make_password(password)
     pwd = ph.make_password(password)
-    cm.UserInfo.objects.filter(phone=phone).update(password=pwd)
+    cm.SysUserInfo.objects.filter(phone=phone).update(password=pwd)
 
 
 
 
 def reset_user_password(request):
 def reset_user_password(request):

+ 1 - 0
src/account/urls_backstage.py

@@ -12,5 +12,6 @@ urlpatterns = [
     url(r'^info$', views.InfoView.as_view()),
     url(r'^info$', views.InfoView.as_view()),
     url(r'^imgcode$', views.CaptchaView.as_view()),
     url(r'^imgcode$', views.CaptchaView.as_view()),
     url(r'^phcode$', views.GetPhoneCodeView.as_view()),
     url(r'^phcode$', views.GetPhoneCodeView.as_view()),
+    url(r'^pwd/reset$', views.ResetPwdView.as_view()),
 ]
 ]
 
 

+ 13 - 0
src/account/views.py

@@ -112,3 +112,16 @@ class InfoView(cv.AdminView):
             return cv.to_suc(users)
             return cv.to_suc(users)
         except Exception as e:
         except Exception as e:
             return cv.to_fail(e)
             return cv.to_fail(e)
+
+class ResetPwdView(cv.AdminView):
+    def put(self, request):
+        """
+        #重置密码(平台管理后台)
+        @password:"",新密码
+        @repassword:"",确认密码
+        """
+        try:
+            cr.reset_password(request)
+            return cv.to_suc()
+        except Exception as e:
+            return cv.to_fail(e)

+ 7 - 12
src/common/core_views.py

@@ -110,21 +110,15 @@ def api_wapper(handler, request, is_vauth, *args, **kwargs):
     if is_vauth:
     if is_vauth:
         if token:
         if token:
             dec_name = aescbc.decrypt(token)
             dec_name = aescbc.decrypt(token)
-            name = dec_name.split("_")[0]
-            utype = dec_name.split("_")[1]
-            if utype == 1:
-                user = cm.Goverment.objects.filter(id=name).first()
-            elif utype == 2:
-                user = cm.EnterPrise.objects.filter(id=name).first()
-            else:
-                user = cm.StaffUser.objects.filter(id=name).first()
+            id = dec_name.split("_")[0]
+            user = cm.UserInfo.objects.filter(id=id).first()
             if not user and False:
             if not user and False:
                 return JsonResponse({"code":403,"data":{}})
                 return JsonResponse({"code":403,"data":{}})
-                #return HttpResponse(status=403)
-
+            #选手
+            player = cm.Player.objects.filter(user_id=id).order_by("-id").first()
             setattr(request, "ip", get_ip(request))
             setattr(request, "ip", get_ip(request))
             setattr(request, "user", user)
             setattr(request, "user", user)
-            setattr(request, "utype", utype)
+            setattr(request, "player", player)
             if request.method == "OPTIONS":
             if request.method == "OPTIONS":
                 return JsonResponse({})
                 return JsonResponse({})
         else:
         else:
@@ -144,8 +138,9 @@ def api_wapper(handler, request, is_vauth, *args, **kwargs):
             info = json.loads(body) if body else {}
             info = json.loads(body) if body else {}
             if not info:
             if not info:
                 info = request.GET.dict()
                 info = request.GET.dict()
-        except:
+        except Exception as e:
             info = {}
             info = {}
+
     setattr(request, "json", info)
     setattr(request, "json", info)
 
 
     try:
     try:

+ 10 - 0
src/common/models.py

@@ -61,9 +61,11 @@ class PlayerRecord(models.Model):
     """参数选手数据
     """参数选手数据
     """
     """
     user_id = models.IntegerField(u"用户id", blank=True,null=True)
     user_id = models.IntegerField(u"用户id", blank=True,null=True)
+    player_id = models.IntegerField(u"用户id", blank=True,null=True)
     username = models.CharField(u"用户名", max_length=255, blank=True,null=True)
     username = models.CharField(u"用户名", max_length=255, blank=True,null=True)
     usercode = models.CharField(u"用户代码", max_length=255, blank=True,null=True)
     usercode = models.CharField(u"用户代码", max_length=255, blank=True,null=True)
     match_id = models.IntegerField(u"比赛id", blank=True,null=True)
     match_id = models.IntegerField(u"比赛id", blank=True,null=True)
+    stock_date = models.CharField(u"持股日期", max_length=255,blank=True,null=True)
     match_name = models.CharField(u"比赛名称", max_length=255,blank=True,null=True)
     match_name = models.CharField(u"比赛名称", max_length=255,blank=True,null=True)
     match_group = models.CharField(u"比赛分组", max_length=255,blank=True,null=True)
     match_group = models.CharField(u"比赛分组", max_length=255,blank=True,null=True)
     init_fund = models.FloatField(u"初始资金",blank=True,null=True)
     init_fund = models.FloatField(u"初始资金",blank=True,null=True)
@@ -73,6 +75,13 @@ class PlayerRecord(models.Model):
     today_stock = models.TextField(u"今日持股",blank=True,null=True)
     today_stock = models.TextField(u"今日持股",blank=True,null=True)
     yesterday_stock_img = models.TextField(u"昨日持股截图",blank=True,null=True)
     yesterday_stock_img = models.TextField(u"昨日持股截图",blank=True,null=True)
     today_stock_img = models.TextField(u"今日持股截图",blank=True,null=True)
     today_stock_img = models.TextField(u"今日持股截图",blank=True,null=True)
+    today_income = models.FloatField(u"今日收益",blank=True,null=True)
+    total_income = models.FloatField(u"总收益",blank=True,null=True)
+    rank = models.IntegerField(u"排名", blank=True,null=True)
+    is_markt = models.SmallIntegerField(u"是否开超市",default=0)
+    yesterday_is_markt = models.SmallIntegerField(u"昨日是否开超市",default=0)
+    auto_complete = models.SmallIntegerField(u"请假次数",default=0)
+    yesterday_auto_complete = models.SmallIntegerField(u"请假次数",default=0)
 
 
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
 
 
@@ -91,6 +100,7 @@ class Match(models.Model):
     name = models.CharField(u"名称", max_length=255, blank=True,null=True)
     name = models.CharField(u"名称", max_length=255, blank=True,null=True)
     start_time = models.CharField(u"开始时间", max_length=255, blank=True,null=True)
     start_time = models.CharField(u"开始时间", max_length=255, blank=True,null=True)
     end_time = models.CharField(u"结束时间", max_length=255, blank=True,null=True)
     end_time = models.CharField(u"结束时间", max_length=255, blank=True,null=True)
+    groups = models.TextField(u"结束时间", max_length=255, blank=True,null=True)
 
 
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
 
 

+ 27 - 0
src/manage/3864628_test.scxjc.club.key

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAhX3sIV+0aqS16WwubLOLZj0Gr12vqtZ7uxgbq/BFYrX6kPXA
+AMaIdSBCudGgQRYDJzDVPA2N1wNJ1bpWf9p24xuHkhGi+3jbyZCTR507u5oSr7uD
+hvIbyPY/u+YVYwQW/x3YIFaN0bWFpPvza3IqojNeykgEOQ/XOjuxNSTetsH8460E
+/6B2YXEMC6ML43OmIN+SMD4zhUPHoiVOPjexxCS3FjOZn+GXqDGfTX2PJjaqhmBy
+NM++hlARdbEp2cgUPEHxID7lOO93FvcxzaAka9M2YeTvpqiZK1orUdyVllI4RWDG
+eSnq1WWdpMXXK+ldCs4ToeV9vATRTEEyPrfsWQIDAQABAoIBAByJ1OE2p2i0IVLP
+hqZFBRx8l/EGP5+vfmC7cPEDayYE/xYd/6f6yaH2nWVB4DeB5/cpLLELucLZiF+p
+mEP5lbiMQmGzJQuLZTt0jdP91I8RC4UnuqDvIgsGwA3gzLowHeV5ASM6tdN7MeDZ
+X0sda2llP5LRrhtv3ESuDb6tjPJ3e9gxlUspkFNx8L5yFQKNx/eMUGtVhqK3czfW
+xPW0UNCsaRjLj7k3d+p8AtB5KcGpVz89z06sqCAOI7xJ5BAtWjQy8AbRHjlS7V+g
+XCmlXJ5V9zttykKECKLi6BwxbzBnpS7JEdTR6oPZ/2UHRZ20TY2ojk5mbpdG42Bl
+e/OL2q0CgYEAun7ChJ+rsf1L+AD+YviGJu/EF9ZqirMa2z6GY7v/1xuYD95skaMk
+X0izIdpiIbuKXsBfwgtvOfjMw7EGiiGBbqCC63SVBggZ0HV0CuLPJ4ofvsrZSbHS
+xFxL1auZM6PQDZZYIuORx8ilBXUZPl58UwStZtIpiw0iuqJLp8vOYJUCgYEAtz4x
+8H1uUwY8uj9Z3r0wOYLlOIPqp6krmyAHixutUV/Rxkx/zaLZHAjVNOEd5iZprdmL
+EDKo4cMMdZ2SaXz8Y21qbeRk/c0saQ8VVXuHFB6fMrLU7iWUKiXuuFVAFQfwijDr
+AAzbseXDz3P5rGBdHYCT8U7o7a/D4MjeRSFPV7UCgYA8k0XNXCuhsZuGX5RBQ2YX
+qZNxBrUufgSAKCvwozTzgsP+i4mKOIps5KlCmrN7L3Y/Vo8D8UDcfKLOAWcVYNKw
+wzQjFIf/IIx5+FyL2KXeuu+awjqXxEmofC4ppgYqDtBaSXYxRueoE9T+E83yQzBw
+qrlEB4l03/xi0KpwQzOyjQKBgQCzyX0cFSUippL8td2KUhs3wjr+eUfJWo0jNYjR
+LsWdeqMKqdIXQ7k67Vuq91jrkDLN1QzBRsM2RrY5y/F0OKI1N4xd5+JCtoTlS1xG
+M93zmpveFWIfipVVyUPwbgxi1hhmrdpUgUkowWOebo7AVwflQ1tkPmUBmBtauBqE
+v0rmpQKBgQCZgnjdkpIfmKShBwJN0xCkKdRt4KdWIWjUdWqKYq0U4X8H1YlPCdvm
+gGv3DIRGXKhFKk4T09hjUr/xWVLkxmee9eFFBeOUAN+RoPUf6FZYSLPJ2b4PCZez
++VrdJqM4vJMxsxqRmBKN8n1Dm7EFvwAXar567uOB/ICO5F8C+BU2DA==
+-----END RSA PRIVATE KEY-----

+ 61 - 0
src/manage/3864628_test.scxjc.club.pem

@@ -0,0 +1,61 @@
+-----BEGIN CERTIFICATE-----
+MIIF8jCCBNqgAwIBAgIQDBQsW99Z4E4yG7eHbRjFGDANBgkqhkiG9w0BAQsFADBu
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
+RFYgVExTIENBIC0gRzEwHhcNMjEwNzMxMDAwMDAwWhcNMjIwNzMxMjM1OTU5WjAa
+MRgwFgYDVQQDEw90ZXN0LnNjeGpjLmNsdWIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQCFfewhX7RqpLXpbC5ss4tmPQavXa+q1nu7GBur8EVitfqQ9cAA
+xoh1IEK50aBBFgMnMNU8DY3XA0nVulZ/2nbjG4eSEaL7eNvJkJNHnTu7mhKvu4OG
+8hvI9j+75hVjBBb/HdggVo3RtYWk+/NrciqiM17KSAQ5D9c6O7E1JN62wfzjrQT/
+oHZhcQwLowvjc6Yg35IwPjOFQ8eiJU4+N7HEJLcWM5mf4ZeoMZ9NfY8mNqqGYHI0
+z76GUBF1sSnZyBQ8QfEgPuU473cW9zHNoCRr0zZh5O+mqJkrWitR3JWWUjhFYMZ5
+KerVZZ2kxdcr6V0KzhOh5X28BNFMQTI+t+xZAgMBAAGjggLeMIIC2jAfBgNVHSME
+GDAWgBRVdE+yck/1YLpQ0dfmUVyaAYca1zAdBgNVHQ4EFgQUPQ3wdeQsd+mGnKLE
+lQ6A3FZFxCgwGgYDVR0RBBMwEYIPdGVzdC5zY3hqYy5jbHViMA4GA1UdDwEB/wQE
+AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwPgYDVR0gBDcwNTAz
+BgZngQwBAgEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20v
+Q1BTMIGABggrBgEFBQcBAQR0MHIwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
+Z2ljZXJ0LmNvbTBKBggrBgEFBQcwAoY+aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu
+Y29tL0VuY3J5cHRpb25FdmVyeXdoZXJlRFZUTFNDQS1HMS5jcnQwCQYDVR0TBAIw
+ADCCAX0GCisGAQQB1nkCBAIEggFtBIIBaQFnAHYAKXm+8J45OSHwVnOfY6V35b5X
+fZxgCvj5TV0mXCVdx4QAAAF6+3z4DgAABAMARzBFAiEAlA7Bhpdj+9SWU7lRb5bz
+ACIC4aSlQU30TQWEAzMEH1kCIH5u+k+Gxys/BfMG03i6t18O/BE14HJShf1VWUef
+t6SFAHUAUaOw9f0BeZxWbbg3eI8MpHrMGyfL956IQpoN/tSLBeUAAAF6+3z4iwAA
+BAMARjBEAiAwp5bP2Tu3+AuMtOoLrI7vuptHtMO6Uv5HTSnuzVzWDAIgVlEHOmxo
+UmISW5y8M5HpZSwCevWMiwjT55BfGg2fHNEAdgBByMqx3yJGShDGoToJQodeTjGL
+GwPr60vHaPCQYpYG9gAAAXr7fPguAAAEAwBHMEUCIQDhAzWgkPuJB4MKoqz1yQJL
+vaZHqzIq/6mS1x5wZeezUwIgMNuv9a7RQl7CFh0/5TYgBes9KefGs/A43hYE78sW
+CqEwDQYJKoZIhvcNAQELBQADggEBAFl93yKr6fjfr1qXBy0ol6iWjXcyiFlAh6+B
+VlDJMAUbpwBUoegoj4ECZzSoe2uGoaiqrZTqa8Vy1jCviCvpxbJ5PiD4VHiYQRl7
+56mKcpCdR26/Rml+5hC7vrkRNU/x7xT92P1amgKONc4ZdYamO7KfPdiO/2GYYBK7
+xuzYG96hYhDHwHxn/dNZJbJmoZKshDS3SPKxORLiXpMoMJyHCrynEK/yR4io+znQ
+OSMWJ2DE58HWVWhKLEP5Cx/ppd3Mwg4ivKjbXNT37b9f7c52zMq6xdumTybJTPMw
+15PDSY6HZwefEQLPvbxLWQaPGZpyDQFEslOwXHAxJf0FnlJtm/0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEqjCCA5KgAwIBAgIQAnmsRYvBskWr+YBTzSybsTANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0xNzExMjcxMjQ2MTBaFw0yNzExMjcxMjQ2MTBaMG4xCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH
+MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALPeP6wkab41dyQh6mKc
+oHqt3jRIxW5MDvf9QyiOR7VfFwK656es0UFiIb74N9pRntzF1UgYzDGu3ppZVMdo
+lbxhm6dWS9OK/lFehKNT0OYI9aqk6F+U7cA6jxSC+iDBPXwdF4rs3KRyp3aQn6pj
+pp1yr7IB6Y4zv72Ee/PlZ/6rK6InC6WpK0nPVOYR7n9iDuPe1E4IxUMBH/T33+3h
+yuH3dvfgiWUOUkjdpMbyxX+XNle5uEIiyBsi4IvbcTCh8ruifCIi5mDXkZrnMT8n
+wfYCV6v6kDdXkbgGRLKsR4pucbJtbKqIkUGxuZI2t7pfewKRc5nWecvDBZf3+p1M
+pA8CAwEAAaOCAU8wggFLMB0GA1UdDgQWBBRVdE+yck/1YLpQ0dfmUVyaAYca1zAf
+BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8EBAMCAYYw
+HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C
+AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
+Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu
+Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG
+/WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT
+MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAK3Gp6/aGq7aBZsxf/oQ+TD/B
+SwW3AU4ETK+GQf2kFzYZkby5SFrHdPomunx2HBzViUchGoofGgg7gHW0W3MlQAXW
+M0r5LUvStcr82QDWYNPaUy4taCQmyaJ+VB+6wxHstSigOlSNF2a6vg4rgexixeiV
+4YSB03Yqp2t3TeZHM9ESfkus74nQyW7pRGezj+TC44xCagCQQOzzNmzEAP2SnCrJ
+sNE2DpRVMnL8J6xBRdjmOsC3N6cQuKuRXbzByVBjCqAA8t1L0I+9wXJerLPyErjy
+rMKWaBFLmfK/AHNF4ZihwPGOc7w6UHczBZXH5RFzJNnww+WnKuTPI0HfnVH8lg==
+-----END CERTIFICATE-----

Plik diff jest za duży
+ 368 - 984
src/manage/controls.py


BIN
src/manage/dump.rdb


+ 19 - 28
src/manage/urls_backstage.py

@@ -5,35 +5,26 @@ from django.conf.urls import url
 from . import views,views_backstage
 from . import views,views_backstage
 
 
 urlpatterns = [
 urlpatterns = [
+    url(r'^uploadfile$', views.UploadFileView.as_view()),
+
     url(r'^user$', views.UserInfoView.as_view()),
     url(r'^user$', views.UserInfoView.as_view()),
     url(r'^user/list$', views.UserInfoListView.as_view()),
     url(r'^user/list$', views.UserInfoListView.as_view()),
-    url(r'^goverment$', views.GovermentView.as_view()),
-    url(r'^goverment/list$', views.GovermentListView.as_view()),
-    url(r'^goverment/subent$', views.GovermentSubEntView.as_view()),
-    url(r'^enterprise$', views.EnterPriseView.as_view()),
-    url(r'^enterprise/list$', views.EnterPriseListView.as_view()),
-    url(r'^enterprise/all$', views.EnterPriseAllView.as_view()),
-    url(r'^uploadfile$', views.UploadFileView.as_view()),
-    url(r'^getdefault$', views.GetDefaultView.as_view()),
-    url(r'^department$', views.DepartmentView.as_view()),
-    url(r'^department/list$', views.DepartmentListView.as_view()),
-    url(r'^riskpoint$', views.RiskPointView.as_view()),
-    url(r'^riskpoint/list$', views.RiskPointListView.as_view()),
-    url(r'^monittask$', views.MonitTaskView.as_view()),
-    url(r'^monittask/list$', views.MonitTaskListView.as_view()),
-    url(r'^monittask/upload$', views.MonitTaskUploadView.as_view()),
-    url(r'^staffuser$', views.StaffUserView.as_view()),
-    url(r'^staffuser/list$', views.StaffUserListView.as_view()),
-    url(r'^messages$', views.MessagesView.as_view()),
-    url(r'^messages/list$', views.MessagesListView.as_view()),
-    url(r'^documention$', views.DocumentionView.as_view()),
-    url(r'^documention/list$', views.DocumentionListView.as_view()),
-    url(r'^bill$', views.BillView.as_view()),
-    url(r'^bill/list$', views.BillListView.as_view()),
-    url(r'^friendlink$', views.FriendLinkView.as_view()),
-    url(r'^friendlink/list$', views.FriendLinkListView.as_view()),
-    url(r'^dashboard/index$', views.DashboardIndexView.as_view()),
-    url(r'^monitjob/list$', views.MonitJobListView.as_view()),
-    url(r'^monitjob/download$', views.MonitJobDownloadView.as_view()),
+    url(r'^player$', views.PlayerView.as_view()),
+    url(r'^player/list$', views.PlayerListView.as_view()),
+    url(r'^match$', views.MatchView.as_view()),
+    url(r'^match/list$', views.MatchListView.as_view()),
+    url(r'^match/group$', views.MatchGroupView.as_view()),
+    url(r'^match/group/list$', views.MatchGroupListView.as_view()),
+    url(r'^player/record$', views.PlayerRecordView.as_view()),
+    url(r'^player/record/list$', views.PlayerRecordListView.as_view()),
+    url(r'^player/record/download$', views.PlayerRecordDownloadView.as_view()),
+    url(r'^match/search$', views.MatchSearchView.as_view()),
+    url(r'^match/group/search$', views.MatchGroupSearchView.as_view()),
+    url(r'^player/search$', views.PlayerSearchView.as_view()),
+    url(r'^stock/search$', views.StockSearchView.as_view()),
+    url(r'^user/search$', views.UserInfoSearchView.as_view()),
+    url(r'^player/fast$', views.PlayerFastSaveView.as_view()),
+    url(r'^player/autorecord$', views.PlayerAutoRecordView.as_view()),
+
 ]
 ]
 
 

Plik diff jest za duży
+ 203 - 756
src/manage/views.py


+ 30 - 0
src/nohup.out

@@ -0,0 +1,30 @@
+Traceback (most recent call last):
+  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
+    "__main__", fname, loader, pkg_name)
+  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
+    exec code in run_globals
+  File "/mnt/wzbapi/src/tools/autocomplete_record.py", line 92, in <module>
+    auto_gen_record()
+  File "/mnt/wzbapi/src/tools/autocomplete_record.py", line 25, in auto_gen_record
+    for pla in plaset:
+  File "/mnt/py27dj11env/lib/python2.7/site-packages/django/db/models/query.py", line 250, in __iter__
+    self._fetch_all()
+  File "/mnt/py27dj11env/lib/python2.7/site-packages/django/db/models/query.py", line 1102, in _fetch_all
+    self._result_cache = list(self._iterable_class(self))
+  File "/mnt/py27dj11env/lib/python2.7/site-packages/django/db/models/query.py", line 53, in __iter__
+    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch)
+  File "/mnt/py27dj11env/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 876, in execute_sql
+    cursor.execute(sql, params)
+  File "/mnt/py27dj11env/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
+    return self.cursor.execute(sql, params)
+  File "/mnt/py27dj11env/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
+    six.reraise(dj_exc_type, dj_exc_value, traceback)
+  File "/mnt/py27dj11env/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
+    return self.cursor.execute(sql, params)
+  File "/mnt/py27dj11env/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 101, in execute
+    return self.cursor.execute(query, args)
+  File "/mnt/py27dj11env/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
+    self.errorhandler(self, exc, value)
+  File "/mnt/py27dj11env/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
+    raise errorclass, errorvalue
+django.db.utils.OperationalError: (2006, 'MySQL server has gone away')

+ 1 - 1
src/settings/base.py

@@ -56,7 +56,7 @@ MIDDLEWARE = [
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
-    #'oplog.OpLogMiddleware.OpLogMiddleware'
+    'oplog.OpLogMiddleware.OpLogMiddleware'
 ]
 ]
 
 
 ROOT_URLCONF = 'urls'
 ROOT_URLCONF = 'urls'

+ 1 - 1
src/settings/settings_dev.py

@@ -59,5 +59,5 @@ LOGGING = {
     },
     },
 }
 }
 
 
-HOST = "http://www.baianxi.com"
+HOST = "https://test.scxjc.club"
 PROJECT_NAME = u"顽主杯"
 PROJECT_NAME = u"顽主杯"

+ 0 - 0
src/tools/__init__.py


+ 107 - 0
src/tools/autocomplete_record.py

@@ -0,0 +1,107 @@
+#coding:utf-8
+import os
+import time
+import datetime
+import sys
+import django
+
+sys.path.append('/mnt/wzbapi/src')
+os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
+django.setup()
+
+import common.models as cm
+
+
+def auto_gen_record():
+    """每天15:30以后如果选手没有填报数据则,自动为其生产一天数据
+    今日资产等于昨日资产,今日收益为0,总收益不变.自动生产一次则
+    标识一次请假,请假超过5次则将该选手表示为退赛状态
+    """
+    now_time = datetime.datetime.now().strftime("%H:%S")
+
+    if "16:00"<now_time<"23:59":
+        now_stock_date = datetime.datetime.now().strftime("%Y-%m-%d")
+        plaset = cm.Player.objects.filter(match_status=1)
+        for pla in plaset:
+            player_id = pla.id
+            match_id = pla.match_id
+            match_group = pla.match_group
+            user = cm.UserInfo.objects.filter(id=pla.user_id).first()
+            if not cm.PlayerRecord.objects.filter(
+                    player_id=player_id,
+                    match_id=match_id,
+                    stock_date=now_stock_date
+                    ).exists():
+                #昨日数据
+                yesterday = cm.PlayerRecord.objects.filter(player_id=player_id,
+                    match_id=match_id).filter(stock_date__lt=now_stock_date).order_by("-stock_date").first()
+                if yesterday: 
+                    obj = cm.PlayerRecord.objects.create(
+                        user_id=user.id,
+                        player_id=player_id,
+                        username=user.username,
+                        usercode=user.usercode,
+                        match_id=match_id,
+                        match_group=match_group,
+                        init_fund=yesterday.init_fund,
+                        yesterday_stock=yesterday.today_stock,
+                        yesterday_stock_img=yesterday.today_stock_img,
+                        today_fund=yesterday.today_fund,
+                        yesterday_fund=yesterday.today_fund,
+                        today_stock=yesterday.today_stock,
+                        today_stock_img=yesterday.today_stock_img,
+                        stock_date=now_stock_date,
+                        today_income=0,
+                        total_income=yesterday.total_income,
+                        is_markt=yesterday.is_markt,
+                        yesterday_is_markt=yesterday.is_markt,
+                        auto_complete=1,
+                        yesterday_auto_complete=yesterday.auto_complete
+                    )
+                else:
+                    obj = cm.PlayerRecord.objects.create(
+                        user_id=user.id,
+                        player_id=player_id,
+                        username=user.username,
+                        usercode=user.usercode,
+                        match_id=match_id,
+                        match_group=match_group,
+                        init_fund=pla.fund,
+                        today_fund=pla.fund,
+                        yesterday_fund=pla.fund,
+                        stock_date=now_stock_date,
+                        today_income=0,
+                        total_income=0,
+                        auto_complete=1
+                    )
+                #更新排名与请假标识
+                records_set = cm.PlayerRecord.objects.filter(match_id=match_id).order_by("-total_income")
+                for index,item in enumerate(records_set):
+                    item.rank = index+1
+                    item.save()
+                #更新请假标识
+                records_set = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id,auto_complete__gt=0).order_by("-stock_date")
+                for index,item in enumerate(records_set):
+                    item.auto_complete = index+1
+                    item.save()
+                if records_set.count()>5:
+                    pla.match_status = -1
+                    pla.save()
+                print u"complete add{} data:{}".format(now_stock_date,pla.usercode)
+
+if __name__ == "__main__":
+    auto_gen_record()
+    #while True:
+    #    try:
+    #        auto_gen_record()
+    #        time.sleep(300)
+    #    except KeyboardInterrupt:
+    #        sys.exit(0)
+
+
+
+
+
+
+
+

+ 1 - 0
src/urls.py

@@ -25,6 +25,7 @@ import wzbapi.views as wview
 
 
 
 
 urlpatterns = [
 urlpatterns = [
+    url(r'^api/canvas', wview.CanvasView.as_view()),
     url(r'^api/doc/', wview.DocView.as_view()),
     url(r'^api/doc/', wview.DocView.as_view()),
     url(r'^api/account/', include('account.urls_backstage')),
     url(r'^api/account/', include('account.urls_backstage')),
     url(r'^api/wx/', include('weixin.urls_backstage')),
     url(r'^api/wx/', include('weixin.urls_backstage')),

+ 8 - 10
src/utils/upload_to_oss.py

@@ -5,20 +5,18 @@ import requests
 import uuid
 import uuid
 import time
 import time
 
 
-class TedOSS:
+class MyOSS:
     def __init__(self):
     def __init__(self):
         """
         """
         """
         """
-        #self.AccessKeyID = 'LTAIWf1G4szSVK57'
-        #self.AccessKeySecret = 'X8cyxHuOumqw4B0MQPdlvYL2FTZh05'
-        self.AccessKeyID = 'LTAI4G9BTKP2D3zfDpQkk8S8'
-        self.AccessKeySecret = 'aTQIvkP5C16e7fUH6zIlrB7I3j4TbR'
-        self.bucket_name = 'tederenoss'
-        self.root_name = 'zky'
+        self.AccessKeyID = 'LTAIbkpKrzQViemJ'
+        self.AccessKeySecret = '9y9mqNFMMDfUEBGvWqHt3wGas2W5ML'
+        self.bucket_name = 'scxjcclub'
+        self.root_name = 'say365'
         self.auth = oss2.Auth(self.AccessKeyID, self.AccessKeySecret)
         self.auth = oss2.Auth(self.AccessKeyID, self.AccessKeySecret)
         self.endpoint = 'http://oss-cn-beijing.aliyuncs.com'
         self.endpoint = 'http://oss-cn-beijing.aliyuncs.com'
         self.bucket = oss2.Bucket(self.auth, self.endpoint, self.bucket_name)
         self.bucket = oss2.Bucket(self.auth, self.endpoint, self.bucket_name)
-        self.domain = 'http://tederenoss.oss-cn-beijing.aliyuncs.com'
+        self.domain = 'http://scxjcclub.oss-cn-beijing.aliyuncs.com'
 
 
 
 
     def upload_from_str(self,content_str=None,filename=None):
     def upload_from_str(self,content_str=None,filename=None):
@@ -89,7 +87,7 @@ class TedOSS:
 if __name__ == '__main__':
 if __name__ == '__main__':
     myoss = MyOSS()
     myoss = MyOSS()
 
 
-    localfile = '/tmp/survey_qrcode_100.png'
-    ossfile = 'test/test.png'
+    localfile = '/tmp/test.txt'
+    ossfile = 'test/test.txt'
     url = myoss.resumable_upload_from_local(localfile,ossfile)
     url = myoss.resumable_upload_from_local(localfile,ossfile)
     print url
     print url

+ 32 - 2
src/weixin/control_auth.py

@@ -1,12 +1,13 @@
 #coding=utf-8
 #coding=utf-8
 '''
 '''
 '''
 '''
-import json
+import json,time,random
 from django.db import transaction
 from django.db import transaction
 import common.models as cm
 import common.models as cm
 import common.error_info as ce
 import common.error_info as ce
 import common.common_functions as ccf
 import common.common_functions as ccf
 import common.common_control as ccc
 import common.common_control as ccc
+from utils.aestool import aescbc
 
 
 def add_wxauth_info(request):
 def add_wxauth_info(request):
     """
     """
@@ -31,8 +32,8 @@ def get_wxauth_info(request):
     """
     """
     #
     #
     uid = request.user.id
     uid = request.user.id
+    print uid
     user = cm.UserInfo.objects.filter(id=uid).values().first()
     user = cm.UserInfo.objects.filter(id=uid).values().first()
-    user = json.loads(user["userinfo"])
     return user
     return user
 
 
 
 
@@ -45,6 +46,35 @@ def update_wxauth_info(request):
     cm.UserInfo.objects.filter(id=uid).update(userinfo=json.dumps(qdata))
     cm.UserInfo.objects.filter(id=uid).update(userinfo=json.dumps(qdata))
 
 
 
 
+def login_user(request):
+    """
+    """
+    info = request.json
+    usercode = info.get('usercode')
+    openid = info.get('openid')
+    avatar = info.get('avatarUrl')
+    nickname = info.get('nickName')
+    if not usercode:
+        raise ce.TipException(u"缺少参数!")
+    user = cm.UserInfo.objects.filter(usercode=usercode).first()
+    if not user:
+        raise ce.TipException(u"用户代号不存在!")
+    if user.is_bind:
+        if not openid == user.openid:
+            raise ce.TipException(u"微信号与用户代码不配!")
+    if not cm.Player.objects.filter(user_id=user.id).first():
+        raise ce.TipException(u"该账号未参加任何比赛,不能登录!")
+
+    user.openid = openid
+    user.avatar = avatar
+    user.nickname = nickname
+    user.is_bind = 1
+    user.save()
+    tstr = "{}_{}{}".format(user.id,time.time(),random.randint(100000,999999))
+    token = aescbc.encrypt(tstr)
+
+    return {"id":user.id,"token":token}
+
 
 
 
 
 
 

+ 483 - 454
src/weixin/controls.py

@@ -1,511 +1,540 @@
-# coding=utf-8
+#coding=utf-8
 '''
 '''
 '''
 '''
-import os
+import os,re,random
 import json,time,datetime
 import json,time,datetime
+import shutil
+import tempfile
+import zipfile
+from docxtpl import DocxTemplate,InlineImage
+from docx.shared import Mm
 from django.db import transaction
 from django.db import transaction
-from django.db.models import Q
+from django.conf import settings
 import common.models as cm
 import common.models as cm
 import common.error_info as ce
 import common.error_info as ce
 import common.common_functions as ccf
 import common.common_functions as ccf
 import common.common_control as ccc
 import common.common_control as ccc
+import account.password_handle as ph
+from utils.exceltool import ExcelTool
+from utils.jgpush import send_notification_by_registration_ids
 import wzhifuSDK as wxpay
 import wzhifuSDK as wxpay
-from django.conf import settings
+from utils.exceltool import ExcelTool
+from utils.qrcodetool import gen_general_qrcode
+from django.db.models import Q,Sum,Count
+from PIL import Image
 from PIL import Image,ImageDraw,ImageFont
 from PIL import Image,ImageDraw,ImageFont
 
 
+import xlrd
+import xlwt
+from xlutils.copy import copy
+from xltpl.writer import BookWriter
+
 def get_index_data(request):
 def get_index_data(request):
+    """首页数据
     """
     """
-    """
-    qset = cm.Category.objects.all()
-    qdata = list(qset.values())
-    for i,qd in enumerate(qdata):
-        if i<6:
-            qd["type"] = "nav"
+    player = request.player
+    if not player:
+        raise ce.TipException(u"该账号未参加任何赛事!")
+    player_id = player.id
+    match_id = player.match_id
+    match_name = cm.Match.objects.filter(id=match_id).first().name
+    records_set = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id).order_by("-stock_date")
+    if records_set:
+        today_record = records_set.first()
+        cur_rank = records_set.first().rank
+        group_income = get_group_income(today_record.match_id,today_record.match_group)
+        if today_record.total_income in group_income:
+            cur_rank = group_income.index(today_record.total_income)+1
         else:
         else:
-            qd["type"] = "article"
-            qd["list"] = list(cm.Article.objects.filter(category__id=qd["id"]).values())
-        if qd["name"]==u"头条通知": 
-            qd["type"] = "notice"
-            qd["list"] = list(cm.Article.objects.filter(category__id=qd["id"]).values())
-        if "{id}" in qd["path"]:
-            artcs = list(cm.Article.objects.filter(category__id=qd["id"]).order_by("order").values())
-            aid = artcs[0]["id"] if artcs else 0
-            qd["path"] = qd["path"].replace("{id}",str(aid))
-    return qdata
-
-
-def get_article_info(request):
-    qdata = request.json
-    need_params = ["id"]
-    mse = ccf.check_params(*need_params,**qdata)
-    if mse:
-        raise ce.TipException(mse)
-    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):
-    """考场和联系我们专用
+            cur_rank = 1
+        records = list(records_set.values())[:10]
+    else:
+        cur_rank = 0 
+        records = []
+    for item in records:
+        today_stock = json.loads(item["today_stock"]) if item["today_stock"] else []
+        today_stock = filter(lambda x:x["name"],today_stock)
+        item["today_stock"] = today_stock 
+        item["today_stock_img"] = json.loads(item["today_stock_img"]) if item["today_stock_img"] else []
+        yesterday_stock = json.loads(item["yesterday_stock"]) if item["yesterday_stock"] else []
+        yesterday_stock = filter(lambda x:x["name"],yesterday_stock)
+        item["yesterday_stock"] = yesterday_stock
+        item["yesterday_stock_img"] = json.loads(item["yesterday_stock_img"]) if item["yesterday_stock_img"] else []
+        item["today_income"] = "{}%".format(item["today_income"]*100)
+        item["total_income"] = "{}%".format(item["total_income"]*100)
+    ret = {"match_name":match_name,"cur_rank":cur_rank,"records":records}
+
+    return ret
+
+
+def get_player_match_list(request):
+    """选手参赛列表数据
     """
     """
-    qdata = request.json
-    need_params = ["id"]
-    mse = ccf.check_params(*need_params,**qdata)
-    if mse:
-        raise ce.TipException(mse)
-    id = qdata.get("id")
-    data = {"id":"1","title":"sfsfd","content":"","ctime":"2020-01-01 00:00:01"}
-    data = {"id":1,"title":u"联系我们","phone":"0827-8589102","address":u"巴中市江北车站三楼(体检门诊第一个办公室)","imgs":["https://www.scxjc.club/images/jgjj.png","https://www.scxjc.club/images/jgjj.png"],"content":u"详情...."}
-    return data
+    uid = request.user.id
+    match_ids = list(cm.Player.objects.filter(user_id=uid).values_list("match_id",flat=True))
+    matchs = list(cm.Match.objects.filter(id__in=match_ids).values())
 
 
-def get_signup_list(request):
+    return matchs
+
+def get_group_income(match_id,match_group):
     """
     """
     """
     """
-    uid = request.user.id
-    qset = cm.SignupOrders.objects.filter(user_id=uid).order_by("-id")
-    qdata = list(qset.values())
-    for qd in qdata:
-        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):
-    qdata = request.json
-    need_params = ["id"]
-    mse = ccf.check_params(*need_params,**qdata)
-    if mse:
-        raise ce.TipException(mse)
-    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 []
+    data = []
+    player_ids = list(cm.Player.objects.filter(match_group=match_group).values_list("id",flat=True))
+    for player_id in player_ids:
+        today_record = cm.PlayerRecord.objects.filter(match_id=match_id,match_group=match_group,player_id=player_id).order_by("-stock_date").first()
+        if today_record:
+            data.append(today_record.total_income)
+    data = sorted(data,key=lambda x:x,reverse=True)
     return data
     return data
 
 
-def get_class_list(request):
-    """
+
+def get_player_match_detail(request):
+    """选手参赛详情数据
     """
     """
     qdata = request.json
     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 = []
-    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)
+    player_id = request.player.id
+    match_id = qdata.get("id")
+    record_id = qdata.get("record_id")
+    if record_id:
+        records_set = cm.PlayerRecord.objects.filter(id=record_id)
+        match_id = records_set.first().match_id
+        player_id = records_set.first().player_id
+        records_set = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id).order_by("-stock_date")
+    else:
+        records_set = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id).order_by("-stock_date")
+
+    match = cm.Match.objects.filter(id=match_id).values().first()
+    groups = list(cm.MatchGroup.objects.filter(match_id=match_id).values_list("name",flat=True))
+    match["groups"] = groups
+    if records_set:
+        today_record = records_set.values().first()
+        records = list(records_set.values())[:10]
     else:
     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)
+        today_record = {}
+        records = []
+
+    for item in records:
+        item["today_stock"] = json.loads(item["today_stock"]) if item["today_stock"] else []
+        item["today_stock_img"] = json.loads(item["today_stock_img"]) if item["today_stock_img"] else []
+        item["yesterday_stock"] = json.loads(item["yesterday_stock"]) if item["yesterday_stock"] else []
+        item["yesterday_stock_img"] = json.loads(item["yesterday_stock_img"]) if item["yesterday_stock_img"] else []
+        item["today_income"] = "{}%".format(item["today_income"]*100)
+        item["total_income"] = "{}%".format(item["total_income"]*100)
+    if today_record:
+        group_income = get_group_income(today_record["match_id"],today_record["match_group"])
+        group_rank = group_income.index(today_record["total_income"])+1
+        today_record["group_rank"] = group_rank
+
+        today_record["today_income"] = "{}%".format(today_record["today_income"]*100)
+        today_record["total_income"] = "{}%".format(today_record["total_income"]*100)
+        today_record["match_group_name"] = cm.MatchGroup.objects.filter(id=today_record["match_group"]).first().name
+    match["groups"] = [today_record["match_group_name"]] if today_record else []
+    records = sorted(records,key=lambda x:x["stock_date"],reverse=True)
+    ret = {"match":match,"today_record":today_record,"records":records}
+
+    return ret
+
+
+def get_rank_list(request):
+    """排名列表
+    """
+    qdata = request.json
+    player_id = request.player.id
+    match_id = request.player.match_id
+    match = cm.Match.objects.filter(id=match_id).values().first()
+    
+    groups = list(cm.MatchGroup.objects.filter(match_id=match_id).values())
+
+    for item in groups:
+        new_players = []
+        players = list(cm.Player.objects.filter(match_id=match_id,match_group=item["id"]).values())
+        for player in players:
+            user_id = player["user_id"]
+            user = cm.UserInfo.objects.filter(id=user_id).first()
+            username = user.username if user else ""
+            records_set = cm.PlayerRecord.objects.filter(player_id=player["id"],match_id=match_id,match_group=item["id"]).order_by("-stock_date")
+            if records_set:
+                today_record = records_set.values().first()
             else:
             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):
+                today_record = {}
+            if today_record:
+                player.update(today_record)
+                player["username"] = username
+                player["total_income"] = "{}%".format(today_record["total_income"]*100)
+                #计算分组排名
+                group_income = get_group_income(today_record["match_id"],today_record["match_group"])
+                if today_record["total_income"] in group_income:
+                    group_rank = group_income.index(today_record["total_income"])+1
+                else:
+                    group_rank = 1
+                player["group_rank"] = group_rank
+                player["fund"] = round(player["fund"],2)
+                player["init_fund"] = round(player["init_fund"],2)
+                player["today_fund"] = round(player["today_fund"],2)
+                new_players.append(player)
+        new_players = sorted(new_players,key=lambda x:x["group_rank"])
+        item["players"] = new_players[:3]
+
+    ret = {"match":match,"groups":groups}
+
+    return ret
+
+
+def get_group_rank_list(request):
+    """排名列表
     """
     """
+    qdata = request.json
+    group_id = qdata.get("id")
+
+    player_id = request.player.id
+    match_id = request.player.match_id
+    match = cm.Match.objects.filter(id=match_id).values().first()
+    
+    group = cm.MatchGroup.objects.filter(id=group_id).values().first()
+
+    players = list(cm.Player.objects.filter(match_id=match_id,match_group=group_id).values())
+    new_players = []
+    for player in players:
+        user_id = player["user_id"]
+        user = cm.UserInfo.objects.filter(id=user_id).first()
+        username = user.username if user else ""
+        records_set = cm.PlayerRecord.objects.filter(player_id=player["id"],match_id=match_id,match_group=group_id).order_by("-stock_date")
+        if records_set:
+            today_record = records_set.values().first()
+        else:
+            today_record = {}
+        if today_record:
+            player.update(today_record)
+            group_income = get_group_income(today_record["match_id"],today_record["match_group"])
+            group_rank = group_income.index(today_record["total_income"])+1
+            player["group_rank"] = group_rank
+            player["username"] = username
+            player["total_income"] = "{}%".format(player["total_income"]*100)
+            player["fund"] = round(player["fund"],2)
+            player["init_fund"] = round(player["init_fund"],2)
+            player["today_fund"] = round(player["today_fund"],2)
+            new_players.append(player)
+    new_players = sorted(new_players,key=lambda x:x["group_rank"])
+    ret = {"group":group,"players":new_players}
+
+    return ret
+
+
+def get_player_match_records(request):
+    """选手参赛每日持股
     """
     """
-    #获取视频信息
-    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
+    qdata = request.json
+    player_id = request.player.id
+    match_id = qdata.get("id")
+    q_player_id = qdata.get("player_id")
+    if q_player_id:
+        player_id = q_player_id
+    page = int(qdata.get("page",0))
+    page_size = int(qdata.get("page_size",20))
+
+    records_set = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id).order_by("-stock_date")
+    data = list(records_set.values())
+    for item in data:
+        today_stock = json.loads(item["today_stock"]) if item["today_stock"] else []
+        today_stock = filter(lambda x:x["name"],today_stock)
+        item["today_stock"] = today_stock 
+        item["today_stock_img"] = json.loads(item["today_stock_img"]) if item["today_stock_img"] else []
+        yesterday_stock = json.loads(item["yesterday_stock"]) if item["yesterday_stock"] else []
+        yesterday_stock = filter(lambda x:x["name"],yesterday_stock)
+        item["yesterday_stock"] = yesterday_stock
+        item["yesterday_stock_img"] = json.loads(item["yesterday_stock_img"]) if item["yesterday_stock_img"] else []
+        item["today_income"] = "{}%".format(item["today_income"]*100)
+        item["total_income"] = "{}%".format(item["total_income"]*100)
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+        return total,data
     else:
     else:
-        papers = []
-        videos = []
-    data = {"papers":papers,"videos":videos}
-    return data
+        return len(data),data
 
 
 
 
-def get_paper_info(request):
-    qdata = request.json
-    need_params = ["id"]
-    mse = ccf.check_params(*need_params,**qdata)
-    if mse:
-        raise ce.TipException(mse)
-    id = qdata.get("id")
-    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):
+def add_model(cls,**kwargs):
     """
     """
     """
     """
-    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","device_cats"])
-    vals = ccf.get_need_params(*need_params,**qdata)
-    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
+    model_name = re.search(r'.*\.(\w+)View',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    if model_name == "Match":
+        name = kwargs.get("name")
+        if cm.Match.objects.filter(name=name).exists():
+            raise ce.TipException(u"比赛名称重复!")
+    if model_name == "MatchGoup":
+        name = kwargs.get("name")
+        match_id = kwargs.get("match_id")
+        if cm.MatchGroup.objects.filter(name=name,match_id=match_id).exists():
+            raise ce.TipException(u"分组名称重复!")
+
+    if model_name == "Player":
+        user_id = kwargs.get("user_id")
+        match_id = kwargs.get("match_id")
+        if cm.Player.objects.filter(user_id=user_id,match_id=match_id).exists():
+            raise ce.TipException(u"重复添加选手!")
+
+    if model_name == "PlayerRecord":
+        match_id = kwargs.get("match_id")
+        stock_date = kwargs.get("stock_date")
+        today_stock = json.dumps(kwargs.get("today_stock"))
+        today_stock_img = json.dumps(kwargs.get("today_stock_img"))
+        player_id = kwargs.get("player_id")
+        today_fund = float(kwargs.get("today_fund"))
+        is_markt = int(kwargs.get("is_markt",0))
+
+        player = cm.Player.objects.filter(id=player_id).first()
+        user_id = player.user_id
+        init_fund = player.fund
+        user = cm.UserInfo.objects.filter(id=user_id).first()
+        username = user.username
+        usercode = user.usercode
+        match_group = player.match_group
+        match = cm.Match.objects.filter(id=match_id).first()
+        if player.match_status < 1:
+            raise ce.TipException(u"该账号已暂停/退出比赛,如有疑问请联系管理员获取详情信息!")
+        now_date = datetime.datetime.now().strftime("%Y-%m-%d")
+        if match.end_time < now_date:
+            raise ce.TipException(u"该比赛已结束!")
+
+        yesterday = cm.PlayerRecord.objects.filter(
+                        match_id=match_id,player_id=player_id).order_by("-id").first()
+        if yesterday:
+            yesterday_fund = yesterday.today_fund
+            yesterday_stock = yesterday.today_stock
+            yesterday_stock_img = yesterday.today_stock_img
+            yesterday_is_markt = yesterday.is_markt
+        else:
+            yesterday_fund = init_fund 
+            yesterday_stock = ""
+            yesterday_stock_img = "" 
+            yesterday_is_markt = 0
+        obj,flag = cm.PlayerRecord.objects.get_or_create(
+                        player_id=player_id,
+                        match_id=match_id,
+                        stock_date=stock_date)
+        obj.init_fund = init_fund
+        obj.yesterday_fund = yesterday_fund
+        obj.yesterday_stock = yesterday_stock
+        obj.yesterday_stock_img = yesterday_stock_img
+        obj.today_fund = today_fund
+        obj.today_stock = today_stock
+        obj.today_stock_img = today_stock_img
+        obj.user_id = user_id
+        obj.username = username
+        obj.usercode = usercode
+        obj.match_group = match_group
+        obj.is_markt = is_markt
+        obj.yesterday_is_markt = yesterday_is_markt
+        #计算今日和昨日盈亏
+        today_income = (today_fund - yesterday_fund)/float(yesterday_fund)
+        total_income = (today_fund - init_fund)/float(init_fund)
+        obj.today_income = round(today_income,4)
+        obj.total_income = round(total_income,4)
+        if not flag:
+            obj.ctime = datetime.datetime.now()
+        obj.save()
+        #更新排名
+        records_set = cm.PlayerRecord.objects.filter(match_id=match_id).order_by("-total_income")
+        for index,item in enumerate(records_set):
+            item.rank = index+1
+            item.save()
+        return obj.id
+
+
+    obj = model.objects.create(**kwargs)
 
 
+    return obj.id
 
 
-def update_signup(request):
+def update_model(cls,**kwargs):
     """
     """
     """
     """
-    uid = request.user.id
-    qdata = request.json
-    need_params = ["id"]
-    mse = ccf.check_params(*need_params,**qdata)
-    if mse:
-        raise ce.TipException(mse)
-    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)
-    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
-    vals["update_time"] = datetime.datetime.now()
-    subject_id = vals.get("subject_id")
-    train_type = vals.get("train_type")
-    subject_obj = cm.Subject.objects.filter(id=subject_id).first()
-    if train_type == u"新办":
-        vals["price"] = subject_obj.price_new
-    if train_type == u"复审":
-        vals["price"] = subject_obj.price_re
-    if train_type == u"换证":
-        vals["price"] = subject_obj.price_change
-    obj = cm.SignupOrders.objects.filter(id=id).update(**vals)
-    vals.pop("update_time")
-    #更新用户信息
-    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
-
-
-def get_yrxindex(request):
+    model_name = re.search(r'.*\.(\w+)View',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    id = kwargs.pop("id")
+    rst = model.objects.filter(id=id).update(**kwargs)
+    if model_name == "Match":
+        for item in kwargs.get("groups").split(","):
+            cm.MatchGroup.objects.get_or_create(match_id=obj.id,name=item)
+    return rst
+
+def delete_model(cls,**kwargs):
     """
     """
     """
     """
-    recs = cm.ClassRoom.objects.all()
-    recs = list(recs.values())
-    teachers = [{
-        "name":u"肖老师",
-        "avatar":"肖老师",
-        "lessons_count":2,
-        "students":200
-    }]
-    data = {
-        "rec":recs,     
-        "lessons":recs,     
-        "teachers":teachers     
-    }
-    return data
+    model_name = re.search(r'.*\.(\w+)View',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    ids = str(kwargs.get("id")).split(",")
+    rst = model.objects.filter(id__in=ids).delete()
+    return ids
 
 
 
 
-def get_yrxlist(request):
+def get_search_list(cls,**kwargs):
     """
     """
     """
     """
-    recs = cm.ClassRoom.objects.all()
-    recs = list(recs.values())
-    teachers = [{
-        "name":u"肖老师",
-        "avatar":"肖老师",
-        "lessons_count":2,
-        "students":200
-    }]
-    data = {
-        "rec":recs,     
-        "lessons":recs,     
-        "teachers":teachers     
-    }
-    return recs
-
-
-def get_yrxdetail(request):
-    qdata = request.json
-    need_params = ["id"]
-    mse = ccf.check_params(*need_params,**qdata)
-    if mse:
-        raise ce.TipException(mse)
-    id = qdata.get("id")
-    data = list(cm.ClassRoom.objects.filter(id=id).values())
-    data = data[0] if data else {}
-    if data:
-        lessons = list(cm.Lessons.objects.filter(classroom_id=id).values())
-        data["lessons"] = lessons
+    model_name = re.search(r'.*\.(\w+)SearchView',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    qset = model.objects.all()
+    if kwargs.get("name"):
+        qset = qset.filter(name__icontains=kwargs.get("name"))
+    if model_name == "Player":
+        data = list(qset.values("id","username"))
+    if model_name == "Stock":
+        data = list(qset.values("id","name","code"))
+        for item in data:
+            item["label"] = "%s(%s)" % (item["name"],item["code"])
+    else:
+        data = list(qset.values("id","name"))
     return data
     return data
 
 
-
-def get_subject_tree(sub=None,data=None):
+def get_detail_info(cls,**kwargs):
     """
     """
     """
     """
-    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:
-        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"]:
-            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):
+    model_name = re.search(r'.*\.(\w+)View',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    id = kwargs.get("id")
+    rst = list(model.objects.filter(id=id).values())
+    rst = rst[0] if rst else {}
+    if model_name == "PlayerRecord":
+        group_income = get_group_income(rst["match_id"],rst["match_group"])
+        if rst["total_income"] in group_income:
+            group_rank = group_income.index(rst["total_income"])+1
+        else:
+            group_rank = 1
+
+        rst["group_rank"] = group_rank
+        rst["match_group"] = cm.MatchGroup.objects.filter(id=rst["match_group"]).first().name
+        today_stock = json.loads(rst["today_stock"]) if rst["today_stock"] else []
+        today_stock = filter(lambda x:x["fund"] and x["name"],today_stock)
+        rst["today_stock"] = today_stock
+        today_stock_img = json.loads(rst["today_stock_img"]) if rst["today_stock_img"] else []
+        rst["today_stock_img"] = today_stock_img
+
+        yesterday_stock = json.loads(rst["yesterday_stock"]) if rst["yesterday_stock"] else []
+        yesterday_stock = filter(lambda x:x["fund"] and x["name"],yesterday_stock)
+        rst["yesterday_stock"] = yesterday_stock
+        
+        yesterday_stock_img = json.loads(rst["yesterday_stock_img"]) if rst["yesterday_stock_img"] else []
+        rst["yesterday_stock_img"] = yesterday_stock_img
+
+        rst["today_income"] = "{}%".format(rst["today_income"]*100)
+        rst["total_income"] = "{}%".format(rst["total_income"]*100)
+    return rst
+
+def get_list_info(cls,**kwargs):
     """
     """
     """
     """
-    data = get_subject_tree()
-    return data
-
+    model_name = re.search(r'.*\.(\w+)ListView',str(cls.__class__)).groups()[0]
+    model = getattr(cm,model_name)
+    qset = model.objects.all()
+    if kwargs.get("name"):
+        qset = qset.filter(name__icontains=kwargs.get("name"))
+    if model_name == "UserInfo":
+        if kwargs.get("username"):
+            qset = qset.filter(username__icontains=kwargs.get("username"))
+        if kwargs.get("usercode"):
+            qset = qset.filter(usercode=kwargs.get("usercode"))
+
+    data = list(qset.order_by("-id").values())
+    page = int(kwargs.get("page",0))
+    page_size = int(kwargs.get("page_size",20))
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+        if model_name == "Player":
+            for item in data:
+                user = cm.UserInfo.objects.filter(id=item["user_id"]).first()
+                match = cm.Match.objects.filter(id=item["match_id"]).first()
+                print user
+                item["username"] = user.username
+                item["usercode"] = user.usercode
+                item["match_name"] = match.name if match else ""
+        return (total,data)
+    else:
+        return len(data),data
 
 
-def post_paper(request):
-    qdata = request.json
-    need_params = ["paper_id","questions"]
-    mse = ccf.check_params(*need_params,**qdata)
-    if mse:
-        raise ce.TipException(mse)
-    paper_id = qdata.get("paper_id")
-    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
+    return rst
 
 
 
 
-def save_video_time(request):
-    qdata = request.json
-    need_params = ["video_id","time"]
-    mse = ccf.check_params(*need_params,**qdata)
-    if mse:
-        raise ce.TipException(mse)
-    paper_id = qdata.get("paper_id")
-    return True
-
-
-def get_docs_list(request):
-    data = [{
-        "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):
-    qdata = request.json
-    need_params = ["signup_id","total_fee"]
-    mse = ccf.check_params(*need_params,**qdata)
-    if mse:
-        raise ce.TipException(mse)
-    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")
-        sorder = cm.SignupOrders.objects.filter(out_trade_no=out_trade_no).first()
-        if sorder and not sorder.transaction_id:
-            now = datetime.datetime.now()
-            cm.SignupOrders.objects.filter(out_trade_no=out_trade_no)\
-            .update(order_status=2,update_time=now,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
-            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):
-    """生成学时证明
+def add_player_record_single(**kwargs):
+    """用户单独上传数据
     """
     """
-    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
+    usercode = kwargs.get("usercode")
+    match_id = kwargs.get("match_id")
+    if not cm.Player.objects.filter(usercode=usercode,match_id=match_id).exists():
+        raise ce.TipException(u"用户代码错误")
+    stock_date = kwargs.get("stock_date")
+    today_stock = json.dumps(kwargs.get("today_stock"))
+    today_stock_img = json.dumps(kwargs.get("today_stock_img"))
+    today_fund = float(kwargs.get("today_fund"))
+    is_markt = int(kwargs.get("is_markt",0))
+
+    player = cm.Player.objects.filter(usercode=usercode,match_id=match_id).first()
+    player_id = player.id
+    user_id = player.user_id
+    init_fund = player.fund
+    user = cm.UserInfo.objects.filter(id=user_id).first()
+    username = user.username
+    usercode = user.usercode
+    match_group = player.match_group
+    match = cm.Match.objects.filter(id=match_id).first()
+
+    if player.match_status < 1:
+        raise ce.TipException(u"该账号已暂停/退出比赛,如有疑问请联系管理员获取详情信息!")
+    now_date = datetime.datetime.now().strftime("%Y-%m-%d")
+    if match.end_time < now_date:
+        raise ce.TipException(u"该比赛已结束!")
+
+    yesterday = cm.PlayerRecord.objects.filter(
+                    match_id=match_id,player_id=player_id).order_by("-id").first()
+    if yesterday:
+        yesterday_fund = yesterday.today_fund
+        yesterday_stock = yesterday.today_stock
+        yesterday_stock_img = yesterday.today_stock_img
     else:
     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(total_classhour),"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
+        yesterday_fund = init_fund 
+        yesterday_stock = ""
+        yesterday_stock_img = "" 
+    obj,flag = cm.PlayerRecord.objects.get_or_create(
+                    player_id=player_id,
+                    match_id=match_id,
+                    stock_date=stock_date)
+    obj.init_fund = init_fund
+    obj.yesterday_fund = yesterday_fund
+    obj.yesterday_stock = yesterday_stock
+    obj.yesterday_stock_img = yesterday_stock_img
+    obj.today_fund = today_fund
+    obj.today_stock = today_stock
+    obj.today_stock_img = today_stock_img
+    obj.user_id = user_id
+    obj.username = username
+    obj.usercode = usercode
+    obj.match_group = match_group
+    obj.is_markt = is_markt
+    #计算今日和昨日盈亏
+    today_income = (today_fund - yesterday_fund)/float(yesterday_fund)
+    total_income = (today_fund - init_fund)/float(init_fund)
+    obj.today_income = round(today_income,4)
+    obj.total_income = round(total_income,4)
+    if not flag:
+        obj.ctime = datetime.datetime.now()
+    obj.save()
+    #更新排名
+    records_set = cm.PlayerRecord.objects.filter(match_id=match_id).order_by("-total_income")
+    for index,item in enumerate(records_set):
+        item.rank = index+1
+        item.save()
+    return obj.id
 
 
-def get_notice_list(request):
+
+def get_single_match_info(match_id):
     """
     """
     """
     """
-    uid = request.user.id
-    #uid = 21
-    qset = cm.SysNotice.objects.filter(to=uid).order_by("-id")
-    data = list(qset.values())
-    return data
+    if not match_id:
+        match = cm.Match.objects.all().order_by("-id").values().first()
+    else:
+        match = cm.Match.objects.filter(id=match_id).values().first()
+    now_date = datetime.datetime.now().strftime("%Y-%m-%d")
+    return now_date,match
+
+
 
 
 
 

+ 13 - 17
src/weixin/urls_backstage.py

@@ -6,26 +6,22 @@ from . import views
 
 
 urlpatterns = [
 urlpatterns = [
     # 运营
     # 运营
+    url(r'^uploadfile$', views.UploadFileView.as_view()),
     url(r'^auth$', views.AuthView.as_view()),
     url(r'^auth$', views.AuthView.as_view()),
     url(r'^authinfo$', views.AuthinfoView.as_view()),
     url(r'^authinfo$', views.AuthinfoView.as_view()),
+    url(r'^login$', views.LoginView.as_view()),
     url(r'^openid$', views.OpenidView.as_view()),
     url(r'^openid$', views.OpenidView.as_view()),
     url(r'^index$', views.IndexView.as_view()),
     url(r'^index$', views.IndexView.as_view()),
-    url(r'^article$', views.ArticleView.as_view()),
-    url(r'^intro$', views.IntroView.as_view()),
-    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()),
-    url(r'^uploadfile$', views.UploadFileView.as_view()),
-    url(r'^sujectitem$', views.GetSubjectView.as_view()),
-    url(r'^postpaper$', views.PostPaperView.as_view()),
-    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'^player/record$', views.PlayerRecordView.as_view()),
+    url(r'^player/record/topic$', views.PlayerRecordSingleView.as_view()),
+    url(r'^player/record/topic/match$', views.PlayerRecordSingleMatchView.as_view()),
+    url(r'^player/record/topic/uploadfile$', views.TopicUploadFileView.as_view()),
+    url(r'^player/match/list$', views.PlayerMatchListView.as_view()),
+    url(r'^player/match$', views.PlayerMatchView.as_view()),
+    url(r'^player/match/record/list$', views.PlayerMatchRecordListView.as_view()),
+    url(r'^stock/search$', views.StockSearchView.as_view()),
+    url(r'^group/rank/list$', views.GroupRankListView.as_view()),
+    url(r'^group/rank$', views.GroupRankView.as_view()),
+
 ]
 ]
 
 

+ 157 - 223
src/weixin/views.py

@@ -1,13 +1,14 @@
 # coding=utf-8
 # coding=utf-8
 from __future__ import unicode_literals
 from __future__ import unicode_literals
 import requests
 import requests
-import random
+import random,datetime
 import json
 import json
 import uuid
 import uuid
 from django.contrib import auth
 from django.contrib import auth
 from django.core.cache import cache
 from django.core.cache import cache
 from django.conf import settings
 from django.conf import settings
 
 
+import common.error_info as ce
 from common import core_views as cv
 from common import core_views as cv
 import common.common_control as ccc
 import common.common_control as ccc
 import common.common_functions as ccf
 import common.common_functions as ccf
@@ -15,6 +16,65 @@ import weixin.control_auth as ca
 import weixin.controls as ctl
 import weixin.controls as ctl
 import weixin.wzhifuSDK as wzf
 import weixin.wzhifuSDK as wzf
 
 
+
+class OpenidView(cv.BaseView):
+    def get(self,request):
+        """
+        #获取openid(小程序)
+        @code:1212
+        """
+        code = request.json.get("code")
+        open_id = cache.get(code)
+        if open_id:
+            return cv.to_suc({"openid":open_id})
+        else:
+            get_token_url = 'https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code' .format(wzf.WxPayConf_pub.APPID,wzf.WxPayConf_pub.APPSECRET,code)
+
+            res = requests.get(get_token_url).json()                                   
+            if res.has_key('openid'):                                                 
+                open_id = res['openid']                                               
+                cache.set(code,open_id,24*3600)
+            else:                                                                      
+                open_id = ''                                                           
+            if open_id:
+                return cv.to_suc({"openid":open_id})
+            else:
+                return cv.to_fail(u"获取用户信息出错!")
+
+
+class UploadFileView(cv.AuthView):
+    def post(self, request):
+        """
+        #文件上传(小程序)
+        @file:"",文件对象
+        """
+        import time
+        upload_file = request.FILES['file']
+        dest = settings.STATIC_ROOT + "/upload/"+str(int(time.time())) + upload_file.name
+        with open(dest,"wb+") as f:
+            for chunk in upload_file.chunks():
+                f.write(chunk)
+        f.close()
+        url = dest.replace(settings.STATIC_ROOT,settings.HOST)
+        return cv.to_suc({"url":url})
+
+
+class TopicUploadFileView(cv.BaseView):
+    def post(self, request):
+        """
+        #文件上传(WEB端)
+        @file:"",文件对象
+        """
+        import time
+        upload_file = request.FILES['file']
+        dest = settings.STATIC_ROOT + "/upload/"+str(int(time.time())) + upload_file.name
+        with open(dest,"wb+") as f:
+            for chunk in upload_file.chunks():
+                f.write(chunk)
+        f.close()
+        url = dest.replace(settings.STATIC_ROOT,settings.HOST)
+        return cv.to_suc({"url":url})
+
 class AuthView(cv.BaseView):
 class AuthView(cv.BaseView):
     def post(self, request):
     def post(self, request):
         """#保存微信授权信息(小程序)
         """#保存微信授权信息(小程序)
@@ -52,322 +112,196 @@ class AuthinfoView(cv.AuthView):
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
 
 
-class IndexView(cv.BaseView):
-    def get(self, request):
-        """#首页导航和top数据(小程序)
+class LoginView(cv.BaseView):
+    def post(self, request):
+        """#小程序登录(小程序)
+        @usercode:"用户代号"
+        @nickanme:"微信昵称"
+        @avatar:"微信头像"
+        @openid:"openid"
         """
         """
         try:
         try:
-            rst = ctl.get_index_data(request)
+            rst = ca.login_user(request)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
-        except Exception as e:
-            cv.tracefail()
+        except Exception as e: 
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
 
 
-class ArticleView(cv.BaseView):
+class IndexView(cv.AuthView):
     def get(self, request):
     def get(self, request):
-        """#文章详情(小程序)
-        @id:1,文章id
+        """#首页数据(小程序)
         """
         """
         try:
         try:
-            rst = ctl.get_article_info(request)
+            rst = ctl.get_index_data(request)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
 
 
-class IntroView(cv.BaseView):
+class PlayerRecordView(cv.AuthView):
     def get(self, request):
     def get(self, request):
-        """#介绍类详情,供考场介绍和联系我们两个模块使用(小程序)
-        @id:1,详情id
+        """#每日数据详情(小程序)
+        @id:1
         """
         """
+        qdata = request.json
+        need_params = ["id"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
         try:
         try:
-            rst = ctl.get_intro_info(request)
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.get_detail_info(self,**vals)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
-
-class SignUpListView(cv.AuthView):
-    def get(self, request):
-        """#报名列表(小程序)
+    def post(self, request):
+        """#新增每日数据(小程序)
+        @stock_date:"2021-07-30"
+        @today_fund:100
+        @today_stock:[{name:"江苏国泰",code:121221}]
+        @today_stock_img:["http://test.png"]
         """
         """
+        qdata = request.json
+        player = request.player
+        now = datetime.datetime.now()
+        if not now.isoweekday() in [1,2,3,4,5] or not "09:30"<now.strftime("%H:%S")<"15:30":
+            raise ce.TipException(u"只有每周一至周五 9:30 - 15:30 之间才可以提交数据!")
+        need_params = ["stock_date","today_fund"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
         try:
         try:
-            rst = ctl.get_signup_list(request)
+            need_params.extend(["is_markt","today_stock","today_stock_img"])
+            vals = ccf.get_need_params(*need_params,**qdata)
+            vals["player_id"] = player.id
+            vals["match_id"] = player.match_id
+            vals["today_fund"] = round(float(vals["today_fund"]),2)
+            rst = ctl.add_model(self,**vals)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
 
 
-class ClassListView(cv.AuthView):
+class PlayerMatchListView(cv.AuthView):
     def get(self, request):
     def get(self, request):
-        """#班级列表(小程序)
-        @subject_item0:"特种作业"
-        @subject_item1:"电工作业"
-        @subject_item2:"高压电工"
+        """#选手参赛列表(小程序)
         """
         """
         try:
         try:
-            rst = ctl.get_class_list(request)
+            rst = ctl.get_player_match_list(request)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
 
 
-class TrainingListView(cv.AuthView):
+class PlayerMatchView(cv.AuthView):
     def get(self, request):
     def get(self, request):
-        """#在线培训列表(小程序)
+        """#选手参赛详情(小程序)
         """
         """
         try:
         try:
-            rst = ctl.get_training_list(request)
+            rst = ctl.get_player_match_detail(request)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
 
 
-class PaperView(cv.AuthView):
+class PlayerMatchRecordListView(cv.AuthView):
     def get(self, request):
     def get(self, request):
-        """#获取试题详情(小程序)
-        """
-        try:
-            rst = ctl.get_paper_info(request)
-            return cv.to_suc(rst)
-        except Exception as e:
-            cv.tracefail()
-            return cv.to_fail(e)
-
-
-class PostPaperView(cv.AuthView):
-    def post(self, request):
-        """#交卷接口(小程序)
-        @paper_id:1,试卷接口
-        @questions:[{"id":1,"answer":"A"}]
-        """
-        try:
-            rst = ctl.post_paper(request)
-            return cv.to_suc({"score":rst})
-        except Exception as e:
-            cv.tracefail()
-            return cv.to_fail(e)
-
-
-class SaveVideoTimeView(cv.BaseView):
-    def post(self, request):
-        """#保存视频播放进度(小程序)
-        @video_id:1,试卷接口
-        @time:"00:12:33"
+        """#选手参赛每日持股(小程序)
+        @id:1,赛事id
+        @page:1
+        @page_size:20
         """
         """
         try:
         try:
-            rst = ctl.save_video_time(request)
-            return cv.to_suc(rst)
+            total,rst = ctl.get_player_match_records(request)
+            return cv.to_suc({"total":total,"list":rst})
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
 
 
-class GetDocsListView(cv.BaseView):
+class StockSearchView(cv.AuthView):
     def get(self, request):
     def get(self, request):
-        """#我的文件列表(小程序)
+        """#股票搜索列表(小程序)
+        @name:名称
         """
         """
         try:
         try:
-            rst = ctl.get_docs_list(request)
+            qdata = request.json
+            rst = ctl.get_search_list(self,**qdata)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
-class GetNoticeListView(cv.AuthView):
+
+class GroupRankListView(cv.AuthView):
     def get(self, request):
     def get(self, request):
-        """#我的消息(小程序)
+        """#排名列表(小程序)
         """
         """
         try:
         try:
-            rst = ctl.get_notice_list(request)
-            data = [{
-                    "id":"1", 
-                    "title":u"标题", 
-                    "content":u"消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容消息内容" 
-                }]
+            rst = ctl.get_rank_list(request)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
 
 
-class GetSubjectView(cv.BaseView):
+class GroupRankView(cv.AuthView):
     def get(self, request):
     def get(self, request):
-        """#获取培训类别/作业类别/准操项目(小程序)
+        """#分组排名(小程序)
         """
         """
         try:
         try:
-            rst = ctl.get_subjectitem_tree(request)
+            rst = ctl.get_group_rank_list(request)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
 
 
 
 
-class SignUpView(cv.AuthView):
+class PlayerRecordSingleView(cv.BaseView):
     def post(self, request):
     def post(self, request):
-        """#新增报名(小程序)
-        @name:"肖小肖",姓名
-        @sex:1,性别1/2
-        @idno:"12321312312",身份证号
-        @education:"本科",学历/教育/文化
-        @phone:"15982456282",手机号
-        @class_id:12,班级id(特种人员不传)
-        @company:"网安",公司(非必填)
-        @subject_id:12,培训科目id
-        @subject_item:"特种人员|电工作业|准操项目|培训类型",培训科目
-        @train_type:"新办",培训类型
-        @receive_card:"邮寄",领取方式
-        @area:"四川|巴中|巴州区",区域
-        @address:"回风大道15号",地址
-        @remark:"备注1",备注(非必填)
-        @idnoimg_face:"",正面照
-        @idnoimg_back:"",反面照
-        @halfbody_img:"",半身照
-        @education_img:"",学历照
-        @price:1800.00,价格
-        """
-        try:
-            rst = ctl.add_signup(request)
-            return cv.to_suc({"id":rst})
-        except Exception as e:
-            cv.tracefail()
-            return cv.to_fail(e)
-
-    def put(self, request):
-        """#修改报名(小程序)
-        @id:12,报名id,
-        @name:"肖小肖",姓名
-        @sex:1,性别1/2
-        @idno:"12321312312",身份证号
-        @education:"本科",学历/教育/文化
-        @phone:"15982456282",手机号
-        @class_id:12,班级id(特种人员不传)
-        @company:"网安",公司(非必填)
-        @subject_id:12,培训科目id
-        @subject_item:"特种人员|电工作业|准操项目|培训类型",培训科目
-        @train_type:"新办",培训类型
-        @receive_card:"邮寄",领取方式
-        @area:"四川|巴中|巴州区",区域
-        @address:"回风大道15号",地址
-        @remark:"备注1",备注(非必填)
-        @idnoimg_face:"",正面照
-        @idnoimg_back:"",反面照
-        @halfbody_img:"",半身照
-        @education_img:"",学历照
-        @price:1800.00,价格
-        """
-        try:
-            rst = ctl.update_signup(request)
-            return cv.to_suc()
-        except Exception as e:
-            cv.tracefail()
-            return cv.to_fail(e)
-
-    def get(self, request):
-        """#报名列表(小程序)
-        >order_status:0,0/1/2/3=待审核/审核通过待支付/已支付/已完成
-        """
-        try:
-            rst = ctl.get_signup_info(request)
-            return cv.to_suc(rst)
-        except Exception as e:
-            cv.tracefail()
-            return cv.to_fail(e)
-
-class SignUpPayView(cv.BaseView):
-    def post(self,request):
-        """#支付接口(小程序)
+        """#新增每日数据(WEB端)
+        @usercode:"选手code"
+        @match_id:"赛事id"
+        @stock_date:"持股日期"
+        @today_fund:"今日净资产"
+        @today_stock:"今日持股"
+        @today_stock_img:"今日持股截图"
         """
         """
+        qdata = request.json
+        now = datetime.datetime.now()
+        if not now.isoweekday() in [1,2,3,4,5] or not "09:30"<now.strftime("%H:%S")<"15:30":
+            raise ce.TipException(u"只有每周一至周五 9:30 - 15:30 之间才可以提交数据!")
+        need_params = ["match_id","usercode","stock_date","today_fund","today_stock_img"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
         try:
         try:
-            rst = ctl.do_signup_pay(request)
+            need_params.extend(["is_markt","today_stock"])
+            vals = ccf.get_need_params(*need_params,**qdata)
+            vals["today_fund"] = round(float(vals["today_fund"]),2)
+            rst = ctl.add_player_record_single(**vals)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             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):
-        """#我的学时证明
+class PlayerRecordSingleMatchView(cv.BaseView):
+    def get(self, request):
+        """#获取赛事数据(WEB端)
+        @id:"赛事id"
         """
         """
+        qdata = request.json
+        match_id = qdata.get("id")
         try:
         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)
+            now_date,rst = ctl.get_single_match_info(match_id)
+            return cv.to_suc({"stock_date":now_date,"match":rst})
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
-
-
-class OpenidView(cv.BaseView):
-    def get(self,request):
-        """
-        #获取openid(小程序)
-        @code:1212
-        """
-        code = request.json.get("code")
-        open_id = cache.get(code)
-        if open_id:
-            return cv.to_suc({"openid":open_id})
-        else:
-            get_token_url = 'https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code' .format(wzf.WxPayConf_pub.APPID,wzf.WxPayConf_pub.APPSECRET,code)
-
-            res = requests.get(get_token_url).json()                                   
-            if res.has_key('openid'):                                                 
-                open_id = res['openid']                                               
-                cache.set(code,open_id,24*3600)
-            else:                                                                      
-                open_id = ''                                                           
-            if open_id:
-                return cv.to_suc({"openid":open_id})
-            else:
-                return cv.to_fail(u"获取用户信息出错!")
-
-
-class UploadFileView(cv.BaseView):
-    def post(self, request):
-        """
-        #文件上传(小程序)
-        @file:"",文件对象
-        """
-        import time
-        upload_file = request.FILES['file']
-        dest = settings.STATIC_ROOT + "/upload/"+str(int(time.time())) + upload_file.name
-        with open(dest,"wb+") as f:
-            for chunk in upload_file.chunks():
-                f.write(chunk)
-        f.close()
-        url = dest.replace(settings.STATIC_ROOT,"https://wxapi.yifeng2016.com")
-        return cv.to_suc({"url":url})

+ 2 - 2
src/weixin/wzhifuSDK.py

@@ -55,9 +55,9 @@ class WxPayConf_pub(object):
 
 
     ##=======【基本信息设置】=====================================
     ##=======【基本信息设置】=====================================
     #微信公众号身份的唯一标识。审核通过后,在微信发送的邮件中查看
     #微信公众号身份的唯一标识。审核通过后,在微信发送的邮件中查看
-    APPID = "wxd417822087cf4573"
+    APPID = "wx2938132b773c7b5a"
     #JSAPI接口中获取openid,审核后在公众平台开启开发模式后可查看
     #JSAPI接口中获取openid,审核后在公众平台开启开发模式后可查看
-    APPSECRET = "787d78cb82407c45603c3d274a9b1acd"
+    APPSECRET = "1707d86ef4d9894775ebac21d87390e6"
     #受理商ID,身份标识
     #受理商ID,身份标识
     MCHID = "1370781802"
     MCHID = "1370781802"
     #商户支付密钥Key。审核通过后,在微信发送的邮件中查看
     #商户支付密钥Key。审核通过后,在微信发送的邮件中查看

+ 139 - 0
src/wzbapi/templates/canvas.html

@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title></title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <link rel="stylesheet" href="/static/index.css">
+    <link rel="stylesheet" href="/static/iconfont/iconfont.css">
+    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
+    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
+    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
+    <script src="/static/layer/layer.js"></script>
+    <script src="/static/jquery.pureCanvas.js"></script>
+</head>
+<body>
+	<div id="container">
+        <div><h3 data-paperno="{{paper.paperno}}" data-paperid="{{paper.id}}" data-std-point="{{paper.std_point}}" style="margin:10px;padding:0px;">{{paper.title}}|{{paper.paperno}}</h3></div>
+		<div class="imgsview" id="imgsview">
+            <div style="height:45px;line-height:45px;">
+                <div style="width: 50%;float:left;text-align:center;">
+                    <button class="btn btn_active">试卷图片</button>
+                </div>
+                <div style="width: 50%;float:right;text-align:center;">
+                    <button class="btn">答案图片</button>
+                </div>
+                <div style="clear: both;height: 0px;"></div>
+            </div>
+            {%for pm in paper.paperimgs%}
+                {%if forloop.first%}
+			        <img class="active_green_border"  src="{{pm}}" id="backgroundImage" data-page={{forloop.counter}} data-pure-canvas-option="setting" data-pure-canvas-type="backgroundImage" width=140 height=200 >
+                {%else%}
+			        <img src="{{pm}}" id="backgroundImage" data-page={{forloop.counter}} data-pure-canvas-option="setting" data-pure-canvas-type="backgroundImage" width=140 height=200 >
+                {%endif%}
+            {% endfor %}
+		</div>
+		<div style="width: 65%;float: left;overflow:scroll;">
+			<!--<canvas id="pureCanvas" width=1295 height="1111"></canvas>-->
+            <div id="purePallete" class="paint_menu" style="" >
+                <button type="button" id="Rectangle" data-type="danti" data-desc="切割单题" class="toolkit_active" data-pure-canvas-option='toolkit' data-pure-canvas-type='type' data-pure-canvas-value="Rectangle">
+                    <i class="icon iconfont icon-jianqie"></i>
+                </button>
+                <button type="button" id="Rectangle" data-type="xiaoti" data-desc="切割小题" data-pure-canvas-option='toolkit' data-pure-canvas-type='type' data-pure-canvas-value="Rectangle">
+                    <i class="icon iconfont icon-caijian"></i>
+                </button>
+                <button type="button" id="Rectangle" data-type="cailiao" data-desc="切割材料" data-pure-canvas-option='toolkit' data-pure-canvas-type='type' data-pure-canvas-value="Rectangle">
+                    <i class="icon iconfont icon-hebing"></i>
+                </button>
+                <button type="button" id="Rectangle" data-desc="刷新" data-pure-canvas-option='toolkit' data-pure-canvas-type='type' data-pure-canvas-value="Rectangle">
+                    <i class="icon iconfont icon-xunhuan"></i>
+                </button>
+                <button type="button" id="Rectangle" data-desc="全屏" data-pure-canvas-option='toolkit' data-pure-canvas-type='type' data-pure-canvas-value="Rectangle">
+                    <i class="icon iconfont icon-quanping"></i>
+                </button>
+                <button type="button" id="Rectangle" data-desc="结束材料" data-pure-canvas-option='toolkit' data-pure-canvas-type='type' data-pure-canvas-value="Rectangle">
+                    <i class="icon iconfont icon-msnui-poweroff"></i>
+                </button>
+                <button data-desc="缩放"  type="button" style="width:150px;">
+                <input type="range" id="rate" value="100" min="10" max="200" step="10" data-pure-canvas-option="setting" data-pure-canvas-type="resizeType" data-pure-canvas-value="rate">
+                </button>
+                
+                <button data-desc="设置分值" class="ui-button ui-widget ui-corner-all handle_btn" style="margin-right: 10px;box-shadow: -3px 3px 0px #888888;">
+                    <a style="text-decoration:none;" href="http://web.say365.xin/ss-admin/index.html#/paper_examines/set_score_pro/{{paper.id}}">下一步</a>
+                </button>
+                <button class="ui-button ui-widget ui-corner-all handle_btn handle_btn_save" data-desc="保存" style="margin-right: 10px;box-shadow: -3px 3px 0px #888888;">保存</button>
+            </div>
+			<div id="pureCanvas" style="overflow:scroll;width:64%;" data-width="" data-height=""></div>
+		</div>
+		<div style="width: 20%;float:left;background:#F8F8F8;height:1000px;position:relative;">
+            <div style="height:35px;line-height:35px;">
+                <div style="width: 50%;float:left;text-align:center;"><b>题目图片</b></div>
+                <div style="width: 50%;float:right;text-align:center;">共1题</div>
+		        <div style="clear: both;height: 0px;"></div>
+            </div>
+            <div id="paperpieces" style="overflow:auto;height:100%;">
+                <ul id="paperpiecesul" style="list-style:none;margin:0px;padding:0px;">
+                    {% for img in paperpieces %} 
+                        {% ifequal img.img_type 0 %}
+                            {% if img.data|length %}
+                            <li class="cut_img_box_li">
+                                {% if img.stuff|length %}
+                                    <span type="text" class="cailiao_num">第{{img.stuff|length}}张材料</span>
+                                    <ul class="cailiao_clean_ul">
+                                    {% for d in img.stuff %}
+                                        <li class="cut_imgview" data-id="{{d.id}}" data-point="0,63,419,174" data-page="{{d.cut_point.page}}" data-image-type="{{d.img_type}}" style="background-image: url('{{d.imgurl}}');background-size:100%;height:{{d.view_height}}vw;">
+                                        <input type="text" class="subqueinput" value="{{forloop.counter}}">
+                                        <i class="icon iconfont icon-shanchu1 del_cut_imgview" style="display: block;"></i>
+                                        </li>
+                                    {%endfor%}
+                                    </ul>
+                                {% endif %}
+                                    <input type="text" class="quenoinput" value="{{img.queno}}">
+                                    <i class="icon iconfont icon-shanchu del_li" style="display: none;"></i>
+                                    <ul class="clean_ul">
+                                    {% for d in img.data%}
+                                        <li class="cut_imgview" data-id="{{d.id}}" data-point="0,63,419,174" data-page="{{d.cut_point.page}}" data-image-type="{{d.img_type}}" style="background-image: url('{{d.imgurl}}');background-size:100%;height:{{d.view_height}}vw;">
+                                        {% ifnotequal d.squeno 0%}
+                                        <input type="text" class="subqueinput" value="{{d.squeno}}">
+                                        {% endifnotequal %}
+                                        <i class="icon iconfont icon-shanchu1 del_cut_imgview" style="display: none;"></i>
+                                        </li>
+                                    {%endfor%}
+                                    </ul>
+                            </li>
+                            {% else %}
+                            <li class="cut_img_box_li">
+                                    <input type="text" class="quenoinput" value="{{img.queno}}">
+                                    <i class="icon iconfont icon-shanchu del_li" style="display: none;"></i>
+                                    {% if img.stuff|length %}
+                                        <span type="text" class="cailiao_num">第{{img.stuff|length}}张材料</span>
+                                        <ul class="cailiao_clean_ul">
+                                        {% for d in img.stuff %}
+                                            <li class="cut_imgview" data-id="{{d.id}}" data-point="0,63,419,174" data-page="{{d.cut_point.page}}" data-image-type="{{d.img_type}}" style="background-image: url('{{d.imgurl}}');background-size:100%;height:{{d.view_height}}vw;">
+                                            <input type="text" class="subqueinput" value="{{forloop.counter}}">
+                                            <i class="icon iconfont icon-shanchu1 del_cut_imgview" style="display: block;"></i>
+                                            </li>
+                                        {%endfor%}
+                                        </ul>
+                                    {% endif %}
+                                    <ul class="clean_ul">
+                                        <li class="cut_imgview" data-id="{{img.id}}" data-point="0,63,419,174" data-page="{{img.cut_point.page}}" data-image-type="{{img.img_type}}" style="background-image: url('{{img.imgurl}}');background-size:100%;height:{{img.view_height}}vw;">
+                                        <i class="icon iconfont icon-shanchu1 del_cut_imgview" style="display: none;"></i>
+                                        </li>
+                                    </ul>
+                            </li>
+                            {% endif %}
+                        {%endifequal%}
+                    {% endfor %}
+                    <!-- 切割单题 -->
+                    <li class="forward_point cut_imgview_active cut_img_box_li">
+                        <input type="text" style="width:40px;" value={{paperpieces|length|add:1}} />
+                    </li>
+                </ul>
+            </div>
+		</div>
+		<div style="clear: both;height: 0px;"></div>
+	</div>
+</body>
+    <script src="/static/index.js"></script>
+    <script src="/static/handle.js"></script>
+</html>

BIN
src/wzbapi/templates/media/1517533995690XZB2018RJYYB01021_1.jpg


BIN
src/wzbapi/templates/media/1517534005179XZB2018RJYYB01021_2.jpg


BIN
src/wzbapi/templates/media/XZB2018RJYWB01001_1.jpg


+ 55 - 0
src/wzbapi/templates/static/handle.js

@@ -0,0 +1,55 @@
+$(function(){
+    var ApiHOST = "http://api.say365.xin/ss-admin"; 
+
+    $(".handle_btn_save").click(function(){
+        var load = layer.load();
+        var imglist = [];
+        var paperno = $("h3").attr("data-paperno");
+        var paperid = $("h3").attr("data-paperid");
+        $(".cut_imgview").each(function(index){
+           var cutimg = {}; 
+           var id = $(this).attr("data-id");
+           console.log(id);
+           if(id==undefined){
+                id = 0;    
+            }
+           cutimg.id = id;
+           cutimg.imgtype = $(this).attr("data-image-type");
+           cutimg.point = $(this).attr("data-point");
+           cutimg.page = parseInt($(this).attr("data-page"))-1;
+
+           if($(this).find(".subqueinput").length){
+                cutimg.squeno = $(this).find(".subqueinput").val(); 
+            }else{
+                cutimg.squeno = 0;     
+            }
+            cutimg.queno = $(this).parents(".cut_img_box_li").find(".quenoinput").val();
+            imglist.push(cutimg);
+        });    
+        console.log(imglist);
+        //保存切片
+        var url = ApiHOST+"/ss-admin/savestdpieces/";
+        var params = {
+                paper_id:paperid, 
+                paper_no:paperno, 
+                cut_paper_imgs_info:imglist, 
+            };
+        $.ajax({
+            type:"post",    
+            url:url,    
+            data:JSON.stringify(params),
+            //dataType:'json',
+            success:function(data){
+               console.log(data); 
+               if(data.code==1){
+                    layer.alert("保存成功",{
+                        icon:1    
+                    }); 
+                    window.location.reload();
+                }
+                layer.close(load);
+            }
+        });
+
+    });
+});

+ 370 - 0
src/wzbapi/templates/static/iconfont/demo.css

@@ -0,0 +1,370 @@
+*{margin: 0;padding: 0;list-style: none;}
+/*
+KISSY CSS Reset
+理念:1. reset 的目的不是清除浏览器的默认样式,这仅是部分工作。清除和重置是紧密不可分的。
+2. reset 的目的不是让默认样式在所有浏览器下一致,而是减少默认样式有可能带来的问题。
+3. reset 期望提供一套普适通用的基础样式。但没有银弹,推荐根据具体需求,裁剪和修改后再使用。
+特色:1. 适应中文;2. 基于最新主流浏览器。
+维护:玉伯<lifesinger@gmail.com>, 正淳<ragecarrier@gmail.com>
+ */
+
+/** 清除内外边距 **/
+body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* structural elements 结构元素 */
+dl, dt, dd, ul, ol, li, /* list elements 列表元素 */
+pre, /* text formatting elements 文本格式元素 */
+form, fieldset, legend, button, input, textarea, /* form elements 表单元素 */
+th, td /* table elements 表格元素 */ {
+  margin: 0;
+  padding: 0;
+}
+
+/** 设置默认字体 **/
+body,
+button, input, select, textarea /* for ie */ {
+  font: 12px/1.5 tahoma, arial, \5b8b\4f53, sans-serif;
+}
+h1, h2, h3, h4, h5, h6 { font-size: 100%; }
+address, cite, dfn, em, var { font-style: normal; } /* 将斜体扶正 */
+code, kbd, pre, samp { font-family: courier new, courier, monospace; } /* 统一等宽字体 */
+small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */
+
+/** 重置列表元素 **/
+ul, ol { list-style: none; }
+
+/** 重置文本格式元素 **/
+a { text-decoration: none; }
+a:hover { text-decoration: underline; }
+
+
+/** 重置表单元素 **/
+legend { color: #000; } /* for ie6 */
+fieldset, img { border: 0; } /* img 搭车:让链接里的 img 无边框 */
+button, input, select, textarea { font-size: 100%; } /* 使得表单元素在 ie 下能继承字体大小 */
+/* 注:optgroup 无法扶正 */
+
+/** 重置表格元素 **/
+table { border-collapse: collapse; border-spacing: 0; }
+
+/* 清除浮动 */
+.ks-clear:after, .clear:after {
+  content: '\20';
+  display: block;
+  height: 0;
+  clear: both;
+}
+.ks-clear, .clear {
+  *zoom: 1;
+}
+
+.main {
+  padding: 30px 100px;
+width: 960px;
+margin: 0 auto;
+}
+.main h1{font-size:36px; color:#333; text-align:left;margin-bottom:30px; border-bottom: 1px solid #eee;}
+
+.helps{margin-top:40px;}
+.helps pre{
+  padding:20px;
+  margin:10px 0;
+  border:solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists{
+  width: 100% !important;
+
+}
+
+.icon_lists li{
+  float:left;
+  width: 100px;
+  height:180px;
+  text-align: center;
+  list-style: none !important;
+}
+.icon_lists .icon{
+  font-size: 42px;
+  line-height: 100px;
+  margin: 10px 0;
+  color:#333;
+  -webkit-transition: font-size 0.25s ease-out 0s;
+  -moz-transition: font-size 0.25s ease-out 0s;
+  transition: font-size 0.25s ease-out 0s;
+
+}
+.icon_lists .icon:hover{
+  font-size: 100px;
+}
+
+
+
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p,
+.markdown pre {
+  margin: 1em 0;
+}
+
+.markdown > p,
+.markdown > blockquote,
+.markdown > .highlight,
+.markdown > ol,
+.markdown > ul {
+  width: 80%;
+}
+
+.markdown ul > li {
+  list-style: circle;
+}
+
+.markdown > ul li,
+.markdown blockquote ul > li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown > ul li p,
+.markdown > ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol > li {
+  list-style: decimal;
+}
+
+.markdown > ol li,
+.markdown blockquote ol > li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown pre {
+  border-radius: 6px;
+  background: #f7f7f7;
+  padding: 20px;
+}
+
+.markdown pre code {
+  border: none;
+  background: #f7f7f7;
+  margin: 0;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown > table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown > table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+
+}
+
+.markdown > table th,
+.markdown > table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown > table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+  font-style: italic;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown > br,
+.markdown > p > br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+pre{
+  background: #fff;
+}
+
+
+
+
+

+ 202 - 0
src/wzbapi/templates/static/iconfont/demo_fontclass.html

@@ -0,0 +1,202 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8"/>
+    <title>IconFont</title>
+    <link rel="stylesheet" href="demo.css">
+    <link rel="stylesheet" href="iconfont.css">
+</head>
+<body>
+    <div class="main markdown">
+        <h1>IconFont 图标</h1>
+        <ul class="icon_lists clear">
+            
+                <li>
+                <i class="icon iconfont icon-msnui-poweroff"></i>
+                    <div class="name">关机</div>
+                    <div class="fontclass">.icon-msnui-poweroff</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-close"></i>
+                    <div class="name">close</div>
+                    <div class="fontclass">.icon-close</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-shanchu"></i>
+                    <div class="name">删除</div>
+                    <div class="fontclass">.icon-shanchu</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-quanping"></i>
+                    <div class="name">全屏</div>
+                    <div class="fontclass">.icon-quanping</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-shanchu1"></i>
+                    <div class="name">删除</div>
+                    <div class="fontclass">.icon-shanchu1</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_huabanfuben"></i>
+                    <div class="name">未标题-1_画板 1 副本 6</div>
+                    <div class="fontclass">.icon-weibiaoti-_huabanfuben</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_huabanfuben1"></i>
+                    <div class="name">未标题-1_画板 1 副本 7</div>
+                    <div class="fontclass">.icon-weibiaoti-_huabanfuben1</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_huabanfuben2"></i>
+                    <div class="name">未标题-1_画板 1 副本 11</div>
+                    <div class="fontclass">.icon-weibiaoti-_huabanfuben2</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_huabanfuben3"></i>
+                    <div class="name">未标题-1_画板 1 副本 10</div>
+                    <div class="fontclass">.icon-weibiaoti-_huabanfuben3</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_huabanfuben4"></i>
+                    <div class="name">未标题-1_画板 1 副本 9</div>
+                    <div class="fontclass">.icon-weibiaoti-_huabanfuben4</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_huabanfuben5"></i>
+                    <div class="name">未标题-1_画板 1 副本 8</div>
+                    <div class="fontclass">.icon-weibiaoti-_huabanfuben5</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_Time-active"></i>
+                    <div class="name">未标题-1_Time-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_Time-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_b-active"></i>
+                    <div class="name">未标题-1_b-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_b-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_A-active"></i>
+                    <div class="name">未标题-1_A-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_A-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_Add-active"></i>
+                    <div class="name">未标题-1_Add-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_Add-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_center-active"></i>
+                    <div class="name">未标题-1_center-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_center-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_life-active"></i>
+                    <div class="name">未标题-1_life-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_life-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_youxu-active"></i>
+                    <div class="name">未标题-1_youxu-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_youxu-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_right-active"></i>
+                    <div class="name">未标题-1_right-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_right-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_U-active"></i>
+                    <div class="name">未标题-1_U-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_U-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_wuxu-active"></i>
+                    <div class="name">未标题-1_wuxu-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_wuxu-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_Pic-active"></i>
+                    <div class="name">未标题-1_Pic-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_Pic-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-weibiaoti-_I-active"></i>
+                    <div class="name">未标题-1_I-active</div>
+                    <div class="fontclass">.icon-weibiaoti-_I-active</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-hebing"></i>
+                    <div class="name">合并 (1)</div>
+                    <div class="fontclass">.icon-hebing</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-caijian"></i>
+                    <div class="name">裁剪</div>
+                    <div class="fontclass">.icon-caijian</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-jianqie"></i>
+                    <div class="name">剪切</div>
+                    <div class="fontclass">.icon-jianqie</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont icon-xunhuan"></i>
+                    <div class="name">循环2</div>
+                    <div class="fontclass">.icon-xunhuan</div>
+                </li>
+            
+        </ul>
+
+        <h2 id="font-class-">font-class引用</h2>
+        <hr>
+
+        <p>font-class是unicode使用方式的一种变种,主要是解决unicode书写不直观,语意不明确的问题。</p>
+        <p>与unicode使用方式相比,具有如下特点:</p>
+        <ul>
+        <li>兼容性良好,支持ie8+,及所有现代浏览器。</li>
+        <li>相比于unicode语意明确,书写更直观。可以很容易分辨这个icon是什么。</li>
+        <li>因为使用class来定义图标,所以当要替换图标时,只需要修改class里面的unicode引用。</li>
+        <li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li>
+        </ul>
+        <p>使用步骤如下:</p>
+        <h3 id="-fontclass-">第一步:引入项目下面生成的fontclass代码:</h3>
+
+
+        <pre><code class="lang-js hljs javascript"><span class="hljs-comment">&lt;link rel="stylesheet" type="text/css" href="./iconfont.css"&gt;</span></code></pre>
+        <h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
+        <pre><code class="lang-css hljs">&lt;<span class="hljs-selector-tag">i</span> <span class="hljs-selector-tag">class</span>="<span class="hljs-selector-tag">iconfont</span> <span class="hljs-selector-tag">icon-xxx</span>"&gt;&lt;/<span class="hljs-selector-tag">i</span>&gt;</code></pre>
+        <blockquote>
+        <p>"iconfont"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。</p>
+        </blockquote>
+    </div>
+</body>
+</html>

+ 279 - 0
src/wzbapi/templates/static/iconfont/demo_symbol.html

@@ -0,0 +1,279 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8"/>
+    <title>IconFont</title>
+    <link rel="stylesheet" href="demo.css">
+    <script src="iconfont.js"></script>
+
+    <style type="text/css">
+        .icon {
+          /* 通过设置 font-size 来改变图标大小 */
+          width: 1em; height: 1em;
+          /* 图标和文字相邻时,垂直对齐 */
+          vertical-align: -0.15em;
+          /* 通过设置 color 来改变 SVG 的颜色/fill */
+          fill: currentColor;
+          /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+             normalize.css 中也包含这行 */
+          overflow: hidden;
+        }
+
+    </style>
+</head>
+<body>
+    <div class="main markdown">
+        <h1>IconFont 图标</h1>
+        <ul class="icon_lists clear">
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-msnui-poweroff"></use>
+                    </svg>
+                    <div class="name">关机</div>
+                    <div class="fontclass">#icon-msnui-poweroff</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-close"></use>
+                    </svg>
+                    <div class="name">close</div>
+                    <div class="fontclass">#icon-close</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-shanchu"></use>
+                    </svg>
+                    <div class="name">删除</div>
+                    <div class="fontclass">#icon-shanchu</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-quanping"></use>
+                    </svg>
+                    <div class="name">全屏</div>
+                    <div class="fontclass">#icon-quanping</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-shanchu1"></use>
+                    </svg>
+                    <div class="name">删除</div>
+                    <div class="fontclass">#icon-shanchu1</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_huabanfuben"></use>
+                    </svg>
+                    <div class="name">未标题-1_画板 1 副本 6</div>
+                    <div class="fontclass">#icon-weibiaoti-_huabanfuben</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_huabanfuben1"></use>
+                    </svg>
+                    <div class="name">未标题-1_画板 1 副本 7</div>
+                    <div class="fontclass">#icon-weibiaoti-_huabanfuben1</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_huabanfuben2"></use>
+                    </svg>
+                    <div class="name">未标题-1_画板 1 副本 11</div>
+                    <div class="fontclass">#icon-weibiaoti-_huabanfuben2</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_huabanfuben3"></use>
+                    </svg>
+                    <div class="name">未标题-1_画板 1 副本 10</div>
+                    <div class="fontclass">#icon-weibiaoti-_huabanfuben3</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_huabanfuben4"></use>
+                    </svg>
+                    <div class="name">未标题-1_画板 1 副本 9</div>
+                    <div class="fontclass">#icon-weibiaoti-_huabanfuben4</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_huabanfuben5"></use>
+                    </svg>
+                    <div class="name">未标题-1_画板 1 副本 8</div>
+                    <div class="fontclass">#icon-weibiaoti-_huabanfuben5</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_Time-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_Time-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_Time-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_b-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_b-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_b-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_A-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_A-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_A-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_Add-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_Add-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_Add-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_center-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_center-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_center-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_life-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_life-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_life-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_youxu-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_youxu-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_youxu-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_right-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_right-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_right-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_U-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_U-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_U-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_wuxu-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_wuxu-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_wuxu-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_Pic-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_Pic-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_Pic-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-weibiaoti-_I-active"></use>
+                    </svg>
+                    <div class="name">未标题-1_I-active</div>
+                    <div class="fontclass">#icon-weibiaoti-_I-active</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-hebing"></use>
+                    </svg>
+                    <div class="name">合并 (1)</div>
+                    <div class="fontclass">#icon-hebing</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-caijian"></use>
+                    </svg>
+                    <div class="name">裁剪</div>
+                    <div class="fontclass">#icon-caijian</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-jianqie"></use>
+                    </svg>
+                    <div class="name">剪切</div>
+                    <div class="fontclass">#icon-jianqie</div>
+                </li>
+            
+                <li>
+                    <svg class="icon" aria-hidden="true">
+                        <use xlink:href="#icon-xunhuan"></use>
+                    </svg>
+                    <div class="name">循环2</div>
+                    <div class="fontclass">#icon-xunhuan</div>
+                </li>
+            
+        </ul>
+
+
+        <h2 id="symbol-">symbol引用</h2>
+        <hr>
+
+        <p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
+        这种用法其实是做了一个svg的集合,与另外两种相比具有如下特点:</p>
+        <ul>
+          <li>支持多色图标了,不再受单色限制。</li>
+          <li>通过一些技巧,支持像字体那样,通过<code>font-size</code>,<code>color</code>来调整样式。</li>
+          <li>兼容性较差,支持 ie9+,及现代浏览器。</li>
+          <li>浏览器渲染svg的性能一般,还不如png。</li>
+        </ul>
+        <p>使用步骤如下:</p>
+        <h3 id="-symbol-">第一步:引入项目下面生成的symbol代码:</h3>
+        <pre><code class="lang-js hljs javascript"><span class="hljs-comment">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;</span></code></pre>
+        <h3 id="-css-">第二步:加入通用css代码(引入一次就行):</h3>
+        <pre><code class="lang-js hljs javascript">&lt;style type=<span class="hljs-string">"text/css"</span>&gt;
+.icon {
+   width: <span class="hljs-number">1</span>em; height: <span class="hljs-number">1</span>em;
+   vertical-align: <span class="hljs-number">-0.15</span>em;
+   fill: currentColor;
+   overflow: hidden;
+}
+&lt;<span class="hljs-regexp">/style&gt;</span></code></pre>
+        <h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
+        <pre><code class="lang-js hljs javascript">&lt;svg <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"icon"</span> aria-hidden=<span class="hljs-string">"true"</span>&gt;<span class="xml"><span class="hljs-tag">
+  &lt;<span class="hljs-name">use</span> <span class="hljs-attr">xlink:href</span>=<span class="hljs-string">"#icon-xxx"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">use</span>&gt;</span>
+</span>&lt;<span class="hljs-regexp">/svg&gt;
+        </span></code></pre>
+    </div>
+</body>
+</html>

+ 240 - 0
src/wzbapi/templates/static/iconfont/demo_unicode.html

@@ -0,0 +1,240 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8"/>
+    <title>IconFont</title>
+    <link rel="stylesheet" href="demo.css">
+
+    <style type="text/css">
+
+        @font-face {font-family: "iconfont";
+          src: url('iconfont.eot'); /* IE9*/
+          src: url('iconfont.eot#iefix') format('embedded-opentype'), /* IE6-IE8 */
+          url('iconfont.woff') format('woff'), /* chrome, firefox */
+          url('iconfont.ttf') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
+          url('iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
+        }
+
+        .iconfont {
+          font-family:"iconfont" !important;
+          font-size:16px;
+          font-style:normal;
+          -webkit-font-smoothing: antialiased;
+          -webkit-text-stroke-width: 0.2px;
+          -moz-osx-font-smoothing: grayscale;
+        }
+
+    </style>
+</head>
+<body>
+    <div class="main markdown">
+        <h1>IconFont 图标</h1>
+        <ul class="icon_lists clear">
+            
+                <li>
+                <i class="icon iconfont">&#xe63d;</i>
+                    <div class="name">关机</div>
+                    <div class="code">&amp;#xe63d;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe69a;</i>
+                    <div class="name">close</div>
+                    <div class="code">&amp;#xe69a;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe613;</i>
+                    <div class="name">删除</div>
+                    <div class="code">&amp;#xe613;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe61f;</i>
+                    <div class="name">全屏</div>
+                    <div class="code">&amp;#xe61f;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe602;</i>
+                    <div class="name">删除</div>
+                    <div class="code">&amp;#xe602;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe606;</i>
+                    <div class="name">未标题-1_画板 1 副本 6</div>
+                    <div class="code">&amp;#xe606;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe607;</i>
+                    <div class="name">未标题-1_画板 1 副本 7</div>
+                    <div class="code">&amp;#xe607;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe608;</i>
+                    <div class="name">未标题-1_画板 1 副本 11</div>
+                    <div class="code">&amp;#xe608;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe609;</i>
+                    <div class="name">未标题-1_画板 1 副本 10</div>
+                    <div class="code">&amp;#xe609;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe60a;</i>
+                    <div class="name">未标题-1_画板 1 副本 9</div>
+                    <div class="code">&amp;#xe60a;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe60b;</i>
+                    <div class="name">未标题-1_画板 1 副本 8</div>
+                    <div class="code">&amp;#xe60b;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe612;</i>
+                    <div class="name">未标题-1_Time-active</div>
+                    <div class="code">&amp;#xe612;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe614;</i>
+                    <div class="name">未标题-1_b-active</div>
+                    <div class="code">&amp;#xe614;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe615;</i>
+                    <div class="name">未标题-1_A-active</div>
+                    <div class="code">&amp;#xe615;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe616;</i>
+                    <div class="name">未标题-1_Add-active</div>
+                    <div class="code">&amp;#xe616;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe617;</i>
+                    <div class="name">未标题-1_center-active</div>
+                    <div class="code">&amp;#xe617;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe618;</i>
+                    <div class="name">未标题-1_life-active</div>
+                    <div class="code">&amp;#xe618;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe619;</i>
+                    <div class="name">未标题-1_youxu-active</div>
+                    <div class="code">&amp;#xe619;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe61a;</i>
+                    <div class="name">未标题-1_right-active</div>
+                    <div class="code">&amp;#xe61a;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe61b;</i>
+                    <div class="name">未标题-1_U-active</div>
+                    <div class="code">&amp;#xe61b;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe61c;</i>
+                    <div class="name">未标题-1_wuxu-active</div>
+                    <div class="code">&amp;#xe61c;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe61d;</i>
+                    <div class="name">未标题-1_Pic-active</div>
+                    <div class="code">&amp;#xe61d;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe61e;</i>
+                    <div class="name">未标题-1_I-active</div>
+                    <div class="code">&amp;#xe61e;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe620;</i>
+                    <div class="name">合并 (1)</div>
+                    <div class="code">&amp;#xe620;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe621;</i>
+                    <div class="name">裁剪</div>
+                    <div class="code">&amp;#xe621;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe622;</i>
+                    <div class="name">剪切</div>
+                    <div class="code">&amp;#xe622;</div>
+                </li>
+            
+                <li>
+                <i class="icon iconfont">&#xe623;</i>
+                    <div class="name">循环2</div>
+                    <div class="code">&amp;#xe623;</div>
+                </li>
+            
+        </ul>
+        <h2 id="unicode-">unicode引用</h2>
+        <hr>
+
+        <p>unicode是字体在网页端最原始的应用方式,特点是:</p>
+        <ul>
+        <li>兼容性最好,支持ie6+,及所有现代浏览器。</li>
+        <li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
+        <li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li>
+        </ul>
+        <blockquote>
+        <p>注意:新版iconfont支持多色图标,这些多色图标在unicode模式下将不能使用,如果有需求建议使用symbol的引用方式</p>
+        </blockquote>
+        <p>unicode使用步骤如下:</p>
+        <h3 id="-font-face">第一步:拷贝项目下面生成的font-face</h3>
+        <pre><code class="lang-js hljs javascript">@font-face {
+  font-family: <span class="hljs-string">'iconfont'</span>;
+  src: url(<span class="hljs-string">'iconfont.eot'</span>);
+  src: url(<span class="hljs-string">'iconfont.eot?#iefix'</span>) format(<span class="hljs-string">'embedded-opentype'</span>),
+  url(<span class="hljs-string">'iconfont.woff'</span>) format(<span class="hljs-string">'woff'</span>),
+  url(<span class="hljs-string">'iconfont.ttf'</span>) format(<span class="hljs-string">'truetype'</span>),
+  url(<span class="hljs-string">'iconfont.svg#iconfont'</span>) format(<span class="hljs-string">'svg'</span>);
+}
+</code></pre>
+        <h3 id="-iconfont-">第二步:定义使用iconfont的样式</h3>
+        <pre><code class="lang-js hljs javascript">.iconfont{
+  font-family:<span class="hljs-string">"iconfont"</span> !important;
+  font-size:<span class="hljs-number">16</span>px;font-style:normal;
+  -webkit-font-smoothing: antialiased;
+  -webkit-text-stroke-width: <span class="hljs-number">0.2</span>px;
+  -moz-osx-font-smoothing: grayscale;
+}
+</code></pre>
+        <h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
+        <pre><code class="lang-js hljs javascript">&lt;i <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"iconfont"</span>&gt;&amp;#x33;<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span></span></code></pre>
+
+        <blockquote>
+        <p>"iconfont"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。</p>
+        </blockquote>
+    </div>
+
+
+</body>
+</html>

Plik diff jest za duży
+ 71 - 0
src/wzbapi/templates/static/iconfont/iconfont.css


BIN
src/wzbapi/templates/static/iconfont/iconfont.eot


Plik diff jest za duży
+ 1 - 0
src/wzbapi/templates/static/iconfont/iconfont.js


Plik diff jest za duży
+ 114 - 0
src/wzbapi/templates/static/iconfont/iconfont.svg


BIN
src/wzbapi/templates/static/iconfont/iconfont.ttf


BIN
src/wzbapi/templates/static/iconfont/iconfont.woff


+ 173 - 0
src/wzbapi/templates/static/index.css

@@ -0,0 +1,173 @@
+/*左侧图片缩略图*/
+#imgsview{
+    width:15%;
+    float: left;
+    text-align:center;
+    background:#F8F8F8;
+}
+#imgsview img{
+
+    margin-top: 20px;
+}
+.active_green{
+    background: #0DD5B2;
+}
+.active_green_border{
+    border:2px solid #0DD5B2;
+}
+/*切割快捷工具*/
+.paint_menu{
+    /*border:1px solid red;*/
+    height: 48px;
+    line-height: 48px;
+    position: fixed;
+    z-index: 100;
+    background: white;
+    width: 64%;
+}
+.paint_menu button{
+    width:60px;
+    height:48px;
+    padding:0px!important;
+    margin:0px;
+    border-width:0px!important;
+    /*background-color:white!important;*/
+    float: left;
+}
+.paint_menu i{
+    color:#A5AAB2;
+    font-size: 28px;
+}
+.active_paint{
+    background-color:#0DD5B2!important;
+}
+/*切图激活状态*/
+.cut_imgview_active{
+    background: #0DD5B2!important;
+    border:2px solid #0DD5B2!important;
+}
+.forward_point{
+    /*background: #0DD5B2!important;*/
+    /*height: 35px;*/
+    margin-top:30px;
+    position: relative;
+    margin-bottom: 450px;
+}
+/*图片展示libox*/
+.cut_img_box_li{
+    position: relative;
+    box-shadow:-3px 3px 3px #888888;
+    margin-top:35px;
+    position:relative;
+    border:1px solid #ccc;
+}
+/*切割图片预览*/
+.cut_imgview{
+    width: 100%;
+    margin: auto;
+    margin-bottom:3px;
+    /*position:absolute;*/
+    position: relative;
+}
+.del_li{
+    position: absolute;
+    top:-23px;
+    left: 92%;
+    font-size: 22px!important;
+    display: none;
+    z-index:200;
+}
+.del_cut_imgview{
+    position: absolute;
+    bottom: -3px;
+    left: 92%;
+    font-size: 20px!important;
+    display: none;
+    z-index:200;
+}
+.toolkit_active{
+    background-color:#0DD5B2;
+}
+.clean_ul{
+    list-style: none;
+    padding:0px;
+    margin: 0px;
+    /*margin-top:35px;*/
+}
+.cailiao_clean_ul{
+    list-style: none;
+    padding:0px;
+    margin: 0px;
+    /*margin-top:35px;*/
+}
+/*小题题号*/
+.subqueinput{
+    width:25px;
+    position:absolute;
+    top:0px;
+    left:-1px;
+    border:0px;
+    color: white;
+    text-align: center;
+    background: black;
+    height: 10px;
+}
+/*大题号*/
+.quenoinput{
+    width:40px;
+    position:absolute;
+    top:-21px;
+    left:-1px;
+}
+/*放大预览*/
+.imgzoom{
+    position:absolute;
+    width:100%;
+    right:213%;
+    index:1000;
+    transform:scale(3.1);
+    border:1px solid #666666;
+}
+.cailiao_num{
+    width:80px;
+    position:absolute;
+    top:-21px;
+    left:60%;
+}
+/*保存下一步*/
+.handle_btn{
+    float: right!important;
+    /*margin-right:20px!important;*/
+    width: 150px!important;
+}
+
+.btn{
+    display:block;
+    width:85%;
+    height:35px;
+    /*background:#0DD5B2;    */
+    margin-top:5px;
+}
+.btn_active{
+    background:#0DD5B2;
+}
+
+/*横条样式*/  
+input[type=range] {  
+    -webkit-appearance: none;/*清除系统默认样式*/  
+    width: 95%;  
+    background: -webkit-linear-gradient(#61bd12, #61bd12) no-repeat, #ddd;/*设置左边颜色为#61bd12,右边颜色为#ddd*/  
+    /*background-size: 75% 100%;/*设置左右宽度比例*/  
+    height: 3px;/*横条的高度*/  
+    vertical-align: middle;
+    outline:0px;
+}  
+/*拖动块的样式*/  
+input[type=range]::-webkit-slider-thumb {  
+    -webkit-appearance: none;/*清除系统默认样式*/  
+    height: 20px;/*拖动块高度*/  
+    width: 20px;/*拖动块宽度*/  
+    background: #fff;/*拖动块背景*/  
+    border-radius: 50%; /*外观设置为圆形*/  
+    border: solid 1px #ddd; /*设置边框*/  
+}  

+ 718 - 0
src/wzbapi/templates/static/index.js

@@ -0,0 +1,718 @@
+$(document).ready(function(){
+    //var imgsrc = "media/1517533995690XZB2018RJYYB01021_1.jpg";
+    var imgsrc = $(".imgsview img:first").attr("src");
+    var canvasWidth = $(".imgsview img:first").get(0).naturalWidth/3;
+    var canvasHeight = $(".imgsview img:first").get(0).naturalHeight/3;
+    //alert(canvasWidth);
+    //alert(canvasHeight);
+    $("#pureCanvas").attr("data-width");
+    $("#pureCanvas").attr("data-height");
+    //检测按键
+    var keyCode = null;
+    var cailiao_flag = false;
+    //document.onkeydown=function(event){
+    //    var e = event || window.event || arguments.callee.caller.arguments[0];
+    //    keyCode = e.keyCode;
+    //}
+    //document.onkeyup=function(event){
+    //    var e = event || window.event || arguments.callee.caller.arguments[0];
+    //    keyCode = null;
+    //}
+
+    document.addEventListener("keydown",function(event){
+        var e = event || window.event || arguments.callee.caller.arguments[0];
+        keyCode = e.keyCode;
+    });
+    document.addEventListener("keyup",function(event){
+        var e = event || window.event || arguments.callee.caller.arguments[0];
+        keyCode = e.keyCode;
+        keyCode = null;
+    });
+
+    // 切割出的图片可切割
+    $("#paperpiecesul").sortable();
+    // $(".clean_ul").each(function(){
+    //     $(this).sortable();
+    // });
+    //放大缩小滑块
+    $( "#slider" ).slider();
+    
+
+    function initCanvas(){
+        //实例化canvas
+        $("#pureCanvas").pureCanvas('setting', 'backgroundImage', {
+            width:canvasWidth,
+            height:canvasHeight,
+            imageSrc: imgsrc,
+            callback: function(imageInfo){
+                var data = imageInfo;
+                data.eventType = 'bg';
+            }
+        });
+        $("#pureCanvas").pureCanvas('Rectangle', 'type', 'Rectangle');
+    }
+    initCanvas();
+
+    //$("#pureCanvas").pureCanvas('Rectangle', 'type', 'Rectangle');
+
+
+    function getImgData(_cropCanvas,x,y,x1,y1){
+        //var dataImg = bb.getImageData(x,y,x1-x,y1-y)
+        var bb = _cropCanvas.getContext('2d');
+        var dataImg = bb.getImageData(50,50,500,300)
+        console.log(dataImg)
+        // 将图像放回画布
+        var canvas2 = document.createElement("canvas")
+        canvas2.width = 500;
+        canvas2.height = 300;
+        var ctx2 = canvas2.getContext("2d")
+
+        ctx2.putImageData(dataImg,0,0,0,0,canvas2.width,canvas2.height);
+
+        // 试卷url
+        var imgurl = canvas2.toDataURL("image/jpeg", 1)
+        imgtmp = document.createElement("img");
+        imgtmp.setAttribute('src',imgurl);
+        document.getElementById("imgsview").append(imgtmp);
+    }
+    //图像裁剪
+    function crop(imgsrc,x,y,x1,y1){
+        x = parseInt(x)*6.37;
+        y = parseInt(y)*6.37;
+        x1 = parseInt(x1)*6.37;
+        y1 = parseInt(y1)*6.37;
+        
+        if(!imgsrc){return;}
+        var img = new Image;
+	    
+        img.setAttribute("crossOrigin",'anonymous');
+        img.src = imgsrc;
+        var _cropCanvas = document.createElement('canvas');
+        _cropCanvas.width = img.width;
+        _cropCanvas.height = img.height;
+        var ctx = _cropCanvas.getContext('2d');
+        img.onload = function () {  
+            ctx.drawImage(img,0,0,img.width,img.height);
+            var dataImg = ctx.getImageData(x,y,x1-x,y1-y)
+            console.log(dataImg)
+            // 将图像放回画布
+            var canvas2 = document.createElement("canvas")
+            canvas2.width = x1-x;
+            canvas2.height = y1-y;
+            var ctx2 = canvas2.getContext("2d")
+
+            ctx2.putImageData(dataImg,0,0,0,0,canvas2.width,canvas2.height);
+            // 试卷url
+            var imgurl = canvas2.toDataURL("image/jpeg", 1)
+            imgtmp = document.createElement("img");
+            imgtmp.setAttribute('src',imgurl);
+            imgtmp.setAttribute('width','100%');
+            document.getElementById("imgsview").append(imgtmp);
+        }
+    }
+
+    // 快捷工具条切换
+    $("[data-pure-canvas-option]").on('click input change', function(e){
+        var $this = $(this);
+        
+        if($this.attr('type')  == 'file'  && !$this.val()){
+            return;
+        }
+        
+        var optionName = $this.attr('data-pure-canvas-option');
+        var optionType = $this.attr('data-pure-canvas-type');
+        
+        var value;
+        if($this.attr('data-pure-canvas-value') == 'rate'){
+            value = {'type': 'rate', 'rateVal': $this.val()};
+        }
+        else if(optionType == 'type' || $this.attr('data-pure-canvas-value')){
+            value = $this.attr('data-pure-canvas-value');
+        }
+        else if(optionType == 'backgroundImage'){
+            value = {
+                    width:canvasWidth,
+                    height:canvasHeight,
+                    imageSrc: $this.prev().val(),
+                callback: function(imageInfo){
+                    var data = imageInfo;
+                    data.eventType = 'bg';
+                    
+                    PureWebSocket.send(data);
+                }
+            }
+        }
+        else{
+            value = $this.val();
+        }
+        $("#pureCanvas").pureCanvas(optionName, optionType, value);
+        
+    });
+    
+    //切换背景图
+    $("#imgsview img").on('click input change', function(e){
+        var $this = $(this);
+        
+        if($this.attr('type')  == 'file'  && !$this.val()){
+            return;
+        }
+        
+        var optionName = $this.attr('data-pure-canvas-option');
+        var optionType = $this.attr('data-pure-canvas-type');
+        
+        var value;
+        if($this.attr('data-pure-canvas-value') == 'rate'){
+            value = {'type': 'rate', 'rateVal': $this.val()};
+        }
+        else if(optionType == 'type' || $this.attr('data-pure-canvas-value')){
+            value = $this.attr('data-pure-canvas-value');
+        }
+        else if(optionType == 'backgroundImage'){
+            value = {
+                    width:canvasWidth,
+                    height:canvasHeight,
+                    imageSrc: $this.attr("src"),
+                    callback: function(imageInfo){
+                        var data = imageInfo;
+                        data.eventType = 'bg';
+                        
+                        // PureWebSocket.send(data);
+                    }
+            }
+        }
+        else{
+            value = $this.val();
+        }
+        $("#pureCanvas").pureCanvas(optionName, optionType, value);
+        imgsrc = $this.attr("src");
+    });
+
+
+    //获取画矩形结果
+    $("#pureCanvas").on('complate.draw.pureCanvas', function(e){
+        var data = e.drawData;
+        var point = data.points.split(",")[0].split(" ").concat(data.points.split(",")[1].split(" "));
+        console.log(point);
+        var timeStamp = e.timeStamp;
+        var src = imgsrc;
+
+        // 切割单题
+        var _this = $("#paperpieces .cut_imgview_active");
+        var point_site = check_point_site();
+
+        // 
+        var toolkit_type = get_toolkit_type();
+        // 单题切割
+        console.log(keyCode);
+        if(toolkit_type=='danti'){
+            var imgviewer = cut_single(src,point);
+
+            //如果cailiao_flag 且上一题有材料
+            if(cailiao_flag&&_this.prev(".cut_img_box_li").find(".cailiao_clean_ul").length){
+               //_this.prev(".cut_img_box_li").find(".cailiao_clean_ul").clone().insertBefore(_this.find(".clean_ul")); 
+               //_this.prev(".cut_img_box_li").find(".cailiao_num").clone().insertBefore(_this.find(".clean_ul")); 
+
+               _this.prev(".cut_img_box_li").find(".cailiao_clean_ul").clone().insertBefore(imgviewer.find(".clean_ul")); 
+               _this.prev(".cut_img_box_li").find(".cailiao_num").clone().insertBefore(imgviewer.find(".clean_ul")); 
+            }
+
+            // 
+            if(keyCode==17){
+                // 如果当前激活状态在最后一位则转移指针特性位置
+                if($(_this).hasClass("forward_point")){
+                    $(_this).removeClass("forward_point");
+                    if($("#paperpieces .forward_point").length==0){
+                        $(_this).after(gen_forward_point());
+                        // 移动指针
+                        change_forward_point();
+                    }
+                }
+                if($(_this).find(".cut_imgview").length<1){
+                    $(_this).html(imgviewer.html());
+                }else{
+                    $(_this).find(".clean_ul").append($(imgviewer).find(".cut_imgview"));
+                }
+
+            }else{
+                // 移动指针
+                change_forward_point();
+                // 指针在结尾
+                if($(_this).hasClass("forward_point")){
+                    $(".forward_point").before(imgviewer);
+                    // 滚动条滚动
+                    $("#paperpieces").scrollTop($("#paperpieces")[0].scrollHeight);
+
+                }else{
+                    imgviewer.find("input").attr("value",_this.find("input").val());
+                    _this.html(imgviewer.html());
+                    
+                }
+                
+
+            }
+        // 切小题
+        }else if(toolkit_type=='xiaoti'){
+            var imgviewer = cut_mul_li(src,point);
+
+            //如果cailiao_flag 且上一题有材料
+            if(cailiao_flag&&_this.prev(".cut_img_box_li").find(".cailiao_clean_ul").length){
+               //_this.prev(".cut_img_box_li").find(".cailiao_clean_ul").clone().insertBefore(_this.find(".clean_ul")); 
+               //_this.prev(".cut_img_box_li").find(".cailiao_num").clone().insertBefore(_this.find(".clean_ul")); 
+
+                if(!_this.find(".cailiao_clean_ul").length){
+                   _this.prev(".cut_img_box_li").find(".cailiao_clean_ul").clone().insertBefore(imgviewer.find(".clean_ul")); 
+                   _this.prev(".cut_img_box_li").find(".cailiao_num").clone().insertBefore(imgviewer.find(".clean_ul")); 
+                }
+            }
+
+            //抛弃
+            if(keyCode==100){
+                // 如果当前激活状态在最后一位则转移指针特性位置
+                if($(_this).hasClass("forward_point")){
+                    $(_this).removeClass("forward_point");
+                    if($("#paperpieces .forward_point").length==0){
+                        $(_this).after(gen_forward_point());
+                    }
+                }
+                // 
+                if($(_this).find(".cut_imgview").length<1){
+                    $(_this).html(imgviewer.html());
+                }else{
+                    $(_this).append($(imgviewer).find(".cut_imgview"));
+                }
+
+            }else{
+                // 移动指针
+                change_forward_point();
+                // 指针在结尾
+                if($(_this).hasClass("forward_point")){
+                    $(imgviewer).addClass("cut_imgview_active");
+                    $(".forward_point").before(imgviewer);
+                    $(_this).removeClass("cut_imgview_active");
+                    // 滚动条滚动
+                    $("#paperpieces").scrollTop($("#paperpieces")[0].scrollHeight);
+
+                }else{
+                    // imgviewer.find("input").attr("value",_this.find("input").val());
+                    // _this.html(imgviewer.html());
+                    if(_this.find(".clean_ul").length){
+                        //如果原来是单题全覆盖如果是小题则增加
+                        if(_this.find(".clean_ul").find(".subqueinput").length){
+                            _this.find(".clean_ul").append(imgviewer.find(".cut_imgview"));
+                        }else{
+                            _this.find(".clean_ul").remove();
+                            _this.append(imgviewer.find(".clean_ul"));
+                        }
+                        //改成全覆盖
+                        //_this.append(imgviewer.find(".clean_ul"));
+                    }else{
+                        _this.append(imgviewer.find(".clean_ul"));
+                    }
+                    
+                }
+                
+
+            }
+        // 切材料
+        }else{
+            var imgviewer = cut_cailiao_li(src,point);
+            // 移动指针
+            change_forward_point();
+
+            // 指针在最后
+            if($(_this).hasClass("forward_point")){
+                $(imgviewer).addClass("cut_imgview_active");
+                $(_this).removeClass("cut_imgview_active");
+                // 
+                if(_this.find(".cailiao_clean_ul").length){
+                    _this.find(".cailiao_clean_ul").append(imgviewer.find(".cut_imgview"));
+                }else{
+                    $(".forward_point").before(imgviewer);
+                }
+            }else{
+                //已存在切割好的题目
+                if(_this.find(".clean_ul").length){
+                    // 
+                    if(_this.find(".cailiao_clean_ul").length){
+                        _this.find(".cailiao_clean_ul").append(imgviewer.find(".cut_imgview"));
+                    }else{
+                        imgviewer.find(".cailiao_clean_ul").insertBefore(_this.find(".clean_ul"));
+                    }
+                    // 添加材料提示
+                    var cailiao_num = _this.find(".cailiao_clean_ul .cut_imgview").length;
+                    if(_this.find(".cailiao_num").length){
+                        _this.find(".cailiao_num").text("第"+cailiao_num+"张材料");
+                    }else{
+                        _this.append(gen_cailiao_num(cailiao_num));
+                    }
+                    
+                }else{
+                    // 
+                    if(_this.find(".cailiao_clean_ul").length){
+                        _this.find(".cailiao_clean_ul").append(imgviewer.find(".cut_imgview"));
+                    }else{
+                        _this.append(imgviewer);
+                    }
+                }
+
+            }
+            // 
+        }
+
+        //添加hover事件
+        add_hover();
+        //添加点击激活事件
+        active_cut_img(imgviewer);
+
+    });
+    //
+    //去除多余的canvas
+    $("canvas:eq(1)").remove();
+    $("canvas:eq(1)").remove();
+
+
+    function check_point_site(){
+        var _this = $("#paperpieces .cut_imgview_active");
+        var point_site = _this.index()+1;
+        return point_site;
+    }
+    //删除操作
+    function del_myself(_this){
+        $(_this).remove();
+    }
+
+    // 切割操作
+    // 单题切割
+    function cut_single(src,point){
+        // var imgtmp = gen_single_li(src,point);
+        var imgtmp = gen_danti(src,point);
+        return $(imgtmp)
+    }
+
+    // 生成定位指针
+    function gen_forward_point(){
+        var tmp_div = document.createElement("div");
+        var value = $("#paperpieces li").length+1;
+        var htmlstr = '<li class="forward_point cut_img_box_li"><input type="text" style="width:40px;" value='+value+' /></li>';
+        $(tmp_div).html(htmlstr);
+        return $(tmp_div).find(".forward_point");
+    }
+
+    //单题目li生成
+    function gen_single_li(src,point){
+        
+        var imgtmp = document.createElement("li");
+        $(imgtmp).addClass("cut_img_box_li");
+        var sub_html = gen_cut_imgview(src,point);
+        imgtmp.innerHTML=sub_html;
+        
+        return imgtmp;
+    }
+    // 切材料
+    function cut_cailiao_li(src,point){
+        // 大题号计算
+        var queno = $("#paperpieces .cut_img_box_li").length;
+        var tmpli = document.createElement("li");
+        $(tmpli).addClass("cut_img_box_li");
+        $(tmpli).append('<input type="text" class="quenoinput" value='+queno+' />');
+        $(tmpli).append('<span type="text" class="cailiao_num">'+'第1张材料'+'</span>');
+        var imgtmp = document.createElement("ul");
+        // $(imgtmp).addClass("cut_img_box_li");
+        $(imgtmp).addClass("cailiao_clean_ul");
+        var sub_html = gen_cailiao_li(src,point);
+        console.log(sub_html);
+        imgtmp.innerHTML=sub_html;
+        $(tmpli).append($(imgtmp));
+        console.log($(tmpli).html());
+        return $(tmpli);
+    }
+
+    // 生成材料提示
+    function gen_cailiao_num(num){
+        var tmp = document.createElement("div");
+        $(tmp).append('<span type="text" class="cailiao_num">第'+num+'张材料</span>');
+        return $(tmp).html();
+    }
+
+    // 生成材料预览
+    function gen_cailiao_li(src,point){
+        // var src="media/1517533995690XZB2018RJYYB01021_1.jpg";
+        var subqueno = 1;
+        // 
+        var _this = $("#paperpieces .cut_imgview_active");
+        var subqueno_num = _this.find(".cailiao_clean_ul").find(".cut_imgview").length;
+        if(keyCode==17){
+            var subqueno = 1;
+            if(subqueno_num<1){
+                subqueno = subqueno_num+1;
+            }else{
+                subqueno = parseInt(_this.find(".cailiao_clean_ul").find(".cut_imgview:last").find(".subqueinput").val());
+            }
+        }else{
+            var subqueno = 1;
+            if(subqueno_num<1){
+                subqueno = subqueno_num+1;
+            }else{
+                subqueno = parseInt(_this.find(".cailiao_clean_ul").find(".cut_imgview:last").find("input").val())+1;
+            }
+        }
+        // 
+        var width = point[2]-point[0];
+        var viewWidth=$('#paperpiecesul li:first').width();
+        var widthRate=viewWidth/width;
+        var background_position =(-point[0]*widthRate)+'px ' +(-point[1]*widthRate)+'px';
+        var rate =(point[3]-point[1])/(point[2]-point[0]);
+        // 子题号html
+        var tmp_ul = document.createElement("ul");
+        $(tmp_ul).addClass("clean_ul");
+        // 
+        // var sub_html = '<input type="text" style="width:40px;position:absolute;top:-21px;left:-1px;" value='+queno+' />';
+        var page = $("#imgsview").find(".active_green_border").attr("data-page");
+        var sub_html = '<li class="cut_imgview" data-point="'+point.join(',')+'" data-page='+page+' data-image-type=1><input type="text" class="subqueinput" value="'+subqueno+'"/>';
+        sub_html += '<i class="icon iconfont icon-shanchu1 del_cut_imgview"></i></li>';
+        $(tmp_ul).html(sub_html);
+        $(tmp_ul).find(".cut_imgview").attr('style','height:'+rate*20+'vw;background-image:url("'+src+'");background-position:'+background_position+';background-size:'+(canvasWidth*widthRate*1.01)+'px;');
+        return $(tmp_ul).html();
+    }
+
+    // 切小题
+    function cut_mul_li(src,point){
+        // 大题号计算
+        var queno = $("#paperpieces .cut_img_box_li").length;
+        var tmpli = document.createElement("li");
+        $(tmpli).addClass("cut_img_box_li");
+        $(tmpli).append('<input type="text" class="quenoinput" value='+queno+' />');
+        $(tmpli).append('<i class="icon iconfont icon-shanchu del_li"></i>');
+        var imgtmp = document.createElement("ul");
+        // $(imgtmp).addClass("cut_img_box_li");
+        $(imgtmp).addClass("clean_ul");
+        var sub_html = gen_cut_subque(src,point);
+        console.log(sub_html);
+        imgtmp.innerHTML=sub_html;
+        $(tmpli).append($(imgtmp));
+        return $(tmpli);
+    }
+
+    // 图片查看div单题
+    function gen_cut_imgview(src,point){
+        //裁剪
+        // var src="media/1517533995690XZB2018RJYYB01021_1.jpg";
+        var width = point[2]-point[0];
+        var viewWidth=$('#paperpiecesul li:first').width();
+        var widthRate=viewWidth/width;
+        var background_position =(-point[0]*widthRate)+'px ' +(-point[1]*widthRate)+'px';
+        var rate =(point[3]-point[1])/(point[2]-point[0]);
+        // 
+        var tmp_div = document.createElement("div");
+        var queno = $('#paperpiecesul li').length;
+        var sub_html = '<input type="text" style="width:40px;position:absolute;top:-21px;left:-1px;" value='+queno+' />';
+        sub_html += '<i class="icon iconfont icon-shanchu del_li"></i>';
+        sub_html += '<div class="cut_imgview"><i class="icon iconfont icon-shanchu1 del_cut_imgview"></i></div>';
+        $(tmp_div).html(sub_html);
+        $(tmp_div).find(".cut_imgview").attr('style','height:'+rate*20+'vw;background-image:url("'+src+'");background-position:'+background_position+';background-size:'+(canvasWidth*widthRate*1.01)+'px;');
+        return $(tmp_div).html();
+    }
+
+    // 生成单题
+    function gen_danti(src,point){
+        // 大题号计算
+        var queno = $("#paperpieces .cut_img_box_li").length;
+        var tmpli = document.createElement("li");
+        $(tmpli).addClass("cut_img_box_li");
+        $(tmpli).append('<input type="text" class="quenoinput" value='+queno+' />');
+        $(tmpli).append('<i class="icon iconfont icon-shanchu del_li"></i>');
+        var imgtmp = document.createElement("ul");
+        // $(imgtmp).addClass("cut_img_box_li");
+        $(imgtmp).addClass("clean_ul");
+        var sub_html = gen_cut_subque(src,point,true);
+        console.log(sub_html);
+        imgtmp.innerHTML=sub_html;
+        $(tmpli).append($(imgtmp));
+        return $(tmpli);
+    }
+
+    function gen_cut_subque(src,point,flag){
+        // 计算子题号
+        
+        // 当前所属题
+        var _this = $("#paperpieces .cut_imgview_active");
+        var subqueno_num = _this.find(".clean_ul").find(".cut_imgview").find(".subqueinput").length;
+        if(keyCode==17){
+            var subqueno = 1;
+            if(subqueno_num<1){
+                subqueno = subqueno_num+1;
+            }else{
+                subqueno = parseInt(_this.find(".cut_imgview:last").find("input").val());
+            }
+        }else{
+            var subqueno = 1;
+            if(subqueno_num<1){
+                subqueno = subqueno_num+1;
+            }else{
+                subqueno = parseInt(_this.find(".cut_imgview:last").find("input").val())+1;
+            }
+        }
+        // var src="media/1517533995690XZB2018RJYYB01021_1.jpg";
+        var width = point[2]-point[0];
+        var viewWidth=$('#paperpiecesul li:first').width();
+        var widthRate=viewWidth/width;
+        var background_position =(-point[0]*widthRate)+'px ' +(-point[1]*widthRate)+'px';
+        var rate =(point[3]-point[1])/(point[2]-point[0]);
+        // 子题号html
+        var tmp_ul = document.createElement("ul");
+        $(tmp_ul).addClass("clean_ul");
+        // 
+        if(flag){
+            var page = $("#imgsview").find(".active_green_border").attr("data-page");
+            var sub_html = '<li class="cut_imgview" data-point="'+point.join(',')+'" data-page='+page+' data-image-type=0>';
+        }else{
+            var page = $("#imgsview").find(".active_green_border").attr("data-page");
+            var sub_html = '<li class="cut_imgview" data-point="'+point.join(',')+'" data-page='+page+' data-image-type=0><input type="text" class="subqueinput" value="'+subqueno+'"/>';
+        }
+        // 
+        sub_html += '<i class="icon iconfont icon-shanchu1 del_cut_imgview" ></i></li>';
+        $(tmp_ul).html(sub_html);
+        $(tmp_ul).find(".cut_imgview").attr('style','height:'+rate*20+'vw;background-image:url("'+src+'");background-position:'+background_position+';background-size:'+(canvasWidth*widthRate*1.01)+'px;');
+        return $(tmp_ul).html();
+    }
+
+    //已切割图片的hover效果
+    function add_hover(targetimg){
+        $(".cut_imgview").hover(function(index){
+            $(this).css("cursor","pointer");
+            $("#paperpieces").append('<div class="imgzoom"></div>');
+            var style=$(this).attr("style");
+            var top = $(this).offset().top;
+            $('.imgzoom').attr("style",style);
+            $('.imgzoom').css("top",top);
+        },function(){
+            $('.imgzoom').remove();
+        });
+    }
+    // 已切割图片添加点击切换激活状态
+    function active_cut_img(targetimg){
+        $("#paperpieces").on("click",".cut_img_box_li",function(){
+            $(this).addClass("cut_imgview_active");
+            $(this).siblings().removeClass("cut_imgview_active");
+            $(".forward_point").css("background",null);
+
+            // 
+            $(".del_li").hide();
+            $(".del_cut_imgview").hide();
+            $(this).find(".del_li").show();
+            $(this).find(".del_cut_imgview").show();
+        });
+    }
+
+    //当按住ctrl键时寻找当前处于激活状态的切图插入新的切图
+    function insert_merge(){
+        var cur_cut_img = $("#paperpieces[class='cut_imgview_active']");
+    }
+    // 改变指针位置
+    function change_forward_point(){
+        if($("#paperpieces .cut_imgview_active").hasClass("forward_point")){
+            var _this = $(".forward_point")
+            var prev_img = _this.prev();
+            if(prev_img.length>0){
+                var point_value = parseInt(_this.find("input").val())+1;
+                console.log(point_value);
+                _this.find("input").val(point_value);
+            }else{
+                _this.find("input").val(2);
+            }
+        }
+        
+    }
+    // 工具hover事件
+    $("#purePallete").find("button:lt(3)").each(function(){
+        $(this).click(function(){
+            $(this).addClass("toolkit_active");
+            $(this).siblings().removeClass("toolkit_active");
+            if($(this).attr("data-type")=="cailiao"){
+               cailiao_flag = true; 
+            }
+        });
+    });
+
+    // 获取切割工具
+    function get_toolkit_type(){
+        var type = $("#purePallete").find(".toolkit_active").attr("data-type");
+        return type;
+    }
+
+    $("#paperpieces").on("click",".cut_img_box_li",function(){
+        $(this).addClass("cut_imgview_active");
+        $(this).siblings().removeClass("cut_imgview_active");
+        $(".forward_point").css("background",null);
+
+        // 
+        $(".del_li").hide();
+        $(".del_cut_imgview").hide();
+        $(this).find(".del_li").show();
+        $(this).find(".del_cut_imgview").show();
+    });
+
+    $("#paperpieces").on("mouseover mouseout",".cut_imgview",function(event){
+        if(event.type=="mouseover"){
+            $(this).css("cursor","pointer");
+            $("#paperpieces").append('<div class="imgzoom"></div>');
+            var style=$(this).attr("style");
+            var top = $(this).offset().top;
+            $('.imgzoom').attr("style",style);
+            $('.imgzoom').css("top",top);
+        }else if(event.type=="mouseout"){
+            $('.imgzoom').remove();
+        }
+    });
+
+    //$("#paperpieces").on("mouseover mouseout",".cut_imgview",function(){
+    //    alert(22222222222222);     
+    //});
+
+    //删除图片
+    $('#paperpiecesul').on('click','.del_cut_imgview',function(){
+        $(this).parents('.cut_imgview').remove()
+        $('.imgzoom').remove()
+    })
+    //删除图片
+    $('#paperpiecesul').on('click','.del_li',function(){
+        $(this).parents('.cut_img_box_li').remove()
+        $('.imgzoom').remove()
+    })
+    //试卷图片切换
+    $('#imgsview img').each(function(){
+        $(this).click(function(index){
+            $(this).addClass("active_green_border");
+            $(this).siblings().removeClass("active_green_border");
+        });
+    });
+    //全屏
+    var openFullScreen = function() {
+        var e = document.documentElement;
+        if (e.requestFullscreen)
+            e.requestFullscreen();
+        else if (e.mozRequestFullScreen)
+            e.mozRequestFullScreen();
+        else if (e.webkitRequestFullScreen)
+            e.webkitRequestFullScreen();
+        else if ("undefined" != typeof window.ActiveXObject) {
+            var t = new ActiveXObject("WScript.Shell");
+            t && t.SendKeys("{F11}")
+        }
+    }
+    $(".icon-quanping").click(function(){
+        openFullScreen();     
+    });
+    //结束材料
+    $(".icon-msnui-poweroff").click(function(){
+        cailiao_flag = false;     
+    });
+    //给快捷工具栏添加hover事件
+    $(".paint_menu button").each(function(){
+        var _this = $(this);
+        $(this).hover(function(){
+            layer.tips(_this.attr("data-desc"),_this,{tips:1});
+        });     
+    });
+    
+});

Plik diff jest za duży
+ 2369 - 0
src/wzbapi/templates/static/jquery.pureCanvas.js


Plik diff jest za duży
+ 2 - 0
src/wzbapi/templates/static/layer/layer.js


Plik diff jest za duży
+ 2 - 0
src/wzbapi/templates/static/layer/mobile/layer.js


Plik diff jest za duży
+ 1 - 0
src/wzbapi/templates/static/layer/mobile/need/layer.css


BIN
src/wzbapi/templates/static/layer/theme/default/icon-ext.png


BIN
src/wzbapi/templates/static/layer/theme/default/icon.png


Plik diff jest za duży
+ 1 - 0
src/wzbapi/templates/static/layer/theme/default/layer.css


BIN
src/wzbapi/templates/static/layer/theme/default/loading-0.gif


BIN
src/wzbapi/templates/static/layer/theme/default/loading-1.gif


BIN
src/wzbapi/templates/static/layer/theme/default/loading-2.gif


+ 14 - 1
src/wzbapi/views.py

@@ -20,7 +20,6 @@ class DocView(cv.BaseView):
         """
         """
         """
         """
         modules = list(cm.OperationLogConfig.objects.order_by("order").values())
         modules = list(cm.OperationLogConfig.objects.order_by("order").values())
-        print modules
         apis = []
         apis = []
         for mo in modules:
         for mo in modules:
             docstr = None
             docstr = None
@@ -83,3 +82,17 @@ class HookView(cv.BaseView):
         cmdstr = "cd /mnt/gzyunweb/pc/gzyun_web & git pull origin master & cnpm run build"
         cmdstr = "cd /mnt/gzyunweb/pc/gzyun_web & git pull origin master & cnpm run build"
         os.system(cmdstr)
         os.system(cmdstr)
         return cv.to_suc()
         return cv.to_suc()
+
+
+class CanvasView(cv.BaseView):
+    def get(self,request):
+        """
+        """
+        ret = {}
+        paper = {
+            "title":u"第一课、空间几何体",
+            "paperno":u"XZBRJB10001",
+            "paperimgs":["/static/test1.jpg","/static/test1.jpg"]     
+        }
+        ret["paper"] = paper
+        return render(request,"canvas.html",ret)

BIN
static/upload/1627651115avatar.jpg


BIN
static/upload/1627651211696.jpg


BIN
static/upload/1627709312570.png


BIN
static/upload/1627709513870.png


BIN
static/upload/1627709639287.png


BIN
static/upload/1627709699418.png


BIN
static/upload/1627709710436.png


BIN
static/upload/1627709906546.png


BIN
static/upload/1627710028763.png


BIN
static/upload/1627710033814.png


BIN
static/upload/1627710066268.png


BIN
static/upload/1627711038264.png


BIN
static/upload/1627721412065.jpg


BIN
static/upload/1627721951930.jpg


BIN
static/upload/1627722019678.jpg


BIN
static/upload/1627735531wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.NK79UQIogbBj972864c4400d0d2cd6758af218cfa843.png


BIN
static/upload/1627735745wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.pMLTM9YqBb9M972864c4400d0d2cd6758af218cfa843.png


BIN
static/upload/1627735791wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.tgep9xOorenY972864c4400d0d2cd6758af218cfa843.png


BIN
static/upload/1627735838wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.H4S8cstZ2mKL972864c4400d0d2cd6758af218cfa843.png


BIN
static/upload/1627735895wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.wbe7bQn8ca4x4937eb3d39d8d2dea41120630a599ec4.png


BIN
static/upload/1627735965wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.8s834l54thAa972864c4400d0d2cd6758af218cfa843.png


BIN
static/upload/1627735996wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.pLDXb15gLr3r402382246a2065cee3c3007b24c5c58b.png


BIN
static/upload/1627736021wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.pYTgp6IyEMCe401b2930b2e029af60026d7086792265.png


BIN
static/upload/1627736104wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.162lsN5XrDQW972864c4400d0d2cd6758af218cfa843.png


BIN
static/upload/1627736115wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.H3oH0etdLBroe64d82b4c534154fd7dd596bf3b48923.png


BIN
static/upload/1627736248wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.Lqc3At7s75FJ972864c4400d0d2cd6758af218cfa843.png


BIN
static/upload/1627736254wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.6lUqK0btk8QCe64d82b4c534154fd7dd596bf3b48923.png


BIN
static/upload/1627736316wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.OdsMMx21C6Dw972864c4400d0d2cd6758af218cfa843.png


BIN
static/upload/1627736323wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.to9s9oFwBODHe64d82b4c534154fd7dd596bf3b48923.png


BIN
static/upload/1627736618wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.DMQkGT1NplCK972864c4400d0d2cd6758af218cfa843.png


BIN
static/upload/1627736701wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.RJ7uEnPuLTmBe64d82b4c534154fd7dd596bf3b48923.png


BIN
static/upload/1627736971wx2938132b773c7b5a.o6zAJs6ak3UlDDc6i7VvXIk4HK98.JLyn4C4BtJYc972864c4400d0d2cd6758af218cfa843.png


BIN
static/upload/1627737199tmp_d9b8dff98c757f955c00483b4e61ec43.jpg


BIN
static/upload/1627775046644.jpg


BIN
static/upload/1627776851436.jpg


BIN
static/upload/1627776945261.jpg


BIN
static/upload/1627777070703.jpg


BIN
static/upload/1627777192640.jpg


BIN
static/upload/1627777303573.jpg


BIN
static/upload/1627777473334.jpg


BIN
static/upload/1627777516142.jpg


BIN
static/upload/1627777705009.jpg


BIN
static/upload/1627778327562.jpg


BIN
static/upload/1627778849040.jpg


BIN
static/upload/1627778946208.jpg


BIN
static/upload/1627779063259.jpg


BIN
static/upload/1627779182578.jpg


BIN
static/upload/1627779337782.jpg


+ 0 - 0
static/upload/1627780708202.jpg


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików