import.html.bak 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. {% extends "base.html" %}
  2. {% block title %}导入交易记录{% endblock %}
  3. {% block content %}
  4. <div class="container-fluid">
  5. <div class="row">
  6. <div class="col-12">
  7. <div class="card">
  8. <div class="card-header">
  9. <h3 class="card-title">导入交易记录</h3>
  10. </div>
  11. <div class="card-body">
  12. <div class="alert alert-info">
  13. <h5><i class="icon fas fa-info"></i> 导入说明</h5>
  14. <ol>
  15. <li>下载导入模板Excel文件</li>
  16. <li>按照模板格式填写交易记录数据</li>
  17. <li>上传填写好的Excel文件</li>
  18. </ol>
  19. <p class="mb-0">
  20. <strong>必填字段:</strong>合约代码、名称、多空仓位(0-开多,1-平多,2-开空,3-平空)、成交价格、成交手数
  21. </p>
  22. </div>
  23. <div class="row">
  24. <div class="col-md-6">
  25. <!-- 下载模板按钮 -->
  26. <div class="form-group">
  27. <a href="{{ url_for('transaction.get_template') }}" class="btn btn-info">
  28. <i class="fas fa-download"></i> 下载导入模板
  29. </a>
  30. </div>
  31. <!-- 上传表单 -->
  32. <form id="uploadForm" enctype="multipart/form-data">
  33. <div class="form-group">
  34. <label for="file">选择文件</label>
  35. <div class="custom-file">
  36. <input type="file" class="custom-file-input" id="file" name="file" accept=".xlsx">
  37. <label class="custom-file-label" for="file">选择Excel文件</label>
  38. </div>
  39. </div>
  40. <div class="form-group">
  41. <button type="submit" class="btn btn-primary">
  42. <i class="fas fa-upload"></i> 开始导入
  43. </button>
  44. <a href="{{ url_for('transaction.index') }}" class="btn btn-default">
  45. <i class="fas fa-arrow-left"></i> 返回列表
  46. </a>
  47. </div>
  48. </form>
  49. </div>
  50. </div>
  51. <!-- 导入结果 -->
  52. <div id="importResult" style="display: none;">
  53. <div class="alert" role="alert">
  54. <h5><i class="icon fas fa-info"></i> 导入结果</h5>
  55. <p id="resultMessage" class="mb-0"></p>
  56. <div id="errorDetails" style="display: none;">
  57. <hr>
  58. <p class="mb-1">错误详情:</p>
  59. <ul id="errorList" class="mb-0"></ul>
  60. </div>
  61. </div>
  62. </div>
  63. </div>
  64. </div>
  65. </div>
  66. </div>
  67. </div>
  68. {% endblock %}
  69. {% block scripts %}
  70. <script>
  71. $(document).ready(function() {
  72. // 文件选择处理
  73. $('.custom-file-input').on('change', function() {
  74. let fileName = $(this).val().split('\\').pop();
  75. $(this).next('.custom-file-label').html(fileName || '选择Excel文件');
  76. });
  77. // 表单提交处理
  78. $('#uploadForm').on('submit', function(e) {
  79. e.preventDefault();
  80. // 检查文件
  81. let fileInput = $('#file')[0];
  82. if (!fileInput.files || !fileInput.files[0]) {
  83. showResult('请选择要导入的文件', 'warning');
  84. return;
  85. }
  86. // 检查文件类型
  87. let fileName = fileInput.files[0].name;
  88. if (!fileName.endsWith('.xlsx')) {
  89. showResult('请上传Excel文件(.xlsx)', 'warning');
  90. return;
  91. }
  92. // 显示加载状态
  93. let submitBtn = $(this).find('button[type="submit"]');
  94. let originalText = submitBtn.html();
  95. submitBtn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> 导入中...');
  96. // 创建FormData对象
  97. let formData = new FormData();
  98. formData.append('file', fileInput.files[0]);
  99. // 发送请求
  100. $.ajax({
  101. url: "{{ url_for('transaction.import_excel') }}",
  102. type: 'POST',
  103. data: formData,
  104. processData: false,
  105. contentType: false,
  106. success: function(response) {
  107. if (response.code === 0) {
  108. // 导入成功
  109. let msg = response.msg;
  110. showResult(msg, 'success');
  111. // 显示错误详情(如果有)
  112. if (response.data.error_messages && response.data.error_messages.length > 0) {
  113. showErrorDetails(response.data.error_messages);
  114. }
  115. // 清空文件选择
  116. $('#file').val('').next('.custom-file-label').html('选择Excel文件');
  117. } else {
  118. // 导入失败
  119. showResult(response.msg, 'danger');
  120. }
  121. },
  122. error: function(jqXHR, textStatus, errorThrown) {
  123. showResult('导入失败:' + textStatus, 'danger');
  124. },
  125. complete: function() {
  126. // 恢复按钮状态
  127. submitBtn.prop('disabled', false).html(originalText);
  128. }
  129. });
  130. });
  131. // 显示结果
  132. function showResult(message, type) {
  133. let resultDiv = $('#importResult');
  134. let alertDiv = resultDiv.find('.alert');
  135. let messageP = $('#resultMessage');
  136. // 设置消息和样式
  137. messageP.text(message);
  138. alertDiv.removeClass('alert-success alert-warning alert-danger')
  139. .addClass('alert-' + type);
  140. // 设置图标
  141. let icon = alertDiv.find('.icon');
  142. icon.removeClass('fa-info fa-check fa-times fa-exclamation-triangle');
  143. switch (type) {
  144. case 'success':
  145. icon.addClass('fa-check');
  146. break;
  147. case 'warning':
  148. icon.addClass('fa-exclamation-triangle');
  149. break;
  150. case 'danger':
  151. icon.addClass('fa-times');
  152. break;
  153. default:
  154. icon.addClass('fa-info');
  155. }
  156. // 显示结果区域
  157. resultDiv.show();
  158. // 隐藏错误详情
  159. $('#errorDetails').hide();
  160. $('#errorList').empty();
  161. // 滚动到结果区域
  162. resultDiv[0].scrollIntoView({ behavior: 'smooth' });
  163. }
  164. // 显示错误详情
  165. function showErrorDetails(errors) {
  166. let errorList = $('#errorList');
  167. errorList.empty();
  168. errors.forEach(function(error) {
  169. errorList.append(`<li>${error}</li>`);
  170. });
  171. $('#errorDetails').show();
  172. }
  173. });
  174. </script>
  175. {% endblock %}