| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="省份" prop="province" show-overflow-tooltip width="120" /> |
| | | <el-table-column label="客户名称" prop="customerName" show-overflow-tooltip width="230" /> |
| | | <el-table-column label="商机来源" prop="businessSource" show-overflow-tooltip width="150" /> |
| | | <el-table-column label="客户描述" prop="description" show-overflow-tooltip min-width="200" /> |
| | | <el-table-column label="录入人" prop="entryPerson" show-overflow-tooltip width="120" /> |
| | | <el-table-column label="更新日期" prop="updateTime" 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="130" align="center"> |
| | | <el-table-column label="操作" fixed="right" width="220" align="center"> |
| | | <template #default="{ row }"> |
| | | <el-button |
| | | link |
| | |
| | | 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-dialog |
| | | v-model="dialogFormVisible" |
| | | :title="operationType === 'add' ? '新建商机' : operationType === 'edit' ? '编辑商机' : '商机详情'" |
| | | :title="operationType === 'add' ? '新建商机' : operationType === 'edit' ? '编辑商机' : operationType === 'addOperation' ? '添加商机' : '商机详情'" |
| | | width="600px" |
| | | @close="closeDialog" |
| | | > |
| | |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="省份" prop="province"> |
| | | <el-select v-model="form.province" filterable placeholder="请选择省份" style="width: 100%" :disabled="operationType === 'detail'"> |
| | | <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" |
| | |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="客户名称" prop="customerName"> |
| | | <el-select v-model="form.customerName" placeholder="请选择" clearable :disabled="operationType === 'detail'"> |
| | | <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-form-item> |
| | | |
| | | <el-form-item label="商机来源" prop="businessSource"> |
| | | <el-input v-model="form.businessSource" placeholder="请输入商机来源" :disabled="operationType === 'detail'" /> |
| | | <el-input v-model="form.businessSource" placeholder="请输入商机来源" :disabled="operationType === 'detail' || operationType === 'addOperation'" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="客户描述" prop="description"> |
| | | <el-form-item label="客户描述" prop="description" v-if="operationType !== 'detail'"> |
| | | <el-input |
| | | v-model="form.description" |
| | | type="textarea" |
| | |
| | | placeholder="请输入客户描述" |
| | | maxlength="500" |
| | | show-word-limit |
| | | :disabled="operationType === 'detail'" |
| | | /> |
| | | </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'"> |
| | | <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="entryDateStart"> |
| | | <el-date-picker style="width: 100%" v-model="form.entryDateStart" value-format="YYYY-MM-DD" format="YYYY-MM-DD" |
| | | type="date" placeholder="请选择" clearable :disabled="operationType === 'detail'" /> |
| | | <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"> |
| | |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 附件列表对话框 --> |
| | | <FileList ref="fileListRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | 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 |
| | | delOpportunity, |
| | | addDescription |
| | | } from '@/api/salesManagement/opportunityManagement.js' |
| | | import { userListNoPage } from '@/api/system/user.js' |
| | | import { customerList } from '@/api/salesManagement/salesLedger.js' |
| | | import {customerList, getSalesLedgerWithProducts} from '@/api/salesManagement/salesLedger.js' |
| | | import FileList from './fileList.vue' |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const userStore = useUserStore() |
| | |
| | | const formRef = ref() |
| | | const form = reactive({ |
| | | id: undefined, |
| | | status: 'new', |
| | | status: undefined, |
| | | province: '', |
| | | customerName: '', |
| | | businessSource: '', |
| | | description: '', |
| | | entryPerson: userStore.nickName, |
| | | entryDateStart: dayjs().format('YYYY-MM-DD') |
| | | 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({ |
| | |
| | | entryPerson: [ |
| | | { required: true, message: '请选择录入人', trigger: 'change' } |
| | | ], |
| | | entryDateStart: [ |
| | | entryDate: [ |
| | | { required: true, message: '请选择录入日期', trigger: 'change' } |
| | | ] |
| | | }) |
| | | |
| | | // 状态选项 |
| | | const statusOptions = [ |
| | | { value: 'new', label: '新建' }, |
| | | { value: 'tracking', label: '项目跟踪' }, |
| | | { value: 'contract', label: '合同签约' }, |
| | | { value: 'delivery', label: '项目交付' }, |
| | | { value: 'acceptance', label: '项目验收' } |
| | | { value: '新建', label: '新建' }, |
| | | { value: '项目跟踪', label: '项目跟踪' }, |
| | | { value: '合同签约', label: '合同签约' }, |
| | | { value: '项目交付', label: '项目交付' }, |
| | | { value: '项目验收', label: '项目验收' } |
| | | ] |
| | | |
| | | // 省份选项(示例) |
| | | const provinceOptions = [ |
| | | { value: 'beijing', label: '北京市' }, |
| | | { value: 'tianjin', label: '天津市' }, |
| | | { value: 'hebei', label: '河北省' }, |
| | | { value: 'shanxi', label: '山西省' }, |
| | | { value: 'neimenggu', label: '内蒙古自治区' }, |
| | | { value: 'liaoning', label: '辽宁省' }, |
| | | { value: 'jilin', label: '吉林省' }, |
| | | { value: 'heilongjiang', label: '黑龙江省' }, |
| | | { value: 'shanghai', label: '上海市' }, |
| | | { value: 'jiangsu', label: '江苏省' }, |
| | | { value: 'zhejiang', label: '浙江省' }, |
| | | { value: 'anhui', label: '安徽省' }, |
| | | { value: 'fujian', label: '福建省' }, |
| | | { value: 'jiangxi', label: '江西省' }, |
| | | { value: 'shandong', label: '山东省' }, |
| | | { value: 'henan', label: '河南省' }, |
| | | { value: 'hubei', label: '湖北省' }, |
| | | { value: 'hunan', label: '湖南省' }, |
| | | { value: 'guangdong', label: '广东省' }, |
| | | { value: 'guangxi', label: '广西壮族自治区' }, |
| | | { value: 'hainan', label: '海南省' }, |
| | | { value: 'chongqing', label: '重庆市' }, |
| | | { value: 'sichuan', label: '四川省' }, |
| | | { value: 'guizhou', label: '贵州省' }, |
| | | { value: 'yunnan', label: '云南省' }, |
| | | { value: 'xizang', label: '西藏自治区' }, |
| | | { value: 'shaanxi', label: '陕西省' }, |
| | | { value: 'gansu', label: '甘肃省' }, |
| | | { value: 'qinghai', label: '青海省' }, |
| | | { value: 'ningxia', label: '宁夏回族自治区' }, |
| | | { value: 'xinjiang', label: '新疆维吾尔自治区' }, |
| | | { value: 'taiwan', label: '台湾省' }, |
| | | { value: 'xianggang', label: '香港特别行政区' }, |
| | | { value: 'aomen', 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: '香港特别行政区' }, |
| | | { value: '澳门特别行政区', label: '澳门特别行政区' } |
| | | ] |
| | | |
| | | // 获取状态标签类型 |
| | | const getStatusTagType = (status) => { |
| | | const typeMap = { |
| | | 'new': 'info', |
| | | 'tracking': 'primary', |
| | | 'contract': 'warning', |
| | | 'delivery': 'success', |
| | | 'acceptance': 'success' |
| | | } |
| | | return typeMap[status] || 'info' |
| | | } |
| | | // 获取状态标签类型 |
| | | const getStatusTagType = (status) => { |
| | | const typeMap = { |
| | | '新建': 'info', |
| | | '项目跟踪': 'primary', |
| | | '合同签约': 'warning', |
| | | '项目交付': 'success', |
| | | '项目验收': 'success' |
| | | } |
| | | return typeMap[status] || 'info' |
| | | } |
| | | |
| | | // 获取状态文本 |
| | | const getStatusText = (status) => { |
| | | const textMap = { |
| | | 'new': '新建', |
| | | 'tracking': '项目跟踪', |
| | | 'contract': '合同签约', |
| | | 'delivery': '项目交付', |
| | | 'acceptance': '项目验收' |
| | | } |
| | | return textMap[status] || '未知' |
| | | // 获取状态文本 |
| | | const getStatusText = (status) => { |
| | | const textMap = { |
| | | '新建': '新建', |
| | | '项目跟踪': '项目跟踪', |
| | | '合同签约': '合同签约', |
| | | '项目交付': '项目交付', |
| | | '项目验收': '项目验收' |
| | | } |
| | | return textMap[status] || '未知' |
| | | } |
| | | |
| | | // 格式化日期 |
| | |
| | | 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' |
| | |
| | | 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 |
| | | } |
| | | |
| | | // 编辑商机 |
| | |
| | | customerOption.value = res |
| | | }) |
| | | |
| | | // 使用updateTime作为录入时间反显 |
| | | // 使用当前账号和当天日期作为默认值 |
| | | Object.assign(form, row, { |
| | | entryDateStart: row.updateTime || row.entryDateStart |
| | | entryPerson: userStore.nickName, // 设置录入人为当前账号 |
| | | entryDate: dayjs().format('YYYY-MM-DD') // 设置录入时间为当天 |
| | | }) |
| | | dialogFormVisible.value = true |
| | | } |
| | |
| | | const submitForm = () => { |
| | | formRef.value.validate(valid => { |
| | | if (valid) { |
| | | const api = operationType.value === 'add' ? addOpportunity : updateOpportunity |
| | | // 收集附件文件的临时ID |
| | | let tempFileIds = [] |
| | | if (fileList.value !== null && fileList.value.length > 0) { |
| | | tempFileIds = fileList.value.map(item => item.tempId) |
| | | } |
| | | |
| | | api(form).then(res => { |
| | | 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(operationType.value === 'add' ? '新建成功' : '修改成功') |
| | | proxy.$modal.msgSuccess(successMessage) |
| | | closeDialog() |
| | | getList() |
| | | } else { |
| | |
| | | const resetForm = () => { |
| | | Object.assign(form, { |
| | | id: undefined, |
| | | status: 'new', |
| | | status: '新建', |
| | | province: '', |
| | | customerName: '', |
| | | businessSource: '', |
| | | description: '', |
| | | entryPerson: userStore.nickName, |
| | | entryDateStart: dayjs().format('YYYY-MM-DD') |
| | | entryDate: dayjs().format('YYYY-MM-DD') |
| | | }) |
| | | |
| | | if (formRef.value) { |
| | |
| | | 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(() => { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* 变更记录时间线样式 */ |
| | | .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> |