', methods=['GET', 'POST'])
@login_required
diff --git a/app/controllers/borrow.py b/app/controllers/borrow.py
index e69de29..c5362a0 100644
--- a/app/controllers/borrow.py
+++ b/app/controllers/borrow.py
@@ -0,0 +1,82 @@
+from flask import Blueprint, request, redirect, url_for, flash, g
+from app.models.book import Book
+from app.models.borrow import BorrowRecord
+from app.models.inventory import InventoryLog
+from app.models.user import db # 修正:从 user 模型导入 db
+from app.utils.auth import login_required
+import datetime
+
+# 创建借阅蓝图
+borrow_bp = Blueprint('borrow', __name__, url_prefix='/borrow')
+
+
+@borrow_bp.route('/book', methods=['POST'])
+@login_required
+def borrow_book():
+ book_id = request.form.get('book_id', type=int)
+ borrow_days = request.form.get('borrow_days', type=int, default=14)
+
+ if not book_id:
+ flash('请选择要借阅的图书', 'danger')
+ return redirect(url_for('book.book_list'))
+
+ book = Book.query.get_or_404(book_id)
+
+ # 检查库存
+ if book.stock <= 0:
+ flash(f'《{book.title}》当前无库存,无法借阅', 'danger')
+ return redirect(url_for('book.book_detail', book_id=book_id))
+
+ # 检查当前用户是否已借阅此书
+ existing_borrow = BorrowRecord.query.filter_by(
+ user_id=g.user.id,
+ book_id=book_id,
+ status=1 # 1表示借阅中
+ ).first()
+
+ if existing_borrow:
+ flash(f'您已借阅《{book.title}》,请勿重复借阅', 'warning')
+ return redirect(url_for('book.book_detail', book_id=book_id))
+
+ try:
+ # 创建借阅记录
+ now = datetime.datetime.now()
+ due_date = now + datetime.timedelta(days=borrow_days)
+
+ borrow_record = BorrowRecord(
+ user_id=g.user.id,
+ book_id=book_id,
+ borrow_date=now,
+ due_date=due_date,
+ status=1, # 1表示借阅中
+ created_at=now,
+ updated_at=now
+ )
+
+ # 更新图书库存
+ book.stock -= 1
+ book.updated_at = now
+
+ db.session.add(borrow_record)
+ db.session.commit()
+
+ # 添加库存变更日志
+ inventory_log = InventoryLog(
+ book_id=book_id,
+ change_type='借出',
+ change_amount=-1,
+ after_stock=book.stock,
+ operator_id=g.user.id,
+ remark='用户借书',
+ changed_at=now
+ )
+ db.session.add(inventory_log)
+ db.session.commit()
+
+ flash(f'成功借阅《{book.title}》,请在 {due_date.strftime("%Y-%m-%d")} 前归还', 'success')
+
+ except Exception as e:
+ db.session.rollback()
+ flash(f'借阅失败: {str(e)}', 'danger')
+
+ return redirect(url_for('book.book_detail', book_id=book_id))
diff --git a/app/models/borrow.py b/app/models/borrow.py
index 4a486b2..413a501 100644
--- a/app/models/borrow.py
+++ b/app/models/borrow.py
@@ -19,6 +19,7 @@ class BorrowRecord(db.Model):
# 添加反向关系引用
user = db.relationship('User', backref=db.backref('borrow_records', lazy='dynamic'))
+ book = db.relationship('Book', backref=db.backref('borrow_records', lazy='dynamic'))
# book 关系会在后面步骤添加
diff --git a/app/static/css/book-form.css b/app/static/css/book-form.css
index 177dbd2..d84e052 100644
--- a/app/static/css/book-form.css
+++ b/app/static/css/book-form.css
@@ -1,26 +1,57 @@
-/* ========== 基础样式 ========== */
+/* ========== 基础重置和变量 ========== */
+:root {
+ --primary-color: #3b82f6;
+ --primary-hover: #2563eb;
+ --primary-light: #eff6ff;
+ --danger-color: #ef4444;
+ --success-color: #10b981;
+ --warning-color: #f59e0b;
+ --info-color: #3b82f6;
+ --text-dark: #1e293b;
+ --text-medium: #475569;
+ --text-light: #64748b;
+ --text-muted: #94a3b8;
+ --border-color: #e2e8f0;
+ --border-focus: #bfdbfe;
+ --bg-white: #ffffff;
+ --bg-light: #f8fafc;
+ --bg-lightest: #f1f5f9;
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
+ --radius-sm: 4px;
+ --radius-md: 6px;
+ --radius-lg: 8px;
+ --radius-xl: 12px;
+ --transition-fast: 0.15s ease;
+ --transition-base: 0.3s ease;
+ --transition-slow: 0.5s ease;
+ --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+}
+
+/* ========== 全局样式 ========== */
.book-form-container {
- padding: 30px;
+ padding: 24px;
max-width: 1400px;
margin: 0 auto;
- background-color: #f8f9fa;
- border-radius: 10px;
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.03);
+ font-family: var(--font-sans);
+ color: var(--text-dark);
}
/* ========== 页头样式 ========== */
.page-header-wrapper {
- margin-bottom: 30px;
- background: linear-gradient(135deg, #ffffff 0%, #f0f4f8 100%);
- border-radius: 8px;
- padding: 20px;
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
+ margin-bottom: 24px;
+ background-color: var(--bg-white);
+ border-radius: var(--radius-lg);
+ box-shadow: var(--shadow-sm);
+ overflow: hidden;
}
.page-header {
display: flex;
justify-content: space-between;
align-items: center;
+ padding: 24px;
}
.header-title-section {
@@ -29,43 +60,46 @@
}
.page-title {
- font-size: 28px;
- font-weight: 700;
- color: #2c3e50;
+ font-size: 1.5rem;
+ font-weight: 600;
+ color: var(--text-dark);
margin: 0;
- display: flex;
- align-items: center;
-}
-
-.page-title i {
- margin-right: 12px;
- color: #3498db;
- font-size: 24px;
}
.subtitle {
- margin: 5px 0 0 0;
- color: #7f8c8d;
- font-size: 16px;
+ margin: 8px 0 0 0;
+ color: var(--text-medium);
+ font-size: 0.9rem;
}
.header-actions {
display: flex;
align-items: center;
- gap: 20px;
+ gap: 16px;
}
-.btn-icon-text {
+.btn-back {
display: flex;
align-items: center;
gap: 8px;
+ color: var(--text-medium);
+ background-color: var(--bg-lightest);
+ border-radius: var(--radius-md);
padding: 8px 16px;
- border-radius: 6px;
+ font-size: 0.875rem;
font-weight: 500;
- transition: all 0.3s ease;
+ transition: all var(--transition-fast);
+ text-decoration: none;
+ box-shadow: var(--shadow-sm);
}
-.btn-icon-text i {
+.btn-back:hover {
+ background-color: var(--border-color);
+ color: var(--text-dark);
+ text-decoration: none;
+}
+
+.btn-back i {
font-size: 14px;
}
@@ -74,74 +108,76 @@
min-width: 180px;
}
-.progress {
- height: 8px;
- border-radius: 4px;
- background-color: #e9ecef;
- margin-bottom: 5px;
+.progress-bar-container {
+ height: 6px;
+ background-color: var(--bg-lightest);
+ border-radius: 3px;
overflow: hidden;
}
.progress-bar {
- background: linear-gradient(45deg, #3498db, #2ecc71);
- transition: width 0.5s ease;
+ height: 100%;
+ background-color: var(--primary-color);
+ border-radius: 3px;
+ transition: width var(--transition-base);
}
.progress-text {
- font-size: 12px;
- color: #6c757d;
+ font-size: 0.75rem;
+ color: var(--text-light);
text-align: right;
display: block;
+ margin-top: 4px;
+}
+
+/* ========== 表单布局 ========== */
+.form-grid {
+ display: grid;
+ grid-template-columns: 1fr 360px;
+ gap: 24px;
+}
+
+.form-main-content {
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+}
+
+.form-sidebar {
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
}
/* ========== 表单卡片样式 ========== */
.form-card {
- margin-bottom: 25px;
- border: none;
- border-radius: 10px;
- box-shadow: 0 3px 12px rgba(0, 0, 0, 0.05);
- background-color: #ffffff;
- transition: all 0.3s ease;
+ background-color: var(--bg-white);
+ border-radius: var(--radius-lg);
+ box-shadow: var(--shadow-sm);
overflow: hidden;
+ transition: box-shadow var(--transition-base);
}
.form-card:hover {
- box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
- transform: translateY(-2px);
+ box-shadow: var(--shadow-md);
}
.card-header {
padding: 16px 20px;
- background: linear-gradient(90deg, rgba(248,249,250,1) 0%, rgba(255,255,255,1) 100%);
- border-bottom: 1px solid #edf2f7;
+ background-color: var(--bg-white);
+ border-bottom: 1px solid var(--border-color);
display: flex;
align-items: center;
}
-.card-header-icon {
- width: 32px;
- height: 32px;
- border-radius: 8px;
- background-color: rgba(52, 152, 219, 0.1);
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 12px;
-}
-
-.card-header-icon i {
- color: #3498db;
- font-size: 16px;
-}
-
-.card-header-title {
+.card-title {
font-weight: 600;
- color: #2c3e50;
- font-size: 16px;
+ color: var(--text-dark);
+ font-size: 0.9375rem;
}
.card-body {
- padding: 25px;
+ padding: 20px;
}
.form-section {
@@ -149,151 +185,298 @@
}
/* ========== 表单元素样式 ========== */
-.form-label {
- font-weight: 500;
- color: #34495e;
- margin-bottom: 8px;
- display: flex;
- align-items: center;
-}
-
-.label-icon {
- color: #3498db;
- margin-right: 8px;
- font-size: 14px;
+.form-row {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 16px;
+ margin-bottom: 16px;
}
.form-group {
margin-bottom: 20px;
- position: relative;
}
-.custom-input, .custom-select, .custom-textarea {
- height: calc(2.8rem + 2px);
- padding: 0.75rem 1rem;
- border: 1px solid #e0e6ed;
- border-radius: 8px;
- font-size: 15px;
- transition: all 0.3s ease;
- box-shadow: 0 1px 3px rgba(0,0,0,0.02);
+.form-group:last-child {
+ margin-bottom: 0;
}
-.custom-input:focus, .custom-select:focus, .custom-textarea:focus {
- border-color: #3498db;
- box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25);
- outline: none;
+.form-label {
+ display: block;
+ font-weight: 500;
+ color: var(--text-dark);
+ margin-bottom: 8px;
+ font-size: 0.9375rem;
}
-.custom-textarea {
- height: auto;
- min-height: 200px;
- resize: vertical;
- line-height: 1.6;
+.form-control {
+ display: block;
+ width: 100%;
+ padding: 10px 14px;
+ font-size: 0.9375rem;
+ line-height: 1.5;
+ color: var(--text-dark);
+ background-color: var(--bg-white);
+ background-clip: padding-box;
+ border: 1px solid var(--border-color);
+ border-radius: var(--radius-md);
+ transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
-.input-group-text {
- background-color: #f8f9fa;
- border: 1px solid #e0e6ed;
- border-radius: 8px;
- color: #6c757d;
+.form-control:focus {
+ border-color: var(--border-focus);
+ outline: 0;
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
}
-.form-text {
+.form-control::placeholder {
+ color: var(--text-muted);
+}
+
+.form-control:disabled, .form-control[readonly] {
+ background-color: var(--bg-lightest);
+ opacity: 0.6;
+}
+
+.form-help {
margin-top: 6px;
- font-size: 13px;
- color: #6c757d;
+ font-size: 0.8125rem;
+ color: var(--text-light);
}
-/* 浮动标签效果 */
-.form-group.focused .floating-label {
- transform: translateY(-22px) scale(0.85);
- color: #3498db;
- opacity: 1;
-}
-
-.floating-label {
- position: absolute;
- pointer-events: none;
- left: 1rem;
- top: 0.75rem;
- transition: 0.2s ease all;
- color: #95a5a6;
- opacity: 0.8;
-}
-
-.floating-input:focus + .floating-label,
-.floating-input:not(:placeholder-shown) + .floating-label {
- transform: translateY(-22px) scale(0.85);
- color: #3498db;
- opacity: 1;
-}
-
-.floating-input {
- padding-top: 1.1rem;
- padding-bottom: 0.4rem;
-}
-
-/* 数字输入组 */
-.input-number-group {
+.form-footer {
display: flex;
- width: 100%;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 8px;
}
-.input-number-group input {
- text-align: center;
- border-radius: 0;
- border-left: none;
- border-right: none;
+.char-counter {
+ font-size: 0.8125rem;
+ color: var(--text-muted);
}
-.input-number-group button {
- border-radius: 8px 0 0 8px;
-}
-
-.input-number-group button:last-child {
- border-radius: 0 8px 8px 0;
-}
-
-/* 价格滑块 */
-.custom-range {
- -webkit-appearance: none;
- width: 100%;
- height: 6px;
- border-radius: 3px;
- background: #e0e6ed;
- outline: none;
- margin: 10px 0;
-}
-
-.custom-range::-webkit-slider-thumb {
- -webkit-appearance: none;
- appearance: none;
- width: 20px;
- height: 20px;
- border-radius: 50%;
- background: #3498db;
- cursor: pointer;
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
- transition: background 0.3s ease;
-}
-
-.custom-range::-webkit-slider-thumb:hover {
- background: #2980b9;
-}
-
-/* 标签输入 */
-.tag-input-container {
+/* 带按钮输入框 */
+.input-with-button {
display: flex;
- gap: 10px;
+ align-items: center;
}
-.tag-input {
+.input-with-button .form-control {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
flex-grow: 1;
}
-.add-tag-btn {
- padding: 0.5rem 0.75rem;
- border-radius: 8px;
+.btn-append {
+ height: 42px;
+ padding: 0 14px;
+ background-color: var(--bg-lightest);
+ border: 1px solid var(--border-color);
+ border-left: none;
+ border-top-right-radius: var(--radius-md);
+ border-bottom-right-radius: var(--radius-md);
+ color: var(--text-medium);
+ cursor: pointer;
+ transition: background-color var(--transition-fast);
+}
+
+.btn-append:hover {
+ background-color: var(--border-color);
+ color: var(--text-dark);
+}
+
+/* 文本域 */
+textarea.form-control {
+ min-height: 150px;
+ resize: vertical;
+}
+
+/* 数字输入控件 */
+.number-control {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ border-radius: var(--radius-md);
+ overflow: hidden;
+}
+
+.number-btn {
+ width: 42px;
+ height: 42px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: var(--bg-lightest);
+ border: 1px solid var(--border-color);
+ color: var(--text-medium);
+ cursor: pointer;
+ transition: all var(--transition-fast);
+ font-size: 1rem;
+ user-select: none;
+}
+
+.number-btn:hover {
+ background-color: var(--border-color);
+ color: var(--text-dark);
+}
+
+.decrement {
+ border-top-left-radius: var(--radius-md);
+ border-bottom-left-radius: var(--radius-md);
+}
+
+.increment {
+ border-top-right-radius: var(--radius-md);
+ border-bottom-right-radius: var(--radius-md);
+}
+
+.number-control .form-control {
+ flex: 1;
+ border-radius: 0;
+ border-left: none;
+ border-right: none;
+ text-align: center;
+ padding: 10px 0;
+}
+
+/* 价格输入 */
+.price-input {
+ position: relative;
+}
+
+.currency-symbol {
+ position: absolute;
+ left: 14px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: var(--text-medium);
+}
+
+.price-input .form-control {
+ padding-left: 30px;
+}
+
+.price-slider {
+ margin-top: 16px;
+}
+
+.range-slider {
+ -webkit-appearance: none;
+ width: 100%;
+ height: 4px;
+ border-radius: 2px;
+ background-color: var(--border-color);
+ outline: none;
+ margin: 14px 0;
+}
+
+.range-slider::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 16px;
+ height: 16px;
+ border-radius: 50%;
+ background: var(--primary-color);
+ cursor: pointer;
+ border: 2px solid var(--bg-white);
+ box-shadow: var(--shadow-sm);
+}
+
+.slider-marks {
+ display: flex;
+ justify-content: space-between;
+ font-size: 0.75rem;
+ color: var(--text-light);
+}
+
+/* ========== 按钮样式 ========== */
+.btn-primary {
+ padding: 12px 16px;
+ background-color: var(--primary-color);
+ color: white;
+ border: none;
+ border-radius: var(--radius-md);
+ font-weight: 500;
+ font-size: 0.9375rem;
+ cursor: pointer;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ transition: all var(--transition-fast);
+ box-shadow: var(--shadow-sm);
+}
+
+.btn-primary:hover {
+ background-color: var(--primary-hover);
+ box-shadow: var(--shadow-md);
+ transform: translateY(-1px);
+}
+
+.btn-primary:focus {
+ outline: none;
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3);
+}
+
+.btn-primary:active {
+ transform: translateY(1px);
+}
+
+.btn-secondary {
+ padding: 10px 16px;
+ background-color: var(--bg-white);
+ color: var(--text-medium);
+ border: 1px solid var(--border-color);
+ border-radius: var(--radius-md);
+ font-weight: 500;
+ font-size: 0.9375rem;
+ cursor: pointer;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ transition: all var(--transition-fast);
+}
+
+.btn-secondary:hover {
+ background-color: var(--bg-lightest);
+ color: var(--text-dark);
+}
+
+.btn-secondary:focus {
+ outline: none;
+ box-shadow: 0 0 0 3px rgba(226, 232, 240, 0.5);
+}
+
+/* ========== 标签输入样式 ========== */
+.tag-input-wrapper {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.tag-input-wrapper .form-control {
+ flex-grow: 1;
+}
+
+.btn-tag-add {
+ width: 42px;
+ height: 42px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: var(--primary-color);
+ border: none;
+ border-radius: var(--radius-md);
+ color: white;
+ cursor: pointer;
+ transition: all var(--transition-fast);
+}
+
+.btn-tag-add:hover {
+ background-color: var(--primary-hover);
}
.tags-container {
@@ -301,76 +484,78 @@
flex-wrap: wrap;
gap: 8px;
margin-top: 12px;
+ min-height: 32px;
}
-.tag-item {
+.tag {
display: inline-flex;
align-items: center;
- background-color: rgba(52, 152, 219, 0.1);
- color: #3498db;
- padding: 6px 12px;
- border-radius: 20px;
- font-size: 14px;
- transition: all 0.3s ease;
+ background-color: var(--primary-light);
+ border-radius: 50px;
+ padding: 6px 10px 6px 14px;
+ font-size: 0.8125rem;
+ color: var(--primary-color);
+ transition: all var(--transition-fast);
}
-.tag-item:hover {
- background-color: rgba(52, 152, 219, 0.2);
+.tag:hover {
+ background-color: rgba(59, 130, 246, 0.2);
}
-.tag-item .remove-tag {
- margin-left: 8px;
+.tag-text {
+ margin-right: 6px;
+}
+
+.tag-remove {
+ background: none;
+ border: none;
+ color: var(--primary-color);
cursor: pointer;
- font-size: 12px;
- color: #3498db;
+ padding: 0;
+ width: 16px;
+ height: 16px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 0.75rem;
+ transition: all var(--transition-fast);
}
-.tag-item .remove-tag:hover {
- color: #e74c3c;
-}
-
-/* 文本计数 */
-.text-count {
- font-size: 12px;
- color: #7f8c8d;
-}
-
-.text-count.text-danger {
- color: #e74c3c;
+.tag-remove:hover {
+ background-color: rgba(59, 130, 246, 0.3);
+ color: white;
}
/* ========== 封面上传区域 ========== */
.cover-preview-container {
display: flex;
flex-direction: column;
- align-items: center;
- gap: 20px;
+ gap: 16px;
}
.cover-preview {
width: 100%;
- height: 320px;
- border: 2px dashed #e0e6ed;
- border-radius: 10px;
+ aspect-ratio: 5/7;
+ background-color: var(--bg-lightest);
+ border-radius: var(--radius-md);
overflow: hidden;
- background-color: #f8f9fa;
- margin-bottom: 10px;
- transition: all 0.3s ease;
- display: flex;
- justify-content: center;
- align-items: center;
cursor: pointer;
+ transition: all var(--transition-fast);
+}
+
+.cover-preview:hover {
+ background-color: var(--bg-light);
}
.cover-preview.dragover {
- border-color: #3498db;
- background-color: rgba(52, 152, 219, 0.05);
+ background-color: var(--primary-light);
}
.cover-image {
width: 100%;
height: 100%;
- object-fit: contain;
+ object-fit: cover;
}
.no-cover-placeholder {
@@ -380,165 +565,188 @@
flex-direction: column;
justify-content: center;
align-items: center;
- color: #95a5a6;
- padding: 20px;
+ color: var(--text-light);
+ padding: 24px;
text-align: center;
}
.no-cover-placeholder i {
- font-size: 64px;
- margin-bottom: 20px;
- color: #d0d0d0;
+ font-size: 48px;
+ margin-bottom: 16px;
+ color: var(--text-muted);
}
.placeholder-tip {
- font-size: 13px;
- margin-top: 10px;
- color: #7f8c8d;
+ font-size: 0.8125rem;
+ margin-top: 8px;
+ color: var(--text-muted);
}
.upload-options {
- width: 100%;
- padding: 0 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
}
.upload-btn-group {
display: flex;
- gap: 10px;
+ gap: 8px;
}
-.custom-upload-btn {
+.btn-upload {
flex-grow: 1;
- padding: 10px 20px;
- border-radius: 8px;
- font-weight: 500;
- transition: all 0.3s ease;
- background-color: #3498db;
- border-color: #3498db;
+ padding: 10px 16px;
+ background-color: var(--primary-color);
color: white;
-}
-
-.custom-upload-btn:hover {
- background-color: #2980b9;
- border-color: #2980b9;
- transform: translateY(-2px);
- box-shadow: 0 4px 10px rgba(52, 152, 219, 0.3);
-}
-
-.btn-icon {
- width: 42px;
- padding: 0;
+ border: none;
+ border-radius: var(--radius-md);
+ font-weight: 500;
+ font-size: 0.875rem;
+ cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
+ gap: 8px;
+ transition: all var(--transition-fast);
+}
+
+.btn-upload:hover {
+ background-color: var(--primary-hover);
+}
+
+.btn-remove {
+ width: 42px;
+ height: 38px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: var(--bg-white);
+ border: 1px solid var(--border-color);
+ border-radius: var(--radius-md);
+ color: var(--text-medium);
+ cursor: pointer;
+ transition: all var(--transition-fast);
+}
+
+.btn-remove:hover {
+ background-color: #fee2e2;
+ border-color: #fca5a5;
+ color: #ef4444;
+}
+
+.upload-tips {
+ text-align: center;
+ font-size: 0.75rem;
+ color: var(--text-muted);
+ line-height: 1.5;
}
/* ========== 表单提交区域 ========== */
-.form-submit-container {
- margin-top: 30px;
-}
-
-.action-buttons {
+.form-actions {
display: flex;
flex-direction: column;
- gap: 15px;
+ gap: 16px;
}
-.secondary-buttons {
- display: flex;
- gap: 10px;
-}
-
-.submit-btn {
- padding: 15px;
- border-radius: 8px;
- font-weight: 600;
- background: linear-gradient(45deg, #3498db, #2980b9);
- border: none;
- transition: all 0.3s ease;
- position: relative;
- overflow: hidden;
-}
-
-.submit-btn:hover {
- transform: translateY(-3px);
- box-shadow: 0 8px 25px rgba(52, 152, 219, 0.4);
-}
-
-.submit-btn:active {
- transform: translateY(-1px);
-}
-
-.reset-btn {
- padding: 12px;
- border-radius: 8px;
- font-weight: 500;
+.secondary-actions {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 8px;
}
.form-tip {
- margin-top: 15px;
- font-size: 13px;
- color: #7f8c8d;
+ margin-top: 8px;
+ font-size: 0.8125rem;
+ color: var(--text-muted);
text-align: center;
}
.form-tip i {
- color: #3498db;
- margin-right: 5px;
+ color: var(--info-color);
+ margin-right: 4px;
}
/* 必填项标记 */
.required {
- color: #e74c3c;
+ color: var(--danger-color);
margin-left: 4px;
- font-weight: bold;
}
/* 无效输入状态 */
.is-invalid {
- border-color: #e74c3c !important;
+ border-color: var(--danger-color) !important;
}
.invalid-feedback {
display: block;
- color: #e74c3c;
- font-size: 13px;
- margin-top: 5px;
+ color: var(--danger-color);
+ font-size: 0.8125rem;
+ margin-top: 6px;
+}
+
+/* ========== Select2 定制 ========== */
+.select2-container--classic .select2-selection--single {
+ height: 42px;
+ border: 1px solid var(--border-color);
+ border-radius: var(--radius-md);
+ background-color: var(--bg-white);
+}
+
+.select2-container--classic .select2-selection--single .select2-selection__rendered {
+ line-height: 40px;
+ color: var(--text-dark);
+ padding-left: 14px;
+}
+
+.select2-container--classic .select2-selection--single .select2-selection__arrow {
+ height: 40px;
+ border-left: 1px solid var(--border-color);
+}
+
+.select2-container--classic .select2-selection--single:focus {
+ border-color: var(--border-focus);
+ outline: 0;
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
}
/* ========== 模态框样式 ========== */
.modal-content {
border: none;
- border-radius: 12px;
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
+ border-radius: var(--radius-lg);
+ box-shadow: var(--shadow-lg);
overflow: hidden;
}
.modal-header {
- background-color: #f8f9fa;
- border-bottom: 1px solid #edf2f7;
- padding: 15px 20px;
+ background-color: var(--bg-white);
+ border-bottom: 1px solid var(--border-color);
+ padding: 16px 20px;
}
.modal-title {
font-weight: 600;
- color: #2c3e50;
+ color: var(--text-dark);
+ font-size: 1.125rem;
}
.modal-body {
- padding: 25px;
+ padding: 20px;
}
.modal-footer {
- border-top: 1px solid #edf2f7;
- padding: 15px 20px;
- justify-content: space-between;
+ border-top: 1px solid var(--border-color);
+ padding: 16px 20px;
+}
+
+.modal-btn {
+ min-width: 100px;
}
/* 裁剪模态框 */
.img-container {
max-height: 500px;
overflow: hidden;
+ margin-bottom: 20px;
}
#cropperImage {
@@ -548,106 +756,232 @@
.cropper-controls {
display: flex;
- gap: 10px;
+ justify-content: center;
+ gap: 20px;
+ margin-top: 16px;
+}
+
+.control-group {
+ display: flex;
+ gap: 8px;
+}
+
+.control-btn {
+ width: 40px;
+ height: 40px;
+ border-radius: var(--radius-md);
+ background-color: var(--bg-lightest);
+ border: 1px solid var(--border-color);
+ color: var(--text-medium);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all var(--transition-fast);
+}
+
+.control-btn:hover {
+ background-color: var(--border-color);
+ color: var(--text-dark);
}
/* 图书预览模态框 */
-.book-preview-container {
- padding: 10px;
+.preview-header {
+ background-color: var(--bg-white);
+ border-bottom: 1px solid var(--border-color);
+}
+
+.preview-body {
+ padding: 0;
+ background-color: var(--bg-lightest);
+}
+
+/* 添加到你的CSS文件中 */
+.book-preview {
+ display: flex;
+ flex-direction: row;
+ gap: 20px;
+}
+
+.preview-cover-section {
+ flex: 0 0 200px;
+}
+
+.preview-details-section {
+ flex: 1;
}
.book-preview-cover {
- width: 100%;
- height: 300px;
- border-radius: 8px;
+ height: 280px;
+ width: 200px;
overflow: hidden;
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
- background-color: #f8f9fa;
- margin-bottom: 20px;
-}
-
-.book-preview-cover img {
- width: 100%;
- height: 100%;
- object-fit: cover;
-}
-
-.book-preview-details {
- padding: 10px 0;
-}
-
-.book-preview-details h3 {
- margin: 0 0 5px 0;
- font-weight: 600;
- color: #2c3e50;
-}
-
-.book-author {
- color: #7f8c8d;
- font-size: 16px;
- margin-bottom: 20px;
-}
-
-.book-info-section {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- gap: 12px;
- margin-bottom: 20px;
-}
-
-.book-info-item {
+ border-radius: 4px;
+ border: 1px solid #ddd;
display: flex;
- flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background: #f8f9fa;
}
-.info-label {
- font-size: 13px;
- color: #7f8c8d;
- margin-bottom: 3px;
-}
-
-.info-value {
- font-weight: 500;
- color: #34495e;
-}
-
-.book-tags {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- margin-bottom: 20px;
+.preview-cover-img {
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
}
.preview-tag {
display: inline-block;
- background-color: rgba(52, 152, 219, 0.1);
- color: #3498db;
- padding: 5px 10px;
- border-radius: 20px;
- font-size: 13px;
+ background: #e9ecef;
+ color: #495057;
+ padding: 3px 8px;
+ border-radius: 12px;
+ font-size: 12px;
+ margin-right: 5px;
+ margin-bottom: 5px;
}
-.book-description {
- background-color: #f8f9fa;
- border-radius: 8px;
- padding: 20px;
+.book-tags-preview {
+ margin: 15px 0;
+}
+
+.book-description-preview {
margin-top: 20px;
}
-.book-description h4 {
- margin-top: 0;
+.section-title {
+ font-size: 16px;
+ margin-bottom: 10px;
+ color: #495057;
+ border-bottom: 1px solid #dee2e6;
+ padding-bottom: 5px;
+}
+
+.book-meta {
+ margin-top: 10px;
+ text-align: center;
+}
+
+.book-price {
+ font-size: 18px;
+ font-weight: bold;
+ color: #dc3545;
+}
+
+.book-stock {
+ font-size: 14px;
+ color: #6c757d;
+}
+
+/* 响应式调整 */
+@media (max-width: 768px) {
+ .book-preview {
+ flex-direction: column;
+ }
+
+ .preview-cover-section {
+ margin: 0 auto;
+ }
+}
+
+.preview-details-section {
+ padding: 24px;
+}
+
+.book-title {
+ font-size: 1.5rem;
font-weight: 600;
- color: #2c3e50;
- margin-bottom: 15px;
+ color: var(--text-dark);
+ margin: 0 0 8px 0;
}
-.book-description p {
- color: #34495e;
+.book-author {
+ color: var(--text-medium);
+ font-size: 1rem;
+ margin-bottom: 24px;
+}
+
+.book-info-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 16px;
+ background-color: var(--bg-white);
+ border-radius: var(--radius-md);
+ padding: 16px;
+ box-shadow: var(--shadow-sm);
+ margin-bottom: 24px;
+}
+
+.info-item {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.info-label {
+ font-size: 0.75rem;
+ color: var(--text-light);
+ text-transform: uppercase;
+}
+
+.info-value {
+ font-weight: 500;
+ color: var(--text-dark);
+}
+
+.book-tags-preview {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 24px;
+}
+
+.preview-tag {
+ display: inline-block;
+ background-color: var(--primary-light);
+ color: var(--primary-color);
+ padding: 4px 12px;
+ border-radius: 50px;
+ font-size: 0.8125rem;
+}
+
+.no-tags {
+ font-size: 0.875rem;
+ color: var(--text-muted);
+}
+
+.book-description-preview {
+ background-color: var(--bg-white);
+ border-radius: var(--radius-md);
+ padding: 16px;
+ box-shadow: var(--shadow-sm);
+}
+
+.section-title {
+ font-size: 1rem;
+ font-weight: 600;
+ color: var(--text-dark);
+ margin: 0 0 12px 0;
+}
+
+.description-content {
+ font-size: 0.9375rem;
+ color: var(--text-medium);
line-height: 1.6;
- margin: 0;
}
-/* ========== 自定义通知样式 ========== */
+.placeholder-text {
+ color: var(--text-muted);
+ font-style: italic;
+}
+
+.preview-footer {
+ background-color: var(--bg-white);
+ display: flex;
+ justify-content: flex-end;
+ gap: 12px;
+}
+
+/* ========== 通知样式 ========== */
.notification-container {
position: fixed;
top: 20px;
@@ -655,61 +989,55 @@
z-index: 9999;
display: flex;
flex-direction: column;
- gap: 10px;
- max-width: 350px;
+ gap: 12px;
+ max-width: 320px;
}
-.custom-notification {
- background: white;
- border-radius: 10px;
- padding: 15px;
- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
+.notification {
+ background-color: var(--bg-white);
+ border-radius: var(--radius-md);
+ padding: 12px 16px;
+ box-shadow: var(--shadow-md);
display: flex;
align-items: center;
+ gap: 12px;
animation-duration: 0.5s;
- border-left: 4px solid #3498db;
}
-.notification-success {
- border-color: #2ecc71;
+.success-notification {
+ border-left: 4px solid var(--success-color);
}
-.notification-error {
- border-color: #e74c3c;
+.error-notification {
+ border-left: 4px solid var(--danger-color);
}
-.notification-warning {
- border-color: #f39c12;
+.warning-notification {
+ border-left: 4px solid var(--warning-color);
}
-.notification-info {
- border-color: #3498db;
+.info-notification {
+ border-left: 4px solid var(--info-color);
}
.notification-icon {
- width: 30px;
- height: 30px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 15px;
+ color: var(--text-light);
}
-.notification-success .notification-icon i {
- color: #2ecc71;
+.success-notification .notification-icon {
+ color: var(--success-color);
}
-.notification-error .notification-icon i {
- color: #e74c3c;
+.error-notification .notification-icon {
+ color: var(--danger-color);
}
-.notification-warning .notification-icon i {
- color: #f39c12;
+.warning-notification .notification-icon {
+ color: var(--warning-color);
}
-.notification-info .notification-icon i {
- color: #3498db;
+.info-notification .notification-icon {
+ color: var(--info-color);
}
.notification-content {
@@ -718,33 +1046,33 @@
.notification-content p {
margin: 0;
- font-size: 14px;
- color: #2c3e50;
+ font-size: 0.875rem;
+ color: var(--text-dark);
}
.notification-close {
background: none;
border: none;
- color: #bdc3c7;
+ color: var(--text-muted);
cursor: pointer;
padding: 5px;
- transition: color 0.3s ease;
+ transition: color var(--transition-fast);
}
.notification-close:hover {
- color: #7f8c8d;
+ color: var(--text-medium);
}
/* ========== 动画效果 ========== */
@keyframes pulse {
0% {
- box-shadow: 0 0 0 0 rgba(52, 152, 219, 0.4);
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4);
}
70% {
- box-shadow: 0 0 0 10px rgba(52, 152, 219, 0);
+ box-shadow: 0 0 0 8px rgba(59, 130, 246, 0);
}
100% {
- box-shadow: 0 0 0 0 rgba(52, 152, 219, 0);
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0);
}
}
@@ -752,18 +1080,11 @@
animation: pulse 2s infinite;
}
-.pulse-icon {
- animation: pulse 2s infinite;
-}
-
/* ========== 响应式样式 ========== */
@media (max-width: 1200px) {
- .book-form-container {
- padding: 20px;
- }
-
- .cover-preview {
- height: 280px;
+ .form-grid {
+ grid-template-columns: 1fr 320px;
+ gap: 20px;
}
}
@@ -771,7 +1092,7 @@
.page-header {
flex-direction: column;
align-items: flex-start;
- gap: 15px;
+ gap: 16px;
}
.header-actions {
@@ -779,43 +1100,73 @@
justify-content: space-between;
}
- .book-info-section {
+ .form-grid {
grid-template-columns: 1fr;
}
+
+ .book-preview {
+ grid-template-columns: 1fr;
+ }
+
+ .preview-cover-section {
+ border-right: none;
+ border-bottom: 1px solid var(--border-color);
+ padding-bottom: 24px;
+ }
+
+ .book-preview-cover {
+ max-width: 240px;
+ margin: 0 auto;
+ }
}
@media (max-width: 768px) {
.book-form-container {
- padding: 15px 10px;
+ padding: 16px 12px;
}
- .page-title {
- font-size: 24px;
- }
-
- .subtitle {
- font-size: 14px;
- }
-
- .card-body {
- padding: 20px 15px;
- }
-
- .cover-preview {
- height: 240px;
- }
-
- .secondary-buttons {
- flex-direction: column;
+ .page-header {
+ padding: 20px;
}
.form-row {
- margin-right: -5px;
- margin-left: -5px;
+ grid-template-columns: 1fr;
+ gap: 12px;
}
- .form-group {
- padding-right: 5px;
- padding-left: 5px;
+ .secondary-actions {
+ grid-template-columns: 1fr;
+ }
+
+ .card-body {
+ padding: 16px;
+ }
+
+ .book-info-grid {
+ grid-template-columns: 1fr;
}
}
+.cover-preview {
+ min-height: 250px;
+ width: 100%;
+ border: 1px dashed #ccc;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+ position: relative;
+}
+.cover-preview img.cover-image {
+ max-width: 100%;
+ max-height: 300px;
+ object-fit: contain;
+}
+.img-container {
+ max-height: 500px;
+ overflow: auto;
+}
+#cropperImage {
+ max-width: 100%;
+ display: block;
+}
\ No newline at end of file
diff --git a/app/static/js/book-add.js b/app/static/js/book-add.js
new file mode 100644
index 0000000..4918f24
--- /dev/null
+++ b/app/static/js/book-add.js
@@ -0,0 +1,644 @@
+/**
+ * 图书添加页面脚本
+ * 处理图书表单的交互、验证和预览功能
+ */
+let isSubmitting = false;
+$(document).ready(function() {
+ // 全局变量
+ let cropper;
+ let coverBlob;
+ let tags = [];
+ const coverPreview = $('#coverPreview');
+ const coverInput = $('#cover');
+ const tagInput = $('#tagInput');
+ const tagsContainer = $('#tagsContainer');
+ const tagsHiddenInput = $('#tags');
+
+ // 初始化函数
+ function initialize() {
+ initSelect2();
+ initFormProgress();
+ initTagsFromInput();
+ initCoverHandlers();
+ initNumberControls();
+ initPriceSlider();
+ initCharCounter();
+ initFormValidation();
+ attachEventListeners();
+ }
+
+ // ========== 组件初始化 ==========
+
+ // 初始化Select2
+ function initSelect2() {
+ $('.select2').select2({
+ placeholder: "选择分类...",
+ allowClear: true,
+ theme: "classic",
+ width: '100%'
+ });
+ }
+
+ // 初始化表单进度条
+ function initFormProgress() {
+ updateFormProgress();
+ $('input, textarea, select').on('change keyup', function() {
+ updateFormProgress();
+ });
+ }
+
+ // 初始化标签(从隐藏输入字段)
+ function initTagsFromInput() {
+ const tagsValue = $('#tags').val();
+ if (tagsValue) {
+ tags = tagsValue.split(',');
+ renderTags();
+ }
+ }
+
+ // 初始化封面处理
+ function initCoverHandlers() {
+ // 拖放上传功能
+ coverPreview.on('dragover', function(e) {
+ e.preventDefault();
+ $(this).addClass('dragover');
+ }).on('dragleave drop', function(e) {
+ e.preventDefault();
+ $(this).removeClass('dragover');
+ }).on('drop', function(e) {
+ e.preventDefault();
+ const file = e.originalEvent.dataTransfer.files[0];
+ if (file && file.type.match('image.*')) {
+ coverInput[0].files = e.originalEvent.dataTransfer.files;
+ coverInput.trigger('change');
+ }
+ }).on('click', function() {
+ if (!$(this).find('img').length) {
+ coverInput.click();
+ }
+ });
+
+ // 重置页面加载完后的字符计数
+ if ($('#description').val()) {
+ $('#charCount').text($('#description').val().length);
+ }
+ }
+
+ // 初始化数字控制
+ function initNumberControls() {
+ $('#stockDecrement').on('click', function() {
+ const input = $('#stock');
+ const value = parseInt(input.val());
+ if (value > parseInt(input.attr('min'))) {
+ input.val(value - 1).trigger('change');
+ }
+ });
+
+ $('#stockIncrement').on('click', function() {
+ const input = $('#stock');
+ const value = parseInt(input.val());
+ input.val(value + 1).trigger('change');
+ });
+ }
+
+ // 初始化价格滑块
+ function initPriceSlider() {
+ $('#priceRange').on('input', function() {
+ $('#price').val($(this).val());
+ });
+
+ $('#price').on('input', function() {
+ const value = parseFloat($(this).val()) || 0;
+ $('#priceRange').val(Math.min(value, 500));
+ });
+ }
+
+ // 初始化字符计数器
+ function initCharCounter() {
+ $('#description').on('input', function() {
+ const count = $(this).val().length;
+ $('#charCount').text(count);
+ if (count > 2000) {
+ $('#charCount').addClass('text-danger');
+ } else {
+ $('#charCount').removeClass('text-danger');
+ }
+ });
+ }
+
+ // 初始化表单验证
+ ffunction initFormValidation() {
+ $('#bookForm').on('submit', function(e) {
+ // 如果表单正在提交中,阻止重复提交
+ if (isSubmitting) {
+ e.preventDefault();
+ showNotification('表单正在提交中,请勿重复点击', 'warning');
+ return false;
+ }
+ let isValid = true;
+ $('[required]').each(function() {
+ if (!$(this).val().trim()) {
+ isValid = false;
+ $(this).addClass('is-invalid');
+ // 添加错误提示
+ if (!$(this).next('.invalid-feedback').length) {
+ $(this).after(`此字段不能为空
`);
+ }
+ } else {
+ $(this).removeClass('is-invalid').next('.invalid-feedback').remove();
+ }
+ });
+ // 验证ISBN格式(如果已填写)
+ const isbn = $('#isbn').val().trim();
+ if (isbn) {
+ // 移除所有非数字、X和x字符后检查
+ const cleanIsbn = isbn.replace(/[^0-9Xx]/g, '');
+ const isbnRegex = /^(?:\d{10}|\d{13})$|^(?:\d{9}[Xx])$/;
+ if (!isbnRegex.test(cleanIsbn)) {
+ isValid = false;
+ $('#isbn').addClass('is-invalid');
+ if (!$('#isbn').next('.invalid-feedback').length) {
+ $('#isbn').after(`ISBN格式不正确,应为10位或13位
`);
+ }
+ }
+ }
+ if (!isValid) {
+ e.preventDefault();
+ // 滚动到第一个错误字段
+ $('html, body').animate({
+ scrollTop: $('.is-invalid:first').offset().top - 100
+ }, 500);
+ showNotification('请正确填写所有标记的字段', 'error');
+ } else {
+ // 设置表单锁定状态
+ isSubmitting = true;
+
+ // 修改提交按钮样式
+ const submitBtn = $(this).find('button[type="submit"]');
+ const originalHtml = submitBtn.html();
+ submitBtn.prop('disabled', true)
+ .html(' 保存中...');
+
+ // 显示提交中通知
+ showNotification('表单提交中...', 'info');
+
+ // 如果表单提交时间过长,30秒后自动解锁
+ setTimeout(function() {
+ if (isSubmitting) {
+ isSubmitting = false;
+ submitBtn.prop('disabled', false).html(originalHtml);
+ showNotification('提交超时,请重试', 'warning');
+ }
+ }, 30000);
+ }
+ });
+ // 输入时移除错误样式
+ $('input, textarea, select').on('input change', function() {
+ $(this).removeClass('is-invalid').next('.invalid-feedback').remove();
+ });
+ }
+ // 还需要在服务端处理成功后重置状态
+ // 在页面加载完成时,添加监听服务器重定向事件
+ $(window).on('pageshow', function(event) {
+ if (event.originalEvent.persisted ||
+ (window.performance && window.performance.navigation.type === 2)) {
+ // 如果页面是从缓存加载的或通过后退按钮回到的
+ isSubmitting = false;
+ $('button[type="submit"]').prop('disabled', false)
+ .html(' 保存图书');
+ }
+ });
+
+ // 绑定事件监听器
+ function attachEventListeners() {
+ // 文件选择处理
+ coverInput.on('change', handleCoverSelect);
+
+ // 裁剪控制
+ $('#rotateLeft').on('click', function() { cropper && cropper.rotate(-90); });
+ $('#rotateRight').on('click', function() { cropper && cropper.rotate(90); });
+ $('#zoomIn').on('click', function() { cropper && cropper.zoom(0.1); });
+ $('#zoomOut').on('click', function() { cropper && cropper.zoom(-0.1); });
+ $('#cropImage').on('click', applyCrop);
+ $('#removeCover').on('click', removeCover);
+
+ // 标签处理
+ tagInput.on('keydown', handleTagKeydown);
+ $('#addTagBtn').on('click', addTag);
+ $(document).on('click', '.tag-remove', removeTag);
+
+ // ISBN查询
+ $('#isbnLookup').on('click', lookupISBN);
+
+ // 预览按钮
+ $('#previewBtn').on('click', showPreview);
+
+ // 表单重置
+ $('#resetBtn').on('click', confirmReset);
+ }
+
+ // ========== 功能函数 ==========
+
+ // 更新表单进度条
+ function updateFormProgress() {
+ const requiredFields = $('[required]');
+ const filledFields = requiredFields.filter(function() {
+ return $(this).val() !== '';
+ });
+
+ const otherFields = $('input:not([required]), textarea:not([required]), select:not([required])').not('[type="file"]');
+ const filledOtherFields = otherFields.filter(function() {
+ return $(this).val() !== '';
+ });
+
+ let requiredWeight = 70; // 必填字段权重70%
+ let otherWeight = 30; // 非必填字段权重30%
+
+ let requiredProgress = requiredFields.length ? (filledFields.length / requiredFields.length) * requiredWeight : requiredWeight;
+ let otherProgress = otherFields.length ? (filledOtherFields.length / otherFields.length) * otherWeight : 0;
+
+ let totalProgress = Math.floor(requiredProgress + otherProgress);
+
+ $('#formProgress').css('width', totalProgress + '%').attr('aria-valuenow', totalProgress);
+ $('#progressText').text('完成 ' + totalProgress + '%');
+
+ if (totalProgress >= 100) {
+ $('.btn-primary').addClass('pulse');
+ } else {
+ $('.btn-primary').removeClass('pulse');
+ }
+ }
+
+ // 处理封面选择
+ function handleCoverSelect(e) {
+ const file = e.target.files[0];
+ if (!file) return;
+ // 验证文件类型
+ if (!file.type.match('image.*')) {
+ showNotification('请选择图片文件', 'warning');
+ return;
+ }
+ // 验证文件大小(最大5MB)
+ if (file.size > 5 * 1024 * 1024) {
+ showNotification('图片大小不能超过5MB', 'warning');
+ return;
+ }
+ const reader = new FileReader();
+ reader.onload = function(e) {
+ // 先显示在预览框中,确保用户能立即看到上传的图片
+ coverPreview.html(`
`);
+
+ // 准备裁剪图片
+ $('#cropperImage').attr('src', e.target.result);
+
+ // 确保图片加载完成后再显示模态框
+ $('#cropperImage').on('load', function() {
+ // 打开模态框
+ $('#cropperModal').modal('show');
+
+ // 在模态框完全显示后初始化裁剪器
+ $('#cropperModal').on('shown.bs.modal', function() {
+ if (cropper) {
+ cropper.destroy();
+ }
+
+ try {
+ cropper = new Cropper(document.getElementById('cropperImage'), {
+ aspectRatio: 5 / 7,
+ viewMode: 2,
+ responsive: true,
+ guides: true,
+ background: true,
+ ready: function() {
+ console.log('Cropper初始化成功');
+ }
+ });
+ } catch (err) {
+ console.error('Cropper初始化失败:', err);
+ showNotification('图片处理工具初始化失败,请重试', 'error');
+ }
+ });
+ });
+ };
+
+ // 处理读取错误
+ reader.onerror = function() {
+ showNotification('读取图片失败,请重试', 'error');
+ };
+
+ reader.readAsDataURL(file);
+ }
+ // 应用裁剪
+ function applyCrop() {
+ if (!cropper) {
+ showNotification('图片处理工具未就绪,请重新上传', 'error');
+ $('#cropperModal').modal('hide');
+ return;
+ }
+
+ try {
+ const canvas = cropper.getCroppedCanvas({
+ width: 500,
+ height: 700,
+ fillColor: '#fff',
+ imageSmoothingEnabled: true,
+ imageSmoothingQuality: 'high',
+ });
+ if (!canvas) {
+ throw new Error('无法生成裁剪后的图片');
+ }
+ canvas.toBlob(function(blob) {
+ if (!blob) {
+ showNotification('图片处理失败,请重试', 'error');
+ return;
+ }
+
+ const url = URL.createObjectURL(blob);
+ coverPreview.html(`
`);
+ coverBlob = blob;
+ // 模拟File对象
+ const fileList = new DataTransfer();
+ const file = new File([blob], "cover.jpg", {type: "image/jpeg"});
+ fileList.items.add(file);
+ document.getElementById('cover').files = fileList.files;
+ $('#cropperModal').modal('hide');
+ showNotification('封面图片已更新', 'success');
+ }, 'image/jpeg', 0.95);
+ } catch (err) {
+ console.error('裁剪失败:', err);
+ showNotification('图片裁剪失败,请重试', 'error');
+ $('#cropperModal').modal('hide');
+ }
+ }
+
+ // 移除封面
+ function removeCover() {
+ coverPreview.html(`
+
+
+
暂无封面
+
点击上传或拖放图片至此处
+
+ `);
+ coverInput.val('');
+ coverBlob = null;
+ }
+
+ // 渲染标签
+ function renderTags() {
+ tagsContainer.empty();
+ tags.forEach(tag => {
+ tagsContainer.append(`
+
+ ${tag}
+
+
+ `);
+ });
+ tagsHiddenInput.val(tags.join(','));
+ }
+
+ // 添加标签
+ function addTag() {
+ const tag = tagInput.val().trim();
+ if (tag && !tags.includes(tag)) {
+ tags.push(tag);
+ renderTags();
+ tagInput.val('').focus();
+ }
+ }
+
+ // 处理标签输入键盘事件
+ function handleTagKeydown(e) {
+ if (e.key === 'Enter' || e.key === ',') {
+ e.preventDefault();
+ addTag();
+ }
+ }
+
+ // 移除标签
+ function removeTag() {
+ const tagToRemove = $(this).data('tag');
+ tags = tags.filter(t => t !== tagToRemove);
+ renderTags();
+ }
+
+ // ISBN查询
+ function lookupISBN() {
+ const isbn = $('#isbn').val().trim();
+ if (!isbn) {
+ showNotification('请先输入ISBN', 'warning');
+ return;
+ }
+
+ // 验证ISBN格式
+ const cleanIsbn = isbn.replace(/[^0-9Xx]/g, '');
+ const isbnRegex = /^(?:\d{10}|\d{13})$|^(?:\d{9}[Xx])$/;
+ if (!isbnRegex.test(cleanIsbn)) {
+ showNotification('ISBN格式不正确,应为10位或13位', 'warning');
+ return;
+ }
+
+ $(this).html('');
+
+ // 先检查ISBN是否已存在
+ $.get('/book/api/check-isbn', {isbn: isbn}, function(data) {
+ if (data.exists) {
+ $('#isbnLookup').html('');
+ showNotification(`ISBN "${isbn}" 已存在: 《${data.book_title}》`, 'warning');
+ $('#isbn').addClass('is-invalid');
+ if (!$('#isbn').next('.invalid-feedback').length) {
+ $('#isbn').after(`此ISBN已被图书《${data.book_title}》使用
`);
+ }
+ } else {
+ // 继续查询外部API(模拟)
+ simulateISBNLookup(isbn);
+ }
+ }).fail(function() {
+ $('#isbnLookup').html('');
+ showNotification('服务器查询失败,请稍后再试', 'error');
+ });
+ }
+
+ // 模拟ISBN查询
+ function simulateISBNLookup(isbn) {
+ // 模拟API查询延迟
+ setTimeout(() => {
+ // 模拟查到的数据
+ if (isbn === '9787020002207') {
+ $('#title').val('红楼梦').trigger('blur');
+ $('#author').val('曹雪芹').trigger('blur');
+ $('#publisher').val('人民文学出版社').trigger('blur');
+ $('#publish_year').val('1996').trigger('blur');
+ $('#category_id').val('1').trigger('change');
+ tags = ['中国文学', '古典', '名著'];
+ renderTags();
+ $('#description').val('《红楼梦》是中国古代章回体长篇小说,中国古典四大名著之一,通行本共120回,一般认为前80回是清代作家曹雪芹所著,后40回作者有争议。小说以贾、史、王、薛四大家族的兴衰为背景,以贾府的家庭琐事、闺阁闲情为脉络,以贾宝玉、林黛玉、薛宝钗的爱情婚姻悲剧为主线,刻画了以贾宝玉和金陵十二钗为中心的正邪两赋有情人的人性美和悲剧美。').trigger('input');
+ $('#price').val('59.70').trigger('input');
+ $('#priceRange').val('59.70');
+
+ showNotification('ISBN查询成功', 'success');
+ } else if (isbn === '9787544270878') {
+ $('#title').val('挪威的森林').trigger('blur');
+ $('#author').val('村上春树').trigger('blur');
+ $('#publisher').val('南海出版社').trigger('blur');
+ $('#publish_year').val('2017').trigger('blur');
+ $('#category_id').val('2').trigger('change');
+ tags = ['外国文学', '日本', '小说'];
+ renderTags();
+ $('#description').val('《挪威的森林》是日本作家村上春树创作的长篇小说,首次出版于1987年。小说讲述了一个悲伤的爱情故事,背景设定在20世纪60年代末的日本。主人公渡边纠缠在与平静的直子和开朗的绿子两人的感情中,最终选择了生活。').trigger('input');
+ $('#price').val('39.50').trigger('input');
+ $('#priceRange').val('39.50');
+
+ showNotification('ISBN查询成功', 'success');
+ } else {
+ showNotification('未找到相关图书信息', 'warning');
+ }
+
+ $('#isbnLookup').html('');
+ updateFormProgress();
+ }, 1500);
+ }
+
+ // 显示预览
+ function showPreview() {
+ // 检查必填字段
+ if (!$('#title').val().trim() || !$('#author').val().trim()) {
+ showNotification('请至少填写书名和作者后再预览', 'warning');
+ return;
+ }
+ try {
+ // 确保所有值都有默认值,防止undefined错误
+ const title = $('#title').val() || '未填写标题';
+ const author = $('#author').val() || '未填写作者';
+ const publisher = $('#publisher').val() || '-';
+ const isbn = $('#isbn').val() || '-';
+ const publishYear = $('#publish_year').val() || '-';
+ const description = $('#description').val() || '';
+ const stock = $('#stock').val() || '0';
+ let price = parseFloat($('#price').val()) || 0;
+
+ // 填充预览内容
+ $('#previewTitle').text(title);
+ $('#previewAuthor').text(author ? '作者: ' + author : '未填写作者');
+ $('#previewPublisher').text(publisher);
+ $('#previewISBN').text(isbn);
+ $('#previewYear').text(publishYear);
+ // 获取分类文本
+ const categoryId = $('#category_id').val();
+ const categoryText = categoryId ? $('#category_id option:selected').text() : '-';
+ $('#previewCategory').text(categoryText);
+ // 价格和库存
+ $('#previewPrice').text(price ? '¥' + price.toFixed(2) : '¥0.00');
+ $('#previewStock').text('库存: ' + stock);
+ // 标签
+ const previewTags = $('#previewTags');
+ previewTags.empty();
+ if (tags && tags.length > 0) {
+ tags.forEach(tag => {
+ previewTags.append(`${tag}`);
+ });
+ } else {
+ previewTags.append('暂无标签');
+ }
+ // 描述
+ if (description) {
+ $('#previewDescription').html(`${description.replace(/\n/g, '
')}
`);
+ } else {
+ $('#previewDescription').html(`暂无简介内容
`);
+ }
+ // 封面
+ const previewCover = $('#previewCover');
+ previewCover.empty(); // 清空现有内容
+
+ if ($('#coverPreview img').length) {
+ const coverSrc = $('#coverPreview img').attr('src');
+ previewCover.html(`
`);
+ } else {
+ previewCover.html(`
+
+
+ 暂无封面
+
+ `);
+ }
+ // 显示预览模态框
+ $('#previewModal').modal('show');
+
+ console.log('预览模态框已显示');
+ } catch (err) {
+ console.error('生成预览时发生错误:', err);
+ showNotification('生成预览时出错,请重试', 'error');
+ }
+ }
+
+ // 确认重置表单
+ function confirmReset() {
+ if (confirm('确定要重置表单吗?所有已填写的内容将被清空。')) {
+ $('#bookForm')[0].reset();
+ removeCover();
+ tags = [];
+ renderTags();
+ updateFormProgress();
+ $('.select2').val(null).trigger('change');
+ $('#charCount').text('0');
+
+ showNotification('表单已重置', 'info');
+ }
+ }
+
+ // 通知提示函数
+ function showNotification(message, type) {
+ // 创建通知元素
+ const notification = $(`
+
+ `);
+
+ // 添加到页面
+ if ($('.notification-container').length === 0) {
+ $('body').append('');
+ }
+ $('.notification-container').append(notification);
+
+ // 自动关闭
+ setTimeout(() => {
+ notification.removeClass('animate__fadeInRight').addClass('animate__fadeOutRight');
+ setTimeout(() => {
+ notification.remove();
+ }, 500);
+ }, 5000);
+
+ // 点击关闭
+ notification.find('.notification-close').on('click', function() {
+ notification.removeClass('animate__fadeInRight').addClass('animate__fadeOutRight');
+ setTimeout(() => {
+ notification.remove();
+ }, 500);
+ });
+ }
+
+ function getIconForType(type) {
+ switch(type) {
+ case 'success': return 'fa-check-circle';
+ case 'warning': return 'fa-exclamation-triangle';
+ case 'error': return 'fa-times-circle';
+ case 'info':
+ default: return 'fa-info-circle';
+ }
+ }
+
+ // 初始化页面
+ initialize();
+});
diff --git a/app/static/uploads/covers/110aad2c-1b7d-4a26-b23c-8efe1e971127_.jpg b/app/static/uploads/covers/110aad2c-1b7d-4a26-b23c-8efe1e971127_.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..72cbaec27d4ed70bf189ab21064ae4f0ef4b0ff3
GIT binary patch
literal 779438
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