refactor: restructure entire project for human maintainability

Server:
- Add Express framework, replace custom router/request parser
- Create DAO layer (12 files) centralizing all 73 SQL queries
- Rewrite 7 route files as thin Express controllers calling DAOs
- Add SCF-to-Express adapter (lib/serverless.js)
- Add auth middleware (middleware/auth.js)
- Remove dead code from lib/auth.js

Admin console:
- Extract DataTable component (table + pagination)
- Extract ConfirmModal component (modal + form styles)
- Create listMixin for paginated list pages
- Move form styles to common.css for slot compatibility
- Refactor device + subscription pages as examples

Miniprogram:
- Split 734-line BLE monolith into 4 focused modules
  (protocol, connection, commands, barrel index)
- Create API module (utils/api.js) with named functions
- Create page utilities (utils/page.js)
- Refactor index + profile pages to use API module
这个提交包含在:
Guoguo
2026-04-29 05:58:20 -07:00
父节点 9f0e629c82
当前提交 bb4b80f867
修改 46 个文件,包含 4306 行新增2020 行删除
@@ -0,0 +1,58 @@
<template>
<view class="modal-mask" v-if="visible" @click="$emit('close')">
<view class="modal-content" @click.stop>
<view class="modal-title">{{ title }}</view>
<slot></slot>
<view class="modal-actions">
<button class="btn-default" @click="$emit('close')">取消</button>
<button class="btn-primary" @click="$emit('confirm')" :loading="loading">{{ confirmText || '确定' }}</button>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
visible: Boolean,
title: String,
loading: Boolean,
confirmText: String
}
}
</script>
<style scoped>
@import '../styles/common.css';
.modal-mask {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.45);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-content {
width: 480px;
background: #fff;
border-radius: 8px;
padding: 24px;
}
.modal-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 20px;
}
.modal-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
margin-top: 20px;
}
</style>
@@ -0,0 +1,57 @@
<template>
<view class="page-card">
<slot name="toolbar"></slot>
<view class="data-table">
<view class="t-header">
<view class="t-row">
<text
v-for="col in columns"
:key="col.key"
:class="'t-th flex' + (col.flex || 1)"
>{{ col.label }}</text>
</view>
</view>
<view class="t-body">
<slot name="rows"></slot>
<view v-if="records.length === 0" class="empty-row">
<text class="empty-text">暂无数据</text>
</view>
</view>
</view>
<view class="pagination" v-if="totalPages > 1">
<button class="btn-page" :disabled="page <= 1" @click="$emit('page', page - 1)"></button>
<button class="btn-page active">{{ page }}</button>
<button class="btn-page" :disabled="page >= totalPages" @click="$emit('page', page + 1)"></button>
<text class="page-info"> {{ totalPages }} </text>
</view>
</view>
</template>
<script>
export default {
props: {
columns: { type: Array, required: true },
records: { type: Array, default: function () { return [] } },
page: { type: Number, default: 1 },
totalPages: { type: Number, default: 1 }
}
}
</script>
<style scoped>
@import '../styles/common.css';
.empty-row {
padding: 40px 0;
text-align: center;
}
.empty-text {
color: #999;
font-size: 14px;
}
.pagination {
justify-content: flex-end;
}
</style>