| | |
| | | <el-table-column prop="salesperson" label="业务员" width="100" /> |
| | | <el-table-column prop="quotationDate" label="报价日期" width="120" /> |
| | | <el-table-column prop="validDate" label="有效期至" width="120" /> |
| | | <el-table-column prop="status" label="审批状态" width="120" align="center"> |
| | | <template #default="{ row }"> |
| | | <el-tag :type="getStatusType(row.status)" disable-transitions> |
| | | {{ row.status || '--' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="totalAmount" label="报价金额" width="120"> |
| | | <template #default="scope"> |
| | | ¥{{ scope.row.totalAmount.toFixed(2) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="250" fixed="right" align="center"> |
| | | <el-table-column label="操作" width="200" fixed="right" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="handleView(scope.row)">查看</el-button> |
| | | <el-button link type="primary" @click="handleEdit(scope.row)" v-if="scope.row.status === '草稿'">编辑</el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)" v-if="scope.row.status === '草稿'">删除</el-button> |
| | | <el-button link type="primary" @click="handleEdit(scope.row)" :disabled="!['待审批','拒绝'].includes(scope.row.status)">编辑</el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | </el-card> |
| | | |
| | | <!-- 新增/编辑对话框 --> |
| | | <FormDialog v-model="dialogVisible" :title="dialogTitle" width="80%" :close-on-click-modal="false" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="100px"> |
| | | <FormDialog v-model="dialogVisible" :title="dialogTitle" width="85%" :close-on-click-modal="false" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false"> |
| | | <div class="quotation-form-container"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="quotation-form"> |
| | | <!-- 基本信息 --> |
| | | <el-card class="form-card" shadow="never"> |
| | | <el-card class="form-card" shadow="hover"> |
| | | <template #header> |
| | | <span class="card-title">基本信息</span> |
| | | <div class="card-header-wrapper"> |
| | | <el-icon class="card-icon"><Document /></el-icon> |
| | | <span class="card-title">基本信息</span> |
| | | </div> |
| | | </template> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客户名称" prop="customer"> |
| | | <el-select v-model="form.customer" placeholder="请选择客户" style="width: 100%" @change="handleCustomerChange"> |
| | | <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.customerName"> |
| | | {{ |
| | | item.customerName + "——" + item.taxpayerIdentificationNumber |
| | | }} |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="业务员" prop="salesperson"> |
| | | <el-select v-model="form.salesperson" placeholder="请选择业务员" style="width: 100%"> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" |
| | | :value="item.nickName" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="报价日期" prop="quotationDate"> |
| | | <el-date-picker |
| | | v-model="form.quotationDate" |
| | | type="date" |
| | | placeholder="选择报价日期" |
| | | style="width: 100%" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="有效期至" prop="validDate"> |
| | | <el-date-picker |
| | | v-model="form.validDate" |
| | | type="date" |
| | | placeholder="选择有效期" |
| | | style="width: 100%" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="付款方式" prop="paymentMethod"> |
| | | <el-select v-model="form.paymentMethod" placeholder="请选择付款方式" style="width: 100%"> |
| | | <el-option label="全款到付" value="全款到付"></el-option> |
| | | <el-option label="分期付款" value="分期付款"></el-option> |
| | | <el-option label="月结" value="月结"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-content"> |
| | | <el-row :gutter="24"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客户名称" prop="customer"> |
| | | <el-select v-model="form.customer" placeholder="请选择客户" style="width: 100%" @change="handleCustomerChange" clearable> |
| | | <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.customerName"> |
| | | {{ |
| | | item.customerName + "——" + item.taxpayerIdentificationNumber |
| | | }} |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="业务员" prop="salesperson"> |
| | | <el-select v-model="form.salesperson" placeholder="请选择业务员" style="width: 100%" clearable> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" |
| | | :value="item.nickName" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="24"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="报价日期" prop="quotationDate"> |
| | | <el-date-picker |
| | | v-model="form.quotationDate" |
| | | type="date" |
| | | placeholder="选择报价日期" |
| | | style="width: 100%" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="有效期至" prop="validDate"> |
| | | <el-date-picker |
| | | v-model="form.validDate" |
| | | type="date" |
| | | placeholder="选择有效期" |
| | | style="width: 100%" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="24"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="付款方式" prop="paymentMethod"> |
| | | <el-input v-model="form.paymentMethod" placeholder="请输入付款方式" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- 审批人信息 --> |
| | | <el-card class="form-card" shadow="hover"> |
| | | <template #header> |
| | | <div class="card-header-wrapper"> |
| | | <el-icon class="card-icon"><UserFilled /></el-icon> |
| | | <span class="card-title">审批人选择</span> |
| | | <el-button type="primary" size="small" @click="addApproverNode" class="header-btn"> |
| | | <el-icon><Plus /></el-icon> |
| | | 新增节点 |
| | | </el-button> |
| | | </div> |
| | | </template> |
| | | <div class="form-content"> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item> |
| | | <div class="approver-nodes-container"> |
| | | <div |
| | | v-for="(node, index) in approverNodes" |
| | | :key="node.id" |
| | | class="approver-node-item" |
| | | > |
| | | <div class="approver-node-label"> |
| | | <span class="node-step">{{ index + 1 }}</span> |
| | | <span class="node-text">审批人</span> |
| | | <el-icon class="arrow-icon"><ArrowRight /></el-icon> |
| | | </div> |
| | | <el-select |
| | | v-model="node.userId" |
| | | placeholder="选择人员" |
| | | class="approver-select" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="user in userList" |
| | | :key="user.userId" |
| | | :label="user.nickName" |
| | | :value="user.userId" |
| | | /> |
| | | </el-select> |
| | | <el-button |
| | | type="danger" |
| | | size="small" |
| | | :icon="Delete" |
| | | @click="removeApproverNode(index)" |
| | | v-if="approverNodes.length > 1" |
| | | class="remove-btn" |
| | | >删除</el-button> |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- 产品信息 --> |
| | | <el-card class="form-card" shadow="never"> |
| | | <el-card class="form-card" shadow="hover"> |
| | | <template #header> |
| | | <div class="card-header"> |
| | | <div class="card-header-wrapper"> |
| | | <el-icon class="card-icon"><Box /></el-icon> |
| | | <span class="card-title">产品信息</span> |
| | | <el-button type="primary" size="small" @click="addProduct">添加产品</el-button> |
| | | <el-button type="primary" size="small" @click="addProduct" class="header-btn"> |
| | | <el-icon><Plus /></el-icon> |
| | | 添加产品 |
| | | </el-button> |
| | | </div> |
| | | </template> |
| | | <el-table :data="form.products" border style="width: 100%"> |
| | | <div class="form-content"> |
| | | <el-table :data="form.products" border style="width: 100%" class="product-table" v-if="form.products.length > 0"> |
| | | <el-table-column prop="product" label="产品名称" width="200"> |
| | | <template #default="scope"> |
| | | <el-tree-select |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-empty v-else description="暂无产品,请点击添加产品" :image-size="80" /> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- 备注信息 --> |
| | | <el-card class="form-card" shadow="never"> |
| | | <el-card class="form-card" shadow="hover"> |
| | | <template #header> |
| | | <span class="card-title">备注信息</span> |
| | | <div class="card-header-wrapper"> |
| | | <el-icon class="card-icon"><EditPen /></el-icon> |
| | | <span class="card-title">备注信息</span> |
| | | </div> |
| | | </template> |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input type="textarea" v-model="form.remark" placeholder="请输入备注信息" rows="3"></el-input> |
| | | </el-form-item> |
| | | <div class="form-content"> |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input |
| | | type="textarea" |
| | | v-model="form.remark" |
| | | placeholder="请输入备注信息(选填)" |
| | | :rows="4" |
| | | maxlength="500" |
| | | show-word-limit |
| | | ></el-input> |
| | | </el-form-item> |
| | | </div> |
| | | </el-card> |
| | | </el-form> |
| | | </div> |
| | | </FormDialog> |
| | | |
| | | <!-- 查看详情对话框 --> |
| | |
| | | <script setup> |
| | | import { ref, reactive, computed, onMounted, markRaw, shallowRef } from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { Search } from '@element-plus/icons-vue' |
| | | import { Search, Document, UserFilled, Box, EditPen, Plus, ArrowRight, Delete } from '@element-plus/icons-vue' |
| | | import Pagination from '@/components/PIMTable/Pagination.vue' |
| | | import FormDialog from '@/components/Dialog/FormDialog.vue' |
| | | import {getQuotationList,addQuotation,updateQuotation,deleteQuotation} from '@/api/salesManagement/salesQuotation.js' |
| | |
| | | salesperson: [{ required: true, message: '请选择业务员', trigger: 'change' }], |
| | | quotationDate: [{ required: true, message: '请选择报价日期', trigger: 'change' }], |
| | | validDate: [{ required: true, message: '请选择有效期', trigger: 'change' }], |
| | | paymentMethod: [{ required: true, message: '请选择付款方式', trigger: 'change' }] |
| | | paymentMethod: [{ required: true, message: '请输入付款方式', trigger: 'blur' }] |
| | | } |
| | | const userList = ref([]); |
| | | const customerOption = ref([]); |
| | | |
| | | // 审批人节点相关 |
| | | const approverNodes = ref([ |
| | | { id: 1, userId: null } |
| | | ]) |
| | | let nextApproverId = 2 |
| | | |
| | | const isEdit = ref(false) |
| | | const editId = ref(null) |
| | | const currentQuotation = ref({}) |
| | | const formRef = ref() |
| | | |
| | | // 添加审批人节点 |
| | | function addApproverNode() { |
| | | approverNodes.value.push({ id: nextApproverId++, userId: null }) |
| | | } |
| | | |
| | | // 删除审批人节点 |
| | | function removeApproverNode(index) { |
| | | approverNodes.value.splice(index, 1) |
| | | } |
| | | |
| | | // 计算属性 |
| | | const filteredList = computed(() => { |
| | |
| | | // 方法 |
| | | const getStatusType = (status) => { |
| | | const statusMap = { |
| | | '草稿': 'info', |
| | | '已发送': 'primary', |
| | | '客户确认': 'success', |
| | | '已过期': 'danger' |
| | | '待审批': 'info', |
| | | '审核中': 'primary', |
| | | '通过': 'success', |
| | | '拒绝': 'danger' |
| | | } |
| | | return statusMap[status] || 'info' |
| | | } |
| | |
| | | dialogTitle.value = '新增报价' |
| | | isEdit.value = false |
| | | resetForm() |
| | | // 重置审批人节点 |
| | | approverNodes.value = [{ id: 1, userId: null }] |
| | | nextApproverId = 2 |
| | | dialogVisible.value = true |
| | | let userLists = await userListNoPage(); |
| | | // 只复制需要的字段,避免将组件引用放入响应式对象 |
| | |
| | | }); |
| | | } |
| | | const getProductOptions = () => { |
| | | productTreeList().then((res) => { |
| | | // 返回 Promise,便于编辑时 await 确保能反显 |
| | | return productTreeList().then((res) => { |
| | | productOptions.value = convertIdToValue(res); |
| | | return productOptions.value |
| | | }); |
| | | }; |
| | | function convertIdToValue(data) { |
| | |
| | | |
| | | return newItem; |
| | | }); |
| | | } |
| | | // 根据名称反查节点 id,便于仅存名称时的反显 |
| | | function findNodeIdByLabel(nodes, label) { |
| | | if (!label) return null; |
| | | for (let i = 0; i < nodes.length; i++) { |
| | | const node = nodes[i]; |
| | | if (node.label === label) return node.value; |
| | | if (node.children && node.children.length > 0) { |
| | | const found = findNodeIdByLabel(node.children, label); |
| | | if (found !== null && found !== undefined) return found; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | const getModels = (value, row) => { |
| | | if (!row) return; |
| | |
| | | viewDialogVisible.value = true |
| | | } |
| | | |
| | | const handleEdit = (row) => { |
| | | const handleEdit = async (row) => { |
| | | dialogTitle.value = '编辑报价' |
| | | isEdit.value = true |
| | | editId.value = row.id |
| | | form.id = row.id || form.id || null |
| | | // 先加载产品树数据,否则 el-tree-select 无法反显产品名称 |
| | | await getProductOptions() |
| | | |
| | | // 只复制需要的字段,避免将组件引用放入响应式对象 |
| | | form.quotationNo = row.quotationNo || '' |
| | | form.customer = row.customer || '' |
| | |
| | | form.paymentMethod = row.paymentMethod || '' |
| | | form.status = row.status || '草稿' |
| | | form.remark = row.remark || '' |
| | | form.products = row.products ? row.products.map(product => ({ |
| | | productId: product.productId || '', |
| | | product: product.product || product.productName || '', |
| | | specificationId: product.specificationId || '', |
| | | specification: product.specification || '', |
| | | quantity: product.quantity || 0, |
| | | unit: product.unit || '', |
| | | unitPrice: product.unitPrice || 0, |
| | | amount: product.amount || 0 |
| | | })) : [] |
| | | form.products = row.products ? row.products.map(product => { |
| | | const productName = product.product || product.productName || '' |
| | | // 优先用 productId;如果只有名称,尝试反查 id 以便树选择器反显 |
| | | const resolvedId = product.productId |
| | | ? Number(product.productId) |
| | | : findNodeIdByLabel(productOptions.value, productName) || '' |
| | | return { |
| | | productId: resolvedId, |
| | | product: productName, |
| | | specificationId: product.specificationId || '', |
| | | specification: product.specification || '', |
| | | quantity: product.quantity || 0, |
| | | unit: product.unit || '', |
| | | unitPrice: product.unitPrice || 0, |
| | | amount: product.amount || 0 |
| | | } |
| | | }) : [] |
| | | form.subtotal = row.subtotal || 0 |
| | | form.freight = row.freight || 0 |
| | | form.otherFee = row.otherFee || 0 |
| | | form.discountRate = row.discountRate || 0 |
| | | form.discountAmount = row.discountAmount || 0 |
| | | form.totalAmount = row.totalAmount || 0 |
| | | |
| | | // 反显审批人 |
| | | if (row.approveUserIds) { |
| | | const userIds = row.approveUserIds.split(',') |
| | | approverNodes.value = userIds.map((userId, idx) => ({ |
| | | id: idx + 1, |
| | | userId: parseInt(userId.trim()) |
| | | })) |
| | | nextApproverId = userIds.length + 1 |
| | | } else { |
| | | approverNodes.value = [{ id: 1, userId: null }] |
| | | nextApproverId = 2 |
| | | } |
| | | |
| | | // 加载用户列表 |
| | | let userLists = await userListNoPage(); |
| | | userList.value = (userLists.data || []).map(item => ({ |
| | | userId: item.userId, |
| | | nickName: item.nickName || '', |
| | | userName: item.userName || '' |
| | | })); |
| | | |
| | | dialogVisible.value = true |
| | | } |
| | | |
| | |
| | | return |
| | | } |
| | | |
| | | // 审批人必填校验 |
| | | const hasEmptyApprover = approverNodes.value.some(node => !node.userId) |
| | | if (hasEmptyApprover) { |
| | | ElMessage.error('请为所有审批节点选择审批人!') |
| | | return |
| | | } |
| | | |
| | | // 收集所有节点的审批人id |
| | | form.approveUserIds = approverNodes.value.map(node => node.userId).join(',') |
| | | |
| | | // 计算所有产品的单价总和 |
| | | form.totalAmount = form.products.reduce((sum, product) => { |
| | | const price = Number(product.unitPrice) || 0 |
| | | return sum + price |
| | | }, 0) |
| | | |
| | | if (isEdit.value) { |
| | | // 编辑 |
| | | const index = quotationList.value.findIndex(item => item.id === editId.value) |
| | |
| | | handleSearch() |
| | | } |
| | | }) |
| | | // quotationList.value[index] = { ...form, id: editId.value } |
| | | // ElMessage.success('编辑成功') |
| | | } |
| | | } else { |
| | | // 新增 |
| | | // const newId = Math.max(...quotationList.value.map(item => item.id)) + 1 |
| | | form.quotationNo = `QT${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(new Date().getDate()).padStart(2, '0')}` |
| | | |
| | | addQuotation(form).then(res=>{ |
| | | // console.log(res) |
| | | if(res.code===200){ |
| | | ElMessage.success('新增成功') |
| | | dialogVisible.value = false |
| | | handleSearch() |
| | | } |
| | | }) |
| | | |
| | | // quotationList.value.push({ |
| | | // ...form, |
| | | // // id: newId, |
| | | // quotationNo: quotationNo |
| | | // }) |
| | | // pagination.total++ |
| | | // ElMessage.success('新增成功') |
| | | } |
| | | |
| | | } |
| | |
| | | } |
| | | const handleSearch = ()=>{ |
| | | const params = { |
| | | page:pagination, |
| | | ...pagination, |
| | | ...searchForm |
| | | } |
| | | getQuotationList(params).then(res=>{ |
| | |
| | | validDate: item.validDate || '', |
| | | paymentMethod: item.paymentMethod || '', |
| | | status: item.status || '草稿', |
| | | // 审批人(用于编辑时反显) |
| | | approveUserIds: item.approveUserIds || '', |
| | | remark: item.remark || '', |
| | | products: item.products ? item.products.map(product => ({ |
| | | productId: product.productId || '', |
| | |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | <style scoped lang="scss"> |
| | | .search-row { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .quotation-form-container { |
| | | padding: 10px 0; |
| | | max-height: calc(100vh - 200px); |
| | | overflow-y: auto; |
| | | |
| | | &::-webkit-scrollbar { |
| | | width: 6px; |
| | | height: 6px; |
| | | } |
| | | |
| | | &::-webkit-scrollbar-thumb { |
| | | background: #c1c1c1; |
| | | border-radius: 3px; |
| | | |
| | | &:hover { |
| | | background: #a8a8a8; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .quotation-form { |
| | | .el-form-item { |
| | | margin-bottom: 22px; |
| | | } |
| | | } |
| | | |
| | | .form-card { |
| | | margin-bottom: 20px; |
| | | margin-bottom: 24px; |
| | | border-radius: 8px; |
| | | transition: all 0.3s ease; |
| | | |
| | | &:hover { |
| | | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08) !important; |
| | | } |
| | | |
| | | :deep(.el-card__header) { |
| | | padding: 16px 20px; |
| | | background: linear-gradient(135deg, #f5f7fa 0%, #ffffff 100%); |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | :deep(.el-card__body) { |
| | | padding: 20px; |
| | | } |
| | | } |
| | | |
| | | .card-title { |
| | | font-weight: bold; |
| | | color: #303133; |
| | | } |
| | | |
| | | .card-header { |
| | | .card-header-wrapper { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | gap: 8px; |
| | | |
| | | .card-icon { |
| | | font-size: 18px; |
| | | color: #409eff; |
| | | } |
| | | |
| | | .card-title { |
| | | font-weight: 600; |
| | | font-size: 16px; |
| | | color: #303133; |
| | | flex: 1; |
| | | } |
| | | |
| | | .header-btn { |
| | | margin-left: auto; |
| | | } |
| | | } |
| | | |
| | | .form-content { |
| | | padding: 8px 0; |
| | | } |
| | | |
| | | .approver-nodes-container { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 24px; |
| | | padding: 12px 0; |
| | | } |
| | | |
| | | .approver-node-item { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | gap: 12px; |
| | | padding: 16px; |
| | | background: #f8f9fa; |
| | | border-radius: 8px; |
| | | border: 1px solid #e4e7ed; |
| | | transition: all 0.3s ease; |
| | | min-width: 180px; |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background: #f0f7ff; |
| | | box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1); |
| | | } |
| | | } |
| | | |
| | | .approver-node-label { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | font-size: 14px; |
| | | color: #606266; |
| | | |
| | | .node-step { |
| | | display: inline-flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 24px; |
| | | height: 24px; |
| | | background: #409eff; |
| | | color: #fff; |
| | | border-radius: 50%; |
| | | font-size: 12px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .node-text { |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .arrow-icon { |
| | | color: #909399; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | |
| | | .approver-select { |
| | | width: 100%; |
| | | min-width: 150px; |
| | | } |
| | | |
| | | .remove-btn { |
| | | margin-top: 4px; |
| | | } |
| | | |
| | | .product-table { |
| | | :deep(.el-table__header) { |
| | | background-color: #f5f7fa; |
| | | |
| | | th { |
| | | background-color: #f5f7fa !important; |
| | | color: #606266; |
| | | font-weight: 600; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-table__row) { |
| | | &:hover { |
| | | background-color: #f5f7fa; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-table__cell) { |
| | | padding: 12px 0; |
| | | } |
| | | } |
| | | |
| | | .dialog-footer { |
| | | text-align: right; |
| | | } |
| | | |
| | | // 响应式优化 |
| | | @media (max-width: 1200px) { |
| | | .approver-nodes-container { |
| | | gap: 16px; |
| | | } |
| | | |
| | | .approver-node-item { |
| | | min-width: 160px; |
| | | } |
| | | } |
| | | </style> |