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
这个提交包含在:
@@ -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>
|
||||
在新工单中引用
屏蔽一个用户