mod 巡检记录展示与表单,增加配置类型折叠功能及相关样式
parent
a44b8e3243
commit
63c3e8ab66
|
|
@ -105,7 +105,6 @@ import { ElMessage } from 'element-plus'
|
||||||
import { Crontab } from '@/components/Crontab'
|
import { Crontab } from '@/components/Crontab'
|
||||||
import * as UserApi from '@/api/system/user'
|
import * as UserApi from '@/api/system/user'
|
||||||
import * as ProjectInspectionConfigApi from '@/api/crm/project/inspection'
|
import * as ProjectInspectionConfigApi from '@/api/crm/project/inspection'
|
||||||
import * as ProjectInspectionCheckpointApi from '@/api/crm/project/inspection/checkpoint'
|
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
|
|
@ -186,9 +185,6 @@ const open = async (projectId?: number) => {
|
||||||
try {
|
try {
|
||||||
// 先加载检查点列表,生成标签页
|
// 先加载检查点列表,生成标签页
|
||||||
await loadCheckpointList()
|
await loadCheckpointList()
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载配置数据失败:', error)
|
console.error('加载配置数据失败:', error)
|
||||||
ElMessage.error('加载配置数据失败')
|
ElMessage.error('加载配置数据失败')
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,12 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="管理规则" prop="name">
|
<el-form-item label="管理规则" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入管理规则" />
|
<el-input
|
||||||
|
v-model="formData.name"
|
||||||
|
placeholder="请输入管理规则"
|
||||||
|
:maxlength="12"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
@ -168,7 +173,10 @@ const formData = ref<Partial<ProjectInspectionDataApi.ProjectInspectionDataVO>>(
|
||||||
})
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
configType: [{ required: true, message: '巡检配置类型不能为空', trigger: 'change' }],
|
configType: [{ required: true, message: '巡检配置类型不能为空', trigger: 'change' }],
|
||||||
name: [{ required: true, message: '管理规则不能为空', trigger: 'blur' }],
|
name: [
|
||||||
|
{ required: true, message: '管理规则不能为空', trigger: 'blur' },
|
||||||
|
{ max: 12, message: '管理规则不能超过12个字符', trigger: 'blur' }
|
||||||
|
],
|
||||||
isRequired: [{ required: true, message: '是否必填不能为空', trigger: 'blur' }],
|
isRequired: [{ required: true, message: '是否必填不能为空', trigger: 'blur' }],
|
||||||
type: [{ required: true, message: '类型不能为空', trigger: 'change' }],
|
type: [{ required: true, message: '类型不能为空', trigger: 'change' }],
|
||||||
options: [
|
options: [
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,21 @@
|
||||||
<!-- 分组下的表单项 -->
|
<!-- 分组下的表单项 -->
|
||||||
<template v-for="item in group.items" :key="item.id">
|
<template v-for="item in group.items" :key="item.id">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="item.name"
|
|
||||||
:prop="`data_${item.id}`"
|
:prop="`data_${item.id}`"
|
||||||
:rules="getFieldRules(item)"
|
:rules="getFieldRules(item)"
|
||||||
|
class="inspection-form-item"
|
||||||
>
|
>
|
||||||
|
<template #label>
|
||||||
|
<div class="form-label-wrapper">
|
||||||
|
<el-tooltip
|
||||||
|
:content="item.name"
|
||||||
|
placement="top"
|
||||||
|
:disabled="!item.name || item.name.length <= 30"
|
||||||
|
>
|
||||||
|
<span class="form-label-text">{{ item.name }}</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<!-- 文本类型 -->
|
<!-- 文本类型 -->
|
||||||
<el-input
|
<el-input
|
||||||
v-if="item.type === 1"
|
v-if="item.type === 1"
|
||||||
|
|
@ -101,6 +112,10 @@
|
||||||
:file-size="20"
|
:file-size="20"
|
||||||
:file-type="['pdf', 'doc', 'docx', 'xls', 'xlsx', 'txt']"
|
:file-type="['pdf', 'doc', 'docx', 'xls', 'xlsx', 'txt']"
|
||||||
/>
|
/>
|
||||||
|
<!-- 备注显示在输入框下方 -->
|
||||||
|
<div v-if="item.remark" class="form-content-remark">
|
||||||
|
{{ item.remark }}
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -471,5 +486,63 @@ const submitForm = async () => {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inspection-form-item {
|
||||||
|
margin-bottom: 22px;
|
||||||
|
|
||||||
|
:deep(.el-form-item__label) {
|
||||||
|
line-height: 1.6;
|
||||||
|
word-break: break-word;
|
||||||
|
white-space: normal;
|
||||||
|
padding-right: 12px;
|
||||||
|
width: 200px !important;
|
||||||
|
min-width: 200px;
|
||||||
|
vertical-align: top;
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-form-item__content) {
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.form-label-text {
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: middle;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-content-remark {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 1.6;
|
||||||
|
word-break: break-word;
|
||||||
|
white-space: normal;
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
|
||||||
|
border-radius: 6px;
|
||||||
|
border-left: 3px solid #409EFF;
|
||||||
|
box-shadow: 0 1px 3px rgba(64, 158, 255, 0.1);
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '💡';
|
||||||
|
margin-right: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,42 +156,64 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.summary" class="card-summary">
|
<div v-if="item.summary" class="card-summary">
|
||||||
<span class="summary-label">巡检内容:</span>
|
<div class="summary-header-row">
|
||||||
|
<span class="summary-label">巡检内容:</span>
|
||||||
|
</div>
|
||||||
<div class="summary-content-wrapper">
|
<div class="summary-content-wrapper">
|
||||||
<template v-if="getParsedSummary(item.summary)">
|
<template v-if="getParsedSummary(item.summary)">
|
||||||
<div
|
|
||||||
v-for="(groupData, configTypeName) in getParsedSummary(item.summary)"
|
|
||||||
:key="configTypeName"
|
|
||||||
class="summary-group"
|
|
||||||
>
|
|
||||||
<div class="summary-group-title">{{ configTypeName }}</div>
|
|
||||||
<div
|
<div
|
||||||
v-for="field in groupData"
|
v-for="(groupData, configTypeName) in getParsedSummary(item.summary)"
|
||||||
:key="`${configTypeName}-${field.name}`"
|
:key="configTypeName"
|
||||||
class="summary-field"
|
class="summary-group"
|
||||||
>
|
>
|
||||||
<span class="field-name">{{ field.name }}:</span>
|
<div
|
||||||
<span v-if="field.type === 6" class="field-value-image">
|
class="summary-group-header"
|
||||||
<img
|
@click="toggleConfigType(item.id, configTypeName)"
|
||||||
:src="getFileUrl(field.value)"
|
|
||||||
@click="previewImage(field.value)"
|
|
||||||
class="inspection-thumbnail"
|
|
||||||
alt="巡检图片"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<a
|
|
||||||
v-else-if="field.type === 7"
|
|
||||||
:href="getFileUrl(field.value)"
|
|
||||||
target="_blank"
|
|
||||||
class="field-value-file"
|
|
||||||
>
|
>
|
||||||
📎 {{ field.value.split('/').pop() }}
|
<div class="summary-group-title">
|
||||||
</a>
|
<el-icon class="summary-group-toggle-icon" :class="{ 'is-expanded': expandedConfigTypes[`${item.id}-${configTypeName}`] }">
|
||||||
<span v-else class="field-value-text">{{ field.value }}</span>
|
<ArrowDown />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ configTypeName }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-collapse-transition>
|
||||||
|
<div v-show="expandedConfigTypes[`${item.id}-${configTypeName}`] || false" class="summary-group-content">
|
||||||
|
<div
|
||||||
|
v-for="field in groupData"
|
||||||
|
:key="`${configTypeName}-${field.name}`"
|
||||||
|
class="summary-field"
|
||||||
|
>
|
||||||
|
<div class="field-question">
|
||||||
|
<span class="field-question-label">题目:</span>
|
||||||
|
<span class="field-question-text">{{ field.name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="field-answer">
|
||||||
|
<span class="field-answer-label">答案:</span>
|
||||||
|
<span v-if="field.type === 6" class="field-value-image">
|
||||||
|
<img
|
||||||
|
:src="getFileUrl(field.value)"
|
||||||
|
@click="previewImage(field.value)"
|
||||||
|
class="inspection-thumbnail"
|
||||||
|
alt="巡检图片"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<a
|
||||||
|
v-else-if="field.type === 7"
|
||||||
|
:href="getFileUrl(field.value)"
|
||||||
|
target="_blank"
|
||||||
|
class="field-value-file"
|
||||||
|
>
|
||||||
|
📎 {{ field.value.split('/').pop() }}
|
||||||
|
</a>
|
||||||
|
<span v-else class="field-value-text">{{ field.value }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-collapse-transition>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
<div v-else class="summary-text">{{ item.summary }}</div>
|
||||||
<div v-else class="summary-text">{{ item.summary }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.status || item.overallStatus" class="card-status">
|
<div v-if="item.status || item.overallStatus" class="card-status">
|
||||||
|
|
@ -249,6 +271,28 @@
|
||||||
{{ getUserName(scope.row.inspector) }}
|
{{ getUserName(scope.row.inspector) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="配置类型" align="center" prop="configType" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tooltip
|
||||||
|
v-if="getRecordConfigTypes(scope.row.configType).length > 0"
|
||||||
|
:content="getRecordConfigTypes(scope.row.configType).join('、')"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<div class="table-config-types">
|
||||||
|
<el-tag
|
||||||
|
v-for="configType in getRecordConfigTypes(scope.row.configType)"
|
||||||
|
:key="configType"
|
||||||
|
size="small"
|
||||||
|
type="info"
|
||||||
|
class="config-type-tag"
|
||||||
|
>
|
||||||
|
{{ configType }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
<span v-else class="text-gray-400">-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="状态" align="center" prop="status">
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_PROJECT_INSPECTION_RECORD_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.CRM_PROJECT_INSPECTION_RECORD_STATUS" :value="scope.row.status" />
|
||||||
|
|
@ -317,6 +361,28 @@
|
||||||
{{ getUserName(scope.row.inspector) }}
|
{{ getUserName(scope.row.inspector) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="配置类型" align="center" prop="configType" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tooltip
|
||||||
|
v-if="getRecordConfigTypes(scope.row.configType).length > 0"
|
||||||
|
:content="getRecordConfigTypes(scope.row.configType).join('、')"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<div class="table-config-types">
|
||||||
|
<el-tag
|
||||||
|
v-for="configType in getRecordConfigTypes(scope.row.configType)"
|
||||||
|
:key="configType"
|
||||||
|
size="small"
|
||||||
|
type="info"
|
||||||
|
class="config-type-tag"
|
||||||
|
>
|
||||||
|
{{ configType }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
<span v-else class="text-gray-400">-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="状态" align="center" prop="status">
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_PROJECT_INSPECTION_RECORD_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.CRM_PROJECT_INSPECTION_RECORD_STATUS" :value="scope.row.status" />
|
||||||
|
|
@ -384,17 +450,39 @@
|
||||||
{{ getUserName(scope.row.inspector) }}
|
{{ getUserName(scope.row.inspector) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="配置类型" align="center" prop="configType" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tooltip
|
||||||
|
v-if="getRecordConfigTypes(scope.row.configType).length > 0"
|
||||||
|
:content="getRecordConfigTypes(scope.row.configType).join('、')"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<div class="table-config-types">
|
||||||
|
<el-tag
|
||||||
|
v-for="configType in getRecordConfigTypes(scope.row.configType)"
|
||||||
|
:key="configType"
|
||||||
|
size="small"
|
||||||
|
type="info"
|
||||||
|
class="config-type-tag"
|
||||||
|
>
|
||||||
|
{{ configType }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
<span v-else class="text-gray-400">-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<!-- <el-table-column label="备注" align="center" prop="remark" /> -->
|
<!-- <el-table-column label="备注" align="center" prop="remark" /> -->
|
||||||
<el-table-column label="状态" align="center" prop="status">
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_PROJECT_INSPECTION_RECORD_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.CRM_PROJECT_INSPECTION_RECORD_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="结论" align="center" prop="overallStatus">
|
<!-- <el-table-column label="结论" align="center" prop="overallStatus">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_PROJECT_INSPECTION_RECORD_OVERALL_STATUS" :value="scope.row.overallStatus" />
|
<dict-tag :type="DICT_TYPE.CRM_PROJECT_INSPECTION_RECORD_OVERALL_STATUS" :value="scope.row.overallStatus" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column> -->
|
||||||
<el-table-column label="操作" align="center" min-width="120px">
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -442,7 +530,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
import { getIntDictOptions, getDictLabel, DICT_TYPE } from '@/utils/dict'
|
||||||
import { dateFormatter, formatDate } from '@/utils/formatTime'
|
import { dateFormatter, formatDate } from '@/utils/formatTime'
|
||||||
import download from '@/utils/download'
|
import download from '@/utils/download'
|
||||||
import * as ProjectInspectionRecordApi from '@/api/crm/project/inspection/record'
|
import * as ProjectInspectionRecordApi from '@/api/crm/project/inspection/record'
|
||||||
|
|
@ -451,6 +539,7 @@ import * as UserApi from '@/api/system/user'
|
||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/store/modules/user'
|
||||||
import ProjectInspectionRecordForm from './ProjectInspectionRecordForm.vue'
|
import ProjectInspectionRecordForm from './ProjectInspectionRecordForm.vue'
|
||||||
import ProjectInspectionRecordUploadForm from './ProjectInspectionRecordUploadForm.vue'
|
import ProjectInspectionRecordUploadForm from './ProjectInspectionRecordUploadForm.vue'
|
||||||
|
import { ArrowDown } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
/** 巡检记录 列表 */
|
/** 巡检记录 列表 */
|
||||||
defineOptions({ name: 'CrmProjectInspectionRecord' })
|
defineOptions({ name: 'CrmProjectInspectionRecord' })
|
||||||
|
|
@ -476,6 +565,7 @@ const userList = ref<UserApi.UserVO[]>([]) // 用户列表
|
||||||
const userStore = useUserStore() // 用户store
|
const userStore = useUserStore() // 用户store
|
||||||
const uploadFormRef = ref() // 填报表单Ref
|
const uploadFormRef = ref() // 填报表单Ref
|
||||||
const activeTab = ref('timeline') // 当前激活的标签页
|
const activeTab = ref('timeline') // 当前激活的标签页
|
||||||
|
const expandedConfigTypes = ref<Record<string, boolean>>({}) // 配置类型展开状态
|
||||||
|
|
||||||
|
|
||||||
/** 格式化日期显示 */
|
/** 格式化日期显示 */
|
||||||
|
|
@ -774,6 +864,30 @@ const getCardStatusClass = (overallStatus: number | undefined) => {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 切换配置类型展开/折叠 */
|
||||||
|
const toggleConfigType = (recordId: number | undefined, configTypeName: string) => {
|
||||||
|
if (recordId === undefined) return
|
||||||
|
const key = `${recordId}-${configTypeName}`
|
||||||
|
expandedConfigTypes.value[key] = !expandedConfigTypes.value[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取记录的配置类型列表(根据configType查询字典) */
|
||||||
|
const getRecordConfigTypes = (configType: number[] | undefined): string[] => {
|
||||||
|
if (!configType || !Array.isArray(configType) || configType.length === 0) return []
|
||||||
|
return configType
|
||||||
|
.map(type => getDictLabel(DICT_TYPE.CRM_PROJECT_INSPECTION_CHECKPOINT, type))
|
||||||
|
.filter(label => label) // 过滤掉空值
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 从summary中获取配置类型名称列表(用于折叠功能) */
|
||||||
|
const getConfigTypeNamesFromSummary = (summary: string | undefined): string[] => {
|
||||||
|
if (!summary) return []
|
||||||
|
const parsed = getParsedSummary(summary)
|
||||||
|
if (!parsed) return []
|
||||||
|
return Object.keys(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 先加载项目列表和用户列表
|
// 先加载项目列表和用户列表
|
||||||
|
|
@ -782,6 +896,23 @@ onMounted(async () => {
|
||||||
// 再加载列表数据
|
// 再加载列表数据
|
||||||
await getList()
|
await getList()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 监听列表变化,初始化配置类型展开状态(默认折叠)
|
||||||
|
watch(list, (newList) => {
|
||||||
|
newList.forEach((item) => {
|
||||||
|
// 初始化配置类型的展开状态(从summary中解析配置类型名称用于折叠功能)
|
||||||
|
if (item.id !== undefined && item.summary) {
|
||||||
|
const configTypeNames = getConfigTypeNamesFromSummary(item.summary)
|
||||||
|
configTypeNames.forEach((configTypeName) => {
|
||||||
|
const key = `${item.id}-${configTypeName}`
|
||||||
|
if (expandedConfigTypes.value[key] === undefined) {
|
||||||
|
expandedConfigTypes.value[key] = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
@ -835,6 +966,20 @@ onMounted(async () => {
|
||||||
color: #303133;
|
color: #303133;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card-config-types {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 6px;
|
||||||
|
margin-top: 8px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.config-type-tag {
|
||||||
|
margin: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.card-tags {
|
.card-tags {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
@ -875,10 +1020,20 @@ onMounted(async () => {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
border-top: 1px solid #ebeef5;
|
border-top: 1px solid #ebeef5;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
.summary-header-row {
|
||||||
flex-wrap: wrap;
|
display: flex;
|
||||||
gap: 4px;
|
align-items: center;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
|
.summary-label {
|
||||||
|
color: #909399;
|
||||||
|
margin-right: 8px;
|
||||||
|
font-weight: 500;
|
||||||
|
flex-shrink: 0;
|
||||||
|
min-width: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.summary-label,
|
.summary-label,
|
||||||
.status-label,
|
.status-label,
|
||||||
|
|
@ -889,7 +1044,7 @@ onMounted(async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-content-wrapper {
|
.summary-content-wrapper {
|
||||||
margin-top: 8px;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
.summary-group {
|
.summary-group {
|
||||||
|
|
@ -899,19 +1054,116 @@ onMounted(async () => {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-group-title {
|
.summary-group-header {
|
||||||
font-size: 14px;
|
cursor: pointer;
|
||||||
font-weight: 600;
|
user-select: none;
|
||||||
color: #0f70d1;
|
margin-bottom: 12px;
|
||||||
margin-bottom: 8px;
|
padding: 12px 16px;
|
||||||
padding-bottom: 6px;
|
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
|
||||||
border-bottom: 1px solid #e4e7ed;
|
border-radius: 8px;
|
||||||
|
border-left: 4px solid #409EFF;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
box-shadow: 0 2px 4px rgba(64, 158, 255, 0.08);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, rgba(64, 158, 255, 0.05) 0%, rgba(37, 99, 235, 0.05) 100%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(135deg, #e0f2fe 0%, #bae6fd 100%);
|
||||||
|
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.2);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
border-left-color: #2563eb;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
box-shadow: 0 2px 6px rgba(64, 158, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-group-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #0f70d1;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
border-bottom: none;
|
||||||
|
|
||||||
|
span {
|
||||||
|
flex: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
min-width: 0;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-group-toggle-icon {
|
||||||
|
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
color: #409EFF;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 16px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&.is-expanded {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
color: #2563eb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-group-content {
|
||||||
|
margin-top: 12px;
|
||||||
|
padding-left: 12px;
|
||||||
|
border-left: 2px dashed #e0f2fe;
|
||||||
|
animation: fadeIn 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-field {
|
.summary-field {
|
||||||
display: flex;
|
margin-bottom: 12px;
|
||||||
align-items: flex-start;
|
padding: 12px;
|
||||||
margin-bottom: 8px;
|
background-color: #f8f9fa;
|
||||||
|
border-radius: 6px;
|
||||||
|
border-left: 3px solid #409EFF;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
|
|
||||||
|
|
@ -919,53 +1171,83 @@ onMounted(async () => {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.field-name {
|
.field-question {
|
||||||
font-weight: 500;
|
margin-bottom: 8px;
|
||||||
color: #606266;
|
padding-bottom: 8px;
|
||||||
margin-right: 8px;
|
border-bottom: 1px dashed #dcdfe6;
|
||||||
flex-shrink: 0;
|
|
||||||
min-width: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-value-text {
|
|
||||||
color: #303133;
|
|
||||||
word-break: break-word;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-value-image {
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
.inspection-thumbnail {
|
.field-question-label {
|
||||||
max-width: 120px;
|
font-weight: 600;
|
||||||
max-height: 120px;
|
color: #409EFF;
|
||||||
|
margin-right: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-question-text {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-answer {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.field-answer-label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #67C23A;
|
||||||
|
margin-right: 6px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-value-text {
|
||||||
|
color: #606266;
|
||||||
|
word-break: break-word;
|
||||||
|
flex: 1;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 6px 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #e4e7ed;
|
border: 1px solid #e4e7ed;
|
||||||
padding: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.field-value-file {
|
.field-value-image {
|
||||||
color: #409EFF;
|
display: inline-block;
|
||||||
text-decoration: none;
|
|
||||||
padding: 2px 8px;
|
.inspection-thumbnail {
|
||||||
border: 1px solid #409EFF;
|
max-width: 120px;
|
||||||
border-radius: 4px;
|
max-height: 120px;
|
||||||
display: inline-block;
|
border-radius: 4px;
|
||||||
transition: all 0.3s;
|
border: 1px solid #e4e7ed;
|
||||||
|
padding: 2px;
|
||||||
&:hover {
|
cursor: pointer;
|
||||||
background-color: #409EFF;
|
transition: all 0.3s;
|
||||||
color: #fff;
|
background-color: #fff;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-value-file {
|
||||||
|
color: #409EFF;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 6px 10px;
|
||||||
|
border: 1px solid #409EFF;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: inline-block;
|
||||||
|
transition: all 0.3s;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #409EFF;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -992,6 +1274,34 @@ onMounted(async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 表格中配置类型样式
|
||||||
|
.table-config-types {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 4px;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.config-type-tag {
|
||||||
|
margin: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-type-more {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #909399;
|
||||||
|
border-color: #909399;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #73767a;
|
||||||
|
border-color: #73767a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.el-timeline) {
|
:deep(.el-timeline) {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue