Browse Source

一些调整

main
betaqi 4 weeks ago
parent
commit
8233284fa5
  1. 2
      .env
  2. 2
      global.types/components.d.ts
  3. 13
      src/api/module/device/category.ts
  4. 17
      src/api/module/engineering/index.ts
  5. 52
      src/views/engineering/config/components/StepDeviceCategory.vue
  6. 94
      src/views/engineering/index.vue

2
.env

@ -1,4 +1,4 @@
VITE_BASE_API = '/remoteServer/admin-api/' VITE_BASE_API = '/remoteServer/admin-api/'
VITE_BASE_API_SYSTEM = '/remoteServer/admin-api/system/' VITE_BASE_API_SYSTEM = '/remoteServer/admin-api/system/'
VITE_SHOW_ONLINE_DEVICE = true VITE_SHOW_ONLINE_DEVICE = true
VITE_BASE_URL = 'http://43.140.245.32:48089' VITE_BASE_URL = 'http://192.168.1.63:48089'

2
global.types/components.d.ts vendored

@ -18,6 +18,8 @@ declare module 'vue' {
EdfsWrap: typeof import('./../src/components/Edfs-wrap.vue')['default'] EdfsWrap: typeof import('./../src/components/Edfs-wrap.vue')['default']
ElAside: typeof import('element-plus/es')['ElAside'] ElAside: typeof import('element-plus/es')['ElAside']
ElButton: typeof import('element-plus/es')['ElButton'] ElButton: typeof import('element-plus/es')['ElButton']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElContainer: typeof import('element-plus/es')['ElContainer'] ElContainer: typeof import('element-plus/es')['ElContainer']
ElDialog: typeof import('element-plus/es')['ElDialog'] ElDialog: typeof import('element-plus/es')['ElDialog']

13
src/api/module/device/category.ts

@ -17,7 +17,7 @@ export const createDeviceType = (params: IDeviceCategoryOV & IDeviceBase) => {
}) })
} }
export const uploadDeviceTypeFile = (params: { file: File, projectName: string, fileName: string }, abort: AbortController) => { export const uploadDeviceTypeFile = (params: { file: File, projectName: string, fileName: string, pointName: string }, abort: AbortController) => {
return globalServer({ return globalServer({
url: '/project/point/import-file', url: '/project/point/import-file',
method: 'post', method: 'post',
@ -27,3 +27,14 @@ export const uploadDeviceTypeFile = (params: { file: File, projectName: string,
timeout: 0, timeout: 0,
}) })
} }
export const downloadDeviceTypeFile = (params: { projectName: string, pointName: string }) => {
return globalServer({
url: '/project/point/download-excel',
method: 'get',
params,
responseType: 'blob',
})
}

17
src/api/module/engineering/index.ts

@ -19,3 +19,20 @@ export const getEngineeringList = (
params, params,
}) })
} }
export const deleteEngineering = (params: { name: string }) => {
return globalServer({
url: 'project/delete',
method: 'delete',
params,
})
}
export const deleteEngineeringBatch = (names: string[]) => {
return globalServer({
url: 'project/delete-list',
method: 'delete',
params: names.join(','),
})
}

52
src/views/engineering/config/components/StepDeviceCategory.vue

@ -65,17 +65,24 @@
<div class="space-y-2 mb-3"> <div class="space-y-2 mb-3">
<div class="text-sm"> <div class="text-sm">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<span class="text-gray-500 whitespace-nowrap">点表文件</span> <span class="text-gray-500 whitespace-nowrap">点表文件</span>
<el-tooltip <el-tooltip
effect="dark" effect="dark"
:content="fileName" :content="fileName"
placement="top" placement="top"
:disabled="!fileName" :disabled="!fileName"
> >
<span class="text-gray-900 font-medium truncate max-w-[200px]"> <span class="text-gray-900 font-medium truncate max-w-[170px]">
{{ fileName || '-' }} {{ fileName || '-' }}
</span> </span>
</el-tooltip> </el-tooltip>
<div
class="ml-2"
v-if="!!status"
@click.stop="handleDownload(categoryName as string)"
>
<el-button type="primary" :icon="Download" link>下载</el-button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -101,7 +108,7 @@
:show-file-list="false" :show-file-list="false"
:disabled="uploadingStates[fileName]" :disabled="uploadingStates[fileName]"
:on-change=" :on-change="
(file: any) => handleFileChange(file, fileName as string) (file: any) => handleFileChange(file, fileName as string, categoryName)
" "
> >
<el-icon class="el-icon--upload !text-3xl !mb-2 !text-gray-400" <el-icon class="el-icon--upload !text-3xl !mb-2 !text-gray-400"
@ -173,11 +180,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, computed, watch } from 'vue' import { ref, reactive, computed, watch } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { UploadFilled, Plus } from '@element-plus/icons-vue' import { UploadFilled, Plus, Download } from '@element-plus/icons-vue'
import type { IDeviceCategoryList, IDeviceCategoryOV } from '@/api/module/device/index.d' import type { IDeviceCategoryList, IDeviceCategoryOV } from '@/api/module/device/index.d'
import type { FormInstance, FormRules, UploadFile } from 'element-plus' import type { FormInstance, FormRules, UploadFile } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { createDeviceType, uploadDeviceTypeFile } from '@/api/module/device/category' import {
createDeviceType,
uploadDeviceTypeFile,
downloadDeviceTypeFile,
} from '@/api/module/device/category'
import { ChannelEnum } from '@/api/module/channel/index' import { ChannelEnum } from '@/api/module/channel/index'
import type { IChannelOV } from '@/api/module/channel/index.d' import type { IChannelOV } from '@/api/module/channel/index.d'
import { validateName } from '@/utils/validate' import { validateName } from '@/utils/validate'
@ -278,7 +289,11 @@ const setUploadRef = (el: any, key: string) => {
} }
} }
const handleFileChange = async (file: UploadFile, fileName: string) => { const handleFileChange = async (
file: UploadFile,
fileName: string,
categoryName: string,
) => {
if (!file.raw) return if (!file.raw) return
const controller = new AbortController() const controller = new AbortController()
uploadControllers[fileName] = controller uploadControllers[fileName] = controller
@ -290,6 +305,7 @@ const handleFileChange = async (file: UploadFile, fileName: string) => {
file: file.raw, file: file.raw,
projectName: projectName.value, projectName: projectName.value,
fileName: fileName, fileName: fileName,
pointName: categoryName,
}, },
controller, controller,
) )
@ -331,6 +347,30 @@ const cancelAllUploads = () => {
}) })
} }
async function handleDownload(pointName: string) {
try {
const res = await fetch(
`/remoteServer/admin-api/project/point/download-excel?projectName=${projectName.value}&pointName=${pointName}`,
)
debugger
//
if (!res.ok) {
throw new Error('Network response was not ok')
}
const blob = await res.blob()
const link = document.createElement('a')
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
link.download = `${pointName}.xlsx`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
URL.revokeObjectURL(link.href)
} catch (error) {
ElMessage.error('下载出现错误')
}
}
// Check before leaving step // Check before leaving step
const checkBeforeLeave = async (): Promise<boolean> => { const checkBeforeLeave = async (): Promise<boolean> => {
if (!hasUploadingFiles()) { if (!hasUploadingFiles()) {

94
src/views/engineering/index.vue

@ -1,7 +1,22 @@
<template> <template>
<EdfsWrap class="wh-full" :title="'工程列表'" :use-scroll-bar="false"> <EdfsWrap class="wh-full" :title="'工程列表'" :use-scroll-bar="false">
<template #title-right>
<div v-if="!isBatchMode">
<el-button type="danger" plain @click="enterBatchMode"> 批量删除 </el-button>
</div>
<div v-else>
<el-button
type="danger"
:disabled="selectedItems.length === 0"
@click="handleBatchDelete"
>
确认删除
</el-button>
<el-button @click="exitBatchMode">取消</el-button>
</div>
</template>
<div class="engineering-list-container"> <div class="engineering-list-container">
<div class="engineering-grid"> <el-checkbox-group v-model="selectedItems" class="engineering-grid">
<div class="engineering-card add-card" @click="addEngineering"> <div class="engineering-card add-card" @click="addEngineering">
<div class="add-card-content"> <div class="add-card-content">
<el-icon :size="48" class="add-icon"> <el-icon :size="48" class="add-icon">
@ -13,7 +28,25 @@
<div v-for="item in list" :key="item.name" class="engineering-card"> <div v-for="item in list" :key="item.name" class="engineering-card">
<div class="card-header"> <div class="card-header">
<span class="card-title">工程名称{{ item.name }}</span> <div class="flex items-center gap-2 flex-1 overflow-hidden">
<el-checkbox v-if="isBatchMode" :value="item.name" @click.stop>
<span class="card-title" :title="item.name"
>工程名称{{ item.name }}</span
>
</el-checkbox>
<div v-else class="h-32 leading-32px">
<span class="card-title" :title="item.name"
>工程名称{{ item.name }}</span
>
</div>
</div>
<el-button
link
type="danger"
v-if="!isBatchMode"
:icon="Delete"
@click="handleDelete(item)"
/>
</div> </div>
<div class="card-body"> <div class="card-body">
<p class="card-desc">工程描述{{ item.description }}</p> <p class="card-desc">工程描述{{ item.description }}</p>
@ -27,7 +60,7 @@
> >
</div> </div>
</div> </div>
</div> </el-checkbox-group>
<p v-if="loading" class="loading-text">加载中...</p> <p v-if="loading" class="loading-text">加载中...</p>
<el-empty v-if="!loading && list.length === 0" description="暂无数据" /> <el-empty v-if="!loading && list.length === 0" description="暂无数据" />
</div> </div>
@ -41,17 +74,21 @@
<script setup lang="ts"> <script setup lang="ts">
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import EdfsWrap from '@/components/Edfs-wrap.vue' import EdfsWrap from '@/components/Edfs-wrap.vue'
import type { IEngineeringOV } from '@/api/module/engineering/index.d' import type { IEngineeringOV } from '@/api/module/engineering/index.d'
import CreateEngineeringDlg from './components/create-engineering-dlg.vue' import CreateEngineeringDlg from './components/create-engineering-dlg.vue'
import { Plus } from '@element-plus/icons-vue' import { Plus, Delete } from '@element-plus/icons-vue'
import { useEngineeringStore } from '@/stores/engineering' import { useEngineeringStore } from '@/stores/engineering'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { deleteEngineering, deleteEngineeringBatch } from '@/api/module/engineering'
const router = useRouter() const router = useRouter()
const engineeringStore = useEngineeringStore() const engineeringStore = useEngineeringStore()
const selectedItems = ref<string[]>([])
const isBatchMode = ref(false)
const createEngineeringDlgRef = ref<typeof CreateEngineeringDlg | null>(null) const createEngineeringDlgRef = ref<typeof CreateEngineeringDlg | null>(null)
const { engineeringList: list, loading } = storeToRefs(engineeringStore) const { engineeringList: list, loading } = storeToRefs(engineeringStore)
@ -123,6 +160,53 @@ async function handleDownload(item: IEngineeringOV) {
console.error('Download failed:', error) console.error('Download failed:', error)
} }
} }
function handleDelete(item: IEngineeringOV) {
ElMessageBox.confirm('确认删除该工程吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(async () => {
const res = await deleteEngineering({ name: item.name })
if (res.code === 0) {
ElMessage.success('删除成功')
engineeringStore.fetchEngineeringList()
}
})
.catch(() => {})
}
function handleBatchDelete() {
ElMessageBox.confirm(
`确认删除选中的 ${selectedItems.value.length} 个工程吗?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
},
)
.then(async () => {
const res = await deleteEngineeringBatch(selectedItems.value)
if (res.code === 0) {
ElMessage.success('删除成功')
selectedItems.value = []
isBatchMode.value = false
engineeringStore.fetchEngineeringList()
}
})
.catch(() => {})
}
function enterBatchMode() {
isBatchMode.value = true
}
function exitBatchMode() {
isBatchMode.value = false
selectedItems.value = []
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

Loading…
Cancel
Save