Gogs 3 vuotta sitten
vanhempi
commit
8bd15e9203

+ 5 - 0
src/common/common_control.py

@@ -67,6 +67,7 @@ def no_cache(key="*"):
     def _wrapper(func):
     def _wrapper(func):
         def __wrapper(*args,**kwargs):
         def __wrapper(*args,**kwargs):
             res = func(*args,**kwargs)
             res = func(*args,**kwargs)
+            print 999999999999999
             print cache.delete_pattern("cdata_{}*".format(key))
             print cache.delete_pattern("cdata_{}*".format(key))
             return res
             return res
         return __wrapper
         return __wrapper
@@ -83,6 +84,10 @@ def no_cache_list(keys=[]):
         return __wrapper
         return __wrapper
     return _wrapper
     return _wrapper
 
 
+def del_cache(key):
+    """
+    """
+    print cache.delete(key)
 
 
 def get_page_qset(qset,page,page_size=20):
 def get_page_qset(qset,page,page_size=20):
     """
     """

+ 100 - 0
src/common/models.py

@@ -16,6 +16,13 @@ class UserInfo(models.Model):
 
 
     is_bind = models.SmallIntegerField(u"是否绑定",default=0)
     is_bind = models.SmallIntegerField(u"是否绑定",default=0)
     utype = models.SmallIntegerField(u"是否激活可用",default=0)
     utype = models.SmallIntegerField(u"是否激活可用",default=0)
+    zq = models.CharField(u"周期", max_length=255, blank=True, null=True)
+    cw = models.CharField(u"仓位", max_length=255, blank=True, null=True)
+    df = models.CharField(u"打法", max_length=255, blank=True, null=True)
+    pz = models.CharField(u"品种", max_length=255, blank=True, null=True)
+    account_img = models.TextField(u"账号截图", max_length=255, blank=True, null=True)
+    join_time = models.CharField(u"入市时间", max_length=255, blank=True, null=True)
+    badge = models.CharField(u"选手标识", max_length=255,blank=False,null=False,default=u"选手")
 
 
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
 
 
@@ -45,6 +52,7 @@ class Player(models.Model):
     match_group = models.CharField(u"比赛分组", max_length=255,blank=True,null=True)
     match_group = models.CharField(u"比赛分组", max_length=255,blank=True,null=True)
     fund = models.FloatField(u"资金",blank=True,null=True)
     fund = models.FloatField(u"资金",blank=True,null=True)
     match_status = models.SmallIntegerField(u"比赛状态,退赛/暂停/比赛中-1/0/1",default=0)
     match_status = models.SmallIntegerField(u"比赛状态,退赛/暂停/比赛中-1/0/1",default=0)
+    badge = models.CharField(u"选手标识", max_length=255,blank=False,null=False,default=u"选手")
 
 
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
 
 
@@ -83,6 +91,13 @@ class PlayerRecord(models.Model):
     yesterday_is_markt = models.SmallIntegerField(u"昨日是否开超市",default=0)
     yesterday_is_markt = models.SmallIntegerField(u"昨日是否开超市",default=0)
     auto_complete = models.SmallIntegerField(u"请假次数",default=0)
     auto_complete = models.SmallIntegerField(u"请假次数",default=0)
     yesterday_auto_complete = models.SmallIntegerField(u"请假次数",default=0)
     yesterday_auto_complete = models.SmallIntegerField(u"请假次数",default=0)
+    wanzhu_comment = models.TextField(u"点评",blank=True,null=True)
+    experience = models.TextField(u"操盘总结",blank=True,null=True)
+    zq = models.CharField(u"周期", max_length=255, blank=True, null=True)
+    cw = models.CharField(u"仓位", max_length=255, blank=True, null=True)
+    df = models.CharField(u"打法", max_length=255, blank=True, null=True)
+    pz = models.CharField(u"品种", max_length=255, blank=True, null=True)
+    badge = models.CharField(u"选手标识", max_length=255,blank=False,null=False,default=u"选手")
 
 
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
 
 
@@ -137,6 +152,9 @@ class Stock(models.Model):
     """
     """
     name = models.CharField(u"名称", max_length=255, blank=True,null=True)
     name = models.CharField(u"名称", max_length=255, blank=True,null=True)
     code = models.CharField(u"代码", max_length=255, blank=True,null=True)
     code = models.CharField(u"代码", max_length=255, blank=True,null=True)
+    img = models.TextField(u"封面图",blank=True,null=True)                       
+    desc = models.TextField(u"内容",blank=True,null=True)                       
+    user_num = models.IntegerField(u"排序字段",blank=False,null=False,default=0)
 
 
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
     ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
 
 
@@ -215,6 +233,8 @@ class OperationLog(models.Model):
 class Article(models.Model):                                                       
 class Article(models.Model):                                                       
     # 基础属性                                                                     
     # 基础属性                                                                     
     name = models.CharField(u"标题", max_length=255, blank=True,null=True)         
     name = models.CharField(u"标题", max_length=255, blank=True,null=True)         
+    type = models.CharField(u"类型", max_length=255, blank=True,null=True)         
+    img = models.TextField(u"封面图",blank=True,null=True)                       
     content = models.TextField(u"内容",blank=True,null=True)                       
     content = models.TextField(u"内容",blank=True,null=True)                       
     status = models.SmallIntegerField(u"下线/上线/编辑中-1/2/1",default=1)
     status = models.SmallIntegerField(u"下线/上线/编辑中-1/2/1",default=1)
                                                                                    
                                                                                    
@@ -237,3 +257,83 @@ class test(models.Model):
         db_table = "test"                                                       
         db_table = "test"                                                       
         verbose_name = u"测试表"                                                 
         verbose_name = u"测试表"                                                 
         app_label = "common"                                                                                                                                                                                                                                                  
         app_label = "common"                                                                                                                                                                                                                                                  
+
+class UserFollows(models.Model):
+    """用户关注表
+    """
+    user_id = models.IntegerField(u"选手id", blank=True,null=True)
+    follow_id = models.IntegerField(u"被关注选手id", blank=True,null=True)
+
+    ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
+
+    class Meta:
+        db_table = "user_follows"
+        verbose_name = u"用户关注表"
+        app_label = "common"
+
+    def __str__(self):
+        return u"{}){}".format(self.id, self.user_id)
+
+
+class UserStock(models.Model):
+    """选手持股情况
+    """
+    player_id = models.IntegerField(u"选手id", blank=True,null=True)
+    stock_id = models.IntegerField(u"股票id", blank=True,null=True)
+    stock_date = models.CharField(u"持股日期", max_length=255,blank=True,null=True)
+
+    ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
+
+    class Meta:
+        db_table = "user_stock"
+        verbose_name = u"选手持股"
+        app_label = "common"
+
+    def __str__(self):
+        return u"{}){}".format(self.id, self.username)
+
+
+class WinDefendRank(models.Model):
+    """胜率榜
+    """
+    match_id = models.IntegerField(u"选手id", blank=True,null=True)
+    match_group = models.CharField(u"比赛分组", max_length=255,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)
+    today_fund = models.FloatField(u"资产",blank=True,null=True)
+    total_income = models.FloatField(u"总收益",blank=True,null=True)
+    win_rate = models.FloatField(u"胜率",blank=True,null=True)
+    badest_income = models.FloatField(u"最大回撤",blank=True,null=True)
+    zq = models.CharField(u"周期", max_length=255, blank=True, null=True)
+    cw = models.CharField(u"仓位", max_length=255, blank=True, null=True)
+    df = models.CharField(u"打法", max_length=255, blank=True, null=True)
+    pz = models.CharField(u"品种", max_length=255, blank=True, null=True)
+
+    ctime = models.DateTimeField(u"创建时间", auto_now_add=True)
+
+    class Meta:
+        db_table = "win_defend_rank"
+        verbose_name = u"胜率防守榜"
+        app_label = "common"
+
+    def __str__(self):
+        return u"{}){}".format(self.id, self.username)
+
+
+class HotStockSellCount(models.Model):
+    """热门清仓
+    """
+    stock_id = models.IntegerField(u"股票id", blank=True,null=True)
+    stock_name = models.CharField(u"股票名称", blank=True,null=True,max_length=255)
+    stock_date = models.CharField(u"持股日期", max_length=255,blank=True,null=True)
+    seller_ids = models.TextField(u"清仓选手id",blank=True,null=True)
+    count = models.IntegerField(u"清仓人数",default=1)
+
+    class Meta:
+        db_table = "hot_stock_seller"
+        verbose_name = u"热门清仓"
+        app_label = "common"
+
+    def __str__(self):
+        return u"{}){}".format(self.stock_id, self.stock_name)

+ 263 - 0
src/manage/WXBizMsgCrypt.py

@@ -0,0 +1,263 @@
+#!/usr/bin/env python
+#-*- encoding:utf-8 -*-
+
+""" 对公众平台发送给公众账号的消息加解密示例代码.
+@copyright: Copyright (c) 1998-2014 Tencent Inc.
+
+"""
+# ------------------------------------------------------------------------
+
+import base64
+import string
+import random
+import hashlib
+import time
+import struct
+from Crypto.Cipher import AES
+import xml.etree.cElementTree as ET
+import sys
+import socket
+reload(sys)
+import ierror
+sys.setdefaultencoding('utf-8')
+
+"""
+关于Crypto.Cipher模块,ImportError: No module named 'Crypto'解决方案
+请到官方网站 https://www.dlitz.net/software/pycrypto/ 下载pycrypto。
+下载后,按照README中的“Installation”小节的提示进行pycrypto安装。
+"""
+class FormatException(Exception):
+    pass
+
+def throw_exception(message, exception_class=FormatException):
+    """my define raise exception function"""
+    raise exception_class(message)
+
+class SHA1:
+    """计算公众平台的消息签名接口"""
+
+    def getSHA1(self, token, timestamp, nonce, encrypt):
+        """用SHA1算法生成安全签名
+        @param token:  票据
+        @param timestamp: 时间戳
+        @param encrypt: 密文
+        @param nonce: 随机字符串
+        @return: 安全签名
+        """
+        try:
+            sortlist = [token, timestamp, nonce, encrypt]
+            sortlist.sort()
+            sha = hashlib.sha1()
+            sha.update("".join(sortlist))
+            return  ierror.WXBizMsgCrypt_OK, sha.hexdigest()
+        except Exception,e:
+            #print e
+            return  ierror.WXBizMsgCrypt_ComputeSignature_Error, None
+
+
+class XMLParse:
+    """提供提取消息格式中的密文及生成回复消息格式的接口"""
+
+    # xml消息模板
+    AES_TEXT_RESPONSE_TEMPLATE = """<xml>
+<Encrypt><![CDATA[%(msg_encrypt)s]]></Encrypt>
+<MsgSignature><![CDATA[%(msg_signaturet)s]]></MsgSignature>
+<TimeStamp>%(timestamp)s</TimeStamp>
+<Nonce><![CDATA[%(nonce)s]]></Nonce>
+</xml>"""
+
+    def extract(self, xmltext):
+        """提取出xml数据包中的加密消息
+        @param xmltext: 待提取的xml字符串
+        @return: 提取出的加密消息字符串
+        """
+        try:
+            xml_tree = ET.fromstring(xmltext)
+            encrypt  = xml_tree.find("Encrypt")
+            print encrypt
+            touser_name    = xml_tree.find("ToUserName")
+            return  ierror.WXBizMsgCrypt_OK, encrypt.text, touser_name.text if touser_name else ""
+        except Exception,e:
+            print e
+            return  ierror.WXBizMsgCrypt_ParseXml_Error,None,None
+
+    def generate(self, encrypt, signature, timestamp, nonce):
+        """生成xml消息
+        @param encrypt: 加密后的消息密文
+        @param signature: 安全签名
+        @param timestamp: 时间戳
+        @param nonce: 随机字符串
+        @return: 生成的xml字符串
+        """
+        resp_dict = {
+                    'msg_encrypt' : encrypt,
+                    'msg_signaturet': signature,
+                    'timestamp'    : timestamp,
+                    'nonce'        : nonce,
+                     }
+        resp_xml = self.AES_TEXT_RESPONSE_TEMPLATE % resp_dict
+        return resp_xml
+
+
+class PKCS7Encoder():
+    """提供基于PKCS7算法的加解密接口"""
+
+    block_size = 32
+    def encode(self, text):
+        """ 对需要加密的明文进行填充补位
+        @param text: 需要进行填充补位操作的明文
+        @return: 补齐明文字符串
+        """
+        text_length = len(text)
+        # 计算需要填充的位数
+        amount_to_pad = self.block_size - (text_length % self.block_size)
+        if amount_to_pad == 0:
+            amount_to_pad = self.block_size
+        # 获得补位所用的字符
+        pad = chr(amount_to_pad)
+        return text + pad * amount_to_pad
+
+    def decode(self, decrypted):
+        """删除解密后明文的补位字符
+        @param decrypted: 解密后的明文
+        @return: 删除补位字符后的明文
+        """
+        pad = ord(decrypted[-1])
+        if pad<1 or pad >32:
+            pad = 0
+        return decrypted[:-pad]
+
+
+class Prpcrypt(object):
+    """提供接收和推送给公众平台消息的加解密接口"""
+
+    def __init__(self,key):
+        #self.key = base64.b64decode(key+"=")
+        self.key = key
+        # 设置加解密模式为AES的CBC模式
+        self.mode = AES.MODE_CBC
+
+
+    def encrypt(self,text,appid):
+        """对明文进行加密
+        @param text: 需要加密的明文
+        @return: 加密得到的字符串
+        """
+        # 16位随机字符串添加到明文开头
+        text = self.get_random_str() + struct.pack("I",socket.htonl(len(text))) + text + appid
+        # 使用自定义的填充方式对明文进行补位填充
+        pkcs7 = PKCS7Encoder()
+        text = pkcs7.encode(text)
+        # 加密
+        cryptor = AES.new(self.key,self.mode,self.key[:16])
+        try:
+            ciphertext = cryptor.encrypt(text)
+            # 使用BASE64对加密后的字符串进行编码
+            return ierror.WXBizMsgCrypt_OK, base64.b64encode(ciphertext)
+        except Exception,e:
+            #print e
+            return  ierror.WXBizMsgCrypt_EncryptAES_Error,None
+
+    def decrypt(self,text,appid):
+        """对解密后的明文进行补位删除
+        @param text: 密文
+        @return: 删除填充补位后的明文
+        """
+        try:
+            cryptor = AES.new(self.key,self.mode,self.key[:16])
+            # 使用BASE64对密文进行解码,然后AES-CBC解密
+            plain_text  = cryptor.decrypt(base64.b64decode(text))
+        except Exception,e:
+            print e
+            return  ierror.WXBizMsgCrypt_DecryptAES_Error,None
+        try:
+            pad = ord(plain_text[-1])
+            # 去掉补位字符串
+            #pkcs7 = PKCS7Encoder()
+            #plain_text = pkcs7.encode(plain_text)
+            # 去除16位随机字符串
+            content = plain_text[16:-pad]
+            xml_len = socket.ntohl(struct.unpack("I",content[ : 4])[0])
+            xml_content = content[4 : xml_len+4]
+            from_appid = content[xml_len+4:]
+            print from_appid
+            print xml_content
+        except Exception,e:
+            print e
+            return  ierror.WXBizMsgCrypt_IllegalBuffer,None
+        if from_appid != appid:
+            print 4444444444444
+            return ierror.WXBizMsgCrypt_ValidateAppid_Error,None
+        return 0,xml_content
+
+    def get_random_str(self):
+        """ 随机生成16位字符串
+        @return: 16位字符串
+        """
+        rule = string.letters + string.digits
+        str = random.sample(rule, 16)
+        return "".join(str)
+
+class WXBizMsgCrypt(object):
+    #构造函数
+    #@param sToken: 公众平台上,开发者设置的Token
+    # @param sEncodingAESKey: 公众平台上,开发者设置的EncodingAESKey
+    # @param sAppId: 企业号的AppId
+    def __init__(self,sToken,sEncodingAESKey,sAppId):
+        try:
+            self.key = base64.b64decode(sEncodingAESKey+"=")
+            assert len(self.key) == 32
+        except:
+            throw_exception("[error]: EncodingAESKey unvalid !", FormatException)
+           #return ierror.WXBizMsgCrypt_IllegalAesKey)
+        self.token = sToken
+        self.appid = sAppId
+
+    def EncryptMsg(self, sReplyMsg, sNonce, timestamp = None):
+        #将公众号回复用户的消息加密打包
+        #@param sReplyMsg: 企业号待回复用户的消息,xml格式的字符串
+        #@param sTimeStamp: 时间戳,可以自己生成,也可以用URL参数的timestamp,如为None则自动用当前时间
+        #@param sNonce: 随机串,可以自己生成,也可以用URL参数的nonce
+        #sEncryptMsg: 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串,
+        #return:成功0,sEncryptMsg,失败返回对应的错误码None
+        pc = Prpcrypt(self.key)
+        ret,encrypt = pc.encrypt(sReplyMsg, self.appid)
+        if ret != 0:
+            return ret,None
+        if timestamp is None:
+            timestamp = str(int(time.time()))
+        # 生成安全签名
+        sha1 = SHA1()
+        ret,signature = sha1.getSHA1(self.token, timestamp, sNonce, encrypt)
+        if ret != 0:
+            return ret,None
+        xmlParse = XMLParse()
+        return ret,xmlParse.generate(encrypt, signature, timestamp, sNonce)
+
+    def DecryptMsg(self, sPostData, sMsgSignature, sTimeStamp, sNonce):
+        # 检验消息的真实性,并且获取解密后的明文
+        # @param sMsgSignature: 签名串,对应URL参数的msg_signature
+        # @param sTimeStamp: 时间戳,对应URL参数的timestamp
+        # @param sNonce: 随机串,对应URL参数的nonce
+        # @param sPostData: 密文,对应POST请求的数据
+        #  xml_content: 解密后的原文,当return返回0时有效
+        # @return: 成功0,失败返回对应的错误码
+         # 验证安全签名
+        xmlParse = XMLParse()
+        print sPostData
+        ret,encrypt,touser_name = xmlParse.extract(sPostData)
+        print ret,encrypt,touser_name
+        if ret != 0:
+            return ret, None
+        sha1 = SHA1()
+        ret,signature = sha1.getSHA1(self.token, sTimeStamp, sNonce, encrypt)
+        print ret,signature,333333333333333
+        if ret  != 0:
+            return ret, None
+        if not signature == sMsgSignature:
+            return ierror.WXBizMsgCrypt_ValidateSignature_Error, None
+        pc = Prpcrypt(self.key)
+        print 777777777777
+        ret,xml_content = pc.decrypt(encrypt,self.appid)
+        return ret,xml_content
+

+ 13 - 0
src/manage/controls.py

@@ -220,6 +220,8 @@ def update_model(cls,**kwargs):
 
 
         #更新group_rank
         #更新group_rank
         update_group_rank_day(obj.match_id,obj.match_group,obj.stock_date)
         update_group_rank_day(obj.match_id,obj.match_group,obj.stock_date)
+    if model_name == "UserInfo":
+        ccc.del_cache("cdata_get_user_info_(%s,)"%id)
 
 
     return rst
     return rst
 
 
@@ -352,6 +354,10 @@ def get_list_info(cls,**kwargs):
             else:
             else:
                 qset = qset.filter(auto_complete=kwargs.get("auto_complete"))
                 qset = qset.filter(auto_complete=kwargs.get("auto_complete"))
 
 
+    if model_name == "Article":
+        if kwargs.get("type"):
+            qset = qset.filter(type=kwargs.get("type"))
+
     if model_name == "PlayerRecord":
     if model_name == "PlayerRecord":
         data = list(qset.order_by("-total_income").values())
         data = list(qset.order_by("-total_income").values())
     else:
     else:
@@ -549,3 +555,10 @@ def update_group_rank(stock_date=None):
                 cursor.close()
                 cursor.close()
 
 
 
 
+def update_comment(**kwargs):
+    """
+    """
+    id = kwargs.get("id")
+    wanzhu_comment = kwargs.get("wanzhu_comment")
+    cm.PlayerRecord.objects.filter(id=id).update(wanzhu_comment=wanzhu_comment)
+

+ 20 - 0
src/manage/ierror.py

@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#########################################################################
+# Author: jonyqin
+# Created Time: Thu 11 Sep 2014 01:53:58 PM CST
+# File Name: ierror.py
+# Description:定义错误码含义 
+#########################################################################
+WXBizMsgCrypt_OK = 0
+WXBizMsgCrypt_ValidateSignature_Error = -40001
+WXBizMsgCrypt_ParseXml_Error = -40002
+WXBizMsgCrypt_ComputeSignature_Error = -40003
+WXBizMsgCrypt_IllegalAesKey = -40004
+WXBizMsgCrypt_ValidateAppid_Error = -40005
+WXBizMsgCrypt_EncryptAES_Error = -40006
+WXBizMsgCrypt_DecryptAES_Error = -40007
+WXBizMsgCrypt_IllegalBuffer = -40008
+WXBizMsgCrypt_EncodeBase64_Error = -40009
+WXBizMsgCrypt_DecodeBase64_Error = -40010
+WXBizMsgCrypt_GenReturnXml_Error = -40011

+ 7 - 1
src/manage/urls_backstage.py

@@ -5,8 +5,8 @@ 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'^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'^player$', views.PlayerView.as_view()),
     url(r'^player$', views.PlayerView.as_view()),
@@ -28,6 +28,12 @@ urlpatterns = [
     url(r'^article$', views.ArticleView.as_view()),
     url(r'^article$', views.ArticleView.as_view()),
     url(r'^article/list$', views.ArticleListView.as_view()),
     url(r'^article/list$', views.ArticleListView.as_view()),
     url(r'^flushrank$', views.FlushRankView.as_view()),
     url(r'^flushrank$', views.FlushRankView.as_view()),
+    url(r'^stock$', views.StockView.as_view()),
+    url(r'^stock/list$', views.StockListView.as_view()),
+    url(r'^player/record/comment$', views.PlayerRecordCommentView.as_view()),
+
+    url(r'^wxtest$', views.WxTestView.as_view()),
+    url(r'^wxtest/(?P<appid>\w+)/callback$', views.WxTestCallbackView.as_view()),
 
 
 ]
 ]
 
 

+ 197 - 2
src/manage/views.py

@@ -92,7 +92,7 @@ class UserInfoView(cv.AdminView):
         if mse:
         if mse:
             raise ce.TipException(mse)
             raise ce.TipException(mse)
         try:
         try:
-            need_params.extend(["usercode"])
+            need_params.extend(["usercode","badge","zq","cw","df"])
             vals = ccf.get_need_params(*need_params,**qdata)
             vals = ccf.get_need_params(*need_params,**qdata)
             if not vals.get("usercode"):
             if not vals.get("usercode"):
                 vals["usercode"] = self.gen_code()
                 vals["usercode"] = self.gen_code()
@@ -115,7 +115,7 @@ class UserInfoView(cv.AdminView):
         if mse:
         if mse:
             raise ce.TipException(mse)
             raise ce.TipException(mse)
         try:
         try:
-            need_params.extend(["is_bind"])
+            need_params.extend(["is_bind","badge","zq","cw","df"])
             vals = ccf.get_need_params(*need_params,**qdata)
             vals = ccf.get_need_params(*need_params,**qdata)
             rst = ctl.update_model(self,**vals)
             rst = ctl.update_model(self,**vals)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
@@ -685,6 +685,7 @@ class ArticleView(cv.AdminView):
         if mse:
         if mse:
             raise ce.TipException(mse)
             raise ce.TipException(mse)
         try:
         try:
+            need_params.extend(["type","img"])
             vals = ccf.get_need_params(*need_params,**qdata)
             vals = ccf.get_need_params(*need_params,**qdata)
             rst = ctl.add_model(self,**vals)
             rst = ctl.add_model(self,**vals)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
@@ -704,6 +705,7 @@ class ArticleView(cv.AdminView):
         if mse:
         if mse:
             raise ce.TipException(mse)
             raise ce.TipException(mse)
         try:
         try:
+            need_params.extend(["type","img"])
             vals = ccf.get_need_params(*need_params,**qdata)
             vals = ccf.get_need_params(*need_params,**qdata)
             rst = ctl.update_model(self,**vals)
             rst = ctl.update_model(self,**vals)
             return cv.to_suc(rst)
             return cv.to_suc(rst)
@@ -759,3 +761,196 @@ class FlushRankView(cv.AdminView):
         except Exception as e:
         except Exception as e:
             cv.tracefail()
             cv.tracefail()
             return cv.to_fail(e)
             return cv.to_fail(e)
+
+class StockView(cv.AdminView):
+    def get(self, request):
+        """#赛事详情(平台管理后台)
+        @id:1
+        """
+        qdata = request.json
+        need_params = ["id"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.get_detail_info(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def post(self,request):
+        """#新增股票(平台管理后台)
+        @name:"赛事名称"
+        @content:"详情"
+        """
+        qdata = request.json
+        need_params = ["name","code"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            need_params.extend(["desc","img"])
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.add_model(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def put(self,request):
+        """#修改股票(平台管理后台)
+        @id:"1"
+        @name:"名称"
+        @content:"详情"
+        """
+        qdata = request.json
+        need_params = ["id","name","code"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            need_params.extend(["desc","img"])
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.update_model(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def delete(self,request):
+        """#删除股票(平台管理后台)
+        @id:"1",多个逗号分隔
+        """
+        qdata = request.json
+        need_params = ["id"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.delete_model(self,**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class PlayerRecordCommentView(cv.AdminView):
+    def put(self,request):
+        """#顽主点评(平台管理后台)
+        @id:"1"
+        @wanzhu_comment:"顽主点评"
+        """
+        qdata = request.json
+        need_params = ["id","wanzhu_comment"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.update_comment(**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class StockListView(cv.AdminView):
+    def get(self, request):
+        """#股票仓库列表(平台管理后台)
+        @name:"用户名"
+        @page:1
+        @page_size:20
+        """
+        qdata = request.json
+        try:
+            total,rst = ctl.get_list_info(self,**qdata)
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class WxTestView(cv.BaseView):
+    def get(self,request):
+        """
+        """
+        return HttpResponse("success")
+
+
+    def get_wx_auth_ticket(self,xml,timestamp,nonce,msg_signature):
+        """获取微信通过授权URL推送的票据
+        """
+        import xml.etree.cElementTree as ET
+        from WXBizMsgCrypt import WXBizMsgCrypt
+        encodingAESKey = "NBFPgHxUIlQ628bYwDJOZQNMp7T1YGykpzzYklo9tmY"
+        token = "1234567890987654321"
+        APPID = "wx02753c07bbfce783"
+
+        decrypt_test = WXBizMsgCrypt(token,encodingAESKey,APPID)
+
+        ret,decryp_xml = decrypt_test.DecryptMsg(xml,msg_signature,timestamp, nonce)
+        if decryp_xml: 
+            xml_tree = ET.fromstring(decryp_xml)
+            print xml_tree,999999999999999
+            ComponentVerifyTicket  = xml_tree.find("ComponentVerifyTicket")
+            return ComponentVerifyTicket
+        return None
+
+    def post(self, request):
+        """#更新排名(平台管理后台)
+        @name:""
+        @page:1
+        @page_size:20
+        """
+        print request.body
+        qdata = request.GET
+        try:
+            postxml = request.body
+            timestamp = request.GET.get("timestamp")
+            nonce = request.GET.get("nonce")
+            msg_signature = request.GET.get("msg_signature")
+            ticket = self.get_wx_auth_ticket(postxml,timestamp,nonce,msg_signature)
+            print "ticket:",ticket
+            return HttpResponse("success")
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class WxTestCallbackView(cv.BaseView):
+    def get(self,request):
+        """
+        """
+        print request.GET
+        print request.REQUEST
+        print request.body
+        return HttpResponse("success")
+
+    def post(self, request,appid):
+        """#更新排名(平台管理后台)
+        @name:""
+        @page:1
+        @page_size:20
+        """
+        print request.POST
+        print 11111111111
+        print request.body
+        print 22222222222222
+        print request.json
+        qdata = request.GET
+        try:
+            openid = qdata.get("openid")
+            from wechatpy import WeChatClient
+            client = WeChatClient("wx84a42c807ed07198", "e2de849dfef826b1854c0b18407a6be2")
+            #client.message.send_mass_text(None,u"欢迎关注四川环宇星创科技有限公司公众号!",True)
+            client.message.send_text(openid,u"点击绑定手机号查看您的电子证书:http://testcaos.tederen.com/zs.jpg")
+
+            return HttpResponse(qdata.get("timestamp"))
+
+            return HttpResponse("success")
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)

+ 1 - 1
src/settings/settings_dev.py

@@ -71,5 +71,5 @@ LOGGING = {
 
 
 RANK_LIST = "RANK_LIST"
 RANK_LIST = "RANK_LIST"
 
 
-HOST = "https://www.hunanwanzhu.com"
+HOST = "https://wx.scxjc.club"
 PROJECT_NAME = u"顽主杯"
 PROJECT_NAME = u"顽主杯"

+ 78 - 2
src/tools/rank_server.py

@@ -13,6 +13,7 @@ django.setup()
 
 
 import common.models as cm
 import common.models as cm
 import common.common_control as ccc
 import common.common_control as ccc
+import common.common_functions as ccf
 
 
 def rank_server():
 def rank_server():
     """
     """
@@ -26,10 +27,51 @@ def rank_server():
         if "15:00"<datetime.datetime.now().strftime("%H:%M") < "15:30":
         if "15:00"<datetime.datetime.now().strftime("%H:%M") < "15:30":
             update_cache_rank(match_id,match_group,stock_date)
             update_cache_rank(match_id,match_group,stock_date)
         else:
         else:
+            update_cache_rank(match_id,match_group,stock_date)
             sync_group_rank(match_id,match_group,stock_date)
             sync_group_rank(match_id,match_group,stock_date)
+            update_hot_seller(record)
+        #更新胜率榜
+        update_win_defend_rank(record)
 
 
-def update_cache_rank(match_id,match_group,stock_date):
+def update_win_defend_rank(record):
+    """更新胜率防守榜
     """
     """
+    player_id = record.player_id
+    match_id = record.match_id
+    match_group = record.match_group
+    user_id = record.user_id
+    user_name = record.username
+    today_fund = record.today_fund
+    total_income = record.total_income
+    zq = record.zq
+    cw = record.cw
+    df = record.df
+    pz = record.pz
+    #胜率
+    qset = cm.PlayerRecord.objects.filter(match_id=match_id,player_id=player_id)
+    win_rate = qset.filter(today_income__gt=0).count()/float(qset.count()) if qset else 0.0
+    win_rate = round(win_rate,3)
+    #win_rate = "{}%".format(win_rate*100)
+    #最大回撤
+    badest_income = qset.order_by("today_income").first().today_income
+    badest_income = round(badest_income,3)
+
+    obj,flag = cm.WinDefendRank.objects.get_or_create(
+        user_id = user_id, 
+        player_id = player_id, 
+        match_id = match_id, 
+        match_group = match_group 
+    )
+    obj.user_name = user_name
+    obj.today_fund = today_fund
+    obj.total_income = total_income
+    obj.win_rate = win_rate
+    obj.badest_income = badest_income
+    obj.save()
+
+
+def update_cache_rank(match_id,match_group,stock_date):
+    """更新redis排名数据
     """
     """
     print "update cache rank..."
     print "update cache rank..."
     delkey = "*_%s_%s_%s" % (match_id,match_group,stock_date)
     delkey = "*_%s_%s_%s" % (match_id,match_group,stock_date)
@@ -51,7 +93,7 @@ def update_cache_rank(match_id,match_group,stock_date):
     ccc.pl.execute()
     ccc.pl.execute()
 
 
 def sync_group_rank(match_id,match_group,stock_date):
 def sync_group_rank(match_id,match_group,stock_date):
-    """
+    """更新数据库排名数据
     """
     """
     print "sync group rank..."
     print "sync group rank..."
     delkey = "*_%s_%s_%s" % (match_id,match_group,stock_date)
     delkey = "*_%s_%s_%s" % (match_id,match_group,stock_date)
@@ -84,6 +126,40 @@ def sync_group_rank(match_id,match_group,stock_date):
         cursor.execute(sql)
         cursor.execute(sql)
         cursor.close()
         cursor.close()
 
 
+def update_hot_seller(record):
+    """更新热门清仓
+    """
+    stock_date = record.stock_date
+
+    stock_date_time = ccf.str_to_datetime(stock_date,"%Y-%m-%d")
+    yesterday = (stock_date_time - datetime.timedelta(days=1)).strftime("%Y-%m-%d")
+    #昨天所有持股id
+    all_stock_ids = list(cm.UserStock.objects.filter(stock_date=yesterday).values_list("stock_id",flat=True))
+    all_stock_ids = list(set(all_stock_ids))
+    for stock_id in all_stock_ids:
+        print stock_date,stock_id
+        stock = cm.Stock.objects.filter(id=stock_id).first()
+        #昨天持股选手
+        yes_players = list(cm.UserStock.objects.filter(stock_date=yesterday,stock_id=stock_id).values_list("player_id",flat=True))
+        #今天持股选手
+        td_players = list(cm.UserStock.objects.filter(stock_date=stock_date,stock_id=stock_id).values_list("player_id",flat=True))
+
+        if yes_players and td_players:
+            #清仓选手
+            sell_players = list(set(yes_players)-set(td_players))
+            if sell_players:
+                seller_ids = json.dumps(sell_players)
+                count = len(sell_players)
+
+                obj,flag = cm.HotStockSellCount.objects.get_or_create(
+                    stock_id = stock_id, 
+                    stock_name = stock.name, 
+                    stock_date = stock_date
+                )
+                obj.seller_ids = seller_ids
+                obj.count = count
+                obj.save()
+
 if __name__ == "__main__":
 if __name__ == "__main__":
     print "start update group rank..."
     print "start update group rank..."
     while True:
     while True:

+ 160 - 0
src/tools/sync_data.py

@@ -0,0 +1,160 @@
+#coding:utf-8
+import os,json
+import time
+import datetime
+import sys
+import django
+from django.core.cache import cache
+from django.db import connection
+from django.db.models import Q,Sum,Count,F
+
+sys.path.append('/mnt/wzbapi/src')
+os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
+django.setup()
+
+import common.models as cm
+import common.common_functions as ccf
+
+def sync_stock():
+    """同步用户持股和股票仓库数据
+    """
+    prset = cm.PlayerRecord.objects.order_by("stock_date")
+    for index,pr in enumerate(prset):
+        player_id = pr.player_id
+        match_id = pr.match_id
+        match_group = pr.match_group
+        stock_date = pr.stock_date
+        today_stock = pr.today_stock
+        yesterday_stock = pr.yesterday_stock
+        print pr.username,stock_date
+        
+        today_stock = json.loads(today_stock) if today_stock else []
+        yesterday_stock = json.loads(yesterday_stock) if yesterday_stock else []
+        
+        new_today_stock = []
+        for ts in today_stock:
+            if ts["name"] and ts["fund"]:
+                stock,flag = cm.Stock.objects.get_or_create(name=ts["name"])
+                ts["stock_id"] = stock.id
+                new_today_stock.append(ts)
+                #更新用户持股情况
+                cm.UserStock.objects.get_or_create(
+                    player_id = player_id, 
+                    stock_id = stock.id, 
+                    stock_date = stock_date
+                )
+
+        yes_today_stock = []
+        for ts in yesterday_stock:
+            if ts["name"] and ts["fund"]:
+                stock,flag = cm.Stock.objects.get_or_create(name=ts["name"])
+                ts["stock_id"] = stock.id
+                yes_today_stock.append(ts)
+
+        pr.today_stock = json.dumps(new_today_stock)
+        pr.yesterday_stock = json.dumps(yes_today_stock)
+
+        pr.save()
+
+
+def sync_win_defend():
+    """更新胜率和最大回撤
+    """
+    match_id = 7
+    players = cm.Player.objects.filter(match_id=match_id)
+    for pl in players:
+        record = cm.PlayerRecord.objects.filter(match_id=match_id,player_id=pl.id).order_by("-stock_date").first()
+        if record:
+            print record.username,record.stock_date
+            from threading import Thread
+            t = Thread(target=update_win_defend_rank,args=(record,))
+            t.start()
+
+
+def update_win_defend_rank(record):
+    """更新胜率防守榜
+    """
+    player_id = record.player_id
+    user_id = record.user_id
+    match_id = record.match_id
+    match_group = record.match_group
+    user_name = record.username
+    today_fund = record.today_fund
+    total_income = record.total_income
+    zq = record.zq
+    cw = record.cw
+    df = record.df
+    pz = record.pz
+    #胜率
+    qset = cm.PlayerRecord.objects.filter(match_id=match_id,player_id=player_id)
+    win_rate = qset.filter(today_income__gt=0).count()/float(qset.count()) if qset else 0.0
+    win_rate = round(win_rate,3)
+    #win_rate = "{}%".format(win_rate*100)
+    #最大回撤
+    badest_income = qset.order_by("today_income").first().today_income
+    badest_income = round(badest_income,3)
+
+    obj,flag = cm.WinDefendRank.objects.get_or_create(
+        user_id = user_id, 
+        player_id = player_id, 
+        match_id = match_id, 
+        match_group = match_group 
+    )
+    obj.username = user_name
+    obj.today_fund = today_fund
+    obj.total_income = total_income
+    obj.win_rate = win_rate
+    obj.badest_income = badest_income
+    obj.save()
+
+def sync_hot_seller():
+    """同步热门清仓数据
+    """
+    all_dates = list(cm.UserStock.objects.order_by("stock_date").values_list("stock_date",flat=True))
+    all_dates = list(set(all_dates))
+    all_dates.sort()
+
+    for stock_date in all_dates:
+        stock_date_time = ccf.str_to_datetime(stock_date,"%Y-%m-%d")
+        yesterday = (stock_date_time - datetime.timedelta(days=1)).strftime("%Y-%m-%d")
+        #昨天所有持股id
+        all_stock_ids = list(cm.UserStock.objects.filter(stock_date=yesterday).values_list("stock_id",flat=True))
+        all_stock_ids = list(set(all_stock_ids))
+        for stock_id in all_stock_ids:
+            print stock_date,stock_id
+            stock = cm.Stock.objects.filter(id=stock_id).first()
+            #昨天持股选手
+            yes_players = list(cm.UserStock.objects.filter(stock_date=yesterday,stock_id=stock_id).values_list("player_id",flat=True))
+            #今天持股选手
+            td_players = list(cm.UserStock.objects.filter(stock_date=stock_date,stock_id=stock_id).values_list("player_id",flat=True))
+
+            if yes_players and td_players:
+                #清仓选手
+                sell_players = list(set(yes_players)-set(td_players))
+                if sell_players:
+                    seller_ids = json.dumps(sell_players)
+                    count = len(sell_players)
+
+                    obj,flag = cm.HotStockSellCount.objects.get_or_create(
+                        stock_id = stock_id, 
+                        stock_name = stock.name, 
+                        stock_date = stock_date
+                    )
+                    obj.seller_ids = seller_ids
+                    obj.count = count
+                    obj.save()
+
+
+
+if __name__ == "__main__":
+    print "start sync stock..."
+    st = time.time()
+    sync_stock()
+    sync_win_defend()
+    sync_hot_seller()
+    print "time cost:",time.time()-st
+
+
+
+
+

+ 36 - 3
src/tools/update_group_rank.py

@@ -1,10 +1,9 @@
 #coding:utf-8
 #coding:utf-8
-import os
+import os,json
 import time
 import time
 import datetime
 import datetime
 import sys
 import sys
 import django
 import django
-import common.common_control as ccc
 from django.db import connection
 from django.db import connection
 
 
 sys.path.append('/mnt/wzbapi/src')
 sys.path.append('/mnt/wzbapi/src')
@@ -12,6 +11,7 @@ os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
 django.setup()
 django.setup()
 
 
 import common.models as cm
 import common.models as cm
+import common.common_control as ccc
 
 
 def update_group_rank(stock_date=None):
 def update_group_rank(stock_date=None):
     """
     """
@@ -54,11 +54,44 @@ def update_group_rank(stock_date=None):
             cursor.close()
             cursor.close()
 
 
 
 
+def update_group_rank_cache(stock_date=None):
+    """
+    """
+    match_id = 7
+    prset = cm.PlayerRecord.objects.filter(match_id=match_id).order_by("-stock_date")
+    if prset:
+        records = prset.values()
+        case_id = " case id "
+        cases = []
+        where = []
+        for index,pr in enumerate(prset):
+            case = "WHEN %s THEN %s" % (pr.id,index+1)
+            cases.append(case)
+            where.append(str(pr.id))
+
+            record = records[index]
+            #
+            key = "%s_%s_%s_%s" % (pr.player_id,pr.match_id,pr.match_group,pr.stock_date)
+            if pr.player_id == 434:
+                print key
+
+            ccc.pl.set(key,json.dumps(record,cls=ccc.CusJSONEncoder))
+        ccc.pl.execute()
+
+        #case = case_id + " ".join(cases)
+        #where = ",".join(where)
+        #sql = "update player_record set group_rank = %s ELSE 0 END where id in (%s)" % (case,where)
+        #cursor = connection.cursor()
+        #cursor.execute(sql)
+        #cursor.close()
+
+
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
     print "start update group rank..."
     print "start update group rank..."
     st = time.time()
     st = time.time()
-    update_group_rank()
+    #update_group_rank()
+    update_group_rank_cache()
     print "time cost:",time.time()-st
     print "time cost:",time.time()-st
 
 
 
 

+ 7 - 1
src/weixin/control_auth.py

@@ -32,9 +32,15 @@ def get_wxauth_info(request):
     """
     """
     #
     #
     uid = request.user.id
     uid = request.user.id
-    print uid
+    player = request.player
     user = cm.UserInfo.objects.filter(id=uid).values().first()
     user = cm.UserInfo.objects.filter(id=uid).values().first()
     user["nickname"] = user["username"]
     user["nickname"] = user["username"]
+    #
+    #if not user["zq"] or not user["cw"] or not user["df"] or not player.fund:
+    if not player.fund:
+        user["need_fill"] = 1
+    else:
+        user["need_fill"] = 0
     return user
     return user
 
 
 
 

+ 720 - 33
src/weixin/controls.py

@@ -20,13 +20,14 @@ from utils.jgpush import send_notification_by_registration_ids
 import wzhifuSDK as wxpay
 import wzhifuSDK as wxpay
 from utils.exceltool import ExcelTool
 from utils.exceltool import ExcelTool
 from utils.qrcodetool import gen_general_qrcode
 from utils.qrcodetool import gen_general_qrcode
-from django.db.models import Q,Sum,Count
+from django.db.models import Q,Sum,Count,F
 from PIL import Image
 from PIL import Image
 from PIL import Image,ImageDraw,ImageFont
 from PIL import Image,ImageDraw,ImageFont
 from django.db import transaction
 from django.db import transaction
 from threading import Thread
 from threading import Thread
 #from django.core.cache import cache
 #from django.core.cache import cache
 from django.db import connection
 from django.db import connection
+import calendar
 
 
 import xlrd
 import xlrd
 import xlwt
 import xlwt
@@ -43,6 +44,7 @@ def async(f):
 
 
 
 
 def get_today_date():
 def get_today_date():
+    return '2021-11-25'
     if datetime.datetime.now().strftime("%H:%M") < "15:00":
     if datetime.datetime.now().strftime("%H:%M") < "15:00":
         if datetime.datetime.now().weekday() in [5,6] or datetime.datetime.now().strftime("%Y-%m-%d") in MISS_DATES:
         if datetime.datetime.now().weekday() in [5,6] or datetime.datetime.now().strftime("%Y-%m-%d") in MISS_DATES:
             today = cm.PlayerRecord.objects.all().order_by("-stock_date").first().stock_date
             today = cm.PlayerRecord.objects.all().order_by("-stock_date").first().stock_date
@@ -79,7 +81,7 @@ def update_group_rank(match_id,match_group,stock_date):
 def get_notices():
 def get_notices():
     """
     """
     """
     """
-    notices = list(cm.Article.objects.filter(status=2).values())
+    notices = list(cm.Article.objects.filter(status=2,type="notice").values())
     return notices
     return notices
 
 
 def get_index_data(request):
 def get_index_data(request):
@@ -159,9 +161,11 @@ def get_player_match_detail(request):
     """
     """
     qdata = request.json
     qdata = request.json
     player_id = request.player.id
     player_id = request.player.id
+    org_player_id = request.player.id
     match_group = request.player.match_group
     match_group = request.player.match_group
     match_id = qdata.get("id")
     match_id = qdata.get("id")
     record_id = qdata.get("record_id")
     record_id = qdata.get("record_id")
+
     if record_id:
     if record_id:
         records_set = cm.PlayerRecord.objects.filter(id=record_id)
         records_set = cm.PlayerRecord.objects.filter(id=record_id)
         match_id = records_set.first().match_id
         match_id = records_set.first().match_id
@@ -169,18 +173,21 @@ def get_player_match_detail(request):
         player_id = records_set.first().player_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")
         records_set = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id).order_by("-stock_date")
     else:
     else:
+        if qdata.get("player_id"):
+            player_id = qdata.get("player_id")
+            match_group = cm.Player.objects.filter(id=player_id).first().match_group
         records_set = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id).order_by("-stock_date")
         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()
     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))
     groups = list(cm.MatchGroup.objects.filter(match_id=match_id).values_list("name",flat=True))
     match["groups"] = groups
     match["groups"] = groups
     if records_set:
     if records_set:
-        #today_record = records_set.values().first()
         records = list(records_set.values())
         records = list(records_set.values())
     else:
     else:
-        #today_record = {}
         records = []
         records = []
-    today = get_today_date()
+
+    today = records_set.first().stock_date
     today_record = get_today_record(player_id,int(match_id),int(match_group),today)
     today_record = get_today_record(player_id,int(match_id),int(match_group),today)
 
 
     for item in records:
     for item in records:
@@ -191,31 +198,56 @@ def get_player_match_detail(request):
         item["today_income"] = "{}%".format(item["today_income"]*100)
         item["today_income"] = "{}%".format(item["today_income"]*100)
         item["total_income"] = "{}%".format(item["total_income"]*100)
         item["total_income"] = "{}%".format(item["total_income"]*100)
     if today_record:
     if today_record:
+        today_record["today_stock_img"] = json.loads(today_record["today_stock_img"]) if today_record["today_stock_img"] else []
+        today_record["today_stock"] = json.loads(today_record["today_stock"]) if today_record["today_stock"] else []
         today_record["today_income"] = "{}%".format(today_record["today_income"]*100)
         today_record["today_income"] = "{}%".format(today_record["today_income"]*100)
         today_record["total_income"] = "{}%".format(today_record["total_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
         today_record["match_group_name"] = cm.MatchGroup.objects.filter(id=today_record["match_group"]).first().name
+        today_record["players_num"] = cm.Player.objects.filter(match_group=today_record["match_group"]).count()
+        today_record["win_rate"] = calc_win_rate(player_id,today_record["match_id"])
+        badest = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id).order_by("today_income").first()
+        if badest:
+            today_record["badest_income"] = "{}%".format(badest.today_income*100)
+
     match["groups"] = [today_record["match_group_name"]] if today_record else []
     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}
+    records = sorted(records,key=lambda x:x["stock_date"],reverse=True)[:5]
+    if cm.UserFollows.objects.filter(user_id=org_player_id,follow_id=player_id).exists():
+        is_follow = 1
+    else:
+        is_follow = 0
+    ret = {"match":match,"today_record":today_record,"records":records,"is_follow":is_follow}
 
 
     return ret
     return ret
 
 
 
 
-#@ccc.cache_data()
-#def get_today_record(player_id,match_id,match_group,today):
-#    records_set = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id,match_group=match_group,stock_date=today)
-#    if records_set:
-#        today_record = records_set.values().first()
-#    else:
-#        today_record = {}
-#    return today_record
-
 def get_today_record(player_id,match_id,match_group,today):
 def get_today_record(player_id,match_id,match_group,today):
     """
     """
     """
     """
     key = "%s_%s_%s_%s" % (player_id,match_id,match_group,today)
     key = "%s_%s_%s_%s" % (player_id,match_id,match_group,today)
     today_record = ccc.cache.get(key)
     today_record = ccc.cache.get(key)
     today_record = json.loads(today_record) if today_record else {}
     today_record = json.loads(today_record) if today_record else {}
+
+    try:
+        if today_record:
+            user_info = get_user_info(today_record["user_id"])
+            if user_info:
+                user_info.pop("id")
+                today_record.update(user_info)
+
+            #仓位
+            today_stock_total = 0
+            today_stock = json.loads(today_record["today_stock"])
+            for ts in today_stock:
+                if ts["fund"]:
+                    try:
+                        today_stock_total += float(ts["fund"])
+                    except Exception as e:
+                        print e
+            today_record["cangwei"] = "{}%".format(round(today_stock_total/today_record["today_fund"],4)*100)
+            today_record["today_stock_total"] = today_stock_total
+    except Exception as e:
+        import traceback
+        traceback.print_exc()
     return today_record
     return today_record
 
 
 @ccc.cache_data()
 @ccc.cache_data()
@@ -232,7 +264,7 @@ def get_match_groups(match_id):
     return match,groups
     return match,groups
 
 
 #@ccc.cache_data()
 #@ccc.cache_data()
-def get_cache_rank_list(player_id,match_id):
+def get_cache_rank_list(player_id,match_id,today):
     """
     """
     """
     """
     match,groups = get_match_groups(match_id)
     match,groups = get_match_groups(match_id)
@@ -241,7 +273,6 @@ def get_cache_rank_list(player_id,match_id):
     #    today = (datetime.datetime.now()-datetime.timedelta(days=1)).strftime("%Y-%m-%d")
     #    today = (datetime.datetime.now()-datetime.timedelta(days=1)).strftime("%Y-%m-%d")
     #else:
     #else:
     #    today = datetime.datetime.now().strftime("%Y-%m-%d")
     #    today = datetime.datetime.now().strftime("%Y-%m-%d")
-    today = get_today_date()
 
 
     for item in groups:
     for item in groups:
         new_players = []
         new_players = []
@@ -257,13 +288,21 @@ def get_cache_rank_list(player_id,match_id):
             if today_record:
             if today_record:
                 player.update(today_record)
                 player.update(today_record)
                 player["username"] = username
                 player["username"] = username
+                player["org_today_income"] = player["today_income"]
                 player["total_income"] = "{}%".format(today_record["total_income"]*100)
                 player["total_income"] = "{}%".format(today_record["total_income"]*100)
+                player["today_income"] = "{}%".format(today_record["today_income"]*100)
 
 
                 player["fund"] = round(player["fund"],4)
                 player["fund"] = round(player["fund"],4)
                 player["init_fund"] = round(player["init_fund"],4)
                 player["init_fund"] = round(player["init_fund"],4)
                 player["today_fund"] = round(player["today_fund"],4)
                 player["today_fund"] = round(player["today_fund"],4)
                 new_players.append(player)
                 new_players.append(player)
         new_players = sorted(new_players,key=lambda x:x["group_rank"])
         new_players = sorted(new_players,key=lambda x:x["group_rank"])
+        win_count = filter(lambda x:x["org_today_income"]>=0.05,new_players)
+        loss_count = filter(lambda x:x["org_today_income"]<=-0.05,new_players)
+        #item["players_num"] = cm.Player.objects.filter(match_group=item["id"]).count()
+        item["players_num"] = len(players)
+        item["win_count"] = len(win_count)
+        item["loss_count"] = len(loss_count)
         item["players"] = new_players[:3]
         item["players"] = new_players[:3]
     return match,groups
     return match,groups
 
 
@@ -274,7 +313,9 @@ def get_rank_list(request):
     qdata = request.json
     qdata = request.json
     player_id = request.player.id
     player_id = request.player.id
     match_id = request.player.match_id
     match_id = request.player.match_id
-    match,groups = get_cache_rank_list(player_id,match_id)
+    today = qdata.get("stock_date")
+
+    match,groups = get_cache_rank_list(player_id,match_id,today)
 
 
     ret = {"match":match,"groups":groups}
     ret = {"match":match,"groups":groups}
 
 
@@ -284,6 +325,14 @@ def get_rank_list(request):
 @ccc.cache_data()
 @ccc.cache_data()
 def get_user_info(uid):
 def get_user_info(uid):
     user = cm.UserInfo.objects.filter(id=uid).values().first()
     user = cm.UserInfo.objects.filter(id=uid).values().first()
+    if user:
+        user["style"] = []
+        if user["zq"]:
+            user["style"].append(user["zq"])
+        if user["cw"]:
+            user["style"].append(user["cw"])
+        if user["df"]:
+            user["style"].append(user["df"])
     return user
     return user
 
 
 @ccc.cache_data()
 @ccc.cache_data()
@@ -294,6 +343,7 @@ def get_match_info(match_id):
 @ccc.cache_data()
 @ccc.cache_data()
 def get_group_info(group_id):
 def get_group_info(group_id):
     group = cm.MatchGroup.objects.filter(id=group_id).values().first()
     group = cm.MatchGroup.objects.filter(id=group_id).values().first()
+    group["players_num"] = cm.Player.objects.filter(match_group=group["id"]).count()
     return group
     return group
 
 
 
 
@@ -306,17 +356,11 @@ def get_group_rank_list(request):
     group_id = qdata.get("id")
     group_id = qdata.get("id")
     player_id = request.player.id
     player_id = request.player.id
     match_id = request.player.match_id
     match_id = request.player.match_id
+    today = qdata.get("stock_date")
 
 
     match = get_match_info(match_id)
     match = get_match_info(match_id)
     group = get_group_info(group_id)
     group = get_group_info(group_id)
 
 
-    #if datetime.datetime.now().hour < 15:
-    #    today = (datetime.datetime.now()-datetime.timedelta(days=1)).strftime("%Y-%m-%d")
-    #else:
-    #    today = datetime.datetime.now().strftime("%Y-%m-%d")
-
-    today = get_today_date()
-    #players = list(cm.Player.objects.filter(match_id=match_id,match_group=group_id).values())
     players = get_match_group_players(match_id,group_id)
     players = get_match_group_players(match_id,group_id)
     new_players = []
     new_players = []
     for player in players:
     for player in players:
@@ -331,12 +375,24 @@ def get_group_rank_list(request):
         if today_record:
         if today_record:
             player.update(today_record)
             player.update(today_record)
             player["username"] = username
             player["username"] = username
+            player["org_today_income"] = player["today_income"]
+            player["org_total_income"] = player["total_income"]
             player["total_income"] = "{}%".format(player["total_income"]*100)
             player["total_income"] = "{}%".format(player["total_income"]*100)
+            player["today_income"] = "{}%".format(player["today_income"]*100)
             player["fund"] = round(player["fund"],4)
             player["fund"] = round(player["fund"],4)
             player["init_fund"] = round(player["init_fund"],4)
             player["init_fund"] = round(player["init_fund"],4)
             player["today_fund"] = round(player["today_fund"],4)
             player["today_fund"] = round(player["today_fund"],4)
             new_players.append(player)
             new_players.append(player)
-    new_players = sorted(new_players,key=lambda x:x["group_rank"])
+    if kwargs.get("order_by") == "today_income__asc":
+        new_players = sorted(new_players,key=lambda x:x["org_today_income"])
+    elif kwargs.get("order_by") == "today_income__desc" :
+        new_players = sorted(new_players,key=lambda x:x["org_today_income"],reverse=True)
+    elif kwargs.get("order_by") == "total_income__asc": 
+        new_players = sorted(new_players,key=lambda x:x["org_total_income"])
+    elif kwargs.get("order_by") == "total_income__desc": 
+        new_players = sorted(new_players,key=lambda x:x["org_total_income"],reverse=True)
+    else:
+        new_players = sorted(new_players,key=lambda x:x["group_rank"])
 
 
     #分页
     #分页
     page = int(kwargs.get("page",0))
     page = int(kwargs.get("page",0))
@@ -346,7 +402,16 @@ def get_group_rank_list(request):
         total,new_players = ccf.get_page_list(new_players,page,page_size)
         total,new_players = ccf.get_page_list(new_players,page,page_size)
     else:
     else:
         total = len(new_players)
         total = len(new_players)
-    ret = {"group":group,"players":new_players,"total":total}
+    #应到、实到、请假人数
+    total_person = cm.Player.objects.filter(match_group=group_id,match_status=1).count()
+    actual_person = cm.PlayerRecord.objects.filter(match_group=group_id,stock_date=today).count()
+    leave_person = total_person - actual_person
+
+    win_person = cm.PlayerRecord.objects.filter(match_group=group_id,stock_date=today,total_income__gte=0).count()
+    loss_person = cm.PlayerRecord.objects.filter(match_group=group_id,stock_date=today,total_income__lt=0).count()
+
+    ret = {"group":group,"players":new_players,"total":total,"total_person":total_person,
+        "actual_person":actual_person,"leave_person":leave_person,"win_person":win_person,"loss_person":loss_person}
 
 
     return ret
     return ret
 
 
@@ -423,6 +488,11 @@ def add_model(cls,**kwargs):
         username = user.username
         username = user.username
         usercode = user.usercode
         usercode = user.usercode
         match_group = player.match_group
         match_group = player.match_group
+        zq = user.zq
+        cw = user.cw
+        df = user.df
+        badge = player.badge
+
         match = cm.Match.objects.filter(id=match_id).first()
         match = cm.Match.objects.filter(id=match_id).first()
         if player.match_status < 1:
         if player.match_status < 1:
             raise ce.TipException(u"该账号已暂停/退出比赛,如有疑问请联系管理员获取详情信息!")
             raise ce.TipException(u"该账号已暂停/退出比赛,如有疑问请联系管理员获取详情信息!")
@@ -445,6 +515,24 @@ def add_model(cls,**kwargs):
             yesterday_stock_img = "" 
             yesterday_stock_img = "" 
             yesterday_is_markt = 0
             yesterday_is_markt = 0
         with transaction.atomic():
         with transaction.atomic():
+            #记录持股情况
+            new_stock_list = []
+            today_stock_list = json.loads(today_stock)
+            for ts in today_stock_list:
+                if ts["name"]:
+                    stock,flag = cm.Stock.objects.get_or_create(
+                        name = ts["name"] 
+                    )
+                    stock_id = stock.id
+                    usobj,flag = cm.UserStock.objects.get_or_create(
+                        player_id = player_id, 
+                        stock_id = stock_id,
+                        stock_date = stock_date
+                    )
+                    ts["stock_id"] = stock_id
+                    new_stock_list.append(ts)
+            today_stock = json.dumps(new_stock_list)
+
             obj,flag = cm.PlayerRecord.objects.get_or_create(
             obj,flag = cm.PlayerRecord.objects.get_or_create(
                             player_id=player_id,
                             player_id=player_id,
                             match_id=match_id,
                             match_id=match_id,
@@ -462,6 +550,10 @@ def add_model(cls,**kwargs):
             obj.match_group = match_group
             obj.match_group = match_group
             obj.is_markt = is_markt
             obj.is_markt = is_markt
             obj.yesterday_is_markt = yesterday_is_markt
             obj.yesterday_is_markt = yesterday_is_markt
+            obj.zq = zq
+            obj.cw = cw
+            obj.df = df
+            obj.badge = badge
             #计算今日和昨日盈亏
             #计算今日和昨日盈亏
             if float(today_fund)>9999 or float(today_fund)<=0:                              
             if float(today_fund)>9999 or float(today_fund)<=0:                              
                 raise ce.TipException(u"数据错误,今日净资产不能超过9999万元,不能低于0万元,请仔细核对数据!")                                                                                                                                                                       
                 raise ce.TipException(u"数据错误,今日净资产不能超过9999万元,不能低于0万元,请仔细核对数据!")                                                                                                                                                                       
@@ -477,8 +569,11 @@ def add_model(cls,**kwargs):
                 obj.ctime = datetime.datetime.now()
                 obj.ctime = datetime.datetime.now()
             obj.save()
             obj.save()
 
 
+            #更新股票持股人数
+            for stock in new_stock_list:
+                cm.Stock.objects.filter(id=stock["stock_id"]).update(user_num=F("user_num")+1)
+
             #更新group_rank
             #更新group_rank
-            #update_group_rank(match_id,match_group,obj.stock_date)
             ccc.cache.lpush(settings.RANK_LIST,obj.id)
             ccc.cache.lpush(settings.RANK_LIST,obj.id)
             return obj.id
             return obj.id
 
 
@@ -515,14 +610,21 @@ def get_search_list(cls,**kwargs):
     model_name = re.search(r'.*\.(\w+)SearchView',str(cls.__class__)).groups()[0]
     model_name = re.search(r'.*\.(\w+)SearchView',str(cls.__class__)).groups()[0]
     model = getattr(cm,model_name)
     model = getattr(cm,model_name)
     qset = model.objects.all()
     qset = model.objects.all()
-    if kwargs.get("name"):
-        qset = qset.filter(name__icontains=kwargs.get("name"))
+    if model_name == "Stock":
+        if kwargs.get("name"):
+            qset = qset.filter(Q(name__icontains=kwargs.get("name"))|Q(code__icontains=kwargs.get("name")))
+    else:
+        if kwargs.get("name"):
+            qset = qset.filter(name__icontains=kwargs.get("name"))
     if model_name == "Player":
     if model_name == "Player":
         data = list(qset.values("id","username"))
         data = list(qset.values("id","username"))
     if model_name == "Stock":
     if model_name == "Stock":
         data = list(qset.values("id","name","code"))
         data = list(qset.values("id","name","code"))
         for item in data:
         for item in data:
-            item["label"] = "%s(%s)" % (item["name"],item["code"])
+            if item["code"]:
+                item["label"] = "%s(%s)" % (item["name"],item["code"])
+            else:
+                item["label"] = "%s" % item["name"]
     else:
     else:
         data = list(qset.values("id","name"))
         data = list(qset.values("id","name"))
     return data
     return data
@@ -552,6 +654,8 @@ def get_detail_info(cls,**kwargs):
 
 
     #    rst["today_income"] = "{}%".format(rst["today_income"]*100)
     #    rst["today_income"] = "{}%".format(rst["today_income"]*100)
     #    rst["total_income"] = "{}%".format(rst["total_income"]*100)
     #    rst["total_income"] = "{}%".format(rst["total_income"]*100)
+    if model_name == "Article":
+        rst["ctime"] = ccf.datetime_to_str(rst["ctime"],"%Y-%m-%d")
     return rst
     return rst
 
 
 #@ccc.cache_data()
 #@ccc.cache_data()
@@ -656,6 +760,25 @@ def add_player_record_single(**kwargs):
         yesterday_fund = init_fund 
         yesterday_fund = init_fund 
         yesterday_stock = ""
         yesterday_stock = ""
         yesterday_stock_img = "" 
         yesterday_stock_img = "" 
+
+    #记录持股情况
+    new_stock_list = []
+    today_stock_list = json.loads(today_stock)
+    for ts in today_stock_list:
+        if ts["name"]:
+            stock,flag = cm.Stock.objects.get_or_create(
+                name = ts["stock"] 
+            )
+            stock_id = stock.id
+            usobj,flag = cm.UserStock.objects.get_or_create(
+                player_id = player_id, 
+                stock_id = stock_id,
+                stock_date = stock_date
+            )
+            ts["stock_id"] = stock_id
+            new_stock_list.append(ts)
+    today_stock = json.dumps(new_stock_list)
+
     obj,flag = cm.PlayerRecord.objects.get_or_create(
     obj,flag = cm.PlayerRecord.objects.get_or_create(
                     player_id=player_id,
                     player_id=player_id,
                     match_id=match_id,
                     match_id=match_id,
@@ -676,15 +799,20 @@ def add_player_record_single(**kwargs):
     today_income = (today_fund - yesterday_fund)/float(yesterday_fund)
     today_income = (today_fund - yesterday_fund)/float(yesterday_fund)
     total_income = (today_fund - init_fund)/float(init_fund)
     total_income = (today_fund - init_fund)/float(init_fund)
     if int(today_fund)>9999 or int(today_fund)<0:                              
     if int(today_fund)>9999 or int(today_fund)<0:                              
-        raise ce.TipException(u"数据错误,今日净资产不能超过9999万元,不能低于0万元,请仔细核对数据!")                                                                                                                                                                       
+        raise ce.TipException(u"数据错误,今日净资产不能超过9999万元,不能低于0万元,请仔细核对数据!") 
     if int(today_income)>2:                                                    
     if int(today_income)>2:                                                    
         raise ce.TipException(u"数据错误,今日盈利已超过2倍,请仔细核对数据!")
         raise ce.TipException(u"数据错误,今日盈利已超过2倍,请仔细核对数据!")
+
     obj.today_income = round(today_income,4)
     obj.today_income = round(today_income,4)
     obj.total_income = round(total_income,4)
     obj.total_income = round(total_income,4)
     if not flag:
     if not flag:
         obj.ctime = datetime.datetime.now()
         obj.ctime = datetime.datetime.now()
     obj.save()
     obj.save()
 
 
+    #更新股票持股人数
+    for stock in new_stock_list:
+        cm.Stock.objects.filter(id=stock["id"]).update(user_num=F("user_num")+1)
+
     #更新group_rank
     #更新group_rank
     #update_group_rank(match_id,match_group,obj.stock_date)
     #update_group_rank(match_id,match_group,obj.stock_date)
     ccc.cache.lpush(settings.RANK_LIST,obj.id)
     ccc.cache.lpush(settings.RANK_LIST,obj.id)
@@ -719,3 +847,562 @@ def get_cur_record(request):
         data["today_stock"] = json.loads(data["today_stock"]) if data["today_stock"] else []
         data["today_stock"] = json.loads(data["today_stock"]) if data["today_stock"] else []
     return data
     return data
 
 
+
+def follow_player(**kwargs):
+    """
+    """
+    user_id = kwargs.get("player_id")
+    follow_id = kwargs.get("follow_id")
+    if kwargs.get("action") == "cancel":
+        cm.UserFollows.objects.filter(user_id=user_id,follow_id=follow_id).delete()
+        return True
+    else:
+        obj,flag = cm.UserFollows.objects.get_or_create(user_id=user_id,follow_id=follow_id)
+        return obj.id
+
+def calc_win_rate(player_id,match_id):
+    """计算胜率
+    """
+    qset = cm.PlayerRecord.objects.filter(match_id=match_id,player_id=player_id)
+    win_rate = qset.filter(today_income__gte=0).count()/float(qset.count()) if qset else 0.0
+    win_rate = round(win_rate,3)
+    win_rate = "{}%".format(win_rate*100)
+    return win_rate
+
+
+def get_user_follows(request):
+    """获取用户关注的选手列表
+    """
+    user_id = request.player.id
+    print user_id
+    match_id = request.player.match_id
+    match_group = request.player.match_group
+    qdata = request.json
+    today = get_today_date()
+    print today
+
+    data = []
+
+    qset = cm.UserFollows.objects.filter(user_id=user_id)
+    follow_ids = list(qset.values_list("follow_id",flat=True))
+
+    for player_id in follow_ids:
+        last = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id).order_by("-stock_date").first()
+        if last:
+            today = last.stock_date
+
+            today_record = get_today_record(player_id,match_id,last.match_group,today)
+            if today_record:
+                data.append(today_record)
+    data = sorted(data,key=lambda x:x["group_rank"])
+    page = int(qdata.get("page",1))
+    page_size = int(qdata.get("page_size",20))
+
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+        for item in data:
+            item["today_stock"] = json.loads(item["today_stock"])
+            item["today_stock_img"] = json.loads(item["today_stock_img"])
+            item["win_rate"] = calc_win_rate(item["player_id"],item["match_id"])
+            item["today_income"] = "{}%".format(item["today_income"]*100)
+            item["total_income"] = "{}%".format(item["total_income"]*100)
+        return total,data
+    else:
+        return len(data),data
+
+
+def get_hot_stock_rank(**kwargs):
+    """
+    """
+    data = {
+            "hot_buy":[
+                {"stock_name":u"创业黑马","count":12} 
+            ],
+            "hot_sell":[
+                {"stock_name":u"创业黑马","count":12} 
+            ]
+        }
+    return data
+
+
+def get_hot_stock_buy(**kwargs):
+    """
+    """
+    stock_date = kwargs.get("stock_date")
+    qset = cm.UserStock.objects.filter(stock_date=stock_date)
+    qset = qset.values("stock_id").annotate(count=Count("stock_id")).order_by("-count")
+    data = []
+    for q in qset:
+        stock_id = q["stock_id"]
+        count = q["count"]
+        data.append(
+            {
+                "stock_name":cm.Stock.objects.filter(id=stock_id).first().name,
+                "count":count,
+                "id":stock_id
+            } 
+        )
+
+    if kwargs.get("name"):
+        data = filter(lambda x:kwargs.get("name") in x["stock_name"],data)
+
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+        return total,data
+    else:
+        return len(data),data
+    return data
+
+
+def get_hot_follow(**kwargs):
+    """
+    """
+    stock_date = kwargs.get("stock_date")
+    #qset = cm.UserFollows.objects.filter(stock_date=stock_date)
+    qset = cm.UserFollows.objects.all()
+    qset = qset.values("follow_id").annotate(count=Count("follow_id")).order_by("-count")
+    data = []
+    for q in qset:
+        player_id = q["follow_id"]
+        count = q["count"]
+        player = cm.Player.objects.filter(id=player_id).first()
+        today = cm.PlayerRecord.objects.filter(player_id=player_id).order_by("-stock_date").first().stock_date
+        badest_income = cm.PlayerRecord.objects.filter(player_id=player_id).order_by("-today_income").first().today_income
+        today_record = get_today_record(player_id,int(player.match_id),int(player.match_group),today)
+        userinfo = get_user_info(today_record["user_id"])
+
+        data.append(
+            {
+                "player_name":player.username,
+                "count":count,
+                "id":player_id,
+                "today_fund":today_record["today_fund"],
+                "total_income":"{}%".format(today_record["total_income"]*100),
+                "today_income":"{}%".format(today_record["today_income"]*100),
+                "badest_income":"{}%".format(badest_income*100),
+                "style":userinfo.get("style"),
+                "badge":userinfo.get("badge"),
+                "match_id":player.match_id,
+                "win_rate":calc_win_rate(player_id,player.match_id)
+            } 
+        )
+
+    if kwargs.get("name"):
+        data = filter(lambda x:kwargs.get("name") in x["player_name"],data)
+
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+        return total,data
+    else:
+        return len(data),data
+    return data
+
+
+def get_hot_stock_sell(**kwargs):
+    """
+    """
+    stock_date = kwargs.get("stock_date")
+    stock_date_time = ccf.str_to_datetime(kwargs.get("stock_date"),"%Y-%m-%d")
+    yesterday = (stock_date_time - datetime.timedelta(days=1)).strftime("%Y-%m-%d")
+
+    ##昨天所有股票
+    #yes_stock_ids = list(cm.UserStock.objects.filter(stock_date=yesterday).values_list("stock_id",flat=True))
+    #yes_stock_ids = list(set(yes_stock_ids))
+    #data = []
+    #for ysi in yes_stock_ids:
+    #    yes_count = cm.UserStock.objects.filter(stock_date=yesterday,stock_id=ysi).count()
+    #    td_count = cm.UserStock.objects.filter(stock_date=stock_date,stock_id=ysi).count()
+    #    if td_count < yes_count:
+    #        stock_name = cm.Stock.objects.filter(id=ysi).first().name
+    #        data.append({"stock_name":stock_name,"count":yes_count-td_count,"id":ysi})
+    qset = cm.HotStockSellCount.objects.filter(stock_date=stock_date).order_by("-count")
+
+    data = list(qset.values("stock_name","stock_id","count"))
+    for item in data:
+        item["id"] = item["stock_id"]
+
+    page = int(kwargs.get("page",0))
+    page_size = int(kwargs.get("page_size",20))
+
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+        return total,data
+    else:
+        return len(data),data
+    return data
+
+
+def get_stock_info(_id):
+    """
+    """
+    data = cm.Stock.objects.filter(id=_id).values().first()
+    return data
+
+
+def get_hot_stock_sell_players(**kwargs):
+    """
+    """
+    _id = kwargs.get("id")
+    stock_date = kwargs.get("stock_date")
+    stock_date_time = ccf.str_to_datetime(kwargs.get("stock_date"),"%Y-%m-%d")
+    yesterday = (stock_date_time - datetime.timedelta(days=1)).strftime("%Y-%m-%d")
+
+    #昨天持股选手
+    yes_players = list(cm.UserStock.objects.filter(stock_date=yesterday,stock_id=_id).values_list("player_id",flat=True))
+    td_players = list(cm.UserStock.objects.filter(stock_date=stock_date,stock_id=_id).values_list("player_id",flat=True))
+    sell_players = list(set(yes_players)-set(td_players))
+
+    data = []
+    for player_id in sell_players:
+        player = cm.Player.objects.filter(id=player_id).first()
+        if player:
+            match_id = player.match_id
+            match_group = player.match_group
+            today_record = get_today_record(player_id,match_id,match_group,stock_date)
+
+            if today_record:
+                today_record["today_stock_img"] = json.loads(today_record["today_stock_img"]) if today_record["today_stock_img"] else []
+                today_record["today_stock"] = json.loads(today_record["today_stock"]) if today_record["today_stock"] else []
+                today_record["today_income"] = "{}%".format(today_record["today_income"]*100)
+                today_record["total_income"] = "{}%".format(today_record["total_income"]*100)
+                data.append(today_record)
+
+    page = int(kwargs.get("page",0))
+    page_size = int(kwargs.get("page_size",20))
+
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+        return total,data
+    else:
+        return len(data),data
+    return data
+
+
+def get_win_rate_rank(request):
+    """
+    """
+    player_id = request.player.id
+    match_id = request.player.match_id
+    match_group = request.player.match_group
+    kwargs = request.json
+
+    qset = cm.WinDefendRank.objects.filter(match_id=match_id).order_by("-win_rate")
+    data = list(qset.values())
+
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+    else:
+        total = len(data)
+    for item in data:
+        item["win_rate"] = "{}%".format(item["win_rate"]*100)
+        item["badest_income"] = "{}%".format(item["badest_income"]*100)
+        item["total_income"] = "{}%".format(item["total_income"]*100)
+        userinfo = get_user_info(item["user_id"])
+        item["badge"] = userinfo.get("badge")
+        item["style"] = userinfo.get("style")
+
+
+    return total,data
+
+
+def get_defend_rank(request):
+    """
+    """
+    player_id = request.player.id
+    match_id = request.player.match_id
+    match_group = request.player.match_group
+    kwargs = request.json
+
+    qset = cm.WinDefendRank.objects.filter(match_id=match_id).order_by("-badest_income")
+    data = list(qset.values())
+
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+    else:
+        total = len(data)
+    for item in data:
+        item["win_rate"] = "{}%".format(item["win_rate"]*100)
+        item["badest_income"] = "{}%".format(item["badest_income"]*100)
+        item["total_income"] = "{}%".format(item["total_income"]*100)
+        item["style"] = []
+        if item["zq"]:
+            item["style"].apepnd(item["zq"])
+        if item["cw"]:
+            item["style"].apepnd(item["cw"])
+        if item["df"]:
+            item["style"].apepnd(item["df"])
+        item["badge"] = cm.Player.objects.filter(id=item["player_id"]).first().badge
+
+    return total,data
+
+
+def get_champion_articles_list(request):
+    """
+    """
+    kwargs = request.json
+    qset = cm.Article.objects.filter(status=2,type="champion")
+
+    page = int(kwargs.get("page",0))
+    page_size = int(kwargs.get("page_size",20))
+
+    if page and page_size:
+        total,qset = ccf.get_page_qset(qset,page,page_size)
+    else:
+        total = qset.count()
+    data = list(qset.values())
+    for item in data:
+        item["ctime"] = ccf.datetime_to_str(item["ctime"],"%Y-%m-%d")
+    return total,data
+
+def get_wanzhu_comment(**kwargs):
+    """
+    """
+    match_id = kwargs.get("match_id")
+    group_id = kwargs.get("group_id")
+    print match_id
+    today = get_today_date()
+    players = get_match_group_players(match_id,group_id)
+    new_players = []
+    for player in players:
+        user_id = player["user_id"]
+        user = get_user_info(user_id) 
+        username = user["username"] if user else ""
+
+        player_id = player["id"]
+        match_group = group_id
+        today_record = get_today_record(player_id,match_id,int(match_group),today)
+        if today_record and today_record.get("wanzhu_comment"):
+            player.update(today_record)
+            player["username"] = username
+            player["total_income"] = "{}%".format(player["total_income"]*100)
+            player["fund"] = round(player["fund"],4)
+            player["init_fund"] = round(player["init_fund"],4)
+            player["today_fund"] = round(player["today_fund"],4)
+            player["today_stock"] = json.loads(player["today_stock"]) if player["today_stock"] else []
+            new_players.append(player)
+    new_players = sorted(new_players,key=lambda x:x["group_rank"])
+    data = new_players
+
+    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)
+    else:
+        total = len(data)
+
+    return total,data
+
+
+def get_enum_list(request):
+    """
+    """
+    data = {
+        "zq":[
+            u"短线博弈", 
+            u"长线价投", 
+            u"长短兼备" 
+        ], 
+        "cw":[
+            u"分仓开超市", 
+            u"重仓押注", 
+            u"全仓单钓", 
+            u"融资加倍" 
+        ], 
+        "df":[
+            u"低吸", 
+            u"半路", 
+            u"首板", 
+            u"接力", 
+            u"撬板", 
+            u"T加0",
+            u"隔夜卖",
+            u"格局锁仓",
+            u"核按钮"
+        ], 
+        "pz":[
+            u"N/C字头新股", 
+            u"次新股", 
+            u"可转债", 
+            u"港股", 
+            u"基金", 
+            u"逆回购" 
+        ]
+    }
+    return data
+
+def get_player_list(**kwargs):
+    """选手列表
+    """
+    match_id = kwargs.get("match_id")
+    today = get_today_date()
+
+    qset = cm.Player.objects.filter(match_id=match_id,match_status=1)
+    if kwargs.get("name"):
+        qset = qset.filter(username__icontains=kwargs.get("name"))
+    data = list(qset.values())
+
+    for item in data:
+        match_id = item["match_id"]
+        match_group = item["match_group"]
+        user_id = item["user_id"]
+        player_id = item["id"]
+        #user = cm.UserInfo.objects.filter(id=user_id).first()
+        today_record = get_today_record(player_id,match_id,match_group,today)
+        if today_record:
+            today_record.pop("id")
+            item.update(today_record)
+        user_info = get_user_info(user_id)
+        if user_info:
+            user_info.pop("id")
+            item.update(user_info)
+
+    if kwargs.get("zq"):
+        data = filter(lambda x:kwargs.get("zq") == x["zq"],data)
+    if kwargs.get("cw"):
+        data = filter(lambda x:kwargs.get("cw") == x["cw"],data)
+    if kwargs.get("df"):
+        data = filter(lambda x:kwargs.get("df") == x["df"],data)
+
+    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)
+    else:
+        total = len(data)
+
+    return total,data
+
+
+def get_mine_style(request):
+    """
+    """
+    user = request.user
+    player = request.player
+    data = {
+        "zq":user.zq,     
+        "cw":user.cw,     
+        "df":user.df,     
+        "pz":user.pz,     
+        "join_time":user.join_time,     
+        "account_img":user.account_img,     
+    }
+    if player:
+        data["is_player"] = 1
+        data["init_fund"] = player.fund
+    else:
+        data["is_player"] = 0
+        data["init_fund"] = None
+    return data
+
+
+def update_user_style(**kwargs):
+    """
+    """
+    user_id = kwargs.pop("user_id")
+    player_id = kwargs.pop("player_id")
+    init_fund = kwargs.pop("init_fund")
+    cm.UserInfo.objects.filter(id=user_id).update(**kwargs)
+    if player_id and init_fund:
+        cm.Player.objects.filter(id=player_id).update(fund=init_fund)
+    return True
+
+
+def get_stock_players(**kwargs):
+    """
+    """
+    stock_id = kwargs.get("stock_id")
+    stock_date = kwargs.get("stock_date")
+    data = []
+    user_stocks = cm.UserStock.objects.filter(stock_id=stock_id,stock_date=stock_date)
+    for us in user_stocks:
+        player_id = us.player_id
+        player = cm.Player.objects.filter(id=player_id).first()
+        if player:
+            match_id = player.match_id
+            match_group = player.match_group
+            if stock_date:
+                today_record = get_today_record(player_id,match_id,match_group,stock_date)
+            else:
+                today_record = get_today_record(player_id,match_id,match_group,us.stock_date)
+            if today_record:
+                today_record["today_stock_img"] = json.loads(today_record["today_stock_img"]) if today_record["today_stock_img"] else []
+                today_record["today_stock"] = json.loads(today_record["today_stock"]) if today_record["today_stock"] else []
+                today_record["today_income"] = "{}%".format(today_record["today_income"]*100)
+                today_record["total_income"] = "{}%".format(today_record["total_income"]*100)
+                data.append(today_record)
+
+    #分页
+    page = int(kwargs.get("page",1))
+    page_size = int(kwargs.get("page_size",20))
+    if page and page_size:
+        total,data = ccf.get_page_list(data,page,page_size)
+    else:
+        total = len(data)
+
+    return data
+        
+
+def update_user_fund(**kwargs):
+    """
+    """
+    user_id = kwargs.pop("user_id")
+    player_id = kwargs.pop("player_id")
+    init_fund = kwargs.pop("init_fund")
+    if player_id and init_fund:
+        cm.Player.objects.filter(id=player_id).update(fund=init_fund)
+    return True
+
+
+def get_player_match_calendar(**kwargs):
+    """
+    """
+    player_id = kwargs.get("player_id")
+    match_id = kwargs.get("match_id")
+    month = kwargs.get("month")
+
+    print kwargs
+
+    week,eday = calendar.monthrange(int(month.split("-")[0]),int(month.split("-")[1]))
+    sday = "01"
+    eday = str(eday).zfill(2)
+    sdate = month + "-" + sday
+    edate = month + "-" + eday
+
+    print sdate,edate
+
+    qset = cm.PlayerRecord.objects.filter(player_id=player_id,match_id=match_id)\
+        .filter(stock_date__gte=sdate,stock_date__lte=edate)
+    data = list(qset.values())
+
+    dct = {}
+    for item in data:
+        item["today_income"] = "{}%".format(item["today_income"]*100)
+        dct[item["stock_date"]] = item["today_income"]
+
+    newdata = []
+    for i in range(1,int(eday)+1):
+        stock_date = month + "-" + str(i).zfill(2)
+        newdata.append({
+            "stock_date":stock_date,     
+            "today_income":dct.get(stock_date,""),     
+        })
+
+    return newdata
+
+
+
+

+ 21 - 1
src/weixin/urls_backstage.py

@@ -5,7 +5,7 @@ from django.conf.urls import url
 from . import views
 from . import views
 
 
 urlpatterns = [
 urlpatterns = [
-    # 运营
+    #1.0
     url(r'^uploadfile$', views.UploadFileView.as_view()),
     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()),
@@ -24,6 +24,26 @@ urlpatterns = [
     url(r'^group/rank$', views.GroupRankView.as_view()),
     url(r'^group/rank$', views.GroupRankView.as_view()),
     url(r'^player/currecord$', views.PlayerCurRecordView.as_view()),
     url(r'^player/currecord$', views.PlayerCurRecordView.as_view()),
     url(r'^article$', views.ArticleView.as_view()),
     url(r'^article$', views.ArticleView.as_view()),
+    url(r'^player/fund$', views.PlayerFundView.as_view()),
+    #2.0
+    url(r'^v2/user/follow$', views.FollowUserView.as_view()),
+    url(r'^v2/user/follow/list$', views.FollowUserListView.as_view()),
+    url(r'^v2/hot/stock/rank$', views.HotStockListView.as_view()),
+    url(r'^v2/hot/stock/buy/list$', views.HotStockBuyListView.as_view()),
+    url(r'^v2/hot/stock/sell/list$', views.HotStockSellListView.as_view()),
+    url(r'^v2/hot/stock/sell/players$', views.HotStockSellPlayersListView.as_view()),
+    url(r'^v2/hot/follow/list$', views.HotFollowListView.as_view()),
+    url(r'^v2/winrate/rank$', views.WinRateRankView.as_view()),
+    url(r'^v2/defend/rank$', views.DefendRankView.as_view()),
+    url(r'^v2/champion/article/list$', views.ChampionArticleListView.as_view()),
+    url(r'^v2/wanzhu/comment/list$', views.WanzhuCommentListView.as_view()),
+    url(r'^v2/enum/list$', views.EnumListView.as_view()),
+    url(r'^v2/player/list$', views.PlayerListView.as_view()),
+    url(r'^v2/mine/style$', views.MineStyleView.as_view()),
+    url(r'^v2/stock$', views.StockView.as_view()),
+    url(r'^v2/notices/list$', views.NoticesListView.as_view()),
+    url(r'^v2/default/date$', views.DefaultDateView.as_view()),
+    url(r'^v2/player/match/calendar$', views.PlayerMatchCalendarView.as_view()),
 
 
 ]
 ]
 
 

+ 369 - 2
src/weixin/views.py

@@ -178,7 +178,7 @@ class PlayerRecordView(cv.AuthView):
         if mse:
         if mse:
             raise ce.TipException(mse)
             raise ce.TipException(mse)
         try:
         try:
-            need_params.extend(["is_markt","today_stock","today_stock_img"])
+            need_params.extend(["is_markt","today_stock","today_stock_img","experience"])
             vals = ccf.get_need_params(*need_params,**qdata)
             vals = ccf.get_need_params(*need_params,**qdata)
             vals["player_id"] = player.id
             vals["player_id"] = player.id
             vals["match_id"] = player.match_id
             vals["match_id"] = player.match_id
@@ -286,7 +286,7 @@ class PlayerRecordSingleView(cv.BaseView):
         if mse:
         if mse:
             raise ce.TipException(mse)
             raise ce.TipException(mse)
         try:
         try:
-            need_params.extend(["is_markt","today_stock"])
+            need_params.extend(["is_markt","today_stock","experience"])
             vals = ccf.get_need_params(*need_params,**qdata)
             vals = ccf.get_need_params(*need_params,**qdata)
             vals["today_fund"] = round(float(vals["today_fund"]),4)
             vals["today_fund"] = round(float(vals["today_fund"]),4)
             rst = ctl.add_player_record_single(**vals)
             rst = ctl.add_player_record_single(**vals)
@@ -338,7 +338,374 @@ class ArticleView(cv.AuthView):
             vals = ccf.get_need_params(*need_params,**qdata)                       
             vals = ccf.get_need_params(*need_params,**qdata)                       
             rst = ctl.get_detail_info(self,**vals)                                 
             rst = ctl.get_detail_info(self,**vals)                                 
             return cv.to_suc(rst)                                                  
             return cv.to_suc(rst)                                                  
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+class FollowUserView(cv.AuthView):                                                    
+    def post(self, request):                                                        
+        """#关注选手(2.0小程序)                                                       
+        @follow_id:1,被关注选手id
+        @action:"cancel",取消关注
+        """                                                                        
+        qdata = request.json                                                       
+        need_params = ["follow_id"]                                                       
+        mse = ccf.check_params(*need_params,**qdata)                               
+        if mse:                                                                    
+            raise ce.TipException(mse)                                             
+        try:                                                                       
+            need_params.extend(["action"])
+            vals = ccf.get_need_params(*need_params,**qdata)                       
+            vals["player_id"] = request.player.id
+            rst = ctl.follow_player(**vals)
+            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 FollowUserListView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#我的关注(2.0小程序)                                                       
+        """                                                                        
+        try:                                                                       
+            total,rst = ctl.get_user_follows(request)                                 
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class HotStockListView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#热门股票(2.0小程序)                                                       
+        @stock_date:"",持股日期
+        """                                                                        
+        qdata = request.json                                                       
+        need_params = ["stock_date"]                                                       
+        mse = ccf.check_params(*need_params,**qdata)                               
+        if mse:                                                                    
+            raise ce.TipException(mse)                                             
+        try:                                                                       
+            need_params.extend(["name"])
+            vals = ccf.get_need_params(*need_params,**qdata)                       
+            rst = ctl.get_hot_stock_rank(**vals)                                 
+            return cv.to_suc(rst)
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+class HotFollowListView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#热门关注(2.0小程序)
+        @stock_date:"",持股日期
+        @page:1
+        @page_size:20
+        """                                                                        
+        qdata = request.json                                                       
+        need_params = ["stock_date"]                                                       
+        mse = ccf.check_params(*need_params,**qdata)                               
+        if mse:                                                                    
+            raise ce.TipException(mse)                                             
+        try:                                                                       
+            need_params.extend(["name"])
+            vals = ccf.get_need_params(*need_params,**qdata)                       
+            total,rst = ctl.get_hot_follow(**vals)                                 
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+class HotStockBuyListView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#热门持仓股票(2.0小程序)
+        @stock_date:"",持股日期
+        @page:1
+        @page_size:20
+        """                                                                        
+        qdata = request.json                                                       
+        need_params = ["stock_date"]                                                       
+        mse = ccf.check_params(*need_params,**qdata)                               
+        if mse:                                                                    
+            raise ce.TipException(mse)                                             
+        try:                                                                       
+            need_params.extend(["name"])
+            vals = ccf.get_need_params(*need_params,**qdata)                       
+            total,rst = ctl.get_hot_stock_buy(**vals)                                 
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class HotStockSellListView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#热门清仓股票(2.0小程序)
+        @stock_date:"",持股日期
+        @page:1
+        @page_size:20
+        """                                                                        
+        qdata = request.json                                                       
+        need_params = ["stock_date"]                                                       
+        mse = ccf.check_params(*need_params,**qdata)                               
+        if mse:                                                                    
+            raise ce.TipException(mse)                                             
+        try:                                                                       
+            vals = ccf.get_need_params(*need_params,**qdata)                       
+            total,rst = ctl.get_hot_stock_sell(**vals)                                 
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class HotStockSellPlayersListView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#获取股票清仓选手列表(2.0小程序)
+        @id:"",股票id
+        @stock_date:"",持股日期
+        @page:1
+        @page_size:20
+        """                                                                        
+        qdata = request.json                                                       
+        need_params = ["stock_date","id"]                                                       
+        mse = ccf.check_params(*need_params,**qdata)                               
+        if mse:                                                                    
+            raise ce.TipException(mse)                                             
+        try:                                                                       
+            vals = ccf.get_need_params(*need_params,**qdata)                       
+            _id = vals["id"]
+            total,rst = ctl.get_hot_stock_sell_players(**vals)                                 
+            data =  {"total":total,"list":rst}
+            stock = ctl.get_stock_info(_id)
+            data.update(stock)
+            return cv.to_suc(data)
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class WinRateRankView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#胜率榜(2.0小程序)                                                       
+        """                                                                        
+        try:                                                                       
+            total,rst = ctl.get_win_rate_rank(request)                                 
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class DefendRankView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#防守榜(2.0小程序)                                                       
+        """                                                                        
+        try:                                                                       
+            total,rst = ctl.get_defend_rank(request)                                 
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class ChampionArticleListView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#冠军心得(2.0小程序)                                                       
+        """                                                                        
+        try:                                                                       
+            total,rst = ctl.get_champion_articles_list(request)                                 
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class WanzhuCommentListView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#顽主点评(2.0小程序)
+        @group_id:1,分组id
+        @page:1
+        @page_size:20
+        """                                                                        
+        qdata = request.json                                                       
+        need_params = ["group_id","page","page_size"]                                                       
+        mse = ccf.check_params(*need_params,**qdata)                               
+        if mse:                                                                    
+            raise ce.TipException(mse)                                             
+        try:                                                                       
+            vals = ccf.get_need_params(*need_params,**qdata)                       
+            vals["match_id"] = request.player.match_id
+            total,rst = ctl.get_wanzhu_comment(**vals)                                 
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class EnumListView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#枚举值(2.0小程序)
+        """                                                                        
+        try:                                                                       
+            rst = ctl.get_enum_list(request)
+            return cv.to_suc(rst)
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class PlayerListView(cv.AuthView):                                                    
+    def get(self, request):                                                        
+        """#选手列表搜索(2.0小程序)
+        @name:"选手名"
+        @zq:"短线",周期
+        @cw:"分仓",仓位
+        @df:"首板",打法
+        @page:1
+        @page_size:20
+        """                                                                        
+        qdata = request.json                                                       
+        need_params = ["page","page_size"]                                                       
+        mse = ccf.check_params(*need_params,**qdata)                               
+        if mse:                                                                    
+            raise ce.TipException(mse)                                             
+        try:                                                                       
+            need_params.extend(["name","zq","cw","df"])
+            vals = ccf.get_need_params(*need_params,**qdata)                       
+            vals["match_id"] = request.player.match_id
+            total,rst = ctl.get_player_list(**vals)                                 
+            return cv.to_suc({"total":total,"list":rst})
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class MineStyleView(cv.AuthView):
+    def get(self, request):
+        """#我的风格(2.0小程序)
+        """
+        try:
+            rst = ctl.get_mine_style(request)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+    def put(self, request):
+        """#修改我的风格(小程序)
+        @zq:"",周期
+        @cw:"",仓位
+        @df:"",打法
+        @pz:"",品种
+        @join_time:"",入市时间
+        @init_fund:"",参数金额
+        @account_img:"",账号截图
+        """
+        qdata = request.json                                                       
+        need_params = ["zq","cw","df","pz","join_time","account_img"]                                                       
+        mse = ccf.check_params(*need_params,**qdata)                               
+        if mse:                                                                    
+            raise ce.TipException(mse)                                             
+        try:                                                                       
+            need_params.extend(["init_fund"])
+            vals = ccf.get_need_params(*need_params,**qdata)                       
+            vals["user_id"] = request.user.id
+            vals["player_id"] = request.player.id if request.player else None
+            rst = ctl.update_user_style(**vals)
+            return cv.to_suc(rst)
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class PlayerFundView(cv.AuthView):
+    def put(self, request):
+        """#修改初始资金(小程序)
+        @init_fund:"",参数金额
+        """
+        qdata = request.json                                                       
+        need_params = ["init_fund"]                                                       
+        mse = ccf.check_params(*need_params,**qdata)                               
+        if mse:                                                                    
+            raise ce.TipException(mse)                                             
+        try:                                                                       
+            vals = ccf.get_need_params(*need_params,**qdata)                       
+            vals["user_id"] = request.user.id
+            vals["player_id"] = request.player.id if request.player else None
+            rst = ctl.update_user_fund(**vals)
+            return cv.to_suc(rst)
+        except Exception as e:                                                     
+            cv.tracefail()                                                         
+            return cv.to_fail(e)
+
+
+class StockView(cv.AuthView):
+    def get(self, request):
+        """#股票詳情(2.0小程序)
+        @id:1
+        @page:1
+        @page_size:1
+        """
+        qdata = request.json
+        need_params = ["id"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            need_params.extend(["page","page_size","stock_date"])
+            vals = ccf.get_need_params(*need_params,**qdata)
+            vals["user_id"] = request.user.id
+            vals["player_id"] = request.player.id if request.player else None
+            rst = ctl.get_detail_info(self,**vals)
+            vals["stock_id"] = rst["id"]
+            rst["list"] = ctl.get_stock_players(**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class DefaultDateView(cv.AuthView):
+    def get(self, request):
+        """#默认日期(2.0小程序)
+        @id:1
+        """
+        try:
+            rst = ctl.get_today_date()
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
 
 
+
+class NoticesListView(cv.AuthView):
+    def get(self, request):
+        """#公告列表(2.0小程序)
+        @id:1
+        """
+        try:
+            rst = ctl.get_notices()
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)
+
+
+class PlayerMatchCalendarView(cv.AuthView):
+    def get(self, request):
+        """#获取日历收益(2.0小程序)
+        @match_id:1
+        @player_id:1
+        @month:2021-12
+        """
+        qdata = request.json
+        need_params = ["player_id","match_id","month"]
+        mse = ccf.check_params(*need_params,**qdata)
+        if mse:
+            raise ce.TipException(mse)
+        try:
+            vals = ccf.get_need_params(*need_params,**qdata)
+            rst = ctl.get_player_match_calendar(**vals)
+            return cv.to_suc(rst)
+        except Exception as e:
+            cv.tracefail()
+            return cv.to_fail(e)

+ 2 - 2
src/weixin/wzhifuSDK.py

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