<template>
|
<view class="production-dispatching">
|
<!-- 使用通用页面头部组件 -->
|
<PageHeader title="生产派工" @back="goBack" />
|
|
<!-- 炒机状态展示 -->
|
<view class="machines-section">
|
<view class="section-title">炒机状态</view>
|
<view class="machines-grid">
|
<view v-for="machine in machines" :key="machine.id" class="machine-card">
|
<view class="machine-title">炒机{{ machine.id }}</view>
|
<view class="machine-metrics">
|
<view class="metric-item">
|
<text class="metric-label">总量(kg)</text>
|
<up-input
|
v-model="machineTotal[machine.key]"
|
type="number"
|
placeholder="请输入总量"
|
border="surround"
|
size="mini"
|
class="metric-input"
|
@change="updateMachineVacant(machine.key)"
|
/>
|
</view>
|
<view class="metric-item">
|
<text class="metric-label">正在生产(kg)</text>
|
<text class="metric-value">{{ machineInProduction[machine.key] }}</text>
|
</view>
|
<view class="metric-item">
|
<text class="metric-label">空余量(kg)</text>
|
<text class="metric-value">{{ machineVacant[machine.key] }}</text>
|
</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 class="search-section">
|
<view class="search-form">
|
<view class="search-item">
|
<text class="search-label">客户名称</text>
|
<up-input
|
v-model="searchForm.customerName"
|
placeholder="请输入客户名称"
|
@change="handleQuery"
|
clearable
|
border="surround"
|
class="search-input"
|
/>
|
</view>
|
<view class="search-item">
|
<text class="search-label">项目名称</text>
|
<up-input
|
v-model="searchForm.projectName"
|
placeholder="请输入项目名称"
|
@change="handleQuery"
|
clearable
|
border="surround"
|
class="search-input"
|
/>
|
</view>
|
<view class="search-buttons">
|
<up-button type="primary" @click="handleQuery" size="small" class="search-btn">搜索</up-button>
|
<up-button @click="handleReset" size="small" class="reset-btn">重置</up-button>
|
</view>
|
</view>
|
</view>
|
|
<!-- 批量操作区域 -->
|
<view class="batch-actions-section" v-if="showBatchActions">
|
<view class="batch-info">
|
<text class="batch-text">已选择 {{ selectedItems.length }} 个项目</text>
|
</view>
|
<view class="batch-buttons">
|
<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 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>
|
</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">
|
<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 class="item-header">
|
<view class="item-left">
|
<view class="document-icon">
|
<up-icon name="file-text" size="16" color="#ffffff"></up-icon>
|
</view>
|
<text class="item-id">{{ item.salesContractNo }}</text>
|
</view>
|
<text class="entry-date">{{ item.entryDate }}</text>
|
</view>
|
|
<view class="item-details">
|
<!-- <view class="detail-row">
|
<text class="detail-label">客户合同号</text>
|
<text class="detail-value">{{ item.customerContractNo }}</text>
|
</view> -->
|
<view class="detail-row">
|
<text class="detail-label">客户名称</text>
|
<text class="detail-value">{{ item.customerName }}</text>
|
</view>
|
<!-- <view class="detail-row">
|
<text class="detail-label">项目名称</text>
|
<text class="detail-value">{{ item.projectName }}</text>
|
</view> -->
|
<view class="detail-row">
|
<text class="detail-label">产品大类</text>
|
<text class="detail-value">{{ item.productCategory }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">规格型号</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-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">
|
<text class="detail-label">排产数量</text>
|
<text class="detail-value highlight">{{ item.schedulingNum }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">待排数量</text>
|
<text class="detail-value" :class="{ 'danger': item.pendingQuantity <= 0 }">{{ item.pendingQuantity }}</text>
|
</view>
|
|
<!-- 操作按钮区域 -->
|
<view class="action-buttons">
|
<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>
|
</view>
|
</view>
|
</view>
|
|
<view v-else class="no-data">
|
<up-empty mode="data" icon="http://cdn.uviewui.com/uview/empty/data.png">
|
<text class="no-data-text">暂无生产派工数据</text>
|
</up-empty>
|
</view>
|
|
<!-- 派工弹窗 -->
|
<DispatchModal ref="dispatchModalRef" @confirm="handleDispatchConfirm" />
|
|
<!-- 自动派单弹窗 -->
|
<AutoDispatchDia ref="autoDispatchDia" />
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
|
import { onShow } from '@dcloudio/uni-app';
|
import dayjs from "dayjs";
|
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 loading = ref(false);
|
|
// 列表数据
|
const tableData = ref([]);
|
|
// 选择相关数据
|
const selectedItems = ref([]);
|
const isAllSelected = ref(false);
|
const showBatchActions = ref(false);
|
|
// 搜索表单数据
|
const data = reactive({
|
searchForm: {
|
customerName: "",
|
projectName: "",
|
},
|
});
|
const { searchForm } = toRefs(data);
|
|
// 分页配置
|
const page = reactive({
|
current: 1,
|
size: 100,
|
total: 0,
|
});
|
|
// 炒机状态数据
|
const machineTotal = reactive({
|
m1: 0,
|
m2: 0,
|
m3: 0,
|
m4: 0,
|
})
|
|
const machineInProduction = reactive({
|
m1: 0,
|
m2: 0,
|
m3: 0,
|
m4: 0,
|
})
|
|
const machineVacant = reactive({
|
m1: 0,
|
m2: 0,
|
m3: 0,
|
m4: 0,
|
})
|
|
// 炒机配置数组
|
const machines = [
|
{ id: 1, key: 'm1' },
|
{ id: 2, key: 'm2' },
|
{ id: 3, key: 'm3' },
|
{ id: 4, key: 'm4' }
|
]
|
|
// 是否有查询数据(用于判断是新增还是修改)
|
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) => {
|
uni.showLoading({
|
title: message,
|
mask: true
|
});
|
};
|
|
const closeToast = () => {
|
uni.hideLoading();
|
};
|
|
// 返回上一页
|
const goBack = () => {
|
uni.navigateBack();
|
};
|
|
// 重置搜索
|
const handleReset = () => {
|
searchForm.value.customerName = "";
|
searchForm.value.projectName = "";
|
handleQuery();
|
};
|
|
// 查询列表
|
const handleQuery = () => {
|
page.current = 1;
|
getList();
|
};
|
|
// 获取炒机生产数据
|
const getMachineProductionData = () => {
|
schedulingList().then((res) => {
|
if (res.data && Array.isArray(res.data)) {
|
// 重置数据
|
machineInProduction.m1 = 0;
|
machineInProduction.m2 = 0;
|
machineInProduction.m3 = 0;
|
machineInProduction.m4 = 0;
|
|
// 处理炒机数据
|
res.data.forEach(item => {
|
const machineId = Number(item.id);
|
if (machineId >= 1 && machineId <= 4) {
|
const machineKey = `m${machineId}`;
|
|
if (item.workLoad !== null && item.workLoad !== undefined) {
|
machineTotal[machineKey] = Number(item.workLoad) || 0;
|
}
|
|
if (item.currentWorkLoad !== null && item.currentWorkLoad !== undefined) {
|
machineInProduction[machineKey] = Number(item.currentWorkLoad) || 0;
|
}
|
|
// 计算空余量
|
machineVacant[machineKey] = machineTotal[machineKey] - machineInProduction[machineKey];
|
}
|
});
|
}
|
}).catch(err => {
|
console.error('获取炒机数据失败:', err);
|
});
|
};
|
|
// 损耗率选择事件
|
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;
|
showLoadingToast('加载中...');
|
|
const params = { ...searchForm.value, ...page };
|
|
schedulingListPage(params).then((res) => {
|
loading.value = false;
|
closeToast();
|
|
tableData.value = (res.data.records || []).map(item => ({
|
...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;
|
closeToast();
|
uni.showToast({
|
title: '加载失败',
|
icon: 'error'
|
});
|
});
|
};
|
|
// 处理派工操作
|
const handleDispatch = (item) => {
|
if (item.pendingQuantity <= 0) {
|
uni.showToast({
|
title: '该项目无需再派工',
|
icon: 'none'
|
});
|
return;
|
}
|
|
if (!item.speculativeTradingName) {
|
uni.showToast({
|
title: '该项目未绑定机器,无法派工',
|
icon: 'none'
|
});
|
return;
|
}
|
|
dispatchModalRef.value?.open(item);
|
};
|
|
// 处理派工确认
|
const handleDispatchConfirm = () => {
|
getList(); // 刷新列表
|
};
|
|
// 更新炒机空余量
|
const updateMachineVacant = (machineKey) => {
|
machineVacant[machineKey] = (Number(machineTotal[machineKey]) || 0) - (Number(machineInProduction[machineKey]) || 0);
|
};
|
|
// 获取炒机查询数据
|
const getMachineQueryData = (machineId) => {
|
// 这里需要根据实际情况从查询数据中获取对应的炒机数据
|
// 暂时返回一个模拟数据
|
return {
|
id: machineId,
|
name: `炒机${machineId}`,
|
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;
|
});
|
};
|
|
// 保存炒机总量设置
|
const saveMachineTotals = () => {
|
// 构造保存数据数组,使用machines数组循环构建
|
const saveData = machines.map(machine => {
|
const machineData = {
|
name: `炒机${machine.id}`, // 炒机名称
|
workLoad: machineTotal[machine.key] || 0, // 总量
|
vacant: machineVacant[machine.key] || 0 // 空余量
|
};
|
|
// 如果是修改操作,需要传递id字段
|
if (hasQueryData.value) {
|
// 这里需要从查询数据中获取对应的id
|
// 假设查询数据中每个炒机数据都有id字段
|
const queryData = getMachineQueryData(machine.id);
|
if (queryData && queryData.id) {
|
machineData.id = queryData.id;
|
}
|
}
|
|
return machineData;
|
});
|
|
console.log('保存炒机设置数据:', saveData);
|
|
// 根据是否有查询数据决定调用新增接口还是修改接口
|
const saveApi = hasQueryData.value ? updateSpeculatTrading : addSpeculatTrading;
|
const successMessage = hasQueryData.value ? '炒机设置修改成功' : '炒机设置新增成功';
|
|
console.log(`调用接口: ${hasQueryData.value ? '修改' : '新增'}`);
|
|
// 先保存损耗率,再保存炒机设置
|
saveLossRate().then(() => {
|
// 调用后端API保存炒机设置
|
return saveApi(saveData);
|
}).then(res => {
|
uni.showToast({
|
title: successMessage,
|
icon: 'success'
|
});
|
console.log('保存成功:', res);
|
|
// 保存成功后,设置hasQueryData为true,下次保存将调用修改接口
|
if (!hasQueryData.value) {
|
hasQueryData.value = true;
|
}
|
}).catch(err => {
|
uni.showToast({
|
title: '保存失败',
|
icon: 'none'
|
});
|
console.error('保存失败:', err);
|
});
|
};
|
|
// 切换单个项目选择状态
|
const toggleItemSelection = (item, checked) => {
|
// 仅允许选择已绑定机器且待派数量>0的项目
|
if (!item.speculativeTradingName || item.pendingQuantity <= 0) return;
|
|
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 {
|
// 如果取消选中且在选中列表中,则移除
|
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 && item.speculativeTradingName).map(item => ({ ...item }));
|
}
|
isAllSelected.value = !isAllSelected.value;
|
updateBatchActionsVisibility();
|
};
|
|
// 更新全选状态
|
const updateAllSelectedStatus = () => {
|
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;
|
}
|
};
|
|
// 更新批量操作显示状态
|
const updateBatchActionsVisibility = () => {
|
showBatchActions.value = selectedItems.value.length > 0;
|
};
|
|
// 清空选择
|
const clearSelection = () => {
|
selectedItems.value = [];
|
isAllSelected.value = false;
|
showBatchActions.value = false;
|
};
|
|
// 获取选中的项目
|
const getSelectedItems = () => {
|
return selectedItems.value;
|
};
|
|
// 处理自动派单
|
const handleAutoDispatch = () => {
|
if (selectedItems.value.length === 0) {
|
uni.showToast({
|
title: '请选择要派工的项目',
|
icon: 'none'
|
});
|
return;
|
}
|
|
// 检查是否所有选中项目都有绑定机器
|
const unboundItems = selectedItems.value.filter(item => !item.speculativeTradingName);
|
if (unboundItems.length > 0) {
|
uni.showToast({
|
title: '所选项目中有未绑定机器的项目,无法自动派单',
|
icon: 'none'
|
});
|
return;
|
}
|
|
// 确保传递的是完整的选中项目数组
|
autoDispatchDia.value?.openDialog([...selectedItems.value]);
|
};
|
|
// 页面显示时加载数据
|
onShow(() => {
|
getList();
|
clearSelection();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
.production-dispatching {
|
min-height: 100vh;
|
background: #f8f9fa;
|
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;
|
}
|
|
.machines-section .section-title {
|
font-size: 32rpx;
|
font-weight: 600;
|
color: #303133;
|
margin-bottom: 20rpx;
|
}
|
|
.machines-grid {
|
display: grid;
|
grid-template-columns: 1fr 1fr;
|
gap: 20rpx;
|
}
|
|
.machine-card {
|
background: #ffffff;
|
border-radius: 16rpx;
|
padding: 24rpx;
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
border: 1rpx solid #e9ecef;
|
}
|
|
.machine-title {
|
font-size: 28rpx;
|
font-weight: 600;
|
color: #2c3e50;
|
text-align: center;
|
margin-bottom: 20rpx;
|
padding-bottom: 16rpx;
|
border-bottom: 2rpx solid #3498db;
|
}
|
|
.machine-metrics {
|
display: flex;
|
flex-direction: column;
|
gap: 16rpx;
|
}
|
|
.metric-item {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 8rpx 0;
|
}
|
|
.metric-label {
|
font-size: 24rpx;
|
color: #6c757d;
|
}
|
|
.metric-value {
|
font-size: 26rpx;
|
font-weight: 600;
|
color: #2c3e50;
|
}
|
|
// 输入框样式
|
.metric-input {
|
width: 120rpx;
|
text-align: right;
|
}
|
|
// 保存区域
|
.save-section {
|
display: flex;
|
justify-content: center;
|
margin-top: 30rpx;
|
padding-top: 20rpx;
|
border-top: 1rpx solid #e9ecef;
|
}
|
|
.save-btn {
|
min-width: 200rpx;
|
}
|
|
// 搜索区域
|
.search-section {
|
background: #ffffff;
|
border-radius: 16rpx;
|
padding: 24rpx;
|
margin-bottom: 30rpx;
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
}
|
|
.search-form {
|
display: flex;
|
flex-direction: column;
|
gap: 20rpx;
|
}
|
|
.search-item {
|
display: flex;
|
align-items: center;
|
gap: 20rpx;
|
}
|
|
.search-label {
|
font-size: 26rpx;
|
color: #606266;
|
min-width: 140rpx;
|
}
|
|
.search-input {
|
flex: 1;
|
}
|
|
.search-buttons {
|
display: flex;
|
gap: 20rpx;
|
justify-content: flex-end;
|
margin-top: 10rpx;
|
}
|
|
.search-btn, .reset-btn {
|
min-width: 120rpx;
|
}
|
|
// 列表样式
|
.ledger-list {
|
display: flex;
|
flex-direction: column;
|
gap: 24rpx;
|
}
|
|
.list-item {
|
background: #ffffff;
|
border-radius: 16rpx;
|
overflow: hidden;
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
}
|
|
.ledger-item {
|
padding: 0;
|
}
|
|
.item-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 24rpx 24rpx 0 24rpx;
|
}
|
|
.item-left {
|
display: flex;
|
align-items: center;
|
gap: 16rpx;
|
}
|
|
.document-icon {
|
width: 48rpx;
|
height: 48rpx;
|
background: #409eff;
|
border-radius: 8rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.item-id {
|
font-size: 28rpx;
|
font-weight: 600;
|
color: #303133;
|
}
|
|
.entry-date {
|
font-size: 24rpx;
|
color: #909399;
|
}
|
|
.item-details {
|
padding: 24rpx;
|
}
|
|
.detail-row {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 12rpx 0;
|
border-bottom: 1rpx solid #f5f5f5;
|
}
|
|
.detail-row:last-child {
|
border-bottom: none;
|
}
|
|
.detail-label {
|
font-size: 26rpx;
|
color: #606266;
|
}
|
|
.detail-value {
|
font-size: 26rpx;
|
color: #303133;
|
font-weight: 500;
|
}
|
|
.detail-value.highlight {
|
color: #ff6b35;
|
font-weight: 600;
|
}
|
|
.detail-value.danger {
|
color: #ee0a24;
|
font-weight: 600;
|
}
|
|
.action-buttons {
|
padding: 0 24rpx 24rpx 24rpx;
|
display: flex;
|
justify-content: flex-end;
|
}
|
|
.action-btn {
|
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;
|
text-align: center;
|
}
|
|
.no-data-text {
|
font-size: 28rpx;
|
color: #909399;
|
margin-top: 20rpx;
|
}
|
|
// 点击编辑区域样式
|
.metric-value-container {
|
cursor: pointer;
|
min-width: 120rpx;
|
text-align: right;
|
padding: 4rpx 8rpx;
|
border-radius: 4rpx;
|
transition: all 0.2s ease;
|
}
|
|
.metric-value-container:hover {
|
background-color: #f0f8ff;
|
border: 1rpx solid #409eff;
|
}
|
|
// 适配 uView 组件样式
|
:deep(.up-input) {
|
background: transparent;
|
}
|
|
:deep(.up-input__content) {
|
background: #f8f9fa;
|
}
|
</style>
|