<template>
|
<div class="app-container">
|
<!-- 搜索区域 -->
|
<div class="search_form">
|
<el-form :model="searchForm" :inline="true" label-width="auto">
|
<el-form-item label="客户名称">
|
<el-input
|
v-model="searchForm.customerName"
|
placeholder="请输入客户名称"
|
clearable
|
prefix-icon="Search"
|
style="width: 200px"
|
@change="handleQuery"
|
/>
|
</el-form-item>
|
<el-form-item label="录入日期:">
|
<el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
|
placeholder="请选择" clearable @change="changeDaterange" />
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="handleQuery">搜索</el-button>
|
<el-button @click="resetQuery">重置</el-button>
|
</el-form-item>
|
</el-form>
|
<div class="actions">
|
<el-button type="primary" @click="handleAdd">新建</el-button>
|
<el-button type="danger" plain @click="handleDelete">删除</el-button>
|
</div>
|
</div>
|
<!-- 表格区域 -->
|
<div class="table_list">
|
<el-table
|
:data="tableData"
|
border
|
v-loading="tableLoading"
|
@selection-change="handleSelectionChange"
|
:row-key="(row) => row.id"
|
height="calc(100vh - 18.5em)"
|
stripe
|
>
|
<el-table-column align="center" type="selection" width="55" />
|
<el-table-column align="center" label="序号" type="index" width="60" />
|
<el-table-column label="状态" prop="status" width="120">
|
<template #default="{ row }">
|
<el-tag
|
:type="getStatusTagType(row.status)"
|
effect="light"
|
>
|
{{ getStatusText(row.status) }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="省份" prop="province" show-overflow-tooltip width="120" />
|
<el-table-column label="客户名称" prop="customerName" show-overflow-tooltip />
|
<el-table-column label="商机来源" prop="businessSource" show-overflow-tooltip />
|
<!-- <el-table-column label="客户描述" prop="description" show-overflow-tooltip min-width="200" /> -->
|
<el-table-column label="录入人" prop="entryPerson" show-overflow-tooltip />
|
<el-table-column label="更新日期" prop="updateTime">
|
<template #default="{ row }">
|
{{ formatDate(row.updateTime) }}
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" fixed="right" width="220" align="center">
|
<template #default="{ row }">
|
<el-button
|
link
|
type="primary"
|
size="small"
|
@click="handleEdit(row)"
|
>
|
编辑
|
</el-button>
|
<el-button
|
link
|
type="primary"
|
size="small"
|
@click="handleAddOperation(row)"
|
>
|
添加描述
|
</el-button>
|
<el-button
|
link
|
type="primary"
|
size="small"
|
@click="handleDetail(row)"
|
>
|
详情
|
</el-button>
|
<el-button
|
link
|
type="primary"
|
size="small"
|
@click="handleAttachment(row)"
|
>
|
附件
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<!-- 分页组件 -->
|
<pagination
|
v-show="total > 0"
|
:total="total"
|
layout="total, sizes, prev, pager, next, jumper"
|
:page="page.current"
|
:limit="page.size"
|
@pagination="paginationChange"
|
/>
|
</div>
|
|
<!-- 新增/编辑对话框 -->
|
<el-dialog
|
v-model="dialogFormVisible"
|
:title="operationType === 'add' ? '新建商机' : operationType === 'edit' ? '编辑商机' : operationType === 'addOperation' ? '添加商机' : '商机详情'"
|
width="600px"
|
@close="closeDialog"
|
>
|
<el-form
|
:model="form"
|
:rules="rules"
|
ref="formRef"
|
label-width="100px"
|
label-position="left"
|
>
|
<el-form-item label="状态" prop="status">
|
<el-select v-model="form.status" placeholder="请选择状态" style="width: 100%" :disabled="operationType === 'detail'">
|
<el-option
|
v-for="item in statusOptions"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</el-form-item>
|
|
<el-form-item label="省份" prop="province">
|
<el-select v-model="form.province" filterable placeholder="请选择省份" style="width: 100%" :disabled="operationType === 'detail' || operationType === 'addOperation'">
|
<el-option
|
v-for="item in provinceOptions"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</el-form-item>
|
|
<el-form-item label="客户名称" prop="customerName">
|
<el-select v-model="form.customerName" placeholder="请选择" clearable :disabled="operationType === 'detail' || operationType === 'addOperation'">
|
<el-option v-for="item in customerOption" :key="item.customerName" :label="item.customerName" :value="item.customerName">
|
{{
|
item.customerName + "——" + item.taxpayerIdentificationNumber
|
}}
|
</el-option>
|
</el-select>
|
</el-form-item>
|
|
<el-form-item label="商机来源" prop="businessSource">
|
<el-input v-model="form.businessSource" placeholder="请输入商机来源" :disabled="operationType === 'detail' || operationType === 'addOperation'" />
|
</el-form-item>
|
|
<el-form-item label="客户描述" prop="description" v-if="operationType !== 'detail'">
|
<el-input
|
v-model="form.description"
|
type="textarea"
|
:rows="3"
|
placeholder="请输入客户描述"
|
maxlength="500"
|
show-word-limit
|
/>
|
</el-form-item>
|
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-form-item label="录入人" prop="entryPerson">
|
<el-select v-model="form.entryPerson" placeholder="请选择" clearable @change="changs" :disabled="operationType === 'detail' || operationType === 'addOperation'">
|
<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="录入日期" prop="entryDate">
|
<el-date-picker style="width: 100%" v-model="form.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
|
type="date" placeholder="请选择" clearable :disabled="operationType === 'detail' || operationType === 'addOperation'" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<!-- 附件上传(非详情模式下显示) -->
|
<el-row :gutter="30" v-if="operationType !== 'detail'">
|
<el-col :span="24">
|
<el-form-item label="附件材料:">
|
<el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
|
:headers="upload.headers" :data="upload.data" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
|
:on-success="handleUploadSuccess" :on-remove="handleRemove">
|
<el-button type="primary">上传</el-button>
|
<template #tip>
|
<div class="el-upload__tip">
|
文件格式支持
|
doc,docx,xls,xlsx,ppt,pptx,pdf,txt,xml,jpg,jpeg,png,gif,bmp,rar,zip,7z
|
</div>
|
</template>
|
</el-upload>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
|
<!-- 变更记录时间线(仅在详情模式下显示) -->
|
<div v-if="operationType === 'detail'" class="change-history-section">
|
<el-divider content-position="left">变更记录</el-divider>
|
<el-timeline>
|
<el-timeline-item
|
v-for="record in changeHistory"
|
:key="record.id"
|
:timestamp="record.timestamp"
|
:type="record.type === 'current' ? 'primary' : record.type === 'update' ? 'success' : 'info'"
|
:hollow="record.type === 'current'"
|
placement="top"
|
>
|
<el-card shadow="hover" class="timeline-card">
|
<template #header>
|
<div class="card-header">
|
<span class="action-type">{{ record.action }}</span>
|
<span class="operator">操作人:{{ record.operator }}</span>
|
</div>
|
</template>
|
<div class="change-content">
|
<div class="status-change" v-if="record.status">
|
<span class="label">状态:</span>
|
<el-tag :type="record.type === 'current' ? 'primary' : 'info'" size="small">
|
{{ getStatusLabel(record.status) }}
|
</el-tag>
|
</div>
|
<div class="description-change" v-if="record.description">
|
<span class="label">客户描述:</span>
|
<span class="description-text">{{ record.description }}</span>
|
</div>
|
</div>
|
</el-card>
|
</el-timeline-item>
|
</el-timeline>
|
</div>
|
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button @click="closeDialog">取消</el-button>
|
<el-button type="primary" @click="submitForm" v-if="operationType !== 'detail'">
|
确定
|
</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
|
<!-- 附件列表对话框 -->
|
<FileList ref="fileListRef" />
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
|
import { Search } from '@element-plus/icons-vue'
|
import { ElMessageBox, ElMessage } from 'element-plus'
|
import pagination from '@/components/PIMTable/Pagination.vue'
|
import useUserStore from '@/store/modules/user'
|
import dayjs from 'dayjs'
|
import { getToken } from '@/utils/auth'
|
import {
|
opportunityListPage,
|
addOpportunity,
|
updateOpportunity,
|
delOpportunity,
|
addDescription
|
} from '@/api/salesManagement/opportunityManagement.js'
|
import { userListNoPage } from '@/api/system/user.js'
|
import {customerList, getSalesLedgerWithProducts} from '@/api/salesManagement/salesLedger.js'
|
import FileList from './fileList.vue'
|
|
const { proxy } = getCurrentInstance()
|
const userStore = useUserStore()
|
|
// 表格数据
|
const tableData = ref([])
|
const selectedRows = ref([])
|
const tableLoading = ref(false)
|
const userList = ref([])
|
const customerOption = ref([])
|
|
// 分页配置
|
const page = reactive({
|
current: 1,
|
size: 100,
|
})
|
const total = ref(0)
|
|
// 搜索表单
|
const searchForm = reactive({
|
customerName: '',
|
entryDate: [],
|
entryDateStart: '',
|
entryDateEnd: ''
|
})
|
|
// 对话框相关
|
const dialogFormVisible = ref(false)
|
const operationType = ref('') // add, detail
|
const formRef = ref()
|
const form = reactive({
|
id: undefined,
|
status: undefined,
|
province: '',
|
customerName: '',
|
businessSource: '',
|
description: '',
|
entryPerson: userStore.nickName,
|
entryDate: dayjs().format('YYYY-MM-DD')
|
})
|
|
// 变更记录数据(模拟数据)
|
const changeHistory = ref([])
|
|
// 文件列表
|
const fileList = ref([])
|
|
// FileList组件引用
|
const fileListRef = ref(null)
|
|
// 上传配置
|
const upload = reactive({
|
// 上传的地址
|
url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
|
// 设置上传的请求头部
|
headers: { Authorization: "Bearer " + getToken() },
|
// 上传参数
|
data: { type: 9 }
|
})
|
|
// 获取状态标签
|
const getStatusLabel = (statusValue) => {
|
const status = statusOptions.find(item => item.value === statusValue)
|
return status ? status.label : statusValue
|
}
|
|
// 表单验证规则
|
const rules = reactive({
|
customerName: [
|
{ required: true, message: '请选择客户', trigger: 'change' }
|
],
|
status: [
|
{ required: true, message: '请选择状态', trigger: 'change' }
|
],
|
entryPerson: [
|
{ required: true, message: '请选择录入人', trigger: 'change' }
|
],
|
entryDate: [
|
{ required: true, message: '请选择录入日期', trigger: 'change' }
|
]
|
})
|
|
// 状态选项
|
const statusOptions = [
|
{ value: '新建', label: '新建' },
|
{ value: '项目跟踪', label: '项目跟踪' },
|
{ value: '合同签约', label: '合同签约' },
|
{ value: '项目交付', label: '项目交付' },
|
{ value: '项目验收', label: '项目验收' }
|
]
|
|
// 省份选项(示例)
|
const provinceOptions = [
|
{ value: '北京市', label: '北京市' },
|
{ value: '天津市', label: '天津市' },
|
{ value: '河北省', label: '河北省' },
|
{ value: '山西省', label: '山西省' },
|
{ value: '内蒙古自治区', label: '内蒙古自治区' },
|
{ value: '辽宁省', label: '辽宁省' },
|
{ value: '吉林省', label: '吉林省' },
|
{ value: '黑龙江省', label: '黑龙江省' },
|
{ value: '上海市', label: '上海市' },
|
{ value: '江苏省', label: '江苏省' },
|
{ value: '浙江省', label: '浙江省' },
|
{ value: '安徽省', label: '安徽省' },
|
{ value: '福建省', label: '福建省' },
|
{ value: '江西省', label: '江西省' },
|
{ value: '山东省', label: '山东省' },
|
{ value: '河南省', label: '河南省' },
|
{ value: '湖北省', label: '湖北省' },
|
{ value: '湖南省', label: '湖南省' },
|
{ value: '广东省', label: '广东省' },
|
{ value: '广西壮族自治区', label: '广西壮族自治区' },
|
{ value: '海南省', label: '海南省' },
|
{ value: '重庆市', label: '重庆市' },
|
{ value: '四川省', label: '四川省' },
|
{ value: '贵州省', label: '贵州省' },
|
{ value: '云南省', label: '云南省' },
|
{ value: '西藏自治区', label: '西藏自治区' },
|
{ value: '陕西省', label: '陕西省' },
|
{ value: '甘肃省', label: '甘肃省' },
|
{ value: '青海省', label: '青海省' },
|
{ value: '宁夏回族自治区', label: '宁夏回族自治区' },
|
{ value: '新疆维吾尔自治区', label: '新疆维吾尔自治区' },
|
{ value: '台湾省', label: '台湾省' },
|
{ value: '香港特别行政区', label: '香港特别行政区' },
|
{ value: '澳门特别行政区', label: '澳门特别行政区' }
|
]
|
|
// 获取状态标签类型
|
const getStatusTagType = (status) => {
|
const typeMap = {
|
'新建': 'info',
|
'项目跟踪': 'primary',
|
'合同签约': 'warning',
|
'项目交付': 'success',
|
'项目验收': 'success'
|
}
|
return typeMap[status] || 'info'
|
}
|
|
// 获取状态文本
|
const getStatusText = (status) => {
|
const textMap = {
|
'新建': '新建',
|
'项目跟踪': '项目跟踪',
|
'合同签约': '合同签约',
|
'项目交付': '项目交付',
|
'项目验收': '项目验收'
|
}
|
return textMap[status] || '未知'
|
}
|
|
// 格式化日期
|
const formatDate = (date) => {
|
if (!date) return ''
|
return dayjs(date).format('YYYY-MM-DD')
|
}
|
|
// 查询列表
|
const handleQuery = () => {
|
page.current = 1
|
getList()
|
}
|
|
// 重置查询
|
const resetQuery = () => {
|
Object.assign(searchForm, {
|
customerName: '',
|
entryDate: [],
|
entryDateStart: '',
|
entryDateEnd: ''
|
})
|
handleQuery()
|
}
|
|
// 日期范围变化
|
const changeDaterange = (val) => {
|
if (val && val.length === 2) {
|
searchForm.entryDateStart = val[0]
|
searchForm.entryDateEnd = val[1]
|
} else {
|
searchForm.entryDateStart = ''
|
searchForm.entryDateEnd = ''
|
}
|
handleQuery()
|
}
|
|
// 获取列表数据
|
const getList = () => {
|
tableLoading.value = true
|
|
// 创建查询参数,排除entryDate字段,只使用entryDateStart和entryDateEnd
|
const { entryDate, ...queryParams } = searchForm
|
const params = {
|
...queryParams,
|
...page
|
}
|
|
// 删除空值参数
|
Object.keys(params).forEach(key => {
|
if (params[key] === '' || params[key] === null || params[key] === undefined) {
|
delete params[key]
|
}
|
})
|
|
opportunityListPage(params).then(res => {
|
tableData.value = res.data.records || []
|
total.value = res.data.total || 0
|
}).catch(err => {
|
console.error('获取商机列表失败:', err)
|
tableData.value = []
|
total.value = 0
|
}).finally(() => {
|
tableLoading.value = false
|
})
|
}
|
|
// 分页变化
|
const paginationChange = (pagination) => {
|
page.current = pagination.page
|
page.size = pagination.limit
|
getList()
|
}
|
|
// 选择变化
|
const handleSelectionChange = (selection) => {
|
selectedRows.value = selection
|
}
|
|
// 新建商机
|
const handleAdd = async () => {
|
operationType.value = 'add'
|
resetForm()
|
|
// 加载用户列表和客户列表
|
let userLists = await userListNoPage()
|
userList.value = userLists.data
|
customerList().then((res) => {
|
customerOption.value = res
|
})
|
|
dialogFormVisible.value = true
|
}
|
|
// 添加操作
|
const handleAddOperation = async (row) => {
|
operationType.value = 'addOperation'
|
|
// 加载用户列表和客户列表
|
let userLists = await userListNoPage()
|
userList.value = userLists.data
|
customerList().then((res) => {
|
customerOption.value = res
|
})
|
|
// 使用当前行数据作为基础,但只能修改状态和客户描述
|
Object.assign(form, row, {
|
// 保留原始商机ID,用于关联操作记录
|
status: row.status,
|
description: '', // 清空客户描述,允许重新填写
|
entryPerson: userStore.nickName, // 设置录入人为当前账号
|
entryDate: dayjs().format('YYYY-MM-DD') // 设置录入时间为当天
|
})
|
dialogFormVisible.value = true
|
}
|
|
// 查看详情
|
const handleDetail = async (row) => {
|
operationType.value = 'detail'
|
|
// 加载用户列表和客户列表
|
let userLists = await userListNoPage()
|
userList.value = userLists.data
|
customerList().then((res) => {
|
customerOption.value = res
|
})
|
|
// 使用updateTime作为录入时间反显
|
Object.assign(form, row, {
|
entryDateStart: row.updateTime || row.entryDateStart
|
})
|
|
// 生成模拟变更记录
|
generateChangeHistory(row)
|
dialogFormVisible.value = true
|
}
|
|
// 生成变更记录
|
const generateChangeHistory = (row) => {
|
// 使用businessDescription数组数据生成变更记录
|
const history = []
|
|
if (row.businessDescription && Array.isArray(row.businessDescription)) {
|
row.businessDescription.forEach((item, index) => {
|
history.push({
|
id: item.id || index,
|
timestamp: item.entryDate || item.updateTime || item.createTime,
|
operator: item.entryPerson || '系统',
|
status: item.status,
|
description: item.description,
|
type: index === 0 ? 'current' : 'info',
|
action: index === 0 ? '当前状态' : '历史记录'
|
})
|
})
|
}
|
|
changeHistory.value = history
|
}
|
|
// 编辑商机
|
const handleEdit = async (row) => {
|
operationType.value = 'edit'
|
|
// 加载用户列表和客户列表
|
let userLists = await userListNoPage()
|
userList.value = userLists.data
|
customerList().then((res) => {
|
customerOption.value = res
|
})
|
|
// 使用当前账号和当天日期作为默认值
|
Object.assign(form, row, {
|
entryPerson: userStore.nickName, // 设置录入人为当前账号
|
entryDate: dayjs().format('YYYY-MM-DD') // 设置录入时间为当天
|
})
|
dialogFormVisible.value = true
|
}
|
|
// 录入人变化处理
|
const changs = (value) => {
|
// 可以根据需要添加处理逻辑
|
}
|
|
// 提交表单
|
const submitForm = () => {
|
formRef.value.validate(valid => {
|
if (valid) {
|
// 收集附件文件的临时ID
|
let tempFileIds = []
|
if (fileList.value !== null && fileList.value.length > 0) {
|
tempFileIds = fileList.value.map(item => item.tempId)
|
}
|
|
let api
|
let successMessage
|
let submitData
|
|
if (operationType.value === 'add') {
|
api = addOpportunity
|
successMessage = '新建成功'
|
submitData = {
|
...form,
|
tempFileIds: tempFileIds,
|
type: 9 // 商机管理的类型标识
|
}
|
} else if (operationType.value === 'addOperation') {
|
api = addDescription
|
successMessage = '添加操作成功'
|
// 添加操作时传递状态、描述、录入人、录入日期、附件和商机ID
|
submitData = {
|
status: form.status,
|
description: form.description,
|
entryPerson: form.entryPerson,
|
entryDate: form.entryDate,
|
tempFileIds: tempFileIds,
|
type: 9, // 商机管理的类型标识
|
businessOpportunityId: form.id // 传递商机ID
|
}
|
} else {
|
api = updateOpportunity
|
successMessage = '修改成功'
|
submitData = {
|
...form,
|
tempFileIds: tempFileIds,
|
type: 9 // 商机管理的类型标识
|
}
|
}
|
|
api(submitData).then(res => {
|
if (res.code === 200) {
|
proxy.$modal.msgSuccess(successMessage)
|
closeDialog()
|
getList()
|
} else {
|
proxy.$modal.msgError(res.msg || '操作失败')
|
}
|
}).catch(err => {
|
proxy.$modal.msgError('操作失败')
|
})
|
}
|
})
|
}
|
|
// 删除商机
|
const handleDelete = () => {
|
if (selectedRows.value.length === 0) {
|
proxy.$modal.msgWarning('请选择要删除的商机')
|
return
|
}
|
|
ElMessageBox.confirm('确定删除选中的商机吗?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
const ids = selectedRows.value.map(item => item.id)
|
delOpportunity(ids).then(res => {
|
if (res.code === 200) {
|
proxy.$modal.msgSuccess('删除成功')
|
getList()
|
} else {
|
proxy.$modal.msgError(res.msg || '删除失败')
|
}
|
}).catch(err => {
|
proxy.$modal.msgError('删除失败')
|
})
|
}).catch(() => {
|
// 用户取消删除
|
})
|
}
|
|
|
|
// 重置表单
|
const resetForm = () => {
|
Object.assign(form, {
|
id: undefined,
|
status: '新建',
|
province: '',
|
customerName: '',
|
businessSource: '',
|
description: '',
|
entryPerson: userStore.nickName,
|
entryDate: dayjs().format('YYYY-MM-DD')
|
})
|
|
if (formRef.value) {
|
formRef.value.clearValidate()
|
}
|
}
|
|
// 关闭对话框
|
const closeDialog = () => {
|
dialogFormVisible.value = false
|
resetForm()
|
}
|
|
// 上传前校检
|
function handleBeforeUpload(file) {
|
// 校检文件大小
|
// if (file.size > 1024 * 1024 * 10) {
|
// proxy.$modal.msgError("上传文件大小不能超过10MB!");
|
// return false;
|
// }
|
proxy.$modal.loading("正在上传文件,请稍候...");
|
return true;
|
}
|
|
// 上传失败
|
function handleUploadError(err) {
|
proxy.$modal.msgError("上传文件失败");
|
proxy.$modal.closeLoading();
|
}
|
|
// 上传成功回调
|
function handleUploadSuccess(res, file, uploadFiles) {
|
proxy.$modal.closeLoading();
|
if (res.code === 200) {
|
file.tempId = res.data.tempId;
|
proxy.$modal.msgSuccess("上传成功");
|
} else {
|
proxy.$modal.msgError(res.msg);
|
proxy.$refs.fileUpload.handleRemove(file);
|
}
|
}
|
|
// 移除文件
|
function handleRemove(file) {
|
// 这里可以添加删除文件的逻辑
|
proxy.$modal.msgSuccess("删除成功");
|
}
|
|
// 查看附件
|
function handleAttachment(row) {
|
fileListRef.value.open(row.businessCommonFiles)
|
}
|
|
onMounted(() => {
|
getList()
|
})
|
</script>
|
|
<style scoped lang="scss">
|
.app-container {
|
padding: 20px;
|
}
|
.search_form {
|
display: flex;
|
align-items: flex-start;
|
justify-content: space-between;
|
}
|
|
.table_list {
|
margin-top: unset;
|
}
|
|
.dialog-footer {
|
text-align: right;
|
}
|
|
:deep(.el-form-item__label) {
|
font-weight: 500;
|
}
|
|
:deep(.el-table) {
|
.el-table__header-wrapper {
|
th {
|
background-color: #f0f2f5;
|
color: #333;
|
font-weight: 600;
|
}
|
}
|
}
|
|
/* 变更记录时间线样式 */
|
.change-history-section {
|
margin-top: 20px;
|
|
.el-divider {
|
margin: 20px 0;
|
}
|
|
.timeline-card {
|
margin: 8px 0;
|
border-radius: 8px;
|
|
.card-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 8px 0;
|
|
.action-type {
|
font-weight: 600;
|
color: #333;
|
}
|
|
.operator {
|
font-size: 12px;
|
color: #666;
|
}
|
}
|
|
.change-content {
|
.status-change, .description-change {
|
margin-bottom: 8px;
|
|
.label {
|
font-weight: 500;
|
color: #666;
|
margin-right: 8px;
|
}
|
|
.description-text {
|
color: #333;
|
line-height: 1.5;
|
}
|
}
|
}
|
}
|
|
/* 时间线样式优化 */
|
:deep(.el-timeline) {
|
padding-left: 0;
|
|
.el-timeline-item {
|
.el-timeline-item__node {
|
background-color: #409eff;
|
|
&.el-timeline-item__node--primary {
|
background-color: #409eff;
|
}
|
|
&.el-timeline-item__node--success {
|
background-color: #67c23a;
|
}
|
|
&.el-timeline-item__node--info {
|
background-color: #909399;
|
}
|
|
&.el-timeline-item__node--hollow {
|
background-color: transparent;
|
border-color: #409eff;
|
}
|
}
|
|
.el-timeline-item__timestamp {
|
color: #666;
|
font-size: 12px;
|
}
|
}
|
}
|
}
|
</style>
|