Browse Source

feat: 功能调整

main
betaqi 1 month ago
parent
commit
dd50808440
  1. 7
      src/api/server/axiosInstance.ts
  2. 1
      src/views/engineering/components/channel-dlg.vue
  3. 16
      src/views/engineering/config/components/StepChannel.vue
  4. 16
      src/views/engineering/config/components/StepDevice.vue
  5. 72
      src/views/engineering/config/components/StepDeviceCategory.vue
  6. 44
      src/views/engineering/config/index.vue

7
src/api/server/axiosInstance.ts

@ -168,7 +168,11 @@ const createAxiosInstance = (module: APIConfigKeys, config: Config) => {
}, },
(error: any): Promise<any> => { (error: any): Promise<any> => {
if (isCancel(error)) { if (isCancel(error)) {
return Promise.resolve() return Promise.reject({
name: 'CanceledError',
message: 'canceled',
code: 10001
})
} }
const message = '请求错误' const message = '请求错误'
if (error.code === 'ECONNABORTED') { if (error.code === 'ECONNABORTED') {
@ -211,7 +215,6 @@ const createAxiosInstance = (module: APIConfigKeys, config: Config) => {
const result = (await service(config)) as Result<T> const result = (await service(config)) as Result<T>
return result return result
} catch (err: any) { } catch (err: any) {
console.log(err)
const result: Result<T> = { const result: Result<T> = {
code: err?.code || -1, code: err?.code || -1,
msg: err.msg || err.message, msg: err.msg || err.message,

1
src/views/engineering/components/channel-dlg.vue

@ -131,7 +131,6 @@ function open(item?: ICustomFormData) {
async function onSave() { async function onSave() {
if (verifyData()) return if (verifyData()) return
emit('on-save', form.value) emit('on-save', form.value)
message.success('保存成功')
close() close()
} }

16
src/views/engineering/config/components/StepChannel.vue

@ -17,7 +17,6 @@
> >
<el-scrollbar> <el-scrollbar>
<div class="grid grid-cols-[repeat(auto-fill,minmax(300px,1fr))] gap-4 p-4"> <div class="grid grid-cols-[repeat(auto-fill,minmax(300px,1fr))] gap-4 p-4">
<!-- Add Channel Card -->
<div <div
class="bg-white rounded-xl shadow-sm p-12 border-2 border-dashed border-gray-200 hover:border-blue-400 transition-all duration-300 cursor-pointer flex items-center justify-center min-h-[200px]" class="bg-white rounded-xl shadow-sm p-12 border-2 border-dashed border-gray-200 hover:border-blue-400 transition-all duration-300 cursor-pointer flex items-center justify-center min-h-[200px]"
@click="handleAdd" @click="handleAdd"
@ -88,7 +87,20 @@
</el-scrollbar> </el-scrollbar>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<el-empty v-else description="暂无通道,请点击上方按钮添加" /> <div v-else>
<div
class="bg-white rounded-xl w-340 shadow-sm p-12 border-2 border-dashed border-gray-200 hover:border-blue-400 transition-all duration-300 cursor-pointer flex items-center justify-center min-h-[200px]"
@click="handleAdd"
>
<div class="flex flex-col items-center gap-3">
<el-icon :size="48" class="text-gray-400">
<Plus />
</el-icon>
<span class="text-base font-medium text-gray-600">新增通道</span>
</div>
</div>
<el-empty description="暂无通道数据" />
</div>
</div> </div>
<ChannelDlg <ChannelDlg

16
src/views/engineering/config/components/StepDevice.vue

@ -17,7 +17,6 @@
> >
<el-scrollbar> <el-scrollbar>
<div class="grid grid-cols-[repeat(auto-fill,minmax(300px,1fr))] gap-4 p-4"> <div class="grid grid-cols-[repeat(auto-fill,minmax(300px,1fr))] gap-4 p-4">
<!-- Add Device Card -->
<div <div
class="bg-white rounded-xl shadow-sm p-12 border-2 border-dashed border-gray-200 hover:border-blue-400 transition-all duration-300 cursor-pointer flex items-center justify-center min-h-[200px]" class="bg-white rounded-xl shadow-sm p-12 border-2 border-dashed border-gray-200 hover:border-blue-400 transition-all duration-300 cursor-pointer flex items-center justify-center min-h-[200px]"
@click="handleAdd" @click="handleAdd"
@ -87,7 +86,20 @@
</el-scrollbar> </el-scrollbar>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<el-empty v-else description="暂无设备,请点击上方按钮添加" /> <div v-else>
<div
class="bg-white rounded-xl w-340 shadow-sm p-12 border-2 border-dashed border-gray-200 hover:border-blue-400 transition-all duration-300 cursor-pointer flex items-center justify-center min-h-[200px]"
@click="handleAdd"
>
<div class="flex flex-col items-center gap-3">
<el-icon :size="48" class="text-gray-400">
<Plus />
</el-icon>
<span class="text-base font-medium text-gray-600">新增设备</span>
</div>
</div>
<el-empty description="暂无设备数据" />
</div>
</div> </div>
<DeviceDlg <DeviceDlg

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

@ -120,13 +120,22 @@
</el-scrollbar> </el-scrollbar>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<el-empty <div v-if="Object.keys(modelValue).length === 0">
v-if="Object.keys(modelValue).length === 0" <div
description="暂无设备类别,请点击上方按钮添加" class="bg-white rounded-xl w-340 shadow-sm p-12 border-2 border-dashed border-gray-200 hover:border-blue-400 transition-all duration-300 cursor-pointer flex items-center justify-center min-h-[200px]"
/> @click="handleAdd"
>
<div class="flex flex-col items-center gap-3">
<el-icon :size="48" class="text-gray-400">
<Plus />
</el-icon>
<span class="text-base font-medium text-gray-600">新增设备类别</span>
</div>
</div>
<el-empty description="暂无设备类别,请点击上方按钮添加" />
</div>
</div> </div>
<!-- Create/Edit Category Dialog -->
<el-dialog <el-dialog
v-model="dialogVisible" v-model="dialogVisible"
:title="'新增设备类别'" :title="'新增设备类别'"
@ -167,7 +176,7 @@ import { useRoute } from 'vue-router'
import { UploadFilled, Plus } from '@element-plus/icons-vue' import { UploadFilled, Plus } 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 } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { createDeviceType, uploadDeviceTypeFile } from '@/api/module/device/category' import { createDeviceType, uploadDeviceTypeFile } 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'
@ -271,7 +280,6 @@ const setUploadRef = (el: any, key: string) => {
const handleFileChange = async (file: UploadFile, fileName: string) => { const handleFileChange = async (file: UploadFile, fileName: string) => {
if (!file.raw) return if (!file.raw) return
const controller = new AbortController() const controller = new AbortController()
uploadControllers[fileName] = controller uploadControllers[fileName] = controller
uploadingStates[fileName] = true uploadingStates[fileName] = true
@ -285,17 +293,15 @@ const handleFileChange = async (file: UploadFile, fileName: string) => {
}, },
controller, controller,
) )
if (res) {
if (res.code === 0) { if (res.code === 0) {
ElMessage.success('上传成功') ElMessage.success('上传成功')
emit('on-load-device-categoty') emit('on-load-device-categoty')
} else if (res.code === 10001) {
ElMessage.success('取消成功')
} else { } else {
ElMessage.error(res.msg || '上传失败') ElMessage.error(res.msg || '上传失败')
} }
} catch (error: any) {
if (error.name === 'CanceledError' || error.message === 'canceled') {
ElMessage.info('上传已取消')
} else {
ElMessage.error('上传失败')
} }
} finally { } finally {
delete uploadControllers[fileName] delete uploadControllers[fileName]
@ -312,6 +318,48 @@ const handleCancelUpload = (fileName: string) => {
uploadingStates[fileName] = false uploadingStates[fileName] = false
} }
} }
// Check if there are any uploading files
const hasUploadingFiles = () => {
return Object.values(uploadingStates).some(state => state === true)
}
// Cancel all uploads
const cancelAllUploads = () => {
Object.keys(uploadControllers).forEach(fileName => {
handleCancelUpload(fileName)
})
}
// Check before leaving step
const checkBeforeLeave = async (): Promise<boolean> => {
if (!hasUploadingFiles()) {
return true
}
return new Promise(resolve => {
ElMessageBox.confirm(
'当前有文件正在上传,离开将取消所有上传任务,是否确定离开?',
'提示',
{
confirmButtonText: '确定离开',
cancelButtonText: '取消',
type: 'warning',
},
)
.then(() => {
cancelAllUploads()
resolve(true)
})
.catch(() => {
resolve(false)
})
})
}
defineExpose({
checkBeforeLeave,
})
</script> </script>
<style scoped> <style scoped>

44
src/views/engineering/config/index.vue

@ -22,19 +22,19 @@
<el-step <el-step
title="1.通道管理" title="1.通道管理"
:icon="Connection" :icon="Connection"
@click="currentStep = 'channel'" @click="handleStepClick('channel')"
class="cursor-pointer" class="cursor-pointer"
/> />
<el-step <el-step
title="2.设备类别" title="2.设备类别"
:icon="Collection" :icon="Collection"
@click="currentStep = 'category'" @click="handleStepClick('category')"
class="cursor-pointer" class="cursor-pointer"
/> />
<el-step <el-step
title="3.设备管理" title="3.设备管理"
:icon="Monitor" :icon="Monitor"
@click="currentStep = 'device'" @click="handleStepClick('device')"
class="cursor-pointer" class="cursor-pointer"
/> />
</el-steps> </el-steps>
@ -64,6 +64,7 @@
<keep-alive> <keep-alive>
<component <component
:is="currentStepComponent" :is="currentStepComponent"
ref="currentComponentRef"
v-model="currentModel as any" v-model="currentModel as any"
v-bind="currentProps" v-bind="currentProps"
@on-load-device-categoty="loadCategoryList" @on-load-device-categoty="loadCategoryList"
@ -111,6 +112,7 @@ const activeStep = computed(() => steps.indexOf(currentStep.value))
const channels = ref<IChannelOV>({}) const channels = ref<IChannelOV>({})
const categories = ref<IDeviceCategoryList>({}) const categories = ref<IDeviceCategoryList>({})
const devices = ref<IDeviceOV>({}) const devices = ref<IDeviceOV>({})
const currentComponentRef = ref<any>(null)
const loading = ref(false) const loading = ref(false)
const currentStepComponent = computed(() => { const currentStepComponent = computed(() => {
@ -168,6 +170,17 @@ const currentProps = computed(() => {
return {} return {}
}) })
const handleStepClick = async (step: Step) => {
if (currentStep.value === step) return
if (currentComponentRef.value?.checkBeforeLeave) {
const canLeave = await currentComponentRef.value.checkBeforeLeave()
if (!canLeave) return
}
currentStep.value = step
}
const goBack = () => { const goBack = () => {
router.push('/engineering') router.push('/engineering')
} }
@ -177,6 +190,10 @@ const prevStep = async () => {
if (currentStep.value === 'channel') { if (currentStep.value === 'channel') {
await loadChannelList() await loadChannelList()
} }
if (currentComponentRef.value?.checkBeforeLeave) {
const canLeave = await currentComponentRef.value.checkBeforeLeave()
if (!canLeave) return
}
if (index > 0) { if (index > 0) {
currentStep.value = steps[index - 1] currentStep.value = steps[index - 1]
} }
@ -188,11 +205,32 @@ const nextStep = async () => {
await saveChannelList() await saveChannelList()
} }
if (currentComponentRef.value?.checkBeforeLeave) {
const canLeave = await currentComponentRef.value.checkBeforeLeave()
if (!canLeave) return
}
if (index < steps.length - 1) { if (index < steps.length - 1) {
currentStep.value = steps[index + 1] currentStep.value = steps[index + 1]
} }
} }
/*
const nextStep = async () => {
if (currentComponentRef.value?.checkBeforeLeave) {
const canLeave = await currentComponentRef.value.checkBeforeLeave()
if (!canLeave) return
}
if (currentStep.value === 'channel') {
currentStep.value = 'category'
} else if (currentStep.value === 'category') {
currentStep.value = 'device'
}
}
*/
const handleFinish = async () => { const handleFinish = async () => {
loading.value = true loading.value = true
try { try {

Loading…
Cancel
Save