m0_70156489 3 дней назад
Родитель
Сommit
264b91c52e

+ 11 - 1
application/admin/controller/Procuremen.php

@@ -1082,7 +1082,17 @@ class Procuremen extends Backend
         }
         foreach ($buckets as &$set) {
             if ($set !== []) {
-                ksort($set, SORT_STRING);
+                // 保证 json 编码为对象(避免 list 下标 0,1,2… 被前端当选项)
+                $normalized = [];
+                foreach ($set as $k => $v) {
+                    $s = trim((string)(is_scalar($v) ? $v : $k));
+                    if ($s === '') {
+                        continue;
+                    }
+                    $normalized[$s] = $s;
+                }
+                ksort($normalized, SORT_STRING);
+                $set = $normalized;
             }
         }
         unset($set);

+ 2 - 2
application/admin/view/procuremen/audit_issue.html

@@ -393,7 +393,7 @@
                 <th style="width:88px;">姓名</th>
                 <th style="width:100px;">邮箱</th>
                 <th style="width:120px;">手机号</th>
-                <th class="text-center" style="width:56px;">排名</th>
+                <th class="text-center col-rank" style="width:64px;">排名</th>
                 <th class="text-center" style="width:88px;">商务/技术得分</th>
                 <th class="text-center" style="width:80px;" title="价格得分=(最低单价合计/本供应商单价合计)×价格权重%×100">价格得分</th>
                 <th class="text-center" style="width:72px;">总分</th>
@@ -421,7 +421,7 @@
                 <td{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{$co.username|default=''|htmlentities}</td>
                 <td{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{:htmlentities(mask_email(isset($co['email']) ? $co['email'] : ''))}</td>
                 <td{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{:htmlentities(mask_phone(isset($co['phone']) ? $co['phone'] : ''))}</td>
-                <td class="text-center"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{if condition="!empty($bidOpenVerified)"}{$co.service_rank_text|default=''|htmlentities}{/if}</td>
+                <td class="text-center col-rank"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;font-size:17px;font-weight:700;">{if condition="!empty($bidOpenVerified)"}{$co.service_rank_text|default=''|htmlentities}{/if}</td>
                 <td class="text-center"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{if condition="!empty($bidOpenVerified)"}{$co.service_quality_score_text|default=''|htmlentities}{/if}</td>
                 <td class="text-center"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;"{if condition="!empty($bidOpenVerified)"} title="单价合计 {$co.service_price_sum_text|default=''|htmlentities}"{/if}>{if condition="!empty($bidOpenVerified)"}{$co.service_price_score_text|default=''|htmlentities}{/if}</td>
                 <td class="text-center"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;font-weight:600;">{if condition="!empty($bidOpenVerified)"}{$co.service_score_text|default=''|htmlentities}{/if}</td>

+ 15 - 2
application/admin/view/procuremen/details_fragment.html

@@ -295,6 +295,19 @@
         white-space: nowrap;
         font-size: 12px;
     }
+    .procuremen-details-wrap .detail-supplier-table th.col-rank,
+    .procuremen-details-wrap .detail-supplier-table td.col-rank {
+        width: 64px;
+        min-width: 64px;
+        text-align: center !important;
+        vertical-align: middle !important;
+    }
+    .procuremen-details-wrap .detail-supplier-table td.col-rank {
+        font-size: 17px;
+        font-weight: 700;
+        color: #1f1f1f;
+        line-height: 1.2;
+    }
     .procuremen-details-wrap .detail-supplier-table th.col-unit-price,
     .procuremen-details-wrap .detail-supplier-table td.col-unit-price {
         width: 90px;
@@ -516,7 +529,7 @@
                 <th class="col-supplier-user">姓名</th>
                 <th class="col-supplier-email">邮箱</th>
                 <th class="col-supplier-phone">手机号</th>
-                <th class="text-center" style="width:56px;">排名</th>
+                <th class="text-center col-rank" style="width:64px;">排名</th>
                 <th class="text-center" style="width:88px;">商务/技术得分</th>
                 <th class="text-center" style="width:80px;" title="价格得分=(最低单价合计/本供应商单价合计)×价格权重%×100">价格得分</th>
                 <th class="text-center" style="width:72px;">总分</th>
@@ -541,7 +554,7 @@
                 <td class="col-supplier-user"{if condition="$sg.display_rowspan gt 1"} rowspan="{$sg.display_rowspan}"{/if} style="vertical-align:middle;">{$sg.username|default=''|htmlentities}</td>
                 <td class="col-supplier-email"{if condition="$sg.display_rowspan gt 1"} rowspan="{$sg.display_rowspan}"{/if} style="vertical-align:middle;">{:htmlentities(mask_email(isset($sg['email']) ? $sg['email'] : ''))}</td>
                 <td class="col-supplier-phone"{if condition="$sg.display_rowspan gt 1"} rowspan="{$sg.display_rowspan}"{/if} style="vertical-align:middle;">{:htmlentities(mask_phone(isset($sg['phone']) ? $sg['phone'] : ''))}</td>
-                <td class="text-center"{if condition="$sg.display_rowspan gt 1"} rowspan="{$sg.display_rowspan}"{/if} style="vertical-align:middle;">{$sg.service_rank_text|default=''|htmlentities}</td>
+                <td class="text-center col-rank"{if condition="$sg.display_rowspan gt 1"} rowspan="{$sg.display_rowspan}"{/if}>{$sg.service_rank_text|default=''|htmlentities}</td>
                 <td class="text-center"{if condition="$sg.display_rowspan gt 1"} rowspan="{$sg.display_rowspan}"{/if} style="vertical-align:middle;">{$sg.service_quality_score_text|default=''|htmlentities}</td>
                 <td class="text-center"{if condition="$sg.display_rowspan gt 1"} rowspan="{$sg.display_rowspan}"{/if} style="vertical-align:middle;" title="单价合计 {$sg.service_price_sum_text|default=''|htmlentities}">{$sg.service_price_score_text|default=''|htmlentities}</td>
                 <td class="text-center"{if condition="$sg.display_rowspan gt 1"} rowspan="{$sg.display_rowspan}"{/if} style="vertical-align:middle;font-weight:600;">{$sg.service_score_text|default=''|htmlentities}</td>

+ 2 - 2
application/admin/view/procuremen/outward_detail.html

@@ -352,7 +352,7 @@
                 <th style="width:88px;">姓名</th>
                 <th style="min-width:160px;">邮箱</th>
                 <th style="width:120px;">手机号</th>
-                <th class="text-center" style="width:56px;">排名</th>
+                <th class="text-center col-rank" style="width:64px;">排名</th>
                 <th class="text-center" style="width:88px;">商务/技术得分</th>
                 <th class="text-center" style="width:80px;" title="价格得分=(最低单价合计/本供应商单价合计)×价格权重%×100">价格得分</th>
                 <th class="text-center" style="width:72px;">总分</th>
@@ -380,7 +380,7 @@
                 <td{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{$co.username|default=''|htmlentities}</td>
                 <td{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{:htmlentities(mask_email(isset($co['email']) ? $co['email'] : ''))}</td>
                 <td{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{:htmlentities(mask_phone(isset($co['phone']) ? $co['phone'] : ''))}</td>
-                <td class="text-center"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{if condition="!empty($bidOpenVerified)"}{$co.service_rank_text|default=''|htmlentities}{/if}</td>
+                <td class="text-center col-rank"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;font-size:17px;font-weight:700;">{if condition="!empty($bidOpenVerified)"}{$co.service_rank_text|default=''|htmlentities}{/if}</td>
                 <td class="text-center"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;">{if condition="!empty($bidOpenVerified)"}{$co.service_quality_score_text|default=''|htmlentities}{/if}</td>
                 <td class="text-center"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;"{if condition="!empty($bidOpenVerified)"} title="单价合计 {$co.service_price_sum_text|default=''|htmlentities}"{/if}>{if condition="!empty($bidOpenVerified)"}{$co.service_price_score_text|default=''|htmlentities}{/if}</td>
                 <td class="text-center"{if condition="$co.display_rowspan gt 1"} rowspan="{$co.display_rowspan}"{/if} style="vertical-align:middle;font-weight:600;">{if condition="!empty($bidOpenVerified)"}{$co.service_score_text|default=''|htmlentities}{/if}</td>

+ 10 - 11
application/database.php

@@ -1,19 +1,18 @@
 <?php
-
-// +----------------------------------------------------------------------
-// | ThinkPHP [ WE CAN DO IT JUST THINK ]
-// +----------------------------------------------------------------------
-// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
-// +----------------------------------------------------------------------
-// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
-// +----------------------------------------------------------------------
-// | Author: liu21st <liu21st@gmail.com>
-// +----------------------------------------------------------------------
-
 use think\Env;
 
 return [
     // 数据库类型
+
+//    // 服务器地址
+//    'hostname'        => Env::get('database.hostname', '121.40.91.170'),
+//    // 数据库名
+//    'database'        => Env::get('database.database', 'xinhua_erp'),
+//    // 用户名
+//    'username'        => Env::get('database.username', 'xinhua_erp'),
+//    // 密码
+//    'password'        => Env::get('database.password', 'YiDxNKHBiAkTnRtb'),
+
     // 服务器地址
     'hostname'        => Env::get('database.hostname', 'rm-bp17w41t6c09dl10ayo.mysql.rds.aliyuncs.com'),
     // 数据库名

+ 121 - 10
public/assets/js/backend/procuremen.js

@@ -1060,16 +1060,23 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 var got = false;
                 ['czlyq', 'CCLBMMC', 'cywyxm', 'CGYMC'].forEach(function (f) {
                     var src = incoming[f];
-                    if (!src || typeof src !== 'object') {
+                    if (src == null) {
                         return;
                     }
-                    if (!filterOpts[f] || typeof filterOpts[f] !== 'object') {
+                    var normalized = procuremenNormalizeFilterMap(src);
+                    if (!filterOpts[f] || typeof filterOpts[f] !== 'object' || $.isArray(filterOpts[f])) {
                         filterOpts[f] = {};
                     }
-                    if (Object.keys(src).length) {
+                    // 若已有选项是下标污染,直接替换
+                    if (procuremenFilterMapLooksLikeIndexJunk(filterOpts[f])) {
+                        filterOpts[f] = {};
+                    }
+                    if (Object.keys(normalized).length) {
                         got = true;
+                        $.extend(filterOpts[f], normalized);
+                        // 再规范化一次,避免 extend 留下数字下标
+                        filterOpts[f] = procuremenNormalizeFilterMap(filterOpts[f]);
                     }
-                    $.extend(filterOpts[f], src);
                 });
                 if (typeof Config !== 'undefined') {
                     Config.procuremenFilterOptions = filterOpts;
@@ -1078,9 +1085,98 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     Controller._filterOptionsReady = true;
                 }
             }
+            function procuremenNormalizeFilterMap(src) {
+                var out = {};
+                if (!src) {
+                    return out;
+                }
+                if ($.isArray(src)) {
+                    // JSON 数组:用值本身做选项,切勿用下标 0/1/2…
+                    src.forEach(function (v) {
+                        var s = String(v == null ? '' : v).trim();
+                        if (s !== '') {
+                            out[s] = s;
+                        }
+                    });
+                    return out;
+                }
+                if (typeof src !== 'object') {
+                    return out;
+                }
+                $.each(src, function (k, v) {
+                    var vs = String(v == null ? '' : v).trim();
+                    var ks = String(k == null ? '' : k).trim();
+                    // 优先用值;值为空时若 key 不是纯数字下标再用 key
+                    var s = vs !== '' ? vs : ((ks !== '' && !/^\d+$/.test(ks)) ? ks : '');
+                    if (s === '') {
+                        return;
+                    }
+                    // 丢掉 0=>0、1=>1 这种数组下标伪选项(真实工序名「1206」会因值=键且来自业务字段而保留:若全是这类则后面用表数据重建)
+                    if (/^\d+$/.test(ks) && vs === ks && /^\d+$/.test(vs) && parseInt(vs, 10) < 50 && String(parseInt(vs, 10)) === vs) {
+                        // 仍保留:可能是合法短数字编码;仅在「整表都是 0..n 连续下标」时判定损坏
+                        out[s] = s;
+                        return;
+                    }
+                    out[s] = s;
+                });
+                return out;
+            }
+            function procuremenFilterMapLooksLikeIndexJunk(map) {
+                var keys = Object.keys(map || {});
+                if (keys.length < 2) {
+                    return keys.length === 0;
+                }
+                var allSmallInt = true;
+                var nums = [];
+                keys.forEach(function (k) {
+                    var s = String(map[k] == null ? k : map[k]).trim();
+                    if (!/^\d+$/.test(s)) {
+                        allSmallInt = false;
+                        return;
+                    }
+                    var n = parseInt(s, 10);
+                    if (n > 30) {
+                        allSmallInt = false;
+                        return;
+                    }
+                    nums.push(n);
+                });
+                if (!allSmallInt || !nums.length) {
+                    return false;
+                }
+                nums.sort(function (a, b) { return a - b; });
+                // 连续 0..n 或 1..n 视为下标污染
+                var start = nums[0];
+                if (start !== 0 && start !== 1) {
+                    return false;
+                }
+                for (var i = 1; i < nums.length; i++) {
+                    if (nums[i] !== nums[i - 1] + 1) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+            function procuremenCollectFilterFromTable(field) {
+                var out = {};
+                try {
+                    var data = $('#table').bootstrapTable('getData') || [];
+                    data.forEach(function (row) {
+                        if (!row || typeof row !== 'object') {
+                            return;
+                        }
+                        var s = String(row[field] == null ? '' : row[field]).trim();
+                        if (s !== '') {
+                            out[s] = s;
+                        }
+                    });
+                } catch (ignore) {
+                }
+                return out;
+            }
             function procuremenSearchList(field) {
                 var list = filterOpts && filterOpts[field] ? filterOpts[field] : {};
-                return list && typeof list === 'object' ? list : {};
+                return procuremenNormalizeFilterMap(list);
             }
             // 表头标题文字后小筛选:承揽部门 / 工序名称 / 类型
             Controller.colFilters = {CCLBMMC: '', CGYMC: '', czlyq: ''};
@@ -1096,22 +1192,37 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     .replace(/>/g, '&gt;')
                     .replace(/"/g, '&quot;');
             }
+            function procuremenResolveFilterList(field) {
+                var list = procuremenSearchList(field);
+                var fromTable = procuremenCollectFilterFromTable(field);
+                if (procuremenFilterMapLooksLikeIndexJunk(list)) {
+                    list = {};
+                }
+                list = procuremenNormalizeFilterMap($.extend({}, list, fromTable));
+                if (procuremenFilterMapLooksLikeIndexJunk(list)) {
+                    // 表数据也异常时至少不要展示 0..n
+                    list = procuremenNormalizeFilterMap(fromTable);
+                }
+                return list;
+            }
             function procuremenBuildHeaderFilterMenu(field) {
                 var cur = Controller.colFilters[field] || '';
-                var list = procuremenSearchList(field);
+                var list = procuremenResolveFilterList(field);
                 var html = '<li' + (!cur ? ' class="active"' : '') + '>'
                     + '<a href="javascript:;" class="procuremen-th-filter-item" data-field="'
                     + procuremenEscOption(field) + '" data-value="">全部</a></li>';
-                $.each(list, function (k, v) {
-                    var val = k != null && String(k) !== '' ? String(k) : String(v);
-                    var lab = v != null && String(v) !== '' ? String(v) : val;
+                var labels = Object.keys(list).sort(function (a, b) {
+                    return String(a).localeCompare(String(b), 'zh');
+                });
+                labels.forEach(function (lab) {
+                    var val = String(list[lab] != null ? list[lab] : lab).trim();
                     if (!val) {
                         return;
                     }
                     html += '<li' + (cur === val ? ' class="active"' : '') + '>'
                         + '<a href="javascript:;" class="procuremen-th-filter-item" data-field="'
                         + procuremenEscOption(field) + '" data-value="' + procuremenEscOption(val) + '">'
-                        + procuremenEscOption(lab) + '</a></li>';
+                        + procuremenEscOption(val) + '</a></li>';
                 });
                 return html;
             }