1059 lines
23 KiB
Vue
1059 lines
23 KiB
Vue
<template>
|
||
<view class="query-page query-layout" :class="`theme-${themeMode}`">
|
||
<view class="query-header">
|
||
<view>
|
||
<text class="query-title">记录查询</text>
|
||
<text class="query-subtitle">快速定位扫码、批量与异常记录</text>
|
||
</view>
|
||
<u-icon name="search" color="#2f6cf6" size="34" />
|
||
</view>
|
||
|
||
<view class="query-tabs">
|
||
<view v-for="item in queryTypes" :key="item.value" class="query-tab" :class="{ 'is-active': activeQueryType === item.value }" @tap="activeQueryType = item.value">
|
||
<u-icon :name="item.icon" :color="activeQueryType === item.value ? '#ffffff' : '#9aa4b4'" size="28" />
|
||
<text>{{ item.label }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="query-search-row">
|
||
<view class="query-input-wrap">
|
||
<u-input v-model="keyword" :input-mode="pdaMode ? 'none' : 'text'" clearable prefix-icon="search" placeholder="请输入单号、商品编码或操作人" placeholder-style="color: #a0a7b5;" @focus="handleKeywordInputFocus" @confirm="handleSearch" />
|
||
</view>
|
||
<view class="camera-button" :class="{ 'is-scanning': isScanning }" @tap="scanKeyword">
|
||
<u-icon name="scan" color="#ffffff" size="32" />
|
||
</view>
|
||
<view class="query-button" @tap="handleSearch">查询</view>
|
||
</view>
|
||
|
||
<view class="advanced-trigger" @tap="showAdvanced = !showAdvanced">
|
||
<view class="advanced-title">
|
||
<u-icon name="list" color="#687386" size="28" />
|
||
<text>高级筛选</text>
|
||
<text class="advanced-state">{{ showAdvanced ? '收起' : '可选' }}</text>
|
||
</view>
|
||
<u-icon :name="showAdvanced ? 'arrow-up' : 'arrow-down'" color="#9aa4b4" size="24" />
|
||
</view>
|
||
|
||
<view v-if="showAdvanced" class="advanced-panel">
|
||
<view class="filter-label">工序</view>
|
||
<view class="chip-row compact-chip-row">
|
||
<view v-for="item in processOptions" :key="item.value" class="chip" :class="{ 'is-active': activeProcess === item.value }" @tap="activeProcess = item.value">
|
||
{{ item.label }}
|
||
</view>
|
||
</view>
|
||
<view class="filter-label status-filter-label">状态</view>
|
||
<view class="chip-row compact-chip-row">
|
||
<view v-for="item in statusOptions" :key="item.value" class="chip" :class="{ 'is-active': activeStatus === item.value }" @tap="activeStatus = item.value">
|
||
{{ item.label }}
|
||
</view>
|
||
</view>
|
||
<view class="filter-actions">
|
||
<text @tap="resetFilter">重置条件</text>
|
||
<text class="filter-confirm" @tap="handleSearch">确定筛选</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="result-header">
|
||
<text>找到 {{ filteredRecords.length }} 条结果</text>
|
||
<text>{{ currentTypeLabel }}</text>
|
||
</view>
|
||
|
||
<view v-if="filteredRecords.length" class="record-list">
|
||
<view v-for="item in filteredRecords" :key="item.id" class="record-card compact-record" @tap="showRecordDetail(item)">
|
||
<view class="record-top">
|
||
<view class="record-number">
|
||
<u-icon name="list" color="#44c653" size="28" />
|
||
<text class="record-main">{{ item.mainNo }}</text>
|
||
</view>
|
||
<view class="record-type-pill">{{ getRecordTypeLabel(item) }}</view>
|
||
</view>
|
||
<view class="record-detail-grid">
|
||
<view class="record-detail"><text>岗位:</text><text>{{ item.position }}</text></view>
|
||
<view class="record-detail"><text>工序:</text><text>{{ item.process }}</text></view>
|
||
<view class="record-detail"><text>状态:</text><text class="record-status" :class="item.statusClass">{{ item.statusLabel }}</text></view>
|
||
<view class="record-detail"><text>操作员:</text><text>{{ item.operator }}</text></view>
|
||
</view>
|
||
<view class="record-footer">
|
||
<text>{{ item.scanTime }}</text>
|
||
<u-icon name="arrow-right" color="#c1c7d0" size="24" />
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<u-empty v-else mode="data" text="暂无查询结果" />
|
||
|
||
<view v-if="detailVisible && selectedRecord" class="detail-mask" @tap="closeRecordDetail">
|
||
<view class="detail-sheet" @tap.stop>
|
||
<view class="sheet-handle"></view>
|
||
<view class="detail-sheet-header">
|
||
<text>录入数据明细</text>
|
||
<u-icon name="close" color="#7d8798" size="30" @tap="closeRecordDetail" />
|
||
</view>
|
||
<text class="sheet-main-no">{{ selectedRecord.mainNo }}</text>
|
||
<view class="sheet-detail-grid">
|
||
<view class="sheet-detail-item"><text>记录类型</text><text>{{ getRecordTypeLabel(selectedRecord) }}</text></view>
|
||
<view class="sheet-detail-item"><text>录入模式</text><text>{{ selectedRecord.modeLabel }}</text></view>
|
||
<view class="sheet-detail-item"><text>岗位</text><text>{{ selectedRecord.position }}</text></view>
|
||
<view class="sheet-detail-item"><text>工序 / 步骤</text><text>{{ selectedRecord.process }} / {{ selectedRecord.step }}</text></view>
|
||
<view class="sheet-detail-item"><text>商品编码</text><text>{{ selectedRecord.productCode || '-' }}</text></view>
|
||
<view class="sheet-detail-item"><text>数量</text><text>{{ selectedRecord.quantity || '-' }}</text></view>
|
||
<view class="sheet-detail-item"><text>操作人</text><text>{{ selectedRecord.operator }}</text></view>
|
||
<view class="sheet-detail-item"><text>扫码时间</text><text>{{ selectedRecord.scanTime }}</text></view>
|
||
</view>
|
||
<view class="sheet-remark"><text>备注</text><text>{{ selectedRecord.remark }}</text></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
// UTS 原生扫码插件仅在 App-Plus 真机/自定义基座中解析,Web 环境不加载。
|
||
// #ifdef APP-PLUS
|
||
import { openCodeScan } from '@/uni_modules/mas-code-scan'
|
||
// #endif
|
||
|
||
import { getScanRegionSetting } from '@/utils/scan-settings.js'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
keyword: '',
|
||
pdaMode: false,
|
||
activeQueryType: 'all',
|
||
showAdvanced: false,
|
||
isScanning: false,
|
||
activeProcess: 'all',
|
||
activeStatus: 'all',
|
||
detailVisible: false,
|
||
selectedRecord: null,
|
||
queryTypes: [
|
||
{ label: '全部', value: 'all', icon: 'search' },
|
||
{ label: '扫码记录', value: 'scan', icon: 'scan' },
|
||
{ label: '批量记录', value: 'batch', icon: 'grid-fill' },
|
||
{ label: '异常记录', value: 'abnormal', icon: 'warning-fill' }
|
||
],
|
||
processOptions: [
|
||
{ label: '全部', value: 'all' },
|
||
{ label: '总装', value: '总装' },
|
||
{ label: '质检', value: '质检' },
|
||
{ label: '包装', value: '包装' },
|
||
{ label: '组装', value: '组装' }
|
||
],
|
||
statusOptions: [
|
||
{ label: '全部', value: 'all' },
|
||
{ label: '成功', value: 'success' },
|
||
{ label: '失败', value: 'failed' }
|
||
],
|
||
records: [
|
||
{
|
||
id: 1,
|
||
queryType: 'scan',
|
||
typeLabel: '扫码记录',
|
||
mainNo: 'SO20260808001',
|
||
position: 'L1C-H',
|
||
process: '总装',
|
||
step: '开始',
|
||
operator: 'U001',
|
||
status: 'success',
|
||
statusLabel: '成功',
|
||
statusClass: 'is-success',
|
||
scanTime: '2026-08-08 18:42:13',
|
||
remark: '录入正常',
|
||
modeLabel: '订单模式',
|
||
productCode: '',
|
||
quantity: ''
|
||
},
|
||
{
|
||
id: 2,
|
||
queryType: 'scan',
|
||
typeLabel: '扫码记录',
|
||
mainNo: 'MO20260808004',
|
||
position: 'L1W-A',
|
||
process: '质检',
|
||
step: '完成',
|
||
operator: 'U003',
|
||
status: 'success',
|
||
statusLabel: '成功',
|
||
statusClass: 'is-success',
|
||
scanTime: '2026-08-08 18:31:05',
|
||
remark: '整机数据已提交',
|
||
modeLabel: '整机模式',
|
||
productCode: 'P10086',
|
||
quantity: '2'
|
||
},
|
||
{
|
||
id: 3,
|
||
queryType: 'abnormal',
|
||
typeLabel: '异常记录',
|
||
mainNo: 'SO20260808005',
|
||
position: 'L1Z-K',
|
||
process: '包装',
|
||
step: '复核',
|
||
operator: 'U002',
|
||
status: 'failed',
|
||
statusLabel: '失败',
|
||
statusClass: 'is-failed',
|
||
scanTime: '2026-08-08 18:12:44',
|
||
remark: '订单号格式不符合规则',
|
||
modeLabel: '订单模式',
|
||
productCode: '',
|
||
quantity: ''
|
||
},
|
||
{
|
||
id: 4,
|
||
queryType: 'batch',
|
||
typeLabel: '批量记录',
|
||
mainNo: 'MO20260808006',
|
||
position: 'L1P-D',
|
||
process: '总装',
|
||
step: '开始',
|
||
operator: 'U004',
|
||
status: 'success',
|
||
statusLabel: '成功',
|
||
statusClass: 'is-success',
|
||
scanTime: '2026-08-08 17:58:07',
|
||
remark: '录入正常',
|
||
modeLabel: '整机模式',
|
||
productCode: 'P10092',
|
||
quantity: '1'
|
||
}
|
||
]
|
||
}
|
||
},
|
||
computed: {
|
||
filteredRecords() {
|
||
const keyword = this.keyword.trim().toLowerCase()
|
||
return this.records.filter((item) => {
|
||
const matchKeyword = !keyword
|
||
|| String(item.mainNo).toLowerCase().includes(keyword)
|
||
|| String(item.position || '').toLowerCase().includes(keyword)
|
||
|| String(item.productCode || '').toLowerCase().includes(keyword)
|
||
|| String(item.operator).toLowerCase().includes(keyword)
|
||
const matchType = this.activeQueryType === 'all' || item.queryType === this.activeQueryType
|
||
const matchProcess = this.activeProcess === 'all' || item.process === this.activeProcess
|
||
const matchStatus = this.activeStatus === 'all' || item.status === this.activeStatus
|
||
return matchKeyword && matchType && matchProcess && matchStatus
|
||
})
|
||
},
|
||
currentTypeLabel() {
|
||
const current = this.queryTypes.find((item) => item.value === this.activeQueryType)
|
||
return current ? current.label : '全部类型'
|
||
},
|
||
successCount() {
|
||
return this.filteredRecords.filter((item) => item.status === 'success').length
|
||
},
|
||
failedCount() {
|
||
return this.filteredRecords.filter((item) => item.status === 'failed').length
|
||
}
|
||
},
|
||
watch: {
|
||
filteredRecords: {
|
||
immediate: true,
|
||
handler(list) {
|
||
if (!list.length) {
|
||
this.selectedRecord = null
|
||
this.detailVisible = false
|
||
return
|
||
}
|
||
if (!this.selectedRecord || !list.some((item) => item.id === this.selectedRecord.id)) {
|
||
this.selectedRecord = list[0]
|
||
}
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
getCurrentUserCode() {
|
||
const user = uni.getStorageSync('scanapp_user') || {}
|
||
return user.username || user.nickname || 'U001'
|
||
},
|
||
loadPdaMode() {
|
||
const settings = uni.getStorageSync(`scanapp_settings_${this.getCurrentUserCode()}`)
|
||
this.pdaMode = settings?.pdaMode === true
|
||
},
|
||
handleKeywordInputFocus() {
|
||
// #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
|
||
},
|
||
handleSearch() {
|
||
if (!this.filteredRecords.length) {
|
||
this.selectedRecord = null
|
||
this.detailVisible = false
|
||
return
|
||
}
|
||
if (!this.selectedRecord || !this.filteredRecords.some((item) => item.id === this.selectedRecord.id)) {
|
||
this.selectedRecord = this.filteredRecords[0]
|
||
}
|
||
},
|
||
resetFilter() {
|
||
this.keyword = ''
|
||
this.activeQueryType = 'all'
|
||
this.activeProcess = 'all'
|
||
this.activeStatus = 'all'
|
||
this.showAdvanced = false
|
||
this.detailVisible = false
|
||
this.selectedRecord = this.records[0] || null
|
||
},
|
||
scanKeyword() {
|
||
if (this.isScanning) return
|
||
// #ifdef APP-PLUS
|
||
this.isScanning = true
|
||
openCodeScan({
|
||
smartZoom: true,
|
||
vibrate: true,
|
||
scanRegion: getScanRegionSetting(),
|
||
success: (result) => {
|
||
const value = String(result?.content || '').trim()
|
||
if (!value) return
|
||
this.keyword = value
|
||
this.handleSearch()
|
||
},
|
||
fail: (error) => {
|
||
const code = Number(error?.errCode)
|
||
if (code === 9021003) return
|
||
const messageMap = {
|
||
9021001: '当前环境不支持扫码,请在 Android 自定义调试基座或正式安装包中使用',
|
||
9021002: '相机权限被拒绝,请到系统设置中开启相机权限',
|
||
9021004: '未获取到有效扫码结果,请重试'
|
||
}
|
||
uni.showToast({ title: messageMap[code] || String(error?.errMsg || '扫码插件调用异常'), icon: 'none' })
|
||
},
|
||
complete: () => {
|
||
this.isScanning = false
|
||
}
|
||
})
|
||
// #endif
|
||
// #ifndef APP-PLUS
|
||
uni.showToast({ title: '请在 Android App 中使用扫码功能', icon: 'none' })
|
||
// #endif
|
||
},
|
||
showRecordDetail(item) {
|
||
this.selectedRecord = item
|
||
this.detailVisible = true
|
||
},
|
||
closeRecordDetail() {
|
||
this.detailVisible = false
|
||
},
|
||
getRecordTypeLabel(item) {
|
||
return item.typeLabel || '记录'
|
||
}
|
||
},
|
||
onLoad() {
|
||
this.loadPdaMode()
|
||
this.selectedRecord = this.records[0] || null
|
||
},
|
||
onShow() {
|
||
this.loadPdaMode()
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.query-page {
|
||
min-height: 100vh;
|
||
padding: 28rpx 24rpx 48rpx;
|
||
box-sizing: border-box;
|
||
background: linear-gradient(180deg, #eef6ff 0%, #f4f6fb 38%, #f4f6fb 100%);
|
||
}
|
||
|
||
.hero-card,
|
||
.filter-card,
|
||
.summary-card,
|
||
.detail-card,
|
||
.list-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);
|
||
}
|
||
|
||
.hero-card {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 0;
|
||
padding: 34rpx 30rpx;
|
||
background: linear-gradient(135deg, #1677ff 0%, #35bfa3 100%);
|
||
}
|
||
|
||
.hero-title,
|
||
.hero-subtitle,
|
||
.card-title,
|
||
.filter-label,
|
||
.summary-value,
|
||
.summary-label,
|
||
.detail-main,
|
||
.detail-sub,
|
||
.detail-key,
|
||
.detail-value,
|
||
.record-main,
|
||
.record-sub,
|
||
.record-key,
|
||
.record-value {
|
||
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.82);
|
||
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);
|
||
}
|
||
|
||
.card-title {
|
||
color: #17233d;
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.search-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
margin-top: 20rpx;
|
||
}
|
||
|
||
.search-input-wrap {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.filter-group {
|
||
margin-top: 20rpx;
|
||
}
|
||
|
||
.filter-label {
|
||
margin-bottom: 14rpx;
|
||
color: #5f6b7a;
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.chip-row {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 14rpx;
|
||
}
|
||
|
||
.chip {
|
||
padding: 14rpx 20rpx;
|
||
border-radius: 999rpx;
|
||
background: #f3f6fb;
|
||
color: #5f6b7a;
|
||
font-size: 24rpx;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.chip.is-active {
|
||
background: rgba(22, 119, 255, 0.12);
|
||
color: #1677ff;
|
||
}
|
||
|
||
.action-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
gap: 16rpx;
|
||
margin-top: 24rpx;
|
||
}
|
||
|
||
.summary-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 16rpx;
|
||
}
|
||
|
||
.summary-item {
|
||
padding: 22rpx 18rpx;
|
||
border-radius: 22rpx;
|
||
background: #f8fbff;
|
||
}
|
||
|
||
.summary-value {
|
||
color: #17233d;
|
||
font-size: 32rpx;
|
||
font-weight: 800;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.summary-value.success {
|
||
color: #19be6b;
|
||
}
|
||
|
||
.summary-value.danger {
|
||
color: #e91f3f;
|
||
}
|
||
|
||
.summary-label {
|
||
margin-top: 8rpx;
|
||
color: #8a94a6;
|
||
font-size: 20rpx;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.detail-card,
|
||
.list-card {
|
||
margin-top: 24rpx;
|
||
}
|
||
|
||
.detail-header,
|
||
.record-top {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
gap: 16rpx;
|
||
}
|
||
|
||
.detail-main,
|
||
.record-main {
|
||
color: #17233d;
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.detail-sub,
|
||
.record-sub {
|
||
margin-top: 6rpx;
|
||
color: #8a94a6;
|
||
font-size: 20rpx;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.status-pill {
|
||
padding: 10rpx 18rpx;
|
||
border-radius: 999rpx;
|
||
font-size: 20rpx;
|
||
font-weight: 600;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.status-pill.is-success {
|
||
background: rgba(25, 190, 107, 0.12);
|
||
color: #19be6b;
|
||
}
|
||
|
||
.status-pill.is-failed {
|
||
background: rgba(233, 31, 63, 0.12);
|
||
color: #e91f3f;
|
||
}
|
||
|
||
.detail-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 16rpx;
|
||
margin-top: 22rpx;
|
||
}
|
||
|
||
.detail-item {
|
||
padding: 18rpx 18rpx 20rpx;
|
||
border-radius: 20rpx;
|
||
background: #f8fbff;
|
||
}
|
||
|
||
.detail-key,
|
||
.record-key {
|
||
color: #8a94a6;
|
||
font-size: 20rpx;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.detail-value,
|
||
.record-value {
|
||
margin-top: 8rpx;
|
||
color: #17233d;
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.record-card {
|
||
padding: 22rpx 24rpx;
|
||
border-radius: 24rpx;
|
||
background: #f8fbff;
|
||
margin-top: 18rpx;
|
||
}
|
||
|
||
.record-card.is-selected {
|
||
border: 1rpx solid rgba(22, 119, 255, 0.22);
|
||
background: #f5f9ff;
|
||
}
|
||
|
||
.record-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 16rpx;
|
||
margin-top: 18rpx;
|
||
}
|
||
|
||
.record-info {
|
||
padding: 16rpx 16rpx 18rpx;
|
||
border-radius: 18rpx;
|
||
background: #ffffff;
|
||
}
|
||
|
||
.query-page.query-layout {
|
||
padding: 24rpx 20rpx 40rpx;
|
||
background: #f5f7fb;
|
||
}
|
||
|
||
.query-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 4rpx 4rpx 20rpx;
|
||
}
|
||
|
||
.query-title,
|
||
.query-subtitle {
|
||
display: block;
|
||
}
|
||
|
||
.query-title {
|
||
color: #17233d;
|
||
font-size: 32rpx;
|
||
font-weight: 800;
|
||
line-height: 1.3;
|
||
}
|
||
|
||
.query-subtitle {
|
||
margin-top: 8rpx;
|
||
color: #8a94a6;
|
||
font-size: 18rpx;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.query-tabs {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 10rpx;
|
||
margin-top: 8rpx;
|
||
}
|
||
|
||
.query-tab {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 6rpx;
|
||
height: 68rpx;
|
||
border: 1rpx solid transparent;
|
||
border-radius: 14rpx;
|
||
background: #edf0f5;
|
||
color: #7d8798;
|
||
font-size: 20rpx;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
}
|
||
|
||
.query-tab.is-active {
|
||
background: #2f6cf6;
|
||
color: #ffffff;
|
||
box-shadow: 0 10rpx 24rpx rgba(47, 108, 246, 0.22);
|
||
}
|
||
|
||
.query-search-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0;
|
||
margin-top: 16rpx;
|
||
padding: 12rpx;
|
||
border: 1rpx solid #e9edf4;
|
||
border-radius: 18rpx;
|
||
background: #ffffff;
|
||
box-shadow: 0 8rpx 20rpx rgba(23, 35, 61, 0.04);
|
||
}
|
||
|
||
.query-input-wrap {
|
||
flex: 1;
|
||
min-width: 0;
|
||
height: 64rpx;
|
||
padding: 0 16rpx;
|
||
border: 1rpx solid #e3e7ef;
|
||
border-radius: 12rpx;
|
||
background: #f6f8fb;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.camera-button,
|
||
.query-button {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 64rpx;
|
||
border-radius: 12rpx;
|
||
background: #2f6cf6;
|
||
color: #ffffff;
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
box-shadow: 0 8rpx 18rpx rgba(47, 108, 246, 0.18);
|
||
}
|
||
|
||
.camera-button {
|
||
width: 64rpx;
|
||
margin-left: 16rpx;
|
||
flex: none;
|
||
transition: opacity 0.2s ease;
|
||
}
|
||
|
||
.camera-button.is-scanning {
|
||
opacity: 0.58;
|
||
}
|
||
|
||
.query-button {
|
||
width: 104rpx;
|
||
margin-left: 16rpx;
|
||
flex: none;
|
||
}
|
||
|
||
.advanced-trigger {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 14rpx;
|
||
padding: 18rpx 16rpx;
|
||
border: 1rpx solid #e9edf4;
|
||
border-radius: 14rpx;
|
||
background: #ffffff;
|
||
}
|
||
|
||
.advanced-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
color: #2c313a;
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
}
|
||
|
||
.advanced-state {
|
||
margin-left: 4rpx;
|
||
padding: 2rpx 8rpx;
|
||
border-radius: 8rpx;
|
||
background: #eef5ff;
|
||
color: #3a82ff;
|
||
font-size: 18rpx;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.advanced-panel {
|
||
margin-top: 10rpx;
|
||
padding: 20rpx 18rpx 16rpx;
|
||
border: 1rpx solid #e9edf4;
|
||
border-radius: 16rpx;
|
||
background: #ffffff;
|
||
box-shadow: 0 8rpx 20rpx rgba(23, 35, 61, 0.04);
|
||
}
|
||
|
||
.status-filter-label {
|
||
margin-top: 10rpx;
|
||
}
|
||
|
||
.compact-chip-row {
|
||
gap: 10rpx;
|
||
}
|
||
|
||
.chip {
|
||
padding: 12rpx 18rpx;
|
||
border-radius: 999rpx;
|
||
background: #f1f4f8;
|
||
color: #6b778c;
|
||
font-size: 20rpx;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.chip.is-active {
|
||
background: #2f6cf6;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.filter-actions {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 12rpx;
|
||
color: #6b778c;
|
||
font-size: 20rpx;
|
||
}
|
||
|
||
.filter-confirm {
|
||
color: #2f6cf6;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.result-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 20rpx;
|
||
padding: 0 6rpx 8rpx;
|
||
color: #7d8798;
|
||
font-size: 18rpx;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.record-list {
|
||
margin-top: 2rpx;
|
||
}
|
||
|
||
.record-card.compact-record {
|
||
margin-top: 10rpx;
|
||
padding: 20rpx 18rpx 16rpx;
|
||
border: 1rpx solid #edf0f5;
|
||
border-radius: 16rpx;
|
||
background: #ffffff;
|
||
box-shadow: 0 8rpx 18rpx rgba(23, 35, 61, 0.04);
|
||
}
|
||
|
||
.record-top {
|
||
align-items: center;
|
||
}
|
||
|
||
.record-number {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
min-width: 0;
|
||
}
|
||
|
||
.record-main {
|
||
max-width: 430rpx;
|
||
overflow: hidden;
|
||
color: #17233d;
|
||
font-size: 26rpx;
|
||
font-weight: 800;
|
||
line-height: 1.35;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.record-type-pill {
|
||
padding: 6rpx 12rpx;
|
||
border: 1rpx solid #b7ec8f;
|
||
border-radius: 999rpx;
|
||
background: #f8fff0;
|
||
color: #7ad63a;
|
||
font-size: 18rpx;
|
||
line-height: 1.35;
|
||
flex: none;
|
||
}
|
||
|
||
.record-detail-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 8rpx 18rpx;
|
||
margin-top: 16rpx;
|
||
padding-top: 14rpx;
|
||
border-top: 1rpx solid #f0f2f6;
|
||
}
|
||
|
||
.record-detail {
|
||
display: flex;
|
||
align-items: baseline;
|
||
font-size: 20rpx;
|
||
line-height: 1.55;
|
||
color: #7d8798;
|
||
}
|
||
|
||
.record-detail text:last-child {
|
||
color: #2b313b;
|
||
margin-left: 4rpx;
|
||
}
|
||
|
||
.record-status.is-success {
|
||
color: #7ad63a;
|
||
}
|
||
|
||
.record-status.is-failed {
|
||
color: #ff8a5b;
|
||
}
|
||
|
||
.record-footer {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 14rpx;
|
||
padding-top: 10rpx;
|
||
border-top: 1rpx solid #f5f6f8;
|
||
color: #9aa4b4;
|
||
font-size: 18rpx;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.detail-mask {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 999;
|
||
display: flex;
|
||
align-items: flex-end;
|
||
background: rgba(0, 0, 0, 0.32);
|
||
}
|
||
|
||
.sheet-handle {
|
||
width: 64rpx;
|
||
height: 8rpx;
|
||
margin: 0 auto 18rpx;
|
||
border-radius: 999rpx;
|
||
background: #dfe4ec;
|
||
}
|
||
|
||
.detail-sheet {
|
||
width: 100%;
|
||
max-height: 72vh;
|
||
overflow: auto;
|
||
padding: 22rpx 22rpx 30rpx;
|
||
border-radius: 24rpx 24rpx 0 0;
|
||
background: #ffffff;
|
||
box-shadow: 0 -16rpx 40rpx rgba(0, 0, 0, 0.08);
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.detail-sheet-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
color: #17233d;
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.sheet-main-no {
|
||
display: block;
|
||
margin-top: 12rpx;
|
||
color: #17233d;
|
||
font-size: 32rpx;
|
||
font-weight: 800;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.sheet-detail-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 12rpx;
|
||
margin-top: 16rpx;
|
||
}
|
||
|
||
.sheet-detail-item {
|
||
padding: 14rpx;
|
||
border-radius: 14rpx;
|
||
background: #f8fbff;
|
||
}
|
||
|
||
.sheet-detail-item text:first-child {
|
||
display: block;
|
||
color: #7d8798;
|
||
font-size: 18rpx;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.sheet-detail-item text:last-child {
|
||
display: block;
|
||
margin-top: 4rpx;
|
||
color: #17233d;
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
line-height: 1.35;
|
||
}
|
||
|
||
.sheet-remark {
|
||
margin-top: 14rpx;
|
||
padding: 14rpx;
|
||
border-radius: 14rpx;
|
||
background: #f8fbff;
|
||
color: #7d8798;
|
||
font-size: 18rpx;
|
||
line-height: 1.45;
|
||
}
|
||
|
||
.sheet-remark text:last-child {
|
||
display: block;
|
||
margin-top: 4rpx;
|
||
color: #17233d;
|
||
font-size: 22rpx;
|
||
line-height: 1.45;
|
||
}
|
||
|
||
.theme-dark.query-page {
|
||
background: #151923;
|
||
}
|
||
|
||
.theme-dark .query-header,
|
||
.theme-dark .query-search-row,
|
||
.theme-dark .advanced-trigger,
|
||
.theme-dark .advanced-panel,
|
||
.theme-dark .record-card,
|
||
.theme-dark .detail-sheet {
|
||
border-color: #364152;
|
||
background: #222936;
|
||
box-shadow: none;
|
||
}
|
||
|
||
.theme-dark .query-tab:not(.is-active),
|
||
.theme-dark .query-input-wrap,
|
||
.theme-dark .chip,
|
||
.theme-dark .record-info,
|
||
.theme-dark .sheet-detail-item,
|
||
.theme-dark .sheet-remark {
|
||
border-color: #364152;
|
||
background: #1c2431;
|
||
}
|
||
|
||
.theme-dark .query-title,
|
||
.theme-dark .advanced-title,
|
||
.theme-dark .record-main,
|
||
.theme-dark .record-detail text:last-child,
|
||
.theme-dark .detail-sheet-header,
|
||
.theme-dark .sheet-main-no,
|
||
.theme-dark .sheet-detail-item text:last-child,
|
||
.theme-dark .sheet-remark text:last-child {
|
||
color: #f2f5fa;
|
||
}
|
||
|
||
.theme-dark .query-subtitle,
|
||
.theme-dark .result-header,
|
||
.theme-dark .filter-actions,
|
||
.theme-dark .record-detail,
|
||
.theme-dark .record-footer,
|
||
.theme-dark .sheet-detail-item text:first-child,
|
||
.theme-dark .sheet-remark {
|
||
color: #aeb9ca;
|
||
}
|
||
|
||
.theme-dark .record-detail-grid,
|
||
.theme-dark .record-footer {
|
||
border-color: #364152;
|
||
}
|
||
|
||
.theme-dark :deep(.u-input__input) {
|
||
color: #f2f5fa !important;
|
||
}
|
||
</style>
|