index.blade.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. @extends('base.base')
  2. @section('base')
  3. <div class="main-panel">
  4. <div class="content-wrapper">
  5. <div class="row">
  6. <div class="col-12 grid-margin stretch-card">
  7. <div class="card">
  8. <div class="card-body">
  9. <h4 class="card-title">Bonus购买回报配置</h4>
  10. <p class="card-description">配置Bonus购买时的倍率和权重</p>
  11. <style>
  12. .table-wrapper {
  13. max-height: calc(100vh - 250px);
  14. overflow-y: auto;
  15. position: relative;
  16. border: 1px solid #ddd;
  17. }
  18. .config-table {
  19. width: 100%;
  20. border-collapse: collapse;
  21. margin: 0;
  22. background: #fff;
  23. }
  24. .config-table th,
  25. .config-table td {
  26. border: 1px solid #ddd;
  27. padding: 10px;
  28. text-align: center;
  29. font-size: 14px;
  30. }
  31. .config-table thead {
  32. position: sticky;
  33. top: 0;
  34. z-index: 100;
  35. }
  36. .config-table th {
  37. background-color: #4CAF50;
  38. color: white;
  39. font-weight: bold;
  40. position: sticky;
  41. top: 0;
  42. box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.4);
  43. }
  44. .config-table tbody tr:nth-child(even) {
  45. background-color: #f9f9f9;
  46. }
  47. .config-table tbody tr:hover {
  48. background-color: #f0f0f0;
  49. }
  50. .config-table input[type="number"],
  51. .config-table input[type="text"] {
  52. width: 95%;
  53. padding: 5px;
  54. border: 1px solid transparent;
  55. border-radius: 3px;
  56. text-align: center;
  57. background: transparent;
  58. cursor: pointer;
  59. }
  60. .config-table input[type="number"]:focus,
  61. .config-table input[type="text"]:focus {
  62. border: 1px solid #4CAF50;
  63. background: #fff;
  64. outline: none;
  65. box-shadow: 0 0 5px rgba(76, 175, 80, 0.3);
  66. }
  67. .config-table input[type="number"]:read-only,
  68. .config-table input[type="text"]:read-only {
  69. cursor: pointer;
  70. }
  71. .editable-cell {
  72. cursor: pointer;
  73. position: relative;
  74. }
  75. .editable-cell:hover::after {
  76. content: '✎';
  77. position: absolute;
  78. right: 5px;
  79. top: 50%;
  80. transform: translateY(-50%);
  81. color: #4CAF50;
  82. font-size: 14px;
  83. }
  84. .field-label {
  85. color: #ccc;
  86. font-size: 11px;
  87. }
  88. /* 滚动条美化 */
  89. .table-wrapper::-webkit-scrollbar {
  90. width: 8px;
  91. }
  92. .table-wrapper::-webkit-scrollbar-track {
  93. background: #f1f1f1;
  94. border-radius: 4px;
  95. }
  96. .table-wrapper::-webkit-scrollbar-thumb {
  97. background: #888;
  98. border-radius: 4px;
  99. }
  100. .table-wrapper::-webkit-scrollbar-thumb:hover {
  101. background: #555;
  102. }
  103. </style>
  104. <form id="configForm">
  105. <div class="table-wrapper">
  106. <table class="config-table">
  107. <thead>
  108. <tr>
  109. <th>ID</th>
  110. <th>倍率最小<br><span class="field-label">(MultiMin)</span></th>
  111. <th>倍率最大<br><span class="field-label">(MultiMax)</span></th>
  112. <th>权重<br><span class="field-label">(Weight)</span></th>
  113. <th>权重调节<br><span class="field-label">(WeightAdjust)</span></th>
  114. </tr>
  115. </thead>
  116. <tbody>
  117. @foreach($configs as $config)
  118. <tr>
  119. <td>{{ $config->ConfigID }}</td>
  120. <td>
  121. <input type="number"
  122. name="configs[{{ $config->ConfigID }}][MultiMin]"
  123. value="{{ number_format($config->MultiMin, 2, '.', '') }}"
  124. min="0"
  125. step="0.01">
  126. </td>
  127. <td>
  128. <input type="number"
  129. name="configs[{{ $config->ConfigID }}][MultiMax]"
  130. value="{{ number_format($config->MultiMax, 2, '.', '') }}"
  131. min="0"
  132. step="0.01">
  133. </td>
  134. <td>
  135. <input type="number"
  136. name="configs[{{ $config->ConfigID }}][Weight]"
  137. value="{{ $config->Weight }}"
  138. min="0"
  139. step="1">
  140. </td>
  141. <td>
  142. <input type="text"
  143. name="configs[{{ $config->ConfigID }}][WeightAdjust]"
  144. value="{{ $config->WeightAdjust }}"
  145. placeholder="如: 10Z"
  146. style="width: 120px;">
  147. </td>
  148. </tr>
  149. @endforeach
  150. </tbody>
  151. </table>
  152. </div>
  153. <div style="text-align: center; margin: 20px 0;">
  154. <button type="button" class="btn btn-primary btn-lg" onclick="saveConfig()">保存配置</button>
  155. </div>
  156. </form>
  157. <script>
  158. // 保存原始数据
  159. const originalData = {};
  160. $(document).ready(function() {
  161. // 记录所有字段的原始值
  162. $('input[name^="configs"]').each(function() {
  163. const name = $(this).attr('name');
  164. originalData[name] = $(this).val();
  165. // 设置为只读,点击后才能编辑
  166. $(this).attr('readonly', true);
  167. });
  168. // 点击input时移除只读,进入编辑模式
  169. $('input[type="number"], input[type="text"]').on('click', function() {
  170. $(this).attr('readonly', false);
  171. $(this).select(); // 选中内容,方便修改
  172. });
  173. // 失去焦点时恢复只读
  174. $('input[type="number"], input[type="text"]').on('blur', function() {
  175. $(this).attr('readonly', true);
  176. });
  177. });
  178. function saveConfig() {
  179. // 收集有变动的数据
  180. const changedData = {};
  181. let hasChanges = false;
  182. $('input[name^="configs"]').each(function() {
  183. const name = $(this).attr('name');
  184. const currentValue = $(this).val();
  185. // 只添加有变动的字段
  186. if (originalData[name] !== currentValue) {
  187. changedData[name] = currentValue;
  188. hasChanges = true;
  189. }
  190. });
  191. if (!hasChanges) {
  192. layer.msg('没有数据被修改', {icon: 0});
  193. return;
  194. }
  195. // 构建只包含变动数据的表单
  196. const formData = $.param(changedData);
  197. layer.msg('正在保存 ' + Object.keys(changedData).length + ' 个变动...', {icon: 16, time: 0, shade: 0.3});
  198. $.ajax({
  199. url: '/admin/game-buy-bonus-config/update',
  200. type: 'POST',
  201. data: formData,
  202. dataType: 'json',
  203. success: function(res) {
  204. layer.closeAll();
  205. if (res.code === 200) {
  206. layer.msg('配置更新成功!', {icon: 1});
  207. setTimeout(function() {
  208. location.reload();
  209. }, 1000);
  210. } else {
  211. layer.msg('更新失败: ' + (res.msg || '未知错误'), {icon: 2});
  212. }
  213. },
  214. error: function(xhr) {
  215. layer.closeAll();
  216. layer.msg('请求失败: ' + xhr.statusText, {icon: 2});
  217. }
  218. });
  219. }
  220. </script>
  221. </div>
  222. </div>
  223. </div>
  224. </div>
  225. </div>
  226. </div>
  227. @endsection