|
@@ -1,90 +1,78 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <ContentWrap v-loading="formLoading">
|
|
|
|
|
- <ContentWrap>
|
|
|
|
|
- <el-form
|
|
|
|
|
- ref="formRef"
|
|
|
|
|
- :model="formData"
|
|
|
|
|
- :rules="formRules"
|
|
|
|
|
- style="margin-right: 4em; margin-left: 0.5em; margin-top: 1em"
|
|
|
|
|
- label-width="130px"
|
|
|
|
|
- >
|
|
|
|
|
- <div class="base-expandable-content">
|
|
|
|
|
- <el-row>
|
|
|
|
|
- <el-col :span="8">
|
|
|
|
|
- <el-form-item :label="t('route.RouteName')" prop="routeName">
|
|
|
|
|
- <el-input v-model="formData.routeName" :placeholder="t('route.RouteName')" />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <el-col :span="8">
|
|
|
|
|
- <el-form-item :label="t('monitor.category')" prop="deviceClassify">
|
|
|
|
|
- <el-tree-select
|
|
|
|
|
- filterable
|
|
|
|
|
- clearable
|
|
|
|
|
- v-model="formData.deviceClassify"
|
|
|
|
|
- :data="productClassifyList"
|
|
|
|
|
- :props="defaultProps"
|
|
|
|
|
- check-strictly
|
|
|
|
|
- node-key="id"
|
|
|
|
|
- :placeholder="t('deviceForm.categoryHolder')"
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <el-col :span="8">
|
|
|
|
|
- <el-form-item :label="t('iotDevice.brand')" prop="brandName">
|
|
|
|
|
- <el-select
|
|
|
|
|
- clearable
|
|
|
|
|
- v-model="formData.brandName"
|
|
|
|
|
- @clear="brandClear"
|
|
|
|
|
- :placeholder="t('iotDevice.brandHolder')"
|
|
|
|
|
- @click="openBrand"
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <el-col :span="8">
|
|
|
|
|
- <el-form-item :label="t('faultForm.device')" prop="deviceName">
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-model="formData.deviceName"
|
|
|
|
|
- @clear="handleClear"
|
|
|
|
|
- :placeholder="t('iotMaintain.deviceHolder')"
|
|
|
|
|
- @click="openDevice"
|
|
|
|
|
- clearable
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <el-col :span="16">
|
|
|
|
|
- <el-form-item :label="t('inspect.routeDesc')" prop="routeDesc">
|
|
|
|
|
- <el-input
|
|
|
|
|
- type="textarea"
|
|
|
|
|
- v-model="formData.routeDesc"
|
|
|
|
|
- :placeholder="t('inspect.routeDescHolder')"
|
|
|
|
|
- clearable
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
|
|
+ <div class="route-form-page" v-loading="formLoading">
|
|
|
|
|
+ <header class="page-header">
|
|
|
|
|
+ <div class="page-header__main">
|
|
|
|
|
+ <div class="page-header__icon"><Icon icon="ep:guide" /></div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <h1>{{ pageTitle }}</h1>
|
|
|
|
|
+ <p>配置巡检设备、路线说明及巡检项执行顺序</p>
|
|
|
</div>
|
|
</div>
|
|
|
- </el-form>
|
|
|
|
|
- </ContentWrap>
|
|
|
|
|
- <ContentWrap>
|
|
|
|
|
- <!-- 列表 -->
|
|
|
|
|
- <ContentWrap>
|
|
|
|
|
- <ContentWrap>
|
|
|
|
|
- <el-form
|
|
|
|
|
- class="-mb-15px"
|
|
|
|
|
- :model="queryParams"
|
|
|
|
|
- ref="queryFormRef"
|
|
|
|
|
- :inline="true"
|
|
|
|
|
- label-width="68px"
|
|
|
|
|
- >
|
|
|
|
|
- <el-form-item>
|
|
|
|
|
- <el-button @click="openForm" type="primary"
|
|
|
|
|
- ><Icon icon="ep:plus" class="mr-5px" />
|
|
|
|
|
- {{ t('route.selectInspectionItems') }}</el-button
|
|
|
|
|
- >
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-form>
|
|
|
|
|
- </ContentWrap>
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-button @click="close"> <Icon icon="ep:arrow-left" class="mr-5px" />返回 </el-button>
|
|
|
|
|
+ </header>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form
|
|
|
|
|
+ ref="formRef"
|
|
|
|
|
+ :model="formData"
|
|
|
|
|
+ :rules="formRules"
|
|
|
|
|
+ size="default"
|
|
|
|
|
+ label-width="100px"
|
|
|
|
|
+ class="route-form">
|
|
|
|
|
+ <section class="form-section">
|
|
|
|
|
+ <header class="section-heading"><span></span>路线信息</header>
|
|
|
|
|
+ <div class="form-grid">
|
|
|
|
|
+ <el-form-item :label="t('route.RouteName')" prop="routeName">
|
|
|
|
|
+ <el-input v-model="formData.routeName" :placeholder="t('route.RouteName')" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="t('monitor.category')" prop="deviceClassify">
|
|
|
|
|
+ <el-tree-select
|
|
|
|
|
+ v-model="formData.deviceClassify"
|
|
|
|
|
+ :data="productClassifyList"
|
|
|
|
|
+ :props="defaultProps"
|
|
|
|
|
+ check-strictly
|
|
|
|
|
+ node-key="id"
|
|
|
|
|
+ :placeholder="t('deviceForm.categoryHolder')"
|
|
|
|
|
+ filterable
|
|
|
|
|
+ clearable />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="t('iotDevice.brand')" prop="brandName">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="formData.brandName"
|
|
|
|
|
+ :placeholder="t('iotDevice.brandHolder')"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @clear="brandClear"
|
|
|
|
|
+ @click="openBrand" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="t('faultForm.device')" prop="deviceName">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.deviceName"
|
|
|
|
|
+ :placeholder="t('iotMaintain.deviceHolder')"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @clear="handleClear"
|
|
|
|
|
+ @click="openDevice" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="t('inspect.routeDesc')" prop="routeDesc" class="form-grid__wide">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.routeDesc"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="3"
|
|
|
|
|
+ :placeholder="t('inspect.routeDescHolder')"
|
|
|
|
|
+ clearable />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+
|
|
|
|
|
+ <section class="form-section inspection-section">
|
|
|
|
|
+ <header class="section-heading section-heading--actions">
|
|
|
|
|
+ <div class="section-heading__title"><span></span>巡检项顺序</div>
|
|
|
|
|
+ <el-button type="primary" @click="openForm">
|
|
|
|
|
+ <Icon icon="ep:plus" class="mr-5px" />{{ t('route.selectInspectionItems') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </header>
|
|
|
|
|
+
|
|
|
|
|
+ <el-empty v-if="items.length === 0" description="暂未选择巡检项" :image-size="72" />
|
|
|
<draggable
|
|
<draggable
|
|
|
|
|
+ v-else
|
|
|
v-model="items"
|
|
v-model="items"
|
|
|
item-key="id"
|
|
item-key="id"
|
|
|
tag="div"
|
|
tag="div"
|
|
@@ -92,47 +80,41 @@
|
|
|
handle=".sortable-item"
|
|
handle=".sortable-item"
|
|
|
:animation="150"
|
|
:animation="150"
|
|
|
@start="dragStart"
|
|
@start="dragStart"
|
|
|
- @end="dragEnd"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ @end="dragEnd">
|
|
|
<template #item="{ element, index }">
|
|
<template #item="{ element, index }">
|
|
|
<div class="sortable-item">
|
|
<div class="sortable-item">
|
|
|
- <!-- 序号显示 -->
|
|
|
|
|
<div class="order-number">{{ index + 1 }}</div>
|
|
<div class="order-number">{{ index + 1 }}</div>
|
|
|
-
|
|
|
|
|
- <!-- 拖动手柄 -->
|
|
|
|
|
- <span class="drag-handle">≡</span>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 组件内容 -->
|
|
|
|
|
|
|
+ <span class="drag-handle"><Icon icon="ep:rank" /></span>
|
|
|
<div class="component-content">
|
|
<div class="component-content">
|
|
|
- <span style="font-weight: bold">{{ t('inspect.InspectionItems') }}:</span
|
|
|
|
|
- ><span style="font-size: 14px">{{ element.item }}</span
|
|
|
|
|
- >
|
|
|
|
|
- <span style="font-weight: bold">{{ t('inspect.InspectionStandards') }}:</span
|
|
|
|
|
- ><span style="font-size: 14px">{{ element.standard }}</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div>
|
|
|
|
|
- <el-button type="warning" @click="deleteDraggable(index)">{{ t('form.delete') }}</el-button>
|
|
|
|
|
|
|
+ <div class="item-field">
|
|
|
|
|
+ <span class="item-field__label">{{ t('inspect.InspectionItems') }}</span>
|
|
|
|
|
+ <span class="item-field__value">{{ element.item || '-' }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="item-field item-field--standard">
|
|
|
|
|
+ <span class="item-field__label">{{ t('inspect.InspectionStandards') }}</span>
|
|
|
|
|
+ <span class="item-field__value">{{ element.standard || '-' }}</span>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <el-button link type="danger" @click="deleteDraggable(index)">
|
|
|
|
|
+ <Icon icon="ep:delete" class="mr-5px" />{{ t('form.delete') }}
|
|
|
|
|
+ </el-button>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
</draggable>
|
|
</draggable>
|
|
|
- </ContentWrap>
|
|
|
|
|
- </ContentWrap>
|
|
|
|
|
- <ContentWrap>
|
|
|
|
|
- <el-form>
|
|
|
|
|
- <el-form-item style="float: right">
|
|
|
|
|
- <el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('iotMaintain.save') }}</el-button>
|
|
|
|
|
- <el-button @click="close">{{ t('iotMaintain.cancel') }}</el-button>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-form>
|
|
|
|
|
- </ContentWrap>
|
|
|
|
|
- <InspectItemList
|
|
|
|
|
- ref="inspectItemFormRef"
|
|
|
|
|
- @choose="inspectItemChoose"
|
|
|
|
|
- />
|
|
|
|
|
|
|
+ </section>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+
|
|
|
|
|
+ <footer class="action-bar">
|
|
|
|
|
+ <el-button size="default" @click="close">{{ t('iotMaintain.cancel') }}</el-button>
|
|
|
|
|
+ <el-button size="default" type="primary" :loading="formLoading" @click="submitForm">
|
|
|
|
|
+ <Icon icon="ep:check" class="mr-5px" />{{ t('iotMaintain.save') }}
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </footer>
|
|
|
|
|
+
|
|
|
|
|
+ <InspectItemList ref="inspectItemFormRef" @choose="inspectItemChoose" />
|
|
|
<DeviceList ref="deviceFormRef" @choose="deviceChoose" />
|
|
<DeviceList ref="deviceFormRef" @choose="deviceChoose" />
|
|
|
<BrandList ref="brandFormRef" @choose="brandChoose" />
|
|
<BrandList ref="brandFormRef" @choose="brandChoose" />
|
|
|
- </ContentWrap>
|
|
|
|
|
|
|
+ </div>
|
|
|
</template>
|
|
</template>
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import * as UserApi from '@/api/system/user'
|
|
import * as UserApi from '@/api/system/user'
|
|
@@ -146,7 +128,7 @@ import draggable from 'vuedraggable'
|
|
|
import InspectItemList from '@/views/pms/inspect/route/InspectItemList.vue'
|
|
import InspectItemList from '@/views/pms/inspect/route/InspectItemList.vue'
|
|
|
import DeviceList from '@/views/pms/failure/DeviceList.vue'
|
|
import DeviceList from '@/views/pms/failure/DeviceList.vue'
|
|
|
import { IotInspectRouteApi, IotInspectRouteVO } from '@/api/pms/inspect/route'
|
|
import { IotInspectRouteApi, IotInspectRouteVO } from '@/api/pms/inspect/route'
|
|
|
-import BrandList from "@/views/pms/device/BrandList.vue";
|
|
|
|
|
|
|
+import BrandList from '@/views/pms/device/BrandList.vue'
|
|
|
|
|
|
|
|
/** 维修工单 表单 */
|
|
/** 维修工单 表单 */
|
|
|
defineOptions({ name: 'RouteAdd' })
|
|
defineOptions({ name: 'RouteAdd' })
|
|
@@ -159,6 +141,7 @@ const deptUsers = ref<UserApi.UserVO[]>([]) // 用户列表
|
|
|
const dialogTitle = ref('') // 弹窗的标题
|
|
const dialogTitle = ref('') // 弹窗的标题
|
|
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
|
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
|
|
|
|
+const pageTitle = computed(() => (formType.value === 'update' ? '编辑巡检路线' : '新增巡检路线'))
|
|
|
const deviceLabel = ref('') // 表单的类型:create - 新增;update - 修改
|
|
const deviceLabel = ref('') // 表单的类型:create - 新增;update - 修改
|
|
|
const drawerVisible = ref<boolean>(false)
|
|
const drawerVisible = ref<boolean>(false)
|
|
|
const showDrawer = ref()
|
|
const showDrawer = ref()
|
|
@@ -188,7 +171,7 @@ const brandChoose = (row) => {
|
|
|
// brandLabel.value = row.value
|
|
// brandLabel.value = row.value
|
|
|
formData.value.brandName = row.label
|
|
formData.value.brandName = row.label
|
|
|
}
|
|
}
|
|
|
-const brandClear = () =>{
|
|
|
|
|
|
|
+const brandClear = () => {
|
|
|
formData.value.brand = undefined
|
|
formData.value.brand = undefined
|
|
|
formData.value.brandName = undefined
|
|
formData.value.brandName = undefined
|
|
|
}
|
|
}
|
|
@@ -246,7 +229,11 @@ const openForm = () => {
|
|
|
message.error('请选择设备类别')
|
|
message.error('请选择设备类别')
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
- inspectItemFormRef.value.open(formData.value.deviceClassify, formData.value.deviceId,formData.value.brandName)
|
|
|
|
|
|
|
+ inspectItemFormRef.value.open(
|
|
|
|
|
+ formData.value.deviceClassify,
|
|
|
|
|
+ formData.value.deviceId,
|
|
|
|
|
+ formData.value.brandName
|
|
|
|
|
+ )
|
|
|
}
|
|
}
|
|
|
const deviceFormRef = ref()
|
|
const deviceFormRef = ref()
|
|
|
const openDevice = () => {
|
|
const openDevice = () => {
|
|
@@ -263,7 +250,7 @@ const close = () => {
|
|
|
// })
|
|
// })
|
|
|
|
|
|
|
|
delView(unref(currentRoute))
|
|
delView(unref(currentRoute))
|
|
|
- push({ name: 'IotInspectRoute', params:{}})
|
|
|
|
|
|
|
+ push({ name: 'IotInspectRoute', params: {} })
|
|
|
}
|
|
}
|
|
|
const itemsWithIndex = computed(() => {
|
|
const itemsWithIndex = computed(() => {
|
|
|
return items.value.map((item, index) => ({
|
|
return items.value.map((item, index) => ({
|
|
@@ -275,7 +262,7 @@ const itemsWithIndex = computed(() => {
|
|
|
})
|
|
})
|
|
|
const itemsWithIndexUpdate = computed(() => {
|
|
const itemsWithIndexUpdate = computed(() => {
|
|
|
return items.value.map((item, index) => ({
|
|
return items.value.map((item, index) => ({
|
|
|
- itemId: item.itemId||item.id,
|
|
|
|
|
|
|
+ itemId: item.itemId || item.id,
|
|
|
item: item.item,
|
|
item: item.item,
|
|
|
standard: item.standard,
|
|
standard: item.standard,
|
|
|
index: index + 1 // 序号从1开始
|
|
index: index + 1 // 序号从1开始
|
|
@@ -345,10 +332,57 @@ const handleDelete = async (id: number) => {
|
|
|
}
|
|
}
|
|
|
</script>
|
|
</script>
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
|
|
+@media (width <= 1400px) {
|
|
|
|
|
+ .route-form-page .form-grid {
|
|
|
|
|
+ grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@media (width <= 768px) {
|
|
|
|
|
+ .route-form-page .page-header {
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .route-form-page .page-header p {
|
|
|
|
|
+ display: none;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .route-form-page .form-grid {
|
|
|
|
|
+ grid-template-columns: minmax(0, 1fr);
|
|
|
|
|
+ padding: 14px 14px 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .route-form-page .form-grid__wide {
|
|
|
|
|
+ grid-column: auto;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .route-form-page .section-heading--actions {
|
|
|
|
|
+ height: auto;
|
|
|
|
|
+ min-height: 44px;
|
|
|
|
|
+ padding-top: 6px;
|
|
|
|
|
+ padding-bottom: 6px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .route-form-page .component-content {
|
|
|
|
|
+ grid-template-columns: minmax(0, 1fr);
|
|
|
|
|
+ gap: 6px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .route-form-page .sortable-item {
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .route-form-page .drag-handle {
|
|
|
|
|
+ padding-right: 8px;
|
|
|
|
|
+ padding-left: 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.base-expandable-content {
|
|
.base-expandable-content {
|
|
|
overflow: hidden; /* 隐藏溢出的内容 */
|
|
overflow: hidden; /* 隐藏溢出的内容 */
|
|
|
transition: max-height 0.3s ease; /* 平滑过渡效果 */
|
|
transition: max-height 0.3s ease; /* 平滑过渡效果 */
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
/* 横向布局容器 */
|
|
/* 横向布局容器 */
|
|
|
.horizontal-list {
|
|
.horizontal-list {
|
|
|
display: flex;
|
|
display: flex;
|
|
@@ -360,28 +394,29 @@ const handleDelete = async (id: number) => {
|
|
|
|
|
|
|
|
/* 拖拽项样式 */
|
|
/* 拖拽项样式 */
|
|
|
.horizontal-item {
|
|
.horizontal-item {
|
|
|
- flex: 0 0 auto;
|
|
|
|
|
|
|
+ display: flex;
|
|
|
min-width: 150px;
|
|
min-width: 150px;
|
|
|
padding: 20px;
|
|
padding: 20px;
|
|
|
|
|
+ cursor: move;
|
|
|
background: #d3a137;
|
|
background: #d3a137;
|
|
|
border: 2px solid #e0e0e0;
|
|
border: 2px solid #e0e0e0;
|
|
|
border-radius: 8px;
|
|
border-radius: 8px;
|
|
|
- cursor: move;
|
|
|
|
|
- user-select: none; /* 防止文字选中:ml-citation{ref="7" data="citationList"} */
|
|
|
|
|
transition:
|
|
transition:
|
|
|
transform 0.3s,
|
|
transform 0.3s,
|
|
|
box-shadow 0.3s;
|
|
box-shadow 0.3s;
|
|
|
- display: flex;
|
|
|
|
|
|
|
+ user-select: none; /* 防止文字选中:ml-citation{ref="7" data="citationList"} */
|
|
|
|
|
+ flex: 0 0 auto;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
gap: 10px;
|
|
gap: 10px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 拖拽手柄样式 */
|
|
/* 拖拽手柄样式 */
|
|
|
.drag-handle {
|
|
.drag-handle {
|
|
|
- opacity: 0.5;
|
|
|
|
|
cursor: move;
|
|
cursor: move;
|
|
|
|
|
+ opacity: 0.5;
|
|
|
transition: opacity 0.3s;
|
|
transition: opacity 0.3s;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.drag-handle:hover {
|
|
.drag-handle:hover {
|
|
|
opacity: 1;
|
|
opacity: 1;
|
|
|
}
|
|
}
|
|
@@ -389,31 +424,31 @@ const handleDelete = async (id: number) => {
|
|
|
/* 拖拽时的悬停效果 */
|
|
/* 拖拽时的悬停效果 */
|
|
|
.horizontal-item:hover {
|
|
.horizontal-item:hover {
|
|
|
transform: translateY(-2px);
|
|
transform: translateY(-2px);
|
|
|
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
|
+ box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 滚动条样式 */
|
|
/* 滚动条样式 */
|
|
|
.horizontal-list::-webkit-scrollbar {
|
|
.horizontal-list::-webkit-scrollbar {
|
|
|
height: 8px;
|
|
height: 8px;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.horizontal-list::-webkit-scrollbar-thumb {
|
|
.horizontal-list::-webkit-scrollbar-thumb {
|
|
|
background: #888;
|
|
background: #888;
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.sortable-container {
|
|
.sortable-container {
|
|
|
- cursor: move;
|
|
|
|
|
display: flex;
|
|
display: flex;
|
|
|
|
|
+ padding: 7px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ cursor: move;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
gap: 9px;
|
|
gap: 9px;
|
|
|
- //max-height: 80vh;
|
|
|
|
|
- overflow-y: auto;
|
|
|
|
|
- padding: 7px;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.sortable-item {
|
|
.sortable-item {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
|
|
|
|
+ height: 50%;
|
|
|
padding: 8px;
|
|
padding: 8px;
|
|
|
background: #fff;
|
|
background: #fff;
|
|
|
border: 1px solid #ebeef5;
|
|
border: 1px solid #ebeef5;
|
|
@@ -422,24 +457,24 @@ const handleDelete = async (id: number) => {
|
|
|
transform 0.3s,
|
|
transform 0.3s,
|
|
|
box-shadow 0.3s;
|
|
box-shadow 0.3s;
|
|
|
user-select: none;
|
|
user-select: none;
|
|
|
- height: 50%;
|
|
|
|
|
|
|
+ align-items: center;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.sortable-item:hover {
|
|
.sortable-item:hover {
|
|
|
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
|
+ box-shadow: 0 2px 12px rgb(0 0 0 / 10%);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.order-number {
|
|
.order-number {
|
|
|
|
|
+ display: flex;
|
|
|
width: 24px;
|
|
width: 24px;
|
|
|
height: 24px;
|
|
height: 24px;
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- justify-content: center;
|
|
|
|
|
- background: #409eff;
|
|
|
|
|
- color: white;
|
|
|
|
|
- border-radius: 50%;
|
|
|
|
|
margin-right: 7px;
|
|
margin-right: 7px;
|
|
|
font-weight: bold;
|
|
font-weight: bold;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ background: #409eff;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.drag-handle {
|
|
.drag-handle {
|
|
@@ -461,8 +496,244 @@ const handleDelete = async (id: number) => {
|
|
|
.sortable-container::-webkit-scrollbar {
|
|
.sortable-container::-webkit-scrollbar {
|
|
|
width: 8px;
|
|
width: 8px;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.sortable-container::-webkit-scrollbar-thumb {
|
|
.sortable-container::-webkit-scrollbar-thumb {
|
|
|
background: #c0c4cc;
|
|
background: #c0c4cc;
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+.route-form-page {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ min-height: calc(
|
|
|
|
|
+ 100vh - 20px - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height)
|
|
|
|
|
+ );
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.page-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ min-height: 66px;
|
|
|
|
|
+ padding: 12px 16px;
|
|
|
|
|
+ background: var(--el-bg-color);
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ box-shadow: var(--el-box-shadow-light);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.page-header__main {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.page-header__icon {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ width: 38px;
|
|
|
|
|
+ height: 38px;
|
|
|
|
|
+ margin-right: 12px;
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+ color: var(--el-color-primary);
|
|
|
|
|
+ background: var(--el-color-primary-light-9);
|
|
|
|
|
+ border: 1px solid var(--el-color-primary-light-7);
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.page-header h1 {
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ font-size: 17px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ line-height: 24px;
|
|
|
|
|
+ color: var(--el-text-color-primary);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.page-header p {
|
|
|
|
|
+ margin: 1px 0 0;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ line-height: 18px;
|
|
|
|
|
+ color: var(--el-text-color-secondary);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.route-form {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-height: 0;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.form-section {
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ background: var(--el-bg-color);
|
|
|
|
|
+ border: 1px solid var(--el-border-color-lighter);
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ box-shadow: var(--el-box-shadow-lighter);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.section-heading {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ height: 44px;
|
|
|
|
|
+ padding: 0 16px;
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: var(--el-text-color-primary);
|
|
|
|
|
+ background: var(--el-fill-color-extra-light);
|
|
|
|
|
+ border-bottom: 1px solid var(--el-border-color-lighter);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.section-heading > span,
|
|
|
|
|
+.section-heading__title > span {
|
|
|
|
|
+ width: 4px;
|
|
|
|
|
+ height: 17px;
|
|
|
|
|
+ margin-right: 9px;
|
|
|
|
|
+ background: var(--el-color-primary);
|
|
|
|
|
+ border-radius: 2px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.section-heading--actions {
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.section-heading__title {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.form-grid {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
|
|
|
+ column-gap: 24px;
|
|
|
|
|
+ padding: 18px 18px 2px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.form-grid__wide {
|
|
|
|
|
+ grid-column: 1 / -1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.route-form :deep(.el-form-item) {
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.route-form :deep(.el-input),
|
|
|
|
|
+.route-form :deep(.el-select),
|
|
|
|
|
+.route-form :deep(.el-tree-select) {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.inspection-section {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ min-height: 280px;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.inspection-section :deep(.el-empty) {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.sortable-container {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ min-height: 0;
|
|
|
|
|
+ padding: 14px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ cursor: default;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.sortable-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ height: auto;
|
|
|
|
|
+ min-height: 58px;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ cursor: grab;
|
|
|
|
|
+ background: var(--el-bg-color);
|
|
|
|
|
+ border: 1px solid var(--el-border-color-lighter);
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ transition:
|
|
|
|
|
+ border-color 0.2s ease,
|
|
|
|
|
+ box-shadow 0.2s ease;
|
|
|
|
|
+ user-select: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.sortable-item:hover {
|
|
|
|
|
+ border-color: var(--el-color-primary-light-7);
|
|
|
|
|
+ box-shadow: 0 3px 10px rgb(0 0 0 / 6%);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.sortable-item:active {
|
|
|
|
|
+ cursor: grabbing;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.order-number {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ width: 26px;
|
|
|
|
|
+ height: 26px;
|
|
|
|
|
+ margin-right: 2px;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ background: var(--el-color-primary);
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ flex: 0 0 auto;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.drag-handle {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ padding: 8px 12px;
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+ color: var(--el-text-color-placeholder);
|
|
|
|
|
+ cursor: grab;
|
|
|
|
|
+ opacity: 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.component-content {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: minmax(180px, 1fr) minmax(280px, 2fr);
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ gap: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-field {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-field__label {
|
|
|
|
|
+ margin-right: 8px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: var(--el-text-color-regular);
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-field__value {
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ color: var(--el-text-color-secondary);
|
|
|
|
|
+ overflow-wrap: anywhere;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.action-bar {
|
|
|
|
|
+ position: sticky;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ z-index: 5;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: flex-end;
|
|
|
|
|
+ min-height: 56px;
|
|
|
|
|
+ padding: 10px 16px;
|
|
|
|
|
+ margin-top: auto;
|
|
|
|
|
+ background: var(--el-bg-color);
|
|
|
|
|
+ border-top: 1px solid var(--el-border-color-lighter);
|
|
|
|
|
+ box-shadow: 0 -4px 12px rgb(0 0 0 / 5%);
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|