index.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. <template>
  2. <HcPageLayout id="hc-settle-node-target">
  3. <template #left>
  4. <div class="hc-layout-tree-box">
  5. <el-scrollbar>
  6. <HcTreeData @nodeTap="treeNodeTap" />
  7. </el-scrollbar>
  8. </div>
  9. </template>
  10. <HcCard>
  11. <template #header>
  12. <div class="w-32">
  13. <el-select v-model="searchForm.type" block clearable placeholder="补偿类型" size="large" @change="changType">
  14. <el-option label="征地补偿" value="1" />
  15. <el-option label="坟地补偿" value="2" />
  16. <el-option label="专项补偿" value="3" />
  17. </el-select>
  18. </div>
  19. <div class="w-32 ml-2">
  20. <el-select v-model="searchForm.stageId" block clearable placeholder="计量期" size="large">
  21. <el-option v-for="item in numberOptions" :key="item.id" :label="item.number" :value="item.id" />
  22. </el-select>
  23. </div>
  24. <div class="w-52 ml-2">
  25. <el-input v-model="searchForm.queryValue" clearable placeholder="请输入名称进行查询" size="large" />
  26. </div>
  27. <div class="ml-4">
  28. <el-button type="primary" size="large" @click="searchClick">
  29. <HcIcon name="search-2" />
  30. <span>搜索</span>
  31. </el-button>
  32. </div>
  33. </template>
  34. <template #extra>
  35. <el-button size="large" type="primary" hc-btn @click="addRowClick">
  36. 新增结算
  37. </el-button>
  38. <el-button size="large" type="success" hc-btn @click="editingClick">
  39. 编辑结算周期
  40. </el-button>
  41. <el-button size="large" type="warning" hc-btn @click="cycleClick">
  42. 查看报表
  43. </el-button>
  44. <el-button size="large" type="danger" hc-btn :disabled="tableCheckedKeys.length < 1" @click="batchDel">
  45. 批量删除
  46. </el-button>
  47. </template>
  48. <HcTable :column="tableColumn" :datas="tableData" :loading="tableLoading" is-check @selection-change="tableSelectionChange">
  49. <template #key3="{ row, index }">
  50. <span class="text-blue text-hover">{{ row.key3 }}</span>
  51. </template>
  52. <template #action="{ row, index }">
  53. <el-button size="small" type="primary" @click="editRowClick(row)">
  54. 修改
  55. </el-button>
  56. <el-button size="small" type="danger" @click="delRowClick(row)">
  57. 删除
  58. </el-button>
  59. </template>
  60. </HcTable>
  61. <template #action>
  62. <HcPages :pages="searchForm" @change="pageChange" />
  63. </template>
  64. </HcCard>
  65. <!-- 抽屉 -->
  66. <HcDrawer :show="isDrawer" uis="hc-settle-drawer" to-id="hc-main-box" @close="drawerClose">
  67. <div class="hc-settle-drawer-box">
  68. <div class="settle-left-box">
  69. <div class="settle-pdf">
  70. <HcPdf src="http://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230504/911982ba85e66cfa58fb02d5a738bb2b.pdf" />
  71. </div>
  72. </div>
  73. <div class="settle-right-box">
  74. <div class="settle-right">
  75. <div class="hc-settle-cycle">
  76. <div class="title">
  77. 结算周期
  78. </div>
  79. <div class="cycle-box">
  80. <el-scrollbar>
  81. <div class="item">
  82. 第一期
  83. </div>
  84. <div class="item">
  85. 第一期
  86. </div>
  87. <div class="item">
  88. 第一期
  89. </div>
  90. <div class="item">
  91. 第一期
  92. </div>
  93. </el-scrollbar>
  94. </div>
  95. </div>
  96. <div class="hc-settle-cycle of">
  97. <div class="title">
  98. 结算报表名称
  99. </div>
  100. <div class="cycle-box">
  101. <el-scrollbar>
  102. <div class="item">
  103. 封面
  104. </div>
  105. <div class="item">
  106. 补偿结算表
  107. </div>
  108. <div class="item">
  109. 补偿明细表
  110. </div>
  111. <div class="item">
  112. 面积统计明细表
  113. </div>
  114. </el-scrollbar>
  115. </div>
  116. </div>
  117. <div class="hc-settle-btn">
  118. <el-button type="primary" hc-btn size="large" @click="drawerClose">
  119. 取 消 查 阅
  120. </el-button>
  121. </div>
  122. </div>
  123. </div>
  124. </div>
  125. </HcDrawer>
  126. <!-- 新增结算单 -->
  127. <HcDialog is-to-body bg-color="white" is-table widths="80%" :title="addTitle" :padding="false" :show="rowModal" :loading="addLoaing" @save="rowModalSave" @close="rowModalClose">
  128. <div class="hc-settle-dialog-box">
  129. <div id="settle-dialog-tree" class="hc-settle-dialog-tree">
  130. <el-scrollbar>
  131. <HcTreeData :is-menu="false" @nodeTap="treeNodeTap1" />
  132. </el-scrollbar>
  133. </div>
  134. <div id="settle-dialog-table" class="hc-settle-dialog-table">
  135. <div class="dialog-table-header">
  136. <i class="ri-asterisk" style="color:red;line-height: 40px;padding-right: 5px;" />
  137. <div class="w-44">
  138. <el-select v-model="jqnumber" block clearable placeholder="请选择结算期数" size="large">
  139. <el-option v-for="item in numberOptions" :key="item.id" :label="item.number" :value="item.number" />
  140. </el-select>
  141. </div>
  142. <div class="w-32 ml-8" style="position: absolute; right: 320px;">
  143. <el-select v-model="searchForm1.type" block clearable placeholder="补偿类型" size="large" @change="changType">
  144. <el-option label="征地补偿" value="1" />
  145. <el-option label="坟地补偿" value="2" />
  146. <el-option label="专项补偿" value="3" />
  147. </el-select>
  148. </div>
  149. <div class="w-52 ml-2" style="position: absolute; right: 100px;">
  150. <el-input v-model="searchForm1.number" clearable placeholder="请输入协议编号进行查询" size="large" />
  151. </div>
  152. <div class="ml-4" style="position: absolute; right: 0;">
  153. <el-button type="primary" size="large" @click="searchClick1">
  154. <HcIcon name="search-2" />
  155. <span>搜索</span>
  156. </el-button>
  157. </div>
  158. </div>
  159. <div class="dialog-table-body">
  160. <HcTable ref="addTableRef" :column="tableColumn1" :datas="tableData1" is-check @selection-change="tableSelectionChange" />
  161. </div>
  162. </div>
  163. </div>
  164. </HcDialog>
  165. <!-- 结算周期编辑 -->
  166. <HcDialog is-to-body bg-color="white" is-table widths="80%" title="编辑结算周期" :show="editingModal" @save="editingModalSave" @close="editingModalClose">
  167. <div class="hc-settle-editing-dialog-box">
  168. <div class="editing-dialog-tip">
  169. <div class="name">
  170. 提示:
  171. </div>
  172. <div class="content">
  173. <div class="item truncate">
  174. 1.日期不能为空
  175. </div>
  176. <div class="item truncate">
  177. 2.同一期的结束日期不能小于开始日期
  178. </div>
  179. <div class="item truncate">
  180. 3.连续的两期,上一期结束日期和下一期的开始日期必须连续,如:期号1的结束日期为2018-1-25,则期号2的开始日期必须是2018-1-26 !
  181. </div>
  182. <div class="item truncate text-orange">
  183. 4.已经存在数据的结算周期不能进行删除以及修改结算类型!
  184. </div>
  185. </div>
  186. <div class="btn">
  187. <el-button type="primary" size="large" @click="addInRow">
  188. <HcIcon name="add" />
  189. <span>添加</span>
  190. </el-button>
  191. </div>
  192. </div>
  193. <div class="editing-dialog-table">
  194. <HcTable :is-index="false" :column="tableColumn2" :datas="tableData2">
  195. <template #number="{ row, index }">
  196. <el-input v-model="row.number" />
  197. </template>
  198. <template #startDate="{ row, index }">
  199. <el-date-picker v-model="row.startDate" class="block" format="YYYY-MM-DD" type="date" value-format="YYYY-MM-DD" @change="checkTime(row)" />
  200. </template>
  201. <template #endDate="{ row, index }">
  202. <el-date-picker v-model="row.endDate" class="block" format="YYYY-MM-DD" type="date" value-format="YYYY-MM-DD" @change="checkTime(row)" />
  203. </template>
  204. <template #printDate="{ row, index }">
  205. <el-date-picker v-model="row.printDate" class="block" format="YYYY-MM-DD" type="date" value-format="YYYY-MM-DD" />
  206. </template>
  207. <template #remark="{ row, index }">
  208. <el-input v-model="row.remark" />
  209. </template>
  210. <template #action="{ row, index }">
  211. <el-button size="small" type="danger" :loading="delInLoad" @click="delInRow(row, index)">
  212. 删除
  213. </el-button>
  214. </template>
  215. </HcTable>
  216. </div>
  217. </div>
  218. </HcDialog>
  219. </HcPageLayout>
  220. </template>
  221. <script setup>
  222. import { nextTick, onUnmounted, ref } from 'vue'
  223. import split from 'split.js'
  224. import settleApi from '~api/settle/index.js'
  225. import { arrToId, getArrValue } from 'js-fast-way'
  226. import { useAppStore } from '~src/store'
  227. import { delMessageV2 } from '~com/message/index.js'
  228. const useAppState = useAppStore()
  229. const projectId = ref(useAppState.getProjectId)
  230. //树节点被点击
  231. const treeNodeTap = ({ node, data }) => {
  232. searchForm.value.areaId = data.id
  233. getTableData()
  234. }
  235. //搜索表单
  236. const searchForm = ref({
  237. projectType: null, queryValue: null, startTime: null, endTime: null,
  238. current: 1, size: 20, total: 0,
  239. })
  240. //搜索
  241. const searchClick = () => {
  242. searchForm.value.current = 1
  243. getTableData()
  244. }
  245. const searchClick1 = () => {
  246. searchForm1.value.current = 1
  247. getTableData1()
  248. }
  249. //分页被点击
  250. const pageChange = ({ current, size }) => {
  251. searchForm.value.current = current
  252. searchForm.value.size = size
  253. getTableData()
  254. }
  255. //获取数据
  256. const tableLoading = ref(false)
  257. const tableColumn = [
  258. { key: 'stage', name: '计量期' },
  259. { key: 'name', name: '结算协议书名称' },
  260. { key: 'type', name: '协议书类型' },
  261. { key: 'agreementMoney', name: '协议书金额' },
  262. { key: 'action', name: '操作', width: '130', align: 'center' },
  263. ]
  264. const tableData = ref([
  265. ])
  266. const getTableData = async () => {
  267. tableLoading.value = true
  268. const { error, code, data } = await settleApi.getOutPage({
  269. projectId: projectId.value,
  270. ...searchForm.value,
  271. })
  272. tableLoading.value = false
  273. if (!error && code === 200) {
  274. tableData.value = getArrValue(data['records'])
  275. } else {
  276. tableData.value = []
  277. }
  278. }
  279. //多选事件
  280. const tableCheckedKeys = ref([])
  281. const tableSelectionChange = (rows) => {
  282. tableCheckedKeys.value = rows
  283. }
  284. //结算周期
  285. const isDrawer = ref(false)
  286. const cycleClick = () => {
  287. isDrawer.value = true
  288. }
  289. const drawerClose = () => {
  290. isDrawer.value = false
  291. }
  292. //弹窗
  293. const rowModal = ref(false)
  294. const formModel = ref({})
  295. const addTitle = ref('新增结算单')
  296. // 初始化设置拖动分割线
  297. const splitvar = ref(null)
  298. const setSplitDom = () => {
  299. try {
  300. //配置参考: https://split.js.org/#/?direction=vertical&snapOffset=0
  301. splitvar.value = split([
  302. '#settle-dialog-tree',
  303. '#settle-dialog-table',
  304. ], {
  305. sizes: [20, 80],
  306. minSize: [200, 900],
  307. })
  308. } catch (e) {
  309. setTimeout(() => {
  310. setSplitDom()
  311. }, 500)
  312. }
  313. }
  314. const tableColumn1 = [
  315. { key: 'number', name: '协议书编号' },
  316. { key: 'name', name: '结算协议书名称' },
  317. { key: 'allMoney', name: '协议书补偿金额(元)' },
  318. ]
  319. const tableData1 = ref([])
  320. const addTableRef = ref(null)
  321. const searchForm1 = ref({ type:'1' })
  322. const tableLoading1 = ref(false)
  323. const getTableData1 = async () => {
  324. tableLoading1.value = true
  325. const { error, code, data } = await settleApi.getAgreementList({
  326. projectId: projectId.value,
  327. ...searchForm1.value,
  328. agreementIds:rowagreementIds.value,
  329. })
  330. tableLoading1.value = false
  331. if (!error && code === 200) {
  332. tableData1.value = getArrValue(data)
  333. let item = tableData1.value.filter(item=>item.isQuote === 1)
  334. await nextTick()
  335. item.forEach((ele)=>{
  336. addTableRef.value.toggleRowSelection(ele, true)
  337. })
  338. } else {
  339. tableData1.value = []
  340. }
  341. }
  342. const treeNodeTap1 = ({ node, data }) => {
  343. searchForm1.value.areaId = data.id
  344. getTableData1()
  345. }
  346. //新增
  347. const addRowClick = () => {
  348. formModel.value = {}
  349. rowModal.value = true
  350. addTitle.value = '新增结算单'
  351. searchForm1.value.type = '1'
  352. rowagreementIds.value = ''
  353. searchForm1.value.number = ''
  354. changType('1')
  355. getTableData1()
  356. nextTick(() => {
  357. setSplitDom()
  358. })
  359. }
  360. //编辑
  361. const rowagreementIds = ref('')
  362. const editId = ref('')
  363. const editRowClick = (row) => {
  364. rowagreementIds.value = row.agreementIds
  365. searchForm1.value.type = row.type.toString()
  366. changType( searchForm1.value.type)
  367. jqnumber.value = row.stage
  368. editId.value = row.id
  369. addTitle.value = '修改结算单'
  370. formModel.value = {}
  371. rowModal.value = true
  372. nextTick(() => {
  373. setSplitDom()
  374. })
  375. }
  376. //删除协议
  377. const delRowClick = (row)=>{
  378. delMessageV2(async (action, instance, done) => {
  379. if (action === 'confirm') {
  380. instance.confirmButtonLoading = true
  381. removeRow(row.id)
  382. instance.confirmButtonLoading = false
  383. done()
  384. } else {
  385. done()
  386. }
  387. })
  388. }
  389. //批量删除
  390. const batchDel = ()=>{
  391. const ids = arrToId(tableCheckedKeys.value)
  392. delMessageV2(async (action, instance, done) => {
  393. if (action === 'confirm') {
  394. instance.confirmButtonLoading = true
  395. removeRow(ids)
  396. instance.confirmButtonLoading = false
  397. done()
  398. } else {
  399. done()
  400. }
  401. })
  402. }
  403. const removeRow = async (id)=>{
  404. const { error, code } = await settleApi.remove( { ids:id })
  405. //判断状态
  406. if (!error && code === 200) {
  407. window.$message?.success('删除成功')
  408. getTableData()
  409. } else {
  410. window.$message?.error('删除失败')
  411. }
  412. }
  413. //保存
  414. const addLoaing = ref(false)
  415. const rowModalSave = async () => {
  416. const agreementIds = arrToId(tableCheckedKeys.value)
  417. const stage = jqnumber.value
  418. let stageId = ''
  419. numberOptions.value.forEach((ele)=>{
  420. if ( ele.number === stage) {
  421. stageId = ele.id
  422. }
  423. })
  424. if (!stage) {
  425. window.$message.warning('请选择结算期数')
  426. } else if (!agreementIds) {
  427. window.$message.warning('请选择协议书')
  428. } else {
  429. addLoaing.value = true
  430. const { error, code, msg } = await settleApi.addOrUpdateAgree({
  431. projectId: projectId.value,
  432. type:searchForm1.value.type,
  433. areaId:searchForm1.value.areaId,
  434. stage:stage,
  435. stageId:stageId,
  436. agreementIds:agreementIds,
  437. id:editId.value,
  438. })
  439. addLoaing.value = false
  440. if (!error && code === 200) {
  441. window.$message.success(msg)
  442. getTableData()
  443. rowModal.value = false
  444. }
  445. }
  446. }
  447. //关闭弹窗
  448. const rowModalClose = () => {
  449. rowModal.value = false
  450. formModel.value = {}
  451. }
  452. const editingModal = ref(false)
  453. const tableColumn2 = [
  454. { key: 'number', name: '期号' },
  455. { key: 'startDate', name: '开始日期' },
  456. { key: 'endDate', name: '结束日期' },
  457. { key: 'printDate', name: '报表打印日期' },
  458. { key: 'remark', name: '备注' },
  459. { key: 'action', name: '操作', width: '90', align: 'center' },
  460. ]
  461. const tableData2 = ref([
  462. ])
  463. const getTableData2 = async () => {
  464. tableLoading.value = true
  465. const { error, code, data } = await settleApi.getPage({
  466. projectId: projectId.value,
  467. type:searchForm.value.type,
  468. })
  469. tableLoading.value = false
  470. if (!error && code === 200) {
  471. tableData2.value = getArrValue(data)
  472. } else {
  473. tableData2.value = []
  474. }
  475. }
  476. //获取期数
  477. const numberOptions = ref([])
  478. const jqnumber = ref('')//计量期
  479. const changType = async (val)=>{
  480. jqnumber.value = ''
  481. const { error, code, data } = await settleApi.getPage({
  482. projectId: projectId.value,
  483. type:val,
  484. })
  485. tableLoading.value = false
  486. if (!error && code === 200) {
  487. numberOptions.value = getArrValue(data)
  488. } else {
  489. numberOptions.value = []
  490. }
  491. }
  492. //编辑结算周期
  493. const editingClick = () => {
  494. if (searchForm.value.type) {
  495. editingModal.value = true
  496. getTableData2()
  497. } else {
  498. window.$message.warning('请选择补偿类型')
  499. }
  500. }
  501. //添加
  502. const addInRow = ()=>{
  503. tableData2.value.push({})
  504. }
  505. const editingModalSave = async () => {
  506. tableData2.value.forEach((ele)=>{
  507. ele.type = searchForm.value.type
  508. ele.projectId = projectId.value
  509. })
  510. if (tableData2.value.length > 0) {
  511. const { error, code, data, msg } = await settleApi.addOrUpdate({
  512. list: tableData2.value,
  513. })
  514. if (!error && code === 200) {
  515. window.$message.success(msg)
  516. editingModal.value = false
  517. }
  518. } else {
  519. window.$message.warning('请先填数据')
  520. }
  521. }
  522. //时间限制
  523. const checkTime = (row) =>{
  524. if (row.startDate && row.endDate) {
  525. const startTime = new Date( row.startDate)
  526. const endTime = new Date( row.endDate)
  527. if (endTime < startTime) {
  528. window.$message.error('结束时间不能早于开始时间')
  529. // 清空结束时间
  530. row.endDate = ''
  531. }
  532. }
  533. }
  534. //删除结算周期
  535. const delInLoad = ref(false)
  536. const delInRow = async (row, index)=>{
  537. delInLoad.value = true
  538. const { error, code, data, msg } = await settleApi.delete({
  539. id: row.id,
  540. })
  541. delInLoad.value = false
  542. if (!error && code === 200) {
  543. window.$message.success(msg)
  544. tableData2.value.splice(index, 1)
  545. }
  546. }
  547. const editingModalClose = () => {
  548. editingModal.value = false
  549. }
  550. //销毁
  551. onUnmounted(() => {
  552. if (splitvar.value) {
  553. splitvar.value.destroy()
  554. }
  555. })
  556. </script>
  557. <style lang="scss" scoped>
  558. @import "~src/styles/settle/index.scoped.scss";
  559. </style>
  560. <style lang="scss">
  561. @import "~src/styles/settle/index.scss";
  562. </style>