359 lines
19 KiB
HTML
359 lines
19 KiB
HTML
{% extends 'base.html' %}
|
||
|
||
{% block title %}添加图书 - 图书管理系统{% endblock %}
|
||
|
||
{% block head %}
|
||
<link rel="stylesheet" href="{{ url_for('static', filename='css/book-form.css') }}">
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css">
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.css">
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="book-form-container animate__animated animate__fadeIn">
|
||
<!-- 顶部导航和标题区域 -->
|
||
<div class="page-header-wrapper">
|
||
<div class="page-header">
|
||
<div class="header-title-section">
|
||
<h1 class="page-title">添加新图书</h1>
|
||
<p class="subtitle">创建新书籍记录并添加到系统库存</p>
|
||
</div>
|
||
<div class="header-actions">
|
||
<a href="{{ url_for('book.book_list') }}" class="btn-back">
|
||
<i class="fas fa-arrow-left"></i>
|
||
<span>返回列表</span>
|
||
</a>
|
||
<div class="form-progress">
|
||
<div class="progress-bar-container">
|
||
<div class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" id="formProgress"></div>
|
||
</div>
|
||
<span class="progress-text" id="progressText">完成 0%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 主表单区域 -->
|
||
<form method="POST" enctype="multipart/form-data" class="book-form" id="bookForm">
|
||
<div class="form-grid">
|
||
<!-- 左侧表单区域 -->
|
||
<div class="form-main-content">
|
||
<!-- 基本信息卡片 -->
|
||
<div class="form-card">
|
||
<div class="card-header">
|
||
<span class="card-title">基本信息</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="form-section">
|
||
<div class="form-group">
|
||
<label for="title" class="form-label">书名 <span class="required">*</span></label>
|
||
<input type="text" class="form-control" id="title" name="title" required
|
||
placeholder="请输入完整图书名称" value="{{ book.title if book else '' }}">
|
||
<div class="form-help">完整准确的书名有助于读者查找</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label for="author" class="form-label">作者 <span class="required">*</span></label>
|
||
<input type="text" class="form-control" id="author" name="author" required
|
||
placeholder="请输入作者姓名" value="{{ book.author if book else '' }}">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="publisher" class="form-label">出版社</label>
|
||
<input type="text" class="form-control" id="publisher" name="publisher"
|
||
placeholder="请输入出版社名称" value="{{ book.publisher if book else '' }}">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label for="isbn" class="form-label">ISBN</label>
|
||
<div class="input-with-button">
|
||
<input type="text" class="form-control" id="isbn" name="isbn"
|
||
placeholder="例如: 978-7-XXXXX-XXX-X" value="{{ book.isbn if book else '' }}">
|
||
<button type="button" class="btn-append" id="isbnLookup">
|
||
<i class="fas fa-search"></i>
|
||
</button>
|
||
</div>
|
||
<div class="form-help">输入ISBN并点击查询按钮自动填充图书信息</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="publish_year" class="form-label">出版年份</label>
|
||
<input type="text" class="form-control" id="publish_year" name="publish_year"
|
||
placeholder="例如: 2023" value="{{ book.publish_year if book else '' }}">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 分类和标签卡片 -->
|
||
<div class="form-card">
|
||
<div class="card-header">
|
||
<span class="card-title">分类与标签</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="form-section">
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label for="category_id" class="form-label">图书分类</label>
|
||
<select class="form-control select2" id="category_id" name="category_id">
|
||
<option value="">选择分类...</option>
|
||
{% for category in categories %}
|
||
<option value="{{ category.id }}" {% if book and book.category_id|string == category.id|string %}selected{% endif %}>
|
||
{{ category.name }}
|
||
</option>
|
||
{% endfor %}
|
||
</select>
|
||
<div class="form-help">为图书选择合适的分类以便于管理和查找</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="tagInput" class="form-label">标签</label>
|
||
<div class="tag-input-wrapper">
|
||
<input type="text" class="form-control" id="tagInput" placeholder="输入标签后按回车添加">
|
||
<input type="hidden" id="tags" name="tags" value="{{ book.tags if book else '' }}">
|
||
<button type="button" class="btn-tag-add" id="addTagBtn">
|
||
<i class="fas fa-plus"></i>
|
||
</button>
|
||
</div>
|
||
<div class="tags-container" id="tagsContainer"></div>
|
||
<div class="form-help">添加多个标签以提高图书的检索率</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 图书简介卡片 -->
|
||
<div class="form-card">
|
||
<div class="card-header">
|
||
<span class="card-title">图书简介</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="form-section">
|
||
<div class="form-group">
|
||
<label for="description" class="form-label">内容简介</label>
|
||
<textarea class="form-control" id="description" name="description" rows="8"
|
||
placeholder="请输入图书的简要介绍...">{{ book.description if book else '' }}</textarea>
|
||
<div class="form-footer">
|
||
<div class="form-help">简要描述图书的内容、特点和主要观点</div>
|
||
<div class="char-counter"><span id="charCount">0</span>/2000</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧表单区域 -->
|
||
<div class="form-sidebar">
|
||
<!-- 封面图片卡片 -->
|
||
<div class="form-card">
|
||
<div class="card-header">
|
||
<span class="card-title">封面图片</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="cover-preview-container">
|
||
<div class="cover-preview" id="coverPreview">
|
||
<div class="no-cover-placeholder">
|
||
<i class="fas fa-book-open"></i>
|
||
<span>暂无封面</span>
|
||
<p class="placeholder-tip">点击上传或拖放图片至此处</p>
|
||
</div>
|
||
</div>
|
||
<div class="upload-options">
|
||
<div class="upload-btn-group">
|
||
<label for="cover" class="btn-upload">
|
||
<i class="fas fa-upload"></i> 上传图片
|
||
</label>
|
||
<button type="button" class="btn-remove" id="removeCover">
|
||
<i class="fas fa-trash-alt"></i>
|
||
</button>
|
||
</div>
|
||
<input type="file" id="cover" name="cover" class="form-control-file" accept="image/*" style="display:none;">
|
||
<div class="upload-tips">
|
||
<div>推荐尺寸: 500×700px (竖版封面)</div>
|
||
<div>支持格式: JPG, PNG, WebP</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 库存和价格卡片 -->
|
||
<div class="form-card">
|
||
<div class="card-header">
|
||
<span class="card-title">库存和价格</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="form-section">
|
||
<div class="form-group">
|
||
<label for="stock" class="form-label">库存数量</label>
|
||
<div class="number-control">
|
||
<button type="button" class="number-btn decrement" id="stockDecrement">-</button>
|
||
<input type="number" class="form-control text-center" id="stock" name="stock" min="0"
|
||
value="{{ book.stock if book else 0 }}">
|
||
<button type="button" class="number-btn increment" id="stockIncrement">+</button>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="price" class="form-label">价格</label>
|
||
<div class="price-input">
|
||
<span class="currency-symbol">¥</span>
|
||
<input type="number" class="form-control" id="price" name="price" step="0.01" min="0"
|
||
placeholder="0.00" value="{{ book.price if book else '' }}">
|
||
</div>
|
||
<div class="price-slider">
|
||
<input type="range" class="range-slider" id="priceRange" min="0" max="500" step="0.5"
|
||
value="{{ book.price if book and book.price else 0 }}">
|
||
<div class="slider-marks">
|
||
<span>¥0</span>
|
||
<span>¥250</span>
|
||
<span>¥500</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 提交按钮区域 -->
|
||
<div class="form-actions">
|
||
<button type="submit" class="btn-primary">
|
||
<i class="fas fa-save"></i> 保存图书
|
||
</button>
|
||
<div class="secondary-actions">
|
||
<button type="button" class="btn-secondary" id="previewBtn">
|
||
<i class="fas fa-eye"></i> 预览
|
||
</button>
|
||
<button type="reset" class="btn-secondary" id="resetBtn">
|
||
<i class="fas fa-undo"></i> 重置
|
||
</button>
|
||
</div>
|
||
<div class="form-tip">
|
||
<i class="fas fa-info-circle"></i>
|
||
<span>带 <span class="required">*</span> 的字段为必填项</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- 图片裁剪模态框 -->
|
||
<div class="modal fade" id="cropperModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||
<div class="modal-dialog modal-lg" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">调整封面图片</h5>
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="img-container">
|
||
<img id="cropperImage" src="" alt="图片预览">
|
||
</div>
|
||
<div class="cropper-controls">
|
||
<div class="control-group">
|
||
<button type="button" class="control-btn" id="rotateLeft" title="向左旋转">
|
||
<i class="fas fa-undo"></i>
|
||
</button>
|
||
<button type="button" class="control-btn" id="rotateRight" title="向右旋转">
|
||
<i class="fas fa-redo"></i>
|
||
</button>
|
||
</div>
|
||
<div class="control-group">
|
||
<button type="button" class="control-btn" id="zoomOut" title="缩小">
|
||
<i class="fas fa-search-minus"></i>
|
||
</button>
|
||
<button type="button" class="control-btn" id="zoomIn" title="放大">
|
||
<i class="fas fa-search-plus"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn-secondary modal-btn" data-dismiss="modal">取消</button>
|
||
<button type="button" class="btn-primary modal-btn" id="cropImage">应用裁剪</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 图书预览模态框 -->
|
||
<div class="modal fade" id="previewModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||
<div class="modal-dialog modal-lg" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header preview-header">
|
||
<h5 class="modal-title">图书预览</h5>
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body preview-body">
|
||
<div class="book-preview">
|
||
<div class="preview-cover-section">
|
||
<div class="book-preview-cover" id="previewCover">
|
||
<div class="no-cover-placeholder">
|
||
<i class="fas fa-book-open"></i>
|
||
<span>暂无封面</span>
|
||
</div>
|
||
</div>
|
||
<div class="book-meta">
|
||
<div class="book-price" id="previewPrice">¥0.00</div>
|
||
<div class="book-stock" id="previewStock">库存: 0</div>
|
||
</div>
|
||
</div>
|
||
<div class="preview-details-section">
|
||
<h2 class="book-title" id="previewTitle">书名加载中...</h2>
|
||
<div class="book-author" id="previewAuthor">作者加载中...</div>
|
||
|
||
<div class="book-info-grid">
|
||
<div class="info-item">
|
||
<div class="info-label">出版社</div>
|
||
<div class="info-value" id="previewPublisher">-</div>
|
||
</div>
|
||
<div class="info-item">
|
||
<div class="info-label">ISBN</div>
|
||
<div class="info-value" id="previewISBN">-</div>
|
||
</div>
|
||
<div class="info-item">
|
||
<div class="info-label">出版年份</div>
|
||
<div class="info-value" id="previewYear">-</div>
|
||
</div>
|
||
<div class="info-item">
|
||
<div class="info-label">分类</div>
|
||
<div class="info-value" id="previewCategory">-</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="book-tags-preview" id="previewTags"></div>
|
||
|
||
<div class="book-description-preview">
|
||
<h3 class="section-title">图书简介</h3>
|
||
<div class="description-content" id="previewDescription">
|
||
<p class="placeholder-text">暂无简介内容</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer preview-footer">
|
||
<button type="button" class="btn-secondary modal-btn" data-dismiss="modal">关闭</button>
|
||
<button type="button" class="btn-primary modal-btn" data-dismiss="modal" id="continueEditBtn">继续编辑</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 通知容器 -->
|
||
<div class="notification-container"></div>
|
||
{% endblock %}
|
||
|
||
{% block scripts %}
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js"></script>
|
||
<script src="{{ url_for('static', filename='js/book-add.js') }}"></script>
|
||
{% endblock %}
|