col_set.ejs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <!--弹出列设置-->
  2. <style>
  3. #col-set .selected-contract-cols table {
  4. margin-bottom: 0;
  5. border-collapse: separate;
  6. border-spacing: 0;
  7. border: 0;
  8. }
  9. #col-set .selected-contract-cols .table-bordered th,
  10. #col-set .selected-contract-cols .table-bordered td {
  11. border: 0;
  12. border-right: 1px solid #dee2e6;
  13. border-bottom: 1px solid #dee2e6;
  14. }
  15. #col-set .selected-contract-cols .table-bordered th:last-child,
  16. #col-set .selected-contract-cols .table-bordered td:last-child {
  17. border-right: 0;
  18. }
  19. #col-set .selected-contract-cols tbody tr:last-child td {
  20. border-bottom: 0;
  21. }
  22. #col-set .selected-contract-cols thead th {
  23. position: sticky;
  24. top: 0;
  25. z-index: 2;
  26. background-color: #f8f9fa;
  27. }
  28. #copy-contract-col-set { z-index: 1060; }
  29. #copy-contract-col-set .copy-target-list { max-height: 420px; overflow-y: auto; }
  30. #copy-contract-col-set .copy-target-row { min-height: 34px; }
  31. </style>
  32. <div class="modal fade" id="col-set" data-backdrop="static">
  33. <div class="modal-dialog modal-xl" role="document">
  34. <div class="modal-content">
  35. <div class="modal-header"><h5 class="modal-title">列设置</h5></div>
  36. <div class="modal-body">
  37. <div class="row">
  38. <div class="col-md-4">
  39. <div class="font-weight-bold mb-2">可添加的合同属性</div>
  40. <div class="contract-col-options border rounded p-2" style="height: 520px; overflow-y: scroll; scrollbar-gutter: stable;">
  41. <% const columnGroups = [
  42. { name: '合同详情', items: contractColumnOptions.detail },
  43. { name: '附加属性', items: contractColumnOptions.attribute },
  44. ]; %>
  45. <% for (const group of columnGroups) { %>
  46. <div class="contract-col-group mb-3">
  47. <div class="bg-light font-weight-bold px-2 py-1 mb-1"><%- group.name %></div>
  48. <% if (group.items.length === 0) { %><div class="text-muted px-2 py-1">暂无可用属性</div><% } %>
  49. <% for (const item of group.items) { %>
  50. <div class="contract-col-option d-flex align-items-center justify-content-between px-2 py-1"
  51. data-field="<%- item.field %>" data-name="<%- item.name %>" data-source="<%- item.source %>">
  52. <span><%- item.name %></span>
  53. <button type="button" class="btn btn-sm btn-outline-primary add-contract-col">添加</button>
  54. </div>
  55. <% } %>
  56. </div>
  57. <% } %>
  58. </div>
  59. </div>
  60. <div class="col-md-8">
  61. <div class="font-weight-bold mb-2">已选择的列</div>
  62. <div class="selected-contract-cols table-responsive border rounded" style="height: 520px; overflow-y: scroll; scrollbar-gutter: stable;">
  63. <table class="table table-hover table-bordered mb-0">
  64. <thead><tr><th width="150px" class="text-center">列名</th><th width="60px" class="text-center">显示</th><th width="150px" class="text-center">别名</th><th width="170px" class="text-center">操作</th></tr></thead>
  65. <tbody class="text-center">
  66. <% for (const cs of colSet) { %>
  67. <tr code="<%- cs.field %>" data-name="<%- cs.name %>" data-source="<%- cs.source || 'base' %>" data-removable="<%- cs.removable ? 1 : 0 %>">
  68. <td><%- cs.name %><% if (cs.hint) { %><i class="fa fa-question-circle text-primary ml-1" data-placement="bottom" data-toggle="tooltip" data-original-title="<%- cs.hint %>"></i><% } %></td>
  69. <td><div class="form-check form-check-inline"><input class="form-check-input col-show" type="checkbox" <% if (cs.show) { %>checked<% } %>></div></td>
  70. <% if (cs.fixed.indexOf('alias') >= 0) { %><td class="disabled">-</td><% } else { %><td><input type="text" class="form-control form-control-sm col-alias" value="<%- cs.alias %>"></td><% } %>
  71. <td class="text-nowrap">
  72. <a href="javascript:;" class="move-up text-primary mr-2">上移</a>
  73. <a href="javascript:;" class="move-down text-primary mr-2">下移</a>
  74. <% if (cs.removable) { %><a href="javascript:;" class="remove-contract-col text-danger">移除</a><% } %>
  75. </td>
  76. </tr>
  77. <% } %>
  78. </tbody>
  79. </table>
  80. </div>
  81. </div>
  82. </div>
  83. </div>
  84. <form class="modal-footer justify-content-between" action="/sp/<%- ctx.subProject.id %>/contract/<%- ctx.contractOptions.tid ? 'tender/'+ctx.contractOptions.tid + '/' : '' %>col-set" method="post" onsubmit="return onSetCol();">
  85. <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>"><input type="hidden" name="col_set" value=""><input type="hidden" name="type" value="<%- ctx.contract_type %>"><input type="hidden" name="col_type" value="info">
  86. <button type="button" class="btn btn-outline-primary btn-sm" id="open-copy-contract-col-set">设置至其他<%- contractColCopyScope === 'tender' ? '标段' : '项目' %></button>
  87. <div><button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button><button type="submit" class="btn btn-primary btn-sm ml-1" id="add-bd-ok">确定修改</button></div>
  88. </form>
  89. </div>
  90. </div>
  91. </div>
  92. <div class="modal fade" id="copy-contract-col-set" data-backdrop="static">
  93. <div class="modal-dialog modal-lg" role="document">
  94. <div class="modal-content">
  95. <div class="modal-header"><h5 class="modal-title">设置至其他<%- contractColCopyScope === 'tender' ? '标段' : '项目' %></h5></div>
  96. <div class="modal-body">
  97. <div class="alert alert-warning py-2">将当前“<%- ctx.contract_type === contractConst.type.income ? '收入合同' : '支出合同' %>”列设置复制到勾选的<%- contractColCopyScope === 'tender' ? '标段' : '子项目' %>。</div>
  98. <div class="border rounded copy-target-list">
  99. <% if (!contractColCopyTargets.some(item => !item.is_folder && !item.current)) { %><div class="text-muted p-3">暂无其他可设置的<%- contractColCopyScope === 'tender' ? '标段' : '子项目' %></div><% } %>
  100. <% for (const target of contractColCopyTargets) { %>
  101. <div class="copy-target-row d-flex align-items-center border-bottom px-2"
  102. style="padding-left: <%- 12 + ((target.tree_level || 1) - 1) * 24 %>px !important;">
  103. <% if (target.is_folder) { %>
  104. <i class="fa fa-folder-o text-warning mr-2"></i><span><%- target.name %></span>
  105. <% } else { %>
  106. <label class="mb-0 w-100">
  107. <input type="checkbox" class="copy-contract-col-target mr-2" value="<%- target.id %>" <%- target.current ? 'disabled' : '' %>>
  108. <i class="fa <%- contractColCopyScope === 'tender' ? 'fa-flag-o' : 'fa-file-o' %> text-muted mr-1"></i><%- target.name %><% if (target.current) { %><span class="text-muted ml-2">(当前)</span><% } %>
  109. </label>
  110. <% } %>
  111. </div>
  112. <% } %>
  113. </div>
  114. </div>
  115. <div class="modal-footer">
  116. <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
  117. <button type="button" class="btn btn-primary btn-sm" id="copy-contract-col-set-ok">确认复制</button>
  118. </div>
  119. </div>
  120. </div>
  121. </div>
  122. <script>
  123. const $colSetModal = $('#col-set');
  124. const $colSetTbody = $colSetModal.find('tbody');
  125. const _initialColSetTbodyHtml = $colSetTbody.html();
  126. const _initialColOptionsHtml = $colSetModal.find('.contract-col-options').html();
  127. function syncContractColOptions() {
  128. const selected = {};
  129. $colSetTbody.find('tr').each(function () { selected[$(this).attr('code')] = true; });
  130. $colSetModal.find('.contract-col-option').each(function () {
  131. const $option = $(this);
  132. if (selected[$option.data('field')]) {
  133. $option.removeClass('d-flex').addClass('d-none');
  134. } else {
  135. $option.removeClass('d-none').addClass('d-flex');
  136. }
  137. });
  138. }
  139. function updateMoveButtons() {
  140. const $rows = $colSetTbody.find('tr');
  141. $rows.each(function(index) {
  142. $(this).find('.move-up').toggle(index > 0);
  143. $(this).find('.move-down').toggle(index < $rows.length - 1);
  144. });
  145. }
  146. function makeContractColRow(field, name, source) {
  147. const $row = $('<tr>').attr({ code: field, 'data-name': name, 'data-source': source, 'data-removable': '1' });
  148. $('<td>').text(name).appendTo($row);
  149. $('<td>').append($('<div class="form-check form-check-inline">').append($('<input class="form-check-input col-show" type="checkbox" checked>'))).appendTo($row);
  150. $('<td class="disabled">').text('-').appendTo($row);
  151. $('<td class="text-nowrap">').append(
  152. $('<a href="javascript:;" class="move-up text-primary mr-2">').text('上移'),
  153. $('<a href="javascript:;" class="move-down text-primary mr-2">').text('下移'),
  154. $('<a href="javascript:;" class="remove-contract-col text-danger">').text('移除')
  155. ).appendTo($row);
  156. return $row;
  157. }
  158. $colSetModal.on('shown.bs.modal', function() { syncContractColOptions(); updateMoveButtons(); });
  159. $colSetModal.on('hidden.bs.modal', function() {
  160. $colSetTbody.html(_initialColSetTbodyHtml);
  161. $colSetModal.find('.contract-col-options').html(_initialColOptionsHtml);
  162. syncContractColOptions(); updateMoveButtons();
  163. });
  164. $colSetModal.on('click', '.add-contract-col', function() {
  165. const $option = $(this).closest('.contract-col-option');
  166. const field = $option.data('field');
  167. if ($colSetTbody.find('tr[code="' + field + '"]').length) return;
  168. $colSetTbody.append(makeContractColRow(field, $option.data('name'), $option.data('source')));
  169. syncContractColOptions(); updateMoveButtons();
  170. });
  171. $colSetTbody.on('click', '.remove-contract-col', function(e) { e.preventDefault(); $(this).closest('tr').remove(); syncContractColOptions(); updateMoveButtons(); });
  172. $colSetTbody.on('click', '.move-up', function(e) { e.preventDefault(); const $row = $(this).closest('tr'), $prev = $row.prev('tr'); if ($prev.length) $row.insertBefore($prev); updateMoveButtons(); });
  173. $colSetTbody.on('click', '.move-down', function(e) { e.preventDefault(); const $row = $(this).closest('tr'), $next = $row.next('tr'); if ($next.length) $row.insertAfter($next); updateMoveButtons(); });
  174. syncContractColOptions(); updateMoveButtons();
  175. function onSetCol() {
  176. const colSet = getCurrentContractColSet();
  177. $colSetModal.find('input[name=col_set]').val(JSON.stringify(colSet));
  178. return true;
  179. }
  180. function getCurrentContractColSet() {
  181. const colSet = [];
  182. $colSetTbody.find('tr').each(function() {
  183. const $row = $(this), $alias = $row.find('.col-alias');
  184. colSet.push({ field: $row.attr('code'), show: Number($row.find('.col-show').is(':checked')), alias: $alias.length ? $alias.val().trim() : '' });
  185. });
  186. return colSet;
  187. }
  188. $('#open-copy-contract-col-set').on('click', function() {
  189. $('#copy-contract-col-set').find('.copy-contract-col-target').prop('checked', false);
  190. $('#copy-contract-col-set').modal('show');
  191. });
  192. $('#copy-contract-col-set').on('shown.bs.modal', function() {
  193. const $backdrops = $('.modal-backdrop');
  194. $backdrops.last().css('z-index', 1055);
  195. });
  196. $('#copy-contract-col-set').on('hidden.bs.modal', function() {
  197. if ($colSetModal.hasClass('show')) $('body').addClass('modal-open');
  198. });
  199. $('#copy-contract-col-set-ok').on('click', function() {
  200. const targetIds = $('#copy-contract-col-set .copy-contract-col-target:checked').map(function() { return this.value; }).get();
  201. if (!targetIds.length) { toastr.warning('请选择需要设置的<%- contractColCopyScope === 'tender' ? '标段' : '子项目' %>'); return; }
  202. const url = '/sp/<%- ctx.subProject.id %>/contract/<%- ctx.contractOptions.tid ? 'tender/' + ctx.contractOptions.tid + '/' : '' %>col-set/copy';
  203. postData(url, {
  204. type: <%- ctx.contract_type %>,
  205. col_set: getCurrentContractColSet(),
  206. target_ids: targetIds,
  207. }, function(data, msg) {
  208. $('#copy-contract-col-set').modal('hide');
  209. toastr.success(msg || ('已设置至' + data.count + '个目标'));
  210. });
  211. });
  212. </script>