1343 lines
30 KiB
Vue
1343 lines
30 KiB
Vue
<template>
|
||||
|
|
<view class="entry-page multi-machine-page" :class="`theme-${themeMode}`">
|
|||
|
|
<view class="hero-card">
|
|||
|
|
<view>
|
|||
|
|
<text class="hero-title">一单多机</text>
|
|||
|
|
<text class="hero-subtitle">按订单录入本次数量,提交后进入数量分摊流程</text>
|
|||
|
|
</view>
|
|||
|
|
<view class="hero-icon"><u-icon name="grid-fill" color="#ffffff" size="46" /></view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="config-card">
|
|||
|
|
<view class="card-title">当前配置</view>
|
|||
|
|
<view class="chip-row">
|
|||
|
|
<view class="select-chip" @tap="showPicker('process')"><text class="chip-label">工序</text><text class="chip-value">{{ processLabel }}</text></view>
|
|||
|
|
<view class="select-chip" @tap="showPicker('step')"><text class="chip-label">步骤</text><text class="chip-value">{{ stepLabel }}</text></view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="form-card">
|
|||
|
|
<view class="form-title-row"><view><text class="card-title">扫码录入</text><text class="card-subtitle">一个订单一次录入本次完成数量</text></view><view class="progress-badge">本次录入</view></view>
|
|||
|
|
<view class="field-card primary-field"><view class="field-main"><text class="field-label">订单号</text><u-input v-model="form.orderNo" :input-mode="pdaMode ? 'none' : 'text'" clearable placeholder="请扫描或输入订单号" placeholder-style="color: #a0a7b5;" @focus="handleOrderInputFocus" /></view><view class="scan-button" @tap="scanOrder"><u-icon name="scan" color="#ffffff" size="36" /></view></view>
|
|||
|
|
<view class="quantity-card">
|
|||
|
|
<view class="quantity-heading"><view><text class="field-label">本次数量</text><text class="quantity-tip">请输入本次需要分摊的数量</text></view><text class="quantity-unit">台</text></view>
|
|||
|
|
<view class="quantity-control"><view class="qty-button" @tap="decreaseQuantity">-</view><input v-model="form.quantity" class="qty-input" type="number" /><view class="qty-button" @tap="increaseQuantity">+</view></view>
|
|||
|
|
</view>
|
|||
|
|
<view class="quantity-preview"><text>提交数量</text><text class="quantity-preview-value">{{ quantity }} 台</text></view>
|
|||
|
|
<view class="action-row"><view class="submit-secondary" @tap="resetForm">重置</view><view class="submit-primary" :class="{ 'is-loading': submitting }" @tap="submitForm">{{ submitting ? '提交中...' : '提交录入' }}</view></view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="stats-card"><view class="stats-header"><view><text class="card-title">今日统计</text><text class="card-subtitle">当前工序/步骤本次录入量</text></view><view class="total-badge">{{ submittedTotal }}</view></view><view class="stats-grid"><view class="stat-item"><text class="stat-value success">{{ statistics.successTotal }}</text><text class="stat-label">成功</text></view><view class="stat-item"><text class="stat-value danger">{{ statistics.failedTotal }}</text><text class="stat-label">失败</text></view><view class="stat-item"><text class="stat-value">{{ submittedTotal }}</text><text class="stat-label">总数</text></view></view></view>
|
|||
|
|
<view class="record-card"><view class="card-title">最近记录</view><view v-for="record in recentRecords" :key="record.id" class="record-item"><view><text class="record-main">{{ record.orderNo }}</text><text class="record-sub">本次数量:{{ record.quantity }} 台</text></view><view class="record-status">成功</view></view><view v-if="!recentRecords.length" class="empty-record">暂无录入记录</view></view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
// UTS 原生扫码插件仅在 App-Plus 真机/自定义基座中解析,Web 环境不加载。
|
|||
|
|
// #ifdef APP-PLUS
|
|||
|
|
import { openCodeScan } from '@/uni_modules/mas-code-scan'
|
|||
|
|
// #endif
|
|||
|
|
|
|||
|
|
import { getDataEntryConfig, getOrderRecentRecords, getOrderStatistics, getProcessOptions, getStepOptions, submitOrderRecord } from '@/api/produce/data-entry.js'
|
|||
|
|
import { getScanRegionSetting } from '@/utils/scan-settings.js'
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
submitting: false,
|
|||
|
|
scanning: false,
|
|||
|
|
pdaMode: false,
|
|||
|
|
currentUser: {
|
|||
|
|
userCode: 'U001'
|
|||
|
|
},
|
|||
|
|
basicSettings: {},
|
|||
|
|
specificRules: [],
|
|||
|
|
processOptions: [],
|
|||
|
|
stepOptions: [],
|
|||
|
|
selectedProcessIndex: 0,
|
|||
|
|
selectedStepIndex: 0,
|
|||
|
|
form: {
|
|||
|
|
orderNo: '',
|
|||
|
|
quantity: 1
|
|||
|
|
},
|
|||
|
|
statistics: {
|
|||
|
|
todayTotal: 0,
|
|||
|
|
successTotal: 0,
|
|||
|
|
failedTotal: 0
|
|||
|
|
},
|
|||
|
|
recentRecords: []
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
onLoad() {
|
|||
|
|
this.loadPdaMode()
|
|||
|
|
this.loadPageData()
|
|||
|
|
},
|
|||
|
|
onShow() {
|
|||
|
|
this.loadPdaMode()
|
|||
|
|
},
|
|||
|
|
computed: {
|
|||
|
|
quantity() {
|
|||
|
|
return Math.max(1, Number(this.form.quantity) || 0)
|
|||
|
|
},
|
|||
|
|
processLabel() {
|
|||
|
|
return this.processOptions[this.selectedProcessIndex]?.label || '请选择'
|
|||
|
|
},
|
|||
|
|
stepLabel() {
|
|||
|
|
return this.stepOptions[this.selectedStepIndex]?.label || '请选择'
|
|||
|
|
},
|
|||
|
|
submittedTotal() {
|
|||
|
|
return this.statistics.todayTotal
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
getCurrentUserCode() {
|
|||
|
|
const user = uni.getStorageSync('scanapp_user') || {}
|
|||
|
|
return user.username || user.nickname || 'U001'
|
|||
|
|
},
|
|||
|
|
loadPdaMode() {
|
|||
|
|
const userCode = this.getCurrentUserCode()
|
|||
|
|
const settings = uni.getStorageSync(`scanapp_settings_${userCode}`)
|
|||
|
|
this.pdaMode = settings?.pdaMode === true
|
|||
|
|
},
|
|||
|
|
handleOrderInputFocus() {
|
|||
|
|
// #ifdef APP-PLUS
|
|||
|
|
try {
|
|||
|
|
const activity = plus.android.runtimeMainActivity()
|
|||
|
|
const focusedView = activity.getWindow().getDecorView().findFocus()
|
|||
|
|
if (focusedView) {
|
|||
|
|
plus.android.invoke(focusedView, 'setShowSoftInputOnFocus', !this.pdaMode)
|
|||
|
|
}
|
|||
|
|
if (this.pdaMode) {
|
|||
|
|
uni.hideKeyboard()
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
if (this.pdaMode) uni.hideKeyboard()
|
|||
|
|
}
|
|||
|
|
// #endif
|
|||
|
|
},
|
|||
|
|
getSelectionStorageKey() {
|
|||
|
|
return `scanapp_entry_multi_machine_selection_${this.currentUser.userCode}`
|
|||
|
|
},
|
|||
|
|
getSavedSelection() {
|
|||
|
|
const selection = uni.getStorageSync(this.getSelectionStorageKey())
|
|||
|
|
return selection && typeof selection === 'object' ? selection : {}
|
|||
|
|
},
|
|||
|
|
findOptionIndex(options, value) {
|
|||
|
|
const index = options.findIndex((item) => String(item.value) === String(value))
|
|||
|
|
return index >= 0 ? index : 0
|
|||
|
|
},
|
|||
|
|
saveSelection() {
|
|||
|
|
const processItem = this.processOptions[this.selectedProcessIndex]
|
|||
|
|
const stepItem = this.stepOptions[this.selectedStepIndex]
|
|||
|
|
uni.setStorageSync(this.getSelectionStorageKey(), {
|
|||
|
|
processId: processItem?.value || '',
|
|||
|
|
stepId: stepItem?.value || ''
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
async loadPageData() {
|
|||
|
|
this.currentUser.userCode = this.getCurrentUserCode()
|
|||
|
|
const savedSelection = this.getSavedSelection()
|
|||
|
|
try {
|
|||
|
|
const processOptions = await getProcessOptions()
|
|||
|
|
this.processOptions = Array.isArray(processOptions) ? processOptions : []
|
|||
|
|
this.selectedProcessIndex = this.findOptionIndex(this.processOptions, savedSelection.processId)
|
|||
|
|
if (this.processOptions.length > 0) {
|
|||
|
|
await this.loadStepOptions(this.processOptions[this.selectedProcessIndex].value, savedSelection.stepId, false)
|
|||
|
|
}
|
|||
|
|
await this.loadRecordData()
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('[scanapp] 一单多机页数据加载失败', error)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
async loadRecordData() {
|
|||
|
|
const processItem = this.processOptions[this.selectedProcessIndex]
|
|||
|
|
const stepItem = this.stepOptions[this.selectedStepIndex]
|
|||
|
|
const params = {
|
|||
|
|
user_code: this.currentUser.userCode,
|
|||
|
|
process_id: processItem?.value,
|
|||
|
|
step_id: stepItem?.value
|
|||
|
|
}
|
|||
|
|
const [statistics, recent] = await Promise.all([
|
|||
|
|
getOrderStatistics(params),
|
|||
|
|
getOrderRecentRecords({ ...params, limit: 5 })
|
|||
|
|
])
|
|||
|
|
this.statistics = {
|
|||
|
|
todayTotal: Number(statistics?.today_total || 0),
|
|||
|
|
successTotal: Number(statistics?.success_total || 0),
|
|||
|
|
failedTotal: Number(statistics?.failed_total || 0)
|
|||
|
|
}
|
|||
|
|
this.recentRecords = Array.isArray(recent?.items) ? recent.items.map((item, index) => ({
|
|||
|
|
id: item.id || index,
|
|||
|
|
orderNo: item.order_no || '-',
|
|||
|
|
quantity: Number(item.quantity || 1)
|
|||
|
|
})) : []
|
|||
|
|
},
|
|||
|
|
async loadStepOptions(processId, stepId = '', refreshRecords = true) {
|
|||
|
|
try {
|
|||
|
|
const options = await getStepOptions(processId)
|
|||
|
|
this.stepOptions = Array.isArray(options) ? options : []
|
|||
|
|
this.selectedStepIndex = this.findOptionIndex(this.stepOptions, stepId)
|
|||
|
|
await this.loadDataEntryConfig()
|
|||
|
|
this.saveSelection()
|
|||
|
|
if (refreshRecords) await this.loadRecordData()
|
|||
|
|
} catch (error) {
|
|||
|
|
this.stepOptions = []
|
|||
|
|
this.selectedStepIndex = 0
|
|||
|
|
this.basicSettings = {}
|
|||
|
|
this.specificRules = []
|
|||
|
|
console.error('[scanapp] 一单多机步骤加载失败', error)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
async loadDataEntryConfig() {
|
|||
|
|
const processItem = this.processOptions[this.selectedProcessIndex]
|
|||
|
|
const stepItem = this.stepOptions[this.selectedStepIndex]
|
|||
|
|
if (!processItem || !stepItem) {
|
|||
|
|
this.basicSettings = {}
|
|||
|
|
this.specificRules = []
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
const config = await getDataEntryConfig({
|
|||
|
|
process_id: processItem.value,
|
|||
|
|
step_id: stepItem.value,
|
|||
|
|
apply_mode: 'order',
|
|||
|
|
order_no: this.form.orderNo.trim(),
|
|||
|
|
user_code: this.currentUser.userCode.trim()
|
|||
|
|
})
|
|||
|
|
this.basicSettings = config?.basic_setting || {}
|
|||
|
|
this.specificRules = Array.isArray(config?.specific_rules) ? config.specific_rules : []
|
|||
|
|
} catch (error) {
|
|||
|
|
this.basicSettings = {}
|
|||
|
|
this.specificRules = []
|
|||
|
|
console.error('[scanapp] 一单多机规则加载失败', error)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
matchSpecificRule(rule, valueMap) {
|
|||
|
|
const matchField = rule.match_field || 'order_no'
|
|||
|
|
const value = String(valueMap[matchField] || '').trim()
|
|||
|
|
const pattern = String(rule.rule_pattern || '').trim()
|
|||
|
|
if (!value || !pattern) return false
|
|||
|
|
try {
|
|||
|
|
return new RegExp(pattern).test(value)
|
|||
|
|
} catch (error) {
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
validateSpecificRules() {
|
|||
|
|
const context = {
|
|||
|
|
order_no: this.form.orderNo.trim(),
|
|||
|
|
user_code: this.currentUser.userCode.trim()
|
|||
|
|
}
|
|||
|
|
const blockedRule = this.specificRules.find((rule) => {
|
|||
|
|
if (rule.apply_mode && rule.apply_mode !== 'order' && rule.apply_mode !== 'both') return false
|
|||
|
|
if (Array.isArray(rule.step_ids) && rule.step_ids.length && !rule.step_ids.map(String).includes(String(this.stepOptions[this.selectedStepIndex]?.value))) return false
|
|||
|
|
return Number(rule.rule_type) === 2 && this.matchSpecificRule(rule, context)
|
|||
|
|
})
|
|||
|
|
if (blockedRule) {
|
|||
|
|
uni.showToast({ title: blockedRule.rule_name || '当前订单命中特定规则,禁止提交', icon: 'none' })
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
return true
|
|||
|
|
},
|
|||
|
|
validatePattern(value, settingKey, label) {
|
|||
|
|
const pattern = String(this.basicSettings[settingKey] || '').trim()
|
|||
|
|
if (!pattern) return true
|
|||
|
|
try {
|
|||
|
|
if (!new RegExp(pattern).test(value)) {
|
|||
|
|
uni.showToast({ title: `${label}格式不符合规则`, icon: 'none' })
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error(`[scanapp] ${label}规则格式错误`, error)
|
|||
|
|
}
|
|||
|
|
return true
|
|||
|
|
},
|
|||
|
|
showPicker(type) {
|
|||
|
|
const list = type === 'process' ? this.processOptions : this.stepOptions
|
|||
|
|
if (!list.length) {
|
|||
|
|
uni.showToast({ title: '当前没有可选项', icon: 'none' })
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
uni.showActionSheet({
|
|||
|
|
itemList: list.map((item) => item.label),
|
|||
|
|
success: async (res) => {
|
|||
|
|
if (type === 'process') {
|
|||
|
|
this.selectedProcessIndex = res.tapIndex
|
|||
|
|
await this.loadStepOptions(this.processOptions[res.tapIndex]?.value)
|
|||
|
|
} else {
|
|||
|
|
this.selectedStepIndex = res.tapIndex
|
|||
|
|
await this.loadDataEntryConfig()
|
|||
|
|
this.saveSelection()
|
|||
|
|
await this.loadRecordData()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
scanOrder() {
|
|||
|
|
if (this.scanning || this.submitting) return
|
|||
|
|
// #ifdef APP-PLUS
|
|||
|
|
this.scanning = true
|
|||
|
|
openCodeScan({
|
|||
|
|
smartZoom: true,
|
|||
|
|
vibrate: true,
|
|||
|
|
scanRegion: getScanRegionSetting(),
|
|||
|
|
success: async (result) => {
|
|||
|
|
const value = String(result?.content || '').trim()
|
|||
|
|
if (!value) return
|
|||
|
|
this.form.orderNo = value
|
|||
|
|
await this.loadDataEntryConfig()
|
|||
|
|
},
|
|||
|
|
fail: (error) => {
|
|||
|
|
if (Number(error?.errCode) === 9021003) return
|
|||
|
|
uni.showToast({
|
|||
|
|
title: Number(error?.errCode) === 9021002 ? '未获得扫码权限' : '未识别到有效条码',
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
complete: () => {
|
|||
|
|
this.scanning = false
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
// #endif
|
|||
|
|
// #ifndef APP-PLUS
|
|||
|
|
uni.showToast({ title: '请在 Android App 中使用扫码功能', icon: 'none' })
|
|||
|
|
// #endif
|
|||
|
|
},
|
|||
|
|
increaseQuantity() {
|
|||
|
|
this.form.quantity = this.quantity + 1
|
|||
|
|
},
|
|||
|
|
decreaseQuantity() {
|
|||
|
|
this.form.quantity = Math.max(1, this.quantity - 1)
|
|||
|
|
},
|
|||
|
|
validateForm() {
|
|||
|
|
if (!this.form.orderNo.trim()) {
|
|||
|
|
uni.showToast({ title: '请输入订单号', icon: 'none' })
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
if (!this.processOptions[this.selectedProcessIndex]) {
|
|||
|
|
uni.showToast({ title: '请选择工序', icon: 'none' })
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
if (!this.stepOptions[this.selectedStepIndex]) {
|
|||
|
|
uni.showToast({ title: '请选择步骤', icon: 'none' })
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
if (this.quantity < 1 || !Number.isInteger(this.quantity)) {
|
|||
|
|
uni.showToast({ title: '本次数量必须为正整数', icon: 'none' })
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
const minLength = Number(this.basicSettings.order_no_min_length || 0)
|
|||
|
|
if (minLength > 0 && this.form.orderNo.trim().length < minLength) {
|
|||
|
|
uni.showToast({ title: `订单号长度不能少于 ${minLength} 位`, icon: 'none' })
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
if (!this.validatePattern(this.form.orderNo.trim(), 'order_no_regex', '订单号')) return false
|
|||
|
|
return this.validateSpecificRules()
|
|||
|
|
},
|
|||
|
|
resetForm() {
|
|||
|
|
this.form.orderNo = ''
|
|||
|
|
this.form.quantity = 1
|
|||
|
|
this.loadDataEntryConfig()
|
|||
|
|
},
|
|||
|
|
async submitForm() {
|
|||
|
|
if (this.submitting) return
|
|||
|
|
await this.loadDataEntryConfig()
|
|||
|
|
if (!this.validateForm()) return
|
|||
|
|
this.submitting = true
|
|||
|
|
try {
|
|||
|
|
const processItem = this.processOptions[this.selectedProcessIndex]
|
|||
|
|
const stepItem = this.stepOptions[this.selectedStepIndex]
|
|||
|
|
await submitOrderRecord({
|
|||
|
|
order_no: this.form.orderNo.trim(),
|
|||
|
|
quantity: this.quantity,
|
|||
|
|
user_code: this.currentUser.userCode,
|
|||
|
|
process_id: processItem?.value,
|
|||
|
|
step_id: stepItem?.value,
|
|||
|
|
entry_mode: 'multi_machine',
|
|||
|
|
scan_result: 1
|
|||
|
|
})
|
|||
|
|
uni.showToast({ title: '数量录入成功', icon: 'success' })
|
|||
|
|
this.form.orderNo = ''
|
|||
|
|
this.form.quantity = 1
|
|||
|
|
await this.loadPageData()
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('[scanapp] 一单多机录入失败', error)
|
|||
|
|
} finally {
|
|||
|
|
this.submitting = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
.multi-machine-page {
|
|||
|
|
min-height: 100vh;
|
|||
|
|
padding: 28rpx 24rpx 48rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
background: linear-gradient(180deg, #eaf4ff 0%, #f4f6fb 34%, #f4f6fb 100%);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-card,
|
|||
|
|
.order-card,
|
|||
|
|
.progress-card,
|
|||
|
|
.machine-section,
|
|||
|
|
.bottom-summary {
|
|||
|
|
border: 1rpx solid rgba(255, 255, 255, 0.72);
|
|||
|
|
border-radius: 28rpx;
|
|||
|
|
background: #ffffff;
|
|||
|
|
box-shadow: 0 16rpx 42rpx rgba(23, 35, 61, 0.06);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-card {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
padding: 34rpx 30rpx;
|
|||
|
|
background: linear-gradient(135deg, #1677ff 0%, #6b70e8 100%);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-title,
|
|||
|
|
.hero-subtitle,
|
|||
|
|
.section-title,
|
|||
|
|
.section-subtitle,
|
|||
|
|
.field-label,
|
|||
|
|
.meta-label,
|
|||
|
|
.meta-value,
|
|||
|
|
.machine-name,
|
|||
|
|
.machine-hint,
|
|||
|
|
.quantity-tip,
|
|||
|
|
.summary-label,
|
|||
|
|
.summary-value,
|
|||
|
|
.summary-unit {
|
|||
|
|
display: block;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-title {
|
|||
|
|
color: #ffffff;
|
|||
|
|
font-size: 38rpx;
|
|||
|
|
font-weight: 800;
|
|||
|
|
line-height: 1.35;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-subtitle {
|
|||
|
|
margin-top: 10rpx;
|
|||
|
|
color: rgba(255, 255, 255, 0.84);
|
|||
|
|
font-size: 22rpx;
|
|||
|
|
line-height: 1.4;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-icon {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
width: 86rpx;
|
|||
|
|
height: 86rpx;
|
|||
|
|
border-radius: 28rpx;
|
|||
|
|
background: rgba(255, 255, 255, 0.18);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.order-card,
|
|||
|
|
.progress-card,
|
|||
|
|
.machine-section,
|
|||
|
|
.bottom-summary {
|
|||
|
|
margin-top: 24rpx;
|
|||
|
|
padding: 28rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-heading,
|
|||
|
|
.progress-header,
|
|||
|
|
.machine-card-header,
|
|||
|
|
.machine-footer,
|
|||
|
|
.bottom-summary,
|
|||
|
|
.action-row {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-heading,
|
|||
|
|
.progress-header,
|
|||
|
|
.machine-card-header,
|
|||
|
|
.machine-footer,
|
|||
|
|
.bottom-summary {
|
|||
|
|
justify-content: space-between;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-title {
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
line-height: 1.35;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-subtitle {
|
|||
|
|
margin-top: 6rpx;
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
line-height: 1.4;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.order-status,
|
|||
|
|
.machine-count,
|
|||
|
|
.machine-state,
|
|||
|
|
.summary-state {
|
|||
|
|
padding: 8rpx 18rpx;
|
|||
|
|
border-radius: 999rpx;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.order-status,
|
|||
|
|
.machine-state.is-ready,
|
|||
|
|
.summary-state.is-complete {
|
|||
|
|
background: rgba(25, 190, 107, 0.12);
|
|||
|
|
color: #19be6b;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-count {
|
|||
|
|
background: rgba(22, 119, 255, 0.1);
|
|||
|
|
color: #1677ff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-state.is-waiting,
|
|||
|
|
.summary-state.is-warning {
|
|||
|
|
background: rgba(247, 183, 51, 0.14);
|
|||
|
|
color: #d99400;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.order-field,
|
|||
|
|
.machine-field {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
width: 100%;
|
|||
|
|
margin-top: 22rpx;
|
|||
|
|
padding: 22rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
border: 1rpx solid rgba(22, 119, 255, 0.18);
|
|||
|
|
border-radius: 24rpx;
|
|||
|
|
background: #f5f9ff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.order-field-main,
|
|||
|
|
.machine-field-main {
|
|||
|
|
flex: 1;
|
|||
|
|
min-width: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.field-label {
|
|||
|
|
margin-bottom: 6rpx;
|
|||
|
|
color: #5f6b7a;
|
|||
|
|
font-size: 22rpx;
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.scan-button {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
width: 76rpx;
|
|||
|
|
height: 76rpx;
|
|||
|
|
margin-left: 18rpx;
|
|||
|
|
border-radius: 24rpx;
|
|||
|
|
background: linear-gradient(135deg, #1677ff 0%, #6b70e8 100%);
|
|||
|
|
box-shadow: 0 12rpx 26rpx rgba(22, 119, 255, 0.2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.scan-button.small {
|
|||
|
|
width: 68rpx;
|
|||
|
|
height: 68rpx;
|
|||
|
|
border-radius: 22rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.order-meta {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(3, 1fr);
|
|||
|
|
gap: 16rpx;
|
|||
|
|
margin-top: 22rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.meta-item {
|
|||
|
|
padding: 18rpx 16rpx;
|
|||
|
|
border-radius: 20rpx;
|
|||
|
|
background: #f8fbff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.meta-label {
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.meta-value {
|
|||
|
|
margin-top: 8rpx;
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
word-break: break-all;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.progress-percent {
|
|||
|
|
color: #1677ff;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
font-weight: 800;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.progress-track {
|
|||
|
|
height: 16rpx;
|
|||
|
|
margin-top: 22rpx;
|
|||
|
|
overflow: hidden;
|
|||
|
|
border-radius: 999rpx;
|
|||
|
|
background: #eaf0f8;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.progress-fill {
|
|||
|
|
height: 100%;
|
|||
|
|
border-radius: 999rpx;
|
|||
|
|
background: linear-gradient(90deg, #1677ff 0%, #6b70e8 100%);
|
|||
|
|
transition: width 0.2s ease;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-heading {
|
|||
|
|
margin-bottom: 22rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card {
|
|||
|
|
padding: 24rpx;
|
|||
|
|
border: 1rpx solid #edf1f7;
|
|||
|
|
border-radius: 24rpx;
|
|||
|
|
background: #f8fbff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card + .machine-card {
|
|||
|
|
margin-top: 18rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-index {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
width: 58rpx;
|
|||
|
|
height: 58rpx;
|
|||
|
|
margin-right: 16rpx;
|
|||
|
|
border-radius: 18rpx;
|
|||
|
|
background: rgba(22, 119, 255, 0.1);
|
|||
|
|
color: #1677ff;
|
|||
|
|
font-size: 22rpx;
|
|||
|
|
font-weight: 800;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card-title {
|
|||
|
|
flex: 1;
|
|||
|
|
min-width: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-name {
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 26rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-hint {
|
|||
|
|
margin-top: 6rpx;
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-footer {
|
|||
|
|
margin-top: 18rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.quantity-copy .field-label {
|
|||
|
|
margin-bottom: 6rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.quantity-tip {
|
|||
|
|
color: #a0a7b5;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.quantity-control {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
overflow: hidden;
|
|||
|
|
border-radius: 18rpx;
|
|||
|
|
background: #ffffff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.qty-button {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
width: 58rpx;
|
|||
|
|
height: 58rpx;
|
|||
|
|
color: #1677ff;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.qty-input {
|
|||
|
|
width: 80rpx;
|
|||
|
|
height: 58rpx;
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.remove-machine {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: flex-end;
|
|||
|
|
margin-top: 18rpx;
|
|||
|
|
color: #e91f3f;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.remove-machine text {
|
|||
|
|
margin-left: 8rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.add-machine {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
margin-top: 18rpx;
|
|||
|
|
padding: 22rpx;
|
|||
|
|
border: 1rpx dashed rgba(22, 119, 255, 0.34);
|
|||
|
|
border-radius: 22rpx;
|
|||
|
|
background: #f8fbff;
|
|||
|
|
color: #1677ff;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.add-machine text {
|
|||
|
|
margin-left: 10rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.add-machine--active {
|
|||
|
|
background: #eef5ff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.bottom-summary {
|
|||
|
|
padding-top: 24rpx;
|
|||
|
|
padding-bottom: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-label {
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-value {
|
|||
|
|
margin-top: 6rpx;
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
font-weight: 800;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-unit {
|
|||
|
|
display: inline;
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
font-weight: 400;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.action-row {
|
|||
|
|
margin-top: 24rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.reset-button,
|
|||
|
|
.submit-button {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
height: 86rpx;
|
|||
|
|
border-radius: 20rpx;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.reset-button {
|
|||
|
|
width: 176rpx;
|
|||
|
|
background: #f2f4f8;
|
|||
|
|
color: #5f6b7a;
|
|||
|
|
flex: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.submit-button {
|
|||
|
|
margin-left: 14rpx;
|
|||
|
|
flex: 1;
|
|||
|
|
background: linear-gradient(135deg, #1677ff 0%, #6b70e8 100%);
|
|||
|
|
color: #ffffff;
|
|||
|
|
box-shadow: 0 14rpx 24rpx rgba(22, 119, 255, 0.18);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.submit-button.is-disabled {
|
|||
|
|
opacity: 0.72;
|
|||
|
|
}
|
|||
|
|
.entry-page {
|
|||
|
|
min-height: 100vh;
|
|||
|
|
padding: 28rpx 24rpx 48rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
background: linear-gradient(180deg, #eaf4ff 0%, #f4f6fb 38%, #f4f6fb 100%);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-card,
|
|||
|
|
.config-card,
|
|||
|
|
.form-card,
|
|||
|
|
.stats-card,
|
|||
|
|
.record-card {
|
|||
|
|
border: 1rpx solid rgba(255, 255, 255, 0.72);
|
|||
|
|
border-radius: 28rpx;
|
|||
|
|
background: #ffffff;
|
|||
|
|
box-shadow: 0 16rpx 42rpx rgba(23, 35, 61, 0.06);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.hero-card {
|
|||
|
|
padding: 34rpx 30rpx;
|
|||
|
|
background: linear-gradient(135deg, #1677ff 0%, #35bfa3 100%);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.config-card,
|
|||
|
|
.form-card,
|
|||
|
|
.stats-card,
|
|||
|
|
.record-card {
|
|||
|
|
margin-top: 24rpx;
|
|||
|
|
padding: 28rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-title,
|
|||
|
|
.card-subtitle,
|
|||
|
|
.chip-label,
|
|||
|
|
.chip-value,
|
|||
|
|
.stat-value,
|
|||
|
|
.stat-label,
|
|||
|
|
.record-main,
|
|||
|
|
.record-sub,
|
|||
|
|
.empty-record,
|
|||
|
|
.progress-badge {
|
|||
|
|
display: block;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-title {
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
line-height: 1.35;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-subtitle {
|
|||
|
|
margin-top: 6rpx;
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
line-height: 1.4;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.chip-row,
|
|||
|
|
.stats-grid {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(2, 1fr);
|
|||
|
|
gap: 18rpx;
|
|||
|
|
margin-top: 22rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.select-chip,
|
|||
|
|
.stat-item {
|
|||
|
|
padding: 20rpx;
|
|||
|
|
border-radius: 22rpx;
|
|||
|
|
background: #f8fbff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.chip-label,
|
|||
|
|
.stat-label {
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.chip-value {
|
|||
|
|
margin-top: 8rpx;
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 26rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.form-title-row,
|
|||
|
|
.stats-header,
|
|||
|
|
.allocation-summary {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
gap: 18rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.progress-badge,
|
|||
|
|
.total-badge {
|
|||
|
|
padding: 10rpx 18rpx;
|
|||
|
|
border-radius: 999rpx;
|
|||
|
|
background: rgba(22, 119, 255, 0.1);
|
|||
|
|
color: #1677ff;
|
|||
|
|
font-size: 22rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.field-card {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
width: 100%;
|
|||
|
|
padding: 22rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
border: 1rpx solid #edf1f7;
|
|||
|
|
border-radius: 24rpx;
|
|||
|
|
background: #f8fbff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.primary-field {
|
|||
|
|
margin-top: 22rpx;
|
|||
|
|
border-color: rgba(22, 119, 255, 0.18);
|
|||
|
|
background: #f5f9ff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.field-main {
|
|||
|
|
flex: 1;
|
|||
|
|
min-width: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.field-label {
|
|||
|
|
display: block;
|
|||
|
|
margin-bottom: 6rpx;
|
|||
|
|
color: #5f6b7a;
|
|||
|
|
font-size: 22rpx;
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.progress-track {
|
|||
|
|
height: 16rpx;
|
|||
|
|
margin-top: 22rpx;
|
|||
|
|
overflow: hidden;
|
|||
|
|
border-radius: 999rpx;
|
|||
|
|
background: #eaf0f8;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.progress-fill {
|
|||
|
|
height: 100%;
|
|||
|
|
border-radius: 999rpx;
|
|||
|
|
background: linear-gradient(90deg, #1677ff 0%, #35bfa3 100%);
|
|||
|
|
transition: width 0.2s ease;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card {
|
|||
|
|
margin-top: 18rpx;
|
|||
|
|
padding: 24rpx;
|
|||
|
|
border: 1rpx solid #edf1f7;
|
|||
|
|
border-radius: 24rpx;
|
|||
|
|
background: #f8fbff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card-header,
|
|||
|
|
.machine-footer {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-index {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
width: 58rpx;
|
|||
|
|
height: 58rpx;
|
|||
|
|
margin-right: 16rpx;
|
|||
|
|
border-radius: 18rpx;
|
|||
|
|
background: rgba(22, 119, 255, 0.1);
|
|||
|
|
color: #1677ff;
|
|||
|
|
font-size: 22rpx;
|
|||
|
|
font-weight: 800;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card-title {
|
|||
|
|
flex: 1;
|
|||
|
|
min-width: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-name,
|
|||
|
|
.machine-hint,
|
|||
|
|
.quantity-tip {
|
|||
|
|
display: block;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-name {
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 26rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-hint,
|
|||
|
|
.quantity-tip {
|
|||
|
|
margin-top: 6rpx;
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-state,
|
|||
|
|
.summary-state {
|
|||
|
|
padding: 8rpx 18rpx;
|
|||
|
|
border-radius: 999rpx;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-state.is-ready,
|
|||
|
|
.summary-state.is-complete {
|
|||
|
|
background: rgba(25, 190, 107, 0.12);
|
|||
|
|
color: #19be6b;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-state.is-waiting,
|
|||
|
|
.summary-state.is-warning {
|
|||
|
|
background: rgba(247, 183, 51, 0.14);
|
|||
|
|
color: #d99400;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-card .field-card {
|
|||
|
|
margin-top: 18rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.scan-button {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
width: 76rpx;
|
|||
|
|
height: 76rpx;
|
|||
|
|
margin-left: 18rpx;
|
|||
|
|
border-radius: 24rpx;
|
|||
|
|
background: linear-gradient(135deg, #1677ff 0%, #35bfa3 100%);
|
|||
|
|
box-shadow: 0 12rpx 26rpx rgba(22, 119, 255, 0.2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.scan-button.small {
|
|||
|
|
width: 68rpx;
|
|||
|
|
height: 68rpx;
|
|||
|
|
border-radius: 22rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.machine-footer {
|
|||
|
|
margin-top: 18rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.quantity-control {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
overflow: hidden;
|
|||
|
|
border-radius: 18rpx;
|
|||
|
|
background: #ffffff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.qty-button {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
width: 58rpx;
|
|||
|
|
height: 58rpx;
|
|||
|
|
color: #1677ff;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.qty-input {
|
|||
|
|
width: 80rpx;
|
|||
|
|
height: 58rpx;
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.remove-machine,
|
|||
|
|
.add-machine {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.remove-machine {
|
|||
|
|
justify-content: flex-end;
|
|||
|
|
margin-top: 18rpx;
|
|||
|
|
color: #e91f3f;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.remove-machine text,
|
|||
|
|
.add-machine text {
|
|||
|
|
margin-left: 8rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.add-machine {
|
|||
|
|
margin-top: 18rpx;
|
|||
|
|
padding: 22rpx;
|
|||
|
|
border: 1rpx dashed rgba(22, 119, 255, 0.34);
|
|||
|
|
border-radius: 22rpx;
|
|||
|
|
background: #f8fbff;
|
|||
|
|
color: #1677ff;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.add-machine--active {
|
|||
|
|
background: #eef5ff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.allocation-summary {
|
|||
|
|
margin-top: 24rpx;
|
|||
|
|
padding-top: 24rpx;
|
|||
|
|
border-top: 1rpx solid #edf1f7;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-label {
|
|||
|
|
display: block;
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-value {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 6rpx;
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
font-weight: 800;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-unit {
|
|||
|
|
display: inline;
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
font-weight: 400;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.action-row {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
margin-top: 28rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.submit-secondary,
|
|||
|
|
.submit-primary {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
height: 86rpx;
|
|||
|
|
border-radius: 20rpx;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.submit-secondary {
|
|||
|
|
width: 176rpx;
|
|||
|
|
background: #f2f4f8;
|
|||
|
|
color: #5f6b7a;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.submit-primary {
|
|||
|
|
margin-left: 14rpx;
|
|||
|
|
flex: 1;
|
|||
|
|
background: linear-gradient(135deg, #1677ff 0%, #35bfa3 100%);
|
|||
|
|
color: #ffffff;
|
|||
|
|
box-shadow: 0 14rpx 24rpx rgba(22, 119, 255, 0.18);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.submit-primary.is-loading {
|
|||
|
|
opacity: 0.8;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.stats-header {
|
|||
|
|
margin-bottom: 22rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.total-badge {
|
|||
|
|
font-size: 26rpx;
|
|||
|
|
font-weight: 800;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.stats-grid {
|
|||
|
|
grid-template-columns: repeat(3, 1fr);
|
|||
|
|
margin-top: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.stat-item {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
min-height: 112rpx;
|
|||
|
|
padding: 0;
|
|||
|
|
flex-direction: column;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.stat-value {
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
font-weight: 800;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.stat-value.success { color: #19be6b; }
|
|||
|
|
.stat-value.danger { color: #e91f3f; }
|
|||
|
|
|
|||
|
|
.stat-label {
|
|||
|
|
margin-top: 8rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.record-item {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
padding: 22rpx 0;
|
|||
|
|
border-bottom: 1rpx solid #edf1f7;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.record-item:last-child { border-bottom: 0; }
|
|||
|
|
.record-main { color: #17233d; font-size: 26rpx; font-weight: 700; }
|
|||
|
|
.record-sub { margin-top: 6rpx; color: #8a94a6; font-size: 20rpx; }
|
|||
|
|
.record-status { padding: 8rpx 18rpx; border-radius: 999rpx; background: rgba(25, 190, 107, 0.12); color: #19be6b; font-size: 20rpx; font-weight: 600; }
|
|||
|
|
.empty-record { padding: 30rpx 0 8rpx; color: #a0a7b5; font-size: 22rpx; text-align: center; }
|
|||
|
|
|
|||
|
|
.config-card,
|
|||
|
|
.form-card,
|
|||
|
|
.stats-card,
|
|||
|
|
.record-card {
|
|||
|
|
margin-top: 24rpx;
|
|||
|
|
padding: 28rpx;
|
|||
|
|
border: 1rpx solid rgba(255, 255, 255, 0.72);
|
|||
|
|
border-radius: 28rpx;
|
|||
|
|
background: #ffffff;
|
|||
|
|
box-shadow: 0 16rpx 42rpx rgba(23, 35, 61, 0.06);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-title,
|
|||
|
|
.card-subtitle,
|
|||
|
|
.field-label,
|
|||
|
|
.quantity-tip,
|
|||
|
|
.record-main,
|
|||
|
|
.record-sub,
|
|||
|
|
.stat-label {
|
|||
|
|
display: block;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-title {
|
|||
|
|
color: #17233d;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.card-subtitle,
|
|||
|
|
.quantity-tip {
|
|||
|
|
margin-top: 6rpx;
|
|||
|
|
color: #8a94a6;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.chip-row,
|
|||
|
|
.form-title-row,
|
|||
|
|
.quantity-heading,
|
|||
|
|
.quantity-preview,
|
|||
|
|
.stats-header {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.chip-row { margin-top: 20rpx; }
|
|||
|
|
|
|||
|
|
.select-chip {
|
|||
|
|
width: calc(50% - 8rpx);
|
|||
|
|
padding: 18rpx 20rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
border-radius: 18rpx;
|
|||
|
|
background: #f5f8fd;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.chip-label { color: #8a94a6; font-size: 20rpx; }
|
|||
|
|
.chip-value { display: block; margin-top: 6rpx; color: #17233d; font-size: 24rpx; font-weight: 700; }
|
|||
|
|
.progress-badge, .quantity-unit { color: #1677ff; font-size: 22rpx; font-weight: 700; }
|
|||
|
|
|
|||
|
|
.field-card,
|
|||
|
|
.quantity-card {
|
|||
|
|
margin-top: 22rpx;
|
|||
|
|
padding: 20rpx 22rpx;
|
|||
|
|
border: 1rpx solid rgba(22, 119, 255, 0.18);
|
|||
|
|
border-radius: 22rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.primary-field { display: flex; align-items: center; }
|
|||
|
|
.field-main { flex: 1; }
|
|||
|
|
.field-label { color: #5f6b7a; font-size: 22rpx; font-weight: 600; }
|
|||
|
|
.scan-button { display: flex; align-items: center; justify-content: center; width: 72rpx; height: 72rpx; margin-left: 16rpx; border-radius: 18rpx; background: #1677ff; }
|
|||
|
|
|
|||
|
|
.quantity-control { display: flex; align-items: center; margin-top: 20rpx; }
|
|||
|
|
.qty-button { display: flex; align-items: center; justify-content: center; width: 72rpx; height: 72rpx; border-radius: 18rpx; background: #edf4ff; color: #1677ff; font-size: 38rpx; font-weight: 500; }
|
|||
|
|
.qty-input { flex: 1; height: 72rpx; margin: 0 16rpx; border-radius: 18rpx; background: #f7f9fc; color: #17233d; font-size: 32rpx; font-weight: 800; text-align: center; }
|
|||
|
|
.quantity-preview { margin-top: 20rpx; padding: 20rpx; border-radius: 18rpx; background: #f4fbf8; color: #5f6b7a; font-size: 22rpx; }
|
|||
|
|
.quantity-preview-value { color: #19be6b; font-size: 30rpx; font-weight: 800; }
|
|||
|
|
.theme-dark.entry-page {
|
|||
|
|
background: #151923;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .config-card,
|
|||
|
|
.theme-dark .form-card,
|
|||
|
|
.theme-dark .stats-card,
|
|||
|
|
.theme-dark .record-card,
|
|||
|
|
.theme-dark .machine-card {
|
|||
|
|
border-color: #364152;
|
|||
|
|
background: #222936;
|
|||
|
|
box-shadow: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .select-chip,
|
|||
|
|
.theme-dark .field-card,
|
|||
|
|
.theme-dark .quantity-card,
|
|||
|
|
.theme-dark .stat-item,
|
|||
|
|
.theme-dark .add-machine {
|
|||
|
|
border-color: #364152;
|
|||
|
|
background: #1c2431;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .quantity-control,
|
|||
|
|
.theme-dark .qty-input,
|
|||
|
|
.theme-dark .part-stepper {
|
|||
|
|
border-color: #364152;
|
|||
|
|
background: #1c2431;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .qty-button,
|
|||
|
|
.theme-dark .submit-secondary {
|
|||
|
|
background: #293344;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .card-title,
|
|||
|
|
.theme-dark .chip-value,
|
|||
|
|
.theme-dark .field-label,
|
|||
|
|
.theme-dark .machine-name,
|
|||
|
|
.theme-dark .record-main,
|
|||
|
|
.theme-dark .stat-value,
|
|||
|
|
.theme-dark .summary-value,
|
|||
|
|
.theme-dark .qty-input {
|
|||
|
|
color: #f2f5fa;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .card-subtitle,
|
|||
|
|
.theme-dark .chip-label,
|
|||
|
|
.theme-dark .quantity-tip,
|
|||
|
|
.theme-dark .machine-hint,
|
|||
|
|
.theme-dark .record-sub,
|
|||
|
|
.theme-dark .stat-label,
|
|||
|
|
.theme-dark .summary-label {
|
|||
|
|
color: #aeb9ca;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark .record-item,
|
|||
|
|
.theme-dark .allocation-summary {
|
|||
|
|
border-color: #364152;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.theme-dark :deep(.u-input__input) {
|
|||
|
|
color: #f2f5fa !important;
|
|||
|
|
}
|
|||
|
|
</style>
|