| New file |
| | |
| | | <template> |
| | | <basic-container> |
| | | <avue-crud :option="option" :table-loading="loading" :data="data" v-model:page="page" :permission="permissionList" |
| | | :before-open="beforeOpen" v-model="form" ref="crud" @row-del="rowDel" @search-change="searchChange" |
| | | @search-reset="searchReset" @selection-change="selectionChange" @current-change="currentChange" |
| | | @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad"> |
| | | <template #menu-left> |
| | | <el-button type="primary" plain v-if="permission.attach_upload" icon="el-icon-upload" @click="handleUpload">上 传 |
| | | </el-button> |
| | | <el-button type="danger" icon="el-icon-delete" plain v-if="permission.attach_delete" @click="handleDelete">删 除 |
| | | </el-button> |
| | | </template> |
| | | <template #menu="scope"> |
| | | <el-button type="primary" text icon="el-icon-download" v-if="permission.attach_download" |
| | | @click="handleDownload(scope.row)">下载 |
| | | </el-button> |
| | | </template> |
| | | <template #attachSize="{ row }"> |
| | | <el-tag>{{ `${func.bytesToKB(row.attachSize)} KB` }}</el-tag> |
| | | </template> |
| | | </avue-crud> |
| | | <el-dialog title="附件管理" append-to-body v-model="attachBox" width="555px"> |
| | | <avue-form ref="form" :option="attachOption" v-model="attachForm" :upload-after="uploadAfter"> |
| | | </avue-form> |
| | | </el-dialog> |
| | | </basic-container> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getList, getDetail, removeAttachAndData } from '@/api/resource/attach' |
| | | import { mapGetters } from 'vuex' |
| | | import func from '@/utils/func' |
| | | |
| | | export default { |
| | | data () { |
| | | return { |
| | | form: {}, |
| | | query: {}, |
| | | loading: true, |
| | | page: { |
| | | pageSize: 10, |
| | | currentPage: 1, |
| | | total: 0, |
| | | }, |
| | | attachBox: false, |
| | | selectionList: [], |
| | | option: { |
| | | emptyBtnText: '重置', |
| | | emptyBtnIcon: 'el-icon-refresh', |
| | | tip: false, |
| | | searchShow: true, |
| | | searchGutter: 30, |
| | | searchMenuPosition: 'left', |
| | | searchMenuSpan: 4, |
| | | border: true, |
| | | index: true, |
| | | viewBtn: true, |
| | | // grid: true, |
| | | selection: true, |
| | | dialogClickModal: false, |
| | | |
| | | addBtn: false, |
| | | |
| | | height: 'auto', |
| | | calcHeight: 20, |
| | | column: [ |
| | | { |
| | | label: '附件地址', |
| | | prop: 'link', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入附件地址', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '附件域名', |
| | | prop: 'domainUrl', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入附件域名', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '附件名称', |
| | | prop: 'name', |
| | | search: true, |
| | | searchSpan: 4, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入附件名称', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '附件原名', |
| | | prop: 'originalName', |
| | | search: true, |
| | | searchSpan: 4, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入附件原名', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '附件拓展名', |
| | | prop: 'extension', |
| | | search: true, |
| | | searchSpan: 4, |
| | | searchLabelWidth: 95, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入附件拓展名', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '附件大小', |
| | | prop: 'attachSize', |
| | | slot: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入附件大小', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '创建日期', |
| | | prop: 'createTime' |
| | | }, |
| | | { |
| | | label: '创建日期', |
| | | prop: 'daterange', |
| | | type: 'daterange', |
| | | search: true, |
| | | searchRange: true, |
| | | searchSpan: 8, |
| | | format: 'YYYY-MM-DD', |
| | | valueFormat: 'YYYY-MM-DD', |
| | | startPlaceholder: '开始时间', |
| | | endPlaceholder: '结束时间', |
| | | viewDisplay: false, |
| | | hide: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请选择操作时间', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | change: (value) => { |
| | | this.searchChange({ ...this.query,daterange:value.value}, () => {}); |
| | | } |
| | | }, |
| | | ], |
| | | }, |
| | | data: [], |
| | | attachForm: {}, |
| | | attachOption: { |
| | | submitBtn: false, |
| | | emptyBtn: false, |
| | | column: [ |
| | | { |
| | | label: '附件上传', |
| | | prop: 'attachFile', |
| | | type: 'upload', |
| | | drag: true, |
| | | loadText: '模板上传中,请稍等', |
| | | span: 24, |
| | | propsHttp: { |
| | | res: 'data', |
| | | }, |
| | | action: '/blade-resource/oss/endpoint/put-file-attach', |
| | | }, |
| | | ], |
| | | }, |
| | | } |
| | | }, |
| | | computed: { |
| | | func () { |
| | | return func |
| | | }, |
| | | ...mapGetters(['permission']), |
| | | permissionList () { |
| | | return { |
| | | addBtn: false, |
| | | editBtn: false, |
| | | viewBtn: false, |
| | | delBtn: this.validData(this.permission.attach_delete, false), |
| | | } |
| | | }, |
| | | ids () { |
| | | let ids = [] |
| | | this.selectionList.forEach(ele => { |
| | | ids.push(ele.id) |
| | | }) |
| | | return ids.join(',') |
| | | }, |
| | | }, |
| | | methods: { |
| | | handleUpload () { |
| | | this.attachBox = true |
| | | }, |
| | | uploadAfter (res, done, loading, column) { |
| | | window.console.log(column) |
| | | this.attachBox = false |
| | | this.refreshChange() |
| | | done() |
| | | }, |
| | | handleDownload (row) { |
| | | window.open(`${row.link}`) |
| | | }, |
| | | rowDel (row) { |
| | | this.$confirm('确定将选择数据及对应的文件删除?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return removeAttachAndData(row.id) |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | }) |
| | | }, |
| | | handleDelete () { |
| | | if (this.selectionList.length === 0) { |
| | | this.$message.warning('请选择至少一条数据') |
| | | return |
| | | } |
| | | this.$confirm('确定将选择数据及对应的文件删除?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return removeAttachAndData(this.ids) |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | this.$refs.crud.toggleSelection() |
| | | }) |
| | | }, |
| | | beforeOpen (done, type) { |
| | | if (['edit', 'view'].includes(type)) { |
| | | getDetail(this.form.id).then(res => { |
| | | this.form = res.data.data |
| | | }) |
| | | } |
| | | done() |
| | | }, |
| | | searchReset () { |
| | | this.query = {} |
| | | this.onLoad(this.page) |
| | | }, |
| | | searchChange (params, done) { |
| | | this.query = params |
| | | this.page.currentPage = 1 |
| | | this.onLoad(this.page, params) |
| | | done() |
| | | }, |
| | | selectionChange (list) { |
| | | this.selectionList = list |
| | | }, |
| | | selectionClear () { |
| | | this.selectionList = [] |
| | | this.$refs.crud.toggleSelection() |
| | | }, |
| | | currentChange (currentPage) { |
| | | this.page.currentPage = currentPage |
| | | }, |
| | | sizeChange (pageSize) { |
| | | this.page.pageSize = pageSize |
| | | }, |
| | | refreshChange () { |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | onLoad (page, params = {}) { |
| | | const { daterange } = this.query |
| | | let values = { |
| | | ...params, |
| | | ...this.query, |
| | | } |
| | | if (daterange) { |
| | | values = { |
| | | ...values, |
| | | startTime: daterange[0], |
| | | endTime: daterange[1], |
| | | } |
| | | values.daterange = null |
| | | } |
| | | this.loading = true |
| | | getList(page.currentPage, page.pageSize, values).then(res => { |
| | | const data = res.data.data |
| | | this.page.total = data.total |
| | | this.data = data.records |
| | | this.loading = false |
| | | this.selectionClear() |
| | | }) |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| New file |
| | |
| | | <template> |
| | | <div></div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import * as Cesium from 'cesium' |
| | | import { ElMessage } from 'element-plus' |
| | | |
| | | let curPolygonPosition = [] |
| | | let savePolygonPosition = [] |
| | | let curPolygon = null |
| | | let curPolygonEntity = null |
| | | let curPolygonObj = null |
| | | let menuPanel = null |
| | | let saveMenuPanel = null |
| | | |
| | | const viewInstance = inject('viewInstance') |
| | | const homeViewer = inject('homeViewer') |
| | | |
| | | const updateBoxSelect = inject('updateBoxSelect') |
| | | |
| | | function preventDefault(event) { |
| | | event.preventDefault() |
| | | |
| | | return |
| | | } |
| | | |
| | | function init() { |
| | | // draw.drawPlane(); |
| | | curPolygon = new Cesium.PolygonHierarchy() |
| | | curPolygonEntity = new Cesium.Entity() |
| | | |
| | | homeViewer.value.scene.globe.depthTestAgainstTerrain = true |
| | | |
| | | viewInstance.value.addLeftClickEvent(null, addPlanerPointEvent, 'drawCustomPolygon') |
| | | viewInstance.value.addRightClickEvent(null, addPlanarMenuEvent, 'drawCustomPolygon') |
| | | viewInstance.value.addMouseHandler(null, mouseMoveEvent, 'drawCustomPolygon') |
| | | } |
| | | |
| | | function mouseMoveEvent(movement, viewer) { |
| | | const mouseInfo = viewInstance.value.getMouseInfoAll(movement.endPosition) |
| | | |
| | | const { x, y } = mouseInfo.windowPosition |
| | | |
| | | if (!menuPanel) { |
| | | menuPanel = createMenuPanel() |
| | | viewer.container.appendChild(menuPanel) |
| | | } |
| | | |
| | | menuPanel.style.transform = `translate3d(${x}px, ${y}px, 0)` |
| | | |
| | | if ( |
| | | curPolygonObj && |
| | | mouseInfo.surfacePosition && |
| | | mouseInfo.surfacePosition != null && |
| | | curPolygonPosition.length >= 1 |
| | | ) { |
| | | curPolygonPosition.pop() |
| | | curPolygonPosition.push(mouseInfo.surfacePosition) |
| | | |
| | | curPolygon.positions.pop() |
| | | curPolygon.positions.push(mouseInfo.surfacePosition) |
| | | } |
| | | } |
| | | |
| | | function addPlanerPointEvent(click, pick) { |
| | | const { position } = click |
| | | |
| | | const mouseInfo = viewInstance.value.getMouseInfoAll(position) |
| | | |
| | | if (mouseInfo.surfacePosition && mouseInfo.surfacePosition != null) drawCustomPolygon(mouseInfo) |
| | | } |
| | | |
| | | function addPlanarMenuEvent(click, pick, viewer) { |
| | | if (savePolygonPosition.length <= 2) { |
| | | ElMessage.warning('当前绘制无法形成面,请继续绘制或取消绘制!!') |
| | | |
| | | return |
| | | } |
| | | const { position } = click |
| | | |
| | | const mouseInfo = viewInstance.value.getMouseInfoAll(position) |
| | | |
| | | remove() |
| | | removeMenuPanel() |
| | | |
| | | if (mouseInfo.surfacePosition && mouseInfo.surfacePosition != null) drawCustomPolygon(mouseInfo) |
| | | |
| | | const { x, y } = position |
| | | saveMenuPanel = createSaveMenuPanel() |
| | | saveMenuPanel.addEventListener('click', saveMenuClickEvent) |
| | | saveMenuPanel.style.transform = `translate3d(${x}px, ${y}px, 0)` |
| | | viewer.container.appendChild(saveMenuPanel) |
| | | } |
| | | |
| | | function createSaveMenuPanel() { |
| | | const menuPanel = document.createElement('div') |
| | | menuPanel.className = 'planar-menu-panel' |
| | | |
| | | const arr = [ |
| | | { title: '保存框选', class: 'save-draw' }, |
| | | { title: '清除框选', class: 'anew-draw' }, |
| | | ] |
| | | |
| | | arr.forEach(item => { |
| | | const title = document.createElement('div') |
| | | title.innerText = item.title |
| | | title.className = item.class |
| | | menuPanel.appendChild(title) |
| | | }) |
| | | |
| | | return menuPanel |
| | | } |
| | | |
| | | const emit = defineEmits(['upDateBoxSelect']) |
| | | |
| | | function saveMenuClickEvent(e) { |
| | | const className = e.target.className |
| | | if (className === 'save-draw') { |
| | | emit('upDateBoxSelect') |
| | | updateBoxSelect(savePolygonPosition) |
| | | } |
| | | if (className == 'anew-draw') { |
| | | cancel() |
| | | } |
| | | |
| | | removeSaveMenuPanel() |
| | | } |
| | | |
| | | function removeSaveMenuPanel() { |
| | | if (saveMenuPanel) { |
| | | homeViewer.value.container?.removeChild(saveMenuPanel) |
| | | saveMenuPanel.removeEventListener('click', saveMenuClickEvent) |
| | | saveMenuPanel = null |
| | | } |
| | | } |
| | | |
| | | function createMenuPanel() { |
| | | const menuPanel = document.createElement('div') |
| | | menuPanel.className = 'planar-menu-panel' |
| | | |
| | | const title = document.createElement('div') |
| | | title.innerText = '左击选择点位,右击结束' |
| | | title.className = 'proof-custom-add-polygon' |
| | | menuPanel.appendChild(title) |
| | | |
| | | return menuPanel |
| | | } |
| | | |
| | | function removeMenuPanel() { |
| | | if (menuPanel) { |
| | | homeViewer.value.container?.removeChild(menuPanel) |
| | | menuPanel = null |
| | | } |
| | | } |
| | | |
| | | function drawCustomPolygon(point) { |
| | | if (curPolygonPosition.length == 0) { |
| | | curPolygonPosition.push(point.surfacePosition.clone()) |
| | | curPolygon.positions.push(point.surfacePosition.clone()) |
| | | } |
| | | |
| | | savePolygonPosition.push(point.wgs84SurfacePosition) |
| | | curPolygonPosition.push(point.surfacePosition.clone()) |
| | | curPolygon.positions.push(point.surfacePosition.clone()) |
| | | |
| | | if (!curPolygonObj) { |
| | | curPolygonEntity.polyline = { |
| | | width: 2, |
| | | material: Cesium.Color.WHITE, |
| | | clampToGround: false, |
| | | } |
| | | |
| | | curPolygonEntity.polyline.positions = new Cesium.CallbackProperty(function () { |
| | | return curPolygonPosition |
| | | }, false) |
| | | |
| | | curPolygonEntity.polygon = { |
| | | hierarchy: new Cesium.CallbackProperty(function () { |
| | | return curPolygon |
| | | }, false), |
| | | |
| | | material: Cesium.Color.fromCssColorString('#00ffff').withAlpha(0.4), |
| | | clampToGround: false, |
| | | } |
| | | curPolygonEntity.name = 'customProofPolygon' |
| | | |
| | | curPolygonEntity._id = 'customProofPolygon' |
| | | curPolygonObj = homeViewer.value.entities.add(curPolygonEntity) |
| | | } |
| | | } |
| | | |
| | | function clearPlanar() { |
| | | homeViewer.value.entities.remove(curPolygonObj) |
| | | curPolygonObj = null |
| | | curPolygon = null |
| | | curPolygonEntity = null |
| | | curPolygonPosition = [] |
| | | savePolygonPosition = [] |
| | | } |
| | | |
| | | function remove() { |
| | | viewInstance.value.removeLeftClickEvent('drawCustomPolygon') |
| | | viewInstance.value.removeRightClickEvent('drawCustomPolygon') |
| | | viewInstance.value.removeMouseHandler('drawCustomPolygon') |
| | | } |
| | | |
| | | function cancel() { |
| | | remove() |
| | | removeMenuPanel() |
| | | clearPlanar() |
| | | |
| | | init() |
| | | } |
| | | |
| | | onMounted(() => { |
| | | document.addEventListener('contextmenu', preventDefault) |
| | | |
| | | init() |
| | | }) |
| | | |
| | | onBeforeUnmount(() => { |
| | | document.removeEventListener('contextmenu', preventDefault) |
| | | |
| | | remove() |
| | | removeMenuPanel() |
| | | removeSaveMenuPanel() |
| | | clearPlanar() |
| | | homeViewer.value.scene.globe.depthTestAgainstTerrain = false |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | p { |
| | | text-indent: 2em; |
| | | color: #ffffff; |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .export-btns { |
| | | margin-top: 44px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-around; |
| | | |
| | | .el-button { |
| | | background-color: transparent !important; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div></div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import * as Cesium from 'cesium'; |
| | | |
| | | import { ElMessage } from 'element-plus'; |
| | | import { sdfwUpdate } from '@/api/home/territory'; |
| | | |
| | | let curPolygonPosition = []; |
| | | let savePolygonPosition = []; |
| | | let curPolygon = null; |
| | | let curPolygonEntity = null; |
| | | let curPolygonObj = null; |
| | | |
| | | let menuPanel = null; |
| | | let saveMenuPanel = null; |
| | | |
| | | const selectionIds = inject('selectionIds'); |
| | | const clearSelect = inject('clearSelect'); |
| | | const getTableList = inject('getTableList') |
| | | |
| | | const viewInstance = inject('viewInstance'); |
| | | const homeViewer = inject('homeViewer'); |
| | | watch( |
| | | () => selectionIds.value, |
| | | (newValue, oldValue) => { |
| | | if (newValue && oldValue && newValue !== oldValue) { |
| | | cancel(); |
| | | } |
| | | } |
| | | ); |
| | | function preventDefault(event) { |
| | | event.preventDefault(); |
| | | |
| | | return; |
| | | } |
| | | |
| | | function init() { |
| | | // let draw = new Draw(homeViewer.value); |
| | | // draw.drawPlane(); |
| | | curPolygon = new Cesium.PolygonHierarchy(); |
| | | curPolygonEntity = new Cesium.Entity(); |
| | | homeViewer.value.scene.globe.depthTestAgainstTerrain = true; |
| | | |
| | | viewInstance.value.addLeftClickEvent(null, addPlanerPointEvent, 'drawCustomPolygon'); |
| | | viewInstance.value.addRightClickEvent(null, addPlanarMenuEvent, 'drawCustomPolygon'); |
| | | viewInstance.value.addMouseHandler(null, mouseMoveEvent, 'drawCustomPolygon'); |
| | | } |
| | | |
| | | function mouseMoveEvent(movement, viewer) { |
| | | const mouseInfo = viewInstance.value.getMouseInfoAll(movement.endPosition); |
| | | |
| | | const { x, y } = mouseInfo.windowPosition; |
| | | |
| | | if (!menuPanel) { |
| | | menuPanel = createMenuPanel(); |
| | | viewer.container.appendChild(menuPanel); |
| | | } |
| | | |
| | | menuPanel.style.transform = `translate3d(${x}px, ${y}px, 0)`; |
| | | |
| | | if ( |
| | | curPolygonObj && |
| | | mouseInfo.surfacePosition && |
| | | mouseInfo.surfacePosition != null && |
| | | curPolygonPosition.length >= 1 |
| | | ) { |
| | | curPolygonPosition.pop(); |
| | | curPolygonPosition.push(mouseInfo.surfacePosition); |
| | | |
| | | curPolygon.positions.pop(); |
| | | curPolygon.positions.push(mouseInfo.surfacePosition); |
| | | } |
| | | } |
| | | |
| | | function addPlanerPointEvent(click, pick) { |
| | | const { position } = click; |
| | | |
| | | const mouseInfo = viewInstance.value.getMouseInfoAll(position); |
| | | |
| | | if (mouseInfo.surfacePosition && mouseInfo.surfacePosition != null) drawCustomPolygon(mouseInfo); |
| | | } |
| | | |
| | | function addPlanarMenuEvent(click, pick, viewer) { |
| | | if (savePolygonPosition.length <= 2) { |
| | | ElMessage.warning('当前绘制无法形成面,请继续绘制或取消绘制!!'); |
| | | |
| | | return; |
| | | } |
| | | const { position } = click; |
| | | |
| | | const mouseInfo = viewInstance.value.getMouseInfoAll(position); |
| | | |
| | | remove(); |
| | | removeMenuPanel(); |
| | | |
| | | if (mouseInfo.surfacePosition && mouseInfo.surfacePosition != null) drawCustomPolygon(mouseInfo); |
| | | |
| | | const { x, y } = position; |
| | | saveMenuPanel = createSaveMenuPanel(); |
| | | saveMenuPanel.addEventListener('click', saveMenuClickEvent); |
| | | saveMenuPanel.style.transform = `translate3d(${x}px, ${y}px, 0)`; |
| | | viewer.container.appendChild(saveMenuPanel); |
| | | } |
| | | |
| | | function createSaveMenuPanel() { |
| | | const menuPanel = document.createElement('div'); |
| | | menuPanel.className = 'planar-menu-panel'; |
| | | |
| | | const arr = [ |
| | | { title: '提交绘制', class: 'save-draw' }, |
| | | { title: '重新绘制', class: 'anew-draw' }, |
| | | ]; |
| | | |
| | | arr.forEach(item => { |
| | | const title = document.createElement('div'); |
| | | title.innerText = item.title; |
| | | title.className = item.class; |
| | | menuPanel.appendChild(title); |
| | | }); |
| | | |
| | | return menuPanel; |
| | | } |
| | | |
| | | function saveMenuClickEvent(e) { |
| | | const className = e.target.className; |
| | | if (className === 'save-draw') { |
| | | updatePolygon(); |
| | | } |
| | | if (className == 'anew-draw') { |
| | | cancel(); |
| | | } |
| | | |
| | | removeSaveMenuPanel(); |
| | | } |
| | | |
| | | function removeSaveMenuPanel() { |
| | | if (saveMenuPanel) { |
| | | homeViewer.value.container?.removeChild(saveMenuPanel); |
| | | saveMenuPanel.removeEventListener('click', saveMenuClickEvent); |
| | | saveMenuPanel = null; |
| | | } |
| | | } |
| | | |
| | | function createMenuPanel() { |
| | | const menuPanel = document.createElement('div'); |
| | | menuPanel.className = 'planar-menu-panel'; |
| | | |
| | | const title = document.createElement('div'); |
| | | title.innerText = '左击选择点位,右击结束'; |
| | | title.className = 'proof-custom-add-polygon'; |
| | | menuPanel.appendChild(title); |
| | | |
| | | return menuPanel; |
| | | } |
| | | |
| | | function removeMenuPanel() { |
| | | if (menuPanel) { |
| | | homeViewer.value.container?.removeChild(menuPanel); |
| | | menuPanel = null; |
| | | } |
| | | } |
| | | |
| | | function drawCustomPolygon(point) { |
| | | if (curPolygonPosition.length == 0) { |
| | | curPolygonPosition.push(point.surfacePosition.clone()); |
| | | curPolygon.positions.push(point.surfacePosition.clone()); |
| | | } |
| | | |
| | | savePolygonPosition.push(point.wgs84SurfacePosition); |
| | | curPolygonPosition.push(point.surfacePosition.clone()); |
| | | curPolygon.positions.push(point.surfacePosition.clone()); |
| | | |
| | | if (!curPolygonObj) { |
| | | curPolygonEntity.polyline = { |
| | | width: 2, |
| | | material: Cesium.Color.WHITE, |
| | | clampToGround: true, |
| | | }; |
| | | |
| | | curPolygonEntity.polyline.positions = new Cesium.CallbackProperty(function () { |
| | | return curPolygonPosition; |
| | | }, false); |
| | | |
| | | curPolygonEntity.polygon = { |
| | | hierarchy: new Cesium.CallbackProperty(function () { |
| | | return curPolygon; |
| | | }, false), |
| | | |
| | | material: Cesium.Color.fromCssColorString('#00ffff').withAlpha(0.4), |
| | | clampToGround: false, |
| | | }; |
| | | curPolygonEntity.name = 'customProofPolygon'; |
| | | |
| | | curPolygonEntity._id = 'customProofPolygon'; |
| | | curPolygonObj = homeViewer.value.entities.add(curPolygonEntity); |
| | | } |
| | | } |
| | | |
| | | function clearPlanar() { |
| | | homeViewer.value.entities.remove(curPolygonObj); |
| | | curPolygonObj = null; |
| | | curPolygon = null; |
| | | curPolygonEntity = null; |
| | | curPolygonPosition = []; |
| | | savePolygonPosition = []; |
| | | } |
| | | |
| | | function remove() { |
| | | viewInstance.value.removeLeftClickEvent('drawCustomPolygon'); |
| | | viewInstance.value.removeRightClickEvent('drawCustomPolygon'); |
| | | viewInstance.value.removeMouseHandler('drawCustomPolygon'); |
| | | } |
| | | |
| | | const emit = defineEmits(['upDateDrawState',]); |
| | | |
| | | function updatePolygon() { |
| | | let polygon = savePolygonPosition.reduce((pre, cur) => { |
| | | pre.push(`${cur.lng} ${cur.lat}`); |
| | | return pre; |
| | | }, []); |
| | | polygon.push(polygon[0]); |
| | | |
| | | // 接口 |
| | | sdfwUpdate({ |
| | | ids: selectionIds.value, |
| | | sdfw: `POLYGON((${polygon.join(',')}))`, |
| | | }) |
| | | .then(res => { |
| | | if (selectionIds.value) { |
| | | emit('upDateDrawState') |
| | | selectionIds.value = null |
| | | clearSelect() |
| | | } |
| | | |
| | | if (res.data.code !== 0) return ElMessage.error(res.message) |
| | | ElMessage.success('重新绘制图斑成功!!') |
| | | getTableList() |
| | | }) |
| | | .catch(e => { |
| | | cancel() |
| | | }) |
| | | } |
| | | |
| | | |
| | | function cancel() { |
| | | remove(); |
| | | removeMenuPanel(); |
| | | clearPlanar(); |
| | | removeSaveMenuPanel(); |
| | | init(); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | document.addEventListener('contextmenu', preventDefault); |
| | | |
| | | init(); |
| | | }); |
| | | |
| | | onBeforeUnmount(() => { |
| | | document.removeEventListener('contextmenu', preventDefault); |
| | | |
| | | remove(); |
| | | removeMenuPanel(); |
| | | removeSaveMenuPanel(); |
| | | clearPlanar(); |
| | | |
| | | homeViewer.value.scene.globe.depthTestAgainstTerrain = false; |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | p { |
| | | text-indent: 2em; |
| | | color: #ffffff; |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .export-btns { |
| | | margin-top: 44px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-around; |
| | | |
| | | .el-button { |
| | | background-color: transparent !important; |
| | | } |
| | | } |
| | | .proof-custom-add-polygon { |
| | | position: absolute; |
| | | left: 20px; |
| | | background: rgba(0, 0, 0, 0.6); |
| | | white-space: nowrap; |
| | | border-radius: 4px; |
| | | pointer-events: none; |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | left: -3px; |
| | | top: calc(50% - 2px); |
| | | width: 0; |
| | | height: 0; |
| | | border-top: 4px solid rgba(0, 0, 0, 0.6); |
| | | border-left: 4px solid rgba(0, 0, 0, 0.6); |
| | | border-right: 4px solid transparent; |
| | | border-bottom: 4px solid transparent; |
| | | transform: rotate(-45deg); |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div class="fun-button-container"> |
| | | <template v-for="(item, index) in tooltipList" :key="index"> |
| | | <el-popover |
| | | effect="dark" |
| | | placement="right" |
| | | :trigger="item.isClick ? 'click' : 'hover'" |
| | | popper-class="function-popover" |
| | | v-if="item.show" |
| | | > |
| | | <div> |
| | | <div>{{ item.label[Number(item.isSelected)] }}</div> |
| | | </div> |
| | | <template #reference v-if="item.show"> |
| | | <div |
| | | :class="['currency-box', { 'actived-blue': item.isSelected && item.isSelectColor && item.showActive }]" |
| | | @click="item.event(item, index)" |
| | | > |
| | | <img :src="item.icon[Number(item.isSelected)]" alt="_icon" /> |
| | | </div> |
| | | </template> |
| | | </el-popover> |
| | | </template> |
| | | </div> |
| | | |
| | | <BoxSelect v-if="isShowBoxSelect" @upDateBoxSelect="upDateBoxSelect" /> |
| | | <DrawPolygon v-if="isShowDrawPolygon" @upDateDrawState="upDateDrawState" /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useStore } from 'vuex' |
| | | import drawPng from '@/assets/images/home/territory/draw.png' |
| | | import noDrawPng from '@/assets/images/home/territory/no-draw.png' |
| | | import boxSelectPng from '@/assets/images/home/territory/box-select.png' |
| | | |
| | | import BoxSelect from './BoxSelect.vue' |
| | | import DrawPolygon from './DrawPolygon.vue' |
| | | |
| | | const isBoxSelect = defineModel('isBoxSelect') |
| | | const isDrawPolygon = defineModel('isDrawPolygon') |
| | | const isShowBoxSelect = ref(false) |
| | | const isShowDrawPolygon = ref(false) |
| | | |
| | | const isDrawPolygonSelect = ref(false) |
| | | |
| | | watch(isBoxSelect, newVal => { |
| | | if (newVal === false) { |
| | | isShowBoxSelect.value = newVal |
| | | |
| | | setBoxSelect(null, 1, newVal) |
| | | } |
| | | }) |
| | | |
| | | watch(isDrawPolygon, newVal => { |
| | | if (newVal === false) { |
| | | isShowDrawPolygon.value = newVal |
| | | |
| | | setDrawState(null, 0, newVal) |
| | | } |
| | | }) |
| | | |
| | | const tooltipList = ref([ |
| | | { |
| | | showActive: true, |
| | | label: ['重新绘制', '取消绘制'], |
| | | isSelectColor: true, |
| | | isSelected: false, |
| | | icon: [drawPng, noDrawPng], |
| | | event: setDrawState, |
| | | show: isDrawPolygon, |
| | | }, |
| | | |
| | | { |
| | | showActive: true, |
| | | label: ['框选', '取消框选'], |
| | | isSelectColor: true, |
| | | isSelected: false, |
| | | icon: [boxSelectPng, boxSelectPng], |
| | | event: setBoxSelect, |
| | | show: isBoxSelect, |
| | | }, |
| | | ]) |
| | | |
| | | function setDrawState(value, index, show = null) { |
| | | if (show != null) { |
| | | tooltipList.value[index].isSelected = show |
| | | } else { |
| | | tooltipList.value[index].isSelected = !tooltipList.value[index].isSelected |
| | | } |
| | | |
| | | isShowDrawPolygon.value = tooltipList.value[index].isSelected |
| | | isDrawPolygonSelect.value = tooltipList.value[index].isSelected |
| | | } |
| | | |
| | | function upDateDrawState(show = false) { |
| | | setDrawState(null, 0, show) |
| | | } |
| | | |
| | | function setBoxSelect(value, index, show = null) { |
| | | if (show != null) { |
| | | tooltipList.value[index].isSelected = show |
| | | } else { |
| | | tooltipList.value[index].isSelected = !tooltipList.value[index].isSelected |
| | | } |
| | | |
| | | isShowBoxSelect.value = tooltipList.value[index].isSelected |
| | | } |
| | | |
| | | function upDateBoxSelect(show = false) { |
| | | setBoxSelect(null, 1, show) |
| | | } |
| | | |
| | | defineExpose({ |
| | | upDateDrawState, |
| | | isDrawPolygonSelect, |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .fun-button-container { |
| | | position: absolute; |
| | | top: 50px; |
| | | left: 23%; |
| | | transform: translate(100%, 0); |
| | | } |
| | | |
| | | .currency-box { |
| | | width: 45px; |
| | | height: 45px; |
| | | border-radius: 3px; |
| | | background: url('@/assets/images/home/territory/newcon_box.png'); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | overflow: hidden; |
| | | cursor: pointer; |
| | | margin-bottom: 8px; |
| | | pointer-events: all; |
| | | |
| | | img { |
| | | width: 31px; |
| | | // height: 31px; |
| | | } |
| | | } |
| | | |
| | | .actived-blue { |
| | | background-image: none; |
| | | // background-color: #409eff; |
| | | background-color: rgba(23, 124, 198, 0.7); |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <el-dialog append-to-body v-model="patchDetailsShow"> |
| | | <el-tabs v-model="activeTab" type="border-card"> |
| | | <el-tab-pane label="图斑详情" name="first">图斑详情</el-tab-pane> |
| | | <el-tab-pane label="图斑类型" name="second">图斑类型</el-tab-pane> |
| | | <el-tab-pane label="图斑区域" name="third">图斑区域</el-tab-pane> |
| | | </el-tabs> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const patchDetailsShow = ref(true) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| New file |
| | |
| | | <template> |
| | | <basic-container> |
| | | <avue-crud :option="option" :table-loading="loading" :data="data" v-model:page="page" :permission="permissionList" |
| | | v-model="form" ref="crud" @row-del="rowDel" @search-change="searchChange" @search-reset="searchReset" |
| | | @selection-change="selectionChange" @current-change="currentChange" @size-change="sizeChange" |
| | | @refresh-change="refreshChange" @on-load="onLoad"> |
| | | <template #menu-left> |
| | | <el-button type="primary" icon="el-icon-download" plain :loading="isDownloading" @click="handleZipDownload">{{ |
| | | isDownloading ? '压缩下载中...' : '压缩下载' }}</el-button> |
| | | </template> |
| | | <template #menu="scope"> |
| | | <el-button type="primary" text icon="el-icon-view" v-if="permission.attach_delete" |
| | | @click="handleRowView(scope.row)">查看 |
| | | </el-button> |
| | | <el-button type="success" text icon="el-icon-download" v-if="permission.attach_delete" |
| | | @click="handleRowDownload(scope.row)">下载 |
| | | </el-button> |
| | | <el-button type="danger" text icon="el-icon-delete" v-if="permission.attach_delete" |
| | | @click="handleRowDelete(scope.row)">删除 |
| | | </el-button> |
| | | </template> |
| | | </avue-crud> |
| | | <el-dialog title="媒体文件" append-to-body v-model="taskBox" width="555px"> |
| | | <avue-form ref="form" :option="taskOption" v-model="taskForm" :upload-after="uploadAfter"> |
| | | </avue-form> |
| | | </el-dialog> |
| | | </basic-container> |
| | | </template> |
| | | |
| | | <script> |
| | | import JSZip from 'jszip' |
| | | import { getMedia, deleteAllFile } from '@/api/resource/media' |
| | | import { getAirportList } from '@/api/device/device' |
| | | import { mapGetters } from 'vuex' |
| | | import func from '@/utils/func' |
| | | |
| | | export default { |
| | | data () { |
| | | const endDate = new Date() |
| | | const startDate = new Date() |
| | | startDate.setMonth(startDate.getMonth() - 1) |
| | | const defaultStartDate = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}` |
| | | const defaultEndDate = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}` |
| | | |
| | | return { |
| | | form: {}, |
| | | query: { |
| | | daterange: [defaultStartDate, defaultEndDate] |
| | | }, |
| | | loading: true, |
| | | page: { |
| | | pageSize: 10, |
| | | currentPage: 1, |
| | | total: 0, |
| | | }, |
| | | taskBox: false, |
| | | selectionList: [], |
| | | selectedWorkspaceId: null, |
| | | option: { |
| | | tip: false, |
| | | searchShow: true, |
| | | searchGutter: 30, |
| | | searchMenuPosition: 'left', |
| | | searchMenuSpan: 4, |
| | | border: true, |
| | | index: true, |
| | | viewBtn: true, |
| | | selection: true, |
| | | dialogClickModal: false, |
| | | delBtn: false, |
| | | addBtn: false, |
| | | |
| | | height: 'auto', |
| | | calcHeight: 20, |
| | | column: [ |
| | | { label: '机场选择', prop: 'airportNickname', type: 'select', search: true, searchSpan: 4, dicData: [], props: { label: 'nickname', value: 'nickname' }, hide: true, change: (value) => { |
| | | this.searchChange({ ...this.query,airportNickname:value.value}, () => {}); |
| | | } }, |
| | | { label: '创建日期', prop: 'daterange', type: 'daterange', search: true, searchRange: true, searchSpan: 8, format: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD', startPlaceholder: '开始时间', endPlaceholder: '结束时间', viewDisplay: false, hide: true, searchValue: [defaultStartDate, defaultEndDate] |
| | | , change: (value) => { |
| | | this.searchChange({ ...this.query,daterange:value.value}, () => {}); |
| | | } |
| | | }, |
| | | { label: '任务名称', prop: 'job_name' }, |
| | | { label: '文件名称', prop: 'file_name' }, |
| | | { label: '拍摄时间', prop: 'create_time' }, |
| | | { label: '文件路径', prop: 'object_key' }, |
| | | { label: '设备负载', prop: 'payload' }, |
| | | ], |
| | | }, |
| | | data: [], |
| | | taskForm: {}, |
| | | taskOption: { |
| | | submitBtn: false, |
| | | emptyBtn: false, |
| | | column: [ |
| | | { label: '任务上传', prop: 'taskFile', type: 'upload', drag: true, loadText: '任务上传中,请稍等', span: 24, propsHttp: { res: 'data' }, action: '/blade-resource/oss/endpoint/put-file-task' }, |
| | | ], |
| | | }, |
| | | domainUrl: '', |
| | | isDownloading: false, // 控制按钮加载状态 |
| | | } |
| | | }, |
| | | computed: { |
| | | func () { return func }, |
| | | ...mapGetters(['permission']), |
| | | permissionList () { |
| | | return { |
| | | addBtn: false, |
| | | editBtn: false, |
| | | viewBtn: this.validData(this.permission.attach_view, false), |
| | | delBtn: this.validData(this.permission.attach_delete, false), |
| | | } |
| | | }, |
| | | ids () { return this.selectionList.map(ele => ele.id).join(',') }, |
| | | }, |
| | | mounted () { |
| | | this.loadAirportList() |
| | | this.$refs.crud.setSearch({ daterange: this.query.daterange }) |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | methods: { |
| | | loadAirportList () { |
| | | getAirportList().then(res => { |
| | | const airportData = res.data.data || [] |
| | | const airportColumn = this.option.column.find(col => col.prop === 'airportNickname') |
| | | if (airportColumn) { |
| | | airportColumn.dicData = airportData.map(item => ({ |
| | | nickname: item.nickname, |
| | | workspace_id: item.workspace_id, |
| | | })) |
| | | } |
| | | }).catch(error => { |
| | | console.error('加载机场列表时出错:', error) |
| | | }) |
| | | }, |
| | | handleUpload () { |
| | | this.taskBox = true |
| | | }, |
| | | uploadAfter (res, done) { |
| | | this.taskBox = false |
| | | this.refreshChange() |
| | | done() |
| | | }, |
| | | async handleRowDownload (row) { |
| | | const mediaUrl = this.domainUrl + row.object_key |
| | | try { |
| | | const response = await fetch(mediaUrl) |
| | | if (!response.ok) throw new Error('文件下载失败') |
| | | const blob = await response.blob() |
| | | const url = window.URL.createObjectURL(blob) |
| | | const link = document.createElement('a') |
| | | link.href = url |
| | | link.download = row.file_name || 'download' |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | document.body.removeChild(link) |
| | | window.URL.revokeObjectURL(url) |
| | | this.$message({ type: 'success', message: '文件下载成功: ' + row.file_name }) |
| | | } catch (error) { |
| | | console.error('下载文件时出错:', error) |
| | | this.$message({ type: 'error', message: '下载失败: ' + error.message }) |
| | | } |
| | | }, |
| | | handleRowDelete (row) { |
| | | this.$confirm('确定删除此文件?', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }) |
| | | .then(() => deleteAllFile(row.id)) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.$message({ type: 'success', message: '删除成功!' }) |
| | | }) |
| | | .catch(error => { |
| | | console.error('删除文件时出错:', error) |
| | | this.$message({ type: 'error', message: '删除失败,请稍后重试!' }) |
| | | }) |
| | | }, |
| | | rowDel (row) { |
| | | this.$confirm('确定将选择数据及对应的文件删除?', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }) |
| | | .then(() => deleteAllFile(row.id)) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.$message({ type: 'success', message: '操作成功!' }) |
| | | }) |
| | | }, |
| | | searchReset () { |
| | | const endDate = new Date() |
| | | const startDate = new Date() |
| | | startDate.setMonth(startDate.getMonth() - 1) |
| | | const defaultStartDate = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}` |
| | | const defaultEndDate = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}` |
| | | this.query = { daterange: [defaultStartDate, defaultEndDate] } |
| | | this.selectedWorkspaceId = null |
| | | this.$refs.crud.setSearch({ daterange: this.query.daterange }) |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | searchChange (params, done) { |
| | | this.query = params |
| | | this.page.currentPage = 1 |
| | | const airportColumn = this.option.column.find(col => col.prop === 'airportNickname') |
| | | const selectedAirport = airportColumn.dicData.find(item => item.nickname === params.airportNickname) |
| | | this.selectedWorkspaceId = selectedAirport ? selectedAirport.workspace_id : null |
| | | this.onLoad(this.page, params) |
| | | done() |
| | | }, |
| | | selectionChange (list) { |
| | | this.selectionList = list |
| | | }, |
| | | selectionClear () { |
| | | this.selectionList = [] |
| | | this.$refs.crud.toggleSelection() |
| | | }, |
| | | currentChange (currentPage) { |
| | | this.page.currentPage = currentPage |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | sizeChange (pageSize) { |
| | | this.page.pageSize = pageSize |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | refreshChange () { |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | onLoad (page, params = {}) { |
| | | this.loading = true |
| | | const { daterange } = params |
| | | let create_time = null |
| | | let end_time = null |
| | | |
| | | if (daterange && Array.isArray(daterange) && daterange.length === 2) { |
| | | const startStr = daterange[0] |
| | | const endStr = daterange[1] |
| | | const startDate = new Date(startStr + ' 00:00:00').getTime() |
| | | const endDate = new Date(endStr + ' 23:59:59').getTime() |
| | | if (!isNaN(startDate) && !isNaN(endDate)) { |
| | | create_time = startDate |
| | | end_time = endDate |
| | | } |
| | | } |
| | | |
| | | let values = { ...params, ...this.query } |
| | | if (daterange) values.daterange = null |
| | | |
| | | getMedia(page.currentPage, page.pageSize, this.selectedWorkspaceId || null, create_time, end_time) |
| | | .then(res => { |
| | | const data = res.data |
| | | if (data && data.data && data.data.list) { |
| | | this.page.total = data.data.pagination.total |
| | | this.data = data.data.list.map(item => ({ |
| | | job_name: item.job_name, |
| | | file_name: item.file_name, |
| | | create_time: this.formatCreateTime(item.create_time), |
| | | object_key: item.object_key, |
| | | payload: item.payload, |
| | | airportNickname: item.airportNickname, |
| | | id: item.id, |
| | | })) |
| | | this.domainUrl = data.data.list.length > 0 ? data.data.list[0].domain_url : 'http://localhost:2888/manage/resource' |
| | | } else { |
| | | this.data = [] |
| | | } |
| | | this.loading = false |
| | | this.selectionClear() |
| | | this.$refs.crud.refreshTable() |
| | | }) |
| | | .catch(error => { |
| | | this.loading = false |
| | | console.error('加载媒体数据时出错:', error) |
| | | }) |
| | | }, |
| | | formatCreateTime (createTime) { |
| | | if (typeof createTime !== 'number' || isNaN(createTime)) return '' |
| | | const timestamp = createTime < 10000000000 ? createTime * 1000 : createTime |
| | | const date = new Date(timestamp) |
| | | if (isNaN(date.getTime())) return '' |
| | | const year = date.getFullYear() |
| | | const month = String(date.getMonth() + 1).padStart(2, '0') |
| | | const day = String(date.getDate()).padStart(2, '0') |
| | | const hours = String(date.getHours()).padStart(2, '0') |
| | | const minutes = String(date.getMinutes()).padStart(2, '0') |
| | | const seconds = String(date.getSeconds()).padStart(2, '0') |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` |
| | | }, |
| | | handleRowView (row) { |
| | | const mediaUrl = this.domainUrl + row.object_key |
| | | const mediaType = this.getMediaType(row.object_key) |
| | | if (mediaType === 'image' || mediaType === 'video') { |
| | | window.open(mediaUrl, '_blank') |
| | | } |
| | | }, |
| | | getMediaType (objectKey) { |
| | | const extension = objectKey.split('.').pop().toLowerCase() |
| | | if (['jpg', 'jpeg', 'png', 'gif'].includes(extension)) return 'image' |
| | | if (['mp4', 'avi', 'mov'].includes(extension)) return 'video' |
| | | return 'unknown' |
| | | }, |
| | | showVideo (url) { |
| | | this.taskBox = true |
| | | this.taskForm = { videoUrl: url } |
| | | this.taskOption = { |
| | | submitBtn: false, |
| | | emptyBtn: false, |
| | | column: [ |
| | | { label: '视频播放', prop: 'videoUrl', type: 'video', span: 24, props: { controls: true, autoplay: false } }, |
| | | ], |
| | | } |
| | | }, |
| | | validData (val, def) { |
| | | return typeof val !== 'undefined' ? val : def |
| | | }, |
| | | async handleZipDownload () { |
| | | if (this.selectionList.length === 0) { |
| | | this.$message({ type: 'warning', message: '请先选择需要下载的文件' }) |
| | | return |
| | | } |
| | | |
| | | this.isDownloading = true |
| | | |
| | | try { |
| | | const zip = new JSZip() |
| | | const files = this.selectionList.map(item => ({ |
| | | url: this.domainUrl + item.object_key, |
| | | name: item.file_name |
| | | })) |
| | | |
| | | const fetchPromises = files.map(async file => { |
| | | const response = await fetch(file.url, { cache: 'force-cache' }) |
| | | if (!response.ok) throw new Error(`下载文件 ${file.name} 失败`) |
| | | const blob = await response.blob() |
| | | zip.file(file.name, blob) |
| | | }) |
| | | |
| | | await Promise.all(fetchPromises) |
| | | |
| | | const content = await zip.generateAsync({ |
| | | type: 'blob', |
| | | compression: 'DEFLATE', |
| | | compressionOptions: { level: 1 } |
| | | }) |
| | | |
| | | const url = window.URL.createObjectURL(content) |
| | | const link = document.createElement('a') |
| | | link.href = url |
| | | link.download = `media_files_${new Date().toISOString().slice(0, 10)}_${new Date().getTime()}.zip` |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | document.body.removeChild(link) |
| | | window.URL.revokeObjectURL(url) |
| | | |
| | | this.$message({ type: 'success', message: `成功下载 ${this.selectionList.length} 个文件` }) |
| | | } catch (error) { |
| | | console.error('压缩下载失败:', error) |
| | | this.$message({ type: 'error', message: '压缩下载失败: ' + error.message }) |
| | | } finally { |
| | | this.isDownloading = false |
| | | } |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| New file |
| | |
| | | <template> |
| | | <basic-container> |
| | | <avue-crud :option="option" :table-loading="loading" :data="data" v-model:page="page" :permission="permissionList" |
| | | v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel" :before-open="beforeOpen" |
| | | @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange" |
| | | @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad"> |
| | | <template #menu-left> |
| | | <el-button type="danger" icon="el-icon-delete" plain v-if="permission.oss_delete" @click="handleDelete">删 除 |
| | | </el-button> |
| | | </template> |
| | | <template #menu="scope"> |
| | | <el-button type="primary" text icon="el-icon-video-play" v-if="userInfo.role_name.includes('admin')" |
| | | @click="handleDebug(scope.row)">调试 |
| | | </el-button> |
| | | <el-button type="primary" text icon="el-icon-circle-check" v-if="scope.row.status == 1 && permission.oss_enable" |
| | | @click.stop="handleEnable(scope.row)">启用 |
| | | </el-button> |
| | | <el-button type="primary" text icon="VideoPause" v-if="scope.row.status == 2 && permission.oss_enable" |
| | | @click.stop="handleDisable(scope.row)">禁用 |
| | | </el-button> |
| | | </template> |
| | | <template #status="{ row }"> |
| | | <el-tag>{{ row.statusName }}</el-tag> |
| | | </template> |
| | | <template #category="{ row }"> |
| | | <el-tag>{{ row.categoryName }}</el-tag> |
| | | </template> |
| | | </avue-crud> |
| | | <el-dialog title="对象存储上传调试" append-to-body v-model="box" width="550px"> |
| | | <avue-form ref="form" :option="debugOption" v-model="debugForm" @submit="handleSubmit" /> |
| | | </el-dialog> |
| | | </basic-container> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getListPage, getDetail, add, update, remove, enable, disable } from '@/api/resource/oss' |
| | | import { mapGetters } from 'vuex' |
| | | import func from '@/utils/func' |
| | | |
| | | export default { |
| | | data () { |
| | | return { |
| | | form: {}, |
| | | query: {}, |
| | | loading: true, |
| | | box: false, |
| | | page: { |
| | | pageSize: 10, |
| | | currentPage: 1, |
| | | total: 0, |
| | | }, |
| | | selectionList: [], |
| | | option: { |
| | | emptyBtnText: '重置', |
| | | emptyBtnIcon: 'el-icon-refresh', |
| | | tip: false, |
| | | searchShow: true, |
| | | searchGutter: 30, |
| | | searchMenuPosition: 'left', |
| | | searchMenuSpan: 4, |
| | | border: true, |
| | | index: true, |
| | | viewBtn: true, |
| | | selection: true, |
| | | grid: false, |
| | | menuWidth: 350, |
| | | labelWidth: 100, |
| | | dialogWidth: 880, |
| | | dialogClickModal: false, |
| | | |
| | | height: 'auto', |
| | | calcHeight: 20, |
| | | column: [ |
| | | { |
| | | label: '存储分类', |
| | | type: 'radio', |
| | | value: 1, |
| | | span: 24, |
| | | width: 120, |
| | | // searchLabelWidth: 50, |
| | | searchSpan: 4, |
| | | row: true, |
| | | dicUrl: '/blade-system/dict/dictionary?code=oss', |
| | | props: { |
| | | label: 'dictValue', |
| | | value: 'dictKey', |
| | | }, |
| | | dataType: 'number', |
| | | slot: true, |
| | | prop: 'category', |
| | | search: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请选择分类', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | change: (value) => { |
| | | this.searchChange({ ...this.query,category:value.value}, () => {}); |
| | | } |
| | | }, |
| | | { |
| | | label: '存储名称', |
| | | prop: 'name', |
| | | span: 24, |
| | | search: true, |
| | | searchSpan: 4, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入名称', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '资源编号', |
| | | prop: 'ossCode', |
| | | span: 24, |
| | | width: 120, |
| | | // searchLabelWidth: 100, |
| | | search: true, |
| | | searchSpan: 4, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入资源编号', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '资源地址', |
| | | labelTip: '对象存储通用资源地址,可以是内网也可以是外网', |
| | | prop: 'endpoint', |
| | | span: 24, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入资源地址', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '外网地址', |
| | | labelTip: '资源地址设置为内网上传,则外部访问需要配置外网映射地址', |
| | | prop: 'transformEndpoint', |
| | | span: 24, |
| | | }, |
| | | { |
| | | label: '空间名', |
| | | prop: 'bucketName', |
| | | span: 24, |
| | | width: 120, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入空间名', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: 'accessKey', |
| | | prop: 'accessKey', |
| | | span: 24, |
| | | search: true, |
| | | searchSpan: 4, |
| | | // searchLabelWidth: 100, |
| | | overHidden: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入accessKey', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: 'secretKey', |
| | | prop: 'secretKey', |
| | | span: 24, |
| | | overHidden: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入secretKey', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: 'appId', |
| | | prop: 'appId', |
| | | span: 24, |
| | | hide: true, |
| | | display: false, |
| | | }, |
| | | { |
| | | label: '过期时间', |
| | | prop: 'expire', |
| | | type: "number", |
| | | span: 24, |
| | | hide: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入过期时间', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '地域简称', |
| | | prop: 'region', |
| | | span: 24, |
| | | hide: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入地域简称', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '是否启用', |
| | | prop: 'status', |
| | | span: 24, |
| | | width: 85, |
| | | align: 'center', |
| | | slot: true, |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: false, |
| | | }, |
| | | { |
| | | label: '备注', |
| | | prop: 'remark', |
| | | span: 24, |
| | | hide: true, |
| | | }, |
| | | ], |
| | | }, |
| | | data: [], |
| | | debugForm: { |
| | | code: '', |
| | | }, |
| | | debugOption: { |
| | | submitText: '提交', |
| | | column: [ |
| | | { |
| | | label: '资源编号', |
| | | prop: 'code', |
| | | disabled: true, |
| | | span: 24, |
| | | }, |
| | | { |
| | | label: '上传背景', |
| | | prop: 'backgroundUrl', |
| | | type: 'upload', |
| | | listType: 'picture-img', |
| | | dataType: 'string', |
| | | action: '/blade-resource/oss/endpoint/put-file', |
| | | propsHttp: { |
| | | res: 'data', |
| | | url: 'link', |
| | | }, |
| | | span: 24, |
| | | }, |
| | | ], |
| | | }, |
| | | } |
| | | }, |
| | | watch: { |
| | | 'form.category' () { |
| | | const category = func.toInt(this.form.category) |
| | | this.$refs.crud.option.column.filter(item => { |
| | | if (item.prop === 'appId') { |
| | | item.display = category === 4 |
| | | } |
| | | // if (item.prop === 'region') { |
| | | // item.display = category === 4 || category === 5; |
| | | // } |
| | | }) |
| | | }, |
| | | 'debugForm.code' () { |
| | | const column = this.findObject(this.debugOption.column, 'backgroundUrl') |
| | | column.action = `/blade-resource/oss/endpoint/put-file?code=${this.debugForm.code}` |
| | | }, |
| | | }, |
| | | computed: { |
| | | ...mapGetters(['userInfo', 'permission']), |
| | | permissionList () { |
| | | return { |
| | | addBtn: this.validData(this.permission.oss_add), |
| | | viewBtn: this.validData(this.permission.oss_view), |
| | | delBtn: this.validData(this.permission.oss_delete), |
| | | editBtn: this.validData(this.permission.oss_edit), |
| | | } |
| | | }, |
| | | ids () { |
| | | let ids = [] |
| | | this.selectionList.forEach(ele => { |
| | | ids.push(ele.id) |
| | | }) |
| | | return ids.join(',') |
| | | }, |
| | | }, |
| | | methods: { |
| | | rowSave (row, done, loading) { |
| | | add(row).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | done() |
| | | }, |
| | | error => { |
| | | window.console.log(error) |
| | | loading() |
| | | } |
| | | ) |
| | | }, |
| | | rowUpdate (row, index, done, loading) { |
| | | update(row).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | done() |
| | | }, |
| | | error => { |
| | | window.console.log(error) |
| | | loading() |
| | | } |
| | | ) |
| | | }, |
| | | rowDel (row) { |
| | | this.$confirm('确定将选择数据删除?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return remove(row.id) |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | }) |
| | | }, |
| | | searchReset () { |
| | | this.query = {} |
| | | this.onLoad(this.page) |
| | | }, |
| | | searchChange (params, done) { |
| | | this.query = params |
| | | this.page.currentPage = 1 |
| | | this.onLoad(this.page, params) |
| | | done() |
| | | }, |
| | | selectionChange (list) { |
| | | this.selectionList = list |
| | | }, |
| | | selectionClear () { |
| | | this.selectionList = [] |
| | | this.$refs.crud.toggleSelection() |
| | | }, |
| | | handleEnable (row) { |
| | | this.$confirm('是否确定启用这条配置?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return enable(row.id) |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | this.$refs.crud.toggleSelection() |
| | | }) |
| | | }, |
| | | handleDisable (row) { |
| | | this.$confirm('是否确定禁用用这条配置?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return disable(row.id) |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | this.$refs.crud.toggleSelection() |
| | | }) |
| | | }, |
| | | handleDebug (row) { |
| | | this.box = true |
| | | this.debugForm.code = row.ossCode |
| | | this.debugForm.backgroundUrl = '' |
| | | }, |
| | | handleSubmit (form, done) { |
| | | this.$message({ |
| | | type: 'success', |
| | | message: `获取到图片地址:[${form.backgroundUrl}]`, |
| | | }) |
| | | done() |
| | | }, |
| | | handleDelete () { |
| | | if (this.selectionList.length === 0) { |
| | | this.$message.warning('请选择至少一条数据') |
| | | return |
| | | } |
| | | this.$confirm('确定将选择数据删除?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return remove(this.ids) |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page) |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }) |
| | | this.$refs.crud.toggleSelection() |
| | | }) |
| | | }, |
| | | beforeOpen (done, type) { |
| | | if (['edit', 'view'].includes(type)) { |
| | | getDetail(this.form.id).then(res => { |
| | | this.form = res.data.data |
| | | }) |
| | | } |
| | | done() |
| | | }, |
| | | currentChange (currentPage) { |
| | | this.page.currentPage = currentPage |
| | | }, |
| | | sizeChange (pageSize) { |
| | | this.page.pageSize = pageSize |
| | | }, |
| | | refreshChange () { |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | onLoad (page, params = {}) { |
| | | this.loading = true |
| | | getListPage(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => { |
| | | const data = res.data.data |
| | | this.page.total = data.total |
| | | this.data = data.records |
| | | this.loading = false |
| | | this.selectionClear() |
| | | }) |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | <style scoped lang="scss"></style> |
| New file |
| | |
| | | <template> |
| | | <basic-container> |
| | | <avue-crud |
| | | :option="option" |
| | | :table-loading="loading" |
| | | :data="data" |
| | | v-model:page="page" |
| | | :permission="permissionList" |
| | | v-model="form" |
| | | ref="crud" |
| | | @row-update="rowUpdate" |
| | | @row-save="rowSave" |
| | | @row-del="rowDel" |
| | | :before-open="beforeOpen" |
| | | @search-change="searchChange" |
| | | @search-reset="searchReset" |
| | | @selection-change="selectionChange" |
| | | @current-change="currentChange" |
| | | @size-change="sizeChange" |
| | | @refresh-change="refreshChange" |
| | | @on-load="onLoad" |
| | | > |
| | | <template #search-menu="{ row, size }"> |
| | | <el-button icon="el-icon-back" @click="goPatchManagement" type="primary"> 返回 </el-button> |
| | | </template> |
| | | <template #status="{ row }"> |
| | | <el-tag>{{ row.statusName }}</el-tag> |
| | | </template> |
| | | <template #category="{ row }"> |
| | | <el-tag>{{ row.categoryName }}</el-tag> |
| | | </template> |
| | | <template #menu="{ row }"> |
| | | <el-button |
| | | :disabled="row.patches_type === '综合类'" |
| | | type="primary" |
| | | text |
| | | icon="el-icon-delete" |
| | | @click="rowDel(row)" |
| | | > |
| | | 删除 |
| | | </el-button> |
| | | </template> |
| | | </avue-crud> |
| | | </basic-container> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { |
| | | searchManagementApi, |
| | | listOfSpotTypesApi, |
| | | spotTypesCreateApi, |
| | | editSpotTypeApi, |
| | | deleteSpotTypeApi, |
| | | } from '@/api/patchManagement/index'; |
| | | import { ref, computed, watch } from 'vue'; |
| | | import { enable, disable } from '@/api/resource/oss'; |
| | | import { useStore } from 'vuex'; |
| | | import func from '@/utils/func'; |
| | | import { useRouter } from 'vue-router'; |
| | | import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'; |
| | | const store = useStore(); |
| | | const router = useRouter(); |
| | | // ---------------- data ---------------- |
| | | const form = ref({}); |
| | | const query = ref({}); |
| | | const creatorOption = ref([]); |
| | | const loading = ref(true); |
| | | const page = ref({ |
| | | pageSize: 20, |
| | | currentPage: 1, |
| | | total: 0, |
| | | lotValue: '', |
| | | userName: '', |
| | | }); |
| | | const selectionList = ref([]); |
| | | const option = ref({ |
| | | emptyBtnText: '重置', |
| | | emptyBtnIcon: 'el-icon-refresh', |
| | | addBtn: true, |
| | | addBtnText: '新增类型', |
| | | tip: false, |
| | | searchShow: true, |
| | | searchGutter: 30, |
| | | searchMenuPosition: 'left', |
| | | searchMenuSpan: 4, |
| | | border: true, |
| | | index: true, |
| | | indexLabel: '序号', |
| | | indexWidth: 60, |
| | | selection: false, |
| | | grid: false, |
| | | menuWidth: 180, |
| | | labelWidth: 90, |
| | | dialogWidth: 600, |
| | | dialogClickModal: false, |
| | | height: 'auto', |
| | | calcHeight: 20, |
| | | refreshBtn: false, |
| | | gridBtn: false, |
| | | searchShowBtn: false, |
| | | columnBtn: false, |
| | | delBtn: false, |
| | | column: [ |
| | | { |
| | | label: '类型名称', |
| | | prop: 'patches_type', |
| | | search: true, |
| | | searchSpan: 4, |
| | | span: 24, |
| | | rules: [{ required: true, message: '请输入类型名称', trigger: 'blur' }], |
| | | }, |
| | | { |
| | | label: '创建时间', |
| | | prop: 'create_time', |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | rules: [{ required: true, message: '请输入创建时间', trigger: 'blur' }], |
| | | }, |
| | | { |
| | | label: '创建人', |
| | | prop: 'user_name', |
| | | search: true, |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | searchSpan: 4, |
| | | type: 'select', |
| | | dicData: creatorOption, |
| | | props: { |
| | | label: 'label', |
| | | value: 'value', |
| | | }, |
| | | rules: [{ required: true, message: '请输入创建人', trigger: 'blur' }], |
| | | }, |
| | | ], |
| | | }); |
| | | |
| | | const data = ref([]); |
| | | // 获取搜索数据 |
| | | const getsearchManagementApi = () => { |
| | | searchManagementApi().then(res => { |
| | | const creatorOptionuniqueMap = new Map(); |
| | | res.data.data.user_names.forEach(item => { |
| | | const [key, value] = Object.entries(item)[0]; |
| | | if (!creatorOptionuniqueMap.has(key)) { |
| | | creatorOptionuniqueMap.set(key, value); |
| | | } |
| | | }); |
| | | creatorOption.value = Array.from(creatorOptionuniqueMap).map(([key, value]) => ({ |
| | | label: value, |
| | | value: value, |
| | | })); |
| | | }); |
| | | }; |
| | | |
| | | // ---------------- watch ---------------- |
| | | watch( |
| | | () => form.value.category, |
| | | () => { |
| | | const category = func.toInt(form.value.category); |
| | | option.value.column.filter(item => { |
| | | if (item.prop === 'appId') { |
| | | item.display = category === 4; |
| | | } |
| | | }); |
| | | } |
| | | ); |
| | | |
| | | // ---------------- computed ---------------- |
| | | const permission = computed(() => store.getters.permission); |
| | | const permissionList = computed(() => ({ |
| | | addBtn: validData(permission.value.oss_add), |
| | | viewBtn: validData(permission.value.oss_view), |
| | | delBtn: validData(permission.value.oss_delete), |
| | | editBtn: validData(permission.value.oss_edit), |
| | | })); |
| | | |
| | | const ids = computed(() => { |
| | | return selectionList.value.map(ele => ele.id).join(','); |
| | | }); |
| | | |
| | | // ---------------- methods ---------------- |
| | | const rowSave = (row, done, loadingFn) => { |
| | | const createParams = { |
| | | patches_type: row.patches_type, |
| | | }; |
| | | spotTypesCreateApi(createParams).then( |
| | | () => { |
| | | onLoad(page.value); |
| | | ElMessage.success('操作成功!'); |
| | | done(); |
| | | }, |
| | | error => { |
| | | console.log(error); |
| | | loadingFn(); |
| | | } |
| | | ); |
| | | }; |
| | | |
| | | const rowUpdate = (row, index, done, loadingFn) => { |
| | | editSpotTypeApi(row).then( |
| | | res => { |
| | | onLoad(page.value); |
| | | ElMessage.success('操作成功!'); |
| | | done(); |
| | | }, |
| | | error => { |
| | | console.log(error); |
| | | loadingFn(); |
| | | } |
| | | ); |
| | | }; |
| | | |
| | | const rowDel = row => { |
| | | ElMessageBox.confirm('确定将选择数据删除?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => deleteSpotTypeApi([row.id])) |
| | | .then(() => { |
| | | onLoad(page.value); |
| | | ElMessage.success('操作成功!'); |
| | | }); |
| | | }; |
| | | |
| | | const searchReset = () => { |
| | | page.value.userName = ''; |
| | | page.value.lotValue = ''; |
| | | page.value.currentPage = 1; |
| | | page.value.pageSize = 20; |
| | | onLoad(page.value); |
| | | }; |
| | | |
| | | const searchChange = (params, done) => { |
| | | page.value.currentPage = 1; |
| | | page.value.lotValue = params.patches_type; |
| | | page.value.userName = params.user_name; |
| | | onLoad(page.value); |
| | | done(); |
| | | }; |
| | | |
| | | const selectionChange = list => { |
| | | // selectionList.value = list |
| | | }; |
| | | |
| | | const selectionClear = () => { |
| | | selectionList.value = []; |
| | | // crudRef.value.toggleSelection() |
| | | }; |
| | | |
| | | const handleEnable = row => { |
| | | ElMessageBox.confirm('是否确定启用这条配置?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => enable(row.id)) |
| | | .then(() => { |
| | | onLoad(page.value); |
| | | ElMessage.success('操作成功!'); |
| | | // crudRef.value.toggleSelection() |
| | | }); |
| | | }; |
| | | |
| | | const handleDisable = row => { |
| | | ElMessageBox.confirm('是否确定禁用这条配置?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => disable(row.id)) |
| | | .then(() => { |
| | | onLoad(page.value); |
| | | ElMessage.success('操作成功!'); |
| | | // crudRef.value.toggleSelection() |
| | | }); |
| | | }; |
| | | |
| | | const beforeOpen = (done, type) => { |
| | | // if (['edit', 'view'].includes(type)) { |
| | | // // getDetail(form.value.id).then(res => { |
| | | // // form.value = res.data.data |
| | | // // }) |
| | | // } |
| | | done(); |
| | | }; |
| | | |
| | | const currentChange = currentPage => { |
| | | page.value.currentPage = currentPage; |
| | | }; |
| | | |
| | | const sizeChange = pageSize => { |
| | | page.value.pageSize = pageSize; |
| | | }; |
| | | const refreshChange = () => { |
| | | onLoad(page.value, query.value); |
| | | }; |
| | | |
| | | const onLoad = (pageParam, params = {}) => { |
| | | const searchparams = { |
| | | current: pageParam.currentPage, |
| | | size: pageParam.pageSize, |
| | | lotValue: pageParam.lotValue, |
| | | userName: pageParam.userName, |
| | | }; |
| | | loading.value = true; |
| | | listOfSpotTypesApi(searchparams).then(res => { |
| | | const resData = res.data.data; |
| | | page.value.total = resData.total; |
| | | data.value = resData.records; |
| | | loading.value = false; |
| | | selectionClear(); |
| | | }); |
| | | }; |
| | | |
| | | // ---------------- extra ---------------- |
| | | const goPatchManagement = () => { |
| | | router.push({ path: '/resource/patchManagement' }); |
| | | }; |
| | | |
| | | // ---------------- utils ---------------- |
| | | function validData(value) { |
| | | return value !== undefined && value !== null && value !== false; |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getsearchManagementApi(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| New file |
| | |
| | | <template> |
| | | <basic-container> |
| | | <avue-crud |
| | | :option="option" |
| | | :table-loading="loading" |
| | | :data="data" |
| | | v-model:page="page" |
| | | :permission="permissionList" |
| | | :before-open="beforeOpen" |
| | | v-model="form" |
| | | ref="crud" |
| | | @row-update="rowUpdate" |
| | | @row-save="rowSave" |
| | | @row-del="rowDel" |
| | | @search-change="searchChange" |
| | | @search-reset="searchReset" |
| | | @selection-change="selectionChange" |
| | | @current-change="currentChange" |
| | | @size-change="sizeChange" |
| | | @refresh-change="refreshChange" |
| | | @on-load="onLoad" |
| | | > |
| | | <template #menu-left> |
| | | <el-button |
| | | type="danger" |
| | | icon="el-icon-delete" |
| | | plain |
| | | v-if="permission.sms_delete" |
| | | @click="handleDelete" |
| | | >删 除 |
| | | </el-button> |
| | | </template> |
| | | <template #menu="scope"> |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="el-icon-video-play" |
| | | v-if="userInfo.role_name.includes('admin')" |
| | | @click="handleDebug(scope.row)" |
| | | >调试 |
| | | </el-button> |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | icon="el-icon-circle-check" |
| | | v-if="permission.sms_enable" |
| | | @click.stop="handleEnable(scope.row)" |
| | | >启用 |
| | | </el-button> |
| | | </template> |
| | | <template #status="{ row }"> |
| | | <el-tag>{{ row.statusName }}</el-tag> |
| | | </template> |
| | | <template #category="{ row }"> |
| | | <el-tag>{{ row.categoryName }}</el-tag> |
| | | </template> |
| | | </avue-crud> |
| | | <el-dialog title="手机短信发送调试" append-to-body v-model="box" width="550px"> |
| | | <avue-form :option="debugOption" v-model="debugForm" @submit="handleSend" /> |
| | | </el-dialog> |
| | | </basic-container> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getList, getDetail, add, update, remove, enable, send } from '@/api/resource/sms'; |
| | | import { mapGetters } from 'vuex'; |
| | | import func from '@/utils/func'; |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | form: {}, |
| | | query: {}, |
| | | loading: true, |
| | | box: false, |
| | | page: { |
| | | pageSize: 10, |
| | | currentPage: 1, |
| | | total: 0, |
| | | }, |
| | | selectionList: [], |
| | | option: { |
| | | tip: false, |
| | | searchShow: true, |
| | | searchMenuSpan: 6, |
| | | border: true, |
| | | index: true, |
| | | viewBtn: true, |
| | | selection: true, |
| | | grid: true, |
| | | menuWidth: 350, |
| | | labelWidth: 100, |
| | | dialogWidth: 880, |
| | | dialogClickModal: false, |
| | | column: [ |
| | | { |
| | | label: '分类', |
| | | type: 'radio', |
| | | value: 1, |
| | | span: 24, |
| | | width: 100, |
| | | searchLabelWidth: 50, |
| | | row: true, |
| | | dicUrl: '/blade-system/dict/dictionary?code=sms', |
| | | props: { |
| | | label: 'dictValue', |
| | | value: 'dictKey', |
| | | }, |
| | | dataType: 'number', |
| | | slot: true, |
| | | prop: 'category', |
| | | search: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请选择分类', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '资源编号', |
| | | prop: 'smsCode', |
| | | span: 24, |
| | | width: 200, |
| | | search: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入资源编号', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '模版ID', |
| | | prop: 'templateId', |
| | | span: 24, |
| | | width: 200, |
| | | search: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入模版ID', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: 'accessKey', |
| | | prop: 'accessKey', |
| | | span: 24, |
| | | overHidden: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入accessKey', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: 'secretKey', |
| | | prop: 'secretKey', |
| | | span: 24, |
| | | overHidden: true, |
| | | display: true, |
| | | hide: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入secretKey', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: 'regionId', |
| | | prop: 'regionId', |
| | | span: 24, |
| | | value: 'cn-hangzhou', |
| | | hide: true, |
| | | display: false, |
| | | }, |
| | | { |
| | | label: '短信签名', |
| | | prop: 'signName', |
| | | span: 24, |
| | | width: 200, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入短信签名', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '是否启用', |
| | | prop: 'status', |
| | | span: 24, |
| | | width: 85, |
| | | align: 'center', |
| | | slot: true, |
| | | addDisplay: false, |
| | | editDisplay: false, |
| | | viewDisplay: false, |
| | | }, |
| | | { |
| | | label: '备注', |
| | | prop: 'remark', |
| | | span: 24, |
| | | hide: true, |
| | | }, |
| | | ], |
| | | }, |
| | | data: [], |
| | | debugForm: { |
| | | code: '', |
| | | }, |
| | | debugOption: { |
| | | submitText: '发送', |
| | | column: [ |
| | | { |
| | | label: '资源编号', |
| | | prop: 'code', |
| | | disabled: true, |
| | | span: 24, |
| | | }, |
| | | { |
| | | label: '发送手机', |
| | | prop: 'phones', |
| | | span: 24, |
| | | }, |
| | | { |
| | | label: '发送参数', |
| | | prop: 'params', |
| | | span: 24, |
| | | placeholder: "例: {'code':2333,'title':'通知标题'}", |
| | | }, |
| | | ], |
| | | }, |
| | | }; |
| | | }, |
| | | watch: { |
| | | 'form.category'() { |
| | | const category = func.toInt(this.form.category); |
| | | this.$refs.crud.option.column.filter(item => { |
| | | if (item.prop === 'templateId') { |
| | | if (category === 1) { |
| | | item.label = '模版内容'; |
| | | } else { |
| | | item.label = '模版ID'; |
| | | } |
| | | } |
| | | if (item.prop === 'accessKey') { |
| | | if (category === 1) { |
| | | item.label = 'apiKey'; |
| | | } else if (category === 4) { |
| | | item.label = 'appId'; |
| | | } else { |
| | | item.label = 'accessKey'; |
| | | } |
| | | } |
| | | if (item.prop === 'secretKey') { |
| | | item.display = category !== 1; |
| | | if (category === 4) { |
| | | item.label = 'appKey'; |
| | | } else { |
| | | item.label = 'secretKey'; |
| | | } |
| | | } |
| | | if (item.prop === 'regionId') { |
| | | if (category === 3) { |
| | | item.display = true; |
| | | item.value = 'cn-hangzhou'; |
| | | } else { |
| | | item.display = false; |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | }, |
| | | computed: { |
| | | ...mapGetters(['userInfo', 'permission']), |
| | | permissionList() { |
| | | return { |
| | | addBtn: this.validData(this.permission.sms_add, false), |
| | | viewBtn: this.validData(this.permission.sms_view, false), |
| | | delBtn: this.validData(this.permission.sms_delete, false), |
| | | editBtn: this.validData(this.permission.sms_edit, false), |
| | | }; |
| | | }, |
| | | ids() { |
| | | let ids = []; |
| | | this.selectionList.forEach(ele => { |
| | | ids.push(ele.id); |
| | | }); |
| | | return ids.join(','); |
| | | }, |
| | | }, |
| | | methods: { |
| | | rowSave(row, done, loading) { |
| | | add(row).then( |
| | | () => { |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }); |
| | | done(); |
| | | }, |
| | | error => { |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ); |
| | | }, |
| | | rowUpdate(row, index, done, loading) { |
| | | update(row).then( |
| | | () => { |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }); |
| | | done(); |
| | | }, |
| | | error => { |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ); |
| | | }, |
| | | rowDel(row) { |
| | | this.$confirm('确定将选择数据删除?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return remove(row.id); |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }); |
| | | }); |
| | | }, |
| | | handleEnable(row) { |
| | | this.$confirm('是否确定启用这条配置?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return enable(row.id); |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }); |
| | | this.$refs.crud.toggleSelection(); |
| | | }); |
| | | }, |
| | | handleDebug(row) { |
| | | this.box = true; |
| | | this.debugForm.code = row.smsCode; |
| | | }, |
| | | handleSend(form, done, loading) { |
| | | send(form.code, form.phones, form.params).then( |
| | | res => { |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '发送成功!', |
| | | }); |
| | | done(); |
| | | window.console.log(res); |
| | | this.box = false; |
| | | }, |
| | | error => { |
| | | window.console.log(error); |
| | | loading(); |
| | | } |
| | | ); |
| | | }, |
| | | handleDelete() { |
| | | if (this.selectionList.length === 0) { |
| | | this.$message.warning('请选择至少一条数据'); |
| | | return; |
| | | } |
| | | this.$confirm('确定将选择数据删除?', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | return remove(this.ids); |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }); |
| | | this.$refs.crud.toggleSelection(); |
| | | }); |
| | | }, |
| | | beforeOpen(done, type) { |
| | | if (['edit', 'view'].includes(type)) { |
| | | getDetail(this.form.id).then(res => { |
| | | this.form = res.data.data; |
| | | }); |
| | | } |
| | | done(); |
| | | }, |
| | | searchReset() { |
| | | this.query = {}; |
| | | this.onLoad(this.page); |
| | | }, |
| | | searchChange(params, done) { |
| | | this.query = params; |
| | | this.page.currentPage = 1; |
| | | this.onLoad(this.page, params); |
| | | done(); |
| | | }, |
| | | selectionChange(list) { |
| | | this.selectionList = list; |
| | | }, |
| | | selectionClear() { |
| | | this.selectionList = []; |
| | | this.$refs.crud.toggleSelection(); |
| | | }, |
| | | currentChange(currentPage) { |
| | | this.page.currentPage = currentPage; |
| | | }, |
| | | sizeChange(pageSize) { |
| | | this.page.pageSize = pageSize; |
| | | }, |
| | | refreshChange() { |
| | | this.onLoad(this.page, this.query); |
| | | }, |
| | | onLoad(page, params = {}) { |
| | | this.loading = true; |
| | | getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => { |
| | | const data = res.data.data; |
| | | this.page.total = data.total; |
| | | this.data = data.records; |
| | | this.loading = false; |
| | | this.selectionClear(); |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| New file |
| | |
| | | <template> |
| | | <basic-container> |
| | | <avue-crud :option="option" :table-loading="loading" :data="data" v-model:page="page" :permission="permissionList" |
| | | v-model="form" ref="crud" @search-change="searchChange" @search-reset="searchReset" |
| | | @selection-change="selectionChange" @current-change="currentChange" @size-change="sizeChange" |
| | | @refresh-change="refreshChange" @on-load="onLoad"> |
| | | </avue-crud> |
| | | </basic-container> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getJobsByUser } from '@/api/resource/wayline' |
| | | import { getAirportList } from '@/api/device/device' |
| | | import { mapGetters } from 'vuex' |
| | | import func from '@/utils/func' |
| | | |
| | | export default { |
| | | data () { |
| | | // 计算默认的开始和结束日期 |
| | | const endDate = new Date() // 当前日期 |
| | | const startDate = new Date() // 一个月前的日期 |
| | | startDate.setMonth(startDate.getMonth() - 1) |
| | | |
| | | // 格式化为 YYYY-MM-DD 字符串 |
| | | const defaultStartDate = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}` |
| | | const defaultEndDate = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}` |
| | | |
| | | return { |
| | | form: {}, |
| | | // 初始化 query,设置默认时间范围 |
| | | query: { |
| | | daterange: [defaultStartDate, defaultEndDate] |
| | | }, |
| | | loading: true, |
| | | page: { |
| | | pageSize: 10, |
| | | currentPage: 1, |
| | | total: 0, |
| | | }, |
| | | selectionList: [], |
| | | selectedWorkspaceId: null, |
| | | option: { |
| | | tip: false, |
| | | searchShow: true, |
| | | searchGutter: 30, |
| | | searchMenuPosition: 'left', |
| | | searchMenuSpan: 4, |
| | | border: true, |
| | | index: true, |
| | | // selection: true, |
| | | dialogClickModal: false, |
| | | menu: false, // 禁用默认操作列 |
| | | |
| | | height: 'auto', |
| | | calcHeight: 20, |
| | | column: [ |
| | | { |
| | | label: '机场选择', |
| | | prop: 'dock_name', |
| | | type: 'select', |
| | | search: true, |
| | | searchSpan: 4, |
| | | dicData: [], |
| | | props: { |
| | | label: 'nickname', |
| | | value: 'nickname', |
| | | }, |
| | | hide: true, |
| | | change: (value) => { |
| | | this.searchChange({ ...this.query,dock_name:value.value}, () => {}); |
| | | } |
| | | }, |
| | | { |
| | | label: '任务名称', |
| | | prop: 'job_name', |
| | | search: true, |
| | | searchSpan: 4, |
| | | }, |
| | | { |
| | | label: '时间范围', |
| | | prop: 'daterange', |
| | | type: 'daterange', |
| | | search: true, |
| | | searchRange: true, |
| | | searchSpan: 8, |
| | | format: 'YYYY-MM-DD', // 显示格式 |
| | | valueFormat: 'YYYY-MM-DD', // 值格式 |
| | | startPlaceholder: '开始时间', |
| | | endPlaceholder: '结束时间', |
| | | searchValue: [defaultStartDate, defaultEndDate], // 设置搜索表单默认值 |
| | | hide: true ,// 隐藏在表格中,只保留在搜索框 |
| | | change: (value) => { |
| | | this.searchChange({ ...this.query,daterange:value.value}, () => {}); |
| | | } |
| | | }, |
| | | { |
| | | label: '机场名称', |
| | | prop: 'dock_name', |
| | | }, |
| | | { |
| | | label: '用户名', |
| | | prop: 'username', |
| | | }, |
| | | { |
| | | label: '执行时间', |
| | | prop: 'begin_time', |
| | | formatter: (row) => this.formatTime(row.begin_time), |
| | | }, |
| | | { |
| | | label: '完成时间', |
| | | prop: 'completed_time', |
| | | formatter: (row) => this.formatTime(row.completed_time), |
| | | }, |
| | | { |
| | | label: '错误原因', |
| | | prop: 'reason', |
| | | formatter: (row) => { |
| | | return [4, 5].includes(row.status) ? row.reason || '未知' : '' |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | data: [], |
| | | } |
| | | }, |
| | | computed: { |
| | | ...mapGetters(['permission']), |
| | | permissionList () { |
| | | return { |
| | | addBtn: false, |
| | | editBtn: false, |
| | | viewBtn: this.validData(this.permission.attach_view, false), |
| | | delBtn: this.validData(this.permission.attach_delete, false), |
| | | } |
| | | }, |
| | | ids () { |
| | | let ids = [] |
| | | this.selectionList.forEach(ele => { |
| | | ids.push(ele.job_id) |
| | | }) |
| | | return ids.join(',') |
| | | }, |
| | | }, |
| | | mounted () { |
| | | this.loadAirportList() |
| | | // 初始化时手动触发搜索,以确保默认值生效 |
| | | this.$refs.crud.searchChange(this.query) |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | methods: { |
| | | loadAirportList () { |
| | | getAirportList().then(res => { |
| | | const airportData = res.data.data || [] |
| | | const airportColumn = this.option.column.find(col => col.prop === 'dock_name') |
| | | if (airportColumn) { |
| | | airportColumn.dicData = airportData.map(item => ({ |
| | | nickname: item.nickname, |
| | | workspace_id: item.workspace_id, |
| | | })) |
| | | } |
| | | }).catch(error => { |
| | | // 处理错误 |
| | | }) |
| | | }, |
| | | searchReset () { |
| | | // 重置时恢复默认时间范围 |
| | | const endDate = new Date() |
| | | const startDate = new Date() |
| | | startDate.setMonth(startDate.getMonth() - 1) |
| | | const defaultStartDate = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}` |
| | | const defaultEndDate = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}` |
| | | this.query = { |
| | | daterange: [defaultStartDate, defaultEndDate] |
| | | } |
| | | this.selectedWorkspaceId = null |
| | | // 更新 searchValue 以确保界面重置后显示默认值 |
| | | const daterangeColumn = this.option.column.find(col => col.prop === 'daterange') |
| | | daterangeColumn.searchValue = [defaultStartDate, defaultEndDate] |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | searchChange (params, done) { |
| | | this.query = params |
| | | this.page.currentPage = 1 |
| | | |
| | | const airportColumn = this.option.column.find(col => col.prop === 'dock_name') |
| | | const selectedAirport = airportColumn.dicData.find(item => item.nickname === params.dock_name) |
| | | this.selectedWorkspaceId = selectedAirport ? selectedAirport.workspace_id : null |
| | | |
| | | const { daterange } = params |
| | | let startTime = null |
| | | let endTime = null |
| | | if (daterange && Array.isArray(daterange) && daterange.length === 2) { |
| | | startTime = this.formatTime(daterange[0]) |
| | | endTime = this.formatTime(daterange[1]) |
| | | } |
| | | |
| | | if (startTime && isNaN(new Date(startTime).getTime())) { |
| | | startTime = null |
| | | } |
| | | if (endTime && isNaN(new Date(endTime).getTime())) { |
| | | endTime = null |
| | | } |
| | | |
| | | this.onLoad(this.page, params) |
| | | if (done) done() |
| | | }, |
| | | selectionChange (list) { |
| | | this.selectionList = list |
| | | }, |
| | | selectionClear () { |
| | | this.selectionList = [] |
| | | this.$refs.crud.toggleSelection() |
| | | }, |
| | | currentChange (currentPage) { |
| | | this.page.currentPage = currentPage |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | sizeChange (pageSize) { |
| | | this.page.pageSize = pageSize |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | refreshChange () { |
| | | this.onLoad(this.page, this.query) |
| | | }, |
| | | onLoad (page, params = {}) { |
| | | this.loading = true |
| | | |
| | | const workspaceId = this.selectedWorkspaceId || null |
| | | const { daterange } = params |
| | | let startTime = null |
| | | let endTime = null |
| | | |
| | | if (daterange && Array.isArray(daterange) && daterange.length === 2) { |
| | | startTime = this.formatTime(daterange[0]) |
| | | endTime = this.formatTime(daterange[1]) |
| | | } |
| | | |
| | | if (startTime && isNaN(new Date(startTime).getTime())) { |
| | | startTime = null |
| | | } |
| | | if (endTime && isNaN(new Date(endTime).getTime())) { |
| | | endTime = null |
| | | } |
| | | |
| | | getJobsByUser( |
| | | workspaceId, |
| | | page.currentPage, |
| | | page.pageSize, |
| | | params.status || '', |
| | | startTime, |
| | | endTime, |
| | | params.job_name || null |
| | | ).then(res => { |
| | | const responseData = res.data |
| | | |
| | | if (responseData && responseData.data && Array.isArray(responseData.data.list)) { |
| | | this.page.total = responseData.data.pagination.total || responseData.data.list.length |
| | | this.data = responseData.data.list.map(item => ({ |
| | | job_id: item.job_id, |
| | | job_name: item.job_name, |
| | | dock_name: item.dock_name, |
| | | status: item.status, |
| | | username: item.username, |
| | | workspace_id: item.workspace_id, |
| | | reason: item.reason, |
| | | begin_time: item.begin_time, |
| | | completed_time: item.completed_time, |
| | | })) |
| | | } else { |
| | | this.data = [] |
| | | this.page.total = 0 |
| | | } |
| | | |
| | | this.loading = false |
| | | this.selectionClear() |
| | | }).catch(error => { |
| | | this.loading = false |
| | | this.data = [] |
| | | this.page.total = 0 |
| | | }) |
| | | }, |
| | | formatTime (time) { |
| | | if (!time) return '' |
| | | let date |
| | | if (typeof time === 'number') { |
| | | date = new Date(time < 10000000000 ? time * 1000 : time) |
| | | } else if (typeof time === 'string') { |
| | | date = new Date(time) |
| | | } |
| | | if (isNaN(date.getTime())) { |
| | | return null |
| | | } |
| | | const year = date.getFullYear() |
| | | const month = String(date.getMonth() + 1).padStart(2, '0') |
| | | const day = String(date.getDate()).padStart(2, '0') |
| | | const hours = String(date.getHours()).padStart(2, '0') |
| | | const minutes = String(date.getMinutes()).padStart(2, '0') |
| | | const seconds = String(date.getSeconds()).padStart(2, '0') |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` |
| | | }, |
| | | validData (val, def) { |
| | | return typeof val !== 'undefined' ? val : def |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| New file |
| | |
| | | <template> |
| | | <basic-container> |
| | | <avue-crud :option="option" :table-loading="loading" :data="data" :page.sync="page" v-model="form" ref="crud" |
| | | @search-change="searchChange" @search-reset="searchReset" @current-change="currentChange" |
| | | @size-change="sizeChange" @refresh-change="refreshChange"> |
| | | </avue-crud> |
| | | </basic-container> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getWaylineFileByUser } from '@/api/resource/waylineFile' |
| | | import { getAirportList } from '@/api/device/device' |
| | | |
| | | export default { |
| | | name: 'WaylineFile', |
| | | data () { |
| | | const { defaultStartDate, defaultEndDate } = this.getDefaultDates() |
| | | return { |
| | | form: {}, |
| | | query: { name: '', dock_name: '', daterange: [defaultStartDate, defaultEndDate] }, |
| | | loading: false, |
| | | page: { pageSize: 10, currentPage: 1, total: 0 }, |
| | | selectedWorkspaceId: null, |
| | | data: [], |
| | | option: { |
| | | tip: false, |
| | | searchShow: true, |
| | | searchGutter: 30, |
| | | searchMenuPosition: 'left', |
| | | searchMenuSpan: 4, |
| | | border: true, |
| | | index: true, |
| | | menu: false, |
| | | page: true, |
| | | |
| | | height: 'auto', |
| | | calcHeight: 20, |
| | | column: [ |
| | | { |
| | | label: '机场选择', |
| | | prop: 'dock_name', |
| | | type: 'select', |
| | | search: true, |
| | | searchSpan: 4, |
| | | dicData: [], |
| | | props: { label: 'nickname', value: 'nickname' }, |
| | | hide: true, |
| | | change: (value) => { |
| | | this.searchChange({ ...this.query,dock_name:value.value}, () => {}); |
| | | } |
| | | }, |
| | | { |
| | | label: '航线名称', |
| | | prop: 'name', |
| | | search: true, |
| | | searchSpan: 4, |
| | | }, |
| | | { |
| | | label: '时间范围', |
| | | prop: 'daterange', |
| | | type: 'daterange', |
| | | search: true, |
| | | searchRange: true, |
| | | searchSpan: 8, |
| | | format: 'YYYY-MM-DD', |
| | | valueFormat: 'YYYY-MM-DD', |
| | | startPlaceholder: '开始时间', |
| | | endPlaceholder: '结束时间', |
| | | searchValue: [defaultStartDate, defaultEndDate], |
| | | hide: true, |
| | | change: (value) => { |
| | | this.searchChange({ ...this.query,daterange:value.value}, () => {}); |
| | | } |
| | | }, |
| | | { label: '航线名称', prop: 'name' }, |
| | | { |
| | | label: '航线类型', |
| | | prop: 'wayline_type', |
| | | formatter: (row) => this.formatWaylineType(row.wayline_type), |
| | | }, |
| | | { label: '用户名', prop: 'user_name' }, |
| | | { label: '航线ID', prop: 'id' }, |
| | | { |
| | | label: '更新时间', |
| | | prop: 'update_time', |
| | | formatter: (row) => this.formatTime(row.update_time), |
| | | }, |
| | | ], |
| | | }, |
| | | } |
| | | }, |
| | | mounted () { |
| | | this.fetchAirports() |
| | | this.fetchData(this.page, this.query) // 初次加载包含默认时间范围 |
| | | }, |
| | | methods: { |
| | | getDefaultDates () { |
| | | const endDate = new Date() |
| | | const startDate = new Date() |
| | | startDate.setMonth(startDate.getMonth() - 1) |
| | | // 结束时间设定为当天 23:59:59 |
| | | endDate.setHours(23, 59, 59, 999) |
| | | |
| | | return { |
| | | defaultStartDate: `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}`, |
| | | defaultEndDate: `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}`, |
| | | } |
| | | }, |
| | | async fetchAirports () { |
| | | try { |
| | | const res = await getAirportList() |
| | | const airportData = res.data.data || [] |
| | | const airportColumn = this.option.column.find((col) => col.prop === 'dock_name') |
| | | if (airportColumn) { |
| | | airportColumn.dicData = airportData.map((item) => ({ |
| | | nickname: item.nickname, |
| | | workspace_id: item.workspace_id, |
| | | })) |
| | | } |
| | | } catch (error) { |
| | | console.error('加载机场列表失败:', error) |
| | | } |
| | | }, |
| | | async fetchData (page, params = {}) { |
| | | this.loading = true |
| | | const { name, dock_name, daterange } = params |
| | | const workspaceId = this.selectedWorkspaceId || null |
| | | |
| | | // 时间范围处理 |
| | | const startDate = new Date(daterange[0]) |
| | | let endDate = new Date(daterange[1]) |
| | | // 结束时间始终设定为当天 23:59:59 |
| | | endDate.setHours(23, 59, 59, 999) |
| | | |
| | | const startTime = isNaN(startDate.getTime()) ? null : startDate.getTime() |
| | | const endTime = isNaN(endDate.getTime()) ? null : endDate.getTime() |
| | | |
| | | const requestParams = { |
| | | workspaceId, |
| | | waylineName: name || null, |
| | | startTime, |
| | | endTime, |
| | | page: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | } |
| | | |
| | | console.log('请求参数:', requestParams) |
| | | |
| | | try { |
| | | const res = await getWaylineFileByUser( |
| | | requestParams.workspaceId, |
| | | requestParams.waylineName, |
| | | requestParams.startTime, |
| | | requestParams.endTime, |
| | | requestParams.page, |
| | | requestParams.pageSize |
| | | ) |
| | | const responseData = res.data |
| | | |
| | | if (responseData?.code === 0 && Array.isArray(responseData.data?.list)) { |
| | | this.data = responseData.data.list.map((item) => ({ |
| | | id: item.id, |
| | | name: item.name, |
| | | wayline_type: item.wayline_type, |
| | | user_name: item.user_name, |
| | | update_time: item.update_time, |
| | | })) |
| | | this.page.total = responseData.data.pagination?.total || responseData.data.list.length |
| | | this.page.currentPage = page.currentPage |
| | | console.log('返回数据条数:', this.data.length) |
| | | console.log('当前页码:', this.page.currentPage) |
| | | console.log('总条数:', this.page.total) |
| | | } else { |
| | | this.data = [] |
| | | this.page.total = 0 |
| | | } |
| | | } catch (error) { |
| | | console.error('加载数据失败:', error) |
| | | this.data = [] |
| | | this.page.total = 0 |
| | | } finally { |
| | | this.loading = false |
| | | } |
| | | }, |
| | | searchChange (params, done) { |
| | | this.query = { ...params } |
| | | const airportColumn = this.option.column.find((col) => col.prop === 'dock_name') |
| | | const selectedAirport = airportColumn.dicData.find((item) => item.nickname === params.dock_name) |
| | | this.selectedWorkspaceId = selectedAirport ? selectedAirport.workspace_id : null |
| | | this.page.currentPage = 1 |
| | | this.fetchData(this.page, this.query) |
| | | done() |
| | | }, |
| | | searchReset () { |
| | | const { defaultStartDate, defaultEndDate } = this.getDefaultDates() |
| | | this.query = { name: '', dock_name: '', daterange: [defaultStartDate, defaultEndDate] } |
| | | this.selectedWorkspaceId = null |
| | | const daterangeColumn = this.option.column.find((col) => col.prop === 'daterange') |
| | | daterangeColumn.searchValue = [defaultStartDate, defaultEndDate] |
| | | this.page.currentPage = 1 |
| | | this.fetchData(this.page, this.query) |
| | | }, |
| | | currentChange (currentPage) { |
| | | console.log('切换页码至:', currentPage) |
| | | this.page.currentPage = currentPage |
| | | this.fetchData(this.page, this.query) |
| | | }, |
| | | sizeChange (pageSize) { |
| | | console.log('每页条数改为:', pageSize) |
| | | this.page.pageSize = pageSize |
| | | this.page.currentPage = 1 |
| | | this.fetchData(this.page, this.query) |
| | | }, |
| | | refreshChange () { |
| | | this.fetchData(this.page, this.query) |
| | | }, |
| | | formatTime (time) { |
| | | if (!time) return '' |
| | | const date = new Date(time < 10000000000 ? time * 1000 : time) |
| | | if (isNaN(date.getTime())) return '无效时间' |
| | | return date.toLocaleString('zh-CN', { hour12: false }).replace(/\//g, '-') |
| | | }, |
| | | formatWaylineType (type) { |
| | | const typeMap = { '0': '普通航线', '1': '图斑举证航线', '2': '航测航线', '3': '航点航线', '4': '正射举证航线' } |
| | | return typeMap[type] || '未知' |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .avue-crud .el-table { |
| | | max-height: none !important; |
| | | } |
| | | </style> |