index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. <template>
  2. <div style="height:100%;padding:0 20px;">
  3. <el-tabs class="impTabs" v-model="activeTab">
  4. <el-tab-pane label="导入批次" name="import">
  5. <tf-page class="pagePanel">
  6. <template #action>
  7. <el-form :inline="true">
  8. <el-form-item label="所属项目">
  9. <el-select v-model="searchInfo.project" size="small" clearable>
  10. <el-option v-for="item of projects" :key="item.id" :value="item.id" :label="item.name"></el-option>
  11. </el-select>
  12. </el-form-item>
  13. <!-- <el-form-item label="导入状态">
  14. <el-select v-model="searchInfo.status" size="small" clearable>
  15. <el-option v-for="item of status" :key="item.id" :value="item.id" :label="item.name"></el-option>
  16. </el-select>
  17. </el-form-item> -->
  18. <el-form-item label="导入时间">
  19. <el-date-picker value-format='yyyy-MM-dd HH:mm:ss' type="datetimerange" size="small" v-model="searchInfo.timeRange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
  20. </el-date-picker>
  21. </el-form-item>
  22. <el-form-item>
  23. <el-button type="primary" size="mini" icon="el-icon-search" @click="batchinfoPage">查询</el-button>
  24. </el-form-item>
  25. <el-form-item>
  26. <el-button type="primary" size="mini" @click="showAddDialog">数据导入</el-button>
  27. <!-- <el-button size="mini" icon="el-icon-search">模板导出</el-button> -->
  28. </el-form-item>
  29. </el-form>
  30. </template>
  31. <tf-table :pagination="batchPagination" @page-change="batchOnPageChange" :columns="columns" :data="list">
  32. <el-table-column label="操作">
  33. <template slot-scope="scope">
  34. <el-button type="text" size="small" @click="viewProjectInfo(scope.row)">详情</el-button>
  35. <!-- <el-button type="text" size="small">重新录入</el-button> -->
  36. </template>
  37. </el-table-column>
  38. </tf-table>
  39. </tf-page>
  40. </el-tab-pane>
  41. <el-tab-pane label="检测数据" name="list">
  42. <tf-page class="pagePanel">
  43. <template #action>
  44. <el-form :inline="true" class="dataSearchForm">
  45. <el-form-item label="所属项目">
  46. <el-select v-model="dataSeachInfo.project" size="small" clearable>
  47. <el-option v-for="item of projects" :key="item.id" :value="item.id" :label="item.name"></el-option>
  48. </el-select>
  49. </el-form-item>
  50. <el-form-item label="批次号">
  51. <el-input v-model="dataSeachInfo.pici" size="small"></el-input>
  52. </el-form-item>
  53. <el-form-item label="行政区">
  54. <el-select v-model="dataSeachInfo.region" size="small" clearable>
  55. <el-option v-for="item of districts" :key="item.id" :value="item.id" :label="item.name"></el-option>
  56. </el-select>
  57. </el-form-item>
  58. <!-- <el-form-item label="数据状态">
  59. <el-select v-model="dataSeachInfo.status" size="small" clearable>
  60. <el-option v-for="item of projects" :key="item.id" :value="item.id" :label="item.name"></el-option>
  61. </el-select>
  62. </el-form-item> -->
  63. <el-form-item label="起点编号">
  64. <el-input v-model="dataSeachInfo.s_code" size="small"></el-input>
  65. </el-form-item>
  66. <el-form-item label="终点编号">
  67. <el-input v-model="dataSeachInfo.e_code" size="small"></el-input>
  68. </el-form-item>
  69. <el-form-item label="导入时间">
  70. <el-date-picker value-format='yyyy-MM-dd HH:mm:ss' type="datetimerange" size="small" v-model="dataSeachInfo.timeRange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
  71. </el-date-picker>
  72. </el-form-item>
  73. <el-form-item>
  74. <el-button type="primary" size="mini" icon="el-icon-search" @click="getDataList">查询</el-button>
  75. </el-form-item>
  76. </el-form>
  77. </template>
  78. <tf-table :columns="dataColumns" :data="dataList" :pagination="pagination" @page-change="onPageChange">
  79. <!-- <template>
  80. <el-button type="text" size="small">校对</el-button>
  81. </template> -->
  82. </tf-table>
  83. </tf-page>
  84. </el-tab-pane>
  85. </el-tabs>
  86. <tf-dialog :close-on-click-modal='false' :close-on-press-escape='false' height="600px" title="检测数据导入" :visible.sync='isAddDialogShow' class="addDialog" width="1000px">
  87. <el-steps simple :active="importStep" finish-status="success" v-if="formType==='add'">
  88. <el-step title="上传导入文件"></el-step>
  89. <el-step title="导入数据"></el-step>
  90. <el-step title="导入完成"></el-step>
  91. </el-steps>
  92. <div v-if="importStep==0">
  93. <el-form :model="addForm" ref='addForm' label-width="100px" :rules="addRules" :disabled="formType==='edit'">
  94. <tf-title>项目信息</tf-title>
  95. <el-row>
  96. <el-col :span="12">
  97. <el-form-item label="数据类型" prop="type">
  98. <el-select v-model="addForm.type" size="small" clearable>
  99. <el-option label="检测数据" value="tc"></el-option>
  100. </el-select>
  101. </el-form-item>
  102. </el-col>
  103. <el-col :span="12">
  104. <el-form-item label="所属项目" prop="project">
  105. <el-select v-model="addForm.project" size="small" clearable>
  106. <el-option v-for="item of projects" :key="item.id" :value="item.id" :label="item.name"></el-option>
  107. </el-select>
  108. </el-form-item>
  109. </el-col>
  110. </el-row>
  111. <el-row>
  112. <el-col :span="12">
  113. <el-form-item label="行政区" prop="district">
  114. <el-select v-model="addForm.district" size="small" clearable>
  115. <el-option v-for="item of districts" :key="item.id" :value="item.id" :label="item.name"></el-option>
  116. </el-select>
  117. </el-form-item>
  118. </el-col>
  119. <el-col :span="12">
  120. <el-form-item label="单位" prop="tcUnit">
  121. <el-select v-model="addForm.tcUnit" size="small" clearable>
  122. <el-option v-for="item of departments" :key="item.id" :value="item.id" :label="item.name"></el-option>
  123. </el-select>
  124. </el-form-item>
  125. </el-col>
  126. </el-row>
  127. <tf-title>附件</tf-title>
  128. <el-row>
  129. <el-upload class="upload-demo" action="https://jsonplaceholder.typicode.com/posts/" :on-preview="handlePreview" :on-remove="handleRemove" :before-remove="beforeRemove" :on-change="beforeAvatarUpload" :on-success="handleAvatarSuccess" accept=".jpg,.jpeg,.png,.pdf,.doc,.xls,.xlsx" :file-list="fileList" :auto-upload="false" multiple :limit="3" :on-exceed="handleExceed" size="small">
  130. <el-button size="small" type="primary" style="margin-top: 3px; left:0px; float:left; ">点击上传</el-button>
  131. <div slot="tip" class="el-upload__tip">
  132. ⚠️注意:请上传jpg,png,jpeg,pdf,excel,word格式的文件,且大小不能超过10MB!最多3个文件!
  133. </div>
  134. </el-upload>
  135. </el-row>
  136. </el-form>
  137. </div>
  138. <div v-else-if="importStep==1">
  139. <el-result title="导入中......" subTitle="">
  140. <template slot="icon">
  141. <i class="el-icon-loading"></i>
  142. </template>
  143. </el-result>
  144. </div>
  145. <div v-else-if="importStep==2">
  146. <el-result icon="success" title="导入成功" subTitle="">
  147. <template slot="extra">
  148. <el-button type="primary" size="medium" @click="isAddDialogShow = false">关闭</el-button>
  149. </template>
  150. </el-result>
  151. </div>
  152. <div slot="footer" style="text-align:right;" v-show="importStep===0&&formType==='add'">
  153. <el-button @click="isAddDialogShow = false" size="small">取 消</el-button>
  154. <el-button type="primary" @click="addSubmit()" size="small">确 定</el-button>
  155. </div>
  156. </tf-dialog>
  157. </div>
  158. </template>
  159. <script lang="ts">
  160. /**
  161. * @description 检测数据导入
  162. * @author lishun <876330731@qq.com>
  163. */
  164. import { Vue, Component,Watch } from 'vue-property-decorator'
  165. import { batchinfoPage, checkDataImport,checkdataPage } from '@/api/dataCheckModule/dataImport'
  166. import { uploadFile, getAllDepartments } from '@/api/base'
  167. import { projectPage } from '@/api/dataCheckModule/projectList'
  168. import { getDefaultPagination } from '@/utils/constant'
  169. import { districts } from '@/views/zhpt/dataImport/common/constant'
  170. import { ElForm } from 'element-ui/types/form'
  171. @Component({
  172. name: 'JianCeDataImport'
  173. })
  174. export default class JianCeDataImport extends Vue {
  175. /**数据导入列名 */
  176. columns = [
  177. { type: 'index', label: '序号' },
  178. { prop: 'prjName', label: '所属项目' },
  179. { prop: 'district', label: '行政区' },
  180. { prop: 'batchNo', label: '批次号' },
  181. { prop: 'departmentName', label: '单位' },
  182. { prop: 'dataCount', label: '总数据量' },
  183. // { prop: 'wrongData', label: '异常数据' },
  184. // { prop: 'status', label: '导入状态' },
  185. { prop: 'createUser', label: '操作人' },
  186. { prop: 'createTime', label: '操作时间' }
  187. ]
  188. /**数据列名 */
  189. dataColumns = [
  190. { type: 'index', label: '序号' },
  191. { prop: 'batchinfo.prjName', label: '所属项目', width: '100px' },
  192. { prop: 'batchinfo.batchNo', label: '批次号', width: '150px' },
  193. { prop: 'area', label: '行政区' },
  194. { prop: 'testingZone', label: '测区' },
  195. { prop: 'pipeProperties', label: '管段属性' },
  196. { prop: 'roadName', label: '道路名称', showOverflowTooltip: true },
  197. { prop: 'startCode', label: '起点编码', showOverflowTooltip: true },
  198. { prop: 'endCode', label: '终点编码', showOverflowTooltip: true },
  199. { prop: 'pipeLength', label: '管道长度(m)', width: '150px' },
  200. { prop: 'sectionDataOne', label: '断面数据1', width: '150px' },
  201. { prop: 'sectionDataTwo', label: '断面数据2', width: '150px' },
  202. { prop: 'videoTime', label: '视频显示时间', width: '150px' },
  203. { prop: 'videoSectionDataOne', label: '视频显示断面数据1', width: '150px' },
  204. { prop: 'videoSectionDataTwo', label: '视频显示断面数据2', width: '150px' },
  205. { prop: 'pdCheckLength', label: '判读检测长度', width: '150px' },
  206. { prop: 'noHandleLength', label: '暂无法预处理长度', width: '150px' },
  207. { prop: 'pdRemark', label: '判读备注', showOverflowTooltip: true, width: '150px' },
  208. { prop: 'isCheck', label: '是否检测' },
  209. { prop: 'rainTask', label: '雨水任务单', showOverflowTooltip: true, width: '100px' },
  210. { prop: 'remark', label: '探测备注', showOverflowTooltip: true },
  211. { prop: 'batchinfo.createTime', label: '导入时间', showOverflowTooltip: true }
  212. ]
  213. /**数据展示数据 */
  214. dataList = []
  215. /**数据导入数据 */
  216. list = []
  217. /**项目添加表单 */
  218. addForm = {
  219. project: '',
  220. type: '',
  221. tcUnit: '',
  222. district: ''
  223. }
  224. /**表单验证 */
  225. addRules = {
  226. type: [{ required: true, message: '请选择数据类型', trigger: 'change' }],
  227. project: [{ required: true, message: '请选择项目', trigger: 'change' }],
  228. tcUnit: [{ required: true, message: '请选择单位', trigger: 'change' }]
  229. }
  230. /**激活 tab panel */
  231. activeTab = 'import'
  232. /**分页 */
  233. pagination = getDefaultPagination()
  234. /**批次表格 */
  235. batchPagination= getDefaultPagination()
  236. /**行政区 */
  237. districts = districts
  238. /**是否编辑 */
  239. formType = 'add'
  240. /**导入过滤信息 */
  241. searchInfo = {
  242. project: '', //项目
  243. status: '', //导入状态
  244. timeRange: [] //导入时间
  245. }
  246. /**数据表格过滤信息 */
  247. dataSeachInfo = {
  248. project: '', //项目
  249. pici: '', //批次号
  250. region: '', //行政区
  251. status: '', //数据状态
  252. s_code: '', //起点编码,
  253. e_code: '', //终点编码
  254. timeRange: [] //导入时间
  255. }
  256. /**项目列表 */
  257. projects = []
  258. /**数据状态 */
  259. status = []
  260. /**导入步骤索引,0开始 */
  261. importStep = 0
  262. /**对话框显隐 */
  263. isAddDialogShow = false
  264. /**项目类型 */
  265. prjTypes = []
  266. /**上传附件列表 */
  267. fileList = []
  268. files = []
  269. /**单位列表 */
  270. departments = []
  271. mounted() {
  272. this.batchinfoPage()
  273. this.getDataList()
  274. this.getProjectList()
  275. this.getDepartments()
  276. }
  277. /*--------------------- 附件上传 ----------------*/
  278. handleRemove(file, fileList) {
  279. console.log('文件列表移除文件时的钩子', file, fileList)
  280. this.fileList = fileList
  281. }
  282. handlePreview(file) {
  283. console.log('点击文件列表中已上传的文件时的钩子', file)
  284. }
  285. handleExceed(files, fileList) {
  286. this.$message.warning(
  287. `当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`
  288. )
  289. }
  290. beforeRemove(file, fileList) {
  291. return this.$confirm(`确定移除 ${file.name}?`)
  292. }
  293. onBeforeUpload(file) {
  294. console.log('图片格式', file.type)
  295. let fileName = file.name
  296. let esuffixt = fileName.substr(fileName.lastIndexOf('.') + 1)
  297. const isIMAGE = esuffixt === 'xls' || esuffixt === 'xlsx'
  298. const isLt1M = file.size / 1024 / 1024 < 10
  299. if (!isIMAGE) {
  300. this.$message.error('上传文件只能是jpg,png,jpeg,pdf,excel,word格式!')
  301. }
  302. if (!isLt1M) {
  303. this.$message.error('上传文件大小不能超过 10MB!')
  304. }
  305. return isIMAGE && isLt1M
  306. }
  307. //上传之前的钩子函数
  308. beforeAvatarUpload(response, file, fileList) {
  309. console.log(response, file)
  310. var isTrue = this.onBeforeUpload(response.raw)
  311. if (isTrue) {
  312. this.fileMap(file)
  313. } else {
  314. file.pop()
  315. }
  316. }
  317. fileMap(file) {
  318. if (file.length !== 0) {
  319. const files = file.map((v) => {
  320. return v.raw
  321. })
  322. this.files = files
  323. }
  324. }
  325. handleAvatarSuccess(res, file, fileList) {
  326. console.log('文件上传成功时的钩子', res, file, fileList)
  327. }
  328. /**导入弹窗 */
  329. showAddDialog() {
  330. this.isAddDialogShow = true
  331. this.formType = 'add'
  332. this.fileList = []
  333. this.files = []
  334. this.importStep=0
  335. this.addForm = {
  336. project: '',
  337. district: '',
  338. type: 'tc',
  339. tcUnit: ''
  340. }
  341. }
  342. /**单位信息 */
  343. getDepartments() {
  344. getAllDepartments()
  345. .then((result) => {
  346. if (result.code === 1) {
  347. this.departments = result.result || []
  348. }
  349. })
  350. .catch((err) => {
  351. console.log(err)
  352. })
  353. }
  354. /**提交 */
  355. addSubmit() {
  356. ;(this.$refs['addForm'] as ElForm).validate((valid) => {
  357. if (!valid) {
  358. return
  359. }
  360. if (this.files.length === 0) {
  361. this.$message.warning('请上传文件')
  362. return
  363. }
  364. if (this.files.length === 1) {
  365. this.importStep = 1
  366. const formdata = new FormData()
  367. this.files.forEach((file) => {
  368. formdata.append('file', file)
  369. })
  370. uploadFile(formdata)
  371. .then((result) => {
  372. if (result.code !== 1) {
  373. this.$message.error('上传文件失败')
  374. return
  375. }
  376. if (!result.result || result.result.length === 0) {
  377. console.log('上传文件未返回fileId')
  378. return
  379. }
  380. const fileID = result.result[0].fileId
  381. const data = {
  382. prjId: this.addForm.project,
  383. district: this.addForm.district,
  384. departmentId: this.addForm.tcUnit,
  385. fileId: fileID
  386. }
  387. checkDataImport(data)
  388. .then((addResult) => {
  389. if (addResult.code === 1) {
  390. this.$message.success('保存成功')
  391. this.importStep = 2
  392. //this.isAddDialogShow = false
  393. this.batchinfoPage()
  394. }
  395. })
  396. .catch((err) => {
  397. this.$message.error('保存失败')
  398. console.log(err)
  399. })
  400. })
  401. .catch((err) => {
  402. this.$message.error('上传文件失败')
  403. console.log(err)
  404. })
  405. } else {
  406. this.$message.warning('单次只允许上传一个文件')
  407. }
  408. })
  409. }
  410. /**详情 */
  411. viewProjectInfo(row) {
  412. this.isAddDialogShow = true
  413. this.formType = 'edit'
  414. this.addForm = {
  415. project: row.prjId,
  416. district: row.district,
  417. tcUnit: row.departmentId,
  418. type: 'tc'
  419. }
  420. // this.fileList = row.toflyFiles.map((item) => {
  421. // return item.fileName
  422. // })
  423. }
  424. /**数据导入列表 */
  425. batchinfoPage() {
  426. let parames = {
  427. prjId: this.searchInfo.project,
  428. stage: 4,
  429. startTime:this.searchInfo.timeRange&&this.searchInfo.timeRange.length>=1?this.searchInfo.timeRange[0]:'',
  430. endTime:this.searchInfo.timeRange&&this.searchInfo.timeRange.length==2?this.searchInfo.timeRange[1]:''
  431. }
  432. parames = { ...parames, ...this.batchPagination }
  433. batchinfoPage(parames)
  434. .then((result) => {
  435. if (result.code === 1) {
  436. this.list = result.result.records
  437. const { current, size, total } = result.result
  438. this.batchPagination = { current, size, total }
  439. }
  440. })
  441. .catch((err) => {
  442. console.log(err)
  443. })
  444. }
  445. /**
  446. * 数据列表
  447. */
  448. getDataList() {
  449. let parames = {
  450. 'batchinfo.batchNo': this.dataSeachInfo.pici,
  451. 'batchinfo.prjId': this.dataSeachInfo.project,
  452. area: this.dataSeachInfo.region,
  453. startCode: this.dataSeachInfo.s_code,
  454. endCode: this.dataSeachInfo.e_code,
  455. 'batchinfo.startTime':this.dataSeachInfo.timeRange&&this.dataSeachInfo.timeRange.length>=1?this.dataSeachInfo.timeRange[0]:'',
  456. 'batchinfo.endTime':this.dataSeachInfo.timeRange&&this.dataSeachInfo.timeRange.length==2?this.dataSeachInfo.timeRange[1]:''
  457. }
  458. parames = { ...parames, ...this.pagination }
  459. checkdataPage(parames)
  460. .then((result) => {
  461. if (result.code === 1) {
  462. this.dataList = result.result.records
  463. const { current, size, total } = result.result
  464. this.pagination = { current, size, total }
  465. }
  466. })
  467. .catch((err) => {
  468. console.log(err)
  469. })
  470. }
  471. /**
  472. * 项目列表
  473. */
  474. getProjectList() {
  475. projectPage({})
  476. .then((result) => {
  477. if (result.code === 1) {
  478. this.projects = result.result.records.map((item) => {
  479. return { id: item.id, name: item.name }
  480. })
  481. }
  482. })
  483. .catch((err) => {
  484. console.log(err)
  485. })
  486. }
  487. /**分页事件 */
  488. onPageChange(pagination) {
  489. this.pagination = { ...this.pagination, ...pagination }
  490. this.getDataList()
  491. }
  492. /**分页事件 */
  493. batchOnPageChange(batchPagination) {
  494. this.batchPagination = { ...this.batchPagination, ...batchPagination }
  495. this.batchinfoPage()
  496. }
  497. }
  498. </script>
  499. <style lang="scss" scoped>
  500. @import '@/views/zhpt/dataImport/common/index.scss';
  501. .addDialog {
  502. >>> .el-form-item {
  503. .el-select {
  504. width: 100%;
  505. }
  506. }
  507. }
  508. .impTabs {
  509. height: 100%;
  510. >>> .el-tabs__content {
  511. height: calc(100% - 55px);
  512. .el-tab-pane {
  513. height: 100%;
  514. }
  515. }
  516. }
  517. // .dataSearchForm{
  518. // >>> .el-form-item{
  519. // .el-input{max-width: 150px;}
  520. // .el-select{max-width: 250px;}
  521. // }
  522. // }
  523. </style>