- 根因:页面(_MainLayout 等)加载的是 bundle.js 等由 bundleconfig.json 打包的生成产物,
但 csproj 未接入 BundlerMinifier,dotnet build 不会重生它们,Jenkins 只是把 git 里
陈旧的 bundle.js 原样发布 -> 改了 fastVue.base.js 后回车不生效(部署的 bundle 仍是无
enter 的旧版)。且源文件带 UTF-8 BOM,拼接后每个 BOM 落入文件中间成为 ZWNBSP,提交
diff 充满不可见字符(历史上曾多次在产物上手工清 BOM 打补丁)。
- 修复:
1. YLErpWeb.csproj 新增 BuildBundlerMinifier(3.2.449);其 BundleMinify 目标在
BeforeCompile 自动按 bundleconfig.json 重建全部 bundle,Jenkins 构建即自动产出正确版本,
不再需要手工重建并提交 bundle.js。
2. .gitignore 忽略 8 个生成产物(jquery.js/bundle.js/vue.js/bundle.css/bundleV2.css/
bundleV2.js/bundle.min.css/bundleV2.min.css) 并 git rm --cached 取消跟踪;这些产物
永不再入版本库、永不陈旧。
3. 剥离 15 个喂给 bundle 的源文件(及 css)开头的 UTF-8 BOM,使重建产物不再含 ZWNBSP。
- 验证:本地 dotnet build -t:BundleMinify 重建后 8 个 bundle 全部 BOM=0,bundle.js 含完整
enter 链路(_enterFired/isEnter/$emit('enter'));删除 bundle.min.css 后构建可自动重建。
339 lines
12 KiB
JavaScript
339 lines
12 KiB
JavaScript
//日期选择组件FastVue.DatePicker
|
|
(function (global) {
|
|
global.vueDatePicker = function () {
|
|
return {
|
|
props: ['value', 'mindate', 'maxdate', 'noholiday'],
|
|
mounted() {
|
|
this.init();
|
|
},
|
|
methods: {
|
|
init() {
|
|
var self = this;
|
|
|
|
if (this.value?.length > 10) {
|
|
this.value = this.value.substring(0, 10);
|
|
}
|
|
|
|
$(this.$el).val(this.value).on('change', function () {
|
|
let val = this.value.trim();
|
|
if (self.isDate(val)) return;
|
|
let val2 = self.identifyDate(val);
|
|
this.value = val2;
|
|
if (self.value !== val2) {
|
|
self.$emit('input', val2);
|
|
}
|
|
|
|
}).datepicker({
|
|
minDate: self.mindate ? new Date(self.mindate) : null,
|
|
beforeShowDay(date) {
|
|
return [(self.noholiday || !ylotc.isHoliday(date))];
|
|
},
|
|
changeMonth: true,
|
|
changeYear: true,
|
|
showButtonPanel: true,
|
|
showOtherMonths: true,
|
|
selectOtherMonths: true,
|
|
onClose(dateText) {
|
|
self.value !== dateText && self.isDate(dateText) && self.$emit('input', dateText);
|
|
}
|
|
});
|
|
$(this.$el).on('click', function (e) {
|
|
var scrollTop = $(window).scrollTop();
|
|
if (scrollTop > 0 && $(this).closest('.pricing-float').length) {
|
|
$("#ui-datepicker-div").css({ 'top': $(this).offset().top - scrollTop + 25 });
|
|
}
|
|
});
|
|
},
|
|
refresh(mindate, maxdate) {
|
|
this.mindate = mindate;
|
|
this.maxdate = maxdate;
|
|
$(this.$el).datepicker("destroy");
|
|
this.init();
|
|
},
|
|
isDate(str) {
|
|
return /^\d{4}-\d{2}-\d{2}$/.test(str);
|
|
},
|
|
identifyDate(dateVal) {
|
|
if (!dateVal) return '';
|
|
dateVal = dateVal.replace(/\D/g, '').padStart(4, '0');
|
|
switch (dateVal.length) {
|
|
case 4:
|
|
dateVal = new Date().getFullYear() + dateVal; break;
|
|
case 6:
|
|
dateVal = '20' + dateVal; break;
|
|
case 8: break;
|
|
default:
|
|
if (dateVal.length < 8) return '';
|
|
dateVal = dateVal.substring(0, 8); break;
|
|
}
|
|
if (dateVal) {
|
|
dateVal = moment(dateVal).format('YYYY-MM-DD');
|
|
!/^\d+/.test(dateVal) && (dateVal = '');
|
|
}
|
|
return dateVal;
|
|
}
|
|
},
|
|
watch: {
|
|
value(val, old) {
|
|
if (val !== old && val !== this.$el.value) {
|
|
this.$el.value = val;
|
|
}
|
|
}
|
|
},
|
|
destroyed() {
|
|
$(this.$el).datepicker('destroy');
|
|
},
|
|
template: '<input type="text" autocomplete="off">'
|
|
};
|
|
};
|
|
}(window.FastVue));
|
|
|
|
/*jQuery Nice Select - v1.1.0
|
|
https://github.com/hernansartorio/jquery-nice-select
|
|
Made by Hernán Sartorio */
|
|
|
|
(function ($) {
|
|
|
|
$.fn.niceSelect = function (method) {
|
|
|
|
// Methods
|
|
if (typeof method === 'string') {
|
|
if (method === 'update') {
|
|
this.each(function () {
|
|
var $select = $(this);
|
|
var $dropdown = $(this).next('.nice-select');
|
|
var open = $dropdown.hasClass('open');
|
|
|
|
if ($dropdown.length) {
|
|
$dropdown.remove();
|
|
create_nice_select($select);
|
|
|
|
if (open) {
|
|
$select.next().trigger('click');
|
|
}
|
|
}
|
|
});
|
|
} else if (method === 'destroy') {
|
|
this.each(function () {
|
|
var $select = $(this);
|
|
var $dropdown = $(this).next('.nice-select');
|
|
|
|
if ($dropdown.length) {
|
|
$dropdown.remove();
|
|
$select.css('display', '');
|
|
}
|
|
});
|
|
if ($('.nice-select').length === 0) {
|
|
$(document).off('.nice_select');
|
|
}
|
|
} else {
|
|
console.log('Method "' + method + '" does not exist.')
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// Hide native select
|
|
this.hide();
|
|
|
|
// Create custom markup
|
|
this.each(function () {
|
|
var $select = $(this);
|
|
|
|
if (!$select.next().hasClass('nice-select')) {
|
|
create_nice_select($select);
|
|
}
|
|
});
|
|
|
|
function create_nice_select($select) {
|
|
$select.after($('<div></div>')
|
|
.addClass('nice-select')
|
|
.addClass($select.attr('class') || '')
|
|
.addClass($select.attr('disabled') ? 'disabled' : '')
|
|
.attr('tabindex', $select.attr('disabled') ? null : '0')
|
|
.html('<span class="current"></span><ul class="list"></ul>')
|
|
);
|
|
|
|
var $dropdown = $select.next();
|
|
var $options = $select.find('option');
|
|
var $selected = $select.find('option:selected');
|
|
|
|
$dropdown.find('.current').html($selected.data('display') || $selected.text());
|
|
|
|
$options.each(function (i) {
|
|
var $option = $(this);
|
|
var display = $option.data('display');
|
|
|
|
$dropdown.find('ul').append($('<li></li>')
|
|
.attr('data-value', $option.val())
|
|
.attr('data-display', (display || null))
|
|
.addClass('option' +
|
|
($option.is(':selected') ? ' selected' : '') +
|
|
($option.is(':disabled') ? ' disabled' : ''))
|
|
.html($option.text())
|
|
);
|
|
});
|
|
}
|
|
|
|
/* Event listeners */
|
|
|
|
// Unbind existing events in case that the plugin has been initialized before
|
|
$(document).off('.nice_select');
|
|
|
|
// Open/close
|
|
$(document).on('click.nice_select', '.nice-select', function (event) {
|
|
var $dropdown = $(this);
|
|
|
|
$('.nice-select').not($dropdown).removeClass('open');
|
|
$dropdown.toggleClass('open');
|
|
|
|
if ($dropdown.hasClass('open')) {
|
|
$dropdown.find('.option');
|
|
$dropdown.find('.focus').removeClass('focus');
|
|
$dropdown.find('.selected').addClass('focus');
|
|
} else {
|
|
$dropdown.focus();
|
|
}
|
|
});
|
|
|
|
// Close when clicking outside
|
|
$(document).on('click.nice_select', function (event) {
|
|
if ($(event.target).closest('.nice-select').length === 0) {
|
|
$('.nice-select').removeClass('open').find('.option');
|
|
}
|
|
});
|
|
|
|
// Option click
|
|
$(document).on('click.nice_select', '.nice-select .option:not(.disabled)', function (event) {
|
|
var $option = $(this);
|
|
var $dropdown = $option.closest('.nice-select');
|
|
|
|
$dropdown.find('.selected').removeClass('selected');
|
|
$option.addClass('selected');
|
|
|
|
var text = $option.data('display') || $option.text();
|
|
$dropdown.find('.current').text(text);
|
|
|
|
$dropdown.prev('select').val($option.data('value') + '').trigger('change');
|
|
});
|
|
|
|
// Keyboard events
|
|
$(document).on('keydown.nice_select', '.nice-select', function (event) {
|
|
var $dropdown = $(this);
|
|
var $focused_option = $($dropdown.find('.focus') || $dropdown.find('.list .option.selected'));
|
|
|
|
// Space or Enter
|
|
if (event.keyCode === 32 || event.keyCode === 13) {
|
|
if ($dropdown.hasClass('open')) {
|
|
$focused_option.trigger('click');
|
|
} else {
|
|
$dropdown.trigger('click');
|
|
}
|
|
return false;
|
|
// Down
|
|
} else if (event.keyCode === 40) {
|
|
if (!$dropdown.hasClass('open')) {
|
|
$dropdown.trigger('click');
|
|
} else {
|
|
var $next = $focused_option.nextAll('.option:not(.disabled)').first();
|
|
if ($next.length > 0) {
|
|
$dropdown.find('.focus').removeClass('focus');
|
|
$next.addClass('focus');
|
|
}
|
|
}
|
|
return false;
|
|
// Up
|
|
} else if (event.keyCode === 38) {
|
|
if (!$dropdown.hasClass('open')) {
|
|
$dropdown.trigger('click');
|
|
} else {
|
|
var $prev = $focused_option.prevAll('.option:not(.disabled)').first();
|
|
if ($prev.length > 0) {
|
|
$dropdown.find('.focus').removeClass('focus');
|
|
$prev.addClass('focus');
|
|
}
|
|
}
|
|
return false;
|
|
// Esc
|
|
} else if (event.keyCode === 27) {
|
|
if ($dropdown.hasClass('open')) {
|
|
$dropdown.trigger('click');
|
|
}
|
|
// Tab
|
|
} else if (event.keyCode === 9) {
|
|
if ($dropdown.hasClass('open')) {
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
|
|
// Detect CSS pointer-events support, for IE <= 10. From Modernizr.
|
|
var style = document.createElement('a').style;
|
|
style.cssText = 'pointer-events:auto';
|
|
if (style.pointerEvents !== 'auto') {
|
|
$('html').addClass('no-csspointerevents');
|
|
}
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
}(jQuery));
|
|
|
|
//下拉选择组件FastVue.vueNiceSelect
|
|
(function (global) {
|
|
global.vueNiceSelect = function () {
|
|
return {
|
|
props: ['value', 'items', 'disabled'],
|
|
data() {
|
|
return { type: 'string', jqSelect: null };
|
|
},
|
|
mounted() {
|
|
var self = this;
|
|
let type = typeof this.value;
|
|
//console.log('[vueNiceSelect]'+this.$el.getAttribute('name'));
|
|
if (type === 'undefined' || this.value === null) {
|
|
this.items[0] && (type = typeof this.items[0].value);
|
|
}
|
|
this.type = type;
|
|
this.jqSelect = $(this.$el).children('select');
|
|
this.jqSelect.val(this.value + '').prop('disabled', this.disabled);
|
|
this.jqSelect.niceSelect().on('change', function () {
|
|
let val = $(this).val();
|
|
if (self.type === 'number') {
|
|
val = parseFloat(val);
|
|
} else if (self.type === 'boolean') {
|
|
val = val === 'true' || val === '1';
|
|
}
|
|
self.$emit('input', val);
|
|
});
|
|
},
|
|
watch: {
|
|
value(val, old) {
|
|
if (typeof val === 'undefined') {
|
|
val = "";
|
|
}
|
|
else if (val === null) {
|
|
val = "";
|
|
} else {
|
|
val = val.toString();
|
|
}
|
|
this.jqSelect.val(val);
|
|
this.jqSelect.niceSelect('update');
|
|
},
|
|
disabled(val, old) {
|
|
this.jqSelect.prop('disabled', val).niceSelect('update');
|
|
},
|
|
items() {
|
|
this.$nextTick(function () {
|
|
this.jqSelect.val(this.value);
|
|
this.jqSelect.niceSelect('update');
|
|
});
|
|
}
|
|
},
|
|
destroyed() {
|
|
this.jqSelect.niceSelect('destroy');
|
|
},
|
|
template: '<div><select><option v-for="item in items" :value="item.value">{{item.text}}</option></select></div>'
|
|
};
|
|
};
|
|
}(window.FastVue)); |