station.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. <template>
  2. <div class="hc-layout-box">
  3. <HcCard :scrollbar="false" actionSize="lg">
  4. <template #header>
  5. <HcTooltip keys="gauge-station-add">
  6. <el-button type="primary" hc-btn @click="AddRowClick">
  7. <HcIcon name="add-box"/>
  8. <span>新增</span>
  9. </el-button>
  10. </HcTooltip>
  11. <HcTooltip keys="gauge-station-import">
  12. <el-button hc-btn @click="importModalClick">
  13. <HcIcon name="upload-cloud"/>
  14. <span>导入</span>
  15. </el-button>
  16. </HcTooltip>
  17. <HcTooltip keys="gauge-station-export">
  18. <el-button hc-btn :loading="downloadLoading" @click="exportModalClick">
  19. <HcIcon name="download"/>
  20. <span>导出</span>
  21. </el-button>
  22. </HcTooltip>
  23. <div class="w-60 ml-6">
  24. <el-input v-model="searchForm.name" size="large" placeholder="请输入测站点或关键字进行搜索" clearable @keyup="keyUpEvent"/>
  25. </div>
  26. <div class="ml-2">
  27. <el-button type="primary" size="large" @click="searchClick">
  28. <HcIcon name="search-2"/>
  29. <span>搜索</span>
  30. </el-button>
  31. </div>
  32. </template>
  33. <template #extra>
  34. <HcNewSwitch :datas="tabsTypeData" :keys="tabsTypeKey" @change="tabsTypeChange"/>
  35. </template>
  36. <HcTable :column="levelTableColumn" :datas="levelTable" :loading="tableLoading" v-if="tabsTypeKey === '0'">
  37. <template #action="{row}">
  38. <HcTooltip keys="gauge-station-edit">
  39. <el-button type="primary" size="small" text @click="handleLevelEdit(row)">编辑</el-button>
  40. </HcTooltip>
  41. <HcTooltip keys="gauge-station-del">
  42. <el-button type="danger" size="small" text @click="handleLevelDelete(row)">删除</el-button>
  43. </HcTooltip>
  44. </template>
  45. </HcTable>
  46. <HcTable :column="traverseTableColumn" :datas="traverseTable" :loading="tableLoading" v-if="tabsTypeKey === '1'">
  47. <template #action="{row}">
  48. <HcTooltip keys="gauge-station-edit">
  49. <el-button type="primary" size="small" text @click="handleTraverseEdit(row)">编辑</el-button>
  50. </HcTooltip>
  51. <HcTooltip keys="gauge-station-del">
  52. <el-button type="danger" size="small" text @click="handleTraverseDelete(row)">删除</el-button>
  53. </HcTooltip>
  54. </template>
  55. </HcTable>
  56. <template #action>
  57. <HcPages :pages="searchForm" @change="pageChange"/>
  58. </template>
  59. </HcCard>
  60. <!--新增/编辑 弹框-->
  61. <el-dialog v-model="showRowModal" :title="`${formRowValue?.id ? '编辑' : '新增'}${tabsTypeKey==='1'?'导线点':'水准点'}`" width="47rem" class="hc-modal-border">
  62. <el-form ref="formRowRef" :model="formRowValue" :rules="rulesRow" label-width="auto" size="large">
  63. <el-form-item label="点名称" prop="name">
  64. <el-input v-model="formRowValue.name" placeholder="请输入点名称"/>
  65. </el-form-item>
  66. <el-form-item label="X坐标(m)" prop="x" v-if="tabsTypeKey === '1'">
  67. <el-input v-model="formRowValue.x" placeholder="请输入X坐标(m)"/>
  68. </el-form-item>
  69. <el-form-item label="Y坐标(m)" prop="y" v-if="tabsTypeKey === '1'">
  70. <el-input v-model="formRowValue.y" placeholder="请输入Y坐标(m)"/>
  71. </el-form-item>
  72. <el-form-item label="高程(m)" prop="h">
  73. <el-input v-model="formRowValue.h" placeholder="请输入高程(m)"/>
  74. </el-form-item>
  75. <el-form-item label="等级">
  76. <el-select v-model="formRowValue.level" block>
  77. <el-option v-for="item in personData" :label="item.label" :value="item.value" placeholder="请选择等级"/>
  78. </el-select>
  79. </el-form-item>
  80. <el-form-item label="备注">
  81. <el-input type="textarea" v-model="formRowValue.remark" placeholder="请输入文字说明" :autosize="{ minRows: 3, maxRows: 5 }"/>
  82. </el-form-item>
  83. </el-form>
  84. <template #footer>
  85. <div class="dialog-footer">
  86. <el-button size="large" @click="showRowModal = false">取消</el-button>
  87. <el-button type="primary" hc-btn :loading="saveFormLoading" @click="saveFormClick">提交</el-button>
  88. </div>
  89. </template>
  90. </el-dialog>
  91. <!--导入 弹框-->
  92. <el-dialog v-model="showImportModal" :title="`导入${tabsTypeKey==='1'?'导线点':'水准点'}`" width="47rem" class="hc-modal-border">
  93. <div class="hc-import-modal-box">
  94. <div class="tip-box">
  95. <span>请先下载导入模板(</span>
  96. <a class="text-link" href="https://bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20220614/a4b08ea228dbf74db1c049c4d878fbe7.xlsx" target="_blank" v-if="tabsTypeKey==='1'">导线点导入模板</a>
  97. <a class="text-link" href="https://bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20220629/5fa2abeaa1ad553ee4adf64118df4e2a.xlsx" target="_blank" v-if="tabsTypeKey==='0'">水准点导入模板</a>
  98. <span> ),按模板样式编辑测站点后,再点击"选择文件"按钮选择编辑好的文件,并点击底部的"确认导入"按钮即可导入成功!</span>
  99. </div>
  100. <div class="upload-box">
  101. <el-upload ref="uploadRef" :action="action" :headers="getTokenHeader()" :accept="accept" :data="addition" :limit="1" :auto-upload="false" v-model:file-list="fileList"
  102. :on-exceed="handleUploadExceed" :on-progress="handleUploadProgress" :on-success="handleUploadFinish" :on-error="handleUploadError">
  103. <template #trigger>
  104. <el-button type="primary" :loading="importLoading">选择文件</el-button>
  105. </template>
  106. </el-upload>
  107. </div>
  108. <div class="text-orange">导入模板格式示例:</div>
  109. <div class="demo-img-box" v-if="tabsTypeKey==='1'">
  110. <img src="../../assets/view/152221@2x.png" alt="">
  111. </div>
  112. <div class="demo-img-box" v-if="tabsTypeKey==='0'">
  113. <img src="../../assets/view/152211@2x.png" alt="">
  114. </div>
  115. </div>
  116. <template #footer>
  117. <div class="dialog-footer">
  118. <el-button size="large" @click="showImportModal = false">取消</el-button>
  119. <el-button type="primary" hc-btn :disabled="fileList.length <= 0" :loading="importLoading" @click="handleImportClick">确认导入</el-button>
  120. </div>
  121. </template>
  122. </el-dialog>
  123. </div>
  124. </template>
  125. <script setup>
  126. import {ref,onMounted} from "vue";
  127. import {useRouter, useRoute} from 'vue-router'
  128. import {useAppStore} from "~src/store/index";
  129. import stationApi from '~api/gauge/station';
  130. import {getTokenHeader} from '~src/api/request/header';
  131. import {getArrValue, downloadBlob, formValidate} from "vue-utils-plus"
  132. import { genFileId } from 'element-plus'
  133. //初始变量
  134. const router = useRouter()
  135. const useRoutes = useRoute()
  136. const useAppState = useAppStore()
  137. //路由参数
  138. const routerQuery = useRoutes?.query;
  139. const typeName = routerQuery?.type || '0'
  140. //全局变量
  141. const projectId = ref(useAppState.getProjectId);
  142. const contractId = ref(useAppState.getContractId);
  143. //类型tab数据和相关处理
  144. const tabsTypeKey = ref(typeName)
  145. const tabsTypeData = ref([
  146. {key:'0', name: '水准点'},
  147. {key:'1', name: '导线点'}
  148. ]);
  149. const tabsTypeChange = (item) => {
  150. tabsTypeKey.value = item?.key
  151. searchForm.value.type = item?.key
  152. searchForm.value.current = 1
  153. getTableData()
  154. //路由跳转
  155. router.push({
  156. path: useRoutes.path,
  157. query: {
  158. type: item?.key
  159. }
  160. })
  161. }
  162. //渲染完成
  163. onMounted(() => {
  164. searchForm.value.type = typeName
  165. getTableData()
  166. })
  167. //搜索表单
  168. const searchForm = ref({
  169. projectId: projectId.value, contractId: contractId.value, name: null, type: '0',
  170. current: 1, size: 20, total: 0
  171. })
  172. //回车搜索
  173. const keyUpEvent = (e) => {
  174. if (e.key === "Enter") {
  175. searchForm.value.current = 1;
  176. getTableData()
  177. }
  178. }
  179. //重新搜索数据
  180. const searchClick = () => {
  181. searchForm.value.current = 1
  182. getTableData()
  183. }
  184. //分页被点击
  185. const pageChange = ({current, size}) => {
  186. searchForm.value.current = current
  187. searchForm.value.size = size
  188. getTableData()
  189. }
  190. //导线点
  191. const traverseTableColumn = ref([
  192. {key:'name', name: '测站点名称'},
  193. {key:'x', name: 'X坐标(m)'},
  194. {key:'y', name: 'Y坐标(m)'},
  195. {key:'h', name: '高程(m)'},
  196. {key:'level', name: '等级'},
  197. {key:'remark', name: '备注'},
  198. {key:'action', name: '操作', width: '130'}
  199. ])
  200. const traverseTable = ref([])
  201. //水准点
  202. const levelTableColumn = ref([
  203. {key:'name', name: '测站点名称'},
  204. {key:'h', name: '高程(m)'},
  205. {key:'level', name: '等级'},
  206. {key:'remark', name: '备注'},
  207. {key:'action', name: '操作', width: '130'}
  208. ])
  209. const levelTable = ref([])
  210. //获取数据
  211. const tableLoading = ref(false)
  212. const getTableData = async () => {
  213. tableLoading.value = true
  214. const { error, code, data } = await stationApi.queryListData({
  215. projectId: projectId.value,
  216. contractId: contractId.value,
  217. ...searchForm.value
  218. })
  219. //处理数据
  220. tableLoading.value = false
  221. if (!error && code === 200) {
  222. let records = getArrValue(data['records'])
  223. if (tabsTypeKey.value === '0') {
  224. levelTable.value = records
  225. } else if (tabsTypeKey.value === '1') {
  226. traverseTable.value = records
  227. }
  228. searchForm.value.total = data.total || 0
  229. } else {
  230. levelTable.value = []
  231. traverseTable.value = []
  232. searchForm.value.total = 0
  233. }
  234. }
  235. //等级
  236. const personData = ref([
  237. {label: "一级", value: "一级"}, {label: "二级", value: "二级"},
  238. {label: "三级", value: "三级"}, {label: "四级", value: "四级"}
  239. ])
  240. //新增 / 编辑 配置
  241. const showRowModal = ref(false)
  242. const formRowRef = ref(null)
  243. const formRowValue = ref({name: '', x: '', y: '', h: '', level: null, remark: null})
  244. const rulesRow = {
  245. name: {
  246. required: true,
  247. trigger: "blur",
  248. message: "请输入测站点名称"
  249. },
  250. x: {
  251. required: true,
  252. trigger: "blur",
  253. message: "请输入X坐标(m)"
  254. },
  255. y: {
  256. required: true,
  257. trigger: "blur",
  258. message: "请输入Y坐标(m)"
  259. },
  260. h: {
  261. required: true,
  262. trigger: "blur",
  263. message: "请输入高程(m)"
  264. }
  265. }
  266. //新增
  267. const AddRowClick = () => {
  268. const type = tabsTypeKey.value
  269. const obj = {
  270. projectId: projectId.value,
  271. contractId: contractId.value,
  272. type: tabsTypeKey.value,
  273. name: '', h: '', level: null, remark: null
  274. }
  275. if (type === '0') {
  276. formRowValue.value = obj
  277. } else if (type === '1') {
  278. formRowValue.value = {...obj, x: '', y: ''}
  279. }
  280. saveFormLoading.value = false
  281. showRowModal.value = true
  282. }
  283. //新增/编辑 保存
  284. const saveFormLoading = ref(false)
  285. const saveFormClick = async () => {
  286. const validate = await formValidate(formRowRef.value)
  287. if (validate) {
  288. const form = formRowValue.value
  289. if (!!form.id) {
  290. saveFormLoading.value = true
  291. const {error, code} = await stationApi.updateSave(form,false)
  292. //判断状态
  293. saveFormLoading.value = false
  294. if (!error && code === 200) {
  295. showRowModal.value = false
  296. window?.$message?.success('保存成功')
  297. getTableData()
  298. } else {
  299. window?.$message?.error('保存失败')
  300. }
  301. } else {
  302. saveFormLoading.value = true
  303. const {error, code} = await stationApi.addSave(form,false)
  304. //判断状态
  305. saveFormLoading.value = false
  306. if (!error && code === 200) {
  307. showRowModal.value = false
  308. window?.$message?.success('新增成功')
  309. getTableData()
  310. } else {
  311. window?.$message?.error('新增失败')
  312. }
  313. }
  314. }
  315. }
  316. //导入配置
  317. const showImportModal = ref(false)
  318. const importLoading = ref(false)
  319. //上传配置
  320. const uploadRef = ref(null)
  321. const addition = ref({})
  322. const fileList = ref([])
  323. const action = '/api/blade-business/dap/import';
  324. const accept = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel';
  325. //导入
  326. const importModalClick = () => {
  327. addition.value = {
  328. projectId: projectId.value,
  329. contractId: contractId.value,
  330. type: tabsTypeKey.value
  331. }
  332. importLoading.value = false
  333. showImportModal.value = true
  334. }
  335. //上传一个文件时,重置
  336. const handleUploadExceed = (files) => {
  337. uploadRef.value?.clearFiles()
  338. const file = files[0]
  339. file.uid = genFileId()
  340. uploadRef.value?.handleStart(file)
  341. }
  342. //确认导入
  343. const handleImportClick = () => {
  344. uploadRef.value?.submit()
  345. }
  346. //上传中
  347. const handleUploadProgress = () => {
  348. importLoading.value = true
  349. }
  350. //上传完成
  351. const handleUploadFinish = () => {
  352. importLoading.value = false
  353. showImportModal.value = false
  354. window?.$message?.success('导入成功')
  355. uploadRef.value?.clearFiles()
  356. getTableData()
  357. }
  358. //上传失败
  359. const handleUploadError = () => {
  360. importLoading.value = false
  361. window?.$message?.error('导入失败')
  362. }
  363. //导出
  364. const exportModalClick = () => {
  365. window?.$messageBox?.alert('将导出当前所有数据?', '导出数据', {
  366. showCancelButton: true,
  367. confirmButtonText: '确定导出',
  368. cancelButtonText: '取消',
  369. callback: (action) => {
  370. if (action === 'confirm') {
  371. getExportExcel()
  372. }
  373. }
  374. })
  375. }
  376. //确定导出
  377. const downloadLoading = ref(false)
  378. const getExportExcel = async () => {
  379. //批量下载
  380. downloadLoading.value = true
  381. const { error, disposition, res } = await stationApi.getExportExcel({
  382. projectId: projectId.value,
  383. contractId: contractId.value,
  384. type: tabsTypeKey.value,
  385. search: searchForm.value['name'] || ''
  386. })
  387. //处理数据
  388. downloadLoading.value = false
  389. if (!error) {
  390. if (disposition) {
  391. downloadBlob(res,disposition)
  392. } else {
  393. window.$message?.error('数据异常')
  394. }
  395. }
  396. }
  397. //水准点
  398. const handleLevelEdit = (row) => {
  399. formRowValue.value = {
  400. ...row,
  401. projectId: projectId.value,
  402. contractId: contractId.value,
  403. type: tabsTypeKey.value
  404. }
  405. saveFormLoading.value = false
  406. showRowModal.value = true
  407. }
  408. const handleLevelDelete = (row) => {
  409. window?.$messageBox?.alert('是否删除当前数据?', '删除提醒', {
  410. showCancelButton: true,
  411. confirmButtonText: '确定删除',
  412. cancelButtonText: '取消',
  413. callback: (action) => {
  414. if (action === 'confirm') {
  415. delData(row.id)
  416. }
  417. }
  418. })
  419. }
  420. //导线点
  421. const handleTraverseEdit = (row) => {
  422. formRowValue.value = {
  423. ...row,
  424. projectId: projectId.value,
  425. contractId: contractId.value,
  426. type: tabsTypeKey.value
  427. }
  428. saveFormLoading.value = false
  429. showRowModal.value = true
  430. }
  431. const handleTraverseDelete = (row) => {
  432. window?.$messageBox?.alert('是否删除当前数据?', '删除提醒', {
  433. showCancelButton: true,
  434. confirmButtonText: '确定删除',
  435. cancelButtonText: '取消',
  436. callback: (action) => {
  437. if (action === 'confirm') {
  438. delData(row.id)
  439. }
  440. }
  441. })
  442. }
  443. //删除请求
  444. const delData = async (id) => {
  445. const {error, code} = await stationApi.delData({ids: id},false)
  446. //判断状态
  447. if (!error && code === 200) {
  448. window?.$message?.success('删除成功')
  449. getTableData()
  450. } else {
  451. window?.$message?.error('删除失败')
  452. }
  453. }
  454. </script>
  455. <style lang="scss" scoped>
  456. @import '../../styles/gauge/station.scss';
  457. </style>