| | |
| | | > |
| | | <template #top> |
| | | <view class="page-top"> |
| | | <CardTitle title="时效任务台账" :hideAction="false"> |
| | | <template #action> |
| | | <wd-tag type="warning" size="small">Mock</wd-tag> |
| | | <wd-button size="small" icon="add" @click="openCreatePopup">新增任务</wd-button> |
| | | </template> |
| | | </CardTitle> |
| | | |
| | | <view class="date-filter-card"> |
| | | <view class="date-filter-heading"> |
| | | <view class="date-filter-title"> |
| | | <view class="date-filter-icon"> |
| | | <wd-icon name="calendar" size="18px" color="#078568" /> |
| | | </view> |
| | | <view> |
| | | <view class="date-filter-name">选择日期</view> |
| | | <view class="date-filter-tip">按任务发起日期查询</view> |
| | | </view> |
| | | </view> |
| | | <text v-if="hasDateFilter" class="date-filter-clear" @click="resetFilters">清除</text> |
| | | </view> |
| | | <view class="date-filter-fields"> |
| | | <view class="date-filter-field"> |
| | | <wd-datetime-picker v-model="filters.startTimestamp" type="date"> |
| | | <view class="date-picker-trigger"> |
| | | <text class="date-picker-label">开始日期</text> |
| | | <view class="date-picker-value"> |
| | | <text :class="{ 'is-placeholder': !filters.startTimestamp }"> |
| | | {{ |
| | | filters.startTimestamp |
| | | ? formatDateOnly(Number(filters.startTimestamp)) |
| | | : "请选择" |
| | | }} |
| | | </text> |
| | | <wd-icon name="arrow-right" size="13px" color="#aebbb7" /> |
| | | </view> |
| | | </view> |
| | | </wd-datetime-picker> |
| | | </view> |
| | | <view class="date-filter-separator">至</view> |
| | | <view class="date-filter-field"> |
| | | <wd-datetime-picker v-model="filters.endTimestamp" type="date"> |
| | | <view class="date-picker-trigger"> |
| | | <text class="date-picker-label">结束日期</text> |
| | | <view class="date-picker-value"> |
| | | <text :class="{ 'is-placeholder': !filters.endTimestamp }"> |
| | | {{ |
| | | filters.endTimestamp |
| | | ? formatDateOnly(Number(filters.endTimestamp)) |
| | | : "请选择" |
| | | }} |
| | | </text> |
| | | <wd-icon name="arrow-right" size="13px" color="#aebbb7" /> |
| | | </view> |
| | | </view> |
| | | </wd-datetime-picker> |
| | | </view> |
| | | </view> |
| | | <view class="date-filter-actions"> |
| | | <wd-button size="small" type="info" plain @click="resetFilters">重置</wd-button> |
| | | <wd-button size="small" icon="search" @click="applyFilters">查询任务</wd-button> |
| | | </view> |
| | | </view> |
| | | <CardTitle title="时效任务台账" :hideAction="false" /> |
| | | </view> |
| | | </template> |
| | | |
| | |
| | | <text>{{ task.machineName || task.machine || "-" }}</text> |
| | | </view> |
| | | <view class="info-item"> |
| | | <text class="info-label">时效件数</text> |
| | | <text class="info-label">领料数量</text> |
| | | <text>{{ task.itemCount ?? task.count ?? task.detailCount ?? 0 }} 件</text> |
| | | </view> |
| | | </view> |
| | |
| | | |
| | | <template #footer> |
| | | <view class="task-actions"> |
| | | <wd-button size="small" plain @click="openDetail(task)">明细</wd-button> |
| | | <wd-button |
| | | v-if="isWaiting(task)" |
| | | size="small" |
| | | plain |
| | | type="warning" |
| | | @click="openEditPopup(task)" |
| | | > |
| | | 编辑 |
| | | </wd-button> |
| | | <wd-button v-if="isWaiting(task)" size="small" plain @click="startTask(task)"> |
| | | 开始时效 |
| | | </wd-button> |
| | | <wd-button |
| | | v-if="isWaiting(task)" |
| | | size="small" |
| | | plain |
| | | type="error" |
| | | @click="deleteTask(task)" |
| | | > |
| | | 删除 |
| | | </wd-button> |
| | | <wd-button |
| | | v-if="isRunning(task)" |
| | | size="small" |
| | | plain |
| | | type="error" |
| | | @click="endTask(task)" |
| | | > |
| | | 结束时效 |
| | | </wd-button> |
| | | <wd-button |
| | | v-if="!isWaiting(task)" |
| | | size="small" |
| | | plain |
| | | type="success" |
| | | @click="openInspection(task)" |
| | | > |
| | | 巡检记录 |
| | | <wd-button block custom-class="claim-button" @click="openDetail(task)"> |
| | | {{ isWaiting(task) ? "领料" : "查看领料记录" }} |
| | | </wd-button> |
| | | </view> |
| | | </template> |
| | | </wd-card> |
| | | </view> |
| | | </z-paging> |
| | | |
| | | <wd-popup |
| | | v-model="taskPopupVisible" |
| | | position="bottom" |
| | | :z-index="30" |
| | | :close-on-click-modal="false" |
| | | custom-style="height: 88vh; border-radius: 24rpx 24rpx 0 0;" |
| | | > |
| | | <view class="popup-layout"> |
| | | <view class="popup-header"> |
| | | <text class="popup-title">{{ editingTaskId ? "编辑时效任务" : "新增时效任务" }}</text> |
| | | <wd-icon name="close" size="20px" @click="taskPopupVisible = false" /> |
| | | </view> |
| | | <scroll-view class="popup-body" scroll-y> |
| | | <wd-form ref="taskFormRef" :model="taskForm"> |
| | | <wd-cell-group border> |
| | | <wd-picker |
| | | v-model="taskForm.materialType" |
| | | :columns="materialTypeOptions" |
| | | label="任务类型" |
| | | required |
| | | :z-index="40" |
| | | /> |
| | | <wd-picker |
| | | v-model="taskForm.initiatorName" |
| | | :columns="userOptions" |
| | | label="发起任务人" |
| | | placeholder="请选择" |
| | | required |
| | | :loading="optionsLoading" |
| | | :z-index="40" |
| | | /> |
| | | <wd-datetime-picker |
| | | v-model="taskForm.initiateTimestamp" |
| | | label="发起时间" |
| | | type="datetime" |
| | | required |
| | | use-second |
| | | :z-index="40" |
| | | /> |
| | | <wd-picker |
| | | v-model="taskForm.inspectorName" |
| | | :columns="userOptions" |
| | | label="巡检员" |
| | | placeholder="请选择" |
| | | required |
| | | :loading="optionsLoading" |
| | | :z-index="40" |
| | | /> |
| | | <wd-input |
| | | v-model="taskForm.setTemperature" |
| | | label="设定温度(℃)" |
| | | type="digit" |
| | | required |
| | | placeholder="请输入" |
| | | /> |
| | | <wd-cell title="时效时长(小时)" required /> |
| | | <view class="duration-row"> |
| | | <wd-input |
| | | v-model="taskForm.durationRise" |
| | | type="digit" |
| | | placeholder="升温" |
| | | no-border |
| | | /> |
| | | <text>+</text> |
| | | <wd-input |
| | | v-model="taskForm.durationHold" |
| | | type="digit" |
| | | placeholder="保温" |
| | | no-border |
| | | /> |
| | | <text>+</text> |
| | | <wd-input |
| | | v-model="taskForm.durationSoak" |
| | | type="digit" |
| | | placeholder="焖炉" |
| | | no-border |
| | | /> |
| | | </view> |
| | | <wd-picker |
| | | v-model="taskForm.machineName" |
| | | :columns="machineOptions" |
| | | label="设定机台" |
| | | placeholder="请选择时效机台" |
| | | required |
| | | :loading="optionsLoading" |
| | | :z-index="40" |
| | | /> |
| | | </wd-cell-group> |
| | | </wd-form> |
| | | </scroll-view> |
| | | <view class="popup-footer"> |
| | | <wd-button type="info" plain @click="taskPopupVisible = false">取消</wd-button> |
| | | <wd-button :loading="taskSubmitting" @click="submitTask"> |
| | | {{ editingTaskId ? "保存修改" : "确定新增" }} |
| | | </wd-button> |
| | | </view> |
| | | </view> |
| | | </wd-popup> |
| | | |
| | | <wd-toast /> |
| | | </view> |
| | |
| | | import type { TagType } from "wot-design-uni/components/wd-tag/types"; |
| | | import CardTitle from "@/components/card-title/index.vue"; |
| | | import zPaging from "@/components/z-paging/z-paging.vue"; |
| | | import TimeSensitiveTaskApi, { |
| | | type TimelinessMaterialType, |
| | | type TimeSensitiveTaskForm, |
| | | } from "@/api/timeSensitiveTask"; |
| | | import { useUserStore } from "@/store/modules/user"; |
| | | import TimeSensitiveTaskApi, { type TimelinessMaterialType } from "@/api/timeSensitiveTask"; |
| | | |
| | | const toast = useToast(); |
| | | const userStore = useUserStore(); |
| | | const pagingRef = ref(); |
| | | const taskFormRef = ref(); |
| | | const taskList = ref<any[]>([]); |
| | | const taskPopupVisible = ref(false); |
| | | const taskSubmitting = ref(false); |
| | | const optionsLoading = ref(false); |
| | | const editingTaskId = ref<number | string | undefined>(); |
| | | const pageReady = ref(false); |
| | | |
| | | const materialTypeOptions = [ |
| | | { label: "单丝", value: "单丝" }, |
| | | { label: "绞线", value: "绞线" }, |
| | | ]; |
| | | |
| | | const statusOptions = [ |
| | | { label: "待开始", value: 0 }, |
| | | { label: "时效中", value: 1 }, |
| | | { label: "时效结束", value: 2 }, |
| | | ]; |
| | | |
| | | const filters = reactive({ |
| | | startTimestamp: "" as "" | number, |
| | | endTimestamp: "" as "" | number, |
| | | }); |
| | | const hasDateFilter = computed(() => Boolean(filters.startTimestamp || filters.endTimestamp)); |
| | | |
| | | const taskForm = reactive({ |
| | | materialType: "单丝" as TimelinessMaterialType, |
| | | initiatorName: "", |
| | | initiateTimestamp: Date.now() as number, |
| | | setTemperature: "" as string | number, |
| | | durationRise: 2 as string | number, |
| | | durationHold: "" as string | number, |
| | | durationSoak: "" as string | number, |
| | | machineName: "", |
| | | inspectorName: "", |
| | | }); |
| | | |
| | | const userOptions = ref<Array<{ label: string; value: string }>>([]); |
| | | const machineOptions = ref<Array<{ label: string; value: string }>>([]); |
| | | |
| | | function pad(value: number) { |
| | | return String(value).padStart(2, "0"); |
| | | } |
| | | |
| | | function formatDateTime(value: number | Date) { |
| | | const date = value instanceof Date ? value : new Date(value); |
| | | return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad( |
| | | date.getHours() |
| | | )}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`; |
| | | } |
| | | |
| | | function formatDate(value: number, endOfDay = false) { |
| | | const date = new Date(value); |
| | | return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${ |
| | | endOfDay ? "23:59:59" : "00:00:00" |
| | | }`; |
| | | } |
| | | |
| | | function formatDateOnly(value: number) { |
| | | return formatDate(value).slice(0, 10); |
| | | } |
| | | |
| | | function parseDateTime(value: unknown) { |
| | | if (!value) return Date.now(); |
| | | const timestamp = new Date(String(value).replace(/-/g, "/")).getTime(); |
| | | return Number.isFinite(timestamp) ? timestamp : Date.now(); |
| | | } |
| | | |
| | | function normalizeStatus(task: any) { |
| | | const key = String(task?.taskStatus ?? task?.timelinessStatus ?? task?.status ?? "") |
| | |
| | | |
| | | function isWaiting(task: any) { |
| | | return normalizeStatus(task) === 0; |
| | | } |
| | | |
| | | function isRunning(task: any) { |
| | | return normalizeStatus(task) === 1; |
| | | } |
| | | |
| | | function getStatusLabel(task: any) { |
| | |
| | | const { data } = await TimeSensitiveTaskApi.queryPage({ |
| | | current: pageNo, |
| | | size: pageSize, |
| | | startTime: filters.startTimestamp ? formatDate(Number(filters.startTimestamp)) : undefined, |
| | | endTime: filters.endTimestamp ? formatDate(Number(filters.endTimestamp), true) : undefined, |
| | | }); |
| | | pagingRef.value?.complete(data?.records || []); |
| | | } catch (error: any) { |
| | |
| | | } |
| | | } |
| | | |
| | | function applyFilters() { |
| | | if ( |
| | | filters.startTimestamp && |
| | | filters.endTimestamp && |
| | | Number(filters.startTimestamp) > Number(filters.endTimestamp) |
| | | ) { |
| | | toast.error("开始日期不能晚于结束日期"); |
| | | return; |
| | | } |
| | | pagingRef.value?.reload(); |
| | | } |
| | | |
| | | function resetFilters() { |
| | | Object.assign(filters, { |
| | | startTimestamp: "", |
| | | endTimestamp: "", |
| | | }); |
| | | applyFilters(); |
| | | } |
| | | |
| | | function getCurrentPerson() { |
| | | const user = userStore.userInfo as any; |
| | | return user?.nickName || user?.nickname || user?.userName || user?.username || ""; |
| | | } |
| | | |
| | | function getPersonName(item: any) { |
| | | return String(item?.nickName || item?.nickname || item?.userName || item?.username || ""); |
| | | } |
| | | |
| | | function getMachineName(item: any) { |
| | | return String(item?.deviceModel || item?.device_model || item?.deviceName || item?.name || ""); |
| | | } |
| | | |
| | | async function loadOptions() { |
| | | if (userOptions.value.length && machineOptions.value.length) return; |
| | | optionsLoading.value = true; |
| | | try { |
| | | const [usersResult, machinesResult] = await Promise.all([ |
| | | TimeSensitiveTaskApi.getUsers(), |
| | | TimeSensitiveTaskApi.getMachines(), |
| | | ]); |
| | | userOptions.value = (usersResult.data || []) |
| | | .map((item: any) => getPersonName(item)) |
| | | .filter(Boolean) |
| | | .map((name: string) => ({ label: name, value: name })); |
| | | machineOptions.value = (machinesResult.data || []) |
| | | .map((item: any) => getMachineName(item)) |
| | | .filter(Boolean) |
| | | .map((name: string) => ({ label: name, value: name })); |
| | | } catch (error: any) { |
| | | toast.error(error?.message || "获取人员或时效机台失败"); |
| | | } finally { |
| | | optionsLoading.value = false; |
| | | } |
| | | } |
| | | |
| | | function resetTaskForm() { |
| | | const currentPerson = getCurrentPerson(); |
| | | Object.assign(taskForm, { |
| | | materialType: "单丝", |
| | | initiatorName: currentPerson, |
| | | initiateTimestamp: Date.now(), |
| | | setTemperature: "", |
| | | durationRise: 2, |
| | | durationHold: "", |
| | | durationSoak: "", |
| | | machineName: "", |
| | | inspectorName: currentPerson, |
| | | }); |
| | | } |
| | | |
| | | function parseDuration(value: unknown) { |
| | | const parts = String(value ?? "") |
| | | .replace(/小时/g, "") |
| | | .split("+") |
| | | .map((item) => Number(item.trim())); |
| | | if (parts.length >= 3 && parts.every(Number.isFinite)) return parts; |
| | | return [2, Number.isFinite(parts[0]) ? parts[0] : "", ""]; |
| | | } |
| | | |
| | | async function openCreatePopup() { |
| | | editingTaskId.value = undefined; |
| | | resetTaskForm(); |
| | | taskPopupVisible.value = true; |
| | | await loadOptions(); |
| | | } |
| | | |
| | | async function openEditPopup(task: any) { |
| | | if (!isWaiting(task)) return; |
| | | try { |
| | | const { data } = await TimeSensitiveTaskApi.getDetail(task.id); |
| | | const detail = { ...task, ...(data || {}) }; |
| | | const duration = parseDuration(detail.agingDuration ?? detail.duration); |
| | | editingTaskId.value = detail.id; |
| | | Object.assign(taskForm, { |
| | | materialType: normalizeMaterialType(detail.materialType), |
| | | initiatorName: getInitiator(detail) === "-" ? "" : getInitiator(detail), |
| | | initiateTimestamp: parseDateTime( |
| | | detail.initiateTime || detail.startTime || detail.createTime |
| | | ), |
| | | setTemperature: detail.setTemperature ?? detail.temperature ?? "", |
| | | durationRise: duration[0], |
| | | durationHold: duration[1], |
| | | durationSoak: duration[2], |
| | | machineName: detail.machineName || detail.machine || "", |
| | | inspectorName: getInspector(detail) === "-" ? "" : getInspector(detail), |
| | | }); |
| | | taskPopupVisible.value = true; |
| | | await loadOptions(); |
| | | } catch (error: any) { |
| | | toast.error(error?.message || "获取时效任务详情失败"); |
| | | } |
| | | } |
| | | |
| | | function buildTaskPayload(): TimeSensitiveTaskForm | null { |
| | | if (!taskForm.materialType) return (toast.error("请选择任务类型"), null); |
| | | if (!taskForm.initiatorName) return (toast.error("请选择发起任务人"), null); |
| | | if (!taskForm.initiateTimestamp) return (toast.error("请选择发起时间"), null); |
| | | if (taskForm.setTemperature === "") return (toast.error("请输入设定温度"), null); |
| | | if (taskForm.durationHold === "") return (toast.error("请输入保温时长"), null); |
| | | if (!taskForm.machineName) return (toast.error("请选择设定机台"), null); |
| | | if (!taskForm.inspectorName) return (toast.error("请选择巡检员"), null); |
| | | |
| | | return { |
| | | materialType: taskForm.materialType, |
| | | initiatorName: taskForm.initiatorName, |
| | | initiateTime: formatDateTime(Number(taskForm.initiateTimestamp)), |
| | | setTemperature: taskForm.setTemperature, |
| | | agingDuration: `${taskForm.durationRise || 0}+${taskForm.durationHold || 0}+${ |
| | | taskForm.durationSoak || 0 |
| | | }`, |
| | | machineName: taskForm.machineName, |
| | | inspectorName: taskForm.inspectorName, |
| | | }; |
| | | } |
| | | |
| | | async function submitTask() { |
| | | const payload = buildTaskPayload(); |
| | | if (!payload || taskSubmitting.value) return; |
| | | taskSubmitting.value = true; |
| | | try { |
| | | const result = editingTaskId.value |
| | | ? await TimeSensitiveTaskApi.update({ id: editingTaskId.value, ...payload }) |
| | | : await TimeSensitiveTaskApi.create(payload); |
| | | taskPopupVisible.value = false; |
| | | toast.success(editingTaskId.value ? "时效任务修改成功" : "新增成功,请添加时效明细"); |
| | | pagingRef.value?.reload(); |
| | | if (!editingTaskId.value) { |
| | | const resultData = result.data; |
| | | const newId = |
| | | resultData && typeof resultData === "object" |
| | | ? resultData.id || resultData.taskId |
| | | : resultData; |
| | | if (newId) { |
| | | setTimeout(() => { |
| | | uni.navigateTo({ url: `/pages/timely/detail?id=${newId}` }); |
| | | }, 500); |
| | | } |
| | | } |
| | | } catch (error: any) { |
| | | toast.error(error?.message || `${editingTaskId.value ? "修改" : "新增"}时效任务失败`); |
| | | } finally { |
| | | taskSubmitting.value = false; |
| | | } |
| | | } |
| | | |
| | | function showConfirm(title: string, content: string, confirmText = "确定") { |
| | | return new Promise<boolean>((resolve) => { |
| | | uni.showModal({ |
| | | title, |
| | | content, |
| | | confirmText, |
| | | success: (result) => resolve(Boolean(result.confirm)), |
| | | fail: () => resolve(false), |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | async function deleteTask(task: any) { |
| | | if (!isWaiting(task)) return toast.error("只有待开始的任务可以删除"); |
| | | const confirmed = await showConfirm( |
| | | "删除任务", |
| | | `确定删除时效任务“${task.taskCode || task.id}”吗?任务明细也会一并删除。`, |
| | | "删除" |
| | | ); |
| | | if (!confirmed) return; |
| | | try { |
| | | await TimeSensitiveTaskApi.delete(task.id); |
| | | toast.success("时效任务删除成功"); |
| | | pagingRef.value?.reload(); |
| | | } catch (error: any) { |
| | | toast.error(error?.message || "删除时效任务失败"); |
| | | } |
| | | } |
| | | |
| | | async function startTask(task: any) { |
| | | if (!isWaiting(task)) return; |
| | | try { |
| | | const [detailResult, itemsResult] = await Promise.all([ |
| | | TimeSensitiveTaskApi.getDetail(task.id), |
| | | TimeSensitiveTaskApi.getItems(task.id), |
| | | ]); |
| | | const detail = { ...task, ...(detailResult.data || {}) }; |
| | | const items = Array.isArray(itemsResult.data) |
| | | ? itemsResult.data |
| | | : (itemsResult.data as any)?.records || []; |
| | | const payload = { |
| | | id: task.id, |
| | | materialType: normalizeMaterialType(detail.materialType), |
| | | initiatorName: getInitiator(detail) === "-" ? "" : getInitiator(detail), |
| | | initiateTime: detail.initiateTime || detail.startTime || detail.createTime || "", |
| | | setTemperature: detail.setTemperature ?? detail.temperature ?? "", |
| | | agingDuration: detail.agingDuration ?? detail.duration ?? "", |
| | | machineName: detail.machineName || detail.machine || "", |
| | | furnaceInTime: detail.furnaceInTime || formatDateTime(new Date()), |
| | | inspectorName: getInspector(detail) === "-" ? "" : getInspector(detail), |
| | | }; |
| | | if ( |
| | | Object.values(payload).some( |
| | | (value) => value === undefined || value === null || String(value) === "" |
| | | ) |
| | | ) { |
| | | return toast.error("任务基础信息不完整,请先编辑完善"); |
| | | } |
| | | if (!items.length) return toast.error("当前任务没有时效明细,不能开始时效"); |
| | | const confirmed = await showConfirm( |
| | | "开始时效", |
| | | `任务:${task.taskCode || task.id}\n明细:${items.length}件\n机台:${payload.machineName}\n确认开始时效吗?`, |
| | | "开始" |
| | | ); |
| | | if (!confirmed) return; |
| | | await TimeSensitiveTaskApi.start(payload); |
| | | toast.success("时效已开始"); |
| | | pagingRef.value?.reload(); |
| | | } catch (error: any) { |
| | | toast.error(error?.message || "开始时效失败"); |
| | | } |
| | | } |
| | | |
| | | function parseCanEnd(data: any) { |
| | | if (typeof data === "boolean") return data; |
| | | return Boolean(data?.canEnd ?? data?.reachedDuration); |
| | | } |
| | | |
| | | async function endTask(task: any) { |
| | | if (!isRunning(task)) return; |
| | | try { |
| | | const { data } = await TimeSensitiveTaskApi.checkEnd(task.id); |
| | | const canEnd = parseCanEnd(data); |
| | | const durationText = |
| | | data?.elapsedMinutes != null && data?.requiredMinutes != null |
| | | ? `当前已时效 ${data.elapsedMinutes} 分钟,设定时长 ${data.requiredMinutes} 分钟。` |
| | | : "当前尚未达到设定时效时长。"; |
| | | const confirmed = await showConfirm( |
| | | canEnd ? "结束时效" : "时长未达到", |
| | | canEnd |
| | | ? "已达到设定时效时长,确定结束时效吗?" |
| | | : `${data?.message || durationText}是否仍要结束时效?`, |
| | | canEnd ? "结束" : "仍然结束" |
| | | ); |
| | | if (!confirmed) return; |
| | | await TimeSensitiveTaskApi.end({ id: task.id, forceEnd: !canEnd }); |
| | | toast.success("时效已结束"); |
| | | pagingRef.value?.reload(); |
| | | } catch (error: any) { |
| | | toast.error(error?.message || "结束时效失败"); |
| | | } |
| | | } |
| | | |
| | | function openDetail(task: any) { |
| | | uni.navigateTo({ url: `/pages/timely/detail?id=${task.id}` }); |
| | | } |
| | | |
| | | function openInspection(task: any) { |
| | | const inspectionId = task.timelinessInspectionId || task.inspectionId || task.id; |
| | | const readonly = normalizeStatus(task) === 2 ? 1 : 0; |
| | | uni.navigateTo({ |
| | | url: `/pages/timely/inspection?id=${inspectionId}&readonly=${readonly}`, |
| | | }); |
| | | } |
| | | |
| | | onShow(() => { |
| | |
| | | background: #ffffff; |
| | | } |
| | | |
| | | .date-filter-card { |
| | | padding: 12px; |
| | | margin: 0 10px 10px; |
| | | background: linear-gradient(135deg, #f3fbf8 0%, #ffffff 72%); |
| | | border: 1px solid rgba(7, 133, 104, 0.12); |
| | | border-radius: 12px; |
| | | box-shadow: 0 4px 14px rgba(19, 94, 78, 0.06); |
| | | } |
| | | |
| | | .date-filter-heading, |
| | | .date-filter-title, |
| | | .date-filter-fields, |
| | | .date-filter-actions, |
| | | .popup-footer, |
| | | .task-actions { |
| | | display: flex; |
| | | width: 100%; |
| | | align-items: center; |
| | | } |
| | | |
| | | .date-filter-heading { |
| | | justify-content: space-between; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .date-filter-title { |
| | | gap: 8px; |
| | | } |
| | | |
| | | .date-filter-icon { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 32px; |
| | | height: 32px; |
| | | background: rgba(7, 133, 104, 0.1); |
| | | border-radius: 9px; |
| | | } |
| | | |
| | | .date-filter-name { |
| | | font-size: 14px; |
| | | :deep(.claim-button) { |
| | | height: 42px; |
| | | font-size: 15px; |
| | | font-weight: 600; |
| | | color: #243832; |
| | | } |
| | | |
| | | .date-filter-tip { |
| | | margin-top: 2px; |
| | | font-size: 11px; |
| | | color: #91a09c; |
| | | } |
| | | |
| | | .date-filter-clear { |
| | | padding: 5px 0 5px 10px; |
| | | font-size: 12px; |
| | | color: #078568; |
| | | } |
| | | |
| | | .date-filter-fields { |
| | | gap: 7px; |
| | | } |
| | | |
| | | .date-filter-field { |
| | | flex: 1; |
| | | min-width: 0; |
| | | background: #ffffff; |
| | | border: 1px solid #e5efec; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .date-picker-trigger { |
| | | padding: 9px 10px; |
| | | } |
| | | |
| | | .date-picker-label { |
| | | display: block; |
| | | margin-bottom: 5px; |
| | | font-size: 11px; |
| | | color: #8c9b97; |
| | | } |
| | | |
| | | .date-picker-value { |
| | | display: flex; |
| | | gap: 4px; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | font-size: 13px; |
| | | font-weight: 500; |
| | | color: #2b3c37; |
| | | } |
| | | |
| | | .is-placeholder { |
| | | font-weight: 400; |
| | | color: #b7c1be; |
| | | } |
| | | |
| | | .date-filter-separator { |
| | | flex: none; |
| | | font-size: 12px; |
| | | color: #8c9b97; |
| | | } |
| | | |
| | | .date-filter-actions { |
| | | gap: 8px; |
| | | justify-content: flex-end; |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .popup-footer, |
| | | .task-actions { |
| | | flex-wrap: wrap; |
| | | gap: 8px; |
| | | justify-content: flex-end; |
| | | border-radius: 10px; |
| | | } |
| | | |
| | | .task-list { |
| | |
| | | .info-label { |
| | | font-size: 12px; |
| | | color: #999999; |
| | | } |
| | | |
| | | .popup-layout { |
| | | display: flex; |
| | | flex-direction: column; |
| | | height: 100%; |
| | | background: #f7f8fa; |
| | | } |
| | | |
| | | .popup-header { |
| | | display: flex; |
| | | flex-shrink: 0; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 16px; |
| | | background: #ffffff; |
| | | border-bottom: 1px solid #eeeeee; |
| | | } |
| | | |
| | | .popup-title { |
| | | font-size: 17px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .popup-body { |
| | | flex: 1; |
| | | height: 0; |
| | | } |
| | | |
| | | .popup-footer { |
| | | flex-shrink: 0; |
| | | padding: 10px 12px calc(10px + env(safe-area-inset-bottom)); |
| | | background: #ffffff; |
| | | border-top: 1px solid #eeeeee; |
| | | } |
| | | |
| | | .duration-row { |
| | | display: grid; |
| | | grid-template-columns: 1fr auto 1fr auto 1fr; |
| | | gap: 4px; |
| | | align-items: center; |
| | | padding: 0 12px 10px; |
| | | background: #ffffff; |
| | | } |
| | | |
| | | .duration-row :deep(.wd-input) { |
| | | padding: 0; |
| | | } |
| | | </style> |