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