dispatch.vue 12 KB

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