detail.ejs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <% include ./sub_menu.ejs %>
  2. <div class="panel-content">
  3. <div class="panel-title">
  4. <div class="title-main d-flex">
  5. <% include ./sub_mini_menu.ejs %>
  6. <div class="d-inline-block">
  7. <div class="dropdown">
  8. <button class="btn btn-sm btn-light dropdown-toggle text-primary" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  9. <i class="fa fa-list-ol"></i> 显示层级
  10. </button>
  11. <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
  12. <a class="dropdown-item" name="showLevel" tag="1" href="javascript: void(0);">第一层</a>
  13. <a class="dropdown-item" name="showLevel" tag="2" href="javascript: void(0);">第二层</a>
  14. <a class="dropdown-item" name="showLevel" tag="3" href="javascript: void(0);">第三层</a>
  15. <a class="dropdown-item" name="showLevel" tag="4" href="javascript: void(0);">第四层</a>
  16. <a class="dropdown-item" name="showLevel" tag="5" href="javascript: void(0);">第五层</a>
  17. <a class="dropdown-item" name="showLevel" tag="last" href="javascript: void(0);">最底层</a>
  18. <!-- <a class="dropdown-item" name="showLevel" tag="leafXmj" href="javascript: void(0);">只显示项目节</a>-->
  19. </div>
  20. </div>
  21. </div>
  22. <% if (ctx.session.sessionUser.is_admin || audit_permission.permission_edit) { %>
  23. <div class="d-inline-block">
  24. <a href="javascript: void(0);" name="base-opr" type="add" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="新增"><i class="fa fa-plus" aria-hidden="true"></i></a>
  25. <a href="javascript: void(0);" name="base-opr" type="add-child" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="新增子节点"><i class="fa fa-sign-in" aria-hidden="true"></i></a>
  26. <a href="javascript: void(0);" name="base-opr" type="delete" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
  27. <a href="javascript: void(0);" name="base-opr" type="up-level" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="升级"><i class="fa fa-arrow-left" aria-hidden="true"></i></a>
  28. <a href="javascript: void(0);" name="base-opr" type="down-level" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="降级"><i class="fa fa-arrow-right" aria-hidden="true"></i></a>
  29. <a href="javascript: void(0);" name="base-opr" type="down-move" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
  30. <a href="javascript: void(0);" name="base-opr" type="up-move" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
  31. <!-- <a href="javascript: void(0);" name="cpc" type="copy" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="复制"><i class="fa fa-files-o" aria-hidden="true"></i></a>-->
  32. <!-- <a href="javascript: void(0);" name="cpc" type="cut" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="剪切"><i class="fa fa-scissors" aria-hidden="true"></i></a>-->
  33. <!-- <a href="javascript: void(0);" name="cpc" type="paste" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="粘贴"><i class="fa fa-clipboard" aria-hidden="true"></i></a>-->
  34. </div>
  35. <% } %>
  36. <div class="ml-auto">
  37. <a href="javascript:void(0);" id="contract-total-btn" class="btn btn-sm btn-primary mr-2">合计</a>
  38. <% if (ctx.session.sessionUser.is_admin) { %>
  39. <a href="#col-set" data-toggle="modal" data-target="#col-set" class="btn btn-sm btn-primary mr-2">列设置</a>
  40. <a href="javascript:void(0);" data-stid="<%- ctx.contract_tender ? ctx.contractOptions.tid : '' %>" class="btn btn-sm btn-primary get-audits mr-2">成员管理</a>
  41. <a href="#empower" data-toggle="modal" data-target="#empower" class="btn btn-sm btn-primary mr-2">节点授权</a>
  42. <% } %>
  43. <!-- <a href="#cons-relat" data-toggle="modal" data-target="#cons-relat" class="btn btn-primary btn-sm pull-right">关联合同</a>-->
  44. <% if (ctx.session.sessionUser.is_admin || audit_permission.permission_add) { %>
  45. <a href="#cons-add" data-toggle="modal" data-target="#cons-add" class="btn btn-primary btn-sm pull-right mr-2" id="add-cons-btn" style="display: none">新增合同</a>
  46. <% } %>
  47. </div>
  48. </div>
  49. </div>
  50. <div class="content-wrap pr-46">
  51. <div class="c-header p-0">
  52. </div>
  53. <div class="row w-100 sub-content">
  54. <div class="col-12 c-body">
  55. <!--上部分-->
  56. <div class="sjs-height-1 row w-100 sub-content">
  57. <!--左栏-->
  58. <div class="c-body" id="left-view" style="width: 100%">
  59. <div class="sjs-height-1" style="overflow: hidden" id="contract-spread"></div>
  60. </div>
  61. <div class="c-body" id="right-view" style="display: none; width: 30%">
  62. <div class="resize-x" id="right-spr" r-Type="width" div1="#left-view" div2="#right-view" title="调整大小" a-type="percent"><!--调整左右高度条--></div>
  63. <div class="tab-content">
  64. <div id="contract-search" class="tab-pane tab-select-show">
  65. </div>
  66. <div id="std-xmj" class="tab-pane">
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. <!--下部分-->
  72. <div class="bcontent-wrap mt-1">
  73. <div id="contract-resize" class="resize-y" id="top-spr" r-Type="height" div1=".sjs-height-1" div2=".bcontent-wrap" title="调整大小"><!--调整上下高度条--></div>
  74. <div class="bc-bar mb-1">
  75. <ul class="nav nav-tabs">
  76. <li class="nav-item">
  77. <a class="nav-link active" data-toggle="tab" href="#htdetail" role="tab">合同详情</a>
  78. </li>
  79. <li class="nav-item">
  80. <a class="nav-link " data-toggle="tab" href="#htpay" role="tab">合同<% if (ctx.contract_type === contractConst.type.expenses) { %>支付<% } else if (ctx.contract_type === contractConst.type.income) { %>回款<% } %></a>
  81. </li>
  82. <li class="nav-item">
  83. <a class="nav-link " data-toggle="tab" href="#htfile" role="tab">合同文件</a>
  84. </li>
  85. <li class="nav-item">
  86. <a class="nav-link " data-toggle="tab" href="#htsupplement" role="tab">补充合同</a>
  87. </li>
  88. <li class="ml-auto">
  89. <!-- 结算合同所有tab可见 ,结算后见解锁合同,2者互斥-->
  90. <a href="#cons-unlock" data-toggle="modal" data-target="#cons-unlock" style="display: none;" class="btn btn-success btn-sm pull-right mr-2">解锁合同</a>
  91. <a href="#cons-close" data-toggle="modal" data-target="#cons-close" style="display: none;" class="btn btn-danger btn-sm pull-right mr-2">结算合同</a>
  92. <!-- 合同文件的按钮 -->
  93. <a href="#cons-upfile" data-toggle="modal" data-target="#cons-upfile" style="display: none;" class="btn btn-primary btn-sm pull-right mr-2">上传文件</a>
  94. <!-- 合同支付的按钮 -->
  95. <!-- <a href="#cons-addpay2" data-toggle="modal" data-target="#cons-addpay2" class="btn btn-primary btn-sm pull-right mr-2">添加回款2</a>-->
  96. <a href="javascript:void(0);" id="add_contract_pay_btn" style="display: none;" class="btn btn-primary btn-sm pull-right mr-2">添加<% if (ctx.contract_type === contractConst.type.expenses) { %>支付<% } else if (ctx.contract_type === contractConst.type.income) { %>回款<% } %></a>
  97. <% if (ctx.contract_type === contractConst.type.expenses) { %><a href="javascript:void(0);" id="add_tender_contract_pay_btn" style="display: none;" class="btn btn-primary btn-sm pull-right mr-2">添加标段支付记录</a><% } %>
  98. <!-- 合同详情的按钮,点击编辑出现确定和取消按钮 -->
  99. <a href="javascript:void(0);" id="cancel_contract_btn" style="display: none" class="btn btn-secondary btn-sm pull-right mr-2">取消</a>
  100. <a href="javascript:void(0);" id="save_contract_btn" style="display: none" class="btn btn-primary btn-sm pull-right mr-2">确定</a>
  101. <a href="javascript:void(0);" id="edit_contract_btn" style="display: none" class="btn btn-primary btn-sm pull-right mr-2">编辑合同</a>
  102. <a href="javascript:void(0);" id="ai_edit_contract_btn" style="display: none" class="btn btn-sm ai-btn pull-right mr-2"><i class="fa fa-magic"></i> AI识别编辑合同</a>
  103. <a href="javascript:void(0);" id="add_contract_supplement_btn" style="display: none;" class="btn btn-primary btn-sm pull-right mr-2">新增补充合同</a>
  104. <% if (shenpi_status) { %>
  105. <span class="pull-right mr-2" id="shenpi_btn">
  106. <a href="#sub-sp" data-toggle="modal" data-target="#sub-sp" class="btn btn-primary btn-sm">待上报</a>
  107. </span>
  108. <% } %>
  109. </li>
  110. </ul>
  111. </div>
  112. <div class="tab-content">
  113. <div class="tab-pane active" id="htdetail">
  114. <div class="sp-wrap col-12" style="overflow: auto;">
  115. <table class="table table-sm table-bordered mb-1" id="htdetail-table" style="display: none;">
  116. <tr>
  117. <th class="text-center align-middle" width="10%">合同编号</th>
  118. <td width="20%" class="change-input-td" id="htdetail_c_code"></td>
  119. <th class="text-center align-middle" width="10%">合同名称</th>
  120. <td width="30%" class="change-input-td" id="htdetail_name"></td>
  121. <th class="text-center align-middle" width="10%">税率(%)</th>
  122. <td width="20%" class="change-input-td" id="htdetail_tax"></td>
  123. </tr>
  124. <tr>
  125. <th class="text-center align-middle">原合同金额</th>
  126. <td class="change-input-td" id="htdetail_price"></td>
  127. <th class="text-center align-middle">补充合同金额</th>
  128. <td class="" id="htdetail_supplement_price"></td>
  129. <th class="text-center align-middle">合同金额</th>
  130. <td class="" id="htdetail_total_price"></td>
  131. </tr>
  132. <tr>
  133. <th class="text-center align-middle"><% if (ctx.contract_type === contractConst.type.income) { %>累计回款(P)<% } else if (ctx.contract_type === contractConst.type.expenses) { %>累计付款(P)<% } %></th>
  134. <td id="htdetail_pay_price"></td>
  135. <th class="text-center align-middle">累计扣款(K)</th>
  136. <td id="htdetail_debit_price"></td>
  137. <th class="text-center align-middle"><% if (ctx.contract_type === contractConst.type.income) { %>累计应回(S=P-K)<% } else if (ctx.contract_type === contractConst.type.expenses) { %>累计应付(S=P-K)<% } %></th>
  138. <td id="htdetail_yf_price"></td>
  139. </tr>
  140. <tr>
  141. <th class="text-center align-middle"><% if (ctx.contract_type === contractConst.type.income) { %>累计实回(A)<% } else if (ctx.contract_type === contractConst.type.expenses) { %>累计实付(A)<% } %></th>
  142. <td id="htdetail_sf_price"></td>
  143. <th class="text-center align-middle"><% if (ctx.contract_type === contractConst.type.income) { %>待回款(S-A)<% } else if (ctx.contract_type === contractConst.type.expenses) { %>待支付(S-A)<% } %></th>
  144. <td id="htdetail_df_price"></td>
  145. <th class="text-center align-middle">创建时间</th>
  146. <td id="htdetail_create_time"></td>
  147. </tr>
  148. <tr>
  149. <th class="text-center align-middle">甲方</th>
  150. <td class="change-input-td" id="htdetail_party_a"></td>
  151. <th class="text-center align-middle">签约人</th>
  152. <td class="change-input-td" id="htdetail_party_a_user"></td>
  153. <th class="text-center align-middle">签订日期</th>
  154. <td class="change-input-td" id="htdetail_sign_date"></td>
  155. </tr>
  156. <tr>
  157. <th class="text-center align-middle">乙方</th>
  158. <td class="change-input-td" id="htdetail_party_b"></td>
  159. <th class="text-center align-middle">签约人</th>
  160. <td class="change-input-td" id="htdetail_party_b_user"></td>
  161. <th class="text-center align-middle">签约地点</th>
  162. <td class="change-input-td" id="htdetail_address"></td>
  163. </tr>
  164. <% if (ctx.contract_type === contractConst.type.expenses) { %>
  165. <tr class="contract-expenses">
  166. <th class="text-center align-middle">收款单位</th>
  167. <td class="change-input-td" id="htdetail_entity"></td>
  168. <th class="text-center align-middle">收款开户行</th>
  169. <td class="change-input-td" id="htdetail_bank"></td>
  170. <th class="text-center align-middle">收款账号</th>
  171. <td class="change-input-td" id="htdetail_bank_account"></td>
  172. </tr>
  173. <% } %>
  174. <tr>
  175. <th class="text-center align-middle">结算书编号</th>
  176. <td id="htdetail_settle_code"></td>
  177. <th class="text-center align-middle">备注</th>
  178. <td class="change-input-td" colspan="5" id="htdetail_remark"></td>
  179. </tr>
  180. </table>
  181. <% let tableHavePayCondition = false; %>
  182. <% if (attributeSet.length > 0) { %>
  183. <div class="mb-1">附加属性</div>
  184. <%
  185. // 按顺序分组:遇到 long_text 就切断,形成 segments
  186. // segments 结构:[{ type: 'inline', items: [...] }, { type: 'long', item: {...} }, ...]
  187. const segments = [];
  188. let buffer = [];
  189. for (const attr of attributeSet) {
  190. if (attr.field === 'pay_condition') tableHavePayCondition = true;
  191. if (attr.type === 'long_text') {
  192. if (buffer.length) {
  193. segments.push({ type: 'inline', items: [...buffer] });
  194. buffer = [];
  195. }
  196. segments.push({ type: 'long', item: attr });
  197. } else {
  198. buffer.push(attr);
  199. }
  200. }
  201. if (buffer.length) segments.push({ type: 'inline', items: [...buffer] });
  202. // 每行3列对应的 td 宽度
  203. const tdWidths = ['20%', '30%', '20%'];
  204. %>
  205. <table class="table table-sm table-bordered" id="htdetail-attr" style="display: none;">
  206. <% for (const seg of segments) { %>
  207. <% if (seg.type === 'long') { %>
  208. <tr>
  209. <th class="text-center align-middle" width="10%"><%- seg.item.alias || seg.item.name %></th>
  210. <td class="change-input-td" colspan="5"
  211. data-type="<%- seg.item.field %>"
  212. id="htdetail_<%- seg.item.field %>"></td>
  213. </tr>
  214. <% } else { %>
  215. <% for (let i = 0; i < seg.items.length; i += 3) { %>
  216. <% const row = seg.items.slice(i, i + 3) %>
  217. <tr>
  218. <% for (let k = 0; k < row.length; k++) { %>
  219. <th class="text-center align-middle" width="10%"><%- row[k].alias || row[k].name %></th>
  220. <td width="<%= tdWidths[k] %>" class="change-input-td"
  221. data-type="<%- row[k].field %>"
  222. id="htdetail_<%- row[k].field %>"></td>
  223. <% } %>
  224. <% if (row.length < 3) { %>
  225. <% const remainColspan = (3 - row.length) * 2 %>
  226. <td colspan="<%= remainColspan %>"></td>
  227. <% } %>
  228. </tr>
  229. <% } %>
  230. <% } %>
  231. <% } %>
  232. </table>
  233. <% } %>
  234. <% if (!tableHavePayCondition) { %>
  235. <textarea style="display: none" id="hidden_pay_condition"></textarea>
  236. <% } %>
  237. </div>
  238. </div>
  239. <div class="tab-pane" id="htpay">
  240. <div class="sp-wrap" style="overflow: auto">
  241. <table class="table table-sm table-bordered" id="htpay-table" style="display: none;">
  242. <thead>
  243. <tr class="text-center" id="pay-header">
  244. <% if (ctx.contract_type === contractConst.type.income) { %>
  245. <th width="3%">序号</th><th width="8%" sort="pay_time">回款日期</th><th width="5%">用途</th><th width="7%">回款金额</th><th width="7%">扣款金额</th><th width="7%">应回金额</th><th width="7%">实回金额</th><th width="5%">回款方式</th><th width="7%">开票金额</th><th width="7%" sort="kp_time">开票时间</th><th width="5%">创建人</th><th width="9%" sort="create_time">创建时间</th><th width="8%">备注</th><th width="4%">附件</th>
  246. <% if (pay_shenpi_status) { %>
  247. <th width="12%">审批进度</th>
  248. <% } %>
  249. <th width="14%" id="contract-pay-operation">操作</th>
  250. <% } else if (ctx.contract_type === contractConst.type.expenses) { %>
  251. <th width="3%">序号</th><th width="8%" sort="pay_time">支付日期</th><th width="5%">用途</th><th width="7%">付款金额</th><th width="7%">扣款金额</th><th width="7%">应付金额</th><th width="7%">实付金额</th><th width="5%">支付方式</th><th width="7%">开票金额</th><th width="7%" sort="kp_time">开票时间</th><th width="5%">创建人</th><th width="9%" sort="create_time">创建时间</th><th width="8%">备注</th><th width="4%">附件</th>
  252. <% if (pay_shenpi_status) { %>
  253. <th width="12%">审批进度</th>
  254. <% } %>
  255. <th width="14%" id="contract-pay-operation">操作</th>
  256. <% } %>
  257. </tr>
  258. </thead>
  259. <tbody>
  260. </tbody>
  261. </table>
  262. </div>
  263. </div>
  264. <div class="tab-pane" id="htfile">
  265. <div class="sp-wrap" style="overflow: auto">
  266. <table class="table table-sm table-bordered" id="htfile-table" style="display: none;">
  267. <thead>
  268. <tr class="text-center">
  269. <th width="5%">序号</th><th>名称</th><th width="5%">上传人</th><th width="15%">上传时间</th><th width="15%">操作</th>
  270. </tr>
  271. </thead>
  272. <tbody>
  273. </tbody>
  274. </table>
  275. </div>
  276. </div>
  277. <div class="tab-pane" id="htsupplement">
  278. <div class="sp-wrap" style="overflow: auto">
  279. <table class="table table-sm table-bordered" id="htsupplement-table" style="display: none;">
  280. <thead>
  281. <tr class="text-center" id="supplement-header">
  282. <th width="3%">序号</th><th width="5%" sort="code">编号</th><th width="8%">名称</th><th width="7%">金额</th><th width="8%">甲方</th><th width="8%">乙方</th><th width="5%">签订时间</th><th width="5%">签订地点</th><th width="5%">创建人</th><th width="9%" sort="create_time">创建时间</th><th width="10%">补充原因及内容</th><th width="4%">附件</th>
  283. <% if (shenpi_status) { %>
  284. <th width="15%">审批进度</th>
  285. <% } %>
  286. <th width="10%">操作</th>
  287. </tr>
  288. </thead>
  289. <tbody>
  290. </tbody>
  291. </table>
  292. </div>
  293. </div>
  294. </div>
  295. </div>
  296. </div>
  297. <div class="side-menu">
  298. <!--右侧菜单-->
  299. <ul class="nav flex-column right-nav">
  300. <li class="nav-item">
  301. <a class="nav-link" content="#contract-search" href="javascript: void(0);">查找定位</a>
  302. </li>
  303. <li class="nav-item">
  304. <a class="nav-link" content="#std-xmj" href="javascript: void(0);">项目节</a>
  305. </li>
  306. </ul>
  307. </div>
  308. </div>
  309. </div>
  310. </div>
  311. <script>
  312. const user_id = <%- ctx.session.sessionUser.accountId %>;
  313. const is_admin = <%- ctx.session.sessionUser.is_admin %>;
  314. const permission_edit = <%- (ctx.session.sessionUser.is_admin || audit_permission.permission_edit) %>;
  315. const permission_add = <%- (ctx.session.sessionUser.is_admin || audit_permission.permission_add) %>;
  316. const permission_att = <%- (ctx.session.sessionUser.is_admin || audit_permission.permission_att) %>;
  317. const permission_edit_contract = <%- (ctx.session.sessionUser.is_admin || audit_permission.permission_edit_contract) %>;
  318. const permission_add_pay = <%- (ctx.session.sessionUser.is_admin || audit_permission.permission_add_pay) %>;
  319. const contract_type = <%- contract_type %>;
  320. const whiteList = JSON.parse(unescape('<%- escape(JSON.stringify(whiteList)) %>'));
  321. const contractConst = JSON.parse(unescape('<%- escape(JSON.stringify(contractConst)) %>'));
  322. let contractTreeAudits = JSON.parse(unescape('<%- escape(JSON.stringify(contractTreeAudits)) %>'));
  323. const colSet = JSON.parse(unescape('<%- escape(JSON.stringify(colSet)) %>'));
  324. const contractColumnOptions = JSON.parse(unescape('<%- escape(JSON.stringify(contractColumnOptions)) %>'));
  325. const auditConst = JSON.parse(unescape('<%- escape(JSON.stringify(auditConst)) %>'));
  326. const shenpi_status = JSON.parse(unescape('<%- escape(JSON.stringify(shenpi_status)) %>'));
  327. const pay_shenpi_status = JSON.parse(unescape('<%- escape(JSON.stringify(pay_shenpi_status)) %>'));
  328. const shenpi = JSON.parse(unescape('<%- escape(JSON.stringify(shenpi)) %>'));
  329. const shenpiConst = JSON.parse(unescape('<%- escape(JSON.stringify(shenpiConst)) %>'));
  330. const auditType = JSON.parse(unescape('<%- escape(JSON.stringify(auditType)) %>'));
  331. const accountGroup3 = JSON.parse(unescape('<%- escape(JSON.stringify(accountGroup)) %>'));
  332. const accountList3 = JSON.parse(unescape('<%- escape(JSON.stringify(accountList)) %>'));
  333. const attributeSet = JSON.parse(unescape('<%- escape(JSON.stringify(attributeSet)) %>'));
  334. const thisUrl = JSON.parse(unescape('<%- escape(JSON.stringify(thisUrl)) %>'));
  335. const stdChapters = JSON.parse(unescape('<%- escape(JSON.stringify(stdChapters)) %>'));
  336. let types = JSON.parse(unescape('<%- escape(JSON.stringify(types)) %>'));
  337. types.push('');
  338. let contractPays = [];
  339. let contractSupplements = [];
  340. </script>
  341. <style>
  342. #contract-pay-operation,.contract-pay-operation-cell {
  343. white-space: nowrap;
  344. }
  345. </style>