<template>
|
<view class="page wide-layout" :class="{'has-overlay': (isShowUserSelect || isShow || barcodeIsShow)}">
|
<view class="status-section">
|
<!-- 报工记录表部分,在标题行添加刷新按钮 -->
|
<view class="report-table-wrapper">
|
<view class="report-header">
|
<view class="report-title">报工记录表</view>
|
<view class="header-buttons">
|
<button class="refresh-btn-header" @click="refresh">刷新</button>
|
<button v-if="isGeneratingBarcode" class="reset-btn-header" @click="resetGenerateState">重置</button>
|
</view>
|
</view>
|
|
<!-- 数采总产量 -->
|
<view class="section-title">当前数采产量报工记录</view>
|
<div class="table-scroll">
|
<table class="report-table">
|
<thead>
|
<tr>
|
<th>时间</th>
|
<th>报工人</th>
|
<th>工单号</th>
|
<th>产品名称</th>
|
<th>计划生产数</th>
|
<th>未报工数量</th>
|
<th>机台号</th>
|
<th>初始采集数</th>
|
<th>报工时采集数</th>
|
<th>基于数采的报工数</th>
|
<th>不良数</th>
|
<th>良品数(计算)</th>
|
<th>报工类型</th> <!-- 新增 -->
|
</tr>
|
</thead>
|
<tbody>
|
<tr class="summary-row highlight-row">
|
<td>{{ nowTime }}</td>
|
<td>{{ staffDisplay || '-' }}</td>
|
<td>{{ orderNo || '-' }}</td>
|
<td>{{ order.daa003 || '-' }}</td>
|
<td>{{ planQtyDisplay }}</td><!--计划生产数-->
|
<td>{{ order.daa008 - order.daa011 }}</td> <!-- 新增:未报工数量 -->
|
<td>{{ machineNo || '-' }}</td>
|
<td>{{ order.initCjNum }}</td>
|
<td>{{ order.currentCjNum }}</td>
|
<td>{{ order.currentCjNum - order.initCjNum }}</td>
|
<td>{{ realTimeDefectiveCount }}</td>
|
<td>{{ realTimeOkCount }}</td>
|
<td>
|
{{ order.daa018 === '开工' ? '生产报工' : '调机报工' }}
|
</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
|
<!-- 历史报工记录 -->
|
<view class="section-title history-title">历史报工记录</view>
|
<div class="table-scroll history-table-scroll">
|
<table class="report-table">
|
<thead>
|
<tr>
|
<th>时间</th>
|
<th>报工人</th>
|
<th>工单号</th>
|
<th>产品名称</th>
|
<th>计划生产数</th>
|
<th>机台号</th>
|
<th>初始采集数</th>
|
<th>报工时采集数</th>
|
<th>报工数(计算)</th>
|
<th>不良数</th>
|
<th>良品数(计算)</th>
|
<th>报工类型</th> <!-- 新增 -->
|
</tr>
|
</thead>
|
<tbody>
|
<tr v-for="(r, idx) in reportingHistory" :key="idx">
|
<td>{{ r.bgDate }}</td>
|
<td>{{ r.staff || '-' }}</td>
|
<td>{{ r.orderNo || '-' }}</td>
|
<td>{{ order.daa003 || '-' }}</td>
|
<td>{{ planQtyDisplay }}</td>
|
<td>{{ r.machineNo || '-' }}</td>
|
<td>{{ r.initialValue }}</td>
|
<td>{{ r.productionCount }}</td>
|
<td>{{ r.totalProduction }}</td>
|
<td>{{ r.BfQty }}</td>
|
<td>{{ r.OkQty }}</td>
|
<td>{{ r.reportType || '-' }}</td> <!-- 新增 -->
|
</tr>
|
<tr v-if="!reportingHistory.length">
|
<td colspan="12" class="no-data">暂无历史报工记录</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
</view>
|
|
<!-- 移除了原来的状态行中的按钮组 -->
|
<view class="status-row">
|
<!--<view class="status-box">
|
<text>机台面板数:</text>
|
<input v-model="productionCount" class="highlight" disabled />
|
</view>
|
<view class="status-box">
|
<text>当前采集数:</text>
|
<input v-model="calculatedCurrentCount" class="highlight" disabled />
|
</view>
|
<view class="operator-box">-</view>
|
<view class="status-box standalone-box">
|
<text>已打印条码数:</text>
|
<input v-model="sQuantity" class="highlight" disabled />
|
</view>
|
<view class="operator-box">=</view>
|
<view class="status-box">
|
<text>机采不良数:</text>
|
<input v-model="calculatedDefectiveCount" class="highlight" disabled />
|
</view>
|
<view class="status-box result-box">
|
<text>已生产数:</text>
|
<input v-model="calculatedTotalProduction" class="highlight" disabled />
|
</view>-->
|
</view>
|
|
<view class="flex-row gap-lg">
|
<!-- 当前报工人部分 -->
|
<view class="current-user-section">
|
<text>当前报工人:</text>
|
<text class="current-user-name">{{ staffDisplay || '未选择' }}</text>
|
<button class="select-user-btn" @click="isShowUserSelect = true">选人</button>
|
</view>
|
|
<!-- 不良数量部分 -->
|
<view class="defective-section">
|
<text>不良数量:</text>
|
<input v-model="customAmount" class="inp bad-input" placeholder="请输入数量" />
|
</view>
|
|
<!-- 确认提交和调机报工按钮 -->
|
<view class="submit-section">
|
<button class="details-btn" @click="confirmCustomAmount">确认提交</button>
|
<button class="details-btn" @click="confirmTiaojiBaogong">调机报工</button>
|
</view>
|
</view>
|
|
<!-- 选人弹窗 -->
|
<view v-if="isShowUserSelect" class="overlay">
|
<view class="popup user-select-popup">
|
<!-- 搜索栏 -->
|
<view class="user-search-bar">
|
<input v-model.trim="userSearch"
|
type="text"
|
class="user-search-input"
|
placeholder="输入工号或姓名搜索"
|
@keydown.enter.prevent />
|
<button v-if="userSearch" class="user-search-clear" @click="userSearch=''">清空</button>
|
<view class="user-search-info">
|
匹配:{{ filteredUsers.length }} / {{ users.length }}
|
</view>
|
</view>
|
<view class="user-list-scroll">
|
<template v-if="filteredUsers.length">
|
<view class="user-list-grid">
|
<button v-for="(u, index) in filteredUsers"
|
:key="index"
|
:class="['user-list-btn', {'selected': u===staffNo}]"
|
@click="selectUser(u)">
|
<span class="user-code">{{ u.split(':')[0] }}</span>
|
<span class="user-name">{{ u.split(':')[1] }}</span>
|
</button>
|
</view>
|
</template>
|
<view v-else class="no-user-result">
|
未找到匹配人员
|
</view>
|
</view>
|
<view class="user-popup-footer">
|
<button class="clean-btn wide-btn" @click="isShowUserSelect = false">关闭</button>
|
</view>
|
</view>
|
</view>
|
|
<!-- 禁用按钮:‘保存并生效'、‘取消’ -->
|
<!--<view class="bottom-section">
|
<button class="save-btn" @click="save">保存并生效</button>
|
<button class="cancel-btn" @click="cancel">取消</button>
|
</view>-->
|
<!-- 保留旧弹窗 -->
|
<view v-if="isShow" class="overlay">
|
<view class="popup">
|
<view class="bottom-section1">
|
<button class="clean-btn" type="warn" @click="deleteBarcode">关闭</button>
|
</view>
|
<view class="reason-section">
|
<text>报工人:</text>
|
<view class="reason-buttons">
|
<button v-for="(u,index) in users" :key="index"
|
:class="{'reason-btn':true,'selected': user===u}"
|
@click="toggleUser(u)">
|
{{ formatUser(u) }}
|
</button>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<view v-if="barcodeIsShow" class="overlay">
|
<view class="popup">
|
<uni-table ref="table" border stripe emptyText="暂无更多数据" class="table1">
|
<uni-tr>
|
<uni-th align="center" style="font-size:40px;">生成时间</uni-th>
|
<uni-th align="center" style="width:39%;font-size:40px;">条码</uni-th>
|
<uni-th align="center" style="font-size:40px;">报工人</uni-th>
|
<uni-th align="center" style="font-size:40px;">报工数量</uni-th>
|
</uni-tr>
|
<uni-tr v-for="(item,index) in reportingList" :key="index">
|
<uni-td align="center"><input type="text" v-model="item.bgDate" style="width:26vh;" /></uni-td>
|
<uni-td align="center"><input v-model="item.itemNoCade" style="width:40vh;" /></uni-td>
|
<uni-td align="center"><input v-model="item.staffName" /></uni-td>
|
<uni-td align="center"><input v-model="item.okQty" /></uni-td>
|
</uni-tr>
|
</uni-table>
|
<view><button class="clean-btn" type="warn" @click="barcodeIsShow=false">关闭</button></view>
|
</view>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
import { printTemplate3 } from "../utils/printTemplate";
|
|
export default {
|
props: { orderNo: String, orderId: Number, machineNo: String },
|
data() {
|
return {
|
isShowUserSelect: false,
|
currentUser: '',
|
barcodeAmount: '',
|
users: [], userForm: [], staff: [], user: {},
|
productionCount: 0, printedCount: 0, defectiveCount: 0, order: {},
|
icount: 1, bqty: 0, sQuantity: 0, kgQty: 0, initialValue: 0, qqty: 0,
|
ngStaid: 0, bufferData: '', dataToPrint: [], isLoading: false, but: false,
|
DAA003List: [], lineList: [], isShow: false, barcodeIsShow: false, barcodeList: [],
|
staffNo: '', printStr: '', printMac: '', bluetoothSocket: {}, device: '', uuid: '',
|
printNum: 1, reportingList: [], printLoading: false, customAmount: '',
|
isGeneratingBarcode: false, lastGenerateTime: 0, generateRequestId: null,
|
nowTimeTimer: null, nowTime: '',
|
userSearch: '',
|
refreshTimer: null, // 新增:自动刷新定时器
|
/* 新增:历史报工记录数组 */
|
reportingHistory: []
|
}
|
},
|
computed: {
|
//良品数实时计算
|
realTimeDefectiveCount() {
|
// 优先用输入框的值,否则用接口数据
|
const val = Number(this.customAmount);
|
if (!isNaN(val) && this.customAmount !== '') return val;
|
return this.calculatedDefectiveCount;
|
},
|
realTimeOkCount() {
|
// 良品数 = 报工数(计算) - 不良数
|
const total = (this.order.currentCjNum || 0) - (this.order.initCjNum || 0);
|
return total - this.realTimeDefectiveCount;
|
},
|
calculatedCurrentCount() { return (this.productionCount || 0) - (this.initialValue || 0); },
|
calculatedTotalProduction() { return (this.kgQty || 0); }, // 若需恢复旧逻辑可用 (this.kgQty||0)+this.calculatedCurrentCount
|
calculatedDefectiveCount() { return this.calculatedTotalProduction - (this.sQuantity || 0); },
|
planQtyDisplay() { return this.order.planQty || this.order.planQuantity || this.order.daa008 || 0; },
|
staffDisplay() {
|
if (!this.staffNo) return '';
|
const segs = this.staffNo.split(':');
|
return segs.length > 1 ? `${segs[0]} ${segs[1]}` : this.staffNo;
|
},
|
filteredUsers() {
|
if (!this.userSearch) return this.users;
|
const kw = this.userSearch.trim().toLowerCase();
|
return this.users.filter(u => u.toLowerCase().includes(kw));
|
}
|
},
|
created() {
|
this.initializeData();
|
this.fetchData(true);
|
this.init();
|
this.getXS0101();
|
this.updateNowTime();
|
// 秒级刷新;如不需动态跳秒可改为 60000
|
this.nowTimeTimer = setInterval(this.updateNowTime, 1000);
|
|
// 新增:每分钟自动刷新数据(60000毫秒 = 1分钟)
|
this.startAutoRefresh();
|
},
|
beforeDestroy() {
|
if (this.nowTimeTimer) clearInterval(this.nowTimeTimer);
|
// 新增:清理自动刷新定时器
|
this.stopAutoRefresh();
|
},
|
methods: {
|
// 新增:开始自动刷新
|
startAutoRefresh() {
|
// 先清除可能存在的旧定时器
|
this.stopAutoRefresh();
|
// 设置新的定时器,每分钟执行一次
|
this.refreshTimer = setInterval(() => {
|
console.log('自动刷新数据...');
|
this.refresh();
|
}, 60000); // 60000毫秒 = 1分钟
|
},
|
// 新增:停止自动刷新
|
stopAutoRefresh() {
|
if (this.refreshTimer) {
|
clearInterval(this.refreshTimer);
|
this.refreshTimer = null;
|
}
|
},
|
|
formatUser(u) {
|
if (!u) return '';
|
const segs = u.split(':');
|
return segs.length > 1 ? `${segs[0]} ${segs[1]}` : u;
|
},
|
selectUser(u) { this.staffNo = u; this.isShowUserSelect = false; this.userSearch = ''; },
|
/* 修改:增加秒 */
|
updateNowTime() {
|
const d = new Date(), p = n => n.toString().padStart(2, '0');
|
this.nowTime = `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
|
},
|
initializeData() {
|
this.productionCount = this.printedCount = this.defectiveCount = 0;
|
this.icount = 1; this.bqty = 0; this.sQuantity = 0; this.kgQty = 0;
|
this.initialValue = 0; this.qqty = 0;
|
this.isGeneratingBarcode = false; this.lastGenerateTime = 0; this.generateRequestId = null;
|
},
|
resetGenerateState() {
|
this.isGeneratingBarcode = false; this.generateRequestId = null; this.lastGenerateTime = 0;
|
this.$showMessage("已重置条码生成状态");
|
},
|
// 修改:在手动刷新时也重置自动刷新计时器
|
refresh() {
|
this.$sendPostRequest({
|
url: "http://192.168.0.94:9095/Numerical/RefreshDevBycl",
|
data: { machineNo: this.order.machineNo },
|
contentType: "application/json"
|
}).then(r => {
|
if (r.code == 200) {
|
this.fetchData(true);
|
this.$showMessage("数据刷新成功");
|
} else {
|
this.$showMessage("同步失败");
|
}
|
}).catch(error => {
|
console.error('刷新失败:', error);
|
this.$showMessage("刷新失败,请检查网络连接");
|
});
|
},
|
onDaa003Change(v) {
|
let o = this.lineList[this.DAA003List.indexOf(v)];
|
this.orderId = o.id; this.orderNo = o.daa001;
|
uni.setStorageSync('machine', this.machineNo);
|
uni.setStorageSync('orderId', this.orderId);
|
uni.setStorageSync('orderNo', this.orderNo);
|
this.fetchData(false);
|
},
|
fetchData(flag) {
|
if (!this.orderId && !this.orderNo) return;
|
this.getOrderById();
|
this.getWomdaaPrintById();
|
this.getReportingHistory(); // 新增:每次刷新同步历史
|
if (flag) {
|
this.$post({ url: "/Womdaa/GetWomdaasByShow", data: { machineNo: this.machineNo } })
|
.then(res => {
|
this.lineList = res.data.tbBillList;
|
this.DAA003List = res.data.tbBillList.map(i => i.daa003);
|
});
|
}
|
},
|
/* 新增:获取历史报工记录 */
|
/* 修改:规范历史时间到秒 */
|
getReportingHistory() {
|
if (!this.orderNo) { this.reportingHistory = []; return; }
|
const fmtSec = v => {
|
if (!v) return '';
|
// 兼容后端可能返回的不同格式
|
const d = new Date(typeof v === 'string' ? v.replace(/-/g, '/') : v);
|
if (isNaN(d.getTime())) return v; // 无法解析则原样返回
|
const p = n => n.toString().padStart(2, '0');
|
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
|
};
|
this.$post({
|
url: "/Womdaa/GetByBillNoBG",
|
data: { billNo: this.orderNo, machineNo: this.machineNo || null }
|
}).then(res => {
|
const list = res?.data?.tbBillList || res?.data || [];
|
this.reportingHistory = list.map(r => {
|
// 依据你数据库字段做映射(下面字段名按常见命名举例,需要按实际改)
|
return {
|
bgDate: r.bgDate || '', // 报工时间
|
staff: (r.staffNo ? (r.staffNo + ' ' + (r.staffName || '')) : (r.staffName || '')),//报工人
|
orderNo: r.billNo,//工单号
|
machineNo: r.machineNo,//机台号
|
initialValue: r.csQty ?? 0,//初始采集数
|
productionCount: r.cjQty ?? 0,//报工时采集数
|
totalProduction: (r.cjQty - r.csQty) ?? 0,//报工数(计算)
|
BfQty: r.bfQty,//不良数
|
OkQty: r.okQty,//良品数(计算)
|
reportType:r.remark //报工类型
|
}
|
});
|
}).catch(() => { this.reportingHistory = []; });
|
},
|
toggleUser(u) {
|
if (!u) return;
|
this.user = this.user === u ? null : u;
|
this.staffNo = this.user;
|
},
|
//选择报工人
|
confirmCustomAmount() {
|
if (!this.customAmount || isNaN(Number(this.customAmount))) { this.$showMessage('请输入有效的数量'); return; }
|
if (!this.staffNo) { this.$showMessage('请选择报工人'); return; }
|
const staffNo = this.staffNo.split(':')[0];
|
const amount = Number(this.customAmount);
|
this.$post({
|
url: "/MesInvItemBarcodes/AddBFToBarcodes",
|
data: {
|
orderNo: this.orderNo,
|
orderId: this.orderId,
|
bf: amount,
|
staffNo: staffNo,
|
initCjNum: this.order.initCjNum, // 初始采集数
|
currentCjNum: this.order.currentCjNum // 报工时采集数
|
}
|
}).then(res => {
|
if (res.status == 1) { this.$showMessage(res.message); return; }
|
this.$showMessage('报废数量填写成功');
|
this.fetchData(true); // 自动刷新历史
|
this.customAmount = '';
|
}).catch(() => this.$showMessage('报废数量填写失败,请重试'));
|
},
|
// 新增:调机报工
|
confirmTiaojiBaogong() {
|
if (!this.customAmount || isNaN(Number(this.customAmount))) { this.$showMessage('请输入有效的数量'); return; }
|
if (!this.staffNo) { this.$showMessage('请选择报工人'); return; }
|
const staffNo = this.staffNo.split(':')[0];
|
const amount = Number(this.customAmount);
|
this.$post({
|
url: "/MesInvItemBarcodes/AddBFToBarcodes", // 如有调机专用接口请替换
|
data: {
|
orderNo: this.orderNo,
|
orderId: this.orderId,
|
bf: amount,
|
staffNo: staffNo,
|
initCjNum: this.order.initCjNum,
|
currentCjNum: this.order.currentCjNum,
|
type: 'tiaoji' // 可加区分字段,后端如需区分调机报工
|
}
|
}).then(res => {
|
if (res.status == 1) { this.$showMessage(res.message); return; }
|
this.$showMessage('调机报工成功');
|
this.fetchData(true);
|
this.customAmount = '';
|
}).catch(() => this.$showMessage('调机报工失败,请重试'));
|
},
|
save() {
|
if (!this.staffNo) { this.$showMessage('请选择报工人'); return; }
|
uni.showToast({ title: '保存成功', icon: 'success' });
|
this.getReportingHistory(); // 保存后也可刷新
|
},
|
cancel() { uni.showToast({ title: '取消操作', icon: 'none' }); },
|
getOrderById() {
|
this.$post({ url: "/Womdaa/GetWomdaaById", data: { orderId: this.orderId, orderNo: this.orderNo } })
|
.then(res => {
|
this.order = res.data.tbBillList;
|
this.printedCount = res.data.tbBillList.bgqty || 0;
|
this.defectiveCount = res.data.tbBillList.blQty || 0;
|
this.productionCount = this.order.todayOutput || 0;
|
});
|
},
|
getXS0101() {
|
this.$post({ url: "/MesStaff/GetAllXS0101" })
|
.then(res => {
|
this.staff = res.data.tbBillList;
|
this.users = this.staff.map(s => s.staffNo + ":" + s.staffName);
|
});
|
},
|
getWomdaaPrintById() {
|
this.$post({ url: "/Womdaa/GetWomdaaPrintById", data: { orderId: this.orderId } })
|
.then(res => {
|
if (!res?.data?.tbBillList) return;
|
const d = res.data.tbBillList;
|
this.bqty = d.bqty;
|
this.icount = 1;
|
this.sQuantity = d.sQuantity || 0;
|
this.initialValue = d.initialValue || 0;
|
this.kgQty = d.kgQty || 0;
|
this.barcodeAmount = d.qqty || 0;
|
if (this.bqty === 0) this.Completed();
|
}).catch(() => { });
|
},
|
Completed() {
|
this.$post({ url: "/MesOrderSta/Completed", data: { orderId: this.orderId, orderNo: this.orderNo } });
|
},
|
init() {
|
try {
|
const v = this.getAndroidVersion();
|
v >= 12 ? this.initForAndroid12Plus() : this.initForAndroidLegacy();
|
} catch (e) { console.error(e); }
|
},
|
getAndroidVersion() {
|
try { var Build = plus.android.importClass("android.os.Build"); return Build.VERSION.SDK_INT; }
|
catch { return 30; }
|
},
|
initForAndroid12Plus() {
|
try {
|
var main = plus.android.runtimeMainActivity();
|
var BluetoothManager = plus.android.importClass("android.bluetooth.BluetoothManager");
|
var Context = plus.android.importClass("android.content.Context");
|
var UUID = plus.android.importClass("java.util.UUID");
|
this.uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
|
var mgr = main.getSystemService(Context.BLUETOOTH_SERVICE);
|
var adp = mgr.getAdapter();
|
if (adp && adp.isDiscovering()) adp.cancelDiscovery();
|
this.printMac = uni.getStorageSync('printMac');
|
var mac = this.printMac || "DC:1D:30:91:06:52";
|
if (adp) {
|
this.device = adp.getRemoteDevice(mac);
|
plus.android.importClass(this.device);
|
}
|
} catch (e) { this.initForAndroidLegacy(); }
|
},
|
initForAndroidLegacy() {
|
try {
|
var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
|
var UUID = plus.android.importClass("java.util.UUID");
|
this.uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
|
var BAdapter = BluetoothAdapter.getDefaultAdapter();
|
if (BAdapter) BAdapter.cancelDiscovery();
|
this.printMac = uni.getStorageSync('printMac');
|
var mac = this.printMac || "DC:1D:30:91:06:52";
|
if (BAdapter) {
|
this.device = BAdapter.getRemoteDevice(mac);
|
plus.android.importClass(this.device);
|
this.bluetoothSocket = this.device.createInsecureRfcommSocketToServiceRecord(this.uuid);
|
plus.android.importClass(this.bluetoothSocket);
|
}
|
} catch (e) { }
|
},
|
deleteBarcode() {
|
this.isShow = false;
|
this.isGeneratingBarcode = false;
|
this.generateRequestId = null;
|
this.bufferData = ''; this.dataToPrint = [];
|
this.staffNo = null; this.user = ''; this.barcodeAmount = ''; this.icount = 1; this.staff = null;
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.section-title {
|
font-size: 20px;
|
font-weight: bold;
|
margin: 18px 0 8px 0;
|
color: #fff;
|
background: #007aff;
|
padding: 8px 18px;
|
border-radius: 8px 8px 0 0;
|
display: inline-block;
|
}
|
|
.history-title {
|
background: #555;
|
}
|
|
.highlight-row {
|
background: #ffe9b3 !important;
|
font-weight: bold;
|
}
|
|
.report-table .summary-row {
|
background: #f0f8ff;
|
font-weight: 600;
|
}
|
|
.report-table .no-data {
|
text-align: center;
|
color: #777;
|
font-size: 14px;
|
}
|
|
.report-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 8px;
|
}
|
|
.header-buttons {
|
display: flex;
|
align-items: center;
|
gap: 12px;
|
}
|
|
.refresh-btn-header {
|
background: #00A2E9;
|
color: #fff;
|
border: none;
|
font-size: 16px;
|
border-radius: 8px;
|
padding: 8px 20px;
|
transition: background 0.15s;
|
}
|
|
.refresh-btn-header:hover {
|
background: #0086c0;
|
}
|
|
.reset-btn-header {
|
background: #ff6b6b;
|
color: #fff;
|
border: none;
|
font-size: 14px;
|
border-radius: 8px;
|
padding: 8px 16px;
|
transition: background 0.15s;
|
}
|
|
.reset-btn-header:hover {
|
background: #e94d4d;
|
}
|
|
.page {
|
padding: 1.2vh 2vw;
|
display: flex;
|
flex-direction: column;
|
box-sizing: border-box;
|
}
|
|
.wide-layout {
|
max-width: none;
|
width: 100%;
|
}
|
|
.page.has-overlay .status-section > :not(.overlay) {
|
pointer-events: none;
|
}
|
|
.page.has-overlay .status-section > .overlay {
|
pointer-events: auto;
|
}
|
|
.report-table-wrapper {
|
width: 100%;
|
max-width: none;
|
}
|
|
.table-scroll {
|
width: 100%;
|
overflow-x: scroll !important;
|
min-height: 40px;
|
}
|
|
.report-title {
|
font-size: 32px;
|
font-weight: 600;
|
text-align: center;
|
margin: 0;
|
}
|
|
/* 2. 区块标题 */
|
.section-title, .history-title {
|
font-size: 26px;
|
}
|
|
/* 3. 表格字体 */
|
.report-table, .report-table th, .report-table td {
|
font-size: 22px;
|
}
|
|
/* 4. 当前报工人、不良数量等输入区 */
|
.current-user-section,
|
.defective-section,
|
.submit-section {
|
font-size: 30px;
|
}
|
|
/* 5. 输入框字体 */
|
.inp, .bad-input {
|
font-size: 28px;
|
}
|
|
/* 6. 按钮字体 */
|
.details-btn,
|
.select-user-btn,
|
.refresh-btn-header,
|
.reset-btn-header {
|
font-size: 22px;
|
}
|
|
.report-table {
|
width: 100%;
|
min-width: 1800px;
|
border-collapse: collapse;
|
background: #fff;
|
}
|
|
.report-table th, .report-table td {
|
border: 1px solid #555;
|
padding: 6px 8px;
|
text-align: center;
|
white-space: normal; /*允许换行*/
|
word-break: break-all; /*长单词 /数字也换行*/
|
}
|
|
.status-section {
|
display: flex;
|
flex-direction: column;
|
gap: 10px;
|
}
|
|
.status-row {
|
display: flex;
|
flex-wrap: wrap;
|
align-items: center;
|
gap: 10px;
|
background: #f9f9f9;
|
padding: 10px 14px;
|
border-radius: 8px;
|
box-shadow: 0 1px 4px rgba(0,0,0,.06);
|
}
|
|
.status-box {
|
display: flex;
|
align-items: center;
|
}
|
|
.result-box {
|
background: #f0f8ff;
|
padding: 4px 12px;
|
border-radius: 6px;
|
border-left: 5px solid #007aff;
|
}
|
|
input.highlight {
|
width: 9vw;
|
min-width: 110px;
|
font-weight: 600;
|
border: none;
|
background: #fff;
|
text-align: center;
|
font-size: 18px;
|
padding: 6px 0;
|
border-radius: 6px;
|
box-shadow: inset 0 1px 3px rgba(0,0,0,.12);
|
}
|
|
.operator-box {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
font-size: 28px;
|
font-weight: bold;
|
color: #007aff;
|
margin: 0 6px;
|
}
|
|
.btn-group {
|
margin-left: auto;
|
display: flex;
|
align-items: center;
|
gap: 12px;
|
}
|
|
.refresh-btn-inline, .reset-btn-inline {
|
transition: .15s;
|
}
|
|
.refresh-btn-inline {
|
background: #00A2E9;
|
color: #fff;
|
font-size: 18px;
|
border-radius: 10px;
|
padding: 8px 30px;
|
border: none;
|
}
|
|
.refresh-btn-inline:hover {
|
background: #0086c0;
|
}
|
|
.reset-btn-inline {
|
background: #ff6b6b;
|
color: #fff;
|
font-size: 16px;
|
border-radius: 10px;
|
padding: 8px 18px;
|
border: none;
|
}
|
|
.reset-btn-inline:hover {
|
background: #e94d4d;
|
}
|
|
.flex-row {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 20px;
|
align-items: stretch;
|
}
|
|
.flex-grow {
|
flex: 1 1 540px;
|
}
|
|
.gap-lg {
|
gap: 30px;
|
}
|
|
/* 不良数量区域 */
|
.defective-section {
|
display: flex;
|
align-items: center;
|
gap: 14px;
|
font-size: 36px; /* 从32px改为36px */
|
font-weight: bold; /* 可选:加粗字体 */
|
}
|
|
.submit-section {
|
display: flex;
|
align-items: center;
|
}
|
|
.inp {
|
padding: 8px;
|
font-size: 16px;
|
border: 1px solid #808080;
|
border-radius: 8px;
|
box-sizing: border-box;
|
}
|
|
/* 不良数量输入框 */
|
.bad-input {
|
width: 320px;
|
max-width: 100%;
|
height: 66px;
|
border: 3px solid #808080;
|
font-size: 42px;
|
text-align: center;
|
}
|
|
/* 确认提交按钮*/
|
.details-btn {
|
padding: 12px 34px;
|
background: #00a2e9;
|
color: #fff;
|
font-size: 32px;
|
border: none;
|
cursor: pointer;
|
border-radius: 12px;
|
}
|
|
.details-btn:hover {
|
background: #008ac2;
|
}
|
|
.current-user-section {
|
display: flex;
|
align-items: center;
|
font-size: 32px;
|
border: 1.5px solid #f00;
|
border-radius: 10px;
|
padding: 14px 22px;
|
background: #fff;
|
gap: 14px;
|
flex: 0 0 auto;
|
}
|
|
.current-user-name {
|
font-weight: bold;
|
font-size: 32px;
|
}
|
|
/* 选人按钮 - 蓝色主题 */
|
.select-user-btn {
|
background: #00a2e9; /* 与提交按钮相同的蓝色 */
|
color: #fff; /* 白色文字 */
|
border: none; /* 移除边框 */
|
padding: 12px 22px; /* 调整内边距与提交按钮协调 */
|
border-radius: 12px; /* 与提交按钮相同的圆角 */
|
font-size: 32px; /* 保持字体大小 */
|
cursor: pointer;
|
transition: background 0.15s; /* 添加过渡效果 */
|
}
|
|
.select-user-btn:hover {
|
background: #008ac2;
|
}
|
|
.overlay {
|
position: fixed;
|
top: 0;
|
left: 0;
|
width: 100%;
|
height: 100%;
|
background: rgba(0,0,0,.45);
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
z-index: 1000;
|
}
|
|
.popup {
|
background: #fff;
|
padding: 2vh;
|
border: 1px solid #ccc;
|
box-shadow: 0 0 14px rgba(0,0,0,.12);
|
width: 72vw;
|
max-width: 1400px;
|
height: 70vh;
|
font-size: 1.4vw;
|
max-height: 80vh;
|
overflow-y: auto;
|
border-radius: 12px;
|
z-index: 1001;
|
}
|
|
/* 选人弹窗更宽,名字更大,关闭按钮更小 */
|
.user-select-popup {
|
width: 1600px;
|
max-width: 99vw;
|
min-width: 1000px;
|
height: auto;
|
min-height: 520px;
|
padding: 0;
|
display: flex;
|
flex-direction: column;
|
font-size: 32px;
|
}
|
|
.user-search-bar {
|
display: flex;
|
align-items: center;
|
gap: 18px;
|
padding: 24px 64px 0 64px;
|
background: #fff;
|
flex-wrap: wrap;
|
}
|
|
.user-search-input {
|
flex: 1 1 260px;
|
padding: 16px 20px;
|
font-size: 28px;
|
border: 1px solid #bbb;
|
border-radius: 8px;
|
outline: none;
|
height: 54px;
|
}
|
|
.user-search-input:focus {
|
border-color: #007aff;
|
box-shadow: 0 0 0 2px rgba(0,122,255,.15);
|
}
|
|
.user-search-clear {
|
padding: 12px 28px;
|
background: #ff9f43;
|
color: #fff;
|
border: none;
|
border-radius: 8px;
|
font-size: 24px;
|
cursor: pointer;
|
}
|
|
.user-search-clear:hover {
|
background: #ff8920;
|
}
|
|
.user-search-info {
|
font-size: 22px;
|
color: #555;
|
}
|
|
.user-list-scroll {
|
flex: 1 1 auto;
|
overflow-y: auto;
|
padding: 32px 64px 0 64px;
|
}
|
|
.user-list-grid {
|
display: grid;
|
grid-template-columns: repeat(auto-fill,minmax(200px,1fr));
|
gap: 22px 22px;
|
}
|
|
.user-list-btn {
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
align-items: center;
|
gap: 2px; /* 原8px,减小行间距 */
|
padding: 10px 10px; /* 适当减小上下内边距 */
|
height: 100px; /* 可适当减小高度 */
|
font-size: 30px;
|
background: #00a2e9;
|
color: #fff;
|
border: none;
|
border-radius: 8px;
|
cursor: pointer;
|
box-sizing: border-box;
|
word-break: break-word;
|
}
|
|
.user-list-btn .user-code {
|
font-weight: 700;
|
font-size: 36px;
|
line-height: 1.1; /* 紧凑一点 */
|
}
|
|
.user-list-btn .user-name {
|
font-size: 32px;
|
line-height: 1.1; /* 紧凑一点 */
|
}
|
|
.user-list-btn.selected {
|
background: #0072c9;
|
box-shadow: 0 0 0 3px rgba(255,255,255,.6) inset;
|
}
|
|
.user-list-btn:hover {
|
background: #008ed0;
|
}
|
|
.no-user-result {
|
padding: 40px 0;
|
text-align: center;
|
font-size: 28px;
|
color: #666;
|
}
|
|
.user-popup-footer {
|
flex-shrink: 0;
|
padding: 24px 64px 32px 64px;
|
background: #fff;
|
text-align: center;
|
}
|
|
.clean-btn {
|
width: 24%;
|
padding: 10px 0;
|
color: #fff;
|
font-size: 20px;
|
border: none;
|
text-align: center;
|
cursor: pointer;
|
border-radius: 0.6vw;
|
background: #007aff;
|
}
|
|
.clean-btn.wide-btn {
|
width: 30%;
|
font-size: 22px;
|
padding: 12px 0;
|
}
|
|
.clean-btn:hover {
|
background: #0062c9;
|
}
|
|
.reason-section {
|
margin: 14px 0 18px;
|
}
|
|
.reason-buttons {
|
display: grid;
|
grid-template-columns: repeat(5,1fr);
|
gap: 12px;
|
}
|
|
.reason-btn {
|
padding: 10px 6px;
|
background: #808080;
|
color: #fff;
|
font-size: 14px;
|
border: none;
|
border-radius: 8px;
|
cursor: pointer;
|
}
|
|
.reason-btn.selected {
|
background: #FFD700;
|
color: #000;
|
}
|
|
.bottom-section {
|
display: flex;
|
justify-content: space-between;
|
margin-top: 16px;
|
gap: 16px;
|
}
|
|
.save-btn, .cancel-btn {
|
flex: 1;
|
padding: 16px 0;
|
background: #00A2E9;
|
color: #fff;
|
font-size: 20px;
|
border: none;
|
border-radius: 10px;
|
}
|
|
.save-btn:hover, .cancel-btn:hover {
|
background: #0086c0;
|
}
|
|
.table1 {
|
width: 100%;
|
border-spacing: 3px;
|
}
|
|
/* 历史报工记录表头固定 */
|
.history-table-scroll thead tr th {
|
position: sticky;
|
top: 0;
|
z-index: 2;
|
background: #fff;
|
box-shadow: 0 2px 6px rgba(0,0,0,0.04);
|
}
|
|
@media (max-width:1400px) {
|
input.highlight {
|
font-size: 16px;
|
}
|
|
.user-list-btn {
|
height: 70px;
|
font-size: 18px;
|
}
|
|
.user-list-btn .user-code {
|
font-size: 18px;
|
}
|
|
.user-list-btn .user-name {
|
font-size: 16px;
|
}
|
|
.reason-btn {
|
font-size: 12px;
|
}
|
|
.refresh-btn-header {
|
font-size: 14px;
|
padding: 6px 16px;
|
}
|
|
.reset-btn-header {
|
font-size: 12px;
|
padding: 6px 12px;
|
}
|
}
|
</style>
|