feat 删除测试代码

This commit is contained in:
Ironsp
2026-09-14 14:31:06 +08:00
parent 830aca7088
commit 3d857002e0
9 changed files with 157 additions and 311 deletions

1
src/components.d.ts vendored
View File

@@ -13,7 +13,6 @@ declare module 'vue' {
DeviceInfo: typeof import('./components/deviceInfo.vue')['default'] DeviceInfo: typeof import('./components/deviceInfo.vue')['default']
FullscreenNav: typeof import('./components/FullscreenNav.vue')['default'] FullscreenNav: typeof import('./components/FullscreenNav.vue')['default']
HomeConstruction: typeof import('./components/home/construction.vue')['default'] HomeConstruction: typeof import('./components/home/construction.vue')['default']
HomeDeviceFooter: typeof import('./components/home/deviceFooter.vue')['default']
HomeHomeNav: typeof import('./components/home/homeNav.vue')['default'] HomeHomeNav: typeof import('./components/home/homeNav.vue')['default']
HomeList: typeof import('./components/home/list.vue')['default'] HomeList: typeof import('./components/home/list.vue')['default']
HomeOverview: typeof import('./components/home/overview.vue')['default'] HomeOverview: typeof import('./components/home/overview.vue')['default']

View File

@@ -1,197 +0,0 @@
<script setup lang="ts">
import { onMounted } from 'vue'
import { useDbStore } from '@/store/modules/db'
import { useDeviceStore } from '@/store/modules/home'
const deviceStore = useDeviceStore()
const dbStore = useDbStore()
onMounted(async () => {
console.log('组件挂载时 初始化设备信息')
deviceStore.initDevice()
await dbStore.loadProjects()
console.log('projects:', dbStore.projects)
await dbStore.loadWorkRecords()
console.log('workRecords:', dbStore.workRecords)
await dbStore.loadRtkTracks()
console.log('rtkTracks:', dbStore.rtkTracks)
await dbStore.loadWarningRecords()
console.log('warningRecords:', dbStore.warningRecords)
})
</script>
<template>
<view v-if="deviceStore.currentDevice" class="device-footer">
<view class="device-info">
<view class="device-main">
<view class="device-icon">
<wd-icon name="settings" size="20px" color="#3b82f6" />
</view>
<view class="device-detail">
<text class="device-name">
{{ deviceStore.currentDevice.brand }} {{ deviceStore.currentDevice.model }}
</text>
<text class="device-model">
{{ deviceStore.osTypeName }} · {{ deviceStore.deviceTypeName }}
</text>
</view>
</view>
<view class="device-status">
<view class="status-indicator status-online" />
<text class="status-text">
已连接
</text>
</view>
</view>
<view class="device-metrics">
<view class="metric-item">
<text class="metric-label">
屏幕
</text>
<text class="metric-value">
{{ deviceStore.currentDevice.windowWidth }} x {{ deviceStore.currentDevice.windowHeight }}
</text>
</view>
<view class="metric-item">
<text class="metric-label">
平台
</text>
<text class="metric-value">
{{ deviceStore.currentDevice.platform }}
</text>
</view>
</view>
<view class="device-id">
<text class="id-label">
设备ID:
</text>
<text class="id-value">
{{ deviceStore.currentDevice.deviceId }}
</text>
</view>
</view>
</template>
<style scoped>
.device-footer {
background: #fff;
border-radius: 12px;
padding: 16px;
margin-top: 12px;
}
.device-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.device-main {
display: flex;
align-items: center;
gap: 12px;
}
.device-icon {
width: 40px;
height: 40px;
border-radius: 10px;
background: #eff6ff;
display: flex;
align-items: center;
justify-content: center;
}
.device-detail {
display: flex;
flex-direction: column;
gap: 2px;
}
.device-name {
font-size: 16px;
font-weight: 600;
color: #333;
}
.device-model {
font-size: 12px;
color: #999;
}
.device-status {
display: flex;
align-items: center;
gap: 6px;
}
.status-indicator {
width: 8px;
height: 8px;
border-radius: 50%;
}
.status-online {
background: #22c55e;
}
.status-text {
font-size: 12px;
color: #666;
}
.device-metrics {
display: flex;
gap: 16px;
}
.metric-item {
flex: 1;
display: flex;
align-items: center;
gap: 8px;
}
.metric-label {
font-size: 12px;
color: #999;
width: 35px;
}
.metric-value {
font-size: 12px;
color: #666;
}
.device-id {
display: flex;
align-items: center;
gap: 6px;
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid #f0f0f0;
}
.id-label {
font-size: 11px;
color: #999;
}
.id-value {
font-size: 11px;
color: #666;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>

View File

@@ -32,6 +32,12 @@
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>", "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>", "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.NEARBY_WIFI_DEVICES\"/>",
"<uses-permission android:name=\"android.permission.BLUETOOTH\"/>",
"<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>",
"<uses-permission android:name=\"android.permission.BLUETOOTH_SCAN\"/>",
"<uses-permission android:name=\"android.permission.BLUETOOTH_CONNECT\"/>",
"<uses-permission android:name=\"android.permission.BLUETOOTH_ADVERTISE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>", "<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>", "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",

View File

@@ -16,10 +16,10 @@
"navigationBarTitleText": "Road-Roller" "navigationBarTitleText": "Road-Roller"
}, },
"pages": [ "pages": [
// GENERATED BY UNI-PAGES, PLATFORM: H5 || APP // GENERATED BY UNI-PAGES, PLATFORM: APP
{ {
"path": "pages/Ahome/index", "path": "pages/Ahome/index",
"type": "page", "type": "home",
"layout": false, "layout": false,
"style": { "style": {
"navigationStyle": "custom" "navigationStyle": "custom"
@@ -121,7 +121,7 @@
"color": "@tabFontColor", "color": "@tabFontColor",
"selectedColor": "@tabSelectedColor", "selectedColor": "@tabSelectedColor",
"list": [ "list": [
// GENERATED BY UNI-PAGES, PLATFORM: H5 || APP // GENERATED BY UNI-PAGES, PLATFORM: APP
{ {
"pagePath": "pages/Ahome/index", "pagePath": "pages/Ahome/index",
"text": "首页", "text": "首页",

View File

@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
definePage({ definePage({
type: 'home',
layout: false, layout: false,
style: { style: {
navigationStyle: 'custom', navigationStyle: 'custom',
@@ -24,9 +25,6 @@ definePage({
<home-warning /> <home-warning />
</view> </view>
</view> </view>
<!-- 当前设备信息 -->
<home-deviceFooter />
</view> </view>
</view> </view>
</template> </template>

View File

@@ -2,18 +2,17 @@ import DB from '@/utils/sqlite'
import { historyReportTableSql } from './historyReport' import { historyReportTableSql } from './historyReport'
import { projectTableSql } from './project' import { projectTableSql } from './project'
import { rtkTrackTableSql } from './rtkTrack' import { rtkTrackTableSql } from './rtkTrack'
import { seedAll, seedIfNeeded } from './seed'
import { warningRecordTableSql } from './warningRecord' import { warningRecordTableSql } from './warningRecord'
import { workRecordTableSql } from './workRecord' import { workRecordTableSql } from './workRecord'
export { historyReportTableSql } from './historyReport' export { historyReportTableSql } from './historyReport'
export * as historyReportService from './historyReport' export * as historyReportService from './historyReport'
export { projectTableSql } from './project' export { projectTableSql } from './project'
// 导出所有 service 方法
export * as projectService from './project' export * as projectService from './project'
export { rtkTrackTableSql } from './rtkTrack' export { rtkTrackTableSql } from './rtkTrack'
export * as rtkTrackService from './rtkTrack' export * as rtkTrackService from './rtkTrack'
export { seedAll } from './seed' export { seedAll, seedIfNeeded } from './seed'
export { warningRecordTableSql } from './warningRecord' export { warningRecordTableSql } from './warningRecord'
export * as warningRecordService from './warningRecord' export * as warningRecordService from './warningRecord'
export { workRecordTableSql } from './workRecord' export { workRecordTableSql } from './workRecord'
@@ -27,14 +26,68 @@ const tableSqls = [
historyReportTableSql, historyReportTableSql,
] ]
/** 当前代码期望的各表字段(用于检测旧库结构) */
const expectedColumns: Record<string, string[]> = {
project: ['id', 'project_name', 'stake_range', 'total_area', 'status', 'created_at', 'updated_at'],
work_record: ['id', 'project_id', 'start_time', 'end_time', 'compaction_area', 'pass_count', 'created_at'],
rtk_track: ['id', 'work_record_id', 'latitude', 'longitude', 'speed', 'heading', 'steel_wheel_temp', 'compaction_value', 'created_at'],
warning_record: ['id', 'project_id', 'device_name', 'exception_type', 'occurred_at', 'site_description', 'disposal_record', 'disposal_type', 'is_read', 'created_at'],
history_report: ['id', 'project_id', 'report_name', 'device_id', 'construction_area', 'start_time', 'end_time', 'duration', 'compaction_area', 'pass_count', 'qualified_rate', 'avg_speed', 'avg_paving_temp', 'avg_compaction', 'exception_count', 'created_at'],
}
/** 按外键依赖倒序删除 */
const dropTableSqls = [
'DROP TABLE IF EXISTS history_report',
'DROP TABLE IF EXISTS warning_record',
'DROP TABLE IF EXISTS rtk_track',
'DROP TABLE IF EXISTS work_record',
'DROP TABLE IF EXISTS project',
]
async function getTableColumns(table: string): Promise<string[]> {
const rows = await DB.selectSql(`PRAGMA table_info(${table})`)
return (rows || []).map((row: { name: string }) => row.name)
}
/** 任一表缺少期望字段则视为结构过期 */
async function isSchemaOutdated(): Promise<boolean> {
for (const [table, columns] of Object.entries(expectedColumns)) {
const existing = await getTableColumns(table)
if (!existing.length)
return true
const missing = columns.filter(col => !existing.includes(col))
if (missing.length) {
console.warn(`表 ${table} 缺少字段:`, missing.join(', '))
return true
}
}
return false
}
/** 重建全部表并重新灌入假数据 */
async function resetDatabase() {
console.warn('检测到表结构过期,正在重建数据库...')
await DB.transaction(dropTableSqls)
await DB.transaction(tableSqls)
await seedAll()
console.log('数据库重建完成')
}
/** /**
* 初始化数据库 * 初始化数据库(建表 → 结构校验/重建 → 空表灌假数据)
*/ */
export async function initTables() { export async function initTables() {
try { try {
console.log('开始初始化数据库表...') console.log('开始初始化数据库表...')
await DB.transaction(tableSqls) await DB.transaction(tableSqls)
if (await isSchemaOutdated()) {
await resetDatabase()
return
}
console.log('数据库表初始化成功') console.log('数据库表初始化成功')
await seedIfNeeded()
} }
catch (err) { catch (err) {
console.error('数据库表初始化失败:', err) console.error('数据库表初始化失败:', err)

View File

@@ -231,3 +231,29 @@ export async function seedAll() {
throw err throw err
} }
} }
/**
* 按需灌入假数据(表为空才插入,避免重复)
*/
export async function seedIfNeeded() {
const projectCount = await DB.count('project')
// 全新库:灌入全部假数据
if (projectCount === 0) {
await seedAll()
return
}
// 已有项目但其它表为空:补种其余表(依赖已有 project / work_record id)
if ((await DB.count('work_record')) === 0)
await seedWorkRecord()
if ((await DB.count('rtk_track')) === 0)
await seedRtkTrack()
if ((await DB.count('warning_record')) === 0)
await seedWarningRecord()
if ((await DB.count('history_report')) === 0)
await seedHistoryReport()
}

View File

@@ -13,121 +13,73 @@ import {
workRecordService, workRecordService,
} from '@/service' } from '@/service'
/**
* 本地库统一数据源
*
* 用法:
* import { useDbStore } from '@/store/modules/db'
* const db = useDbStore()
* await db.loadAll()
*
* db.project // 项目表
* db.work_record // 作业记录表
* db.rtk_track // RTK 轨迹表
* db.warning_record // 告警记录表
* db.history_report // 历史报告表
*/
export const useDbStore = defineStore('db', () => { export const useDbStore = defineStore('db', () => {
// --- State --- const project = ref<Project[]>([])
const projects = ref<Project[]>([]) const work_record = ref<WorkRecord[]>([])
const workRecords = ref<WorkRecord[]>([]) const rtk_track = ref<RtkTrack[]>([])
const rtkTracks = ref<RtkTrack[]>([]) const warning_record = ref<WarningRecord[]>([])
const warningRecords = ref<WarningRecord[]>([]) const history_report = ref<HistoryReport[]>([])
const historyReports = ref<HistoryReport[]>([])
// --- Project --- /** 一次性加载所有表 */
async function loadProjects() { async function loadAll() {
projects.value = await projectService.selectAll() const [projects, workRecords, rtkTracks, warningRecords, historyReports] = await Promise.all([
projectService.selectAll(),
workRecordService.selectAll(),
rtkTrackService.selectAll(),
warningRecordService.selectAll(),
historyReportService.selectAll(),
])
project.value = projects
work_record.value = workRecords
rtk_track.value = rtkTracks
warning_record.value = warningRecords
history_report.value = historyReports
} }
async function addProject(data: Project) { /** 按项目筛选作业记录 */
await projectService.insert(data) async function loadWorkRecordByProject(projectId: number) {
await loadProjects() work_record.value = await workRecordService.selectByProjectId(projectId)
} }
async function updateProject(id: number, data: Partial<Project>) { /** 按作业记录筛选轨迹 */
await projectService.update(id, data) async function loadRtkTrackByWorkRecord(workRecordId: number) {
await loadProjects() rtk_track.value = await rtkTrackService.selectByWorkRecordId(workRecordId)
} }
async function deleteProject(id: number) { /** 按项目筛选告警 */
await projectService.remove(id) async function loadWarningByProject(projectId: number) {
await loadProjects() warning_record.value = await warningRecordService.selectByProjectId(projectId)
} }
// --- WorkRecord --- /** 按项目筛选历史报告 */
async function loadWorkRecords() { async function loadHistoryReportByProject(projectId: number) {
workRecords.value = await workRecordService.selectAll() history_report.value = await historyReportService.selectByProjectId(projectId)
}
async function loadWorkRecordsByProject(projectId: number) {
workRecords.value = await workRecordService.selectByProjectId(projectId)
}
async function addWorkRecord(data: WorkRecord) {
await workRecordService.insert(data)
await loadWorkRecords()
}
// --- RtkTrack ---
async function loadRtkTracks() {
rtkTracks.value = await rtkTrackService.selectAll()
}
async function loadRtkTracksByWorkRecord(workRecordId: number) {
rtkTracks.value = await rtkTrackService.selectByWorkRecordId(workRecordId)
}
async function addRtkTrack(data: RtkTrack) {
await rtkTrackService.insert(data)
}
// --- WarningRecord ---
async function loadWarningRecords() {
warningRecords.value = await warningRecordService.selectAll()
}
async function loadUnreadWarnings() {
warningRecords.value = await warningRecordService.selectUnread()
}
async function markWarningRead(id: number) {
await warningRecordService.markRead(id)
await loadWarningRecords()
}
// --- HistoryReport ---
async function loadHistoryReports() {
historyReports.value = await historyReportService.selectAll()
}
async function loadHistoryReportsByProject(projectId: number) {
historyReports.value = await historyReportService.selectByProjectId(projectId)
}
async function loadHistoryReportsByDevice(deviceId: string) {
historyReports.value = await historyReportService.selectByDeviceId(deviceId)
}
async function addHistoryReport(data: HistoryReport) {
await historyReportService.insert(data)
await loadHistoryReports()
} }
return { return {
// State project,
projects, work_record,
workRecords, rtk_track,
rtkTracks, warning_record,
warningRecords, history_report,
historyReports, loadAll,
// Project loadWorkRecordByProject,
loadProjects, loadRtkTrackByWorkRecord,
addProject, loadWarningByProject,
updateProject, loadHistoryReportByProject,
deleteProject,
// WorkRecord
loadWorkRecords,
loadWorkRecordsByProject,
addWorkRecord,
// RtkTrack
loadRtkTracks,
loadRtkTracksByWorkRecord,
addRtkTrack,
// WarningRecord
loadWarningRecords,
loadUnreadWarnings,
markWarningRead,
// HistoryReport
loadHistoryReports,
loadHistoryReportsByProject,
loadHistoryReportsByDevice,
addHistoryReport,
} }
}) })

View File

@@ -11,12 +11,21 @@ import UniPolyfill from 'vite-plugin-uni-polyfill'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
css: {
preprocessorOptions: {
scss: {
// 压制依赖包(uni-ui 等)的 Sass 旧 API / 全局函数弃用警告
silenceDeprecations: ['legacy-js-api', 'global-builtin', 'color-functions', 'import'],
},
},
},
plugins: [ plugins: [
// https://uni-helper.js.org/vite-plugin-uni-manifest // https://uni-helper.js.org/vite-plugin-uni-manifest
UniHelperManifest(), UniHelperManifest(),
// https://uni-helper.js.org/vite-plugin-uni-pages // https://uni-helper.js.org/vite-plugin-uni-pages
UniHelperPages({ UniHelperPages({
dts: 'src/uni-pages.d.ts', dts: 'src/uni-pages.d.ts',
homePage: 'pages/Ahome/index',
}), }),
// https://uni-helper.js.org/vite-plugin-uni-layouts // https://uni-helper.js.org/vite-plugin-uni-layouts
UniHelperLayouts(), UniHelperLayouts(),