admin
2025-07-25 f5e8c9ecc4b1980e215dcf940aba004a8d6ab353
网页内容修改
12个文件已修改
523 ■■■■ 已修改文件
constant.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/codes_list.html 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/css/index23-05-04.css 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/index23-05-04.html 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/code_list.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/http.js 118 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/ls_http.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/page.js 118 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/low_suction_data.html 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.py 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
res/setting.conf 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
setting.py 35 ●●●●● 补丁 | 查看 | 原始文档 | 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 = True
IS_TEST = False
kp_html/kp/codes_list.html
@@ -412,14 +412,20 @@
                                        <span style="width: 120px;">{{l2_code_name}}</span>
                                        <div class="column-space"></div>
                                        <button class="btn" v-on:click="refresh_h_cancel_data">H撤</button>
                                        <button class="btn" v-on:click="refresh_h_cancel_data" style="display: none;">H撤</button>
                                        <div class="column-space"></div>
                                        <button class="btn" v-on:click="refresh_l_cancel_data(0)">L前撤</button>
                                        <button class="btn" v-on:click="refresh_l_cancel_data(0)"  style="display: none;">L前撤</button>
                                        <div class="column-space"></div>
                                        <button class="btn" v-on:click="refresh_l_cancel_data(1)">L后撤</button>
                                        <div class="column-space"></div>
                                        <button class="btn" v-on:click="clear_cancel_mark">清除标记</button>
                                        <div class="column-space"></div>
                                        <div style="line-height: 20px;margin-top: 5px;"><input
                                                type="checkbox" value="1" checked
                                                v-on:click="set_fast_mode($event)" /> <label>极速模式</label>
                                        </div>
                                        <button class="btn" v-on:click="refresh_l2_data">刷新L2</button>
                                        <div class="column-space"></div>
                                        <button class="btn" v-on:click="refresh_trade_progress">成交进度</button>
kp_html/kp/css/index23-05-04.css
@@ -313,6 +313,10 @@
    color: #0084ff;
}
.blue {
    color: #0084ff;
}
.purple {
    color: #ff80ff;
}
kp_html/kp/index23-05-04.html
@@ -554,9 +554,7 @@
                                    </div>
                                    <img class="delete" src="./images/delete.png" alt=""
                                        style="float: right;margin-top: 12px;margin-right: -8px;"
                                        @click="del_code_level_1(index)">
                                    <div style="display:flex;justify-content:space-between;align-items:center">
                                        <div>
                                            <span class="bule">{{item[7]}}</span>(<span
@@ -570,8 +568,11 @@
                                    </div>
                                    <div>代码:<span class="num-style">{{item[0]}}</span>&nbsp;&nbsp;&nbsp;&nbsp;自由市值:<span
                                            class="num-style">{{item[9]}}</span></div>
                                    <div>自由市值:<span
                                            class="num-style">{{item[9]}}</span>
                                            <button class="layui-btn layui-btn layui-btn-primary" style="width: 140px;"  @click="add_to_ths(item[0])">查看</button>
                                            </div>
                                    <!-- 交易信息 -->
                                    <div class="num-style" style="font-size:12px;overflow: hidden;width:260px;"
                                        v-html="item[12]"></div>
@@ -602,13 +603,16 @@
                                    <div style="width: 270px;">
                                        <button class="layui-btn layui-btn-xs"
                                            v-on:click="get_l2_subscript_codes">刷新数据</button>
                                        <span>订阅数量:{{l2_subscript_codes.length}}</span>
                                        <div class="l2_subscript_codes scroll-x">
                                            <span class="label-style" v-for="(item, index) in l2_subscript_codes"
                                                :class="{'green': item[2]<0, 'red': item[3]&&item[3][3]}"
                                                :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]}})-【{{item[2]}}%】</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>
                                                <img src="images/delete.png" v-on:click="add_to_forbidden(item[0])" />
                                            </span>
@@ -623,6 +627,19 @@
                                            </ul>
                                            <div class="layui-tab-content">
                                                <div class="layui-tab-item">
                                                    <fieldset class="layui-elem-field">
                                                        <legend>量化板块</legend>
                                                        <div class="layui-field-box">
                                                         <div style="display: flex;flex-wrap: wrap;">
                                                                <div class="label-style"
                                                                    style="margin: 10px; display: inline-block; max-width: auto;"
                                                                    v-for="(item, index) in low_suction_plates">
                                                                    <span>{{item}}</span>
                                                                </div>
                                                            </div>
                                                        </div>
                                                    </fieldset>
                                                    <fieldset class="layui-elem-field">
                                                        <legend>板块白名单</legend>
@@ -647,9 +664,10 @@
                                                                <table class="layui-table" >
                                                                    <thead>
                                                                        <th>下单时间</th>
                                                                        <th>代码</th>
                                                                            <th>板块</th>
                                                                        <th>下单时间</th>
                                                                        <th style="width: 30px;">成本价</th>
                                                                        <th>成本涨幅</th>
                                                                    
@@ -659,9 +677,9 @@
                                                                    <tbody>
                                                                        <tr
                                                                            v-for="(item, index) in low_suction_place_order_records">
                                                                            <td>{{item[3].time_str}}</td>
                                                                            <td>{{item[3].code}}</td>
                                                                            <td><span @click="add_to_ths(item[3].code)">{{item[3].code}}({{item[3].code_name}})</span></td>
                                                                            <td>{{item[3].plates}}</td>
                                                                            <td>{{item[3].time_str}}</td>
                                                                            <td>{{item[3].price}}</td>
                                                                            <td>{{item[3].rate}}%</td>
                                                                            <td>{{item[3].plates_info}}</td>
kp_html/kp/js/code_list.js
@@ -79,8 +79,8 @@
            // 费用数据
            commission_data:{"total_commission":0, "month_commission":0},
            // L2数据结束索引
            l2_end_index:null
            l2_end_index:null,
            fast_mode: 1
        },
        watch: {
            delegated_buy_code_infos: function() {
@@ -192,7 +192,7 @@
                
                var date = $("#date").val();
                http_util.get_l2_datas(app.code, date, app.l2_end_index, function(res) {
                http_util.get_l2_datas(app.code, date, app.l2_end_index, app.fast_mode, function(res) {
                    layer.close(index);
                    res = JSON.parse(res);
                    if (res.code == 0) {
@@ -335,6 +335,10 @@
                app.hidden_little_money = e.currentTarget.checked;
            },
            
            set_fast_mode: function(e) {
                app.fast_mode = e.currentTarget.checked?1:0;
            },
            hidden_canceled_big_money_check: function(e) {
                app.not_hidden_canceled_big_money = e.currentTarget.checked;
            },
kp_html/kp/js/http.js
@@ -1,3 +1,16 @@
function is_trade_time() {
        var nowdate = new Date();
        h = nowdate.getHours();
        m = nowdate.getMinutes();
        total_m = h * 60 + m;
        if ((total_m >= (9 * 60 + 25) && total_m <= (11 * 60 + 30)) || (total_m >= 13 * 60 && total_m <= 15 *
                60)) {
            return true;
        } else {
            return false;
        }
}
var http_util = {
    request_callback: {},
    getQueryString: function(name) {
@@ -229,6 +242,7 @@
        md5Hash = md5(params_str);
        return md5Hash;
    },
    // 撤单
    cancel_order: function(code, success) {
        var data = {
            type: "cancel_order",
@@ -245,6 +259,22 @@
            }
        });
    },
    // 同步交易数据
    sync_trade_data: function(type, success) {
        var data = {
            type: "sync_trade_data",
            data: {
                "type": type
            }
        };
        http_util.socket_request(JSON.stringify(data), function(result) {
            result = JSON.parse(result);
            success(result);
        });
    },
    forbidden_plate: function(plate, callback) {
        http_util.http_request("/kpl/forbidden_plate", {
            plate: plate
@@ -256,12 +286,10 @@
        }, callback);
    },
    list_forbidden_plate: function(callback) {
        http_util.http_request("/kpl/list_forbidden_plate", {
        }, callback);
        http_util.http_request("/kpl/list_forbidden_plate", {}, callback);
    },
    list_deleted_forbidden_plate :function(callback){
        http_util.http_request("/kpl/list_deleted_forbidden_plate", {
        }, callback);
        http_util.http_request("/kpl/list_deleted_forbidden_plate", {}, callback);
    },
    // 获取板块下的代码
    get_plate_codes: function(plate, day, callback) {
@@ -310,9 +338,10 @@
    },
    //获取L2的数据
    get_l2_datas: function(code, date, end_index, callback) {
    get_l2_datas: function(code, date, end_index, fast_mode, callback) {
        var params = {
            code: code
            code: code,
            fast: fast_mode
        }
        if (date) {
            params['date'] = date
@@ -366,12 +395,11 @@
        data = {
            type: "common",
            data: {
                ctype: "get_delegated_buy_code_infos"
                ctype: "get_delegated_buy_code_infos_v2"
            },
            sign: ''
        }
        http_util.socket_request(JSON.stringify(data), function(result) {
            console.log(result);
            result = JSON.parse(result);
            callback(result);
        });
@@ -478,15 +506,16 @@
    },
    // 获取所有L2订阅的列表
    get_l2_subscript_codes: function(callback) {
        var params = {
            type: "get_huaxin_subscript_codes",
            data: {},
            sign: ''
        }
        http_util.socket_request(JSON.stringify(params), function(result) {
            result = JSON.parse(result);
            callback(result);
        });
        // var params = {
        //     type: "get_huaxin_subscript_codes",
        //     data: {},
        //     sign: ''
        // }
        // http_util.socket_request(JSON.stringify(params), function(result) {
        //     result = JSON.parse(result);
        //     callback(result);
        // });
        http_util.http_request("/get_l2_subscript_codes", {}, callback);
    },
    
    get_big_order_deal_info:function(code, callback){
@@ -496,12 +525,10 @@
    },
    
    get_all_special_codes:function(callback){
        http_util.http_request("/get_all_special_codes", {
        }, callback);
        http_util.http_request("/get_all_special_codes", {}, callback);
    },
    get_new_blocks_special_codes:function(callback){
        http_util.http_request("/get_new_blocks_special_codes", {
        }, callback);
        http_util.http_request("/get_new_blocks_special_codes", {}, callback);
    },
    // 设置累计成交大单的阈值 
    set_total_deal_big_order_threshold_money: function(code, money, callback) {
@@ -520,7 +547,54 @@
        });
    },
    
    // 设置L后撤单比例
    set_l_down_rate: function(code, rate, callback) {
        let data = {
            type: "common",
            data: {
                ctype: "set_l_down_rate",
                code: code,
                rate: rate
            },
            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 = {
            type: "common",
            data: {
                ctype: "get_trade_queue",
                code: code
            },
            sign: ''
        }
        http_util.socket_request(JSON.stringify(data), function(result) {
            result = JSON.parse(result);
            callback(result);
        });
    },
    // 获取已成交的大单
    get_deal_big_money_list: function(code, callback) {
        let data = {
            type: "common",
            data: {
                ctype: "get_deal_big_money_list",
                code: code
            },
            sign: ''
        }
        http_util.socket_request(JSON.stringify(data), function(result) {
            result = JSON.parse(result);
            callback(result);
        });
    },
kp_html/kp/js/ls_http.js
@@ -157,6 +157,20 @@
            result = JSON.parse(result);
            callback(result);
        });
    },
    get_can_buy_plates:function(callback){
        let data = {
            ctype: "get_can_buy_plates"
        };
        var params = {
            type: "common",
            data: data,
            sign: ''
        }
        http_util_of_ls.socket_request(JSON.stringify(params), function(result) {
            result = JSON.parse(result);
            callback(result);
        });
    }
    
};
kp_html/kp/js/page.js
@@ -98,9 +98,13 @@
    setInterval(function() {
        if (is_trade_time()) {
            app.get_low_suction_place_order_records();
            app.get_low_suction_plates();
        }
    }, 3000, 3000);
    
    
    
@@ -416,6 +420,8 @@
                new_block_code_special_blocks:{},
                low_suction_plate_white_list:[],
                low_suction_place_order_records:[],
                low_suction_plates: []
            },
            watch: {
                want_codes: function() {
@@ -462,8 +468,7 @@
                        }
                        break;
                        case 4:
                        case 5:
                        {
                    case 5: {
                            http_util.get_blocks_in_money_info(type%2, function(result) {
                                result = JSON.parse(result);
                                if (result.code == 0) {
@@ -507,7 +512,8 @@
                                    for (var i = 0; i < app.first_info
                                        .limit_up_reason_statistic
                                        .length; i++) {
                                        var limit_up_info = app.first_info.limit_up_reason_statistic[i];
                                        var limit_up_info = app.first_info
                                            .limit_up_reason_statistic[i];
                                        if (limit_up_info[0] == e[1]) {
                                            s = limit_up_info;
                                            break;
@@ -576,7 +582,9 @@
                            var temps = new Array();
                            var current_limit_up_reason =null;
                            res.data.limit_up_reason_statistic.forEach(function(d) {
                                if (app.code_third_blocks&&app.code_third_blocks.match_blocks&&app.code_third_blocks.match_blocks[0].includes(d[0])) {
                                if (app.code_third_blocks && app.code_third_blocks
                                    .match_blocks && app.code_third_blocks
                                    .match_blocks[0].includes(d[0])) {
                                    current_limit_up_reason = d;
                                } else {
                                    temps.push(d);
@@ -643,7 +651,6 @@
                    if (app.choose_code.first != app.first_info.limit_up_codes[index][0]) {
                        app.choose_code.first = app.first_info.limit_up_codes[index][0];
                        app.code = app.first_info.limit_up_codes[index][0];
                        pyjs.add_code_to_ths(app.code);
                        app.code_name = app.code + "(" + app.first_info.limit_up_codes[index][1] +
                            ")";
                        app.get_score_data(app.first_info.limit_up_codes[index][0], app.first_info
@@ -762,14 +769,17 @@
                            if (res.code == 0) {
                                res.data.plate.forEach(function(e) {
                                    var s = null;
                                    if (app.first_info.limit_up_reason_statistic) {
                                    if (app.first_info
                                        .limit_up_reason_statistic) {
                                        for (var i = 0; i < app.first_info
                                            .limit_up_reason_statistic
                                            .length; i++) {
                                            if (app.first_info
                                                .limit_up_reason_statistic[
                                                    i][0] == e[1]) {
                                                s = app.first_info.limit_up_reason_statistic[i];
                                                s = app.first_info
                                                    .limit_up_reason_statistic[
                                                        i];
                                                break;
                                            }
                                        }
@@ -782,10 +792,10 @@
                                // 设置当日涨停原因
                                try{
                                    app.kpl_limit_up_reason = app.kpl_code_info.today[0]
                                    app.kpl_limit_up_reason = app.kpl_code_info
                                        .today[0]
                                            [0];
                                }catch(e){
                                }
                                } catch (e) {}
                                // 将当前涨停原因置顶
                                var limit_up_reason_statistic = app.first_info
                                    .limit_up_reason_statistic;
@@ -1070,8 +1080,7 @@
                    pyjs.add_code_to_ths(code);
                    try{
                        app.set_target_code(code);
                    }catch(e){
                    }
                    } catch (e) {}
                },
                show_latest_limit_up_queue:function(time_str){
                       http_util.get_kpl_latest_limit_up_queue_by_time(time_str,function(res){
@@ -1081,11 +1090,16 @@
                            res.data.sort((a,b)=>a[2] - b[2]);
                            res.data.forEach(function(e){
                                let date = new Date(e[2]*1000);
                                let hours = String(date.getHours()).padStart(2, '0');
                                let minutes = String(date.getMinutes()).padStart(2, '0');
                                let seconds = String(date.getSeconds()).padStart(2, '0');
                                let hours = String(date.getHours()).padStart(2,
                                '0');
                                let minutes = String(date.getMinutes()).padStart(2,
                                    '0');
                                let seconds = String(date.getSeconds()).padStart(2,
                                    '0');
                                temp_time_str = `${hours}:${minutes}:${seconds}`;
                                datas.push([e[0],e[1],temp_time_str,e[4],e[5],e[6]]);
                                datas.push([e[0], e[1], temp_time_str, e[4], e[5],
                                    e[6]
                                ]);
                            });
                            app.latest_limit_up_datas = datas;
                            layer.open({
@@ -1171,13 +1185,16 @@
                
                get_l2_subscript_codes:function(){
                    http_util.get_l2_subscript_codes(function(res){
                        res= JSON.parse(res);
                        if(res.code == 0){
                            console.log("订阅的代码:", res.data);
                            try{
                                res.data.list.sort((a, b) => (b[3][3]?1:0) - (a[3][3]?1:0));
                                res.data.sort((a, b) => b[4] - a[4]);
                            }catch(e){
                                
                            }
                            app.l2_subscript_codes = res.data.list;
                            app.l2_subscript_codes = res.data;
                        }
                    });
                },
@@ -1258,20 +1275,54 @@
                },
                edit_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];
                    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)
                        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)
                        threshold_money_number = (parseFloat(threshold_money.replace("亿", "")))
                            .toFixed(2)
                    } 
                    
                    layer.prompt({
                        title: '修改累计大单成交阈值(单位:亿)原值:'+app.big_order_deal_info[2][3]
                        ,formType: 0,   //输入框类型,支持0(文本)默认1(密码)2(多行文本)
                    let prompt_index = layer.prompt({
                        title: '修改累计大单成交阈值(单位:亿)原值:' + app.big_order_deal_info[2][3],
                        formType: 0, //输入框类型,支持0(文本)默认1(密码)2(多行文本)
                        value: threshold_money_number,   //初始时的值,默认空字符
                        maxlength: 20, //可输入文本的最大长度,默认500
                        area: ['200px', '150px'] //自定义文本域宽高
                        area: ['200px', '150px'], //自定义文本域宽高
                        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 money = parseFloat(val).toFixed(2) *
                                        100000000
                                    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(prompt_index) // 关闭当前弹窗
                                                app.get_big_order_deal_info(app
                                                    .code);
                                                setTimeout(function(){
                                                    app.get_l2_subscript_codes();
                                                },100);
                                            });
                                }
                            });
                        }
                    },function(val, index){
                        // 只有当点击确认时才会执行这里
                        if(isNaN(val)){
@@ -1279,7 +1330,8 @@
                            return;
                        }
                        let money = parseFloat(val).toFixed(2)*100000000
                        http_util.set_total_deal_big_order_threshold_money(app.code, money, function(res){
                        http_util.set_total_deal_big_order_threshold_money(app.code, money,
                            function(res) {
                            if(res.code!=0){
                                layer.msg(res.msg)
                                return;
@@ -1304,8 +1356,7 @@
                    // });
                    
                },
                check_low_suction_white_plate:function(event, plate)
                {
                check_low_suction_white_plate: function(event, plate) {
                    if(event.target.checked){
                        this.add_low_suction_white_plate(plate);
                    }else{
@@ -1354,6 +1405,14 @@
                            app.low_suction_place_order_records = res.data;
                        }
                    });
                },
                get_low_suction_plates: function() {
                    http_util_of_ls.get_can_buy_plates(function(res) {
                        console.log("低吸量化板块", JSON.stringify(res.data))
                        if (res.code == 0) {
                            app.low_suction_plates = res.data;
                        }
                    });
                }
                
                
@@ -1376,6 +1435,7 @@
        app.statistic_latest_limit_up_block("");
        app.list_forbidden_buy_plates();
        app.list_low_suction_white_plate();
        app.get_low_suction_place_order_records();
        
    }
kp_html/kp/low_suction_data.html
@@ -2,7 +2,7 @@
<html>
    <head>
        <meta charset="utf-8">
        <title>看盘端</title>
        <title>低吸回测</title>
        <link rel="stylesheet" type="text/css" href="./css/index23-05-04.css?_=1" />
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <script src="js/jquery.min.js"></script>
@@ -173,6 +173,8 @@
                                    <th>代码</th>
                                    <th>涨幅</th>
                                    <th>是否买入</th>
                                    <th>收盘溢价率</th>
                                    <th>次日开盘溢价率</th>
                                    <th>说明</th>
                                </thead>
                                
@@ -182,6 +184,8 @@
                                        <td>{{item[1]}}</td>
                                        <td>{{item[2]}}%</td>
                                        <td>{{item[3][0]?'是':'否'}}</td>
                                        <td><span v-if="item.length>4"> {{item[4]}}% </span> <span v-else> -- </span> </td>
                                        <td><span v-if="item.length>5"> {{item[5]}}% </span> <span v-else> -- </span></td>
                                        <td>
                                          <span v-if="item[3][0]"> {{item[3][2]}} </span>
                                          <span v-else> {{item[3][1]}} </span>
main.py
@@ -152,6 +152,22 @@
        # 添加到同花顺
        threading.Thread(target=lambda: ths_util.add_code_to_zixuan(code), daemon=True).start()
    @pyqtSlot(str)
    def open_webview_window(self, data):
        """
        打开独立网页窗口
        :param data:
        :return:
        """
        data = json.loads(data)
        url = data.get("url")
        title = data.get("title")
        key = data.get("key")
        size = data.get("size")
        common_window = CommonWindow(title, key, size, parent=self.__webview.window())
        common_window.loadUrl(url)
        common_window.show()
class SecondWindowBridgeClass(BaseBridgeClass):
    @pyqtSlot(str)
@@ -291,6 +307,7 @@
        channel = QWebChannel(self.webview.page())
        self.webview.page().setWebChannel(channel)
        self.python_bridge = SecondWindowBridgeClass(self.webview)
        channel.registerObject("Bridge", self.python_bridge)
        # win32gui.SetWindowLong(self.winId(), win32con.GWL_WNDPROC, self.handleCustomMessage)
@@ -351,6 +368,138 @@
                (self.pos().x(), self.pos().y(), self.size().width(), self.size().height()))
        except Exception as e:
            print("")
class DelegatingWindow(QMainWindow):
    """
    加贝控制中心
    """
    signal_update_kpl = pyqtSignal(str)
    def update_kpl_func(self):
        while True:
            time.sleep(3)
            try:
                self.__update_kpl()
            except:
                pass
    def __init__(self, parent=None):
        super(DelegatingWindow, self).__init__(parent)
        self.setWindowTitle('加贝控制中心')
        window_info = setting.get_delegating_window_info()
        if window_info:
            self.move(window_info[0], window_info[1])
            self.resize(window_info[2], window_info[3])
        else:
            self.resize(600, 800)
        self.webview = QWebEngineView()
        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)
        self.python_bridge = BaseBridgeClass(self.webview)
        channel.registerObject("Bridge", self.python_bridge)
    # 自定义消息处理函数
    def handleCustomMessage(self, hwnd, msg, wparam, lparam):
        if msg == win32con.WM_USER + 1024:
            # 解析数据
            # try:
            #     code = ctypes.cast(lparam, ctypes.py_object).value
            #     print(code)
            # except:
            #     pass
            pass
            # 处理数据
            # self.dataReceived.emit(intValue, stringValue)
        return win32gui.DefWindowProc(hwnd, msg, wparam, lparam)
    def loadUrl(self, url):
        self.webview.load(QUrl(url))
    def closeEvent(self, event):
        try:
            setting.set_delegating_window_info(
                (self.pos().x(), self.pos().y(), self.size().width(), self.size().height()))
        except Exception as e:
            print("")
class CommonWindow(QMainWindow):
    """
    加贝控制中心
    """
    signal_update_kpl = pyqtSignal(str)
    def update_kpl_func(self):
        while True:
            time.sleep(3)
            try:
                self.__update_kpl()
            except:
                pass
    def __init__(self, title, key, default_size, parent=None):
        """
        :param title: 标题
        :param key: 标识
        :param default_size:(宽, 高)
        :param parent:
        """
        super(CommonWindow, self).__init__(parent)
        self.setWindowTitle(title)
        window_info = setting.get_window_info(f"{key}_window_info")
        if window_info:
            self.move(window_info[0], window_info[1])
            self.resize(window_info[2], window_info[3])
        else:
            self.resize(default_size[0], default_size[1])
        self.key = key
        self.webview = QWebEngineView()
        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)
        self.python_bridge = BaseBridgeClass(self.webview)
        channel.registerObject("Bridge", self.python_bridge)
    # 自定义消息处理函数
    def handleCustomMessage(self, hwnd, msg, wparam, lparam):
        if msg == win32con.WM_USER + 1024:
            # 解析数据
            # try:
            #     code = ctypes.cast(lparam, ctypes.py_object).value
            #     print(code)
            # except:
            #     pass
            pass
            # 处理数据
            # self.dataReceived.emit(intValue, stringValue)
        return win32gui.DefWindowProc(hwnd, msg, wparam, lparam)
    def loadUrl(self, url):
        self.webview.load(QUrl(url))
    def closeEvent(self, event):
        try:
            setting.set_window_info(f"{self.key}_window_info",
                                    (self.pos().x(), self.pos().y(), self.size().width(), self.size().height()))
        except Exception as e:
            print("")
        self.webview.close()
class WebEnginePage(QWebEnginePage):
@@ -454,6 +603,9 @@
        def __show_second_window():
            self.secondWindow.show()
        def __show_delegating_window():
            self.delegatingWindow.show()
        def __show_his_msg_window():
            self.msgListWindow.loadUrl(URL_MSG_LIST)
            self.msgListWindow.show()
@@ -494,6 +646,10 @@
        action.triggered.connect(__show_second_window)
        view_.addAction(action)
        action = QAction("&打开加贝控制中心", self)
        action.triggered.connect(__show_delegating_window)
        view_.addAction(action)
        action = QAction("&打开历史消息", self)
        action.triggered.connect(__show_his_msg_window)
        view_.addAction(action)
@@ -524,6 +680,7 @@
        channel.registerObject("Bridge", self.python_bridge)
        # 设置副屏
        self.secondWindow = SecondWindow(self)
        self.delegatingWindow = DelegatingWindow(self)
        self.setCentralWidget(self.webview)
        self.show()
@@ -539,6 +696,11 @@
            else:
                self.secondWindow.loadUrl("http://127.0.0.1:8848/kp/codes_list.html")
        self.delegatingWindow.show()
        if not constant.IS_TEST:
            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")
        # 绑定槽函数
        self.signal_update_code.connect(self.set_target_code)
        # self.statusBar().showMessage("这是条测试数据额", 10000)
res/setting.conf
@@ -1,10 +1,10 @@
[config]
stay_on_top = 1
window_info = [[-1711, 194, 1280, 800], [1473, 621, 320, 195]]
xgb_window_info = [-1567, 208, 1146, 987]
xgb_window_info = [-2625, 529, 1920, 1017]
window_watch_float_info = [146, 419, 435, 220]
window_tick_info = [280, 40, 800, 1000]
kp_second_window_info = [-961, 106, 558, 942]
kp_second_window_info = [-889, 356, 638, 910]
code_attribute_window_info = [-650, 315, 291, 278]
client = hxh
float_frame_auto_focus = 1
@@ -12,6 +12,8 @@
only_convertible_bonds = 0
screen_scale = 1
ths_buy = 1
delegating_window_info = [-879, 175, 644, 800]
trade_queue_window_info = [-1024, 450, 437, 369]
[juejin]
strategy_id = 95a982ce-fc2d-11ec-8ff3-0a0027000010
setting.py
@@ -239,6 +239,41 @@
        return val
def set_delegating_window_info(window):
    set_window_info("delegating_window_info", window)
def get_delegating_window_info():
    return get_window_info("delegating_window_info")
def set_window_info(key, window):
    """
    设置窗口信息
    :param key:
    :param window:
    :return:
    """
    cp = __read_setting()
    cp.set("config", key, json.dumps(window))
    __write_setting(cp)
def get_window_info(key):
    """
    获取窗口信息
    :param key:
    :return:
    """
    cp = __read_setting()
    val = __get_setting(cp, "config", key)
    if val is None:
        return None
    else:
        val = json.loads(val)
        return val
# 设置代码属性框信息
def set_code_attribute_window_info(window):
    cp = __read_setting()