admin
2 天以前 ec060ce444cdd1c48a54686cadbc8950478eedcf
网页内容修改
8个文件已添加
7个文件已修改
1913 ■■■■■ 已修改文件
constant.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/css/index23-05-04.css 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/delegating_list.html 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/images/icon_open.png 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/images/warning.gif 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/images/warning.png 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/index23-05-04.html 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/delegate.js 323 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/http.js 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/page.js 168 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/l_down_cancel_indexes.html 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/trade_queue.html 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/want_buy_codes_list.html 461 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kpl/kpl_api.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.py 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constant.py
@@ -1,4 +1,4 @@
SERVER_HOST = "43.138.167.68"
# SERVER_HOST = "192.168.3.122"
WEB_HOST = "192.168.3.252"
IS_TEST = False
IS_TEST = True
kp_html/kp/css/index23-05-04.css
@@ -889,6 +889,7 @@
    display: flex;
    flex-wrap: wrap;
    width: 100%;
    position: relative;
}
.l2_subscript_codes span{
@@ -897,11 +898,14 @@
    margin-top: 5px;
    margin-right: 5px;
    max-width: 480px;
    width: 480px;
    width: 550px;
}
.l2_subscript_codes span img{
    width: 20px;
    position: absolute;
    right: 20px;
}
.want_list{
kp_html/kp/delegating_list.html
New file
@@ -0,0 +1,394 @@
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport"
            content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>加贝控制中心</title>
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <script src="js/jquery.min.js"></script>
        <script src="http://cdn.yeshitv.com/js/vue.min.js"></script>
        <script src="js/qwebchannel.js"></script>
        <script src="js/http.js"></script>
        <script src="js/vconsole.min.js"></script>
        <script src="layui/layui.js"></script>
        <script src="js/md5.min.js"></script>
        <script src="js/delegate.js"></script>
        <script>
            window.onresize = function() {
                document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px';
            };
            window.onresize();
        </script>
        <style>
            .white {
                color: #FFF;
            }
            .red {
                color: #FF0000;
            }
            .red-bg {
                background-color: #FF0000;
            }
            .dark-red {
                color: #CE0E5F;
            }
            .dark-red-bg {
                background-color: #CE0E5F;
            }
            .purple {
                color: rgb(209, 135, 252);
            }
            .purple-bg {
                background-color: rgb(209, 135, 252);
            }
            .blue {
                color: #0088FF;
            }
            .blue-bg {
                background-color: #85CAFF;
            }
            .green {
                color: #009688;
            }
            .light-green {
                color: rgb(36, 164, 36);
            }
            .light-green-1 {
                color: #00E600;
            }
            .green-bg {
                background-color: #009688;
            }
            .orange {
                color: #FF5722;
            }
            .orange-bg {
                background-color: #FF5722;
            }
            .gray {
                color: gray;
            }
            .gray-bg {
                background-color: gray;
            }
            .yellow {
                color: #FF8020;
            }
        </style>
        <style>
            body {
                background-color: #EEE;
                line-height: 0.3rem;
                color: white;
                font-weight: 500;
                font-family: 微软雅黑;
            }
            .scroll-y {
                overflow: hidden;
                overflow-y: auto;
                white-space: nowrap;
                outline: none;
            }
            #app {
                width: 100%;
                height: 100%;
            }
            .layui-btn {
                width: 65px;
                height: 32px;
                line-height: 32px;
                padding: 0;
                font-size: 13px;
                margin-left: 5px !important;
            }
            .title {
                text-align: right;
                padding: 0.1rem;
                color: black;
            }
            .trade_queue {
                margin-top: 0.1rem;
                display: flex;
                background-color: black;
            }
            .trade_queue div {
                width: 1.5rem;
                height: 0.35rem;
                line-height: 0.35rem;
                text-align: center;
                padding: 0;
            }
            .delegating-list .item {
                margin-bottom: 0rem;
                padding: 0.05rem 0.1rem;
                color: black;
                font-size: 13px;
            }
            .text {
                word-wrap: break-word;
                flex-wrap: wrap;
                display: flex;
            }
            .img-warning {
                height: 18px;
                line-height: 18px;
                margin-top: -5px;
            }
            .delegate-records {
                height: 30%;
            }
            .delegate-records table tr {
                font-size: 14px;
            }
            .delegate-records table tr td,
            th {
                padding: 2px 5px;
                border: 1px solid #ddd;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="title">
                账户可用资金:{{account_available_money}}元
                <button class="layui-btn layui-btn-primary" @click="refresh_data">刷新</button>
            </div>
            <div class="delegate-records scroll-y" style=" overflow-x: auto;">
                <table style="width: 680px; ">
                    <thead style="color: #000;">
                        <th style="width: 70px;">委托时间</th>
                        <th style="width: 70px;">合约名称</th>
                        <th style="width: 50px;">操作</th>
                        <th style="width: 70px;">委托数量</th>
                        <th style="width: 70px;">已成交</th>
                        <th style="width: 100px;">备注</th>
                        <th style="width: 70px;">委托价格</th>
                        <th style="width: 70px;">成交均价</th>
                        <th style="width: 70px;">撤单时间</th>
                    </thead>
                    <tbody>
                        <tr v-if="item.orderStatus==3||item.orderStatus==4||item.orderStatus==5"
                            v-for="(item,index) in getReversedDelegateRecords()"
                            :class="{'blue':item.direction==1&&item.cancelTime.length==0, 'gray':item.cancelTime.length>0,'red':item.direction==0&&item.cancelTime.length==0, 'red':(item.orderStatus==3||item.orderStatus==4)&&item.direction==0, 'yellow':item.orderStatus==5&&item.direction==0}">
                            <td>{{item.acceptTime}}</td>
                            <td>{{item.securityName}}</td>
                            <td>{{item.direction==0?'买入':'卖出'}}</td>
                            <td>{{item.volume}}</td>
                            <td>
                                {{item.volumeTraded}}
                            </td>
                            <td>{{getOrderStatusDesc(item.orderStatus)}}</td>
                            <td>{{item.limitPrice}}</td>
                            <td>
                                <span v-if="item.volumeTraded>0">
                                    {{ (parseFloat(item.turnover)/item.volumeTraded).toFixed(2)}}
                                </span>
                                <span v-else>
                                    --
                                </span>
                            <td>{{item.cancelTime}}</td>
                        </tr>
                        <tr v-if="item.orderStatus==2"
                            v-for="(item,index) in getReversedDelegateRecords()"
                            :class="{'blue':item.direction==1&&item.cancelTime.length==0, 'gray':item.cancelTime.length>0,'red':item.direction==0&&item.cancelTime.length==0, 'red':(item.orderStatus==3||item.orderStatus==4||item.orderStatus==2)&&item.direction==0, 'yellow':item.orderStatus==5&&item.direction==0}">
                            <td>{{item.acceptTime}}</td>
                            <td>{{item.securityName}}</td>
                            <td>{{item.direction==0?'买入':'卖出'}}</td>
                            <td>{{item.volume}}</td>
                            <td>
                                {{item.volumeTraded}}
                            </td>
                            <td>{{getOrderStatusDesc(item.orderStatus)}}</td>
                            <td>{{item.limitPrice}}</td>
                            <td>
                                <span v-if="item.volumeTraded>0">
                                    {{ (parseFloat(item.turnover)/item.volumeTraded).toFixed(2)}}
                                </span>
                                <span v-else>
                                    --
                                </span>
                            <td>{{item.cancelTime}}</td>
                        </tr>
                        <tr v-if="item.orderStatus!=3&&item.orderStatus!=4&&item.orderStatus!=5&&item.orderStatus!=2"
                            v-for="(item,index) in getReversedDelegateRecords()"
                            :class="{'blue':item.direction==1&&item.cancelTime.length==0, 'gray':item.cancelTime.length>0,'red':item.direction==0&&item.cancelTime.length==0, 'red':(item.orderStatus==3||item.orderStatus==4)&&item.direction==0, 'yellow':item.orderStatus==5&&item.direction==0}">
                            <td>{{item.acceptTime}}</td>
                            <td>{{item.securityName}}</td>
                            <td>{{item.direction==0?'买入':'卖出'}}</td>
                            <td>{{item.volume}}</td>
                            <td>{{item.volumeTraded}}</td>
                            <td>{{getOrderStatusDesc(item.orderStatus)}}</td>
                            <td>{{item.limitPrice}}</td>
                            <td><span v-if="item.volumeTraded>0">
                                    {{ (parseFloat(item.turnover)/item.volumeTraded).toFixed(2)}}
                                </span>
                                <span v-else>
                                    --
                                </span>
                            </td>
                            <td>{{item.cancelTime}}</td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <div style="height: 30px;"></div>
            <div class="delegating-list scroll-y">
                <div class="item" v-for="(item,index) in delegates">
                    <div style="display: flex;justify-content: space-between;min-height: 35px;align-items: center;">
                        <div style="position: absolute; right: 0.1rem;">
                            <button class="layui-btn dark-red-bg" @click="update_l_down_cancel_rate(item)">修改</button>
                            <button class="layui-btn blue-bg"
                                @click="audo_increase_l_down_cancel_rate(item)">变大</button>
                            <button class="layui-btn orange-bg" @click="reset_l_down_cancel_rate(item)">立改</button>
                            <button class="layui-btn green-bg"
                                @click="audo_decrease_l_down_cancel_rate(item)">变小</button>
                            <button class="layui-btn gray-bg" @click="cancelOrder(item)">撤单</button>
                            <button class="layui-btn"
                                :style="{'visibility': index%2==1?'hidden':'visibility'  , 'display':index%2==0?'none':'inline'}"></button>
                            <button class="layui-btn layui-btn-primary" @click="viewDetail(item)">查看</button>
                        </div>
                    </div>
                    <div>
                        <div>
                            <span :class="{'red': item.pay_attention}">{{item.code_info[0]}}({{item.code_info[1]}})
                                <span v-if="item.pay_attention">****</span></span>
                        </div>
                        <div>
                            剩<span :class="{'red': item.left_count<=10}">{{item.left_count}}</span>笔 &nbsp;<span
                                :class="{'red': parseMoneyAsW(item.left_money)<=1500}">{{item.left_money}}</span>/封单{{item.buy1_money}}【排预期:<span
                                class="dark-red">{{item.trade_progress_percent}}%</span>】
                            {{item.zyltgb}}
                        </div>
                        <div>
                            <span>【撤:<span class="green">{{(item.l_down_cancel_rate*100).toFixed(2)}}% </span>
                                <span v-if="item.l_down_watch_indexes_info&&item.l_down_watch_indexes_info.current">
                                    &nbsp;/&nbsp;
                                    实撤: <img :style="{'visibility': (item.id in warning_ids_info)?'visible':'hidden'}"
                                        class="img-warning"
                                        :src="warning_ids_info[item.id] > now_timestamp?'images/warning.gif':'images/warning.png'" />
                                    <span class="blue">{{item.l_down_watch_indexes_info.current[3]}}%</span>
                                    &nbsp;
                                    <br>
                                    (大:<span class="orange">{{ item.l_down_watch_indexes_info.current[5][0]}}%</span>
                                    {{ toMoneyDesc(item.l_down_watch_indexes_info.current[5][3])}}/{{ toMoneyDesc(item.l_down_watch_indexes_info.current[5][1])}}
                                    {{ item.l_down_watch_indexes_info.current[5][4]}}笔/<span
                                        :class="{'red': item.l_down_watch_indexes_info.current[5][2] <3 }">{{ item.l_down_watch_indexes_info.current[5][2]}}</span>笔
                                    )
                                    &nbsp;/&nbsp;
                                    {{ item.l_down_watch_indexes_info.current[2][0]}}笔&{{ item.l_down_watch_indexes_info.current[0][0]}}笔
                                    &nbsp;/&nbsp;
                                    {{ toMoneyDesc(item.l_down_watch_indexes_info.current[2][1])}}&{{toMoneyDesc( item.l_down_watch_indexes_info.current[0][1])}}
                                    】
                                    <img src="images/icon_open.png" style="width: 20px;height: 20px;"
                                        @click="open_l2_down_watch_index_overview(item.code_info[0], item.code_info[1])" />
                                </span>
                                <span v-else>
                                    】
                                </span>
                            </span>
                        </div>
                        <div v-if="item.deal_big_money_info">
                            建比:{{(item.deal_big_money_info[1]*100/item.deal_big_money_info[5]).toFixed(0)}}% &nbsp;
                            &nbsp; 实成:<span
                                :class="{'light-green-1':item.deal_big_money_info[5]*0.8>item.deal_big_money_info[1],'yellow': item.deal_big_money_info[5]*0.8<=item.deal_big_money_info[1]&& item.deal_big_money_info[1]<item.deal_big_money_info[5],  'dark-red':item.deal_big_money_info[1]>=item.deal_big_money_info[5]}">{{toMoneyDesc(item.deal_big_money_info[1])}}</span>&nbsp;/&nbsp;要求:{{toMoneyDesc(item.deal_big_money_info[5])}}
                        </div>
                        <div>
                            <span> 涨停价:{{item.limit_up_price}}, </span>
                            <span>
                                {{item.block}},
                            </span>
                            <span> 涨停时间:{{item.limit_up_time}} </span>
                        </div>
                        <div class="trade_queue" @dblclick="open_trade_queue(item)">
                            <div v-for="(item1, index1) in item.trade_queue"
                                :class="{'red':item1[1]==0,'white':item1[1]==1,'purple':item1[1]==2 }" v-if="index1<8">
                                {{toMoneyDesc(item1[2])}}
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </body>
    <script>
    </script>
</html>
kp_html/kp/images/icon_open.png
kp_html/kp/images/warning.gif
kp_html/kp/images/warning.png
kp_html/kp/index23-05-04.html
@@ -312,40 +312,48 @@
                                    </div>
                                </td>
                            </tr>
                            <tr>
                                <td><span class="bold">板块流入</span></td>
                                <td class="budinggundong">
                                    <div class="scroll-y" style="height: 60px;" v-if="code_third_blocks">
                                        <span v-for="(item,i) in code_third_blocks.block_in_moneys"
                                            class="label-style">{{item[0]}}:{{item[1]}}
                                            ——【{{(item[2]/100000000).toFixed(2)}}亿】
                                            <span v-if="forbidden_buy_plates.includes(item[0])"> ❌</span>
                                        </span>
                                    </div>
                                </td>
                            </tr>
                            <tr v-if="big_order_deal_info&&big_order_deal_info!=null">
                                <td><span class="bold">大单成交</span></td>
                                <td>
                                    <div style="height: 80px;" class="scroll-y">
                                    <div style="height: 160px;" class="scroll-y">
                                        <span style="line-height: 20px;"
                                            v-if="big_order_deal_info[2]&&big_order_deal_info[2]!=null&&big_order_deal_info[3]&&big_order_deal_info[3]!=null&&big_order_deal_info[3][2]&&big_order_deal_info[3][2]!=null">
                                            首封均大单-买:{{big_order_deal_info[2][0][0]}},
                                            均大单-买:{{big_order_deal_info[2][0][1]}},
                                            均大单-卖:{{big_order_deal_info[2][0][2]}}<br>
                                            大单成交占比:{{big_order_deal_info[2][0][3]}}%
                                            <br>成交大单:(买:{{big_order_deal_info[2][5]}},卖:{{big_order_deal_info[2][6]}}){{big_order_deal_info[2][1]}}&nbsp;/&nbsp;<span
                                                v-if="big_order_deal_info[2][4]"> {{big_order_deal_info[2][4]}} </span>
                                            <span v-else>{{big_order_deal_info[2][2]}}</span>
                                            <span
                                                v-if="big_order_deal_info[2][4]">&{{big_order_deal_info[2][3]}}</span><a
                                                class="layui-btn layui-btn-xs layui-btn-primary"
                                                @click="edit_total_big_order_threshold">修改</a>
                                            <br>成交大单:(买:{{big_order_deal_info[2][5]}},卖:{{big_order_deal_info[2][6]}})
                                            <br>
                                            实成:{{big_order_deal_info[2][1]}}&nbsp;/&nbsp;
                                            <br>卖大单:{{big_order_deal_info[3][2][0]>100000000?((big_order_deal_info[3][2][0]/100000000).toFixed(2)+'亿'):((big_order_deal_info[3][2][0]/10000).toFixed(2)+'万')}}/{{big_order_deal_info[3][2][1]}}
                                            要求:{{big_order_deal_info[2][4][1]}}
                                            <br>
                                            实执:{{big_order_deal_info[2][2]}}&nbsp;/&nbsp;
                                            自改:{{big_order_deal_info[2][3]}}&nbsp;/&nbsp;
                                            人改:{{big_order_deal_info[2][4][0]}}
                                            <div>
                                                <button class="layui-btn layui-btn-primary" style="background-color: #85CAFF;color: white;height: 30px;line-height: 30px;" @click="add_total_big_order_threshold">变大</button>
                                                <button class="layui-btn" style="height: 30px;line-height: 30px;" @click="sub_total_big_order_threshold">变小</button>
                                                <button class="layui-btn" style="background-color: #CE0E5F;color: white;height: 30px;line-height: 30px;" @click="edit_total_big_order_threshold">修改</button>
                                                <button class="layui-btn-primary layui-btn " style="height: 30px;line-height: 30px;" @click="edit_l_down_cancel_rate">预设比例</button>
                                                <span v-if="big_order_deal_info.length>7&&big_order_deal_info[7]>0">{{big_order_deal_info[7]*100}}%</span>
                                                <button class="layui-btn layui-btn-primary" style="height: 30px;line-height: 30px;" @click="reset_l_down_cancel_rate">恢复比例</button>
                                            </div>
                                            卖大单:{{big_order_deal_info[3][2][0]>100000000?((big_order_deal_info[3][2][0]/100000000).toFixed(2)+'亿'):((big_order_deal_info[3][2][0]/10000).toFixed(2)+'万')}}/{{big_order_deal_info[3][2][1]}}
                                        </span>
                                    </div>
                                </td>
                            </tr>
@@ -600,7 +608,7 @@
                        <div class="layui-tab-content">
                            <div class="layui-tab-item layui-show">
                                <div style="display: flex;min-height: 1000px;">
                                    <div style="width: 270px;">
                                    <div style="width: 320px;">
                                        <button class="layui-btn layui-btn-xs"
                                            v-on:click="get_l2_subscript_codes">刷新数据</button>
                                        <span>订阅数量:{{l2_subscript_codes.length}}</span>    
@@ -612,7 +620,8 @@
                                                :class="{'blue': item[4]==1, 'red': item[4]==2}"
                                                :style="{'border':item[0]==code?'solid orange 2px':'none'}">
                                                <span
                                                    @click="add_to_ths(item[0])">{{new_block_code_special_blocks[item[0]]?'N':''}}{{code_special_blocks[item[0]]?'@':''}}{{item[1]}}({{item[0]}})-<span :class="{'green':!item[6]&&item[4]>0}">【{{item[5]}}%】</span></span>
                                                    @click="add_to_ths(item[0])">{{new_block_code_special_blocks[item[0]]?'N':''}}{{code_special_blocks[item[0]]?'@':''}}{{item[1]}}({{item[0]}})<span :class="{'green':!item[6]&&item[4]>0}">【{{item[5]}}%】<span style="color: black;">x{{item[2][0][4]}}</span>
                                                    </span></span>
                                                <img src="images/delete.png" v-on:click="add_to_forbidden(item[0])" />
                                            </span>
kp_html/kp/js/delegate.js
New file
@@ -0,0 +1,323 @@
    document.addEventListener("DOMContentLoaded", function() {
            //把对象赋值到JS中
            try {
                new QWebChannel(qt.webChannelTransport, function(channel) {
                    window.pyjs = channel.objects.Bridge;
                    console.log("回调成功");
                });
            } catch (e) {
            }
        });
        $(function() {
            new VConsole();
            var app = new Vue({
                el: "#app",
                data: {
                    account_available_money: 0,
                    delegate_records: [],
                    delegate_records_updatetime: '',
                    delegates: [],//[{id:1,'code_info':["000333","美的集团"],'l_down_cancel_rate':0.3,'deal_big_money_info':[0,10000,0,0,0,100000],left_money:'200万'}],
                    now_timestamp: Date.now(),
                    warning_ids_info: { // ID: 生效时间
                    },
                    last_cancel_rate_dict: { // 上一次的撤单比例
                        // ID: 撤单比例
                    },
                    code_names: {},
                    deal_statistic_info: {},
                },
                mounted: function() {
                    setTimeout(function() {
                        app.get_delegate_list();
                        app.list_delegate_records('');
                    }, 500);
                    setInterval(function() {
                        if (is_trade_time()) {
                            app.get_delegate_list();
                        }
                    }, 2000);
                    setInterval(function() {
                        app.now_timestamp = Date.now();
                    }, 1000);
                    setInterval(function() {
                        if (is_trade_time()) {
                            app.list_delegate_records();
                        }
                    }, 3000);
                },
                methods: {
                    refresh_data: function() {
                        http_util.sync_trade_data("delegate_list", function(res) {
                            if (res.code === 0) {
                                layer.msg("刷新成功");
                            } else {
                                layer.msg(res.msg);
                            }
                        });
                        this.get_delegate_list();
                    },
                    get_delegate_list: function() {
                        http_util.get_delegated_buy_code_infos(function(res) {
                            if (res.code == 0) {
                                let data = res.data;
                                app.account_available_money = data.account_available_money;
                                app.delegates = data.delegates;
                                // 记录上一次的数据
                                app.delegates.forEach(function(item) {
                                    // if (!(item.id in app.last_cancel_rate_dict)){
                                    //     app.last_cancel_rate_dict[item.id] = 0;
                                    // }
                                    if (item.id in app.last_cancel_rate_dict) {
                                        // 实撤变大
                                        if (item.l_down_watch_indexes_info.current[3] -
                                            app.last_cancel_rate_dict[item.id] >= 5) {
                                            app.warning_ids_info[item.id] = Date.now() +
                                                1000 * 9;
                                            // 变化5%以上才计数
                                            app.last_cancel_rate_dict[item.id] = item
                                                .l_down_watch_indexes_info.current[3]
                                        }
                                        if (item.l_down_watch_indexes_info.current[3] <
                                            app.last_cancel_rate_dict[item.id]) {
                                            // 变小的时候赋值
                                            app.last_cancel_rate_dict[item.id] = item
                                                .l_down_watch_indexes_info.current[3]
                                            delete app.warning_ids_info[item.id];
                                        }
                                    } else {
                                        app.last_cancel_rate_dict[item.id] = item
                                            .l_down_watch_indexes_info.current[3];
                                    }
                                });
                            }
                        });
                    },
                    parseMoneyAsW: function(money_str) {
                        if (money_str.indexOf('亿') >= 0) {
                            return parseFloat(money_str.replace("亿", "")) * 10000
                        } else if (money_str.indexOf('万') >= 0) {
                            return parseFloat(money_str.replace("万", ""))
                        } else {
                            return parseFloat(money_str) / 10000
                        }
                    },
                    toMoneyDesc: function(money) {
                        if (Math.abs(money) > 100000000) {
                            return (money / 100000000.0).toFixed(1) + "亿";
                        } else if (Math.abs(money) > 10000) {
                            return (money / 10000.0).toFixed(1) + "万";
                        } else {
                            return money + "";
                        }
                    },
                    update_l_down_cancel_rate: function(item) {
                        // 修改撤单比例
                        let code = item.code_info[0];
                        let prompt_index = layer.prompt({
                            title: 'L后撤单比例修改(保留2位小数:0-2)',
                            formType: 0, //输入框类型,支持0(文本)默认1(密码)2(多行文本)
                            value: '', //初始时的值,默认空字符
                            maxlength: 20, //可输入文本的最大长度,默认500
                            area: ['200px', '150px'], //自定义文本域宽高
                            // 绑定enter事件
                            success: function(layero, index) {
                                $(layero).on('keydown', function(e) {
                                    if (e.keyCode === 13) {
                                        // 绑定enter
                                        var val = $('.layui-layer-input').val();
                                        if (isNaN(val)) {
                                            layer.msg("输入格式有误")
                                            return;
                                        }
                                        let rate = parseFloat(val)
                                        http_util.set_l_down_rate(code, rate,
                                            function(res) {
                                                if (res.code == 0) {
                                                    layer.msg("修改成功")
                                                    layer.close(prompt_index)
                                                    app.get_delegate_list();
                                                } else {
                                                    layer.msg(res.msg)
                                                }
                                            });
                                    }
                                });
                            }
                        }, function(val, index) {
                            if (isNaN(val)) {
                                layer.msg("输入格式有误")
                                return;
                            }
                            let rate = parseFloat(val)
                            http_util.set_l_down_rate(code, rate, function(res) {
                                if (res.code == 0) {
                                    layer.msg("修改成功")
                                    layer.close(prompt_index)
                                    app.get_delegate_list();
                                } else {
                                    layer.msg(res.msg)
                                }
                            });
                        });
                    },
                    reset_l_down_cancel_rate: function(item) {
                        // 将撤单比例设置和原来一样
                        let code = item.code_info[0];
                        let rate = item.l_down_cancel_rate;
                        http_util.set_l_down_rate(code, rate,
                            function(res) {
                                if (res.code == 0) {
                                    layer.msg("立改成功")
                                    app.get_delegate_list();
                                } else {
                                    layer.msg(res.msg)
                                }
                            });
                    },
                    audo_increase_l_down_cancel_rate: function(item) {
                        let code = item.code_info[0];
                        let rate = item.l_down_cancel_rate + 0.1;
                        http_util.set_l_down_rate(code, rate,
                            function(res) {
                                if (res.code == 0) {
                                    layer.msg("变大成功")
                                    app.get_delegate_list();
                                } else {
                                    layer.msg(res.msg)
                                }
                            });
                    },
                    audo_decrease_l_down_cancel_rate: function(item) {
                        let code = item.code_info[0];
                        let rate = item.l_down_cancel_rate - 0.1;
                        http_util.set_l_down_rate(code, rate,
                            function(res) {
                                if (res.code == 0) {
                                    layer.msg("变小成功")
                                    app.get_delegate_list();
                                } else {
                                    layer.msg(res.msg)
                                }
                            });
                    },
                    forbiddenBuy: function(item) {
                        let code = item.code_info[0];
                        http_util.do_action_for_code(code, '', 0, function(res) {
                        });
                        this.cancelOrder(item);
                    },
                    cancelOrder: function(item) {
                        let code = item.code_info[0];
                        http_util.cancel_order(code, function() {
                            layer.msg("撤单成功");
                        })
                    },
                    viewDetail: function(item) {
                        pyjs.add_code_to_ths(item.code_info[0]);
                    },
                    open_trade_queue: function(item) {
                        let code = item.code_info[0];
                        let url = window.location.protocol + "//" + window.location.host +
                            "/kp/trade_queue.html?code=" + code;
                        let params = {
                            "url": url,
                            "title": code,
                            "key": "trade_queue",
                            "size": [400, 400]
                        };
                        pyjs.open_webview_window(JSON.stringify(params))
                    },
                    open_l2_down_watch_index_overview: function(code, name) {
                        let url = window.location.protocol + "//" + window.location.host +
                            "/kp/l_down_cancel_indexes.html?code=" + code;
                        let params = {
                            "url": url,
                            "title": "L后囊括(" + name + ")",
                            "key": "l_down_watch_index",
                            "size": [400, 400]
                        };
                        pyjs.open_webview_window(JSON.stringify(params))
                    },
                    getOrderStatusDesc: function(orderStatus) {
                        switch (orderStatus) {
                            case 0:
                                return "预埋";
                            case 1:
                                return "未知";
                            case 2:
                                return "交易所已接收";
                            case 3:
                                return "部分成交";
                            case 4:
                                return "全部成交";
                            case 5:
                                return "部成部撤";
                            case 6:
                                return "全部撤单";
                            case 7:
                                return "交易所已拒绝";
                            default:
                                return "发往交易核心";
                        }
                    },
                    getReversedDelegateRecords: function() {
                        return this.delegate_records.slice().reverse();
                    },
                    list_delegate_records: function() {
                        http_util.list_delegate_records(app.delegate_records_updatetime, function(
                            res) {
                            res = JSON.parse(res);
                            console.log("委托列表", res);
                            if (res.code == 0) {
                                if (res.data.list.length > 0) {
                                    var index_dict = {};
                                    for (var i = 0; i < app.delegate_records.length; i++) {
                                        index_dict[app.delegate_records[i].orderLocalID] = i;
                                    }
                                    res.data.list.forEach(function(e) {
                                        if (e.orderLocalID in index_dict) {
                                            app.$set(app.delegate_records, index_dict[e
                                                .orderLocalID], e);
                                        } else {
                                            app.delegate_records.push(e);
                                        }
                                        app.code_names[e.securityID] = e.securityName;
                                    });
                                }
                                app.delegate_records_updatetime = res.data.update_time;
                            }
                        });
                    },
                }
            });
        });
kp_html/kp/js/http.js
@@ -565,6 +565,25 @@
            callback(result);
        });
    },
    remove_l_down_rate: function(code, callback) {
        let data = {
            type: "common",
            data: {
                ctype: "remove_l_down_rate",
                code: code
            },
            sign: ''
        }
        console.log("请求元数据:", data)
        console.log("请求json数据:", JSON.stringify(data))
        http_util.socket_request(JSON.stringify(data), function(result) {
            result = JSON.parse(result);
            callback(result);
        });
    },
    // 获取委托队列 
    get_trade_queue: function(code, callback) {
        let data = {
@@ -596,6 +615,43 @@
        });
    },
    get_want_buy_detail_list: function(callback) {
        var params = {
        }
        http_util.http_request("/get_want_buy_detail_list", params, callback);
    },
    get_l_down_watch_index_overview: function(code, callback) {
        var params = {
            code:code
        };
        http_util.http_request("/get_l_down_watch_index_overview", params, callback);
    },
    list_delegate_records: function(updateTime, callback) {
        var params = {
            update_time: updateTime,
        }
        http_util.http_request("/get_all_delegate_list", params, callback);
    },
    list_deal_records: function(updateTime, callback) {
        let data = {
            type: "deal_list",
            data: {
                update_time: updateTime
            },
            sign: ''
        };
        http_util.socket_request(JSON.stringify(data), function(result) {
            result = JSON.parse(result);
            callback(result);
        });
    },
kp_html/kp/js/page.js
@@ -825,7 +825,6 @@
                },
                get_big_order_deal_info: function(code) {
                    http_util.get_big_order_deal_info(code, function(res) {
                        res = JSON.parse(res);
                        if (res.code == 0) {
@@ -1273,6 +1272,55 @@
                        }
                    });
                },
                add_total_big_order_threshold: function() {
                    // 编辑总大单
                    let threshold_money = app.big_order_deal_info[2][4] ? app.big_order_deal_info[2]
                        [4] : app.big_order_deal_info[2][2];
                    var threshold_money_number = 0;
                    if (threshold_money.indexOf("万") >= 0) {
                        threshold_money_number = (parseFloat(threshold_money.replace("万", "")) /
                            10000).toFixed(2)
                    } else if (threshold_money.indexOf("亿") >= 0) {
                        threshold_money_number = (parseFloat(threshold_money.replace("亿", "")))
                            .toFixed(2)
                    }
                    let money = threshold_money_number * 100000000 + 10000000;
                    http_util.set_total_deal_big_order_threshold_money(app.code, money,
                        function(res) {
                            if (res.code != 0) {
                                layer.msg(res.msg)
                                return;
                            }
                            layer.msg("修改成功")
                            layer.close(index) // 关闭当前弹窗
                            app.get_big_order_deal_info(app.code);
                        });
                },
                sub_total_big_order_threshold: function() {
                    // 编辑总大单
                    let threshold_money = app.big_order_deal_info[2][4] ? app.big_order_deal_info[2]
                        [4] : app.big_order_deal_info[2][2];
                    var threshold_money_number = 0;
                    if (threshold_money.indexOf("万") >= 0) {
                        threshold_money_number = (parseFloat(threshold_money.replace("万", "")) /
                            10000).toFixed(2)
                    } else if (threshold_money.indexOf("亿") >= 0) {
                        threshold_money_number = (parseFloat(threshold_money.replace("亿", "")))
                            .toFixed(2)
                    }
                    let money = threshold_money_number * 100000000 - 10000000;
                    http_util.set_total_deal_big_order_threshold_money(app.code, money,
                        function(res) {
                            if (res.code != 0) {
                                layer.msg(res.msg)
                                return;
                            }
                            layer.msg("修改成功")
                            layer.close(index) // 关闭当前弹窗
                            app.get_big_order_deal_info(app.code);
                        });
                },
                edit_total_big_order_threshold: function() {
                    // 编辑总大单
                    let threshold_money = app.big_order_deal_info[2][4] ? app.big_order_deal_info[2]
@@ -1312,11 +1360,13 @@
                                                    return;
                                                }
                                                layer.msg("修改成功")
                                                layer.close(prompt_index) // 关闭当前弹窗
                                                layer.close(
                                                    prompt_index) // 关闭当前弹窗
                                                app.get_big_order_deal_info(app
                                                    .code);
                                                setTimeout(function(){
                                                    app.get_l2_subscript_codes();
                                                    app
                                                        .get_l2_subscript_codes();
                                                },100);    
                                            
                                            });
@@ -1341,21 +1391,105 @@
                                app.get_big_order_deal_info(app.code);
                            });
                    })
                    // layer.open({
                    //   type: 0,
                    //   title:'修改大单阈值',
                    //   content: "<input type='text' value = '"+ threshold_money_number +"' class='layui-input'>亿", //这里content是一个普通的String
                    //   btn: ['确认修改', '取消'],
                    //   yes: function(index, layero){
                    //           // 验证通过后的回调
                    //          alert("123");
                    //   }
                    // });
                },
                edit_l_down_cancel_rate: function() {
                    let code = app.code;
                    let prompt_index = layer.prompt({
                        title: '修改L后撤单比例',
                        formType: 0, //输入框类型,支持0(文本)默认1(密码)2(多行文本)
                        value: "0.70", //初始时的值,默认空字符
                        maxlength: 20, //可输入文本的最大长度,默认500
                        area: ['200px', '150px'], //自定义文本域宽高
                        success: function(layero, index) {
                            // 在输入框旁边添加增减按钮
                            var input = layero.find('.layui-layer-input');
                            var btnContainer = $(
                                '<div style="margin-top: 10px;"></div>');
                            btnContainer.append(
                                $(
                                    '<button class="layui-btn layui-btn-primary">-</button>'
                                    )
                                .click(function() {
                                    var val = parseFloat(input.val()) || 0;
                                    if (val > 0.2) {
                                        input.val((val - 0.2).toFixed(2));
                                    } else {
                                        input.val(0);
                                    }
                                })
                            );
                            btnContainer.append(
                                $(
                                    '<button class="layui-btn" style="margin-left: 10px;">+</button>'
                                    )
                                .click(function() {
                                    var val = parseFloat(input.val()) || 0;
                                    input.val((val + 0.2).toFixed(2));
                                })
                            );
                            input.after(btnContainer);
                            $(layero).on('keydown', function(e) {
                                if (e.keyCode === 13) {
                                    // 绑定enter
                                    var val = $('.layui-layer-input').val();
                                    if (isNaN(val)) {
                                        layer.msg("输入格式有误")
                                        return;
                                    }
                                    let rate = parseFloat(val);
                                    http_util.set_l_down_rate(code, rate,
                                        function(res) {
                                            if (res.code == 0) {
                                                layer.msg("修改成功")
                                                layer.close(prompt_index)
                                            } else {
                                                layer.msg(res.msg)
                                            }
                                        });
                                }
                            });
                        }
                    }, function(val, index) {
                        // 只有当点击确认时才会执行这里
                        if (isNaN(val)) {
                            layer.msg("输入格式有误")
                            return;
                        }
                        let rate = parseFloat(val);
                        http_util.set_l_down_rate(code, rate,
                            function(res) {
                                if (res.code == 0) {
                                    layer.msg("修改成功")
                                    layer.close(prompt_index)
                                } else {
                                    layer.msg(res.msg)
                                }
                            });
                    })
                },
                reset_l_down_cancel_rate: function() {
                    let code = app.code;
                    http_util.remove_l_down_rate(code,
                        function(res) {
                            if (res.code == 0) {
                                layer.msg("设置成功")
                            } else {
                                layer.msg(res.msg)
                            }
                        });
                },
                check_low_suction_white_plate: function(event, plate) {
                    if (event.target.checked) {
                        this.add_low_suction_white_plate(plate);
kp_html/kp/l_down_cancel_indexes.html
New file
@@ -0,0 +1,160 @@
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport"
            content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>L后囊括范围</title>
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <script src="js/jquery.min.js"></script>
        <script src="http://cdn.yeshitv.com/js/vue.min.js"></script>
        <script src="js/qwebchannel.js"></script>
        <script src="js/http.js"></script>
        <script src="js/vconsole.min.js"></script>
        <script src="layui/layui.js"></script>
        <script src="js/md5.min.js"></script>
        <script>
            window.onresize = function() {
                document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px';
            };
            window.onresize();
        </script>
        <style>
            .white {
                color: #FFF;
            }
            .red {
                color: #CE0E5F;
            }
            .gray {
                color: #BBB;
            }
            .purple {
                color: rgb(209, 135, 252);
            }
        </style>
        <style>
            body {
                background-color: #EEE;
                line-height: 0.3rem;
                color: white;
                font-family: 微软雅黑;
                background: #000;
                font-size: 0;
            }
            .scroll-y {
                overflow: hidden;
                overflow-y: auto;
                white-space: nowrap;
                outline: none;
            }
            #app {
                width: 100%;
                height: 100%;
            }
            .container {
                height: 100%;
            }
            .item {
                display: inline-block;
                width: 110px;
                height: 30px;
                line-height: 30px;
                text-align: center;
                font-size: 14px;
                margin: 2px;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="container">
                <div v-for="item in watch_info_list" class="item"
                    :class="{'gray':item[3]==14,'red':item[3]==12,'white':(item[3]==11||item[3]==0)&&item[1]<300e4, 'purple': (item[3]==11||item[3]==0)&&item[1]>=300e4 }">
                    {{toMoneyDesc(item[1])}}-{{item[4]}}%
                </div>
            </div>
        </div>
    </body>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            //把对象赋值到JS中
            try {
                new QWebChannel(qt.webChannelTransport, function(channel) {
                    window.pyjs = channel.objects.Bridge;
                    console.log("回调成功");
                });
            } catch (e) {
            }
        });
        $(function() {
            var app = new Vue({
                el: "#app",
                data: {
                    watch_info_list: [],
                },
                mounted: function() {
                    setTimeout(function() {
                        app.get_l_down_watch_index_overview();
                    }, 200);
                },
                methods: {
                    get_l_down_watch_index_overview: function() {
                        let code = http_util.getQueryString("code");
                        http_util.get_l_down_watch_index_overview(code, function(res) {
                            res = JSON.parse(res);
                            if (res.code == 0) {
                                var total_money = 0;
                                res.data.forEach(function(e){
                                    total_money+=e[1];
                                });
                                res.data.forEach(function(e){
                                    e.push((e[1]*100/total_money).toFixed(0));
                                });
                                app.watch_info_list = res.data;
                            }
                        });
                    },
                    toMoneyDesc: function(money) {
                        if (Math.abs(money) > 100000000) {
                            return (money / 100000000.0).toFixed(1) + "亿";
                        } else if (Math.abs(money) > 10000) {
                            return (money / 10000.0).toFixed(1) + "万";
                        } else {
                            return money + "";
                        }
                    },
                }
            });
        });
    </script>
</html>
kp_html/kp/trade_queue.html
New file
@@ -0,0 +1,248 @@
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport"
            content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>成交队列</title>
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <script src="js/jquery.min.js"></script>
        <script src="http://cdn.yeshitv.com/js/vue.min.js"></script>
        <script src="js/qwebchannel.js"></script>
        <script src="js/http.js"></script>
        <script src="js/vconsole.min.js"></script>
        <script src="layui/layui.js"></script>
        <script src="js/md5.min.js"></script>
        <script>
            window.onresize = function() {
                document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px';
            };
            window.onresize();
        </script>
        <style>
            .white {
                color: #FFF;
            }
            .red {
                color: #FF0000;
            }
            .red-bg {
                background-color: #FF0000;
            }
            .dark-red {
                color: #CE0E5F;
            }
            .dark-red-bg {
                background-color: #CE0E5F;
            }
            .purple {
                color: rgb(209, 135, 252);
            }
            .purple-bg {
                background-color: rgb(209, 135, 252);
            }
            .blue {
                color: #0088FF;
            }
            .blue-bg {
                background-color: #85CAFF;
            }
            .green {
                color: #009688;
            }
            .light-green {
                color: rgb(36, 164, 36);
            }
            .green-bg {
                background-color: #009688;
            }
            .orange {
                color: #FF5722;
            }
            .orange-bg {
                background-color: #FF5722;
            }
        </style>
        <style>
            body {
                background-color: #EEE;
                line-height: 0.3rem;
                color: white;
                font-family: 微软雅黑;
                background: #000;
                font-size: 0;
            }
            .scroll-y {
                overflow: hidden;
                overflow-y: auto;
                white-space: nowrap;
                outline: none;
            }
            #app {
                width: 100%;
                height: 100%;
            }
            .container {
                height: 100%;
            }
            .item {
                display: inline-block;
                width: 80px;
                height: 30px;
                line-height: 30px;
                text-align: center;
                font-size: 14px;
                margin: 2px;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="container">
                <div v-for="item in deal_queues" class="white item">
                    {{item}}
                </div>
            </div>
            <div class="container">
                <div v-for="item in trade_queues" class="item"
                    :class="{'red':item[1]==0,'white':item[1]==1,'purple':item[1]==2 }">
                    {{toMoneyDesc(item[2])}}
                </div>
            </div>
        </div>
    </body>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            //把对象赋值到JS中
            try {
                new QWebChannel(qt.webChannelTransport, function(channel) {
                    window.pyjs = channel.objects.Bridge;
                    console.log("回调成功");
                });
            } catch (e) {
            }
        });
        $(function() {
            var app = new Vue({
                el: "#app",
                data: {
                    deal_queues: [],
                    trade_queues: []
                },
                mounted: function() {
                    setTimeout(function() {
                        app.get_trade_queue();
                        app.get_deal_big_money_list();
                    }, 500);
                    setInterval(function() {
                        if(is_trade_time()){
                            app.get_trade_queue();
                            app.get_deal_big_money_list();
                        }
                    }, 3000);
                },
                methods: {
                    get_trade_queue: function() {
                        let code = http_util.getQueryString("code");
                        http_util.get_trade_queue(code, function(res) {
                            if (res.code == 0) {
                                let data = res.data;
                                app.trade_queues = data;
                                console.log(JSON.stringify(data))
                            }
                        });
                    },
                    get_deal_big_money_list: function() {
                        let code = http_util.getQueryString("code");
                        http_util.get_deal_big_money_list(code, function(res) {
                            if (res.code == 0) {
                                let data = res.data;
                                app.deal_queues = data;
                            }
                        });
                    },
                    toMoneyDesc: function(money) {
                        if (Math.abs(money) > 100000000) {
                            return (money / 100000000.0).toFixed(1) + "亿";
                        } else if (Math.abs(money) > 10000) {
                            return (money / 10000.0).toFixed(1) + "万";
                        } else {
                            return money + "";
                        }
                    },
                }
            });
        });
    </script>
    <script>
        window.addEventListener('wheel', function(event) {
            const scrollAmount = window.innerHeight; // 一个屏幕的高度
            let delta = event.deltaY;
            let targetScrollTop = window.scrollY;
            if (delta > 0) {
                // 向下滚动
                targetScrollTop += scrollAmount;
            } else {
                // 向上滚动
                targetScrollTop -= scrollAmount;
            }
            // 限制滚动范围
            targetScrollTop = Math.max(0, Math.min(targetScrollTop, document.body.scrollHeight - window.innerHeight));
            window.scrollTo({
                top: targetScrollTop,
                behavior: 'smooth' // 平滑滚动
            });
        });
    </script>
</html>
kp_html/kp/want_buy_codes_list.html
New file
@@ -0,0 +1,461 @@
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport"
            content="width=device-width, viewport-fit=cover, initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>加贝控制中心</title>
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <script src="js/jquery.min.js"></script>
        <script src="http://cdn.yeshitv.com/js/vue.min.js"></script>
        <script src="js/qwebchannel.js"></script>
        <script src="js/http.js"></script>
        <script src="js/vconsole.min.js"></script>
        <script src="layui/layui.js"></script>
        <script src="js/md5.min.js"></script>
        <script>
            window.onresize = function() {
                document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px';
            };
            window.onresize();
        </script>
        <style>
            .white {
                color: #FFF;
            }
            .red {
                color: #FF2A07;
            }
            .dark-red {
                color: #CE0E5F;
            }
            .purple {
                color: #CC4EE8;
            }
            .blue {
                color: #0088FF;
            }
            .dark-blue {
                color: #159EEC;
            }
            .green {
                color: #00E600;
            }
            .orange {
                color: #FF5722;
            }
            .gray {
                color: gray;
            }
            .yellow {
                color: #F0F888;
            }
            .pink {
                color: #FF8DB7;
            }
            .yellow {
                color: #FF8020;
            }
            .dark-green {
                color: #009688;
            }
        </style>
        <style>
            body {
                background-color: #000;
                line-height: 0.3rem;
                color: white;
                font-weight: 500;
                font-family: 微软雅黑;
                -webkit-user-select: none;
                /* Chrome, Safari, Opera */
                -moz-user-select: none;
                /* Firefox */
                -ms-user-select: none;
                /* IE 10+ */
                user-select: none;
            }
            .scroll-y {
                overflow: hidden;
                overflow-y: auto;
                white-space: nowrap;
                outline: none;
            }
            #app {
                width: 100%;
                height: 100%;
            }
            .text {
                word-wrap: break-word;
                flex-wrap: wrap;
                display: flex;
            }
            .img-warning {
                height: 18px;
                line-height: 18px;
                margin-top: -5px;
            }
            table {
                width: 100%;
            }
            table tbody {
                font-size: 19px;
            }
            table tbody tr {
                height: 30px;
            }
            table tbody td {
                padding: 5px;
            }
            table th:nth-child(1) {
                width: 30px;
            }
            table .active {
                background-color: #410080;
            }
            .delete {
                display: block;
                padding: 0px 5px;
            }
            #detail-info {
                display: none;
                position: fixed;
                z-index: 1000;
                background-color: #EEE;
                width: 400px;
                height: 200px;
            }
            #detail-info tbody {
                font-size: 19px;
                color: #000;
            }
            #detail-info tr td {
                padding: 5px;
            }
            #detail-info tr td:nth-child(1) {
                width: 150px;
                max-width: 130px;
                text-align: left;
                vertical-align: top;
            }
            #detail-info tr td:nth-child(2) {
                width: 300px;
                max-width: 300px;
                text-align: left;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="want-codes-list scroll-y">
                <table>
                    <tbody>
                        <tr style="color: #BBB;">
                            <td></td>
                            <td>名称</td>
                            <td style="text-align: right;">涨幅</td>
                            <td style="text-align: right;">现手</td>
                            <td style="text-align: right;">自由市值</td>
                            <td style="text-align: right;">现价</td>
                            <td style="text-align: right;">操作</td>
                        </tr>
                        <tr v-for="(item,index) in want_codes_list" :class="{'active':selected_index==index}"
                            @click="select_item(index,item[0])" @mouseenter="activeIndex = index"
                            @mouseleave="activeIndex = -1">
                            <td>{{index+1}}</td>
                            <td style="width: 120px;"
                                :class="{'yellow':item[7]==0,'dark-blue':item[9]==10||item[9]==11,'pink':item[9]==13||item[9]==14, 'dark-red':item[9]==12}">
                                <span @mouseenter="show_detail_info($event, index, item)"
                                    @mouseleave="dismiss_detail_info"> {{item[1]}}</span> <span
                                    v-if="item[8]&&item[8][0]!=null"
                                    style="font-size: 12px">{{item[8][0][1]+1}}/{{item[8][0][2]}}</span>
                            </td>
                            <td style="width: 120px;text-align: right;"
                                :class="{'red':item[3]<(item[0].indexOf('30')==0?19.5:9.5)&&item[3]>=0, 'green': item[3]<0, 'purple': item[0].indexOf('30') == 0? item[3]>=19.5:  item[3]>=9.5 }">
                                <span v-if="!isNaN(item[3])">
                                    <span v-if="item[3]>0">+</span>{{item[3].toFixed(2)}}%
                                </span>
                                <span v-else>
                                    {{item[3]}}
                                </span>
                                <span style="font-size: 14px;color: #FFF;">
                                <span v-if="!isNaN(item[11])" :class="{'red':item[11]>=0.7}"> {{(item[11]*100).toFixed(0)}}%</span>
                                <span v-else> {{item[11]}}%</span>
                                </span>
                            </td>
                            <td style="width: 80px;text-align: right;"
                                :class="{'red':item[4][1]>0, 'green':item[4][1]<0}">
                                <div style="display: flex;align-items: center;justify-content: flex-end;">
                                    <span>{{item[4][0]}}</span>
                                    <svg width="20px" height="20px" viewBox="1 1 20 20" style="margin-left: -2px;"
                                        v-if="item[4][1]>0">
                                        <path d="M12 6l-5 5h3v6h4v-6h3z" fill="#FF2A07" stroke="#FF2A07"
                                            stroke-width="2" />
                                    </svg>
                                    <svg width="20px" height="20px" viewBox="1 1 14 20" style="margin-left: -2px;"
                                        v-else>
                                        <path d="M12 18l5-5h-3V7h-4v6H7z" fill="#00E600" stroke="#00E600"
                                            stroke-width="2" />
                                    </svg>
                                </div>
                            </td>
                            <td style="width: 100px;;text-align: right;">{{item[5]}}</td>
                            <td style="width: 70px;text-align: right;padding-right: 10px;"
                                :class="{'red':item[3]>0, 'green':item[3]<0}">
                                <span v-if="!isNaN(item[6])">
                                    {{item[6].toFixed(2)}}
                                </span>
                                <span v-else>
                                    {{item[6]}}
                                </span>
                            </td>
                            <td style="width: 50px;;text-align: right;">
                                <img v-show="activeIndex === index" class="delete" src="images/delete.png"
                                    @click.stop="addToForbidden(item[0])" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <div id="detail-info" style="">
                <table>
                    <tr>
                        <td>开盘啦板块:</td>
                        <td>
                            <span v-if="detail_index>=0">
                                <span>{{want_codes_list[detail_index][8][2]}}</span>
                                <span >/&nbsp;{{want_codes_list[detail_index][8][3]}}</span>
                            </span>
                            <span v-else>-- </span>
                        </td>
                    </tr>
                    <tr>
                        <td>最终板块:</td>
                        <td>
                            <span v-if="detail_index>=0">
                                <span v-for="(item, index) in want_codes_list[detail_index][8][1]">
                                    {{item}}
                                    <span v-if="index+1<want_codes_list[detail_index][8][1].length">、</span>
                                </span>
                            </span>
                            <span v-else>-- </span>
                        </td>
                    </tr>
                    <tr>
                        <td>大买单:</td>
                        <td>
                            <span v-if="big_order_deal_info&&big_order_deal_info[2]&&(temp=big_order_deal_info[2])">
                                <span :class="{'dark-green':parseMoneyAsW(temp[4][1])*0.8>parseMoneyAsW(temp[1]),'yellow': parseMoneyAsW(temp[4][1])*0.8<=parseMoneyAsW(temp[1])&& parseMoneyAsW(temp[1])<parseMoneyAsW(temp[4][1]),  'dark-red':parseMoneyAsW(temp[1])>=parseMoneyAsW(temp[4][1])}">{{temp[1]}}</span>&nbsp;/&nbsp;{{temp[4][1]}}
                            </span>
                            <span v-else>--</span>
                        </td>
                    </tr>
                    <tr>
                        <td>卖单:</td>
                        <td>
                            <span v-if="big_order_deal_info">
                                {{big_order_deal_info[3][2][0]>100000000?((big_order_deal_info[3][2][0]/100000000).toFixed(2)+'亿'):((big_order_deal_info[3][2][0]/10000).toFixed(2)+'万')}}/{{big_order_deal_info[3][2][1]}}
                            </span>
                            <span v-else>--</span>
                        </td>
                    </tr>
                    <tr>
                        <td>参考量日期:</td>
                        <td><span v-if="detail_index>=0" >{{want_codes_list[detail_index][10]}}</span></td>
                    </tr>
                </table>
            </div>
        </div>
    </body>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            //把对象赋值到JS中
            try {
                new QWebChannel(qt.webChannelTransport, function(channel) {
                    window.pyjs = channel.objects.Bridge;
                    console.log("回调成功");
                });
            } catch (e) {
            }
        });
        $(function() {
            new VConsole();
            var app = new Vue({
                el: "#app",
                data: {
                    want_codes_list: [],
                    selected_index: -1,
                    activeIndex: -1,
                    show_info: false,
                    kpl_code_info: null,
                    detail_index: -1,
                    big_order_deal_info: null
                },
                mounted: function() {
                    setTimeout(function() {
                        app.get_want_buy_detail_list();
                    }, 500);
                    setInterval(function() {
                        if (is_trade_time()) {
                            app.get_want_buy_detail_list();
                        }
                    }, 3000);
                },
                methods: {
                    get_want_buy_detail_list: function() {
                        http_util.get_want_buy_detail_list(function(res) {
                            res = JSON.parse(res);
                            if (res.code == 0) {
                                let data = res.data;
                                app.want_codes_list = data;
                            }
                        });
                    },
                    parseMoneyAsW: function(money_str) {
                        if (money_str.indexOf('亿') >= 0) {
                            return parseFloat(money_str.replace("亿", "")) * 10000
                        } else if (money_str.indexOf('万') >= 0) {
                            return parseFloat(money_str.replace("万", ""))
                        } else {
                            return parseFloat(money_str) / 10000
                        }
                    },
                    toMoneyDesc: function(money) {
                        if (Math.abs(money) > 100000000) {
                            return (money / 100000000.0).toFixed(2) + "亿";
                        } else if (Math.abs(money) > 10000) {
                            return (money / 10000.0).toFixed(2) + "万";
                        } else {
                            return money + "";
                        }
                    },
                    select_item: function(index, code) {
                        app.selected_index = index;
                        app.viewDetail(code);
                    },
                    viewDetail: function(code) {
                        pyjs.set_target_code(code);
                        pyjs.add_code_to_ths(code);
                    },
                    addToForbidden: function(code) {
                        http_util.do_action_for_code(code, '', 0, function(res) {
                            app.get_want_buy_detail_list();
                        });
                        return false;
                    },
                    show_detail_info: function(event, index, item) {
                        app.detail_index = index;
                        const clientX = event.clientX;
                        const clientY = event.clientY;
                        const rect = event.target.getBoundingClientRect();
                        this.get_big_order_deal_info(item[0]);
                        const viewportHeight = window.innerHeight;
                        $("#detail-info").css("display", "block");
                        if (rect.bottom + $("#detail-info").height() < viewportHeight) {
                            $("#detail-info").css("top", rect.bottom);
                        } else {
                            $("#detail-info").css("top", rect.bottom - $("#detail-info").height());
                        }
                        $("#detail-info").css("left", rect.right);
                        console.log("鼠标位置:", clientX, clientY);
                    },
                    dismiss_detail_info: function() {
                        console.log("移除鼠标");
                        $("#detail-info").css("display", "none");
                    },
                    get_big_order_deal_info: function(code) {
                        http_util.get_big_order_deal_info(code, function(res) {
                            res = JSON.parse(res);
                            console.log("大单:", res);
                            if (res.code == 0) {
                                app.big_order_deal_info = res.data[0];
                            }
                        });
                    },
                }
            });
        });
    </script>
</html>
kpl/kpl_api.py
@@ -141,7 +141,7 @@
def __getLimitUpInfo(pidType, page, pageSize):
    data = f"Order=0&a=DailyLimitPerformance&st={pageSize}&apiv=w35&Type=4&c=HomeDingPan&PhoneOSNew=1&DeviceID=a38adabb-99ef-3116-8bb9-6d893c846e24&VerSion=5.13.0.0&Index={(page - 1) * pageSize}&PidType={pidType}&"
    data = f"Order=0&a=DailyLimitPerformance&st={pageSize}&apiv=w35&Type=4&c=HomeDingPan&PhoneOSNew=1&DeviceID=a38adabb-99ef-3116-8bb9-7d893c846e24&VerSion=5.20.0.8&Index={(page - 1) * pageSize}&PidType={pidType}&"
    result = __base_request("https://apphq.longhuvip.com/w1/api/index.php", data=data)
    return result.text
@@ -220,4 +220,6 @@
if __name__ == '__main__':
    print(changeStatistics())
    result = getLimitUpInfoNew()
    resultJSON = json.loads(result)
    print(len(resultJSON["list"]))
main.py
@@ -55,7 +55,7 @@
            result, need_delegate = LocalKanPanNetworkDelegate.http_delegate_request(url)
            if not need_delegate:
                result = network_util.http_get(url)
            print(url, "请求结果:", result)
            print(url, f"请求结果:{len(result.encode('utf-8'))}", result)
            self.signal_request.emit(callback_info[0], callback_info[1], result)
            return result
        except Exception as e:
@@ -68,7 +68,7 @@
                result = network_util.socket_request(text, port=port)
            else:
                result = network_util.socket_request(text)
            print("请求结果:", result)
            print(f"请求结果:{len(result.encode('utf-8'))}", result)
            self.signal_request.emit(callback_info[0], callback_info[1], result)
            return result
        except Exception as e:
@@ -167,6 +167,11 @@
        common_window = CommonWindow(title, key, size, parent=self.__webview.window())
        common_window.loadUrl(url)
        common_window.show()
    @pyqtSlot(str)
    def set_target_code(self, code):
        # 设置目标代码
        window_msg_queue.put_nowait({"type": "set_target_code", "data": {"code": code}})
class SecondWindowBridgeClass(BaseBridgeClass):
@@ -398,7 +403,6 @@
        self.webview.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True)
        self.webview.page().setZoomFactor(1)
        self.setCentralWidget(self.webview)
        # JS桥设置
        channel = QWebChannel(self.webview.page())
        self.webview.page().setWebChannel(channel)
@@ -454,6 +458,8 @@
        :param parent:
        """
        super(CommonWindow, self).__init__(parent)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowMaximizeButtonHint)
        self.setWindowTitle(title)
        window_info = setting.get_window_info(f"{key}_window_info")
        if window_info:
@@ -499,7 +505,7 @@
                                    (self.pos().x(), self.pos().y(), self.size().width(), self.size().height()))
        except Exception as e:
            print("")
        self.webview.close()
        # self.webview.close()
class WebEnginePage(QWebEnginePage):
@@ -606,6 +612,9 @@
        def __show_delegating_window():
            self.delegatingWindow.show()
        def __show_want_buy_codes_window():
            self.wantBuyCodesWindow.show()
        def __show_his_msg_window():
            self.msgListWindow.loadUrl(URL_MSG_LIST)
            self.msgListWindow.show()
@@ -650,6 +659,10 @@
        action.triggered.connect(__show_delegating_window)
        view_.addAction(action)
        action = QAction("&打开想买单", self)
        action.triggered.connect(__show_want_buy_codes_window)
        view_.addAction(action)
        action = QAction("&打开历史消息", self)
        action.triggered.connect(__show_his_msg_window)
        view_.addAction(action)
@@ -681,6 +694,7 @@
        # 设置副屏
        self.secondWindow = SecondWindow(self)
        self.delegatingWindow = DelegatingWindow(self)
        self.wantBuyCodesWindow = CommonWindow("想买单", "want_buy_codes", (500, 1000), parent=self)
        self.setCentralWidget(self.webview)
        self.show()
@@ -701,6 +715,14 @@
            self.delegatingWindow.loadUrl(f"http://{constant.WEB_HOST}/kp/delegating_list.html")
        else:
            self.delegatingWindow.loadUrl("http://127.0.0.1:8848/kp/delegating_list.html")
        if not constant.IS_TEST:
            self.wantBuyCodesWindow.loadUrl(f"http://{constant.WEB_HOST}/kp/want_buy_codes_list.html")
        else:
            self.wantBuyCodesWindow.loadUrl("http://127.0.0.1:8848/kp/want_buy_codes_list.html")
        self.wantBuyCodesWindow.show()
        # 绑定槽函数
        self.signal_update_code.connect(self.set_target_code)
        # self.statusBar().showMessage("这是条测试数据额", 10000)