| | |
| | | <view class="production-dispatching"> |
| | | <!-- 使用通用页面头部组件 --> |
| | | <PageHeader title="生产派工" @back="goBack" /> |
| | | |
| | | |
| | | <!-- 炒机状态展示 --> |
| | | <view class="machines-section"> |
| | | <view class="section-title">炒机状态</view> |
| | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <!-- 损耗率设置 --> |
| | | <view class="loss-rate-section"> |
| | | <view class="section-title">损耗率设置</view> |
| | | <view class="loss-rate-content"> |
| | | <view class="loss-rate-item"> |
| | | <up-button |
| | | class="loss-rate-btn" |
| | | type="primary" |
| | | plain |
| | | size="small" |
| | | @click="showLossRateSheet = true" |
| | | >{{ lossRate ? `损耗率: ${lossRate}%` : '请选择损耗率' }}</up-button> |
| | | <up-action-sheet |
| | | :show="showLossRateSheet" |
| | | :actions="lossRateOptions" |
| | | @select="onLossRateSelect" |
| | | title="选择损耗率" |
| | | @close="showLossRateSheet = false" |
| | | /> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view class="save-section"> |
| | | <up-button type="primary" @click="saveMachineTotals" size="normal" class="save-btn">保存炒机设置</up-button> |
| | | </view> |
| | |
| | | </view> |
| | | |
| | | <!-- 批量操作区域 --> |
| | | <view v-if="showBatchActions" class="batch-actions-section"> |
| | | <view class="batch-actions-section" v-if="showBatchActions"> |
| | | <view class="batch-info"> |
| | | <text class="batch-count">已选择 {{ selectedItems.length }} 个项目</text> |
| | | <text class="batch-text">已选择 {{ selectedItems.length }} 个项目</text> |
| | | </view> |
| | | <view class="batch-buttons"> |
| | | <up-button type="primary" size="small" @click="handleAutoDispatch" class="batch-btn"> |
| | | <up-icon name="play-circle" size="16" color="#ffffff"></up-icon> |
| | | 自动派单 |
| | | </up-button> |
| | | <up-button type="default" size="small" @click="clearSelection" class="batch-btn"> |
| | | <up-icon name="close-circle" size="16" color="#6c757d"></up-icon> |
| | | 取消选择 |
| | | </up-button> |
| | | <up-button type="primary" size="small" @click="handleAutoDispatch" class="batch-btn">自动派单</up-button> |
| | | <up-button type="default" size="small" @click="clearSelection" class="batch-btn">取消选择</up-button> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <!-- 全选操作区域 --> |
| | | <view v-if="tableData.length > 0" class="select-all-section"> |
| | | <view class="select-all-checkbox" @click="toggleAllSelection"> |
| | | <up-icon |
| | | :name="isAllSelected ? 'checkbox-mark' : 'circle'" |
| | | :color="isAllSelected ? '#409eff' : '#c0c4cc'" |
| | | size="18" |
| | | ></up-icon> |
| | | <text class="select-all-text">{{ isAllSelected ? '取消全选' : '全选' }}</text> |
| | | <view class="select-all-section" v-if="tableData.length > 0"> |
| | | <view class="select-all-content"> |
| | | <up-checkbox |
| | | v-model="isAllSelected" |
| | | @change="toggleAllSelection" |
| | | label="全选" |
| | | class="select-all-checkbox" |
| | | :disabled="tableData.length === 0 || tableData.filter(item => item.pendingQuantity > 0 && item.speculativeTradingName).length === 0" |
| | | /> |
| | | </view> |
| | | <text class="select-all-hint">(仅选择待排数量大于0的项目)</text> |
| | | </view> |
| | | |
| | | |
| | | <!-- 生产派工列表 --> |
| | | <view class="ledger-list" v-if="tableData.length > 0"> |
| | | <view v-for="(item, index) in tableData" :key="item.id || index" class="list-item"> |
| | | <view class="ledger-item"> |
| | | <!-- 选择复选框 --> |
| | | <view class="item-checkbox" @click="toggleItemSelection(item)"> |
| | | <up-icon |
| | | :name="selectedItems.includes(item.id) ? 'checkbox-mark' : 'circle'" |
| | | :color="selectedItems.includes(item.id) ? '#409eff' : '#c0c4cc'" |
| | | size="18" |
| | | ></up-icon> |
| | | <view class="item-checkbox"> |
| | | <up-checkbox |
| | | :model-value="selectedItems.some(selected => selected.id === item.id)" |
| | | @change="(checked) => toggleItemSelection(item, checked)" |
| | | :disabled="item.pendingQuantity <= 0 || !item.speculativeTradingName" |
| | | shape="circle" |
| | | /> |
| | | </view> |
| | | |
| | | <view class="item-content"> |
| | |
| | | </view> |
| | | |
| | | <view class="item-details"> |
| | | <view class="detail-row"> |
| | | <!-- <view class="detail-row"> |
| | | <text class="detail-label">客户合同号</text> |
| | | <text class="detail-value">{{ item.customerContractNo }}</text> |
| | | </view> |
| | | </view> --> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">客户名称</text> |
| | | <text class="detail-value">{{ item.customerName }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <!-- <view class="detail-row"> |
| | | <text class="detail-label">项目名称</text> |
| | | <text class="detail-value">{{ item.projectName }}</text> |
| | | </view> |
| | | </view> --> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">产品大类</text> |
| | | <text class="detail-value">{{ item.productCategory }}</text> |
| | |
| | | <text class="detail-value">{{ item.specificationModel }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">绑定机器</text> |
| | | <text class="detail-value">{{ item.speculativeTradingName }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">单位</text> |
| | | <text class="detail-value">{{ item.unit }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">总数量</text> |
| | | <text class="detail-label">录入日期</text> |
| | | <text class="detail-value">{{ item.entryDate }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">数量</text> |
| | | <text class="detail-value">{{ item.quantity }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | |
| | | <!-- 操作按钮区域 --> |
| | | <view class="action-buttons"> |
| | | <up-button |
| | | type="primary" |
| | | size="small" |
| | | @click="handleDispatch(item)" |
| | | class="action-btn" |
| | | :disabled="item.pendingQuantity <= 0" |
| | | > |
| | | {{ item.pendingQuantity <= 0 ? '无需派工' : '生产派工' }} |
| | | </up-button> |
| | | type="primary" |
| | | size="small" |
| | | @click="handleDispatch(item)" |
| | | class="action-btn" |
| | | :disabled="item.pendingQuantity <= 0 || !item.speculativeTradingName" |
| | | > |
| | | {{ item.pendingQuantity <= 0 ? '无需派工' : !item.speculativeTradingName ? '未绑定机器' : '生产派工' }} |
| | | </up-button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | |
| | | <!-- 派工弹窗 --> |
| | | <DispatchModal ref="dispatchModalRef" @confirm="handleDispatchConfirm" /> |
| | | |
| | | <!-- 自动派单弹窗 --> |
| | | <AutoDispatchDia ref="autoDispatchDia" /> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, toRefs, getCurrentInstance } from "vue"; |
| | | import { ref, reactive, toRefs, getCurrentInstance, nextTick } from "vue"; |
| | | import { onShow } from '@dcloudio/uni-app'; |
| | | import dayjs from "dayjs"; |
| | | import {schedulingListPage, schedulingList, addSpeculatTrading, updateSpeculatTrading} from "@/api/productionManagement/productionOrder.js"; |
| | | import {schedulingListPage, schedulingList, addSpeculatTrading, updateSpeculatTrading, getLossRate, addLossRate, updateLossRate} from "@/api/productionManagement/productionOrder.js"; |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | import DispatchModal from "./components/DispatchModal.vue"; |
| | | import AutoDispatchDia from "./components/autoDispatchDia.vue"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | |
| | | // 列表数据 |
| | | const tableData = ref([]); |
| | | |
| | | // 批量选择相关数据 |
| | | const selectedItems = ref([]); // 选中的项目ID数组 |
| | | const isAllSelected = ref(false); // 是否全选 |
| | | const showBatchActions = ref(false); // 是否显示批量操作区域 |
| | | // 选择相关数据 |
| | | const selectedItems = ref([]); |
| | | const isAllSelected = ref(false); |
| | | const showBatchActions = ref(false); |
| | | |
| | | // 搜索表单数据 |
| | | const data = reactive({ |
| | |
| | | // 是否有查询数据(用于判断是新增还是修改) |
| | | const hasQueryData = ref(false); |
| | | |
| | | // 损耗率相关数据 |
| | | const lossRate = ref(""); // 当前选择的损耗率 |
| | | const showLossRateSheet = ref(false); // 控制损耗率选择面板显示 |
| | | const lossRateOptions = ref([ |
| | | { name: "6%", value: "6" }, |
| | | { name: "7%", value: "7" }, |
| | | { name: "8%", value: "8" }, |
| | | { name: "9%", value: "9" }, |
| | | { name: "10%", value: "10" } |
| | | ]); |
| | | const lossRateData = ref(null); // 损耗率查询返回的数据 |
| | | |
| | | // 派工弹窗引用 |
| | | const dispatchModalRef = ref(); |
| | | |
| | | // 自动派单弹窗引用 |
| | | const autoDispatchDia = ref(); |
| | | |
| | | // 通用提示函数 |
| | | const showLoadingToast = (message) => { |
| | |
| | | }); |
| | | }; |
| | | |
| | | // 损耗率选择事件 |
| | | const onLossRateSelect = (action) => { |
| | | lossRate.value = action.value; |
| | | showLossRateSheet.value = false; |
| | | console.log('选择了损耗率:', action.name, '值:', action.value); |
| | | }; |
| | | |
| | | // 获取损耗率数据 |
| | | const getLossRateData = () => { |
| | | getLossRate().then((res) => { |
| | | if (res.data) { |
| | | lossRateData.value = res.data; |
| | | // 设置当前选择的损耗率 |
| | | if (res.data.rate !== null && res.data.rate !== undefined) { |
| | | lossRate.value = res.data.rate.toString(); |
| | | } |
| | | } |
| | | }).catch(err => { |
| | | console.error('获取损耗率失败:', err); |
| | | }); |
| | | }; |
| | | |
| | | // 获取列表数据 |
| | | const getList = () => { |
| | | loading.value = true; |
| | |
| | | closeToast(); |
| | | |
| | | tableData.value = (res.data.records || []).map(item => ({ |
| | | ...item, |
| | | pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0) |
| | | })); |
| | | ...item, |
| | | pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0) |
| | | })).filter(item => item.pendingQuantity > 0); |
| | | |
| | | page.total = res.data.total || 0; |
| | | |
| | | // 获取炒机数据 |
| | | getMachineProductionData(); |
| | | |
| | | // 获取损耗率数据 |
| | | getLossRateData(); |
| | | |
| | | }).catch(() => { |
| | | loading.value = false; |
| | |
| | | if (item.pendingQuantity <= 0) { |
| | | uni.showToast({ |
| | | title: '该项目无需再派工', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | if (!item.speculativeTradingName) { |
| | | uni.showToast({ |
| | | title: '该项目未绑定机器,无法派工', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | |
| | | workLoad: machineTotal[`m${machineId}`] || 0, |
| | | currentWorkLoad: machineInProduction[`m${machineId}`] || 0 |
| | | }; |
| | | }; |
| | | |
| | | // 保存损耗率设置 |
| | | const saveLossRate = () => { |
| | | if (!lossRate.value) { |
| | | console.log('未选择损耗率,跳过保存'); |
| | | return Promise.resolve(); |
| | | } |
| | | |
| | | const lossRateDataToSave = { |
| | | rate: parseFloat(lossRate.value) || 0 |
| | | }; |
| | | |
| | | // 如果有查询到的损耗率数据,说明是修改操作,需要传递id |
| | | if (lossRateData.value && lossRateData.value.id) { |
| | | lossRateDataToSave.id = lossRateData.value.id; |
| | | } |
| | | |
| | | console.log('保存损耗率数据:', lossRateDataToSave); |
| | | |
| | | // 根据是否有损耗率数据决定调用新增接口还是修改接口 |
| | | const saveLossApi = lossRateData.value && lossRateData.value.id ? updateLossRate : addLossRate; |
| | | const successMessage = lossRateData.value && lossRateData.value.id ? '损耗率修改成功' : '损耗率新增成功'; |
| | | |
| | | return saveLossApi(lossRateDataToSave).then(res => { |
| | | console.log('损耗率保存成功:', res); |
| | | uni.showToast({ |
| | | title: successMessage, |
| | | icon: 'success' |
| | | }); |
| | | |
| | | // 更新损耗率数据 |
| | | if (res.data) { |
| | | lossRateData.value = res.data; |
| | | } |
| | | |
| | | return res; |
| | | }).catch(err => { |
| | | console.error('损耗率保存失败:', err); |
| | | uni.showToast({ |
| | | title: '损耗率保存失败', |
| | | icon: 'none' |
| | | }); |
| | | throw err; |
| | | }); |
| | | }; |
| | | |
| | | // 保存炒机总量设置 |
| | |
| | | |
| | | console.log(`调用接口: ${hasQueryData.value ? '修改' : '新增'}`); |
| | | |
| | | // 调用后端API保存 |
| | | saveApi(saveData).then(res => { |
| | | proxy.$message.success(successMessage); |
| | | // 先保存损耗率,再保存炒机设置 |
| | | saveLossRate().then(() => { |
| | | // 调用后端API保存炒机设置 |
| | | return saveApi(saveData); |
| | | }).then(res => { |
| | | uni.showToast({ |
| | | title: successMessage, |
| | | icon: 'success' |
| | | }); |
| | | console.log('保存成功:', res); |
| | | |
| | | // 保存成功后,设置hasQueryData为true,下次保存将调用修改接口 |
| | |
| | | hasQueryData.value = true; |
| | | } |
| | | }).catch(err => { |
| | | proxy.$message.error('保存失败'); |
| | | uni.showToast({ |
| | | title: '保存失败', |
| | | icon: 'none' |
| | | }); |
| | | console.error('保存失败:', err); |
| | | }); |
| | | }; |
| | | |
| | | // 批量选择相关函数 |
| | | |
| | | // 切换单个项目的选择状态 |
| | | const toggleItemSelection = (item) => { |
| | | const itemId = item.id; |
| | | const index = selectedItems.value.indexOf(itemId); |
| | | // 切换单个项目选择状态 |
| | | const toggleItemSelection = (item, checked) => { |
| | | // 仅允许选择已绑定机器且待派数量>0的项目 |
| | | if (!item.speculativeTradingName || item.pendingQuantity <= 0) return; |
| | | |
| | | if (index > -1) { |
| | | // 如果已选中,则取消选择 |
| | | selectedItems.value.splice(index, 1); |
| | | console.log('切换选择状态:', item.id, checked); |
| | | |
| | | // 使用更严格的比较逻辑,确保ID唯一性 |
| | | const index = selectedItems.value.findIndex(selected => { |
| | | // 深度比较对象,确保是同一个项目 |
| | | return JSON.stringify(selected) === JSON.stringify(item); |
| | | }); |
| | | |
| | | if (checked) { |
| | | // 如果选中且不在选中列表中,则添加 |
| | | if (index === -1) { |
| | | selectedItems.value.push({...item}); // 创建新对象,避免引用问题 |
| | | console.log('添加项目后选中数量:', selectedItems.value.length); |
| | | } |
| | | } else { |
| | | // 如果未选中,则添加选择 |
| | | selectedItems.value.push(itemId); |
| | | // 如果取消选中且在选中列表中,则移除 |
| | | if (index > -1) { |
| | | selectedItems.value.splice(index, 1); |
| | | console.log('移除项目后选中数量:', selectedItems.value.length); |
| | | } |
| | | } |
| | | |
| | | // 更新全选状态 |
| | | console.log('当前选中项目列表:', selectedItems.value.map(s => s.id)); |
| | | updateAllSelectedStatus(); |
| | | // 更新批量操作区域显示状态 |
| | | updateBatchActionsVisibility(); |
| | | }; |
| | | |
| | | // 切换全选状态 |
| | | const toggleAllSelection = () => { |
| | | if (isAllSelected.value) { |
| | | // 取消全选 |
| | | selectedItems.value = []; |
| | | } else { |
| | | // 全选 |
| | | selectedItems.value = tableData.value |
| | | .filter(item => item.pendingQuantity > 0) // 只选择待排数量大于0的项目 |
| | | .map(item => item.id); |
| | | selectedItems.value = tableData.value.filter(item => item.pendingQuantity > 0 && item.speculativeTradingName).map(item => ({ ...item })); |
| | | } |
| | | |
| | | isAllSelected.value = !isAllSelected.value; |
| | | updateBatchActionsVisibility(); |
| | | }; |
| | | |
| | | // 更新全选状态 |
| | | const updateAllSelectedStatus = () => { |
| | | const selectableItems = tableData.value.filter(item => item.pendingQuantity > 0); |
| | | if (selectableItems.length === 0) { |
| | | const selectableItems = tableData.value.filter(item => item.pendingQuantity > 0 && item.speculativeTradingName); |
| | | if (selectableItems.length > 0 && selectedItems.value.length === selectableItems.length && |
| | | selectableItems.every(item => selectedItems.value.some(selected => selected.id === item.id))) { |
| | | isAllSelected.value = true; |
| | | } else { |
| | | isAllSelected.value = false; |
| | | return; |
| | | } |
| | | |
| | | isAllSelected.value = selectedItems.value.length === selectableItems.length && |
| | | selectableItems.every(item => selectedItems.value.includes(item.id)); |
| | | }; |
| | | |
| | | // 更新批量操作区域显示状态 |
| | | // 更新批量操作显示状态 |
| | | const updateBatchActionsVisibility = () => { |
| | | showBatchActions.value = selectedItems.value.length > 0; |
| | | }; |
| | |
| | | |
| | | // 获取选中的项目 |
| | | const getSelectedItems = () => { |
| | | return tableData.value.filter(item => selectedItems.value.includes(item.id)); |
| | | return selectedItems.value; |
| | | }; |
| | | |
| | | // 自动派单功能 |
| | | // 处理自动派单 |
| | | const handleAutoDispatch = () => { |
| | | const selectedItemsList = getSelectedItems(); |
| | | |
| | | if (selectedItemsList.length === 0) { |
| | | if (selectedItems.value.length === 0) { |
| | | uni.showToast({ |
| | | title: '请先选择要派工的项目', |
| | | title: '请选择要派工的项目', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 检查是否有项目待排数量不足 |
| | | const invalidItems = selectedItemsList.filter(item => item.pendingQuantity <= 0); |
| | | if (invalidItems.length > 0) { |
| | | // 检查是否所有选中项目都有绑定机器 |
| | | const unboundItems = selectedItems.value.filter(item => !item.speculativeTradingName); |
| | | if (unboundItems.length > 0) { |
| | | uni.showToast({ |
| | | title: `有${invalidItems.length}个项目无需派工,已自动过滤`, |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | |
| | | // 过滤掉待排数量不足的项目 |
| | | const validItems = selectedItemsList.filter(item => item.pendingQuantity > 0); |
| | | |
| | | if (validItems.length === 0) { |
| | | uni.showToast({ |
| | | title: '没有可派工的项目', |
| | | title: '所选项目中有未绑定机器的项目,无法自动派单', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | uni.showModal({ |
| | | title: '确认自动派单', |
| | | content: `确定要对选中的${validItems.length}个项目进行自动派单吗?`, |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | executeAutoDispatch(validItems); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 执行自动派单 |
| | | const executeAutoDispatch = (items) => { |
| | | showLoadingToast('自动派单中...'); |
| | | |
| | | // 模拟自动派单过程 |
| | | setTimeout(() => { |
| | | closeToast(); |
| | | |
| | | // 这里应该调用实际的自动派单API |
| | | // 暂时使用模拟成功 |
| | | uni.showToast({ |
| | | title: `成功为${items.length}个项目完成自动派单`, |
| | | icon: 'success' |
| | | }); |
| | | |
| | | // 清空选择 |
| | | clearSelection(); |
| | | // 刷新列表 |
| | | getList(); |
| | | |
| | | console.log('自动派单项目:', items); |
| | | }, 1500); |
| | | // 确保传递的是完整的选中项目数组 |
| | | autoDispatchDia.value?.openDialog([...selectedItems.value]); |
| | | }; |
| | | |
| | | // 页面显示时加载数据 |
| | | onShow(() => { |
| | | getList(); |
| | | // 清空选择状态 |
| | | clearSelection(); |
| | | }); |
| | | </script> |
| | |
| | | padding: 20rpx; |
| | | } |
| | | |
| | | // 损耗率设置区域 |
| | | .loss-rate-section { |
| | | background: #ffffff; |
| | | border: 1rpx solid #e4e7ed; |
| | | border-radius: 12rpx; |
| | | padding: 32rpx; |
| | | margin-top: 24rpx; |
| | | margin-bottom: 32rpx; |
| | | box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08); |
| | | } |
| | | |
| | | .loss-rate-section .section-title { |
| | | font-size: 32rpx; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | .loss-rate-section .loss-rate-content { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 24rpx; |
| | | } |
| | | |
| | | .loss-rate-section .loss-rate-content .loss-rate-item { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 24rpx; |
| | | } |
| | | |
| | | .loss-rate-section .loss-rate-content .loss-rate-label { |
| | | font-size: 30rpx; |
| | | font-weight: 500; |
| | | color: #303133; |
| | | min-width: 140rpx; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .loss-rate-section .loss-rate-content .loss-rate-btn { |
| | | min-width: 260rpx; |
| | | font-size: 28rpx; |
| | | height: 64rpx; |
| | | line-height: 64rpx; |
| | | border-radius: 8rpx; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | // 炒机状态区域 |
| | | .machines-section { |
| | | margin-bottom: 30rpx; |
| | | |
| | | .section-title { |
| | | font-size: 32rpx; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | } |
| | | |
| | | .machines-section .section-title { |
| | | font-size: 32rpx; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | .machines-grid { |
| | |
| | | align-items: center; |
| | | padding: 12rpx 0; |
| | | border-bottom: 1rpx solid #f5f5f5; |
| | | |
| | | &:last-child { |
| | | border-bottom: none; |
| | | } |
| | | } |
| | | |
| | | .detail-row:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | .detail-label { |
| | |
| | | font-size: 26rpx; |
| | | color: #303133; |
| | | font-weight: 500; |
| | | |
| | | &.highlight { |
| | | color: #ff6b35; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | &.danger { |
| | | color: #ee0a24; |
| | | font-weight: 600; |
| | | } |
| | | } |
| | | |
| | | .detail-value.highlight { |
| | | color: #ff6b35; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .detail-value.danger { |
| | | color: #ee0a24; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .action-buttons { |
| | |
| | | min-width: 180rpx; |
| | | } |
| | | |
| | | // 批量操作区域样式 |
| | | .batch-actions-section { |
| | | background: #e8f4ff; |
| | | border: 1rpx solid #409eff; |
| | | border-radius: 12rpx; |
| | | padding: 20rpx 24rpx; |
| | | margin-bottom: 24rpx; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | |
| | | .batch-actions-section .batch-text { |
| | | font-size: 28rpx; |
| | | font-weight: 600; |
| | | color: #409eff; |
| | | } |
| | | |
| | | .batch-actions-section .batch-buttons { |
| | | display: flex; |
| | | gap: 16rpx; |
| | | } |
| | | |
| | | .batch-actions-section .batch-btn { |
| | | min-width: 140rpx; |
| | | } |
| | | |
| | | // 全选操作区域样式 |
| | | .select-all-section { |
| | | background: #ffffff; |
| | | border-radius: 12rpx; |
| | | padding: 20rpx 24rpx; |
| | | margin-bottom: 16rpx; |
| | | border: 1rpx solid #e4e7ed; |
| | | } |
| | | |
| | | .select-all-section .select-all-content { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .select-all-section .select-all-checkbox { |
| | | font-size: 28rpx; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | // 列表项选择框样式 |
| | | .ledger-item { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | padding: 0; |
| | | } |
| | | |
| | | .item-checkbox { |
| | | padding: 24rpx 16rpx 0 24rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .item-content { |
| | | flex: 1; |
| | | } |
| | | |
| | | // 空状态 |
| | | .no-data { |
| | | padding: 100rpx 0; |
| | |
| | | font-size: 28rpx; |
| | | color: #909399; |
| | | margin-top: 20rpx; |
| | | } |
| | | |
| | | // 批量操作区域样式 |
| | | .batch-actions-section { |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | border-radius: 16rpx; |
| | | padding: 24rpx; |
| | | margin-bottom: 24rpx; |
| | | box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.3); |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .batch-info { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | .batch-count { |
| | | font-size: 28rpx; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .batch-buttons { |
| | | display: flex; |
| | | gap: 20rpx; |
| | | justify-content: flex-end; |
| | | } |
| | | |
| | | .batch-btn { |
| | | min-width: 180rpx; |
| | | } |
| | | |
| | | // 全选操作区域样式 |
| | | .select-all-section { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | background: #f8f9fa; |
| | | border-radius: 12rpx; |
| | | padding: 20rpx 24rpx; |
| | | margin-bottom: 20rpx; |
| | | border: 1rpx solid #e9ecef; |
| | | } |
| | | |
| | | .select-all-checkbox { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 12rpx; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .select-all-text { |
| | | font-size: 26rpx; |
| | | color: #606266; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .select-all-hint { |
| | | font-size: 22rpx; |
| | | color: #909399; |
| | | } |
| | | |
| | | // 列表项选择样式 |
| | | .ledger-item { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | padding: 0; |
| | | } |
| | | |
| | | .item-checkbox { |
| | | padding: 24rpx 16rpx 0 24rpx; |
| | | cursor: pointer; |
| | | display: flex; |
| | | align-items: center; |
| | | min-height: 48rpx; |
| | | } |
| | | |
| | | .item-content { |
| | | flex: 1; |
| | | padding: 0; |
| | | } |
| | | |
| | | // 点击编辑区域样式 |