|
|
@@ -210,11 +210,46 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
return (n < 10 ? '0' : '') + n;
|
|
|
}
|
|
|
|
|
|
+ function procuremenTodayYmd() {
|
|
|
+ if (typeof moment === 'function') {
|
|
|
+ return moment().format('YYYY-MM-DD');
|
|
|
+ }
|
|
|
+ var d = new Date();
|
|
|
+ return d.getFullYear() + '-' + procuremenPad2(d.getMonth() + 1) + '-' + procuremenPad2(d.getDate());
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 日期控件禁止选择今天之前(min=今天) */
|
|
|
+ function procuremenApplyDateMinToday($input, tipMsg) {
|
|
|
+ if (!$input || !$input.length) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var today = procuremenTodayYmd();
|
|
|
+ $input.attr('min', today);
|
|
|
+ var v = ($input.val() || '').trim();
|
|
|
+ if (v && v < today) {
|
|
|
+ $input.val(today);
|
|
|
+ }
|
|
|
+ $input.off('change.procuremenMinToday input.procuremenMinToday')
|
|
|
+ .on('change.procuremenMinToday input.procuremenMinToday', function () {
|
|
|
+ var t = procuremenTodayYmd();
|
|
|
+ var cur = ($(this).val() || '').trim();
|
|
|
+ if (cur && cur < t) {
|
|
|
+ $(this).val(t);
|
|
|
+ if (tipMsg && typeof Toastr !== 'undefined' && typeof Toastr.warning === 'function') {
|
|
|
+ Toastr.warning(tipMsg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
function procuremenDefaultSysRqValue() {
|
|
|
+ // 默认取当前时间+1分钟,避免同一分钟内默认值已过期
|
|
|
if (typeof moment === 'function') {
|
|
|
- return moment().format('YYYY-MM-DD HH:mm:ss');
|
|
|
+ return moment().add(1, 'minutes').seconds(0).format('YYYY-MM-DD HH:mm:ss');
|
|
|
}
|
|
|
var d = new Date();
|
|
|
+ d.setMinutes(d.getMinutes() + 1);
|
|
|
+ d.setSeconds(0);
|
|
|
return d.getFullYear() + '-' + procuremenPad2(d.getMonth() + 1) + '-' + procuremenPad2(d.getDate())
|
|
|
+ ' ' + procuremenPad2(d.getHours()) + ':' + procuremenPad2(d.getMinutes()) + ':00';
|
|
|
}
|
|
|
@@ -232,6 +267,118 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
return procuremenDefaultSysRqValue();
|
|
|
}
|
|
|
|
|
|
+ /** 初选/补加:进页即把供应商列表锁成「铺满到底栏」的固定高度,避免点复选框后才跳变 */
|
|
|
+ /**
|
|
|
+ * 钉住供应商列表区高度(仅进页/加载时用)。
|
|
|
+ * 勾选/取消勾选切勿再调用:重复按 offset 重算会令表格高度跳动。
|
|
|
+ * 定稿后复用同一高度,避免二次测量漂移。
|
|
|
+ */
|
|
|
+ function procuremenPinSupplierPickerLayout(force) {
|
|
|
+ var $form = $('.review-dialog-form').first();
|
|
|
+ if (!$form.length) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var $panel = $form.find('.review-company-panel').first();
|
|
|
+ var $footer = $form.find('.layer-footer').first();
|
|
|
+ var $right = $form.find('.review-split-right').first();
|
|
|
+ if (!$panel.length || !$right.length) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var applyHeight = function (h) {
|
|
|
+ var px = h + 'px';
|
|
|
+ // 覆盖样式表里的 height:auto !important,否则钉高无效
|
|
|
+ try {
|
|
|
+ $right[0].style.setProperty('height', px, 'important');
|
|
|
+ $right[0].style.setProperty('min-height', px, 'important');
|
|
|
+ $right[0].style.setProperty('max-height', px, 'important');
|
|
|
+ $panel[0].style.setProperty('height', px, 'important');
|
|
|
+ $panel[0].style.setProperty('min-height', px, 'important');
|
|
|
+ $panel[0].style.setProperty('max-height', px, 'important');
|
|
|
+ } catch (eStyle) {
|
|
|
+ $right.css({height: px, minHeight: px, maxHeight: px});
|
|
|
+ $panel.css({height: px, minHeight: px, maxHeight: px});
|
|
|
+ }
|
|
|
+ };
|
|
|
+ var measureAndApply = function () {
|
|
|
+ try {
|
|
|
+ $('html, body').css({
|
|
|
+ height: '100%',
|
|
|
+ maxHeight: '100%',
|
|
|
+ overflow: 'hidden',
|
|
|
+ margin: 0
|
|
|
+ });
|
|
|
+ } catch (eBody) {
|
|
|
+ }
|
|
|
+ $form.css({
|
|
|
+ height: '100%',
|
|
|
+ maxHeight: '100%',
|
|
|
+ overflow: 'hidden'
|
|
|
+ });
|
|
|
+ // 勿清空 .review-selected-summary 的 height/maxHeight,否则已选区会随勾选撑开并把列表顶矮
|
|
|
+ $form.find('.review-split-left').css({flex: '0 0 auto'});
|
|
|
+ var winH = $(window).height() || 0;
|
|
|
+ if (winH < 200) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ var footerH = $footer.length ? ($footer.outerHeight(true) || 48) : 48;
|
|
|
+ var top = 0;
|
|
|
+ try {
|
|
|
+ top = Math.floor($panel.offset().top || 0);
|
|
|
+ } catch (eTop) {
|
|
|
+ top = 0;
|
|
|
+ }
|
|
|
+ var h = Math.floor(winH - top - footerH - 2);
|
|
|
+ if (h < 260) {
|
|
|
+ h = 260;
|
|
|
+ }
|
|
|
+ applyHeight(h);
|
|
|
+ return h;
|
|
|
+ };
|
|
|
+ var pinned = parseInt($form.data('procuremenPinnedPanelH'), 10) || 0;
|
|
|
+ if (pinned >= 260 && !force) {
|
|
|
+ applyHeight(pinned);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 弹层动画结束后的强制重测:测一次即定稿,避免连串 setTimeout 反复跳
|
|
|
+ if (force) {
|
|
|
+ var hf = measureAndApply();
|
|
|
+ if (hf >= 260) {
|
|
|
+ $form.data('procuremenPinnedPanelH', hf);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ measureAndApply();
|
|
|
+ setTimeout(function () {
|
|
|
+ if ($form.data('procuremenPinnedPanelH')) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ measureAndApply();
|
|
|
+ }, 50);
|
|
|
+ setTimeout(function () {
|
|
|
+ if ($form.data('procuremenPinnedPanelH')) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ measureAndApply();
|
|
|
+ }, 200);
|
|
|
+ setTimeout(function () {
|
|
|
+ if ($form.data('procuremenPinnedPanelH')) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var h = measureAndApply();
|
|
|
+ if (h >= 260) {
|
|
|
+ $form.data('procuremenPinnedPanelH', h);
|
|
|
+ }
|
|
|
+ }, 450);
|
|
|
+ if (typeof window.requestAnimationFrame === 'function') {
|
|
|
+ window.requestAnimationFrame(function () {
|
|
|
+ if ($form.data('procuremenPinnedPanelH')) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ measureAndApply();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/** 截止时间:日期 + 时下拉 + 分下拉(options.readonly 时仅展示不可改) */
|
|
|
function procuremenInitSysRqSplit($wrap, eventNs, options) {
|
|
|
if (!$wrap || !$wrap.length) {
|
|
|
@@ -240,6 +387,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
options = options || {};
|
|
|
var readonly = !!options.readonly;
|
|
|
var $hidden = $wrap.find('input[type="hidden"][id$="-sys-rq"]');
|
|
|
+ if (!$hidden.length) {
|
|
|
+ $hidden = $wrap.find('input[type="hidden"]').first();
|
|
|
+ }
|
|
|
var $date = $wrap.find('.procuremen-sys-rq-date');
|
|
|
var $hour = $wrap.find('.procuremen-sys-rq-hour');
|
|
|
var $minute = $wrap.find('.procuremen-sys-rq-minute');
|
|
|
@@ -293,9 +443,123 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ procuremenApplyDateMinToday($date, '招标截止日期不能早于今天');
|
|
|
+
|
|
|
+ // 选今天时:过去的时/分直接不渲染(不灰显),避免客户误以为点不了
|
|
|
+ var rebuildHourOptions = function (minH) {
|
|
|
+ var keep = $hour.val();
|
|
|
+ var html = [];
|
|
|
+ var h;
|
|
|
+ for (h = minH; h < 24; h++) {
|
|
|
+ html.push('<option value="' + procuremenPad2(h) + '">' + procuremenPad2(h) + '</option>');
|
|
|
+ }
|
|
|
+ $hour.html(html.join(''));
|
|
|
+ if (keep !== null && keep !== undefined && parseInt(keep, 10) >= minH) {
|
|
|
+ $hour.val(procuremenPad2(parseInt(keep, 10)));
|
|
|
+ } else if (html.length) {
|
|
|
+ $hour.val(procuremenPad2(minH));
|
|
|
+ }
|
|
|
+ };
|
|
|
+ var rebuildMinuteOptions = function (minM) {
|
|
|
+ var keep = $minute.val();
|
|
|
+ var html = [];
|
|
|
+ var m;
|
|
|
+ for (m = minM; m < 60; m++) {
|
|
|
+ html.push('<option value="' + procuremenPad2(m) + '">' + procuremenPad2(m) + '</option>');
|
|
|
+ }
|
|
|
+ $minute.html(html.join(''));
|
|
|
+ if (keep !== null && keep !== undefined && parseInt(keep, 10) >= minM) {
|
|
|
+ $minute.val(procuremenPad2(parseInt(keep, 10)));
|
|
|
+ } else if (html.length) {
|
|
|
+ $minute.val(procuremenPad2(minM));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ var refreshTimeOptionsForToday = function (showTip) {
|
|
|
+ var today = procuremenTodayYmd();
|
|
|
+ var d = ($date.val() || '').trim();
|
|
|
+ var now = new Date();
|
|
|
+ var curH = now.getHours();
|
|
|
+ var curM = now.getMinutes();
|
|
|
+ var isToday = (d === today);
|
|
|
+ var prevH = parseInt($hour.val(), 10);
|
|
|
+ var prevM = parseInt($minute.val(), 10);
|
|
|
+ var changed = false;
|
|
|
+
|
|
|
+ if (!isToday) {
|
|
|
+ rebuildHourOptions(0);
|
|
|
+ rebuildMinuteOptions(0);
|
|
|
+ if (!isNaN(prevH)) {
|
|
|
+ $hour.val(procuremenPad2(prevH));
|
|
|
+ }
|
|
|
+ if (!isNaN(prevM)) {
|
|
|
+ $minute.val(procuremenPad2(prevM));
|
|
|
+ }
|
|
|
+ syncToHidden();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 当天:只列出当前时刻之后的时分
|
|
|
+ var minH = curH;
|
|
|
+ var minM = curM + 1;
|
|
|
+ if (minM >= 60) {
|
|
|
+ minM = 0;
|
|
|
+ minH = curH + 1;
|
|
|
+ }
|
|
|
+ if (minH > 23) {
|
|
|
+ // 当天已无可用时间,跳到明天 00:00
|
|
|
+ var t = new Date();
|
|
|
+ t.setDate(t.getDate() + 1);
|
|
|
+ var nd = t.getFullYear() + '-' + procuremenPad2(t.getMonth() + 1) + '-' + procuremenPad2(t.getDate());
|
|
|
+ $date.val(nd);
|
|
|
+ rebuildHourOptions(0);
|
|
|
+ rebuildMinuteOptions(0);
|
|
|
+ $hour.val('00');
|
|
|
+ $minute.val('00');
|
|
|
+ changed = true;
|
|
|
+ } else {
|
|
|
+ rebuildHourOptions(minH);
|
|
|
+ var selH = parseInt($hour.val(), 10);
|
|
|
+ if (isNaN(selH) || selH < minH) {
|
|
|
+ selH = minH;
|
|
|
+ $hour.val(procuremenPad2(selH));
|
|
|
+ changed = true;
|
|
|
+ }
|
|
|
+ if (selH === minH) {
|
|
|
+ rebuildMinuteOptions(minM);
|
|
|
+ var selM = parseInt($minute.val(), 10);
|
|
|
+ if (isNaN(selM) || selM < minM) {
|
|
|
+ $minute.val(procuremenPad2(minM));
|
|
|
+ changed = true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ rebuildMinuteOptions(0);
|
|
|
+ if (!isNaN(prevM)) {
|
|
|
+ $minute.val(procuremenPad2(prevM));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!isNaN(prevH) && prevH < minH) {
|
|
|
+ changed = true;
|
|
|
+ }
|
|
|
+ if (!isNaN(prevM) && selH === minH && prevM < minM) {
|
|
|
+ changed = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ syncToHidden();
|
|
|
+ if (changed && showTip && typeof Toastr !== 'undefined' && typeof Toastr.warning === 'function') {
|
|
|
+ Toastr.warning('当天截止时间不能早于当前时间');
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ refreshTimeOptionsForToday(false);
|
|
|
+
|
|
|
$date.add($hour).add($minute)
|
|
|
.off('change.' + eventNs + ' input.' + eventNs)
|
|
|
- .on('change.' + eventNs + ' input.' + eventNs, syncToHidden);
|
|
|
+ .on('change.' + eventNs + ' input.' + eventNs, function () {
|
|
|
+ refreshTimeOptionsForToday(true);
|
|
|
+ syncToHidden();
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
function procuremenFocusSysRqSplit($wrap) {
|
|
|
@@ -1412,7 +1676,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
sessionStorage.setItem('procuremen_merge_rows', JSON.stringify(selRows));
|
|
|
} catch (ignoreStore) {
|
|
|
}
|
|
|
- var titlePick = ' ';
|
|
|
+ var titlePick = '初选供应商';
|
|
|
var revUrl = Fast.api.fixurl('procuremen/pickreview?ids=' + encodeURIComponent(ids[0]) + '&merge=1');
|
|
|
var winPick = window;
|
|
|
if (!winPick.Backend || !winPick.Backend.api) {
|
|
|
@@ -1492,7 +1756,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
);
|
|
|
Layer.confirm(deleteMsg, $.extend({}, procuremenConfirmLayerBase, {
|
|
|
title: '删除',
|
|
|
- btn: ['确定删除', '取消']
|
|
|
+ btn: ['确认删除', '取消']
|
|
|
}), function (idxDel) {
|
|
|
Layer.close(idxDel);
|
|
|
Fast.api.ajax({
|
|
|
@@ -1525,7 +1789,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
);
|
|
|
Layer.confirm(finishBatchMsg, $.extend({}, procuremenConfirmLayerBase, {
|
|
|
title: '完结确认',
|
|
|
- btn: ['确定', '取消']
|
|
|
+ btn: ['确认', '取消']
|
|
|
}), function (idxFin) {
|
|
|
Layer.close(idxFin);
|
|
|
var tokenFin = $('input[name=\'__token__\']').val() || '';
|
|
|
@@ -1927,7 +2191,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
}
|
|
|
var winA = window;
|
|
|
if (winA.Backend && winA.Backend.api) {
|
|
|
- winA.Backend.api.open(auditUrl, '供应商报价明细', {area: ['98%', '92%']});
|
|
|
+ winA.Backend.api.open(auditUrl, '供应商报价明细', {area: ['100%', '100%']});
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
@@ -2477,7 +2741,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
title: '采购终审 — 审批通过',
|
|
|
area: ['480px', 'auto'],
|
|
|
offset: 'auto',
|
|
|
- btn: ['确定提交', '取消'],
|
|
|
+ btn: ['确认提交', '取消'],
|
|
|
fixed: true,
|
|
|
shade: 0.35,
|
|
|
zIndex: procuremenLayerNextZIndex(),
|
|
|
@@ -2611,8 +2875,33 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
review: function () {
|
|
|
Controller.api.bindevent();
|
|
|
procuremenInitSysRqSplit($('#review-sys-rq-wrap'), 'reviewSysRq');
|
|
|
+ procuremenPinSupplierPickerLayout();
|
|
|
+
|
|
|
+ (function () {
|
|
|
+ var $dd = $('#review-delivery-deadline');
|
|
|
+ if (!$dd.length) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ procuremenApplyDateMinToday($dd, '交货截止日期不能早于今天');
|
|
|
+ var syncDeliveryDeadlineUi = function () {
|
|
|
+ $dd.toggleClass('has-value', !!(($dd.val() || '').trim()));
|
|
|
+ };
|
|
|
+ $dd.on('change input', syncDeliveryDeadlineUi);
|
|
|
+ syncDeliveryDeadlineUi();
|
|
|
+ })();
|
|
|
|
|
|
function procuremenReviewWarn(msg) {
|
|
|
+ // 弹层 iframe 内优先本页提示,避免被父页 Layer 遮罩盖住
|
|
|
+ var inDialog = false;
|
|
|
+ try {
|
|
|
+ inDialog = !!(window.frameElement) || ($('body').hasClass('is-dialog'));
|
|
|
+ } catch (eIn) {
|
|
|
+ inDialog = false;
|
|
|
+ }
|
|
|
+ if (inDialog && typeof Toastr !== 'undefined' && typeof Toastr.warning === 'function') {
|
|
|
+ Toastr.warning(msg);
|
|
|
+ return;
|
|
|
+ }
|
|
|
var shown = false;
|
|
|
try {
|
|
|
if (typeof parent !== 'undefined' && parent.Toastr && typeof parent.Toastr.warning === 'function') {
|
|
|
@@ -2695,10 +2984,39 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
}
|
|
|
var sysRq = ($rq.val() || '').trim();
|
|
|
if (!sysRq) {
|
|
|
- procuremenReviewWarn('请选择截止时间');
|
|
|
+ procuremenReviewWarn('请选择招标截止日期');
|
|
|
procuremenFocusSysRqSplit($rqWrap);
|
|
|
return;
|
|
|
}
|
|
|
+ var todayYmd = procuremenTodayYmd();
|
|
|
+ var bidYmd = (sysRq.match(/^(\d{4}-\d{2}-\d{2})/) || [])[1] || '';
|
|
|
+ if (!bidYmd || bidYmd < todayYmd) {
|
|
|
+ procuremenReviewWarn('招标截止日期不能早于今天');
|
|
|
+ procuremenFocusSysRqSplit($rqWrap);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var bidTs = Date.parse(String(sysRq).replace(/-/g, '/'));
|
|
|
+ if (!bidTs || isNaN(bidTs) || bidTs <= Date.now()) {
|
|
|
+ procuremenReviewWarn('招标截止时间不能早于当前时间');
|
|
|
+ procuremenFocusSysRqSplit($rqWrap);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var $deliveryDeadline = $('#review-delivery-deadline');
|
|
|
+ var deliveryDeadline = ($deliveryDeadline.val() || '').trim();
|
|
|
+ if (!deliveryDeadline) {
|
|
|
+ procuremenReviewWarn('请选择交货截止日期');
|
|
|
+ try {
|
|
|
+ $deliveryDeadline.focus();
|
|
|
+ } catch (ignoreFocus) {}
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (deliveryDeadline < todayYmd) {
|
|
|
+ procuremenReviewWarn('交货截止日期不能早于今天');
|
|
|
+ try {
|
|
|
+ $deliveryDeadline.focus();
|
|
|
+ } catch (ignoreFocus2) {}
|
|
|
+ return;
|
|
|
+ }
|
|
|
var cons;
|
|
|
try {
|
|
|
cons = JSON.parse($('#c-row-json').val() || '{}');
|
|
|
@@ -2728,7 +3046,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
row_json: JSON.stringify(cons),
|
|
|
merge_rows_json: mergePayload,
|
|
|
companies_json: JSON.stringify(selected),
|
|
|
- sys_rq: sysRq
|
|
|
+ sys_rq: sysRq,
|
|
|
+ delivery_deadline: deliveryDeadline
|
|
|
}
|
|
|
}, function (data, ret) {
|
|
|
var msg = (ret && ret.msg) ? ret.msg : '操作成功';
|
|
|
@@ -3374,6 +3693,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
$masterF.prop('indeterminate', nF > 0 && nF < $cbsF.length);
|
|
|
}
|
|
|
syncReviewSelectedSummary();
|
|
|
+ procuremenPinSupplierPickerLayout();
|
|
|
return false;
|
|
|
});
|
|
|
}
|
|
|
@@ -3413,6 +3733,403 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
});
|
|
|
},
|
|
|
|
|
|
+ auditappend: function () {
|
|
|
+ var existingNames = {};
|
|
|
+ try {
|
|
|
+ var rawEx = $('#audit-append-existing-json').val() || '[]';
|
|
|
+ var arrEx = JSON.parse(rawEx);
|
|
|
+ if ($.isArray(arrEx)) {
|
|
|
+ $.each(arrEx, function (i, n) {
|
|
|
+ var t = String(n || '').trim();
|
|
|
+ if (t) {
|
|
|
+ existingNames[t] = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } catch (eEx) {
|
|
|
+ existingNames = {};
|
|
|
+ }
|
|
|
+
|
|
|
+ var reviewCompaniesAll = [];
|
|
|
+ var activeReviewCategory = null;
|
|
|
+ var reviewCompanySearchQ = '';
|
|
|
+ var reviewSelectedMap = {};
|
|
|
+ var reviewSearchTimer = null;
|
|
|
+
|
|
|
+ function isExistingCompany(c) {
|
|
|
+ var n = String((c && (c.name || c.company_name)) || '').trim();
|
|
|
+ return !!(n && existingNames[n]);
|
|
|
+ }
|
|
|
+
|
|
|
+ function syncReviewSelectedSummary() {
|
|
|
+ var entries = [];
|
|
|
+ $.each(reviewSelectedMap, function (k, c) {
|
|
|
+ if (!c || isExistingCompany(c)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var t = String(c.name || c.company_name || '').trim() || '(无名称)';
|
|
|
+ entries.push({k: k, label: t});
|
|
|
+ });
|
|
|
+ entries.sort(function (a, b) {
|
|
|
+ return a.label.localeCompare(b.label, 'zh-CN');
|
|
|
+ });
|
|
|
+ var n = entries.length;
|
|
|
+ var $summary = $('#review-selected-summary');
|
|
|
+ $('#review-selected-count').text(String(n));
|
|
|
+ $summary.toggleClass('is-empty', n === 0);
|
|
|
+ var $tags = $('#review-selected-tags').empty();
|
|
|
+ if (!n) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $.each(entries, function (i, e) {
|
|
|
+ var $chip = $('<span class="review-selected-chip"/>').attr('title', e.label);
|
|
|
+ $chip.data('reviewSelKey', e.k);
|
|
|
+ $chip.append(
|
|
|
+ $('<span class="review-chip-text"/>').text(e.label),
|
|
|
+ $('<button type="button" class="review-chip-remove" title="取消选择"/>').text('\u00d7')
|
|
|
+ );
|
|
|
+ $tags.append($chip);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function companyMatchesCategory(c, cat) {
|
|
|
+ if (!cat) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ var rawCat = (c.company_type != null && String(c.company_type).trim() !== '')
|
|
|
+ ? String(c.company_type).trim()
|
|
|
+ : String(c.category || '').trim();
|
|
|
+ var segs = [];
|
|
|
+ if (!rawCat) {
|
|
|
+ segs = ['未分类'];
|
|
|
+ } else {
|
|
|
+ var seen = {};
|
|
|
+ $.each(String(rawCat).split('、'), function (idx, p) {
|
|
|
+ var tt = String(p).trim();
|
|
|
+ if (!tt || seen[tt]) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ seen[tt] = true;
|
|
|
+ segs.push(tt);
|
|
|
+ });
|
|
|
+ if (!segs.length) {
|
|
|
+ segs = ['未分类'];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $.inArray(cat, segs) !== -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ function filteredCompanyList() {
|
|
|
+ var q = reviewCompanySearchQ;
|
|
|
+ var searchActive = q.length > 0;
|
|
|
+ var list = [];
|
|
|
+ $.each(reviewCompaniesAll, function (i, c) {
|
|
|
+ if (!c || typeof c !== 'object') {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!searchActive && activeReviewCategory !== null && !companyMatchesCategory(c, activeReviewCategory)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (q) {
|
|
|
+ var blob = [
|
|
|
+ c.name, c.company_name, c.username, c.email, c.phone,
|
|
|
+ c.company_type, c.category
|
|
|
+ ].map(function (x) {
|
|
|
+ return x == null ? '' : String(x);
|
|
|
+ }).join(' ').toLowerCase();
|
|
|
+ if (blob.indexOf(q) === -1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ list.push(c);
|
|
|
+ });
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ function renderCompanyRows() {
|
|
|
+ var list = filteredCompanyList();
|
|
|
+ var $tbody = $('#review-company-tbody').empty();
|
|
|
+ if (!list.length) {
|
|
|
+ $tbody.append($('<tr/>').append($('<td colspan="6" class="text-muted text-center"/>').text('暂无符合条件的单位')));
|
|
|
+ $('#review-check-all').prop('checked', false).prop('indeterminate', false);
|
|
|
+ syncReviewSelectedSummary();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $.each(list, function (i, c) {
|
|
|
+ var existing = isExistingCompany(c);
|
|
|
+ var $cb = $('<input type="checkbox" class="review-company-cb"/>');
|
|
|
+ $cb.data('company', c);
|
|
|
+ if (existing) {
|
|
|
+ $cb.prop('disabled', true).prop('checked', true);
|
|
|
+ } else {
|
|
|
+ var k = procuremenReviewCompanyKey(c);
|
|
|
+ if (k && reviewSelectedMap[k]) {
|
|
|
+ $cb.prop('checked', true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var $tr = $('<tr/>');
|
|
|
+ if (existing) {
|
|
|
+ $tr.addClass('is-existing').attr('title', '该供应商已在本单中');
|
|
|
+ }
|
|
|
+ $tr.append($('<td class="review-td-cb"/>').append($cb));
|
|
|
+ $tr.append($('<td/>').text((c.name || c.company_name || '') + (existing ? '(已下发)' : '')));
|
|
|
+ $tr.append($('<td/>').text(c.username || ''));
|
|
|
+ $tr.append($('<td/>').text(c.email || ''));
|
|
|
+ $tr.append($('<td/>').text(c.phone || ''));
|
|
|
+ $tr.append($('<td/>').text((c.company_type != null && String(c.company_type).trim() !== '') ? String(c.company_type).trim() : (c.category || '')));
|
|
|
+ $tbody.append($tr);
|
|
|
+ });
|
|
|
+ var $cbs = $('#review-company-tbody .review-company-cb:not(:disabled)');
|
|
|
+ var $master = $('#review-check-all');
|
|
|
+ if (!$cbs.length) {
|
|
|
+ $master.prop('checked', false).prop('indeterminate', false);
|
|
|
+ } else {
|
|
|
+ var n = $cbs.filter(':checked').length;
|
|
|
+ $master.prop('checked', n === $cbs.length);
|
|
|
+ $master.prop('indeterminate', n > 0 && n < $cbs.length);
|
|
|
+ }
|
|
|
+ syncReviewSelectedSummary();
|
|
|
+ }
|
|
|
+
|
|
|
+ function rebuildCategorySidebar() {
|
|
|
+ var counts = {};
|
|
|
+ var total = 0;
|
|
|
+ $.each(reviewCompaniesAll, function (i, c) {
|
|
|
+ if (!c || typeof c !== 'object') {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ total++;
|
|
|
+ var raw = (c.company_type != null && String(c.company_type).trim() !== '')
|
|
|
+ ? String(c.company_type).trim()
|
|
|
+ : String(c.category || '').trim();
|
|
|
+ var segs = [];
|
|
|
+ if (!raw) {
|
|
|
+ segs = ['未分类'];
|
|
|
+ } else {
|
|
|
+ var seen = {};
|
|
|
+ $.each(String(raw).split('、'), function (idx, p) {
|
|
|
+ var tt = String(p).trim();
|
|
|
+ if (!tt || seen[tt]) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ seen[tt] = true;
|
|
|
+ segs.push(tt);
|
|
|
+ });
|
|
|
+ if (!segs.length) {
|
|
|
+ segs = ['未分类'];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $.each(segs, function (j, seg) {
|
|
|
+ counts[seg] = (counts[seg] || 0) + 1;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ var cats = Object.keys(counts).sort(function (a, b) {
|
|
|
+ return a.localeCompare(b, 'zh-CN');
|
|
|
+ });
|
|
|
+ var $list = $('#review-category-list').empty();
|
|
|
+ var $all = $('<div class="review-cat-item review-cat-all"/>').append(
|
|
|
+ $('<span/>').text('全部 '),
|
|
|
+ $('<span class="review-cat-count"/>').text('(' + total + ')')
|
|
|
+ );
|
|
|
+ $all.toggleClass('active', activeReviewCategory === null);
|
|
|
+ $list.append($all);
|
|
|
+ $.each(cats, function (i, cat) {
|
|
|
+ var $it = $('<div class="review-cat-item"/>').append(
|
|
|
+ $('<span/>').text(cat + ' '),
|
|
|
+ $('<span class="review-cat-count"/>').text('(' + counts[cat] + ')')
|
|
|
+ );
|
|
|
+ $it.data('reviewCat', cat);
|
|
|
+ $it.toggleClass('active', activeReviewCategory === cat);
|
|
|
+ $list.append($it);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function loadCompanies() {
|
|
|
+ Fast.api.ajax({
|
|
|
+ url: 'procuremen/reviewCompanies',
|
|
|
+ type: 'GET',
|
|
|
+ loading: false
|
|
|
+ }, function (data) {
|
|
|
+ reviewCompaniesAll = Array.isArray(data) ? data : [];
|
|
|
+ reviewSelectedMap = {};
|
|
|
+ activeReviewCategory = null;
|
|
|
+ reviewCompanySearchQ = '';
|
|
|
+ $('#review-company-search').val('');
|
|
|
+ rebuildCategorySidebar();
|
|
|
+ renderCompanyRows();
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (typeof procuremenInitSysRqSplit === 'function') {
|
|
|
+ procuremenInitSysRqSplit($('#audit-append-sys-rq-wrap'), 'auditAppend', {readonly: true});
|
|
|
+ }
|
|
|
+
|
|
|
+ $(document).off('click.auditAppendCat', '#review-category-list .review-cat-item')
|
|
|
+ .on('click.auditAppendCat', '#review-category-list .review-cat-item', function () {
|
|
|
+ if ($(this).hasClass('review-cat-all')) {
|
|
|
+ activeReviewCategory = null;
|
|
|
+ } else {
|
|
|
+ activeReviewCategory = $(this).data('reviewCat') || null;
|
|
|
+ }
|
|
|
+ $('#review-category-list .review-cat-item').removeClass('active');
|
|
|
+ $(this).addClass('active');
|
|
|
+ renderCompanyRows();
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#review-company-search').off('input.auditAppendSearch').on('input.auditAppendSearch', function () {
|
|
|
+ var v = ($(this).val() || '').trim().toLowerCase();
|
|
|
+ if (reviewSearchTimer) {
|
|
|
+ clearTimeout(reviewSearchTimer);
|
|
|
+ }
|
|
|
+ reviewSearchTimer = setTimeout(function () {
|
|
|
+ reviewCompanySearchQ = v;
|
|
|
+ renderCompanyRows();
|
|
|
+ }, 180);
|
|
|
+ });
|
|
|
+
|
|
|
+ $(document).off('change.auditAppendCb', '#review-company-tbody .review-company-cb')
|
|
|
+ .on('change.auditAppendCb', '#review-company-tbody .review-company-cb', function () {
|
|
|
+ var $cb = $(this);
|
|
|
+ if ($cb.prop('disabled')) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var c = $cb.data('company');
|
|
|
+ var k = procuremenReviewCompanyKey(c);
|
|
|
+ var $cbs = $('#review-company-tbody .review-company-cb:not(:disabled)');
|
|
|
+ var $master = $('#review-check-all');
|
|
|
+ if (!k) {
|
|
|
+ if (!$cbs.length) {
|
|
|
+ $master.prop('checked', false).prop('indeterminate', false);
|
|
|
+ } else {
|
|
|
+ var n0 = $cbs.filter(':checked').length;
|
|
|
+ $master.prop('checked', n0 === $cbs.length);
|
|
|
+ $master.prop('indeterminate', n0 > 0 && n0 < $cbs.length);
|
|
|
+ }
|
|
|
+ syncReviewSelectedSummary();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if ($cb.prop('checked')) {
|
|
|
+ reviewSelectedMap[k] = c;
|
|
|
+ } else {
|
|
|
+ delete reviewSelectedMap[k];
|
|
|
+ }
|
|
|
+ var n = $cbs.filter(':checked').length;
|
|
|
+ $master.prop('checked', n === $cbs.length);
|
|
|
+ $master.prop('indeterminate', n > 0 && n < $cbs.length);
|
|
|
+ // 仅更新已选摘要,勿再钉高度(会按 offset 重算导致表格跳动)
|
|
|
+ syncReviewSelectedSummary();
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#review-check-all').off('change.auditAppendAll').on('change.auditAppendAll', function () {
|
|
|
+ var on = $(this).prop('checked');
|
|
|
+ $(this).prop('indeterminate', false);
|
|
|
+ $('#review-company-tbody .review-company-cb:not(:disabled)').each(function () {
|
|
|
+ var $cb = $(this);
|
|
|
+ var c = $cb.data('company');
|
|
|
+ var k = procuremenReviewCompanyKey(c);
|
|
|
+ $cb.prop('checked', on);
|
|
|
+ if (!k) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (on) {
|
|
|
+ reviewSelectedMap[k] = c;
|
|
|
+ } else {
|
|
|
+ delete reviewSelectedMap[k];
|
|
|
+ }
|
|
|
+ });
|
|
|
+ syncReviewSelectedSummary();
|
|
|
+ });
|
|
|
+
|
|
|
+ $(document).off('click.auditAppendChip', '.review-chip-remove')
|
|
|
+ .on('click.auditAppendChip', '.review-chip-remove', function (e) {
|
|
|
+ e.preventDefault();
|
|
|
+ var k = $(this).closest('.review-selected-chip').data('reviewSelKey');
|
|
|
+ if (k) {
|
|
|
+ delete reviewSelectedMap[k];
|
|
|
+ }
|
|
|
+ renderCompanyRows();
|
|
|
+ });
|
|
|
+
|
|
|
+ function closeAppendLayer() {
|
|
|
+ var index = parent.Layer.getFrameIndex(window.name);
|
|
|
+ parent.Layer.close(index);
|
|
|
+ }
|
|
|
+
|
|
|
+ $('#btn-audit-append-close').off('click.auditAppendClose').on('click.auditAppendClose', function () {
|
|
|
+ closeAppendLayer();
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#btn-audit-append-submit').off('click.auditAppendSubmit').on('click.auditAppendSubmit', function () {
|
|
|
+ var companies = [];
|
|
|
+ $.each(reviewSelectedMap, function (k, c) {
|
|
|
+ if (!c || isExistingCompany(c)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ companies.push(procuremenReviewCompanyPayload(c));
|
|
|
+ });
|
|
|
+ if (!companies.length) {
|
|
|
+ Toastr.warning('请至少选择一家新的供应商');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 弹窗久开后截止可能已到:确认前提示,服务端仍会再校验
|
|
|
+ var sysRq = ($('#audit-append-sys-rq').val() || '').trim();
|
|
|
+ if (sysRq) {
|
|
|
+ var normalized = String(sysRq).replace(/T/, ' ').replace(/-/g, '/');
|
|
|
+ var ts = Date.parse(normalized);
|
|
|
+ if (ts && !isNaN(ts) && Date.now() >= ts) {
|
|
|
+ Toastr.warning('已经超过了招标截止日期,不可操作');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var $btn = $(this);
|
|
|
+ if ($btn.data('loading')) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $btn.data('loading', 1).prop('disabled', true);
|
|
|
+ Fast.api.ajax({
|
|
|
+ url: 'procuremen/auditappendsubmit',
|
|
|
+ type: 'POST',
|
|
|
+ data: {
|
|
|
+ __token__: $('#audit-append-form input[name="__token__"]').val(),
|
|
|
+ scydgy_id: $('#audit-append-scydgy-id').val(),
|
|
|
+ companies_json: JSON.stringify(companies)
|
|
|
+ }
|
|
|
+ }, function (data, ret) {
|
|
|
+ var msg = (ret && ret.msg) ? ret.msg : '补加成功';
|
|
|
+ if (typeof parent !== 'undefined' && parent.Toastr) {
|
|
|
+ parent.Toastr.success(msg);
|
|
|
+ } else {
|
|
|
+ Toastr.success(msg);
|
|
|
+ }
|
|
|
+ setTimeout(function () {
|
|
|
+ try {
|
|
|
+ if (window.parent && window.parent !== window) {
|
|
|
+ var frames = window.parent.frames;
|
|
|
+ for (var fi = 0; fi < frames.length; fi++) {
|
|
|
+ try {
|
|
|
+ var href = frames[fi].location && frames[fi].location.href;
|
|
|
+ if (href && /auditissue/i.test(href)) {
|
|
|
+ frames[fi].location.reload();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } catch (eF) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (e2) {
|
|
|
+ }
|
|
|
+ closeAppendLayer();
|
|
|
+ }, 350);
|
|
|
+ return false;
|
|
|
+ }, function () {
|
|
|
+ $btn.data('loading', 0).prop('disabled', false);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ loadCompanies();
|
|
|
+ },
|
|
|
+
|
|
|
auditissue: function () {
|
|
|
function auditIssueClose() {
|
|
|
var index = parent.Layer.getFrameIndex(window.name);
|
|
|
@@ -3441,7 +4158,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
$('#audit-sys-rq-wrap').find('.procuremen-sys-rq-date').trigger('change');
|
|
|
var sysRq = auditIssueSysRq();
|
|
|
if (!sysRq) {
|
|
|
- Toastr.warning('请选择报价截止时间');
|
|
|
+ Toastr.warning('请选择招标截止日期');
|
|
|
procuremenFocusSysRqSplit($('#audit-sys-rq-wrap'));
|
|
|
return false;
|
|
|
}
|
|
|
@@ -3660,7 +4377,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
var layerIdx = Layer.open({
|
|
|
type: 1,
|
|
|
title: '开标验证',
|
|
|
- area: ['560px', 'auto'],
|
|
|
+ area: ['640px', 'auto'],
|
|
|
content: html,
|
|
|
btn: ['提交验证', '取消'],
|
|
|
yes: function (idx) {
|
|
|
@@ -3758,6 +4475,44 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
|
auditIssueOpenBidModal();
|
|
|
});
|
|
|
|
|
|
+ $('#btn-audit-append-supplier').off('click.auditAppend').on('click.auditAppend', function () {
|
|
|
+ var sid = $('input[name="scydgy_id"]').val() || '';
|
|
|
+ if (!sid) {
|
|
|
+ Toastr.warning('缺少工序参数');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (auditIssueBidOpenVerified()) {
|
|
|
+ Toastr.warning('已开标验证,不能再补加供应商');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 已过招标截止:按钮仍显示,点击提示不可操作
|
|
|
+ var deadlinePassed = parseInt($('#audit-append-deadline-passed').val(), 10) === 1;
|
|
|
+ if (!deadlinePassed) {
|
|
|
+ var sysRq = auditIssueSysRq();
|
|
|
+ if (sysRq) {
|
|
|
+ var normalized = String(sysRq).replace(/T/, ' ').replace(/-/g, '/');
|
|
|
+ var ts = Date.parse(normalized);
|
|
|
+ if (ts && !isNaN(ts) && Date.now() >= ts) {
|
|
|
+ deadlinePassed = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (deadlinePassed) {
|
|
|
+ Toastr.warning('已经超过了招标截止日期,不可操作');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var url = Fast.api.fixurl('procuremen/auditappend?scydgy_id=' + encodeURIComponent(sid));
|
|
|
+ var openApi = (typeof parent !== 'undefined' && parent.Backend && parent.Backend.api && parent.Backend.api.open)
|
|
|
+ ? parent.Backend.api.open
|
|
|
+ : (Backend.api.open.bind(Backend.api));
|
|
|
+ openApi(url, '补加供应商', {
|
|
|
+ area: ['100%', '100%'],
|
|
|
+ callback: function () {
|
|
|
+ window.location.reload();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
function auditIssueSelectedCompany() {
|
|
|
var $checked = $('input[name="audit_quote_pick"]:checked');
|
|
|
if (!$checked.length) {
|