|
|
|
@ -85,37 +85,24 @@
|
|
|
|
<text class="drawer-title">{{ t('equipmentInspectionTasks.moreFilter') }}</text>
|
|
|
|
<text class="drawer-title">{{ t('equipmentInspectionTasks.moreFilter') }}</text>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
<scroll-view scroll-y class="drawer-body">
|
|
|
|
<scroll-view scroll-y class="drawer-body">
|
|
|
|
<view class="drawer-section">
|
|
|
|
<view class="drawer-section drawer-fields">
|
|
|
|
<view class="drawer-section-head">
|
|
|
|
<view class="drawer-field">
|
|
|
|
<text class="drawer-section-title">{{ t('equipmentInspectionTasks.filterScope') }}</text>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<view class="drawer-field drawer-field-wide">
|
|
|
|
|
|
|
|
<text class="drawer-label">{{ t('equipmentInspectionTasks.projectFormName') }}</text>
|
|
|
|
<text class="drawer-label">{{ t('equipmentInspectionTasks.projectFormName') }}</text>
|
|
|
|
<view class="drawer-picker" @click="togglePlanPanel">
|
|
|
|
<picker class="drawer-picker-host" mode="selector" :range="planPickerOptions" range-key="label" :value="planPickerIndex" @change="onPlanPickerChange">
|
|
|
|
<text :class="['drawer-picker-text', selectedPlanIds.length ? '' : 'placeholder']">{{ selectedPlanLabel }}</text>
|
|
|
|
<view class="drawer-picker">
|
|
|
|
<uni-icons type="bottom" size="14" color="#9ca3af"></uni-icons>
|
|
|
|
<text :class="['drawer-picker-text', selectedPlanIds.length ? '' : 'placeholder']">{{ selectedPlanLabel }}</text>
|
|
|
|
</view>
|
|
|
|
<uni-icons type="bottom" size="14" color="#9ca3af"></uni-icons>
|
|
|
|
<scroll-view v-if="planPanelOpen" scroll-y class="drawer-option-panel">
|
|
|
|
|
|
|
|
<view v-for="option in drawerPlanOptions" :key="option.id" :class="['drawer-option-item', selectedPlanIds.includes(String(option.id)) ? 'active' : '']" @click="togglePlanOption(option)">
|
|
|
|
|
|
|
|
<text class="drawer-option-text">{{ option.name }}</text>
|
|
|
|
|
|
|
|
<uni-icons v-if="selectedPlanIds.includes(String(option.id))" type="checkmarkempty" size="18" color="#174b78"></uni-icons>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
<view v-if="!drawerPlanOptions.length" class="drawer-option-empty">{{ t('equipmentInspectionTasks.noPlanData') }}</view>
|
|
|
|
</picker>
|
|
|
|
</scroll-view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
<view class="drawer-field drawer-field-wide drawer-field-gap">
|
|
|
|
<view class="drawer-field">
|
|
|
|
<text class="drawer-label">{{ t('equipmentInspectionTasks.deviceList') }}</text>
|
|
|
|
<text class="drawer-label">{{ t('equipmentInspectionTasks.deviceList') }}</text>
|
|
|
|
<view class="drawer-picker" @click="toggleDevicePanel">
|
|
|
|
<picker class="drawer-picker-host" mode="selector" :range="devicePickerOptions" range-key="label" :value="devicePickerIndex" @change="onDevicePickerChange">
|
|
|
|
<text :class="['drawer-picker-text', selectedDeviceIds.length ? '' : 'placeholder']">{{ selectedDeviceLabel }}</text>
|
|
|
|
<view class="drawer-picker">
|
|
|
|
<uni-icons type="bottom" size="14" color="#9ca3af"></uni-icons>
|
|
|
|
<text :class="['drawer-picker-text', selectedDeviceIds.length ? '' : 'placeholder']">{{ selectedDeviceLabel }}</text>
|
|
|
|
</view>
|
|
|
|
<uni-icons type="bottom" size="14" color="#9ca3af"></uni-icons>
|
|
|
|
<scroll-view v-if="devicePanelOpen" scroll-y class="drawer-option-panel">
|
|
|
|
|
|
|
|
<view v-for="option in drawerDeviceOptions" :key="option.id" :class="['drawer-option-item', selectedDeviceIds.includes(String(option.id)) ? 'active' : '']" @click="toggleDeviceOption(option)">
|
|
|
|
|
|
|
|
<text class="drawer-option-text">{{ option.label }}</text>
|
|
|
|
|
|
|
|
<uni-icons v-if="selectedDeviceIds.includes(String(option.id))" type="checkmarkempty" size="18" color="#174b78"></uni-icons>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
<view v-if="!drawerDeviceOptions.length" class="drawer-option-empty">{{ t('equipmentInspectionTasks.noDeviceData') }}</view>
|
|
|
|
</picker>
|
|
|
|
</scroll-view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</scroll-view>
|
|
|
|
</scroll-view>
|
|
|
|
@ -160,8 +147,6 @@ const selectedTaskType = ref('')
|
|
|
|
const selectedPlanIds = ref([])
|
|
|
|
const selectedPlanIds = ref([])
|
|
|
|
const selectedDeviceIds = ref([])
|
|
|
|
const selectedDeviceIds = ref([])
|
|
|
|
const planOptions = ref([])
|
|
|
|
const planOptions = ref([])
|
|
|
|
const planPanelOpen = ref(false)
|
|
|
|
|
|
|
|
const devicePanelOpen = ref(false)
|
|
|
|
|
|
|
|
const filterPopupRef = ref(null)
|
|
|
|
const filterPopupRef = ref(null)
|
|
|
|
const list = ref([])
|
|
|
|
const list = ref([])
|
|
|
|
const loading = ref(false)
|
|
|
|
const loading = ref(false)
|
|
|
|
@ -226,7 +211,22 @@ const drawerDeviceOptions = computed(() => deviceOptions.value.map((item) => ({
|
|
|
|
|
|
|
|
|
|
|
|
const selectedPlanLabel = computed(() => formatSelectedSummary(selectedPlanIds.value, drawerPlanOptions.value, 'name', t('equipmentInspectionTasks.placeholderProjectForm')))
|
|
|
|
const selectedPlanLabel = computed(() => formatSelectedSummary(selectedPlanIds.value, drawerPlanOptions.value, 'name', t('equipmentInspectionTasks.placeholderProjectForm')))
|
|
|
|
const selectedDeviceLabel = computed(() => formatSelectedSummary(selectedDeviceIds.value, drawerDeviceOptions.value, 'label', t('equipmentInspectionTasks.placeholderDeviceList')))
|
|
|
|
const selectedDeviceLabel = computed(() => formatSelectedSummary(selectedDeviceIds.value, drawerDeviceOptions.value, 'label', t('equipmentInspectionTasks.placeholderDeviceList')))
|
|
|
|
|
|
|
|
const planPickerOptions = computed(() => [
|
|
|
|
|
|
|
|
{ id: '', label: t('functionCommon.all') },
|
|
|
|
|
|
|
|
...drawerPlanOptions.value.map((item) => ({
|
|
|
|
|
|
|
|
id: item.id,
|
|
|
|
|
|
|
|
label: formatPickerOptionLabel(selectedPlanIds.value, item.id, item.name)
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
const devicePickerOptions = computed(() => [
|
|
|
|
|
|
|
|
{ id: '', label: t('functionCommon.all') },
|
|
|
|
|
|
|
|
...drawerDeviceOptions.value.map((item) => ({
|
|
|
|
|
|
|
|
id: item.id,
|
|
|
|
|
|
|
|
label: formatPickerOptionLabel(selectedDeviceIds.value, item.id, item.label)
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
const planPickerIndex = computed(() => getPickerIndex(planPickerOptions.value, selectedPlanIds.value))
|
|
|
|
|
|
|
|
const devicePickerIndex = computed(() => getPickerIndex(devicePickerOptions.value, selectedDeviceIds.value))
|
|
|
|
onLoad(async () => {
|
|
|
|
onLoad(async () => {
|
|
|
|
activateKeywordFocus()
|
|
|
|
activateKeywordFocus()
|
|
|
|
await Promise.all([loadLineTree(), ensurePlanOptionsLoaded(), ensureDeviceOptionsLoaded()])
|
|
|
|
await Promise.all([loadLineTree(), ensurePlanOptionsLoaded(), ensureDeviceOptionsLoaded()])
|
|
|
|
@ -411,28 +411,26 @@ function closeFilterDrawer() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function confirmFilterDrawer() {
|
|
|
|
async function confirmFilterDrawer() {
|
|
|
|
planPanelOpen.value = false
|
|
|
|
|
|
|
|
devicePanelOpen.value = false
|
|
|
|
|
|
|
|
closeFilterDrawer()
|
|
|
|
closeFilterDrawer()
|
|
|
|
await fetchList(true)
|
|
|
|
await fetchList(true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function togglePlanPanel() {
|
|
|
|
function onPlanPickerChange(event) {
|
|
|
|
planPanelOpen.value = !planPanelOpen.value
|
|
|
|
handleMultiPickerChange(planPickerOptions.value, selectedPlanIds, event)
|
|
|
|
devicePanelOpen.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function toggleDevicePanel() {
|
|
|
|
function onDevicePickerChange(event) {
|
|
|
|
devicePanelOpen.value = !devicePanelOpen.value
|
|
|
|
handleMultiPickerChange(devicePickerOptions.value, selectedDeviceIds, event)
|
|
|
|
planPanelOpen.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function togglePlanOption(option) {
|
|
|
|
function handleMultiPickerChange(options, targetRef, event) {
|
|
|
|
toggleStringSelection(selectedPlanIds, option?.id)
|
|
|
|
const index = Number(event?.detail?.value || 0)
|
|
|
|
}
|
|
|
|
const option = options[index]
|
|
|
|
|
|
|
|
if (!option || option.id === '') {
|
|
|
|
function toggleDeviceOption(option) {
|
|
|
|
targetRef.value = []
|
|
|
|
toggleStringSelection(selectedDeviceIds, option?.id)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleStringSelection(targetRef, option.id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function toggleStringSelection(targetRef, value) {
|
|
|
|
function toggleStringSelection(targetRef, value) {
|
|
|
|
@ -442,6 +440,18 @@ function toggleStringSelection(targetRef, value) {
|
|
|
|
targetRef.value = current.includes(id) ? current.filter((item) => item !== id) : [...current, id]
|
|
|
|
targetRef.value = current.includes(id) ? current.filter((item) => item !== id) : [...current, id]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function getPickerIndex(options, selectedIds) {
|
|
|
|
|
|
|
|
const selected = Array.isArray(selectedIds) ? selectedIds.map((item) => String(item)) : []
|
|
|
|
|
|
|
|
if (!selected.length) return 0
|
|
|
|
|
|
|
|
const index = options.findIndex((item) => selected.includes(String(item.id)))
|
|
|
|
|
|
|
|
return index >= 0 ? index : 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatPickerOptionLabel(selectedIds, id, label) {
|
|
|
|
|
|
|
|
const selected = (Array.isArray(selectedIds) ? selectedIds : []).map((item) => String(item))
|
|
|
|
|
|
|
|
return `${selected.includes(String(id)) ? '[x]' : '[ ]'} ${label}`
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function formatSelectedSummary(ids, options, labelKey, placeholder) {
|
|
|
|
function formatSelectedSummary(ids, options, labelKey, placeholder) {
|
|
|
|
const selected = Array.isArray(ids) ? ids : []
|
|
|
|
const selected = Array.isArray(ids) ? ids : []
|
|
|
|
if (!selected.length) return placeholder
|
|
|
|
if (!selected.length) return placeholder
|
|
|
|
@ -471,8 +481,6 @@ async function resetFilters() {
|
|
|
|
selectedTaskType.value = ''
|
|
|
|
selectedTaskType.value = ''
|
|
|
|
selectedPlanIds.value = []
|
|
|
|
selectedPlanIds.value = []
|
|
|
|
selectedDeviceIds.value = []
|
|
|
|
selectedDeviceIds.value = []
|
|
|
|
planPanelOpen.value = false
|
|
|
|
|
|
|
|
devicePanelOpen.value = false
|
|
|
|
|
|
|
|
closeFilterDrawer()
|
|
|
|
closeFilterDrawer()
|
|
|
|
resetLineFilter()
|
|
|
|
resetLineFilter()
|
|
|
|
activateKeywordFocus()
|
|
|
|
activateKeywordFocus()
|
|
|
|
@ -626,23 +634,16 @@ function formatDate(value) {
|
|
|
|
.drawer-header { height: 104rpx; padding: 18rpx 34rpx 0; background: #ffffff; display: flex; align-items: center; box-sizing: border-box; }
|
|
|
|
.drawer-header { height: 104rpx; padding: 18rpx 34rpx 0; background: #ffffff; display: flex; align-items: center; box-sizing: border-box; }
|
|
|
|
.drawer-title { color: #1f2937; font-size: 34rpx; line-height: 1.3; font-weight: 700; }
|
|
|
|
.drawer-title { color: #1f2937; font-size: 34rpx; line-height: 1.3; font-weight: 700; }
|
|
|
|
.drawer-body { flex: 1; min-height: 0; padding-bottom: 40rpx; box-sizing: border-box; }
|
|
|
|
.drawer-body { flex: 1; min-height: 0; padding-bottom: 40rpx; box-sizing: border-box; }
|
|
|
|
.drawer-section { margin-bottom: 18rpx; padding: 28rpx 28rpx 30rpx; border-radius: 24rpx; background: #ffffff; box-sizing: border-box; }
|
|
|
|
.drawer-section { margin-bottom: 18rpx; padding: 8rpx 28rpx; border-radius: 24rpx; background: #ffffff; box-sizing: border-box; }
|
|
|
|
.drawer-section-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 24rpx; }
|
|
|
|
.drawer-fields { display: flex; flex-direction: column; }
|
|
|
|
.drawer-section-title { font-size: 32rpx; line-height: 1.3; color: #1f2937; font-weight: 700; }
|
|
|
|
.drawer-field { min-width: 0; min-height: 98rpx; display: flex; align-items: center; gap: 20rpx; border-bottom: 1rpx solid #eceff3; box-sizing: border-box; }
|
|
|
|
.drawer-field { min-width: 0; }
|
|
|
|
.drawer-field:last-child { border-bottom: 0; }
|
|
|
|
.drawer-field-wide { grid-column: 1 / -1; }
|
|
|
|
.drawer-field-wide { grid-column: auto; }
|
|
|
|
.drawer-field-gap { margin-top: 22rpx; }
|
|
|
|
.drawer-label { width: 160rpx; flex: 0 0 160rpx; font-size: 24rpx; line-height: 1.3; color: #4b5563; font-weight: 500; }
|
|
|
|
.drawer-label { display: block; margin-bottom: 12rpx; font-size: 24rpx; line-height: 1.3; color: #4b5563; font-weight: 500; }
|
|
|
|
.drawer-picker-host { min-width: 0; flex: 1; display: block; }
|
|
|
|
.drawer-picker { width: 100%; min-height: 74rpx; border: 0; border-radius: 8rpx; background: #f7f8fb; box-sizing: border-box; display: flex; align-items: center; justify-content: center; padding: 0 18rpx; gap: 8rpx; }
|
|
|
|
.drawer-picker { width: 100%; min-height: 74rpx; border: 0; border-radius: 8rpx; background: #f7f8fb; box-sizing: border-box; display: flex; align-items: center; justify-content: flex-end; padding: 0 18rpx; gap: 8rpx; }
|
|
|
|
.drawer-picker-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 26rpx; color: #111827; text-align: center; }
|
|
|
|
.drawer-picker-text { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 26rpx; color: #111827; text-align: right; }
|
|
|
|
.drawer-picker-text.placeholder { color: #9ca3af; }
|
|
|
|
.drawer-picker-text.placeholder { color: #9ca3af; }
|
|
|
|
.drawer-option-panel { max-height: 420rpx; margin-top: 12rpx; border-radius: 12rpx; background: #f7f8fb; overflow: hidden; }
|
|
|
|
|
|
|
|
.drawer-option-item { min-height: 72rpx; padding: 0 24rpx; display: flex; align-items: center; gap: 12rpx; border-bottom: 1rpx solid #eceff3; box-sizing: border-box; }
|
|
|
|
|
|
|
|
.drawer-option-item:last-child { border-bottom: 0; }
|
|
|
|
|
|
|
|
.drawer-option-item.active { background: rgba(23, 75, 120, 0.1); }
|
|
|
|
|
|
|
|
.drawer-option-item.active .drawer-option-text { color: #174b78; font-weight: 600; }
|
|
|
|
|
|
|
|
.drawer-option-text { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 26rpx; color: #1f2937; }
|
|
|
|
|
|
|
|
.drawer-option-empty { padding: 28rpx 0; text-align: center; font-size: 26rpx; color: #9ca3af; }
|
|
|
|
|
|
|
|
.drawer-actions { height: 126rpx; padding: 18rpx 28rpx 24rpx; box-sizing: border-box; display: flex; align-items: center; gap: 0; background: #ffffff; box-shadow: 0 -8rpx 24rpx rgba(17, 24, 39, 0.06); }
|
|
|
|
.drawer-actions { height: 126rpx; padding: 18rpx 28rpx 24rpx; box-sizing: border-box; display: flex; align-items: center; gap: 0; background: #ffffff; box-shadow: 0 -8rpx 24rpx rgba(17, 24, 39, 0.06); }
|
|
|
|
.drawer-action { flex: 1; height: 72rpx; display: flex; align-items: center; justify-content: center; font-size: 28rpx; font-weight: 600; border: 2rpx solid #174b78; box-sizing: border-box; }
|
|
|
|
.drawer-action { flex: 1; height: 72rpx; display: flex; align-items: center; justify-content: center; font-size: 28rpx; font-weight: 600; border: 2rpx solid #174b78; box-sizing: border-box; }
|
|
|
|
.drawer-action.reset { border-radius: 12rpx 0 0 12rpx; background: #ffffff; color: #174b78; }
|
|
|
|
.drawer-action.reset { border-radius: 12rpx 0 0 12rpx; background: #ffffff; color: #174b78; }
|
|
|
|
|