bezier.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. <template>
  2. <div class="hc-layout-box">
  3. <HcNewCard :scrollbar="false" action-size="lg">
  4. <template #header>
  5. <HcTooltip keys="gauge-bezier-add">
  6. <el-button :disabled="searchForm.partId.length < 1" hc-btn type="primary" @click="addLineEleModal">
  7. <HcIcon name="add-box" />
  8. <span>添加线元</span>
  9. </el-button>
  10. </HcTooltip>
  11. <HcTooltip keys="gauge-bezier-to">
  12. <el-button hc-btn @click="showToModalClick">
  13. <HcIcon name="repeat" />
  14. <span>转换坐标</span>
  15. </el-button>
  16. </HcTooltip>
  17. <HcTooltip keys="gauge-bezier-pile">
  18. <el-button hc-btn @click="pileModalClick">
  19. <HcIcon name="settings-6" />
  20. <span>逐桩坐标</span>
  21. </el-button>
  22. </HcTooltip>
  23. <HcTooltip keys="gauge-bezier-import">
  24. <el-button hc-btn @click="importModalClick">
  25. <HcIcon name="upload-cloud" />
  26. <span>导入</span>
  27. </el-button>
  28. </HcTooltip>
  29. <HcTooltip keys="gauge-bezier-export">
  30. <el-button :loading="downloadLoading" hc-btn @click="exportModalClick">
  31. <HcIcon name="download" />
  32. <span>导出</span>
  33. </el-button>
  34. </HcTooltip>
  35. </template>
  36. <template #extra>
  37. <div class="w-60">
  38. <el-select v-model="searchForm.partId" block clearable placeholder="片段查询" @change="searchClick">
  39. <el-option v-for="item in partData" :key="item.id" :label="item.name" :value="item.id" />
  40. </el-select>
  41. </div>
  42. <HcTooltip keys="gauge-bezier-add-part">
  43. <div class="hc-extra-icon-btn" @click="AddPartClick">
  44. <HcIcon name="add-circle" />
  45. </div>
  46. </HcTooltip>
  47. <HcTooltip keys="gauge-bezier-admin-part">
  48. <div class="hc-extra-icon-btn" @click="AdminPartClick">
  49. <HcIcon name="list-settings" />
  50. </div>
  51. </HcTooltip>
  52. </template>
  53. <HcTable :column="tableColumn" :datas="tableData" :loading="tableLoading" is-new :index-style="{ width: 60 }">
  54. <template #name="{ row }">{{ row.valueStr }}~{{ row.valueEndStr }}</template>
  55. <template #type="{ row }">{{ getTypeName(row?.type) }}</template>
  56. <!-- <template #angle="{row}">
  57. {{row['du']}}°{{row['fen']}}′{{row['miao']}}″
  58. </template> -->
  59. <template #action="{ row }">
  60. <HcTooltip keys="gauge-station-edit">
  61. <el-button size="small" text type="primary" @click="handleTableEdit(row)">编辑</el-button>
  62. </HcTooltip>
  63. <HcTooltip keys="gauge-station-del">
  64. <el-button size="small" text type="danger" @click="handleTableDelete(row)">删除</el-button>
  65. </HcTooltip>
  66. </template>
  67. </HcTable>
  68. <template #action>
  69. <HcPages :pages="searchForm" @change="pageChange" />
  70. </template>
  71. </HcNewCard>
  72. <!-- 管理片段弹框 -->
  73. <hc-new-dialog v-model="showAdminPartModal" title="管理片段" widths="47rem">
  74. <div class="admin-part-data-table">
  75. <el-scrollbar>
  76. <div class="hc-table-ref-box">
  77. <el-table :data="AdminPartTableData" hc border>
  78. <el-table-column label="片段名称" prop="name">
  79. <template #default="scope">
  80. <el-input v-if="scope.row.isEdit" v-model="scope.row.name" placeholder="片段名称" />
  81. <div v-else>{{ scope.row.name }}</div>
  82. </template>
  83. </el-table-column>
  84. <el-table-column label="桩号前缀" prop="prefix">
  85. <template #default="scope">
  86. <el-input v-if="scope.row.isEdit" v-model="scope.row.prefix" placeholder="桩号前缀" />
  87. <div v-else>{{ scope.row.prefix }}</div>
  88. </template>
  89. </el-table-column>
  90. <el-table-column align="center" label="操作" width="130">
  91. <template #default="scope">
  92. <el-button v-if="scope.row.isEdit" size="small" text type="primary" @click="handleAdminPartSave(scope.row)">保存</el-button>
  93. <HcTooltip v-else keys="gauge-station-edit">
  94. <el-button size="small" text type="primary" @click="handleAdminPartEdit(scope.row)">编辑</el-button>
  95. </HcTooltip>
  96. <HcTooltip keys="gauge-station-del">
  97. <el-button size="small" text type="danger" @click="handleAdminPartDelete(scope.row, scope.$index)">删除</el-button>
  98. </HcTooltip>
  99. </template>
  100. </el-table-column>
  101. </el-table>
  102. </div>
  103. </el-scrollbar>
  104. </div>
  105. <template #footer>
  106. <div class="dialog-footer">
  107. <el-button size="large" @click="showAdminPartModal = false">取消</el-button>
  108. <el-button hc-btn type="primary" @click="AddAdminPart">新增</el-button>
  109. </div>
  110. </template>
  111. </hc-new-dialog>
  112. <!-- 新增片段弹框 -->
  113. <hc-new-dialog v-model="showAddPartModal" title="新增片段" widths="38rem">
  114. <el-form ref="partFormRef" :model="partForm" :rules="partRules" label-width="auto" size="large">
  115. <el-form-item label="名称" prop="name">
  116. <el-input v-model="partForm.name" placeholder="请输入名称" />
  117. </el-form-item>
  118. <el-form-item label="桩号前缀" prop="prefix">
  119. <el-input v-model="partForm.prefix" placeholder="只允许输入大写的英文字母" />
  120. </el-form-item>
  121. </el-form>
  122. <template #footer>
  123. <div class="dialog-footer">
  124. <el-button size="large" @click="showAddPartModal = false">取消</el-button>
  125. <el-button :loading="savePartLoading" hc-btn type="primary" @click="savePartInfo">保存</el-button>
  126. </div>
  127. </template>
  128. </hc-new-dialog>
  129. <!-- 添加/编辑线元弹框 -->
  130. <hc-new-dialog v-model="showLineEleModal" :title="(formLineEleValue.id === -1 || !formLineEleValue.id) ? '添加线元' : '编辑线元'" widths="40rem">
  131. <el-form :model="formLineEleValue" label-width="auto" size="large">
  132. <el-form-item label="类型">
  133. <el-radio-group v-model="formLineEleValue.type">
  134. <el-radio v-for="(item, index) in lineElementType" :key="index" :value="item.value">{{ item.label }}</el-radio>
  135. </el-radio-group>
  136. </el-form-item>
  137. <el-form-item label="开始里程">
  138. <el-input v-model="formLineEleValue.value" placeholder="请输入开始里程" />
  139. </el-form-item>
  140. <el-form-item label="X">
  141. <el-input v-model="formLineEleValue.x" placeholder="请输入X" />
  142. </el-form-item>
  143. <el-form-item label="Y">
  144. <el-input v-model="formLineEleValue.y" placeholder="请输入Y" />
  145. </el-form-item>
  146. <el-form-item v-if="formLineEleValue.type !== 0" label="半径">
  147. <el-input v-model="formLineEleValue.r" placeholder="请输入半径" />
  148. </el-form-item>
  149. <el-form-item v-if="formLineEleValue.type === 4" label="结束半径">
  150. <el-input v-model="formLineEleValue.r2" placeholder="请输入半径" />
  151. </el-form-item>
  152. <el-form-item v-if="formLineEleValue.type !== 0" label="转向">
  153. <el-radio-group v-model="formLineEleValue.swing">
  154. <el-radio value="左转">左转</el-radio>
  155. <el-radio value="右转">右转</el-radio>
  156. </el-radio-group>
  157. </el-form-item>
  158. <el-form-item label="线长度">
  159. <el-input v-model="formLineEleValue.l" placeholder="请输入线长度" />
  160. </el-form-item>
  161. <div class="flex">
  162. <el-form-item class="flex-1" label="方位角">
  163. <el-input v-model="formLineEleValue.du" placeholder="输入度">
  164. <template #suffix>度</template>
  165. </el-input>
  166. </el-form-item>
  167. <el-form-item class="flex-1 ml-4" no-label>
  168. <el-input v-model="formLineEleValue.fen" placeholder="输入分">
  169. <template #suffix>分</template>
  170. </el-input>
  171. </el-form-item>
  172. <el-form-item class="flex-1 ml-4" no-label>
  173. <el-input v-model="formLineEleValue.miao" placeholder="输入秒">
  174. <template #suffix>秒</template>
  175. </el-input>
  176. </el-form-item>
  177. </div>
  178. <el-form-item v-if="formLineEleValue.type !== 3" label="断链前里程">
  179. <el-input v-model="formLineEleValue.dlq" placeholder="请输入断链前里程" />
  180. </el-form-item>
  181. <el-form-item v-if="formLineEleValue.type !== 3" label="断链后里程">
  182. <el-input v-model="formLineEleValue.dlh" placeholder="请输入断链后里程" />
  183. </el-form-item>
  184. <el-form-item label="顺序">
  185. <el-input v-model="formLineEleValue.orderNum" placeholder="请输入顺序" />
  186. </el-form-item>
  187. </el-form>
  188. <template #footer>
  189. <div class="dialog-footer">
  190. <el-button size="large" @click="showLineEleModal = false">取消</el-button>
  191. <el-button size="large" @click="refreshable">刷新</el-button>
  192. <el-button :loading="saveLoading" hc-btn type="primary" @click="saveLineEleClick">保存</el-button>
  193. </div>
  194. </template>
  195. </hc-new-dialog>
  196. <!-- 里程转换坐标 -->
  197. <hc-new-dialog v-model="showToModal" title="里程转换坐标" widths="38rem">
  198. <el-form :model="formToValue" label-width="auto" size="large">
  199. <el-form-item label="里程">
  200. <el-input v-model="formToValue.value" placeholder="请输入名称" />
  201. </el-form-item>
  202. <el-form-item label="偏移">
  203. <el-input v-model="formToValue.b" placeholder="请输入偏移" />
  204. </el-form-item>
  205. <el-form-item label="夹角">
  206. <el-input v-model="formToValue.jj" placeholder="请输入夹角" />
  207. </el-form-item>
  208. <el-form-item label="X">
  209. <div class="form-item-div">{{ formToValue.x }}</div>
  210. </el-form-item>
  211. <el-form-item label="Y">
  212. <div class="form-item-div">{{ formToValue.y }}</div>
  213. </el-form-item>
  214. </el-form>
  215. <template #footer>
  216. <div class="dialog-footer">
  217. <el-button size="large" @click="showToModal = false">取消</el-button>
  218. <el-button hc-btn type="primary" @click="queryPsChange">转换</el-button>
  219. </div>
  220. </template>
  221. </hc-new-dialog>
  222. <!-- 逐桩坐标弹框 -->
  223. <hc-new-dialog v-model="showPileModal" title="逐桩坐标" widths="62rem">
  224. <el-form :model="formPileValue" inline label-position="top" label-width="auto" size="large">
  225. <el-form-item label="开始桩号">
  226. <el-input v-model="formPileValue.x" placeholder="开始桩号" />
  227. </el-form-item>
  228. <el-form-item label="结束桩号">
  229. <el-input v-model="formPileValue.y" placeholder="结束桩号" />
  230. </el-form-item>
  231. <el-form-item label="桩距">
  232. <el-input v-model="formPileValue.value" placeholder="桩距" />
  233. </el-form-item>
  234. <el-form-item label="偏距">
  235. <el-input v-model="formPileValue.b" placeholder="偏距" />
  236. </el-form-item>
  237. <el-form-item label=" ">
  238. <el-button :loading="generateLoading" attr-type="button" type="primary" @click="generateClick">生成</el-button>
  239. </el-form-item>
  240. </el-form>
  241. <div class="admin-part-data-table">
  242. <el-scrollbar>
  243. <div class="hc-table-ref-box">
  244. <el-table :data="pileTable" hc border>
  245. <el-table-column label="序号" prop="num" width="80">
  246. <template #default="scope">{{ scope.$index + 1 }}</template>
  247. </el-table-column>
  248. <el-table-column label="里程" prop="valueStr" />
  249. <el-table-column label="偏距" prop="b" />
  250. <el-table-column label="X" prop="xxStr" />
  251. <el-table-column label="Y" prop="yyStr" />
  252. </el-table>
  253. </div>
  254. </el-scrollbar>
  255. </div>
  256. </hc-new-dialog>
  257. <!-- 导入弹框 -->
  258. <hc-new-dialog v-model="showImportModal" title="导入线元" widths="32rem">
  259. <div class="text-center">
  260. <el-upload
  261. ref="uploadRef" v-model:file-list="fileList" :accept="accept" :action="action"
  262. :auto-upload="false" :data="addition" :headers="getHeader()" :limit="1"
  263. :on-error="handleUploadError" :on-exceed="handleUploadExceed"
  264. :on-progress="handleUploadProgress" :on-success="handleUploadFinish"
  265. >
  266. <template #trigger>
  267. <el-button :loading="importLoading" type="primary">选择文件</el-button>
  268. </template>
  269. </el-upload>
  270. </div>
  271. <template #footer>
  272. <div class="lr-dialog-footer">
  273. <div class="left">
  274. <el-button size="large" @click="tmportTmpClick">下载导入模板</el-button>
  275. </div>
  276. <div class="right">
  277. <el-button size="large" @click="showImportModal = false">取消</el-button>
  278. <el-button :disabled="fileList.length <= 0" :loading="importLoading" hc-btn type="primary" @click="handleImportClick">确认导入</el-button>
  279. </div>
  280. </div>
  281. </template>
  282. </hc-new-dialog>
  283. </div>
  284. </template>
  285. <script setup>
  286. import { onMounted, ref } from 'vue'
  287. import { useAppStore } from '~src/store'
  288. import bezierApi from '~api/gauge/bezier'
  289. import { getHeader } from 'hc-vue3-ui'
  290. import { deepClone, downloadBlob, formValidate, getArrValue, getObjValue, isObjNull } from 'js-fast-way'
  291. import { genFileId } from 'element-plus'
  292. import { HcDelMsg } from 'hc-vue3-ui'
  293. //初始变量
  294. const useAppState = useAppStore()
  295. const projectId = ref(useAppState.getProjectId)
  296. const contractId = ref(useAppState.getContractId)
  297. //渲染完成
  298. onMounted(() => {
  299. queryPartList()
  300. })
  301. //获取下拉列表
  302. const partData = ref([])
  303. const queryPartList = async () => {
  304. const { error, code, data } = await bezierApi.queryPartList({
  305. projectId: projectId.value,
  306. contractId: contractId.value,
  307. })
  308. if (!error && code === 200) {
  309. let records = getArrValue(data)
  310. partData.value = records
  311. AdminPartTableData.value = deepClone(records)
  312. if (records.length > 0 && !searchForm.value.partId) {
  313. searchForm.value.partId = records[0].id
  314. partNo.value = records[0].prefix
  315. getTableData()
  316. }
  317. } else {
  318. partData.value = []
  319. AdminPartTableData.value = []
  320. searchForm.value.partId = null
  321. }
  322. }
  323. //搜索表单
  324. const searchForm = ref({ partId: '', current: 1, size: 20, total: 0 })
  325. const partNo = ref('')
  326. //重新搜索数据
  327. const searchClick = (id) => {
  328. partData.value.forEach((ele) => {
  329. if (ele.id === id) {
  330. partNo.value = ele.prefix
  331. }
  332. })
  333. searchForm.value.current = 1
  334. getTableData()
  335. }
  336. //分页被点击
  337. const pageChange = ({ current, size }) => {
  338. searchForm.value.current = current
  339. searchForm.value.size = size
  340. getTableData()
  341. }
  342. //获取数据
  343. const tableColumn = ref([
  344. { key: 'name', name: '里程' },
  345. { key: 'orderNum', name: '排序' },
  346. { key: 'l', name: '长度' },
  347. { key: 'angleStr', name: '方位角' },
  348. { key: 'type', name: '类型' },
  349. { key: 'swing', name: '转向' },
  350. { key: 'xxStr', name: 'X' },
  351. { key: 'yyStr', name: 'Y' },
  352. { key: 'r', name: '半径' },
  353. { key: 'action', name: '操作', width: '130' },
  354. ])
  355. const tableData = ref([])
  356. const tableLoading = ref(false)
  357. const getTableData = async () => {
  358. tableLoading.value = true
  359. const { error, code, data } = await bezierApi.queryListData(searchForm.value)
  360. tableLoading.value = false
  361. if (!error && code === 200) {
  362. tableData.value = getArrValue(data['records'])
  363. searchForm.value.total = data['total'] || 0
  364. } else {
  365. tableData.value = []
  366. searchForm.value.total = 0
  367. }
  368. }
  369. //编辑表格
  370. const handleTableEdit = (row) => {
  371. const form = deepClone(row)
  372. formLineEleValue.value['id'] = form['id']
  373. formLineEleValue.value['type'] = form['type']
  374. formLineEleValue.value['projectId'] = projectId.value
  375. formLineEleValue.value['contractId'] = contractId.value
  376. formLineEleValue.value['partId'] = searchForm.value.partId
  377. let mile = ['x', 'y', 'fen', 'miao', 'du', 'value', 'l', 'dlq', 'dlh', 'swing', 'r', 'r2', 'orderNum']
  378. mile.forEach((key) => {
  379. formLineEleValue.value[key] = form[key] + ''
  380. })
  381. saveLoading.value = false
  382. showLineEleModal.value = true
  383. }
  384. //删除表格
  385. const handleTableDelete = (row) => {
  386. delMessageV2(async (action, instance, done) => {
  387. if (action === 'confirm') {
  388. instance.confirmButtonLoading = true
  389. saveDelMileage(row.id)
  390. instance.confirmButtonLoading = false
  391. done()
  392. } else {
  393. done()
  394. }
  395. })
  396. }
  397. //确认删除
  398. const saveDelMileage = async (rid) => {
  399. const { error, code } = await bezierApi.saveDelMileage({ id: rid }, false)
  400. //判断状态
  401. if (!error && code === 200) {
  402. window?.$message?.success('删除成功')
  403. getTableData()
  404. } else {
  405. window?.$message?.error('删除失败')
  406. }
  407. }
  408. //线元类型
  409. const showLineEleModal = ref(false)
  410. const formLineEleValue = ref({ type: 0 })
  411. const lineElementType = ref([
  412. { value: 0, label: '直线段' },
  413. { value: 1, label: '圆曲线' },
  414. { value: 2, label: '入缓和曲线' },
  415. { value: 3, label: '出缓和曲线' },
  416. { value: 4, label: '不完整缓和曲线' },
  417. ])
  418. //获取类型名称
  419. const getTypeName = (val) => {
  420. if (val !== -1 || val >= 0) {
  421. return lineElementType.value[val].label || ''
  422. } else {
  423. return '-'
  424. }
  425. }
  426. //添加线元
  427. const addLineEleModal = () => {
  428. formLineEleValue.value = { type: 0 }
  429. saveLoading.value = false
  430. showLineEleModal.value = true
  431. getNextMileagexy({ partId:searchForm.value.partId })
  432. }
  433. //刷新
  434. const refreshable = () => {
  435. getNextMileagexy({
  436. orderNum: formLineEleValue.value['orderNum'],
  437. partId:searchForm.value.partId,
  438. })
  439. }
  440. //保存
  441. const saveLoading = ref(false)
  442. const saveLineEleClick = async () => {
  443. let form = formLineEleValue.value
  444. form.partId = searchForm.value.partId
  445. form.partNo = partNo.value
  446. if (form.id === -1 || !form.id) {
  447. saveLoading.value = true
  448. const { error, code } = await bezierApi.saveAddMileage(form)
  449. saveLoading.value = false
  450. if (!error && code === 200) {
  451. window?.$message?.success('保存成功')
  452. showLineEleModal.value = false
  453. getTableData()
  454. }
  455. } else {
  456. saveLoading.value = true
  457. const { error, code } = await bezierApi.saveUpdateMileage(form)
  458. saveLoading.value = false
  459. if (!error && code === 200) {
  460. window?.$message?.success('保存成功')
  461. showLineEleModal.value = false
  462. getTableData()
  463. }
  464. }
  465. }
  466. //获取数据
  467. const getNextMileagexy = async (obj = {}) => {
  468. const { error, code, data } = await bezierApi.getNextMileagexy({
  469. ...obj,
  470. projectId: projectId.value,
  471. contractId: contractId.value,
  472. })
  473. if (!error && code === 200) {
  474. const res = getObjValue(data)
  475. if (!isObjNull(res)) {
  476. let mile = ['x', 'y', 'fen', 'miao', 'du', 'value', 'l', 'dlq', 'dlh', 'swing', 'r', 'r2', 'orderNum']
  477. mile.forEach((key) => {
  478. formLineEleValue.value[key] = res[key] + ''
  479. })
  480. formLineEleValue.value['type'] = res['type']
  481. formLineEleValue.value['projectId'] = projectId.value
  482. formLineEleValue.value['contractId'] = contractId.value
  483. formLineEleValue.value['partId'] = searchForm.value.partId
  484. } else {
  485. formLineEleValue.value = { type: 0 }
  486. formLineEleValue.value['projectId'] = projectId.value
  487. formLineEleValue.value['contractId'] = contractId.value
  488. formLineEleValue.value['partId'] = searchForm.value.partId
  489. }
  490. }
  491. }
  492. //转换坐标
  493. const showToModal = ref(false)
  494. const formToValue = ref({ value: '', b: '0', jj: '90', x: '', y: '' })
  495. const showToModalClick = () => {
  496. formToValue.value = { value: '', b: '0', jj: '90', x: '', y: '' }
  497. showToModal.value = true
  498. }
  499. //转换坐标
  500. const queryPsChange = async () => {
  501. const { error, code, data } = await bezierApi.queryPsChange({
  502. ...formToValue.value,
  503. projectId: projectId.value,
  504. partId: searchForm.value.partId,
  505. })
  506. //判断状态
  507. if (!error && code === 200) {
  508. const res = getObjValue(data)
  509. formToValue.value['x'] = res?.x + ''
  510. formToValue.value['y'] = res?.y + ''
  511. window?.$message?.success('转换成功')
  512. }
  513. }
  514. //逐桩坐标
  515. const showPileModal = ref(false)
  516. const formPileValue = ref({})
  517. const pileModalClick = () => {
  518. formPileValue.value = { x: '0', y: '0', value: '0', b: '0' }
  519. pileTable.value = []
  520. generateLoading.value = false
  521. showPileModal.value = true
  522. }
  523. //确认生成
  524. const generateLoading = ref(false)
  525. const pileTable = ref([])
  526. const generateClick = async () => {
  527. generateLoading.value = true
  528. const { error, code, data } = await bezierApi.getZzList({
  529. ...formPileValue.value,
  530. projectId: projectId.value,
  531. partId: searchForm.value.partId,
  532. })
  533. //判断状态
  534. generateLoading.value = false
  535. if (!error && code === 200) {
  536. pileTable.value = getArrValue(data)
  537. } else {
  538. pileTable.value = []
  539. }
  540. }
  541. //导入配置
  542. const showImportModal = ref(false)
  543. const importLoading = ref(false)
  544. //上传配置
  545. const uploadRef = ref(null)
  546. const addition = ref({})
  547. const fileList = ref([])
  548. const action = '/api/blade-business/mileage/import'
  549. const accept = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel'
  550. //导入
  551. const importModalClick = () => {
  552. addition.value = {
  553. projectId: projectId.value,
  554. contractId: contractId.value,
  555. partId: searchForm.value.partId,
  556. }
  557. importLoading.value = false
  558. showImportModal.value = true
  559. }
  560. //下载导入模板
  561. const tmportTmpClick = () => {
  562. window.open('https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230817/063231e1b4813060e67d872cc732e82d.xlsx', '_blank')
  563. }
  564. //上传一个文件时,重置
  565. const handleUploadExceed = (files) => {
  566. uploadRef.value?.clearFiles()
  567. const file = files[0]
  568. file.uid = genFileId()
  569. uploadRef.value?.handleStart(file)
  570. }
  571. //确认导入
  572. const handleImportClick = () => {
  573. uploadRef.value?.submit()
  574. }
  575. //上传中
  576. const handleUploadProgress = () => {
  577. importLoading.value = true
  578. }
  579. //上传完成
  580. const handleUploadFinish = (res) => {
  581. importLoading.value = false
  582. showImportModal.value = false
  583. if (res.code === 200) {
  584. window?.$message?.success(res.msg)
  585. uploadRef.value?.clearFiles()
  586. getTableData()
  587. } else {
  588. window?.$message?.error(res.msg)
  589. }
  590. }
  591. //上传失败
  592. const handleUploadError = (res) => {
  593. importLoading.value = false
  594. window?.$message?.error(res.msg || '导入失败')
  595. }
  596. //导出
  597. const exportModalClick = () => {
  598. window?.$messageBox?.alert('请确认当前查询条件,系统将以当前筛选条件导出数据', '导出数据', {
  599. showCancelButton: true,
  600. confirmButtonText: '确定导出',
  601. cancelButtonText: '取消',
  602. callback: (action) => {
  603. if (action === 'confirm') {
  604. getExportExcel()
  605. }
  606. },
  607. })
  608. }
  609. //确定导出
  610. const downloadLoading = ref(false)
  611. const getExportExcel = async () => {
  612. //批量下载
  613. downloadLoading.value = true
  614. const { error, disposition, res } = await bezierApi.getExportExcel({
  615. projectId: projectId.value,
  616. partId: searchForm.value.partId,
  617. partNo: partNo.value,
  618. })
  619. //处理数据
  620. downloadLoading.value = false
  621. if (!error) {
  622. if (disposition) {
  623. downloadBlob(res, disposition)
  624. } else {
  625. window.$message?.error('数据异常')
  626. }
  627. }
  628. }
  629. //片段管理表单
  630. const partFormRef = ref(null)
  631. const partForm = ref({ name: '', prefix: '' })
  632. const partRules = {
  633. name: {
  634. required: true,
  635. trigger: 'blur',
  636. message: '请输入名称',
  637. },
  638. prefix: {
  639. required: true,
  640. validator: (rule, value, callback) => {
  641. const reg = /^[A-Z]+$/
  642. if (value && !reg.test(value)) {
  643. callback(new Error('只允许输入大写的英文字母'))
  644. } else {
  645. callback()
  646. }
  647. },
  648. trigger: 'blur',
  649. },
  650. }
  651. //管理片段
  652. const showAdminPartModal = ref(false)
  653. const AdminPartTableData = ref([])
  654. const AdminPartClick = () => {
  655. AdminPartTableData.value = deepClone(partData.value)
  656. showAdminPartModal.value = true
  657. }
  658. //新增片段弹框
  659. const showAddPartModal = ref(false)
  660. const AddPartClick = () => {
  661. partForm.value = { name: '', prefix: '' }
  662. savePartLoading.value = false
  663. showAddPartModal.value = true
  664. }
  665. //新增保存
  666. const savePartLoading = ref(false)
  667. const savePartInfo = async () => {
  668. const validate = await formValidate(partFormRef.value)
  669. if (validate) {
  670. savePartLoading.value = true
  671. const { error, code } = await bezierApi.savePartAdd({
  672. ...partForm.value,
  673. projectId: projectId.value,
  674. contractId: contractId.value,
  675. })
  676. savePartLoading.value = false
  677. if (!error && code === 200) {
  678. window?.$message?.success('新增成功')
  679. showAddPartModal.value = false
  680. queryPartList()
  681. }
  682. }
  683. }
  684. //新增
  685. const AddAdminPart = () => {
  686. AdminPartTableData.value.push({
  687. id: '', name: '', prefix: '', isEdit: true,
  688. })
  689. }
  690. //编辑
  691. const handleAdminPartEdit = (row) => {
  692. row.isEdit = true
  693. }
  694. //保存
  695. const handleAdminPartSave = async (row) => {
  696. //严格模式/^[A-Z]+((#\d+)?|\d+)$/
  697. const reg = /^[A-Z#-\d]+$/
  698. if (!row.name) {
  699. window?.$message?.warning('请输入名称')
  700. } else if (!row.prefix && row.name.indexOf('主线') < 0) {
  701. //没有前缀,且片段名称中不包含‘主线’
  702. window?.$message?.warning('请输入桩号前缀')
  703. } else if (!reg.test(row.prefix) && row.name.indexOf('主线') < 0) {
  704. window?.$message?.warning('桩号前缀,只允许输入大写的英文字母')
  705. } else if (row.id) {
  706. const { error, code } = await bezierApi.savePartUpdate({
  707. ...row,
  708. projectId: projectId.value,
  709. contractId: contractId.value,
  710. })
  711. if (!error && code === 200) {
  712. window?.$message?.success('保存成功')
  713. row.isEdit = false
  714. queryPartList()
  715. }
  716. } else if (!row.id) {
  717. const { error, code, data } = await bezierApi.savePartAdd({
  718. ...row,
  719. projectId: projectId.value,
  720. contractId: contractId.value,
  721. })
  722. if (!error && code === 200) {
  723. window?.$message?.success('保存成功')
  724. row.isEdit = false
  725. alert(222)
  726. row.id = data.id
  727. partData.value.push(data)
  728. //queryPartList()不要刷新
  729. }
  730. }
  731. }
  732. //删除
  733. const handleAdminPartDelete = (row, index) => {
  734. if (row.id) {
  735. window?.$messageBox?.alert('关联平曲线一起删除', '是否删除当前数据?', {
  736. showCancelButton: true,
  737. confirmButtonText: '确定删除',
  738. cancelButtonText: '取消',
  739. callback: (action) => {
  740. if (action === 'confirm') {
  741. handleAdminPartDeleteSub(row, index)
  742. }
  743. },
  744. })
  745. } else {
  746. AdminPartTableData.value.splice(index, 1)
  747. }
  748. }
  749. const handleAdminPartDeleteSub = async (row, index) => {
  750. const { error, code } = await bezierApi.delPartData({
  751. ids: row.id,
  752. })
  753. if (!error && code === 200) {
  754. window?.$message?.success('删除成功')
  755. queryPartList()
  756. }
  757. }
  758. </script>
  759. <style lang="scss" scoped>
  760. @import '../../styles/gauge/bezier.scss';
  761. </style>