Merge remote-tracking branch 'origin/feature/v6.0/6.0.3' into feature/v6.0/6.0.3
31 files modified
1 files added
| | |
| | | # 算法仓库图片地址 |
| | | VITE_APP_PICTURE_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket |
| | | |
| | | # 行政区划存放地址 |
| | | VITE_APP_REGION_URL = https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_region |
| | | # 是否在打包时开启压缩,支持 gzip 和 brotli |
| | | VITE_BUILD_COMPRESS = gzip |
| | | |
| | |
| | | } |
| | | |
| | | // 注销 |
| | | export const deviceOffline = (dockSn) => { |
| | | export const deviceOffline = (dockSn, deleteFlag) => { |
| | | return request({ |
| | | url: `/drone-device-core/manage/api/v1/devices/deviceOffline?dockSn=${dockSn}`, |
| | | url: `/drone-device-core/manage/api/v1/devices/deviceOffline?dockSn=${dockSn}&deleteFlag=${deleteFlag}`, |
| | | method: 'get', |
| | | }) |
| | | } |
| | |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | | } |
| | | |
| | | export const devicesUpAndDown = (param) => { |
| | | return request({ |
| | | url: `/drone-device-core/manage/api/v1/devices/upAndDown`, |
| | | method: 'post', |
| | | data: param |
| | | }) |
| | | } |
| | |
| | | }) |
| | | } |
| | | |
| | | export const getDeviceRegion = params => { |
| | | export const getDeviceRegion = data => { |
| | | return request({ |
| | | url: '/drone-device-core/manage/api/v1/devices/getDeviceRegion', |
| | | method: 'get', |
| | | params, |
| | | }) |
| | | } |
| | | |
| | | export const getDeviceRegionByPost = data => { |
| | | return request({ |
| | | url: '/drone-device-core/manage/api/v1/devices/getDeviceRegion', |
| | | method: 'post', |
| | | data, |
| | | method: 'post', |
| | | data:{ hidden_flag:0, ...data }, |
| | | }) |
| | | } |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | export const getDeviceRegion = params => { |
| | | export const getDeviceRegion = data => { |
| | | return request({ |
| | | url: '/drone-device-core/manage/api/v1/devices/getDeviceRegion', |
| | | method: 'get', |
| | | params, |
| | | method: 'post', |
| | | data:{ hidden_flag:0, ...data }, |
| | | }) |
| | | } |
| | | |
| | |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | | } |
| New file |
| | |
| | | <template> |
| | | <el-dialog class="ztzf-dialog-mange" append-to-body v-model="props.isShowView" :title="props.title" |
| | | :width="props.width" :close-on-click-modal="false" :destroy-on-close="true" @close="cancel"> |
| | | <slot name="default" /> |
| | | <template #footer v-if="props.addEditView !== 'view'"> |
| | | <div class="dialog-footer"> |
| | | <el-button v-if="props.addEditView === 'add'" type="primary" @click="submit" :icon="CirclePlus">保存</el-button> |
| | | <el-button v-else type="primary" @click="submit" :icon="CircleCheck">确认</el-button> |
| | | <el-button @click="cancel" :icon="CircleClose">取消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | <script setup> |
| | | import { ElMessage } from 'element-plus' |
| | | import { Delete, Search, CircleCheck, CircleClose, CirclePlus } from '@element-plus/icons-vue' |
| | | import { defineEmits } from 'vue'; |
| | | |
| | | const emit = defineEmits(['cancel', 'confirm']); |
| | | |
| | | const props = defineProps({ |
| | | width: { |
| | | type: String, |
| | | default: '800' |
| | | }, |
| | | isShowView: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | addEditView: { |
| | | type: String, |
| | | default: 'add' |
| | | }, |
| | | title:{ |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }) |
| | | |
| | | function submit() { |
| | | emit('submit') |
| | | } |
| | | function cancel() { |
| | | emit('cancel') |
| | | } |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | </style> |
| | |
| | | index: true, |
| | | selection: true, |
| | | viewBtn: true, |
| | | menuWidth: 250, |
| | | menuWidth: 280, |
| | | dialogWidth: 880, |
| | | dialogClickModal: false, |
| | | |
| | |
| | | index: true, |
| | | selection: true, |
| | | viewBtn: true, |
| | | menuWidth: 250, |
| | | menuWidth: 280, |
| | | dialogWidth: 880, |
| | | dialogClickModal: false, |
| | | |
| | |
| | | <el-dropdown class="avue-tags__menu"> |
| | | <el-button type="primary" style="background: #409eff;border-color: #409eff"> |
| | | {{ $t('tagsView.menu') }} |
| | | <i class="el-icon-arrow-down el-icon--right"></i> |
| | | <!-- <i class="el-icon-arrow-down el-icon--right"></i> --> |
| | | </el-button> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | |
| | | @import './variables.scss'; |
| | | @import './base.scss'; |
| | | @import './tool.scss'; |
| | | @import './element-ui.scss'; |
| | | a { |
| | | text-decoration: none; |
| | | color: #333; |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | //======以下针对表格功能 增删查改样式和弹窗========= |
| | | .ztzf-dialog-mange { |
| | | .el-dialog__body { |
| | | padding: 2rem 2rem 4rem; |
| | | flex: 1; |
| | | overflow: scroll; |
| | | border-top: 0.1rem solid #f0f0f0; |
| | | } |
| | | .el-dialog__footer { |
| | | z-index: 2; |
| | | display: block; |
| | | padding: 1rem 1.6rem; |
| | | box-sizing: border-box; |
| | | border-top: 0.1rem solid #f0f0f0; |
| | | width: 100%; |
| | | position: absolute; |
| | | left: 0; |
| | | bottom: 0; |
| | | background-color: #fff; |
| | | text-align: right; |
| | | } |
| | | } |
| | | .ztzf-search-mange { |
| | | height: 40px; |
| | | .search-contain { |
| | | display: flex;justify-content: space-between; |
| | | } |
| | | } |
| | | .ztzf-form-mange { |
| | | .el-form-item { |
| | | width: 300px; |
| | | :deep(.el-form-item__label) { |
| | | width: 120px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ztzf-table-mange { |
| | | th.el-table__cell { |
| | | color: rgba(0, 0, 0, .85); |
| | | background-color: #fafafa; |
| | | } |
| | | } |
| | | |
| | | .table-view-mange { |
| | | width: 100%; |
| | | border-top: 0.1rem solid #ebeef5; |
| | | border-left: 0.1rem solid #ebeef5; |
| | | margin-left: 0; |
| | | margin-right: 0; |
| | | .el-col { |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | margin-bottom: 0; |
| | | height: 32px; |
| | | line-height: 32px; |
| | | border-right: 0.1rem solid #ebeef5; |
| | | text-align: center; |
| | | align-items: center; |
| | | .el-input__wrapper { |
| | | box-shadow: none !important; |
| | | border-bottom: 0.1rem solid #ebeef5; |
| | | } |
| | | } |
| | | .label { |
| | | color: #909399; |
| | | box-sizing: border-box; |
| | | background: #fafafa; |
| | | } |
| | | } |
| | |
| | | speed: 5 |
| | | }) |
| | | |
| | | let arrowLineMaterialPropertyOrange = new ArrowLineMaterialProperty({ |
| | | color: new Cesium.Color(255 / 255, 185 / 255, 58 / 255, 1), |
| | | directionColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineWidth: 0, |
| | | speed: 5, |
| | | }) |
| | | |
| | | let arrowLineMaterialPropertyGreen = new ArrowLineMaterialProperty({ |
| | | color: new Cesium.Color(6 / 255, 217 / 255, 87 / 255, 1), |
| | | directionColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineWidth: 0, |
| | | speed: 5, |
| | | }) |
| | | |
| | | // 记录index |
| | | let indexLog = 0 |
| | | // 颜色 |
| | | function getLineColor(lineNumber) { |
| | | // 颜色顺序: 蓝(0), 黄(1), 绿(2) |
| | | const colors = [arrowLineMaterialProperty, arrowLineMaterialPropertyOrange, arrowLineMaterialPropertyGreen] |
| | | // 计算颜色索引 (从0开始) |
| | | const colorIndex = (lineNumber - 1) % 3 |
| | | // 返回对应颜色 |
| | | return colors[colorIndex] |
| | | } |
| | | |
| | | let runningLineMaterial = new LineTrailMaterial({ |
| | | color: Cesium.Color.fromCssColorString('#1FFF69'), |
| | | opacity: 1, |
| | |
| | | * @param {*} viewer |
| | | */ |
| | | initCreateRoute (viewer) { |
| | | indexLog = 0 |
| | | this.viewer = viewer |
| | | } |
| | | |
| | |
| | | */ |
| | | async drawPointRoute (lineObj, missionConfig, dronePosition, data, startPoint, isShowDock, isShowPointBillboard, wayline_type) { |
| | | const { positionArray, filePositions } = this.disposeData(lineObj, missionConfig, dronePosition, data, startPoint, wayline_type) |
| | | |
| | | |
| | | const droneTransformPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(dronePosition.longitude), |
| | | Number(dronePosition.latitude), |
| | |
| | | |
| | | // 路径线 |
| | | let polyline |
| | | |
| | | |
| | | if (this.type === 'clusterScheduling') { |
| | | filePositions.forEach((item, index) => { |
| | |
| | | polyline: { |
| | | width: 4, |
| | | positions: positionArray, |
| | | material: arrowLineMaterialProperty, |
| | | material: getLineColor(indexLog), |
| | | clampToGround: false, |
| | | }, |
| | | |
| | |
| | | * @returns {} {positionArray: 带拼接点位置, filePositions:光航线点位置} |
| | | */ |
| | | disposeData (lineObj, missionConfig, dronePosition, data, startPoint, wayline_type) { |
| | | indexLog = indexLog + 1 |
| | | const { device_sn } = data |
| | | |
| | | const executeHeightMode = lineObj.executeHeightMode === "WGS84" |
| | |
| | | <template> |
| | | <div class="algorithmMange"> |
| | | <div class="search-box"> |
| | | <div class="ztzf-search-mange"> |
| | | <el-form :model="params" inline> |
| | | <div style="display: flex;justify-content: space-between;"> |
| | | <div class="search-contain"> |
| | | <div> |
| | | <el-form-item label="算法名称:"> |
| | | <el-input v-model="params.algName" placeholder="请输入算法名称" clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="算法类型:"> |
| | | <el-select class="ztzf-select" :teleported="false" v-model="params.algTypeCode" placeholder="请选择算法类型" clearable> |
| | | <el-option v-for="item in sfTypes" :key="item.id" :label="item.dictValue" :value="item.dictKey" ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </div> |
| | | <div> |
| | | <el-form-item class="btns"> |
| | | <el-button type="primary" @click="getList">搜索</el-button> |
| | | <el-button @click="cancelSearch">清空</el-button> |
| | | <el-input v-model="params.algName" placeholder="请输入算法名称" clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="算法类型:"> |
| | | <el-select class="ztzf-select" :teleported="false" v-model="params.algTypeCode" placeholder="请选择算法类型" clearable> |
| | | <el-option v-for="item in sfTypes" :key="item.id" :label="item.dictValue" :value="item.dictKey" ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </div> |
| | | <div class="btns"> |
| | | <el-button type="primary" @click="getList" :icon="Search">搜索</el-button> |
| | | <el-button @click="cancelSearch" :icon="Delete">清空</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | </el-form> |
| | | </div> |
| | | <div class="mange-table"> |
| | | <el-table border :data="tableList" class="custom-header"> |
| | | <el-table border :data="tableList" class="ztzf-table-mange"> |
| | | <el-table-column label="序号" type="index" width="60"></el-table-column> |
| | | <el-table-column prop="model_name" label="算法名称" align="center" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="alg_type" label="算法类型" align="center"></el-table-column> |
| | |
| | | </div> |
| | | <div class="pagination"> |
| | | <el-pagination class="ztzf-pagination" popper-class="custom-pagination-dropdown" background |
| | | :page-sizes="[10, 20, 30, 40, 50, 100]" :size="size" v-model:current-page="params.current" |
| | | :page-sizes="[10, 20, 30, 40, 50, 100]" :size="params.size" v-model:current-page="params.current" |
| | | v-model:page-size="params.size" layout="total, sizes, prev, pager, next, jumper" :total="total" |
| | | @size-change="handleSizeChange" @current-change="handleCurrentChange" /> |
| | | </div> |
| | | </div> |
| | | <el-dialog class="ztzf-dialog" append-to-body v-model="isShowView" title="查看" |
| | | :width="pxToRem(600)" :close-on-click-modal="false" :destroy-on-close="true"> |
| | | <div class="content"> |
| | | <table class="view-table" border> |
| | | <tr> |
| | | <td class="label">算法名称</td> |
| | | <td class="value">{{ rowView.model_name }}</td> |
| | | <td class="label">算法类型</td> |
| | | <td class="value">{{ rowView.alg_type }}</td> |
| | | </tr> |
| | | <tr> |
| | | <td class="label">最低准确率</td> |
| | | <td class="value">{{ rowView.qua_rate }}</td> |
| | | <td class="label">最高准确率</td> |
| | | <td class="value">{{ rowView.pass_rate }}</td> |
| | | </tr> |
| | | <tr> |
| | | <td class="label">事件生成类型</td> |
| | | <td class="value">{{ rowView.event_type == 0 ? '常规类' : '紧急类' }}</td> |
| | | <td class="label">算法描述</td> |
| | | <td class="value">{{ rowView.remark }}</td> |
| | | </tr> |
| | | </table> |
| | | </div> |
| | | </el-dialog> |
| | | <el-dialog class="ztzf-dialog" append-to-body v-model="isShowEditView" title="编辑" |
| | | :width="pxToRem(800)" :close-on-click-modal="false" :destroy-on-close="true"> |
| | | <div class="content-edit"> |
| | | <el-form ref="ruleFormRef" :model="editParams" :rules="rules" inline> |
| | | <commonDialog :isShowView="isShowViewTest" width="1000" title="查看" addEditView="view" @cancel="isShowViewTest = false"> |
| | | <template #default> |
| | | <el-row :gutter="0" class="table-view-mange"> |
| | | <el-col :span="6" class="label">算法名称</el-col> |
| | | <el-col :span="6">{{ rowView.model_name }}</el-col> |
| | | <el-col :span="6" class="label">算法类型</el-col> |
| | | <el-col :span="6">{{ rowView.alg_type }}</el-col> |
| | | </el-row> |
| | | <el-row :gutter="0" class="table-view-mange"> |
| | | <el-col :span="6" class="label">最低准确率</el-col> |
| | | <el-col :span="6">{{ rowView.qua_rate }}</el-col> |
| | | <el-col :span="6" class="label">最高准确率</el-col> |
| | | <el-col :span="6">{{ rowView.pass_rate }}</el-col> |
| | | </el-row> |
| | | <el-row :gutter="0" class="table-view-mange"> |
| | | <el-col :span="6" class="label">事件生成类型</el-col> |
| | | <el-col :span="6">{{ rowView.event_type == 0 ? '常规类' : '紧急类' }}</el-col> |
| | | <el-col :span="6" class="label"></el-col> |
| | | <el-col :span="6"></el-col> |
| | | </el-row> |
| | | <el-row :gutter="0" class="table-view-mange"> |
| | | <el-col :span="6" class="label">算法描述</el-col> |
| | | <el-col :span="18"> |
| | | <el-input v-model="rowView.remark"></el-input> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </commonDialog> |
| | | <commonDialog :isShowView="isShowEditView" title="编辑" addEditView="edit" @submit="submit(ruleFormRef)" @cancel="isShowEditView = false"> |
| | | <template #default> |
| | | <el-form class="ztzf-form-mange" ref="ruleFormRef" :model="editParams" :rules="rules" inline> |
| | | <el-form-item label="算法名称"> |
| | | <el-input v-model="editParams.model_name" disabled /> |
| | | </el-form-item> |
| | |
| | | <el-form-item label="算法描述"> |
| | | <el-input v-model="editParams.remark" placeholder="请输入算法描述" clearable /> |
| | | </el-form-item> |
| | | <div class="btns"> |
| | | <el-button type="primary" @click="submit(ruleFormRef)">确认</el-button> |
| | | <el-button @click="isShowEditView = false">取消</el-button> |
| | | </div> |
| | | </el-form> |
| | | </div> |
| | | </el-dialog> |
| | | </template> |
| | | </commonDialog> |
| | | </template> |
| | | <script setup> |
| | | import { getAlgorithmManageList, algorithmManageEdit } from '@/api/algorithmMange/algorithmMange'; |
| | | import { getDictionaryByCode } from '@/api/system/dictbiz'; |
| | | import commonDialog from '@/components/commonDialog.vue' |
| | | import { ElMessage } from 'element-plus'; |
| | | import { Delete, Search } from '@element-plus/icons-vue' |
| | | |
| | | const total = ref(0) |
| | | const params = ref({ |
| | |
| | | |
| | | let tableList = ref([]) |
| | | |
| | | let isShowView = ref(false) |
| | | let isShowViewTest = ref(false) |
| | | |
| | | let rowView = ref({}) |
| | | |
| | |
| | | }); |
| | | } |
| | | function handleDetail(row) { |
| | | isShowView.value = true |
| | | isShowViewTest.value = true |
| | | rowView.value = row |
| | | } |
| | | function handleEdit(row) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .content { |
| | | padding: 20px; |
| | | |
| | | .view-table { |
| | | width: 100%; |
| | | border-collapse: collapse; |
| | | border: 1px solid #EBEEF5; |
| | | |
| | | tr { |
| | | &:not(:last-child) { |
| | | border-bottom: 1px solid #EBEEF5; |
| | | } |
| | | |
| | | td { |
| | | padding: 12px 10px; |
| | | |
| | | &.label { |
| | | width: 140px; |
| | | text-align: right; |
| | | // color: #909399; |
| | | // background-color: #F5F7FA; |
| | | border-right: 1px solid #EBEEF5; |
| | | } |
| | | |
| | | &.value { |
| | | width: 180px; |
| | | // color: #303133; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .content-edit { |
| | | .el-form { |
| | | .el-form-item { |
| | | width: 300px; |
| | | :deep(.el-form-item__label) { |
| | | width: 120px; |
| | | } |
| | | |
| | | } |
| | | .btns { |
| | | display: flex; |
| | | justify-content: center |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <el-dialog modal-class="mapDialog" v-model="isShow" width="80%"> |
| | | <el-dialog modal-class="mapDialog" v-model="isShow" width="80%" class="ztzf-dialog-mange"> |
| | | <template #header="{ titleId, titleClass }"> |
| | | <div class="my-header"> |
| | | <h4 :id="titleId" :class="titleClass">定位</h4> |
| | |
| | | |
| | | <style scoped lang="scss"> |
| | | .mapBox { |
| | | margin-top: 10px; |
| | | z-index: 2; |
| | | height: 650px; |
| | | width: 98%; |
| | |
| | | <!-- 查看弹框 --> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | class="ztzf-dialog-mange" |
| | | width="60%" |
| | | append-to-body |
| | | @close="dialogClose" |
| | |
| | | <!-- 视频预览 --> |
| | | <el-dialog |
| | | :title="currentVideoTitle" |
| | | class="ztzf-dialog-mange" |
| | | modal-class="videoDialog" |
| | | append-to-body |
| | | width="54%" |
| | |
| | | @click.stop="copyInfo(scope.row, scope.index)" v-if="userInfo.role_name.includes('admin')">复制 |
| | | </el-button> |
| | | </template> |
| | | </avue-crud> |
| | | </avue-crud>F |
| | | </basic-container> |
| | | </template> |
| | | |
| | |
| | | label: '设备类型', |
| | | editDisplay: false, |
| | | prop: 'type', |
| | | type: 'radio', |
| | | labelWidth: 130, |
| | | value: 0, |
| | | type: 'select', |
| | | dicData: [ |
| | | { |
| | | label: '机场', |
| | | label: '机巢', |
| | | value: 0 |
| | | }, |
| | | { |
| | | label: '遥控器', |
| | | label: '控制器', |
| | | value: 1 |
| | | } |
| | | ], |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: '设备描述', // '工作空间描述', |
| | | prop: 'workspace_desc', |
| | | labelWidth: 130, |
| | | searchSpan: 4, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入设备描述', |
| | | trigger: 'blur', |
| | | }, |
| | | { |
| | | max: 30, |
| | | message: '设备描述不能超过30个字', |
| | | trigger: 'blur', |
| | | }, |
| | | // 如果需要更严格的校验(如中文字符计算),可以使用 validator |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (value && value.length > 30) { |
| | | callback(new Error('设备描述不能超过30个字')); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | { |
| | | label: '创建时间', |
| | | prop: 'create_time', |
| | | addDisplay: false, |
| | |
| | | format: 'YYYY-MM-DD HH:mm:ss', |
| | | |
| | | }, |
| | | { |
| | | label: '设备描述', // '工作空间描述', |
| | | prop: 'workspace_desc', |
| | | type: 'textarea', |
| | | labelWidth: 130, |
| | | searchSpan: 4, |
| | | overHidden: true, |
| | | minRows: 3, |
| | | maxRows: 5, |
| | | maxlength: 250, |
| | | span: 24, |
| | | showWordLimit: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入设备描述不能超过250个字', |
| | | trigger: 'blur', |
| | | }, |
| | | { |
| | | max: 250, |
| | | message: '设备描述不能超过250个字', |
| | | trigger: 'blur', |
| | | }, |
| | | // 如果需要更严格的校验(如中文字符计算),可以使用 validator |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (value && value.length > 250) { |
| | | callback(new Error('设备描述不能超过250个字')); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | |
| | | |
| | | |
| | | ], |
| | |
| | | </template> |
| | | <template #menu="scope"> |
| | | <el-dropdown> |
| | | <el-button type="primary" text v-if="permission.oss_set"><el-icon><MoreFilled /></el-icon>更多</el-button> |
| | | <el-button type="primary" text v-if="permission.oss_set"><el-icon><MoreFilled /></el-icon>更多</el-button> |
| | | <template #dropdown v-if="scope.row.domain == 3"> |
| | | <el-dropdown-menu teleported> |
| | | <el-dropdown-item command="a"> |
| | |
| | | <el-dropdown-item command="d"><el-button type="primary" text icon="el-icon-collection" v-if="permission.fly_device_offline" |
| | | @click.stop="rollFirmware(scope.row)">固件版本管理</el-button> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item command="d"> |
| | | <el-button type="primary" text icon="el-icon-collection" v-if="!scope.row.status" @click.stop="dockNotLine(scope.row)"> |
| | | {{ scope.row.hidden_flag == 1 ? '设备上线' : '设备下线'}} |
| | | <el-dropdown-item command="d" v-if="!scope.row.status"> |
| | | <el-button type="primary" text icon="el-icon-collection" @click.stop="dockNotLine(scope.row)"> |
| | | {{ scope.row.hidden_flag === 1 ? '设备上线' : '设备下线'}} |
| | | </el-button> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item command="e"><el-button type="primary" text icon="el-icon-document-delete" v-if="permission.fly_device_offline" |
| | |
| | | </template> |
| | | <template #dropdown v-else> |
| | | <el-dropdown-menu teleported> |
| | | <el-dropdown-item command="a"> |
| | | <!-- <el-dropdown-item command="a"> |
| | | <el-button type="primary" text icon="el-icon-circle-close" @click.stop="rowDel(scope.row, scope.index)">删除</el-button> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item command="a"> |
| | | </el-dropdown-item> --> |
| | | <!-- <el-dropdown-item command="a"> |
| | | <el-button type="primary" text icon="el-icon-key" v-if="permission.operate_password_set" @click.stop="handleOperatePassword(scope.row, scope.index)">操控密码设置</el-button> |
| | | </el-dropdown-item> --> |
| | | <el-dropdown-item command="d"><el-button type="primary" text icon="el-icon-collection" @click.stop="rollFirmware(scope.row)">固件版本管理</el-button> |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </template> |
| | | |
| | | |
| | | <!-- 添加行政区划显示模板 --> |
| | | <template #area_code="{ row }"> |
| | | <span>{{ row.area_name }}</span> |
| | |
| | | |
| | | <el-dialog title="操控密码查看" append-to-body v-model="operatePasswordViewBox" width="455px"> |
| | | <el-input v-model="operate_password" disabled></el-input> |
| | | </el-dialog> |
| | | |
| | | <el-dialog title="注销" class="zx-cancel" append-to-body v-model="cancenOperate" width="460px"> |
| | | <div style="display: flex;justify-content: center;margin-bottom: 10px;">注销 |
| | | <span style="color:cornflowerblue;font-weight: bolder;margin: 0px 4px;"> |
| | | {{ cancelSNName }} |
| | | </span> 设备可能会影响相关数据,确认注销吗?</div> |
| | | <div style="display: flex;justify-content: center;color:red;font-size: 12px;">*删除相关图片、视频、事件</div> |
| | | <template #footer> |
| | | <span class="dialog-footer" style="display: flex;justify-content: center;"> |
| | | <el-button @click="cancenOperate = false">取 消</el-button> |
| | | <el-button type="primary" @click="cancenOperateDo">确 定</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <el-dialog title="固件升级" append-to-body v-model="firmwareBox" width="455px"> |
| | |
| | | getDeviceFirmwareList, |
| | | getDevices, |
| | | deviceOffline, |
| | | devicesUpdate |
| | | devicesUpdate, |
| | | devicesUpAndDown |
| | | } from '@/api/device/device' |
| | | import { deleteByOssId, addOrUpdate as addOrUpdateOssBind } from '@/api/device/ossBind' |
| | | import { getListPage as getOssList } from '@/api/resource/oss' |
| | |
| | | } |
| | | } |
| | | return { |
| | | treeResolveMap: new Map(), |
| | | rules: { |
| | | password: [{ required: true, validator: validatePass, trigger: 'blur' }], |
| | | password2: [{ required: true, validator: validatePass2, trigger: 'blur' }], |
| | | }, |
| | | cancelSNName: '', |
| | | cancenOperate: false, |
| | | cancenOperateRow: {}, |
| | | deleteFlag: false, |
| | | passwordForm: { |
| | | id: '', |
| | | password: '', |
| | |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | |
| | | // { |
| | | // label: '设备位置', |
| | | // prop: 'address', |
| | |
| | | width: 200, |
| | | type: 'daterange', |
| | | format: 'YYYY-MM-DD', |
| | | valueFormat: 'YYYY-MM-DD HH:mm:ss', |
| | | valueFormat: 'YYYY-MM-DD', |
| | | startPlaceholder: '保险开始日期', |
| | | endPlaceholder: '保险结束日期', |
| | | align: 'center', |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | required: false, |
| | | message: '请选择保险有效期', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | formatter: (row, value) => { |
| | | return value[0]? `${this.$dayjs(value[0]).format('YYYY-MM-DD')}~${this.$dayjs(value[1]).format('YYYY-MM-DD')}` : '/'; |
| | | }, |
| | | }, |
| | | // { |
| | | // label: '保险有效期', |
| | |
| | | // }, |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | { |
| | | label: '在线时间', |
| | |
| | | }, |
| | | }, |
| | | destroyed () { |
| | | this.treeResolveMap.clear() |
| | | this.websocketMap.forEach((k, v) => { |
| | | if (null != v) { |
| | | v.close() |
| | |
| | | this.operateTitle = row.nickname + ' - ' + row.device_sn |
| | | }, |
| | | |
| | | // 设备下线 |
| | | // 设备注销 |
| | | handleDeviceOffline (row) { |
| | | ElMessageBox.confirm('确定注销该设备吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }) |
| | | .then(() => { |
| | | deviceOffline(row.device_sn) |
| | | .then(res => { |
| | | ElMessage.success('注销成功') |
| | | this.cancenOperate = true |
| | | this.cancelSNName = row.nickname |
| | | this.cancenOperateRow = row |
| | | |
| | | }, |
| | | |
| | | this.init() |
| | | }) |
| | | .catch(error => { |
| | | ElMessage.error('注销失败') |
| | | }) |
| | | }) |
| | | .catch(() => { }) |
| | | cancenOperateDo () { |
| | | this.cancenOperate = false |
| | | this.deleteFlag = false |
| | | deviceOffline(this.cancenOperateRow.device_sn, true).then(res => { |
| | | ElMessage.success('注销成功') |
| | | |
| | | this.init() |
| | | }).catch(error => { |
| | | ElMessage.error('注销失败') |
| | | }) |
| | | }, |
| | | |
| | | // 打开存储对象配置页面 |
| | |
| | | }) |
| | | .then(() => { |
| | | let hidden_flag = row.hidden_flag === 1?0:1 |
| | | devicesUpdate({id:row.id, hidden_flag:hidden_flag}) |
| | | devicesUpAndDown({id:row.id, hiddenFlag:hidden_flag}) |
| | | .then(res => { |
| | | ElMessage.success('下线成功') |
| | | ElMessage.success(`${txt}成功`) |
| | | this.init() |
| | | }) |
| | | .catch(error => { |
| | |
| | | const submitData = { |
| | | ...row, |
| | | area_code: row.area_code.split(',').pop(), |
| | | insure_start_time: row.duration_of_insurance[0], |
| | | insure_expired_time: row.duration_of_insurance[1], |
| | | insure_start_time: row.duration_of_insurance[0] || null, |
| | | insure_expired_time: row.duration_of_insurance[1] || null, |
| | | deptId: row.dept_id, |
| | | areaCode: row.area_code.split(',').pop(), |
| | | } |
| | |
| | | |
| | | update(submitData).then( |
| | | () => { |
| | | this.onLoad(this.page) |
| | | if (row.domain === 0) { |
| | | // 获取保存的 resolve 函数 |
| | | const resolve = this.treeResolveMap.get(row.device_sn) |
| | | if (resolve) { |
| | | // 重新加载子节点数据 |
| | | var params = { |
| | | childSn: row.device_sn, |
| | | } |
| | | getList(1, 10, params).then(res => { |
| | | const data = res.data.data.records |
| | | data.forEach(e => { |
| | | e.duration_of_insurance = [e.insure_start_time || '', e.insure_expired_time || ''] |
| | | }) |
| | | resolve(data) |
| | | }) |
| | | } |
| | | } else { |
| | | this.onLoad(this.page) |
| | | } |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | |
| | | area_code: await this.getFullAreaCode(data.area_code), |
| | | area_name: this.form.area_name, |
| | | cnmode_code: this.getDockModeText(this.form.mode_code), |
| | | // domain: data.domain === 0 ? '无人机' : data.domain === 3 ? '机巢' : '未知', |
| | | domainTxt: data.domain === 0 ? '无人机' : data.domain === 3 ? '机巢' : '未知', |
| | | cnstatus: this.form.status === false ? '离线' : '在线', |
| | | duration_of_insurance: [data?.insure_start_time || '', data?.insure_expired_time || ''], |
| | |
| | | }) |
| | | }, |
| | | treeLoad (tree, treeNode, resolve) { |
| | | // 保存resolve |
| | | this.treeResolveMap.set(tree.child_sn, resolve) |
| | | var params = { |
| | | childSn: tree.child_sn, |
| | | } |
| | | getList(1, 10, params).then(res => { |
| | | const data = res.data.data.records |
| | | data.forEach(e => { |
| | | e.duration_of_insurance = [e.insure_start_time || '', e.insure_expired_time || ''] |
| | | }) |
| | | resolve(data) |
| | | }) |
| | | }, |
| | |
| | | right: 0; |
| | | } |
| | | |
| | | :deep(.avue-crud__pagination) { |
| | | position: fixed; |
| | | bottom: 10px; |
| | | right: 30px; |
| | | } |
| | | |
| | | |
| | | </style> |
| | |
| | | watch( |
| | | () => Store.getters.deviceState, |
| | | value => { |
| | | console.log(value, '测试') |
| | | // console.log('设备状态变化', value.deviceInfo[props.deviceInfo.child_sn]) |
| | | if (props.sn && (value.currentSn === props.deviceInfo.child_sn || value.currentSn === props.deviceInfo.device_sn)) { |
| | | debugStatus.value = value.dockInfo[props.deviceInfo.device_sn]?.basic_osd?.mode_code === EDockModeCode.Remote_Debugging |
| | |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | label: '授权功能', |
| | | prop: 'devicePerMenuId', |
| | | labelWidth: 130, |
| | | type: 'tree', |
| | | dicUrl: '/blade-system/manage/api/v1/devicePerMenu/selectDeviceList', |
| | | props: { |
| | | label: 'name', |
| | | value: 'id', |
| | | }, |
| | | multiple: true, |
| | | dataType: 'string', |
| | | span: 24, |
| | | row: true, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请输入授权功能', |
| | | trigger: 'blur', |
| | | }, |
| | | ], |
| | | }, |
| | | // { |
| | | // label: '授权功能', |
| | | // prop: 'devicePerMenuId', |
| | | // labelWidth: 130, |
| | | // type: 'tree', |
| | | // dicUrl: '/blade-system/manage/api/v1/devicePerMenu/selectDeviceList', |
| | | // props: { |
| | | // label: 'name', |
| | | // value: 'id', |
| | | // }, |
| | | // multiple: true, |
| | | // dataType: 'string', |
| | | // span: 24, |
| | | // row: true, |
| | | // rules: [ |
| | | // { |
| | | // required: true, |
| | | // message: '请输入授权功能', |
| | | // trigger: 'blur', |
| | | // }, |
| | | // ], |
| | | // }, |
| | | { |
| | | label: '授权时间', |
| | | prop: 'createTime', |
| | |
| | | </el-button> |
| | | </template> |
| | | </avue-crud> |
| | | <el-dialog title="固件上传" append-to-body v-model="firmwareUploadBox" width="40%" height="60%"> |
| | | <el-dialog title="固件上传" class="ztzf-dialog-mange" append-to-body v-model="firmwareUploadBox" width="40%" height="60%"> |
| | | <el-form |
| | | ref="form" |
| | | class="ztzf-form-mange" |
| | | :model="importForm" |
| | | v-loading="loadingForm" |
| | | label-width="80px" |
| | | style="width: 80%; margin-left: 10%" |
| | | :rules="rules" |
| | | > |
| | |
| | | <el-form-item label="说明" label-width="80px" prop="release_note"> |
| | | <el-input type="textarea" v-model="importForm.release_note" clearable></el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="onConfirm">确定</el-button> |
| | | <el-button @click="onCancel">取消</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="onConfirm">确定</el-button> |
| | | <el-button @click="onCancel">取消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </basic-container> |
| | | </template> |
| | |
| | | const jobId = ref('') |
| | | const handleDetail = row => { |
| | | if (!row.device_sns.length) return ElMessage.warning('没有device_sns') |
| | | if (row.device_sns.length !== 1) return ElMessage.success('即将跳转到集群调度') |
| | | rowData.value = row ? row : {} |
| | | jobId.value = rowData.value?.job_id |
| | | if (row.device_sns.length > 1 && (row.status === 2 || row.status === 1)) { |
| | | const adminUrl = `${import.meta.env.VITE_APP_AREA_NAME}/command-center-dashboard/#/clusterScheduling` |
| | | const targetPath = `taskNo=${encodeURIComponent(rowData.value.job_info_num)}` |
| | | window.open(`${adminUrl}?${targetPath}`, '_blank') |
| | | return |
| | | } |
| | | jobId.value = rowData.value?.job_id |
| | | if (row.status === 2 || row.status === 1) { |
| | | // isShowCurrentTaskDetails.value = true |
| | | // 跳转大屏当前任务详情 |
| | |
| | | type: 'category', |
| | | // data: ['1月', '2月', '3月', '4月', '5月', '6月'], |
| | | axisLine: { |
| | | show: false, // 隐藏轴线 |
| | | }, |
| | | axisLine: { |
| | | show: false, // 隐藏轴线 |
| | | show: true, // 隐藏轴线 |
| | | }, |
| | | axisLabel: { |
| | | color: '#5B5B5D', |
| | |
| | | formatter: '{b}: {c} ({d}%)', |
| | | }, |
| | | legend: { |
| | | orient: 'horizontal', |
| | | left: 'center', |
| | | bottom: '2%', |
| | | orient: 'vertical', |
| | | top: 'center', |
| | | right: '20', |
| | | textStyle: { |
| | | color: '#363636', |
| | | fontSize: 12, |
| | | }, |
| | | itemWidth: 2, // 减小图例标记的宽度 |
| | | itemHeight: 3, // 减小图例标记的高度 |
| | | itemHeight: 6, // 减小图例标记的高度 |
| | | itemGap: 8, // 减小图例项之间的间距 |
| | | formatter: '{name}', // 简化图例文本 |
| | | }, |
| | |
| | | name: '机巢事件统计', |
| | | type: 'pie', |
| | | // roseType: 'radius', |
| | | radius: ['36%', '60%'], |
| | | // center: ['50%', '45%'], |
| | | // radius: '70%', // 设置饼图的半径 |
| | | center: ['50%', '36%'], // 调整饼图位置 |
| | | radius: ['20%', '70%'], |
| | | center: ['30%', '50%'], |
| | | data: [], |
| | | label: { |
| | | show: true, |
| | |
| | | |
| | | <style lang="scss" scoped> |
| | | .task-industry { |
| | | width: 276px; |
| | | width: 300px; |
| | | height: 100%; |
| | | background: #FFFFFF; |
| | | border-radius: 8px 8px 8px 8px; |
| | |
| | | type: 'category', |
| | | data: ['1'], |
| | | axisLine: { |
| | | show: false, // 隐藏轴线 |
| | | show: true, // 隐藏轴线 |
| | | }, |
| | | axisTick: { |
| | | show: true, |
| | | length: 2, |
| | | lineStyle: { |
| | | color: '#363636', |
| | | }, |
| | | }, |
| | | // axisTick: { |
| | | // show: true, |
| | | // length: 2, |
| | | // lineStyle: { |
| | | // color: 'red', |
| | | // }, |
| | | // }, |
| | | axisLabel: { |
| | | color: '#363636', |
| | | margin: 8, |
| | |
| | | </avue-crud> |
| | | |
| | | <!-- 新增弹窗 --> |
| | | <el-dialog title="新增 License" v-model="addDialogVisible" width="70%" :close-on-click-modal="false" |
| | | <el-dialog class="ztzf-dialog-mange" title="新增 License" v-model="addDialogVisible" width="70%" :close-on-click-modal="false" |
| | | @close="resetForm"> |
| | | <el-form :model="newLicense" ref="licenseForm" label-width="120px"> |
| | | <el-form-item label="机构ID" prop="licenseId"> |
| | |
| | | <el-form-item label="机构名称" prop="licenseName" required> |
| | | <el-input v-model="newLicense.licenseName" /> |
| | | </el-form-item> |
| | | <el-form-item label="是否验证过期时间类型" prop="licenseType" required> |
| | | <el-form-item label="过期时间类型" prop="licenseType" required> |
| | | <el-select v-model="newLicense.licenseType" placeholder="请选择"> |
| | | <el-option label="不验证过期时间" :value="1" /> |
| | | <el-option label="验证过期时间" :value="2" /> |
| | |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="addDialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="createLicense">保存</el-button> |
| | | <el-button type="primary" @click="createLicense" :icon="CircleCheck">保存</el-button> |
| | | <el-button @click="addDialogVisible = false" :icon="CircleClose">取消</el-button> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | <script> |
| | | import { getList, add } from '@/api/license/license' |
| | | import { mapGetters } from 'vuex' |
| | | import { CircleCheck, CircleClose } from '@element-plus/icons-vue'; |
| | | |
| | | export default { |
| | | data () { |
| | |
| | | } |
| | | }, |
| | | computed: { |
| | | CircleClose() { |
| | | return CircleClose |
| | | }, |
| | | CircleCheck() { |
| | | return CircleCheck |
| | | }, |
| | | ...mapGetters(['userInfo', 'permission']), |
| | | permissionList () { |
| | | return { |
| | |
| | | <template> |
| | | <el-dialog |
| | | class="spotDialog" |
| | | class="spotDialog ztzf-dialog-mange" |
| | | :title="props.title" |
| | | v-model="uploadPatchDialog" |
| | | width="78%" |
| | | align-center |
| | | |
| | | > |
| | | <div class="container"> |
| | | <!-- 信息展示区 --> |
| | |
| | | <el-button type="primary" text icon="el-icon-edit" @click="uploadPatch(scope.row, 'edit')" |
| | | >编辑 |
| | | </el-button> |
| | | <el-button type="primary" text icon="el-icon-delete" @click="rowDel(scope.row)" |
| | | <el-button :disabled="scope.row.patches_type_desc==='综合类'" type="primary" text icon="el-icon-delete" @click="rowDel(scope.row)" |
| | | >删除 |
| | | </el-button> |
| | | </template> |
| | | </avue-crud> |
| | | |
| | | <el-dialog title="上传图斑" append-to-body align-center v-model="box" width="550px"> |
| | | <el-dialog title="上传图斑" class="ztzf-dialog-mange" append-to-body align-center v-model="box" width="550px"> |
| | | <el-form |
| | | ref="ruleFormRef" |
| | | style="max-width: 600px" |
| | |
| | | </basic-container> |
| | | </template> |
| | | <script setup> |
| | | import {findAreaName} from '@/utils/areaUtils' |
| | | import { findAreaName } from '@/utils/areaUtils'; |
| | | import { |
| | | spotManagementTableApi, |
| | | searchManagementApi, |
| | |
| | | border: true, |
| | | index: true, |
| | | indexLabel: '序号', |
| | | indexWidth: 60, |
| | | indexWidth: 60, |
| | | selection: true, |
| | | grid: false, |
| | | menuWidth: 240, |
| | |
| | | data.value = d.records.map(i => ({ |
| | | ...i, |
| | | dataFrom: i.date_from === 0 ? '本地上传' : '国土调查云', |
| | | areaName: findAreaName(i.area_code, regionalData.value, true) |
| | | areaName: findAreaName(i.area_code, regionalData.value, true), |
| | | })); |
| | | loading.value = false; |
| | | selectionClear(); |
| | |
| | | }; |
| | | // 图斑上传 |
| | | const uploadFlightFile = (file, t) => { |
| | | loading.value = true |
| | | loading.value = true; |
| | | const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1); |
| | | if (!['kmz', 'kml', 'zip'].includes(fileSuffix)) { |
| | | return ElMessage.error('请上传zip/kmz/kml格式的文件'); |
| | | } |
| | | |
| | | if (file) { |
| | | box.value = false; |
| | | } |
| | | let data = new FormData(); |
| | | let type = t === '3' ? '' : t; |
| | | const params = { |
| | |
| | | |
| | | ElMessage.success('上传成功'); |
| | | |
| | | box.value = false; |
| | | |
| | | loading.value = false; |
| | | ruleForm.name = ''; |
| | | ruleForm.region = ''; |
| | | |
| | | if (ruleFormRef.value) { |
| | | ruleFormRef.value.resetFields(); |
| | | } |
| | | loading.value = true |
| | | |
| | | searchReset(); |
| | | }); |
| | | }; |
| | |
| | | <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> |
| | |
| | | selection: true, |
| | | grid: false, |
| | | menuWidth: 180, |
| | | labelWidth: 100, |
| | | dialogWidth: 880, |
| | | labelWidth: 90, |
| | | dialogWidth: 600, |
| | | dialogClickModal: false, |
| | | height: 'auto', |
| | | calcHeight: 20, |
| | |
| | | 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' }], |
| | | }, |
| | | { |
| | |
| | | </el-row> |
| | | <!-- 表单模块 --> |
| | | <el-dialog |
| | | class="ztzf-dialog-mange" |
| | | :title="title" |
| | | v-model="box" |
| | | width="50%" |
| | |
| | | |
| | | <!-- 新建工单对话框 --> |
| | | <el-dialog |
| | | class="ztzf-dialog-mange" |
| | | v-model="dialogVisible" |
| | | title="新建工单" |
| | | width="70%" |
| | |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row> |
| | | <div class="add-box-btns"> |
| | | <el-button type="danger" @click="submitForm(1)">发起</el-button> |
| | | <el-button type="primary" @click="submitForm(0)">存草稿</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </div> |
| | | </el-row> |
| | | <!-- <el-row>--> |
| | | <!-- <div class="add-box-btns">--> |
| | | <!-- <el-button type="danger" @click="submitForm(1)">发起</el-button>--> |
| | | <!-- <el-button type="primary" @click="submitForm(0)">存草稿</el-button>--> |
| | | <!-- <el-button @click="dialogVisible = false">取消</el-button>--> |
| | | <!-- </div>--> |
| | | <!-- </el-row>--> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="danger" @click="submitForm(1)">发起</el-button> |
| | | <el-button type="primary" @click="submitForm(0)">存草稿</el-button> |
| | | <el-button @click="dialogVisible = false" :icon="CircleClose">取消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 工单详情对话框 --> |
| | | <el-dialog |
| | | class="ztzf-dialog-mange" |
| | | align-center |
| | | v-model="detailVisible" |
| | | :title="detailTitle" |
| | |
| | | <map-container v-if="detailVisible" ref="MapContainer"></map-container> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row> |
| | | <div class="add-box-btns"> |
| | | <el-button |
| | | type="danger" |
| | | v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" |
| | | @click="submitForm(1)" |
| | | >发布</el-button |
| | | > |
| | | <el-button |
| | | type="primary" |
| | | v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" |
| | | @click="submitForm(0)" |
| | | >保存</el-button |
| | | > |
| | | <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user" |
| | | @click="submitForm(0)">保存</el-button> --> |
| | | |
| | | <el-button |
| | | type="primary" |
| | | v-if="form.status == 1 && hasPaddingBtnPermission()" |
| | | @click="orderLogPass(form.id)" |
| | | >通过</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | v-if="form.status == 1 && hasRejectionBtnPermission()" |
| | | @click="orderLogReject(form.id)" |
| | | >驳回</el-button |
| | | > |
| | | </div> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button |
| | | type="danger" |
| | | v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" |
| | | @click="submitForm(1)" |
| | | >发布</el-button |
| | | > |
| | | <el-button |
| | | type="primary" |
| | | v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" |
| | | @click="submitForm(0)" |
| | | >保存</el-button |
| | | > |
| | | <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user" |
| | | @click="submitForm(0)">保存</el-button> --> |
| | | |
| | | <el-button |
| | | type="primary" |
| | | v-if="form.status == 1 && hasPaddingBtnPermission()" |
| | | @click="orderLogPass(form.id)" |
| | | >通过</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | v-if="form.status == 1 && hasRejectionBtnPermission()" |
| | | @click="orderLogReject(form.id)" |
| | | >驳回</el-button |
| | | > |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 工单详情 --> |
| | | <el-dialog |
| | | class="ztzf-dialog-mange" |
| | | align-center |
| | | v-model="detailVisibleCopy" |
| | | title="工单详情" |
| | |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row> |
| | | <div class="add-box-btns"> |
| | | <el-button |
| | | type="danger" |
| | | v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" |
| | | @click="submitForm(1)" |
| | | >发布</el-button |
| | | > |
| | | <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user" |
| | | @click="submitForm(0)">保存</el-button> --> |
| | | |
| | | <el-button |
| | | type="primary" |
| | | v-if="form.status == 1 && hasPaddingBtnPermission()" |
| | | @click="orderLogPass(form.id)" |
| | | >通过</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | v-if="form.status == 1 && hasRejectionBtnPermission()" |
| | | @click="orderLogReject(form.id)" |
| | | >驳回</el-button |
| | | > |
| | | <el-button @click="detailVisibleCopy = false">取消</el-button> |
| | | </div> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button |
| | | type="danger" |
| | | v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" |
| | | @click="submitForm(1)" |
| | | >发布</el-button |
| | | > |
| | | <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user" |
| | | @click="submitForm(0)">保存</el-button> --> |
| | | |
| | | <el-button |
| | | type="primary" |
| | | v-if="form.status == 1 && hasPaddingBtnPermission()" |
| | | @click="orderLogPass(form.id)" |
| | | >通过</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | v-if="form.status == 1 && hasRejectionBtnPermission()" |
| | | @click="orderLogReject(form.id)" |
| | | >驳回</el-button |
| | | > |
| | | <el-button @click="detailVisibleCopy = false">取消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </basic-container> |
| | | </template> |
| | |
| | | import 'dayjs/locale/zh-cn'; // 导入中文语言包 |
| | | import weekday from 'dayjs/plugin/weekday'; |
| | | import elTooltipCopy from '@/components/ElTooltipCopy.vue'; |
| | | import { CircleClose } from '@element-plus/icons-vue'; |
| | | |
| | | dayjs.extend(weekday); |
| | | dayjs.locale('zh-cn'); |
| | |
| | | } |
| | | }, |
| | | computed: { |
| | | CircleClose() { |
| | | return CircleClose |
| | | }, |
| | | ...mapGetters(['userInfo', 'permission']), |
| | | filteredTabs() { |
| | | // rejection_and_draft 权限控制“已驳回”和“草稿”tab |
| | |
| | | </div> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <div class="dialog-footer-new"> |
| | | <el-button type="danger" :loading="submitLoading" @click="submitForm">发布</el-button> |
| | | <el-button type="infoprimary" plain :loading="draftLoading" @click="saveDraft" |
| | | >存草稿</el-button |
| | | > |
| | | |
| | | <el-button @click="handleCancel">取 消</el-button> |
| | | <el-button @click="handleCancel" :icon="CircleClose">取 消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | </div> |
| | | |
| | | <!-- 操作按钮 --> |
| | | <div class="dialog-footer1"> |
| | | <div class="dialog-footer1-new"> |
| | | <div class="leftBtn" :class="currentIndex === 0 ? 'disableds' : ''" @click="leftClick"> |
| | | 上一页 |
| | | </div> |
| | |
| | | @click="rejectTicket" |
| | | >不通过</el-button |
| | | > |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | <el-button @click="detailVisible = false":icon="CircleClose">取消</el-button> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 0"> |
| | | <el-button |
| | |
| | | title="批量审核" |
| | | width="1100" |
| | | append-to-body |
| | | class="ztzf-dialog-mange" |
| | | custom-class="review-dialog" |
| | | @close="cancleBatchReject" |
| | | > |
| | |
| | | title="工单复核" |
| | | width="30%" |
| | | append-to-body |
| | | custom-class="re-check-dialog" |
| | | class="ztzf-dialog-mange" |
| | | @close="reCheckDialog = false" |
| | | > |
| | | <div class="dialog-footer"> |
| | |
| | | import elTooltipCopy from '@/components/ElTooltipCopy.vue'; |
| | | import getBaseConfig from '@/buildConfig/config'; |
| | | import CreateQRcode from '@/components/CreateQRcode/CreateQRcode.vue'; |
| | | import { CircleClose } from '@element-plus/icons-vue'; |
| | | const { envName } = getBaseConfig(); |
| | | function regExp(label, name) { |
| | | var reg = new RegExp(label + '=([^&]*)(&|$)', 'g'); |
| | |
| | | |
| | | this.loadAMapScripts(); |
| | | this.fetchDropdownData(); |
| | | // console.log('permission.tickets_processing_btn', this.permission.tickets_processing_btn); |
| | | // console.log('permission', this.permission.tickets_tab_pending); |
| | | |
| | | }, |
| | | |
| | | mounted() { |
| | |
| | | } |
| | | |
| | | let curQueryParams = {}; |
| | | |
| | | let isTabProcessed = false; |
| | | if (href.indexOf('?') != -1 && href.split('?').length > 0) { |
| | | curQueryParams = href |
| | | .split('?')[1] |
| | |
| | | return pre; |
| | | }, {}); |
| | | |
| | | const { orderNumber = undefined, day = undefined } = curQueryParams; |
| | | const { orderNumber = undefined, day = undefined, tab = undefined } = curQueryParams; |
| | | |
| | | // 日历传值 |
| | | if (day) { |
| | |
| | | find && (find.query = {}); |
| | | }); |
| | | } |
| | | if (tab) { |
| | | const isTabValid = this.filteredTabs.some(t => t.name === tab); |
| | | if (isTabValid) { |
| | | this.activeTab = tab; |
| | | this.handleTabChangeAfterJump(); |
| | | isTabProcessed = true; |
| | | const find = this.$store.state.tags.bsTagList.find(i => i.path === '/tickets/ticket'); |
| | | find && (find.query = {}); |
| | | } |
| | | } |
| | | } |
| | | |
| | | this.fetchTabCounts(); // 新增:初始化时获取 tab 数据 |
| | | this.fetchTableData(); |
| | | }, |
| | | computed: { |
| | | CircleClose() { |
| | | return CircleClose |
| | | }, |
| | | firstRowData() { |
| | | return this.tableData.length > 0 ? this.tableData[0] : null; |
| | | }, |
| | |
| | | // 修改这里:使用 types 数组查找对应的 label |
| | | value: |
| | | this.types.find(t => t.value === this.currentDetail.type)?.label || |
| | | this.currentDetail.type || |
| | | '/', |
| | | this.currentDetail.type |
| | | }, |
| | | { label: '关联任务', value: this.currentDetail.job_name || '/' }, |
| | | { label: '任务发起人', value: this.currentDetail.creator }, |
| | |
| | | label: '关联算法', |
| | | value: |
| | | this.algorithms.find(t => t.value === this.currentDetail.aiType)?.label || |
| | | this.currentDetail.aiType || |
| | | '/', |
| | | this.currentDetail.aiType |
| | | }, |
| | | { label: '发起单位', value: this.currentDetail.department }, |
| | | { label: '发起任务时间', value: this.currentDetail.startTime }, |
| | |
| | | }, |
| | | |
| | | handleSFNodeClick(data) { |
| | | console.log(data.dictKey, '666666666'); |
| | | this.filters.type = ''; |
| | | this.filters.algorithm = ''; |
| | | this.filters.type = data.dictKey; |
| | |
| | | |
| | | handleTabChange(tab) { |
| | | this.activeTab = tab.props?.name || tab.name; |
| | | |
| | | const isReview = this.findObject(this.option.column, 'isReview'); |
| | | // 根据条件切换显隐 |
| | | isReview.hide = !['all', 'completed', 'myTickets'].includes(this.activeTab); |
| | |
| | | this.fetchTableData(); |
| | | this.fetchTabCounts(); // 切换 tab 时重新获取数据 |
| | | }, |
| | | |
| | | //新增 跳转后触发的Tab切换 |
| | | handleTabChangeAfterJump() { |
| | | const isReview = this.findObject(this.option.column, 'isReview'); |
| | | isReview.hide = !['all', 'completed', 'myTickets'].includes(this.activeTab); |
| | | this.handleReset(); |
| | | this.page.currentPage = 1; |
| | | this.fetchTableData(); |
| | | this.fetchTabCounts(); |
| | | }, |
| | | handleSearch() { |
| | | this.page.currentPage = 1; |
| | | this.fetchTableData(); |
| | |
| | | <style lang="scss"> |
| | | .custom-dialog { |
| | | max-height: 96vh; |
| | | .el-dialog__body { |
| | | |
| | | border-top: 0.1rem solid #f0f0f0; |
| | | } |
| | | } |
| | | .custom-qrcode-popover { |
| | | min-width: 160px !important; |
| | |
| | | width: 100%; |
| | | } |
| | | } |
| | | |
| | | .dialog-footer { |
| | | text-align: center; |
| | | :deep(.el-dialog__body) { |
| | | border-top: 0.1rem solid #f0f0f0; |
| | | } |
| | | .dialog-footer-new { |
| | | text-align: right; |
| | | padding-top: 16px; |
| | | border-top: 1px solid #ebeef5; |
| | | |
| | |
| | | } |
| | | } |
| | | } |
| | | .dialog-footer1 { |
| | | .dialog-footer1-new { |
| | | position: sticky; |
| | | bottom: 28px; |
| | | left: 0; |
| | |
| | | :deep(.el-dialog__body) { |
| | | padding: 0; |
| | | background-color: #f5f7fa; |
| | | border-top: 0.1rem solid #f0f0f0; |
| | | } |
| | | } |
| | | |
| | |
| | | :deep(.el-dialog__body) { |
| | | padding: 0; |
| | | background-color: #f5f7fa; |
| | | border-top: 0.1rem solid #f0f0f0; |
| | | } |
| | | } |
| | | |
| | |
| | | </div> |
| | | |
| | | <div class="action-area"> |
| | | <!-- <img :src="st7" alt="" /> --> |
| | | <!-- <span class="todo-date">{{ item.date?.slice(0, 10).replace(/-/g, '.') }}</span> --> |
| | | <span class="todo-date">{{ item.name }}</span> |
| | | <!-- <span class="todo-date">{{ item.name }}</span> --> |
| | | <el-tooltip effect="dark" :content="item.name" placement="top"> |
| | | <span class="todo-date">{{item.name}}</span> |
| | | </el-tooltip> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | .action-area { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 42px; |
| | | margin-right: 22px; |
| | | |
| | | img { |
| | | width: 15px; |
| | |
| | | |
| | | .todo-date { |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #343434; |
| | | margin-left: 2px; |
| | | font-size: 14px; |
| | | color: #343434; |
| | | margin-left: 2px; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | max-width: 200px; |
| | | display: inline-block; |
| | | } |
| | | } |
| | | } |
| | |
| | | :key="index" |
| | | @click="timeClick(item, index)" |
| | | > |
| | | {{ timeListStr[index] }} |
| | | {{ timeListStr[index] }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="card-group"> |
| | | <div class="main-card"> |
| | | <div class="status-grid"> |
| | | <div class="status-item" v-for="(item, index) in eventTypeList" :key="index"> |
| | | <div class="status-item" v-for="(item, index) in eventTypeList" :key="index" @click="jumpEventDetails(item,index)"> |
| | | <div class="statusCon"> |
| | | <div class="status-label">{{ item.name }}</div> |
| | | <div class="status-value">{{ item.value }}<span>个</span></div> |
| | |
| | | import overviewImg3 from '@/assets/images/workbench/tc3.svg'; |
| | | import overviewImg4 from '@/assets/images/workbench/tc4.svg'; |
| | | import overviewImg5 from '@/assets/images/workbench/tc5.svg'; |
| | | import { useRouter } from 'vue-router' |
| | | const router = useRouter() |
| | | let checked = ref('CURRENT_YEAR'); |
| | | let timeListStr = ['本周', '本月', '本年']; |
| | | let timeListEnum = ['CURRENT_WEEK', 'CURRENT_MONTH', 'CURRENT_YEAR']; |
| | |
| | | }); |
| | | const dateSelect = ref('CURRENT_YEAR'); |
| | | const eventTypeList = ref([ |
| | | { name: '待审核', value: 0, img: overviewImg2, color: '#FF472F', status: '2', rate: 0 }, |
| | | { name: '待处理', value: 0, img: overviewImg3, color: '#FF7411', status: '0', rate: 0 }, |
| | | { name: '处理中', value: 0, img: overviewImg4, color: '#FFC300', status: '3', rate: 0 }, |
| | | { name: '已完成', value: 0, img: overviewImg5, color: '#0291A1', status: '4', rate: 0 }, |
| | | { name: '待审核', value: 0, img: overviewImg2, color: '#FF472F', status: '2', rate: 0 ,tagging:'pending' }, |
| | | { name: '待处理', value: 0, img: overviewImg3, color: '#FF7411', status: '0', rate: 0 ,tagging:'processing' }, |
| | | { name: '处理中', value: 0, img: overviewImg4, color: '#FFC300', status: '3', rate: 0 ,tagging:'inProgress'}, |
| | | { name: '已完成', value: 0, img: overviewImg5, color: '#0291A1', status: '4', rate: 0 ,tagging:'completed'}, |
| | | ]); |
| | | // 工单统计 |
| | | const getTypeData = () => { |
| | |
| | | dateSelect.value = item; |
| | | getTypeData(); |
| | | }; |
| | | // 跳转事件工单 |
| | | const jumpEventDetails = (item,index)=>{ |
| | | // console.log('tiaozhuan',item); |
| | | router.replace({ |
| | | path: `/tickets/ticket`, |
| | | query: { tab: item.tagging } |
| | | }); |
| | | } |
| | | // 图表 |
| | | const echartsRef = ref(null); |
| | | let { chart } = useEchartsResize(echartsRef); |
| | |
| | | width: 144px; |
| | | background: #f6f8fe; |
| | | border-radius: 8px 8px 8px 8px; |
| | | |
| | | cursor: pointer; |
| | | img { |
| | | width: 26px; |
| | | height: 26px; |