dispatch.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. <template>
  2. <basic-container>
  3. <div class="flex flex-col padding-left" style="width: 95%">
  4. <div class="text-left grey-6 font-18 bold">
  5. {{ year }}年{{ month }}月项目进度信息填报
  6. </div>
  7. <!------进度描述------>
  8. <div>
  9. <div class="flex flex-center flex-justify-between mt-20">
  10. <span class="bold font-18 main-color">进度描述</span>
  11. <div class="flex flex-center">
  12. <base-button
  13. type="0"
  14. title="批量导出"
  15. icon="upload"
  16. @click="exportFile"
  17. />
  18. <base-button
  19. class="ml-10"
  20. :title="btnTitle"
  21. icon="upload"
  22. @click="edit"
  23. />
  24. </div>
  25. </div>
  26. <div class="mt-20">
  27. <el-input
  28. v-model="progress"
  29. :rows="10"
  30. type="textarea"
  31. :disabled="btnTitle === '编辑'"
  32. placeholder="填写项目进度信息"
  33. />
  34. </div>
  35. </div>
  36. <!------相关文件------>
  37. <div class="mt-20">
  38. <div class="flex flex-center flex-justify-between mt-20">
  39. <span class="bold font-18 main-color">相关文件</span>
  40. </div>
  41. <avue-crud
  42. ref="crud"
  43. v-model="form"
  44. v-model:page="page"
  45. :data="data"
  46. :option="option"
  47. :table-loading="loading"
  48. class="curd"
  49. :before-open="beforeOpen"
  50. @row-del="rowDel"
  51. >
  52. <template #menu="{ row }">
  53. <el-button icon="Upload" type="primary" text @click="openFile(row)">
  54. 上传
  55. </el-button>
  56. <el-button
  57. text
  58. type="primary"
  59. icon="Download"
  60. @click="fileDownload(row)"
  61. >下载
  62. </el-button>
  63. </template>
  64. <template #menu-right>
  65. <div class="full-width">
  66. <el-button
  67. icon="el-icon-refresh"
  68. circle
  69. @click="detail"
  70. ></el-button>
  71. </div>
  72. </template>
  73. <template #isuploaded="{ row }">
  74. <div>
  75. {{ row.isUploaded === 1 ? '已上传' : '' }}
  76. </div>
  77. </template>
  78. <template #filefolder="{ row }">
  79. <div v-if="row.fileFolder">
  80. {{ row.fileFolder.title }}
  81. </div>
  82. </template>
  83. </avue-crud>
  84. </div>
  85. <!------现场图片------>
  86. <div class="mb-20">
  87. <div class="flex flex-center flex-justify-between mt-20">
  88. <span class="bold font-18 main-color">施工现场图</span>
  89. <div class="flex flex-center">
  90. <base-button
  91. type="0"
  92. title="上传"
  93. icon="upload"
  94. @click="
  95. openFile({
  96. dispatchType: 4
  97. })
  98. "
  99. />
  100. </div>
  101. </div>
  102. <div class="mt-20">
  103. <el-empty description="暂无施工现场图" v-if="srcList.length === 0" />
  104. <el-carousel
  105. v-else
  106. autoplay
  107. :interval="4000"
  108. type="card"
  109. height="400px"
  110. :initial-index="0"
  111. >
  112. <el-carousel-item v-for="(item, index) in srcList" :key="item">
  113. <el-image
  114. :src="item"
  115. fit="cover"
  116. @click="showImageView(item, index)"
  117. />
  118. </el-carousel-item>
  119. </el-carousel>
  120. </div>
  121. </div>
  122. </div>
  123. <el-image-viewer
  124. v-if="showImage"
  125. :url-list="preList"
  126. :initial-index="imageIndex"
  127. @close="showImage = false"
  128. />
  129. </basic-container>
  130. </template>
  131. <script>
  132. import BasicContainer from '@/components/basic-container/main.vue'
  133. import baseButton from '@/components/base-button.vue'
  134. import api from '@/api/index.js'
  135. export default {
  136. name: 'dispatch',
  137. components: { BasicContainer, baseButton },
  138. props: {
  139. year: {
  140. type: Number,
  141. default: 0
  142. },
  143. month: {
  144. type: Number,
  145. default: 0
  146. }
  147. },
  148. watch: {
  149. year: {
  150. handler(val) {
  151. if (val) {
  152. this.detail()
  153. }
  154. },
  155. immediate: false
  156. },
  157. month: {
  158. handler(val) {
  159. if (val) {
  160. this.detail()
  161. }
  162. },
  163. immediate: false
  164. }
  165. },
  166. data() {
  167. return {
  168. preList: [],
  169. projectId: '',
  170. btnTitle: '编辑',
  171. showImage: false,
  172. imageIndex: 0,
  173. progress: '',
  174. info: null,
  175. loading: false,
  176. srcList: [],
  177. data: [
  178. {
  179. fileName: '支付情况表',
  180. dispatchType: 1
  181. },
  182. {
  183. fileName: '工程完工月报表',
  184. dispatchType: 2
  185. },
  186. {
  187. fileName: '工程量清单',
  188. dispatchType: 3
  189. }
  190. ],
  191. form: {},
  192. option: {
  193. menuBtnTitle: '操作',
  194. refreshBtn: false,
  195. tip: false,
  196. columnBtn: false,
  197. selection: false,
  198. editBtn: true,
  199. editBtnText: '打开',
  200. editBtnIcon: 'FolderOpened',
  201. addBtn: false,
  202. delBtn: true,
  203. border: true,
  204. reserveSelection: true,
  205. align: 'center',
  206. viewBtn: true,
  207. menuWidth: 500,
  208. viewBtnText: '预览',
  209. dialogClickModal: false,
  210. column: [
  211. {
  212. label: '文件类别',
  213. prop: 'fileName'
  214. },
  215. {
  216. label: '文件名称',
  217. prop: 'fileFolder',
  218. slot: true
  219. },
  220. {
  221. label: '上传状态',
  222. prop: 'isUploaded',
  223. slot: true
  224. },
  225. {
  226. label: '上传时间',
  227. prop: 'createTime'
  228. }
  229. ]
  230. },
  231. images: []
  232. }
  233. },
  234. created() {
  235. this.projectId = this.$route.query.id
  236. this.detail()
  237. },
  238. methods: {
  239. detail() {
  240. this.data = [
  241. {
  242. fileName: '支付情况表',
  243. dispatchType: 1
  244. },
  245. {
  246. fileName: '工程完工月报表',
  247. dispatchType: 2
  248. },
  249. {
  250. fileName: '工程量清单',
  251. dispatchType: 3
  252. }
  253. ]
  254. this.srcList.length = 0
  255. const data = {
  256. projectId: this.projectId,
  257. year: this.year,
  258. month: this.month
  259. }
  260. this.$api.dispatch.home(data).then(res => {
  261. if (res.code === 200) {
  262. this.progress = res.data.processDescribe
  263. this.info = res.data
  264. } else {
  265. this.$message.error(res.msg)
  266. }
  267. })
  268. this.$api.dispatch.homeFile(data).then(res => {
  269. if (res.code === 200) {
  270. const tmp = res.data
  271. if (tmp && tmp.length > 0) {
  272. this.data = this.data.map(sub => {
  273. const item = tmp.find(ele => ele.type === sub.dispatchType)
  274. if (item) {
  275. sub = Object.assign(sub, item)
  276. }
  277. return sub
  278. })
  279. const img = tmp.filter(ele => ele.type === 4)
  280. if (img && img.length > 0) {
  281. img.forEach(i => {
  282. this.srcList.push(i.fileFolder.url)
  283. })
  284. }
  285. }
  286. } else {
  287. this.$message.error(res.msg)
  288. }
  289. })
  290. },
  291. showImageView(res, index) {
  292. this.preList = this.srcList
  293. this.imageIndex = index
  294. this.showImage = true
  295. },
  296. edit() {
  297. if (this.btnTitle === '保存' && this.progress.length > 0) {
  298. const data = {
  299. projectId: this.projectId,
  300. year: this.year,
  301. month: this.month,
  302. processDescribe: this.progress,
  303. id: this.info ? this.info.id : ''
  304. }
  305. this.$api.dispatch.saveOrUpdate(data).then(res => {
  306. if (res.code === 200) {
  307. console.log(res)
  308. this.$message.success(res.msg)
  309. } else {
  310. this.$message.error(res.msg)
  311. }
  312. })
  313. }
  314. this.btnTitle = this.btnTitle === '编辑' ? '保存' : '编辑'
  315. },
  316. beforeOpen(done, type) {
  317. if (type === 'view') {
  318. this.previewFile(this.form)
  319. } else if (type === 'edit') {
  320. if (!Object.hasOwn(this.form, 'fileFolder')) {
  321. this.$message.error('暂无文件')
  322. return
  323. }
  324. this.$router.push({
  325. path: '/home/files',
  326. query: {
  327. id: this.form.fileFolder.parentId,
  328. projectId: this.projectId
  329. }
  330. })
  331. } else {
  332. done()
  333. }
  334. },
  335. previewFile(item) {
  336. if (item.id === undefined || item.length === 0) {
  337. this.$message.error('暂无文件')
  338. return
  339. }
  340. if (api.offices.includes(item.fileFolder.suffix)) {
  341. const routeData = this.$router.resolve({
  342. path: '/home/file_detail',
  343. query: { id: item.fileFolder.fileId }
  344. })
  345. window.open(routeData.href, '_blank')
  346. } else {
  347. this.preList.length = 0
  348. this.preList.push(item.fileFolder.url)
  349. this.showImage = true
  350. }
  351. },
  352. rowDel(row, index, done) {
  353. if (!Object.hasOwn(row, 'fileFolder')) {
  354. this.$message.error('暂无文件')
  355. return
  356. }
  357. this.$confirm('确定将选择数据删除?', {
  358. confirmButtonText: '确定',
  359. cancelButtonText: '取消',
  360. type: 'warning'
  361. }).then(() => {
  362. this.$api.project.fileRemove({ ids: row.fileId, type: 2 }).then(res => {
  363. if (res.code === 200) {
  364. this.$message.success(res.msg)
  365. this.detail()
  366. } else {
  367. this.$message.error(res.msg)
  368. }
  369. })
  370. })
  371. },
  372. openFile(row) {
  373. const routeUrl = this.$router.resolve({
  374. path: '/home/details',
  375. query: {
  376. id: this.projectId,
  377. dispatchType: row.dispatchType,
  378. type: 2,
  379. year: this.year,
  380. month: this.month
  381. }
  382. })
  383. window.open(routeUrl.href, '_blank')
  384. },
  385. fileDownload(res) {
  386. if (Object.hasOwn(res, 'fileFolder')) {
  387. window.open(res.fileFolder.url)
  388. } else {
  389. this.$message.error('暂无文件')
  390. }
  391. },
  392. exportFile() {
  393. const data = {
  394. projectId: this.projectId,
  395. year: this.year,
  396. month: this.month
  397. }
  398. this.$api.dispatch.exportFile(data).then(res => {
  399. if (res.size === 0) {
  400. this.$message.error('下载错误,请稍后再试...')
  401. return
  402. }
  403. this.$message.success('开始下载,请稍后...')
  404. this.download(res)
  405. })
  406. },
  407. download(res) {
  408. const url = window.URL.createObjectURL(
  409. new Blob([res], { type: 'application/octet-stream;charset=UTF-8' })
  410. )
  411. const link = document.createElement('a')
  412. link.style.display = 'none'
  413. link.href = url
  414. const excelName = this.year + '年' + this.month + '月.zip'
  415. link.setAttribute('download', excelName)
  416. document.body.appendChild(link)
  417. link.click()
  418. link.remove()
  419. this.diaType = -1
  420. this.$message.success('导出成功')
  421. }
  422. }
  423. }
  424. </script>
  425. <style scoped></style>