177 lines
5.3 KiB
Plaintext
177 lines
5.3 KiB
Plaintext
// 用于调试
|
||
console.log("ISBN验证脚本已加载 v2.0");
|
||
|
||
$(document).ready(function() {
|
||
console.log("DOM已加载,开始设置ISBN验证");
|
||
|
||
// 获取ISBN输入框
|
||
const isbnInput = $("#isbn");
|
||
|
||
if (isbnInput.length === 0) {
|
||
console.error("找不到ISBN输入字段!");
|
||
return;
|
||
}
|
||
|
||
console.log("找到ISBN输入框:", isbnInput.val());
|
||
|
||
// 添加ISBN帮助文本和错误提示
|
||
isbnInput.after('<div class="invalid-feedback" id="isbn-error">请输入有效的10位或13位ISBN号码</div>');
|
||
isbnInput.after('<small class="form-text text-muted">请输入有效的ISBN-10或ISBN-13格式</small>');
|
||
|
||
// 验证ISBN函数
|
||
function validateISBN(isbn) {
|
||
// 空值视为有效
|
||
if (!isbn || isbn.trim() === '') return true;
|
||
|
||
// 移除所有连字符和空格
|
||
isbn = isbn.replace(/[-\s]/g, '');
|
||
|
||
console.log("验证ISBN:", isbn, "长度:", isbn.length);
|
||
|
||
// 长度检查
|
||
if (isbn.length !== 10 && isbn.length !== 13) {
|
||
console.log("ISBN长度无效");
|
||
return false;
|
||
}
|
||
|
||
// ISBN-10验证
|
||
if (isbn.length === 10) {
|
||
// 检查前9位是否为数字,最后一位可以是X
|
||
if (!/^\d{9}[\dXx]$/.test(isbn)) {
|
||
console.log("ISBN-10格式错误");
|
||
return false;
|
||
}
|
||
|
||
let sum = 0;
|
||
for (let i = 0; i < 9; i++) {
|
||
sum += parseInt(isbn[i]) * (10 - i);
|
||
}
|
||
|
||
// 处理校验位
|
||
let checkDigit = isbn[9].toUpperCase() === 'X' ? 10 : parseInt(isbn[9]);
|
||
sum += checkDigit;
|
||
|
||
let valid = (sum % 11 === 0);
|
||
console.log("ISBN-10校验结果:", valid);
|
||
return valid;
|
||
}
|
||
|
||
// ISBN-13验证
|
||
if (isbn.length === 13) {
|
||
// 检查是否全是数字
|
||
if (!/^\d{13}$/.test(isbn)) {
|
||
console.log("ISBN-13必须全是数字");
|
||
return false;
|
||
}
|
||
|
||
let sum = 0;
|
||
for (let i = 0; i < 12; i++) {
|
||
sum += parseInt(isbn[i]) * (i % 2 === 0 ? 1 : 3);
|
||
}
|
||
|
||
let checkDigit = (10 - (sum % 10)) % 10;
|
||
let valid = (checkDigit === parseInt(isbn[12]));
|
||
|
||
console.log("ISBN-13校验结果:", valid);
|
||
return valid;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
// 添加输入事件处理
|
||
isbnInput.on('input', function() {
|
||
const value = $(this).val().trim();
|
||
|
||
if (value === '') {
|
||
// 不验证空值
|
||
$(this).removeClass('is-invalid is-valid');
|
||
} else if (validateISBN(value)) {
|
||
$(this).removeClass('is-invalid').addClass('is-valid');
|
||
} else {
|
||
$(this).removeClass('is-valid').addClass('is-invalid');
|
||
}
|
||
});
|
||
|
||
// 表单提交验证
|
||
const form = $(".book-form");
|
||
form.on('submit', function(event) {
|
||
const isbnValue = isbnInput.val().trim();
|
||
|
||
console.log("表单提交,ISBN值:", isbnValue);
|
||
|
||
// 仅当有ISBN且无效时才阻止提交
|
||
if (isbnValue !== '' && !validateISBN(isbnValue)) {
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
|
||
isbnInput.addClass('is-invalid');
|
||
isbnInput.focus();
|
||
|
||
alert('请输入有效的ISBN号码,或将此字段留空');
|
||
console.log("表单提交被阻止 - ISBN无效");
|
||
|
||
return false;
|
||
}
|
||
|
||
console.log("表单提交继续 - ISBN有效或为空");
|
||
});
|
||
|
||
// 处理封面图片预览
|
||
$('#cover').change(function() {
|
||
const file = this.files[0];
|
||
if (file) {
|
||
const reader = new FileReader();
|
||
reader.onload = function(e) {
|
||
$('#coverPreview').html(`<img src="${e.target.result}" class="cover-image" alt="新封面预览">`);
|
||
};
|
||
reader.readAsDataURL(file);
|
||
} else {
|
||
// 默认回退
|
||
if (typeof bookCoverUrl !== 'undefined' && bookCoverUrl) {
|
||
$('#coverPreview').html(`<img src="${bookCoverUrl}" class="cover-image" alt="${bookTitle || '图书封面'}">`);
|
||
} else {
|
||
$('#coverPreview').html(`
|
||
<div class="no-cover-placeholder">
|
||
<i class="fas fa-book"></i>
|
||
<span>暂无封面</span>
|
||
</div>
|
||
`);
|
||
}
|
||
}
|
||
});
|
||
|
||
// 在页面加载时初始验证现有ISBN
|
||
if (isbnInput.val()) {
|
||
isbnInput.trigger('input');
|
||
}
|
||
|
||
// 添加帮助样式
|
||
$("<style>")
|
||
.prop("type", "text/css")
|
||
.html(`
|
||
.is-invalid {
|
||
border-color: #dc3545 !important;
|
||
background-color: #fff8f8 !important;
|
||
}
|
||
|
||
.is-valid {
|
||
border-color: #28a745 !important;
|
||
background-color: #f8fff8 !important;
|
||
}
|
||
|
||
.invalid-feedback {
|
||
display: none;
|
||
color: #dc3545;
|
||
font-size: 80%;
|
||
margin-top: 0.25rem;
|
||
}
|
||
|
||
.is-invalid + .invalid-feedback,
|
||
.is-invalid ~ .invalid-feedback {
|
||
display: block !important;
|
||
}
|
||
`)
|
||
.appendTo("head");
|
||
});
|