You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

985 lines
24 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="page-container">
<!-- 顶部导航栏 -->
<NavBar :title="t('moldOperate.tabDown')">
<template #right>
<view class="nav-right-btn" @click="goToHistory">
<uni-icons type="clock" size="22" color="#1f7cff"></uni-icons>
<text class="nav-right-text">{{ t('moldPressureNet.history') }}</text>
</view>
</template>
</NavBar>
<!-- 操作按钮区 -->
<view class="action-row">
<view class="action-btn scan-btn" @click="handleScan">
<view class="btn-icon-wrap">
<text class="iconfont icon-scan btn-icon"></text>
</view>
<text class="btn-text">{{ t('moldOperate.scanDevice') }}</text>
</view>
<view class="action-btn select-btn" @click="openDevicePicker">
<view class="btn-icon-wrap">
<text class="iconfont icon-device btn-icon"></text>
</view>
<text class="btn-text">{{ t('moldOperate.selectDevice') }}</text>
</view>
</view>
<!-- 设备信息卡片 -->
<view class="section-card">
<view class="section-title-bar">
<view class="section-bar-line"></view>
<text class="section-title">{{ t('moldOperate.deviceInfo') }}</text>
</view>
<view class="card-body-grid">
<view class="grid-row">
<view class="grid-cell">
<text class="grid-label">{{ t('moldOperate.deviceName') }}</text>
<text class="grid-value">{{ textValue(selectedDevice.deviceName) }}</text>
</view>
<view class="grid-cell">
<text class="grid-label">{{ t('moldOperate.deviceCode') }}</text>
<text class="grid-value">{{ textValue(selectedDevice.deviceCode) }}</text>
</view>
</view>
<view class="grid-row">
<view class="grid-cell">
<text class="grid-label">{{ t('moldOperate.productionLine') }}</text>
<text class="grid-value">{{ getTopLineName(selectedDevice.deviceLine) }}</text>
</view>
<view class="grid-cell">
<text class="grid-label">{{ t('moldOperate.deviceStatus') }}</text>
<view class="status-tag" :class="deviceStatusClass">{{ deviceStatusLabel }}</view>
</view>
</view>
</view>
</view>
<!-- 当前在机模具 -->
<view class="section-card">
<view class="section-title-bar">
<view class="section-bar-line"></view>
<text class="section-title">{{ t('moldOperate.currentMoldInfo') }}</text>
</view>
<template v-if="selectedMold && selectedMold.id">
<view class="card-body-grid">
<view class="grid-row">
<view class="grid-cell">
<text class="grid-label">{{ t('moldOperate.moldName') }}</text>
<text class="grid-value highlight">{{ textValue(selectedMold.moldName) }}</text>
</view>
<view class="grid-cell">
<text class="grid-label">{{ t('moldOperate.moldCode') }}</text>
<text class="grid-value">{{ textValue(selectedMold.moldCode) }}</text>
</view>
</view>
<view class="grid-row">
<view class="grid-cell">
<text class="grid-label">{{ t('moldOperate.product') }}</text>
<text class="grid-value">{{ textValue(selectedMold.productName) }}</text>
</view>
</view>
</view>
<!-- 更换下模对象按钮 -->
<view class="change-target-btn" @click="openLowerMoldPicker">
<text class="change-icon">&#8644;</text>
<text class="change-text">{{ t('moldOperate.changeTarget') }}</text>
</view>
</template>
<!-- 已选设备但无在机模具 -->
<view v-else-if="selectedDevice.id && moldsLoaded" class="empty-mold-hint">
<text class="empty-mold-text empty-gray">{{ t('moldOperate.noMoldOnDevice') }}</text>
</view>
<!-- 未选设备 -->
<view v-else class="empty-mold-hint">
<text class="empty-mold-text empty-gray">{{ t('moldOperate.clickSelectDeviceFirst') }}</text>
</view>
</view>
<!-- 操作人与备注 -->
<view class="section-card">
<view class="section-title-bar">
<view class="section-bar-line"></view>
<text class="section-title">{{ t('moldOperate.operator') + ' & ' + t('moldOperate.remark') }}</text>
</view>
<view class="card-body-grid">
<view class="form-row">
<view class="form-cell">
<text class="form-label"><text class="required">*</text>{{ t('moldOperate.operator') }}</text>
<view class="dropdown-input readonly-input">
<text class="dropdown-value">{{ currentUserName }}</text>
</view>
</view>
</view>
<view class="form-row">
<view class="form-cell">
<text class="form-label">{{ t('moldOperate.remark') }}</text>
<input
class="form-input"
v-model="remarkText"
:placeholder="t('moldOperate.placeholderRemark')"
:maxlength="200"
/>
</view>
</view>
</view>
</view>
<!-- 底部操作栏 -->
<view class="bottom-actions">
<view class="bottom-btn cancel-btn" @click="handleCancel">{{ t('functionCommon.cancel') }}</view>
<view class="bottom-btn confirm-btn" @click="handleConfirm">{{ t('moldOperate.confirmDismount') }}</view>
</view>
<!-- 在机模具选择弹框(更换下模对象) -->
<uni-popup ref="lowerMoldPickerRef" type="bottom">
<view class="picker-popup">
<view class="picker-header">
<text class="picker-close-left" @click="closeLowerMoldPicker">{{ t('functionCommon.cancel') }}</text>
<text class="picker-title">{{ t('moldOperate.currentMoldInfo') }}</text>
<text class="picker-close-right" @click="confirmLowerMoldSelection">{{ t('functionCommon.confirm') }}</text>
</view>
<scroll-view scroll-y class="picker-scroll">
<view v-for="m in lowerMoldOptions" :key="m.id || m.moldId"
class="picker-item" :class="{ active: tempSelectedMoldId === String(m.id || m.moldId) }"
@click="tempSelectedMoldId = String(m.id || m.moldId)">
<view class="picker-item-content">
<text class="picker-item-name">{{ textValue(m.moldName || m.name) }}</text>
<text class="picker-item-code">{{ textValue(m.moldCode || m.code) }}</text>
</view>
<text class="picker-check-icon" v-if="tempSelectedMoldId === String(m.id || m.moldId)">&#10003;</text>
</view>
<view v-if="lowerMoldLoading" class="picker-hint">{{ t('functionCommon.loading') }}</view>
<view v-else-if="!lowerMoldOptions.length" class="picker-empty">{{ t('moldOperate.noMoldOnDevice') }}</view>
</scroll-view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { computed, reactive, ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { useI18n } from 'vue-i18n'
import NavBar from '@/components/common/NavBar.vue'
import { getDeviceLedgerList, createMoldOperate } from '@/api/mes/moldoperate'
import { getMoldBrandPage } from '@/api/mes/mold'
import useUserStore from '@/store/modules/user'
import { getDeviceLineTree } from '@/api/mes/deviceLine'
const { t } = useI18n()
const userStore = useUserStore()
// 当前登录用户
const currentUserName = computed(() => userStore.name || '未知用户')
const currentUserId = computed(() => userStore.userId)
const lineInfoMap = ref(new Map()) // deviceLine id → { name, parentId, parentChain }
// 递归拍平产线树(保存完整节点信息用于向上追溯)
function flattenLineTree(nodes, parentId) {
if (!Array.isArray(nodes)) return
for (const node of nodes) {
if (node.id != null && node.name != null) {
lineInfoMap.value.set(String(node.id), {
id: node.id,
name: node.name,
parentId: node.parentId != null ? node.parentId : (parentId || null),
parentChain: node.parentChain || ''
})
}
if (Array.isArray(node.children)) {
flattenLineTree(node.children, node.id)
}
}
}
// 根据设备产线节点,向上追溯顶层产线名称(参考后端 fillTopCategoryInfo 逻辑)
function getTopLineName(deviceLineId) {
if (deviceLineId == null) return '-'
const node = lineInfoMap.value.get(String(deviceLineId))
if (!node) return String(deviceLineId)
// 策略1通过 parentChain 取第一个 ID最顶层
if (node.parentChain) {
const firstId = node.parentChain.split(',')[0]?.trim()
if (firstId) {
const topNode = lineInfoMap.value.get(firstId)
if (topNode) return topNode.name
}
}
// 策略2通过 parentId 向上遍历直到根节点
let current = node
const visited = new Set()
while (current.parentId != null && current.parentId > 0 && !visited.has(current.id)) {
visited.add(current.id)
const parent = lineInfoMap.value.get(String(current.parentId))
if (!parent) break
current = parent
}
return current.name || String(deviceLineId)
}
// 加载产线树
async function loadLineTree() {
if (lineInfoMap.value.size > 0) return
try {
const res = await getDeviceLineTree()
const tree = (res && res.data !== undefined) ? res.data : res
const nodes = Array.isArray(tree) ? tree : (tree?.list || tree?.children || [])
flattenLineTree(nodes)
} catch (e) {
console.error('load line tree error', e)
}
}
// ---- 设备相关 ----
const selectedDevice = ref({})
const deviceOptions = ref([])
// ---- 模具相关 ----
const selectedMold = ref({})
const lowerMoldPickerRef = ref(null)
const lowerMoldOptions = ref([])
const lowerMoldLoading = ref(false)
const moldsLoaded = ref(false)
const tempSelectedMoldId = ref(null)
// ---- 操作人与备注 ----
const remarkText = ref('')
const selectedOperator = ref(null)
// ---- 工具函数 ----
function textValue(v) {
if (v === 0) return '0'
if (v == null) return '-'
const s = String(v).trim()
return s || '-'
}
function formatTime(time) {
if (!time) return '-'
if (typeof time === 'string') {
if (time.includes('-') || time.includes('T')) {
return time.replace(/T/, ' ').substring(0, 19)
}
const ts = Number(time)
if (!isNaN(ts) && ts > 1e10) return new Date(ts).toLocaleString()
else if (!isNaN(ts) && ts > 1e7) return new Date(ts * 1000).toLocaleString()
return time
}
if (typeof time === 'number') {
if (time > 1e10) return new Date(time).toLocaleString()
if (time > 1e7) return new Date(time * 1000).toLocaleString()
return String(time)
}
return '-'
}
const deviceStatusClass = computed(() => {
const status = Number(selectedDevice.value?.deviceStatus)
if (status === 0) return 'running-tag'
if (status === 1) return 'stop-tag'
if (status >= 2) return 'fault-tag'
return ''
})
const deviceStatusLabel = computed(() => {
const status = Number(selectedDevice.value?.deviceStatus)
const map = {
0: t('moldOperate.statusRunning'),
1: t('moldOperate.statusStop'),
2: t('moldOperate.statusFault'),
3: t('moldOperate.statusFault')
}
return map[status] || textValue(selectedDevice.value?.deviceStatus) || '-'
})
// ---- 数据加载 ----
async function loadDevices() {
try {
const res = await getDeviceLedgerList({ pageNo: 1, pageSize: 100 })
const root = res && res.data !== undefined ? res.data : res
const data = Array.isArray(root)
? root
: Array.isArray(root?.list) ? root.list
: Array.isArray(root?.rows) ? root.rows
: []
deviceOptions.value = data.map((d) => ({
value: d.id,
label: `${d.deviceCode || ''} ${d.deviceName || ''}`.trim(),
raw: d
}))
} catch (e) {
console.error('loadDevices error', e)
}
}
// 通用递归数组提取
function findArr(obj, d = 0) {
if (!obj || typeof obj !== 'object' || d > 3) return []
if (Array.isArray(obj)) return obj
for (const k of ['list', 'rows', 'records', 'items', 'data']) {
if (Array.isArray(obj[k])) return obj[k]
}
for (const v of Object.values(obj)) {
const found = findArr(v, d + 1)
if (found.length) return found
}
return []
}
async function loadLowerMolds(deviceName) {
lowerMoldLoading.value = true
try {
const res = await getMoldBrandPage({ deviceName, pageSize: 100 })
const root = (res && res.data !== undefined) ? res.data : res
const pageData = root?.pageResult || root
const list = Array.isArray(pageData) ? pageData : (Array.isArray(pageData?.list) ? pageData.list : [])
lowerMoldOptions.value = list.map(m => ({
id: m.id,
moldId: m.id,
moldName: m.name || '-',
moldCode: m.code || '-',
productName: m.productName || '-'
}))
} catch (e) {
console.error('loadLowerMolds error', e)
} finally {
lowerMoldLoading.value = false
}
}
// ---- 扫描设备码 ----
function handleScan() {
uni.scanCode({
onlyFromCamera: false,
scanType: ['qrCode', 'barCode'],
success(res) {
const code = res.result?.trim()
if (!code) return
const matched = deviceOptions.value.find((d) =>
d.raw.deviceCode === code || String(d.raw.code) === code || d.label.includes(code)
)
if (matched) {
selectDevice(matched.raw)
} else {
uni.showToast({ title: t('moldOperate.deviceNotFound'), icon: 'none' })
}
},
fail(err) {
if (err.errMsg && !err.errMsg.includes('cancel')) {
console.warn('scan failed:', err)
}
}
})
}
// ---- 设备选择 ----
function selectDevice(device) {
selectedDevice.value = device || {}
moldsLoaded.value = false
selectedMold.value = {}
if (device?.deviceName) {
loadLowerMolds(device.deviceName).then(() => {
moldsLoaded.value = true
if (lowerMoldOptions.value.length > 0) {
const first = lowerMoldOptions.value[0]
selectedMold.value = {
id: first.id || first.moldId,
moldName: first.moldName || first.name,
moldCode: first.moldCode || first.code,
productName: first.productName || '-'
}
}
})
}
}
function openDevicePicker() {
uni.navigateTo({ url: '/pages_function/pages/moldoperate/deviceSelect' })
}
// ---- 在机模具选择(更换下模对象)----
function openLowerMoldPicker() {
if (!selectedDevice.value?.deviceName) {
uni.showToast({ title: t('moldOperate.validatorDeviceRequired'), icon: 'none' })
return
}
tempSelectedMoldId.value = selectedMold.value ? String(selectedMold.value.id || selectedMold.value.moldId) : null
loadLowerMolds(selectedDevice.value.deviceName).then(() => {
lowerMoldPickerRef.value?.open()
})
}
function confirmLowerMoldSelection() {
const mold = lowerMoldOptions.value.find(
(m) => String(m.id || m.moldId) === tempSelectedMoldId.value
)
if (mold) {
selectedMold.value = {
id: mold.id || mold.moldId,
moldName: mold.moldName || mold.name,
moldCode: mold.moldCode || mold.code,
productName: mold.productName || '-'
}
}
lowerMoldPickerRef.value?.close()
}
function closeLowerMoldPicker() { lowerMoldPickerRef.value?.close() }
// ---- 操作人自动设置为当前登录用户 ----
function autoSetOperator() {
if (currentUserId.value && currentUserName.value) {
selectedOperator.value = {
value: currentUserId.value,
label: currentUserName.value
}
}
}
function goToHistory() {
uni.navigateTo({ url: '/pages_function/pages/moldoperate/history?type=down' })
}
function goBack() {
uni.navigateBack({ fail: () => uni.switchTab({ url: '/pages/index/index' }) })
}
// ---- 提交 ----
function validForm() {
if (!selectedDevice.value?.id) {
uni.showToast({ title: t('moldOperate.validatorDeviceRequired'), icon: 'none' })
return false
}
if (!selectedMold.value?.id) {
uni.showToast({ title: t('moldOperate.validatorLowerMoldRequired'), icon: 'none' })
return false
}
if (!selectedOperator.value) {
uni.showToast({ title: t('moldOperate.validatorOperatorRequired'), icon: 'none' })
return false
}
return true
}
async function handleConfirm() {
if (!validForm()) return
try {
const device = selectedDevice.value
const payload = {
operateType: '2',
deviceId: String(device.id),
moldId: String(selectedMold.value.id),
lineId: device.deviceLine != null ? String(device.deviceLine) : undefined,
lineName: device.deviceLine != null ? getTopLineName(device.deviceLine) : (device.lineName || undefined)
}
// 添加操作人和备注
if (selectedOperator.value) {
payload.operatorId = selectedOperator.value.value
}
if (remarkText.value.trim()) {
payload.remark = remarkText.value.trim()
}
console.log('[下模] 提交参数 =', JSON.stringify(payload))
await createMoldOperate(payload)
uni.showToast({ title: t('functionCommon.createSuccess'), icon: 'success' })
// 重置表单
selectedDevice.value = {}
selectedMold.value = {}
lowerMoldOptions.value = []
remarkText.value = ''
} catch (e) {
console.error('[下模] 保存失败 =', e)
const errMsg = e?.msg || (typeof e === 'string' ? e : e?.message) || '系统异常'
uni.showToast({ title: t('functionCommon.saveFailed') + ': ' + errMsg, icon: 'none', duration: 3000 })
}
}
function handleCancel() {
// 返回上一页(管理页面)
uni.navigateBack({
fail: () => uni.switchTab({ url: '/pages/work' })
})
}
onShow(async () => {
autoSetOperator()
await Promise.allSettled([loadDevices(), loadLineTree()])
// 从 globalData 读取设备选择页回传的设备
const device = getApp().globalData._deviceSelectResult
if (device) {
getApp().globalData._deviceSelectResult = null
selectDevice(device)
}
})
</script>
<style lang="scss" scoped>
/* ====== 导航栏右侧按钮 ====== */
.nav-right-btn {
display: flex;
align-items: center;
gap: 6rpx;
padding: 8rpx 18rpx;
background: #ffffff;
border-radius: 999rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.08);
}
.nav-right-text {
font-size: 24rpx;
color: #374151;
font-weight: 500;
}
.page-container {
min-height: 100vh;
background: #f5f6f8;
padding-bottom: 140rpx;
}
/* ====== 操作按钮区 ====== */
.action-row {
display: flex;
gap: 20rpx;
padding: 20rpx 24rpx;
}
.action-btn {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
gap: 12rpx;
height: 96rpx;
border-radius: 12rpx;
background: #1f4b79;
color: #fff;
font-size: 28rpx;
font-weight: 600;
.btn-icon-wrap {
width: 44rpx;
height: 44rpx;
display: flex;
align-items: center;
justify-content: center;
}
.btn-icon {
font-size: 36rpx;
color: #fff;
}
.btn-text {
font-size: 28rpx;
}
}
/* ====== 卡片通用样式 ====== */
.section-card {
margin: 16rpx 24rpx;
background: #ffffff;
border-radius: 14rpx;
}
.section-title-bar {
display: flex;
align-items: center;
gap: 10rpx;
padding: 22rpx 24rpx 0;
}
.section-bar-line {
width: 6rpx;
height: 32rpx;
border-radius: 3rpx;
background: #1f4b79;
}
.section-title {
font-size: 30rpx;
font-weight: 700;
color: #1a1a1a;
}
.card-body-grid {
padding: 20rpx 24rpx 28rpx;
}
/* ====== 网格布局 ====== */
.grid-row {
display: flex;
gap: 20rpx;
margin-top: 18rpx;
&:first-child {
margin-top: 0;
}
}
.grid-cell {
flex: 1;
min-width: 0;
&.full-width {
flex-basis: 100%;
display: flex;
align-items: center;
gap: 12rpx;
}
}
.grid-label {
display: block;
font-size: 24rpx;
color: #999;
margin-bottom: 6rpx;
}
.grid-value {
display: block;
font-size: 27rpx;
color: #333;
word-break: break-all;
&.highlight {
color: #2563eb;
font-weight: 600;
}
}
/* ====== 状态标签 ====== */
.status-tag {
display: inline-flex;
align-items: center;
padding: 6rpx 18rpx;
border-radius: 6rpx;
font-size: 24rpx;
font-weight: 500;
&.running-tag {
color: #059669;
background: #ecfdf5;
border: 1rpx solid #a7f3d0;
}
&.stop-tag {
color: #d97706;
background: #fffbeb;
border: 1rpx solid #fde68a;
}
&.fault-tag {
color: #dc2626;
background: #fef2f2;
border: 1rpx solid #fecaca;
}
&.pending-tag {
color: #2563eb;
background: #eff6ff;
border: 1rpx solid #bfdbfe;
}
}
/* ====== 更换下模对象按钮 ====== */
.change-target-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 8rpx;
margin: 0 24rpx 24rpx;
padding: 20rpx 0;
border: 1rpx dashed #ccc;
border-radius: 10rpx;
.change-icon {
font-size: 28rpx;
color: #666;
}
.change-text {
font-size: 26rpx;
color: #666;
}
&:active {
background: #fafafa;
}
}
/* ====== 表单行(操作人/备注) ====== */
.form-row {
margin-top: 18rpx;
&:first-child {
margin-top: 0;
}
}
.form-cell {
width: 100%;
.form-label {
display: block;
font-size: 24rpx;
color: #999;
margin-bottom: 8rpx;
.required {
color: #dc2626;
margin-right: 4rpx;
}
}
}
/* ====== 下拉选择器(操作人) ====== */
.select-dropdown {
position: relative;
width: 100%;
}
.dropdown-input {
display: flex;
align-items: center;
height: 72rpx;
padding: 0 20rpx;
border: 1rpx solid #e0e0e0;
border-radius: 10rpx;
font-size: 27rpx;
color: #333;
background: #f9fafb;
&.readonly-input {
background: #f8fafc;
border-color: #f0f0f0;
}
}
.dropdown-value {
flex: 1;
&.placeholder {
color: #bbb;
}
}
.dropdown-arrow {
position: absolute;
right: 16rpx;
top: 50%;
transform: translateY(-50%);
pointer-events: none;
}
/* ====== 下拉面板(在输入框下方展开) ====== */
.dropdown-panel {
position: absolute;
top: 76rpx;
left: 0;
right: 0;
z-index: 99;
background: #ffffff;
border: 1rpx solid #e0e0e0;
border-radius: 12rpx;
box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.dropdown-scroll {
max-height: 400rpx;
}
.dropdown-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 22rpx 28rpx;
font-size: 27rpx;
color: #333;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
&:active {
background: #f5f7fa;
}
&.active {
color: #1f7cff;
background: #f0f7ff;
}
}
.dropdown-item-text {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dropdown-empty {
padding: 32rpx;
text-align: center;
font-size: 26rpx;
color: #999;
}
.form-input {
height: 72rpx;
padding: 0 20rpx;
border: 1rpx solid #e0e0e0;
border-radius: 10rpx;
font-size: 27rpx;
color: #333;
background: #f9fafb;
}
/* ====== 空提示 ====== */
.empty-mold-hint {
padding: 40rpx 24rpx;
text-align: center;
}
.empty-mold-text {
font-size: 28rpx;
color: #2563eb;
}
.empty-gray {
color: #9ca3af;
}
/* ====== 底部操作栏 ====== */
.bottom-actions {
position: fixed;
left: 0;
right: 0;
bottom: 0;
display: flex;
gap: 18rpx;
padding: 18rpx 24rpx calc(18rpx + env(safe-area-inset-bottom));
background: #fff;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
z-index: 99;
}
.bottom-btn {
flex: 1;
height: 84rpx;
line-height: 84rpx;
text-align: center;
border-radius: 16rpx;
font-size: 30rpx;
font-weight: 600;
}
.confirm-btn {
background: #1f4b79;
color: #fff;
}
.cancel-btn {
background: #eef2f7;
color: #475569;
}
/* ====== 弹窗通用 ====== */
.picker-popup {
background: #fff;
border-radius: 24rpx 24rpx 0 0;
max-height: 75vh;
}
.picker-header {
height: 96rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.picker-close-left,
.picker-close-right {
font-size: 28rpx;
color: #2563eb;
padding: 8rpx 0;
}
.picker-title {
font-size: 30rpx;
font-weight: 700;
color: #1a1a1a;
}
.picker-scroll {
max-height: calc(75vh - 96rpx);
padding: 12rpx 0 32rpx;
}
.picker-item {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 24rpx 12rpx;
padding: 22rpx 20rpx;
border-radius: 12rpx;
background: #f8fafc;
&.active {
background: #eff6ff;
border: 1rpx solid #bfdbfe;
}
}
.picker-item-content {
flex: 1;
min-width: 0;
}
.picker-item-name {
display: block;
font-size: 28rpx;
color: #1a1a1a;
font-weight: 500;
}
.picker-item-code {
display: block;
font-size: 23rpx;
color: #999;
margin-top: 4rpx;
}
.picker-check-icon {
font-size: 30rpx;
color: #2563eb;
font-weight: 700;
margin-left: 16rpx;
flex-shrink: 0;
}
.picker-empty,
.picker-hint {
text-align: center;
color: #999;
padding: 60rpx 0;
font-size: 26rpx;
}
</style>