feat 联调项目表
This commit is contained in:
@@ -4,21 +4,27 @@ import { useCurrentProject } from '@/composables/useCurrentProject'
|
||||
import { useDbStore } from '@/store/modules/db'
|
||||
|
||||
const db = useDbStore()
|
||||
const { hasCurrentProject } = useCurrentProject()
|
||||
const { hasCurrentProject, currentProjectId } = useCurrentProject()
|
||||
|
||||
const now = new Date()
|
||||
const dateStr = `${now.getFullYear()}年${now.getMonth() + 1}月${now.getDate()}日`
|
||||
|
||||
const projectWorkRecords = computed(() => {
|
||||
if (!hasCurrentProject.value || currentProjectId.value == null)
|
||||
return []
|
||||
return (db.work_record || []).filter(item => item.project_id === currentProjectId.value)
|
||||
})
|
||||
|
||||
const totalCompactionArea = computed(() => {
|
||||
if (!hasCurrentProject.value)
|
||||
return null
|
||||
return (db.work_record || []).reduce((sum, item) => sum + (item.compaction_area ?? 0), 0)
|
||||
return projectWorkRecords.value.reduce((sum, item) => sum + (item.compaction_area ?? 0), 0)
|
||||
})
|
||||
|
||||
const totalDuration = computed(() => {
|
||||
if (!hasCurrentProject.value)
|
||||
return null
|
||||
return (db.work_record || []).reduce((sum, item) => sum + (item.duration ?? 0), 0)
|
||||
return projectWorkRecords.value.reduce((sum, item) => sum + (item.duration ?? 0), 0)
|
||||
})
|
||||
|
||||
const onlineCount = computed(() => {
|
||||
@@ -40,8 +46,9 @@ function formatCount(value: number | null) {
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (!db.work_record?.length)
|
||||
await db.loadAll()
|
||||
if (!hasCurrentProject.value || currentProjectId.value == null)
|
||||
return
|
||||
await db.loadByProject(currentProjectId.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -5,18 +5,14 @@ import { calcUncompactedArea } from '@/service/project'
|
||||
import { useDbStore } from '@/store/modules/db'
|
||||
|
||||
const db = useDbStore()
|
||||
const { currentProject: storedProject, hasCurrentProject } = useCurrentProject()
|
||||
const { hasCurrentProject, currentProjectId } = useCurrentProject()
|
||||
|
||||
const currentProject = computed(() => {
|
||||
if (!hasCurrentProject.value)
|
||||
if (!hasCurrentProject.value || currentProjectId.value == null)
|
||||
return null
|
||||
|
||||
const list = db.project || []
|
||||
const storedId = storedProject.value?.id
|
||||
if (storedId == null)
|
||||
return null
|
||||
|
||||
return list.find(item => item.id === storedId) || null
|
||||
return list.find(item => item.id === currentProjectId.value) || null
|
||||
})
|
||||
|
||||
const progressPercent = computed(() => {
|
||||
@@ -84,8 +80,9 @@ function formatPercent(value: number | null) {
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (!db.project?.length)
|
||||
await db.loadAll()
|
||||
if (!hasCurrentProject.value || currentProjectId.value == null)
|
||||
return
|
||||
await db.loadByProject(currentProjectId.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { Project } from '@/service/project'
|
||||
import { computed, onMounted } from 'vue'
|
||||
import { useCurrentProject } from '@/composables/useCurrentProject'
|
||||
import { useDbStore } from '@/store/modules/db'
|
||||
|
||||
const db = useDbStore()
|
||||
const { hasCurrentProject } = useCurrentProject()
|
||||
|
||||
/** 首页只展示最近几条 */
|
||||
const list = computed(() => {
|
||||
if (!hasCurrentProject.value)
|
||||
return []
|
||||
return (db.project || []).slice(0, 2)
|
||||
})
|
||||
/** 首页展示最近 2 条,按 id 倒序 */
|
||||
const list = computed(() => (db.project || []).slice().sort((a, b) => (b.id ?? 0) - (a.id ?? 0)).slice(0, 2))
|
||||
|
||||
onMounted(async () => {
|
||||
if (!db.project?.length)
|
||||
@@ -45,10 +39,7 @@ function goToDetail(item: Project) {
|
||||
</wd-button>
|
||||
</view>
|
||||
<view class="card-body">
|
||||
<view v-if="!hasCurrentProject" class="empty-tip">
|
||||
--
|
||||
</view>
|
||||
<view v-else-if="!list.length" class="empty-tip">
|
||||
<view v-if="!list.length" class="empty-tip">
|
||||
暂无项目
|
||||
</view>
|
||||
<home-list
|
||||
|
||||
@@ -37,7 +37,7 @@ function goToWork() {
|
||||
</view>
|
||||
</view>
|
||||
<view class="status-params">
|
||||
<view class="param">
|
||||
<!-- <view class="param">
|
||||
<text class="param-label">
|
||||
振动频率
|
||||
</text>
|
||||
@@ -52,7 +52,7 @@ function goToWork() {
|
||||
<text class="param-value">
|
||||
8939mm
|
||||
</text>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="param">
|
||||
<text class="param-label">
|
||||
行驶速度
|
||||
|
||||
@@ -5,21 +5,21 @@ import { useCurrentProject } from '@/composables/useCurrentProject'
|
||||
import { useDbStore } from '@/store/modules/db'
|
||||
|
||||
const db = useDbStore()
|
||||
const { hasCurrentProject, currentProject } = useCurrentProject()
|
||||
const { hasCurrentProject, currentProjectId } = useCurrentProject()
|
||||
|
||||
/** 首页只展示当前项目最近几条 */
|
||||
const list = computed(() => {
|
||||
if (!hasCurrentProject.value)
|
||||
if (!hasCurrentProject.value || currentProjectId.value == null)
|
||||
return []
|
||||
const projectId = currentProject.value?.id
|
||||
return (db.warning_record || [])
|
||||
.filter(item => projectId == null || item.project_id === projectId)
|
||||
.filter(item => item.project_id === currentProjectId.value)
|
||||
.slice(0, 3)
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
if (!db.warning_record?.length)
|
||||
await db.loadAll()
|
||||
if (!hasCurrentProject.value || currentProjectId.value == null)
|
||||
return
|
||||
await db.loadByProject(currentProjectId.value)
|
||||
})
|
||||
|
||||
function goToWarningList() {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { useCurrentProject } from '@/composables/useCurrentProject'
|
||||
import { projectService } from '@/service'
|
||||
import storage from '@/utils/storage'
|
||||
import { useDbStore } from '@/store/modules/db'
|
||||
|
||||
const PROJECT_KEY = 'current_project'
|
||||
const currentProject = storage.get(PROJECT_KEY)
|
||||
const db = useDbStore()
|
||||
const { setCurrentProject, currentProjectId } = useCurrentProject()
|
||||
|
||||
const projectName = ref(currentProject?.project_name || '')
|
||||
const startEndStation = ref(currentProject?.stake_range || '')
|
||||
const totalArea = ref(currentProject?.total_area ? String(currentProject.total_area) : '')
|
||||
const projectName = ref('')
|
||||
const startEndStation = ref('')
|
||||
const totalArea = ref('')
|
||||
|
||||
async function handleSave() {
|
||||
if (!projectName.value) {
|
||||
@@ -16,21 +17,30 @@ async function handleSave() {
|
||||
}
|
||||
|
||||
try {
|
||||
const id = await projectService.insert({
|
||||
const payload = {
|
||||
project_name: projectName.value,
|
||||
stake_range: startEndStation.value,
|
||||
total_area: Number(totalArea.value) || 0,
|
||||
status: 0,
|
||||
})
|
||||
status: 0 as const,
|
||||
}
|
||||
|
||||
// 保存到 storage
|
||||
storage.set(PROJECT_KEY, {
|
||||
id,
|
||||
project_name: projectName.value,
|
||||
stake_range: startEndStation.value,
|
||||
total_area: Number(totalArea.value) || 0,
|
||||
status: 0,
|
||||
})
|
||||
// 始终新建项目,写入数据库
|
||||
const id = await projectService.insert(payload)
|
||||
if (!id) {
|
||||
uni.showToast({ title: '保存失败:未获取到项目ID', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
// 写入 storage,后续业务按该项目 id 查询
|
||||
const project = await projectService.selectById(id)
|
||||
if (!project) {
|
||||
uni.showToast({ title: '保存失败:项目不存在', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
setCurrentProject(project)
|
||||
await db.loadByProject(id)
|
||||
console.log('id22222', id, 'currentProjectId.value', currentProjectId.value)
|
||||
|
||||
uni.showToast({ title: '保存成功', icon: 'success' })
|
||||
}
|
||||
|
||||
@@ -1,28 +1,49 @@
|
||||
import type { Project } from '@/service/project'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { computed, ref } from 'vue'
|
||||
import storage from '@/utils/storage'
|
||||
|
||||
const PROJECT_KEY = 'current_project'
|
||||
|
||||
/** 模块级共享,保证各页面读到同一当前项目 */
|
||||
const currentProject = ref<Partial<Project> | undefined>(storage.get(PROJECT_KEY))
|
||||
|
||||
/**
|
||||
* 读取本地当前项目;无项目时首页/压实作业数据统一展示为 `--`
|
||||
* 有项目时,业务查询应以 currentProjectId 为条件
|
||||
*/
|
||||
export function useCurrentProject() {
|
||||
const currentProject = ref(storage.get(PROJECT_KEY))
|
||||
const currentProjectId = computed(() => {
|
||||
const id = currentProject.value?.id
|
||||
return id == null ? null : Number(id)
|
||||
})
|
||||
|
||||
const hasCurrentProject = computed(() => currentProject.value?.id != null)
|
||||
const hasCurrentProject = computed(() => currentProjectId.value != null && currentProjectId.value > 0)
|
||||
|
||||
function refreshCurrentProject() {
|
||||
currentProject.value = storage.get(PROJECT_KEY)
|
||||
}
|
||||
|
||||
/** 写入 storage 并同步内存中的当前项目 */
|
||||
function setCurrentProject(project: Partial<Project> | null | undefined) {
|
||||
if (!project?.id) {
|
||||
storage.remove(PROJECT_KEY)
|
||||
currentProject.value = undefined
|
||||
return
|
||||
}
|
||||
storage.set(PROJECT_KEY, project)
|
||||
currentProject.value = project
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
refreshCurrentProject()
|
||||
})
|
||||
|
||||
return {
|
||||
currentProject,
|
||||
currentProjectId,
|
||||
hasCurrentProject,
|
||||
setCurrentProject,
|
||||
refreshCurrentProject,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ const projects = computed(() => {
|
||||
}
|
||||
return true
|
||||
})
|
||||
.slice()
|
||||
.reverse()
|
||||
.map(mapProjectItem)
|
||||
})
|
||||
|
||||
|
||||
@@ -68,14 +68,23 @@ export async function selectByStatus(status: 0 | 1): Promise<Project[]> {
|
||||
return DB.selectByField(TABLE, 'status', status)
|
||||
}
|
||||
|
||||
/** 新增项目 */
|
||||
/** 新增项目,返回新记录 id */
|
||||
export async function insert(data: Omit<Project, 'id'>): Promise<number> {
|
||||
await DB.insert(TABLE, {
|
||||
...data,
|
||||
uncompacted_area: calcUncompactedArea(data.total_area, data.total_compaction_area),
|
||||
})
|
||||
|
||||
const result = await DB.selectSql('SELECT last_insert_rowid() as id')
|
||||
return result?.[0]?.id || 0
|
||||
let id = Number(result?.[0]?.id) || 0
|
||||
|
||||
// 部分端上 last_insert_rowid 不稳定,回退取最新一条
|
||||
if (!id) {
|
||||
const latest = await DB.select(TABLE, '*', undefined, 'id DESC', 1)
|
||||
id = Number(latest?.[0]?.id) || 0
|
||||
}
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
/** 更新项目;标记为已完成(status=1)时清除该项目的作业记录与 RTK 轨迹 */
|
||||
|
||||
@@ -46,6 +46,15 @@ export async function selectByWorkRecordId(workRecordId: number): Promise<RtkTra
|
||||
return DB.selectByField(TABLE, 'work_record_id', workRecordId)
|
||||
}
|
||||
|
||||
/** 按项目 ID 查询(通过 work_record 关联) */
|
||||
export async function selectByProjectId(projectId: number): Promise<RtkTrack[]> {
|
||||
return DB.selectSql(
|
||||
`SELECT t.* FROM ${TABLE} t
|
||||
INNER JOIN work_record w ON t.work_record_id = w.id
|
||||
WHERE w.project_id = ${projectId}`,
|
||||
)
|
||||
}
|
||||
|
||||
/** 新增轨迹点 */
|
||||
export async function insert(data: RtkTrack): Promise<any> {
|
||||
return DB.insert(TABLE, data)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 当日工作记录表
|
||||
// 工作记录表
|
||||
import DB from '@/utils/sqlite'
|
||||
|
||||
const TABLE = 'work_record'
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
* import { useDbStore } from '@/store/modules/db'
|
||||
* const db = useDbStore()
|
||||
* await db.loadAll()
|
||||
* await db.loadByProject(projectId) // 按当前项目加载关联数据
|
||||
*
|
||||
* db.project // 项目表
|
||||
* db.work_record // 作业记录表
|
||||
@@ -50,6 +51,25 @@ export const useDbStore = defineStore('db', () => {
|
||||
history_report.value = historyReports
|
||||
}
|
||||
|
||||
/**
|
||||
* 按项目加载关联数据(作业 / 轨迹 / 告警)
|
||||
* 项目列表、历史报告始终全量加载,不按项目 id 过滤
|
||||
*/
|
||||
async function loadByProject(projectId: number) {
|
||||
const [projects, workRecords, rtkTracks, warningRecords, historyReports] = await Promise.all([
|
||||
projectService.selectAll(),
|
||||
workRecordService.selectByProjectId(projectId),
|
||||
rtkTrackService.selectByProjectId(projectId),
|
||||
warningRecordService.selectByProjectId(projectId),
|
||||
historyReportService.selectAll(),
|
||||
])
|
||||
project.value = projects
|
||||
work_record.value = workRecords
|
||||
rtk_track.value = rtkTracks
|
||||
warning_record.value = warningRecords
|
||||
history_report.value = historyReports
|
||||
}
|
||||
|
||||
/** 按项目筛选作业记录 */
|
||||
async function loadWorkRecordByProject(projectId: number) {
|
||||
work_record.value = await workRecordService.selectByProjectId(projectId)
|
||||
@@ -65,9 +85,9 @@ export const useDbStore = defineStore('db', () => {
|
||||
warning_record.value = await warningRecordService.selectByProjectId(projectId)
|
||||
}
|
||||
|
||||
/** 按项目筛选历史报告 */
|
||||
async function loadHistoryReportByProject(projectId: number) {
|
||||
history_report.value = await historyReportService.selectByProjectId(projectId)
|
||||
/** 加载全部历史报告(不按项目过滤) */
|
||||
async function loadHistoryReportAll() {
|
||||
history_report.value = await historyReportService.selectAll()
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -77,9 +97,10 @@ export const useDbStore = defineStore('db', () => {
|
||||
warning_record,
|
||||
history_report,
|
||||
loadAll,
|
||||
loadByProject,
|
||||
loadWorkRecordByProject,
|
||||
loadRtkTrackByWorkRecord,
|
||||
loadWarningByProject,
|
||||
loadHistoryReportByProject,
|
||||
loadHistoryReportAll,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user