index_jili.blade.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. @extends('base.base')
  2. @section('base')
  3. <meta name="csrf-token" content="{{ csrf_token() }}">
  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">Jili游戏参数配置</h3>
  10. </div>
  11. <div class="card-body">
  12. <div class="table-responsive">
  13. <table class="table table-bordered">
  14. <thead>
  15. <tr>
  16. <th>游戏ID</th>
  17. <th>游戏名称</th>
  18. <th>配置</th>
  19. <th>操作</th>
  20. </tr>
  21. </thead>
  22. <tbody>
  23. @foreach($pgGames as $game)
  24. <tr>
  25. <td>{{ $game['gameId'] }}</td>
  26. <td>{{ $game['gameName'] }}</td>
  27. <td>
  28. <div class="config-editor" data-game-id="{{ $game['gameId'] }}">
  29. @php
  30. $config = $game['config'] ? $game['config'] : [
  31. "1" => ["FreeWinMax" => 7000, "RechargeControl" => 7000, "RechargeMaxPercent" => 70],
  32. "2" => ["FreeWinMax" => 30000, "RechargeControl" => 100000, "RechargeMaxPercent" => 50],
  33. "3" => ["FreeWinMax" => 150000, "RechargeControl" => 500000, "RechargeMaxPercent" => 40]
  34. ];
  35. @endphp
  36. <div class="config-form">
  37. @foreach([1, 2, 3] as $level)
  38. <div class="card mb-3">
  39. <div class="card-header bg-light">
  40. <strong>等级{{ $level }}配置</strong>
  41. </div>
  42. <div class="card-body">
  43. <div class="row">
  44. <div class="col-md-4 form-group">
  45. <label>免费最大赢额 (FreeWinMax)</label>
  46. <input type="number" class="form-control freeWinMax-input"
  47. step="0.01"
  48. name="level[{{ $level }}][FreeWinMax]"
  49. value="{{ isset($config[$level]['FreeWinMax']) ? $config[$level]['FreeWinMax'] / 100 : 0 }}">
  50. </div>
  51. <div class="col-md-4 form-group">
  52. <label>充值控制额 (RechargeControl)</label>
  53. <input type="number" class="form-control rechargeControl-input"
  54. step="0.01"
  55. name="level[{{ $level }}][RechargeControl]"
  56. value="{{ isset($config[$level]['RechargeControl']) ? $config[$level]['RechargeControl'] / 100 : 0 }}">
  57. </div>
  58. <div class="col-md-4 form-group">
  59. <label>充值最大百分比 (RechargeMaxPercent)</label>
  60. <input type="number" class="form-control"
  61. name="level[{{ $level }}][RechargeMaxPercent]"
  62. value="{{ $config[$level]['RechargeMaxPercent'] ?? 0 }}">
  63. </div>
  64. </div>
  65. </div>
  66. </div>
  67. @endforeach
  68. </div>
  69. </div>
  70. </td>
  71. <td>
  72. <button class="btn btn-primary btn-sm save-config" data-game-id="{{ $game['gameId'] }}">保存</button>
  73. <span class="save-status ml-2"></span>
  74. <button class="btn btn-warning btn-sm copy-config ml-3" data-game-id="{{ $game['gameId'] }}">复制到所有游戏</button>
  75. <span class="copy-status ml-2"></span>
  76. </td>
  77. </tr>
  78. @endforeach
  79. </tbody>
  80. </table>
  81. </div>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. </div>
  87. <script>
  88. $(document).ready(function() {
  89. // 添加按钮点击调试信息
  90. console.log('JS加载完成');
  91. $('.save-config').click(function() {
  92. console.log('保存按钮被点击');
  93. const gameId = $(this).data('game-id');
  94. console.log('游戏ID:', gameId);
  95. const configForm = $(this).closest('tr').find('.config-form');
  96. const saveBtn = $(this);
  97. const saveStatus = $(this).siblings('.save-status');
  98. // 显示保存中状态
  99. saveBtn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> 保存中...');
  100. saveStatus.html('').removeClass('text-success text-danger');
  101. // 构建配置对象
  102. let configObj = {
  103. "1": {"FreeWinMax": 0, "RechargeControl": 0, "RechargeMaxPercent": 0},
  104. "2": {"FreeWinMax": 0, "RechargeControl": 0, "RechargeMaxPercent": 0},
  105. "3": {"FreeWinMax": 0, "RechargeControl": 0, "RechargeMaxPercent": 0}
  106. };
  107. // 收集表单数据
  108. configForm.find('input').each(function() {
  109. const name = $(this).attr('name');
  110. let value = 0;
  111. // 根据字段类型处理不同的转换逻辑
  112. if ($(this).hasClass('freeWinMax-input') || $(this).hasClass('rechargeControl-input')) {
  113. // 乘以100保存
  114. value = Math.round(parseFloat($(this).val() || 0) * 100);
  115. } else {
  116. value = parseInt($(this).val()) || 0;
  117. }
  118. // 解析name属性 level[1][FreeWinMax] 格式
  119. const matches = name.match(/level\[(\d+)\]\[([^\]]+)\]/);
  120. if (matches) {
  121. const level = matches[1];
  122. const field = matches[2];
  123. configObj[level][field] = value;
  124. }
  125. });
  126. // 转换成JSON
  127. const config = JSON.stringify(configObj);
  128. console.log('准备提交的配置:', config);
  129. // 确保CSRF令牌存在
  130. const token = $('meta[name="csrf-token"]').attr('content');
  131. console.log('CSRF令牌:', token ? '存在' : '不存在');
  132. // 阻止可能的默认行为
  133. event.preventDefault();
  134. $.ajax({
  135. url: "{{ url('/admin/jl-game-config/update') }}",
  136. method: 'POST',
  137. data: {
  138. gameId: gameId,
  139. config: config,
  140. _token: "{{ csrf_token() }}"
  141. },
  142. success: function(response) {
  143. console.log('成功响应:', response);
  144. // 恢复按钮状态
  145. saveBtn.prop('disabled', false).text('保存');
  146. if (response.status === 'success') {
  147. // 显示成功提示
  148. saveStatus.html('<i class="fa fa-check-circle"></i> 更新成功').addClass('text-success');
  149. // 使用toastr提示
  150. if (typeof toastr !== 'undefined') {
  151. toastr.success('配置更新成功');
  152. } else {
  153. // 备用提示方式
  154. alert('配置更新成功');
  155. }
  156. } else {
  157. // 显示错误提示
  158. saveStatus.html('<i class="fa fa-times-circle"></i> ' + (response.message || '更新失败')).addClass('text-danger');
  159. // 使用toastr提示
  160. if (typeof toastr !== 'undefined') {
  161. toastr.error(response.message || '更新失败');
  162. } else {
  163. // 备用提示方式
  164. alert('更新失败: ' + (response.message || '未知错误'));
  165. }
  166. }
  167. // 3秒后清除状态提示
  168. setTimeout(function() {
  169. saveStatus.fadeOut(function() {
  170. $(this).html('').show().removeClass('text-success text-danger');
  171. });
  172. }, 3000);
  173. },
  174. error: function(xhr, status, error) {
  175. console.error('错误:', xhr.responseText);
  176. // 恢复按钮状态
  177. saveBtn.prop('disabled', false).text('保存');
  178. saveStatus.html('<i class="fa fa-times-circle"></i> 系统错误').addClass('text-danger');
  179. // 使用toastr提示
  180. if (typeof toastr !== 'undefined') {
  181. toastr.error('系统错误,请稍后重试');
  182. } else {
  183. // 备用提示方式
  184. alert('系统错误,请稍后重试');
  185. }
  186. // 3秒后清除状态提示
  187. setTimeout(function() {
  188. saveStatus.fadeOut(function() {
  189. $(this).html('').show().removeClass('text-success text-danger');
  190. });
  191. }, 3000);
  192. }
  193. });
  194. });
  195. });
  196. // 复制到所有游戏
  197. $('.copy-config').click(function() {
  198. const gameId = $(this).data('game-id');
  199. const configForm = $(this).closest('tr').find('.config-form');
  200. const copyBtn = $(this);
  201. const copyStatus = $(this).siblings('.copy-status');
  202. if (!confirm('确定将该游戏当前参数复制到所有JILI游戏?(不包含本游戏)')) {
  203. return;
  204. }
  205. // 显示复制中状态
  206. copyBtn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> 复制中...');
  207. copyStatus.html('').removeClass('text-success text-danger');
  208. // 构建配置对象(与保存逻辑一致)
  209. let configObj = {
  210. "1": {"FreeWinMax": 0, "RechargeControl": 0, "RechargeMaxPercent": 0},
  211. "2": {"FreeWinMax": 0, "RechargeControl": 0, "RechargeMaxPercent": 0},
  212. "3": {"FreeWinMax": 0, "RechargeControl": 0, "RechargeMaxPercent": 0}
  213. };
  214. configForm.find('input').each(function() {
  215. const name = $(this).attr('name');
  216. let value = 0;
  217. if ($(this).hasClass('freeWinMax-input') || $(this).hasClass('rechargeControl-input')) {
  218. value = Math.round(parseFloat($(this).val() || 0) * 100);
  219. } else {
  220. value = parseInt($(this).val()) || 0;
  221. }
  222. const matches = name.match(/level\[(\d+)\]\[([^\]]+)\]/);
  223. if (matches) {
  224. const level = matches[1];
  225. const field = matches[2];
  226. configObj[level][field] = value;
  227. }
  228. });
  229. const config = JSON.stringify(configObj);
  230. $.ajax({
  231. url: "{{ url('/admin/jl-game-config/copy_all') }}",
  232. method: 'POST',
  233. data: {
  234. gameId: gameId,
  235. config: config,
  236. _token: "{{ csrf_token() }}"
  237. },
  238. success: function(response) {
  239. copyBtn.prop('disabled', false).text('复制到所有游戏');
  240. if (response.status === 'success') {
  241. copyStatus.html('<i class="fa fa-check-circle"></i> 已复制到其他游戏(' + (response.affected || 0) + ' 个)').addClass('text-success');
  242. if (typeof toastr !== 'undefined') toastr.success('复制成功');
  243. } else {
  244. copyStatus.html('<i class="fa fa-times-circle"></i> ' + (response.message || '复制失败')).addClass('text-danger');
  245. if (typeof toastr !== 'undefined') toastr.error(response.message || '复制失败');
  246. }
  247. setTimeout(function() {
  248. copyStatus.fadeOut(function() {
  249. $(this).html('').show().removeClass('text-success text-danger');
  250. });
  251. }, 3000);
  252. },
  253. error: function(xhr) {
  254. copyBtn.prop('disabled', false).text('复制到所有游戏');
  255. copyStatus.html('<i class="fa fa-times-circle"></i> 系统错误').addClass('text-danger');
  256. if (typeof toastr !== 'undefined') toastr.error('系统错误,请稍后重试');
  257. setTimeout(function() {
  258. copyStatus.fadeOut(function() {
  259. $(this).html('').show().removeClass('text-success text-danger');
  260. });
  261. }, 3000);
  262. }
  263. });
  264. });
  265. });
  266. </script>
  267. <style>
  268. .config-editor {
  269. position: relative;
  270. }
  271. </style>
  272. @endsection