Kamixitong/app/web/templates/license/import.html
2025-11-11 21:39:12 +08:00

209 lines
8.0 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}导入卡密 - 软件授权管理系统{% endblock %}
{% block page_title %}导入卡密{% endblock %}
{% block page_actions %}
<a href="{{ url_for('web.licenses') }}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>
返回列表
</a>
{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-8">
<div class="card shadow">
<div class="card-body">
<form id="import-form" enctype="multipart/form-data">
<div class="mb-3">
<label for="product_id" class="form-label">选择产品 *</label>
<select class="form-select" id="product_id" name="product_id" required>
<option value="">请选择产品</option>
{% for product in products %}
<option value="{{ product.product_id }}">{{ product.product_name }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="license_file" class="form-label">选择文件 *</label>
<input type="file" class="form-control" id="license_file" name="license_file" accept=".txt,.csv" required>
<div class="form-text">支持TXT或CSV格式文件每行一个卡密</div>
</div>
<div class="mb-3">
<label for="license_type" class="form-label">卡密类型</label>
<select class="form-select" id="license_type" name="license_type">
<option value="">自动识别</option>
<option value="1">正式卡密</option>
<option value="0">试用卡密</option>
</select>
<div class="form-text">如果选择自动识别,系统会根据卡密前缀判断类型</div>
</div>
<div class="mb-3">
<label for="expire_days" class="form-label">有效期(天)</label>
<input type="number" class="form-control" id="expire_days" name="expire_days" min="1" max="3650">
<div class="form-text">卡密有效期天数,留空表示使用文件中的设置或永久有效</div>
</div>
<div class="mb-3">
<label for="max_devices" class="form-label">最大绑定设备数</label>
<input type="number" class="form-control" id="max_devices" name="max_devices" min="1" max="100" value="1">
<div class="form-text">同一卡密最多可绑定的设备数量</div>
</div>
<div class="mb-3">
<label for="description" class="form-label">备注</label>
<textarea class="form-control" id="description" name="description" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary" id="submit-btn">
<i class="fas fa-file-import me-2"></i>
<span id="submit-text">导入卡密</span>
</button>
<a href="{{ url_for('web.licenses') }}" class="btn btn-secondary">取消</a>
</form>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card shadow">
<div class="card-header">
<h6 class="mb-0">导入说明</h6>
</div>
<div class="card-body">
<ul class="list-unstyled">
<li class="mb-2">
<i class="fas fa-info-circle text-primary me-2"></i>
<small>文件格式:每行一个卡密,纯文本格式</small>
</li>
<li class="mb-2">
<i class="fas fa-info-circle text-primary me-2"></i>
<small>支持CSV格式第一列为卡密</small>
</li>
<li class="mb-2">
<i class="fas fa-info-circle text-primary me-2"></i>
<small>系统会自动过滤重复和无效的卡密</small>
</li>
<li class="mb-2">
<i class="fas fa-info-circle text-primary me-2"></i>
<small>导入前请确保选择了正确的产品</small>
</li>
</ul>
<h6 class="mt-3">示例文件格式</h6>
<pre class="bg-light p-2 small">LICENSE_KEY_001
LICENSE_KEY_002
TRIAL_KEY_001
TRIAL_KEY_002</pre>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
initEventListeners();
});
// 初始化事件监听器
function initEventListeners() {
// 表单提交
document.getElementById('import-form').addEventListener('submit', function(e) {
e.preventDefault();
importLicenses();
});
}
// 导入卡密
function importLicenses() {
const submitBtn = document.getElementById('submit-btn');
const submitText = document.getElementById('submit-text');
const fileInput = document.getElementById('license_file');
// 获取表单数据
const formData = new FormData();
formData.append('product_id', document.getElementById('product_id').value);
formData.append('license_file', fileInput.files[0]);
const licenseType = document.getElementById('license_type').value;
if (licenseType) {
formData.append('license_type', licenseType);
}
const expireDays = document.getElementById('expire_days').value;
if (expireDays) {
formData.append('expire_days', expireDays);
}
const maxDevices = document.getElementById('max_devices').value;
if (maxDevices) {
formData.append('max_devices', maxDevices);
}
const description = document.getElementById('description').value.trim();
if (description) {
formData.append('description', description);
}
// 基础验证
if (!document.getElementById('product_id').value) {
showNotification('请选择产品', 'warning');
return;
}
if (!fileInput.files[0]) {
showNotification('请选择要导入的文件', 'warning');
return;
}
// 显示加载状态
submitBtn.disabled = true;
submitText.textContent = '导入中...';
// 发送请求
showLoading();
fetch('/api/v1/licenses/import', {
method: 'POST',
body: formData,
credentials: 'same-origin'
})
.then(response => {
hideLoading();
if (response.ok) {
return response.json();
} else {
throw new Error(`HTTP error! status: ${response.status}`);
}
})
.then(data => {
if (data.success) {
showNotification(`成功导入 ${data.data.imported} 个卡密,跳过 ${data.data.skipped} 个重复卡密`, 'success');
// 延迟跳转到卡密列表
setTimeout(() => {
window.location.href = '/licenses';
}, 2000);
} else {
showNotification(data.message || '导入失败', 'error');
}
})
.catch(error => {
hideLoading();
console.error('Failed to import licenses:', error);
showNotification('导入失败,请检查文件格式后重试', 'error');
})
.finally(() => {
// 恢复按钮状态
submitBtn.disabled = false;
submitText.textContent = '导入卡密';
});
}
</script>
{% endblock %}