| src/api/environmentAccess/accessVehicle.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/api/environmentAccess/deviceCommand.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/api/environmentAccess/inspection.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/api/environmentAccess/reportCenter.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/api/environmentAccess/unattendedWeighbridgeSystem.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/api/environmentAccess/vehicleInfo.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/environmentAccess/remoteMonitor/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/environmentAccess/vehicleInfoAudit/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/environmentAccess/vehicleInfoCenter/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/environmentAccess/vehicleInfoCollect/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/api/environmentAccess/accessVehicle.js
ÎļþÒÑɾ³ý src/api/environmentAccess/deviceCommand.js
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,21 @@ import request from "@/utils/request"; // 设å¤å表ï¼è¿ç¨æ§å¶å¯¹è±¡ï¼ export function getDeviceList() { return request({ url: "/environmentAccess/deviceCommand/deviceList", method: "get" }); } // å¼å¸¸æ¥è¦å表 export function getAlarmList() { return request({ url: "/environmentAccess/deviceCommand/alarmList", method: "get" }); } // æä»¤è®°å½å页 export function getCommandPage(params) { return request({ url: "/environmentAccess/deviceCommand/listPage", method: "get", params }); } // ä¸åå¯åæä»¤ export function sendCommand(data) { return request({ url: "/environmentAccess/deviceCommand/send", method: "post", data }); } src/api/environmentAccess/inspection.js
ÎļþÒÑɾ³ý src/api/environmentAccess/reportCenter.js
ÎļþÒÑɾ³ý src/api/environmentAccess/unattendedWeighbridgeSystem.js
ÎļþÒÑɾ³ý src/api/environmentAccess/vehicleInfo.js
ÎļþÒÑɾ³ý src/views/environmentAccess/remoteMonitor/index.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,189 @@ <template> <div class="app-container"> <el-tabs v-model="activeTab"> <el-tab-pane label="设å¤å°è´¦" name="ledger" /> <el-tab-pane label="è¿ç¨æ§å¶" name="control" /> <el-tab-pane label="å¼å¸¸æ¥è¦" name="alarm"> <template #label> <span>å¼å¸¸æ¥è¦<el-badge v-if="unhandledCount > 0" :value="unhandledCount" style="margin-left: 6px" /></span> </template> </el-tab-pane> </el-tabs> <!-- è¿ç¨æ§å¶ --> <div v-if="activeTab === 'ledger'"> <LedgerPage /> </div> <div v-else-if="activeTab === 'control'"> <div class="section-title">设å¤å表ï¼è¿ç¨å¯åï¼</div> <el-table :data="deviceList" border v-loading="deviceLoading" height="300"> <el-table-column align="center" label="åºå·" type="index" width="60" /> <el-table-column label="设å¤åç§°" prop="deviceName" show-overflow-tooltip /> <el-table-column label="è§æ ¼åå·" prop="deviceModel" show-overflow-tooltip /> <el-table-column label="åä½" prop="unit" width="80" /> <el-table-column fixed="right" label="è¿ç¨æ§å¶" width="180" align="center"> <template #default="scope"> <el-button link type="success" size="small" @click="handleSend(scope.row, 'start')">å¯å¨</el-button> <el-button link type="danger" size="small" @click="handleSend(scope.row, 'stop')">忢</el-button> </template> </el-table-column> </el-table> <div class="section-title" style="margin-top: 16px">æä»¤è®°å½</div> <el-table :data="commandList" border v-loading="commandLoading" height="300"> <el-table-column align="center" label="åºå·" type="index" width="60" /> <el-table-column label="设å¤åç§°" prop="deviceName" show-overflow-tooltip /> <el-table-column label="æä»¤" prop="commandType" width="90" align="center"> <template #default="scope"> <el-tag :type="scope.row.commandType === 'start' ? 'success' : 'danger'"> {{ scope.row.commandType === 'start' ? 'å¯å¨' : '忢' }} </el-tag> </template> </el-table-column> <el-table-column label="ç¶æ" prop="commandStatus" width="100" align="center"> <template #default="scope"> <el-tag :type="scope.row.commandStatus === 'success' ? 'success' : (scope.row.commandStatus === 'failed' ? 'danger' : 'info')"> {{ scope.row.commandStatus === 'success' ? 'æå' : (scope.row.commandStatus === 'failed' ? '失败' : 'ä¸åä¸') }} </el-tag> </template> </el-table-column> <el-table-column label="æä½äºº" prop="operator" width="110" /> <el-table-column label="ä¸åæ¶é´" prop="commandTime" width="170" /> <el-table-column label="æ§è¡ç»æ" prop="resultMsg" show-overflow-tooltip /> </el-table> <pagination v-show="commandPage.total > 0" :total="commandPage.total" layout="total, prev, pager, next" :page="commandPage.current" :limit="commandPage.size" @pagination="commandPageChange" /> </div> <!-- å¼å¸¸æ¥è¦ --> <div v-else> <el-alert type="info" :closable="false" show-icon style="margin-bottom: 10px" title="ç³»ç»æ¯ 60 ç§èªå¨æ£æ¥ä¸æ¬¡æ°æ¥è¦ï¼åç°æªå¤çæ¥è¦ä¼å¼¹çªæéï¼ç«å æ¨éï¼" /> <el-table :data="alarmList" border v-loading="alarmLoading" height="calc(100vh - 16em)"> <el-table-column align="center" label="åºå·" type="index" width="60" /> <el-table-column label="设å¤åç§°" prop="deviceName" show-overflow-tooltip width="220"> <template #default="scope">{{ scope.row.deviceName || '-' }}</template> </el-table-column> <el-table-column label="æ éæè¿°" prop="defectDescription" show-overflow-tooltip /> <el-table-column label="设å¤ç¶æ" prop="status" width="120" /> <el-table-column label="æ¯å¦å¤ç" width="110" align="center"> <template #default="scope"> <el-tag :type="scope.row.handled ? 'success' : 'danger'">{{ scope.row.handled ? 'å·²æ¶é¤' : 'æªå¤ç' }}</el-tag> </template> </el-table-column> <el-table-column label="åçæ¶é´" prop="createTime" width="170" /> <el-table-column label="æ¶é¤æ¶é´" prop="eliminateTime" width="170" /> </el-table> </div> </div> </template> <script setup> import { ref, onMounted, onUnmounted, computed } from "vue"; import { ElNotification, ElMessageBox, ElMessage } from "element-plus"; import pagination from "@/components/PIMTable/Pagination.vue"; import LedgerPage from "@/views/equipmentManagement/ledger/index.vue"; import { getDeviceList, getAlarmList, getCommandPage, sendCommand } from "@/api/environmentAccess/deviceCommand.js"; defineOptions({ name: "设å¤è¿ç¨çæ§" }); const activeTab = ref("ledger"); const deviceList = ref([]); const deviceLoading = ref(false); const commandList = ref([]); const commandLoading = ref(false); const commandPage = ref({ current: 1, size: 10, total: 0 }); const alarmList = ref([]); const alarmLoading = ref(false); const unhandledCount = computed(() => alarmList.value.filter((a) => !a.handled).length); /* ---------- è¿ç¨æ§å¶ ---------- */ const loadDevices = () => { deviceLoading.value = true; getDeviceList().then((res) => { deviceList.value = res.data || []; }).finally(() => { deviceLoading.value = false; }); }; const loadCommands = () => { commandLoading.value = true; getCommandPage({ current: commandPage.value.current, size: commandPage.value.size }).then((res) => { commandList.value = (res.data && res.data.records) || []; commandPage.value.total = (res.data && res.data.total) || 0; }).finally(() => { commandLoading.value = false; }); }; const commandPageChange = (obj) => { commandPage.value.current = obj.page; commandPage.value.size = obj.limit; loadCommands(); }; const handleSend = (row, type) => { const label = type === "start" ? "å¯å¨" : "忢"; ElMessageBox.confirm(`确认对ã${row.deviceName || '该设å¤'}ãä¸å${label}æä»¤ï¼`, "è¿ç¨æ§å¶", { type: "warning" }) .then(() => { sendCommand({ deviceLedgerId: row.id, deviceName: row.deviceName, commandType: type }).then((res) => { ElMessage.success(res.msg || `${label}æä»¤å·²ä¸å`); commandPage.value.current = 1; loadCommands(); }); }) .catch(() => {}); }; /* ---------- å¼å¸¸æ¥è¦ï¼å«ç«å å¼¹çªæéï¼ ---------- */ let alarmTimer = null; let lastMaxAlarmId = null; const loadAlarms = (notify) => { alarmLoading.value = true; return getAlarmList().then((res) => { const list = res.data || []; alarmList.value = list; const maxId = list.reduce((m, a) => Math.max(m, Number(a.id) || 0), 0); if (notify && lastMaxAlarmId !== null && maxId > lastMaxAlarmId) { const fresh = list.filter((a) => Number(a.id) > lastMaxAlarmId && !a.handled); fresh.slice(0, 3).forEach((a) => { ElNotification({ title: "设å¤å¼å¸¸æ¥è¦", message: `ã${a.deviceName || 'æªç¥è®¾å¤'}ã${a.defectDescription || 'åçè®¾å¤æ é'}ï¼è¯·åæ¶å¤ç`, type: "error", duration: 15000, position: "bottom-right", }); }); } lastMaxAlarmId = maxId; }).finally(() => { alarmLoading.value = false; }); }; const startAlarmPolling = () => { loadAlarms(false); alarmTimer = setInterval(() => loadAlarms(true), 60000); }; onMounted(() => { loadDevices(); loadCommands(); startAlarmPolling(); }); onUnmounted(() => { if (alarmTimer) { clearInterval(alarmTimer); alarmTimer = null; } }); </script> <style scoped lang="scss"> .section-title { font-size: 14px; font-weight: 600; color: #303133; margin-bottom: 8px; } </style> src/views/environmentAccess/vehicleInfoAudit/index.vue
@@ -367,8 +367,8 @@ function loadTableData() { tableLoading.value = true; listVehicleInfo({ pageNum: page.current, pageSize: page.size, current: page.current, size: page.size, ...searchForm, }) .then((res) => { @@ -419,6 +419,7 @@ .then(() => { ElMessage.success(operationType.value === "add" ? "æ°å¢æå" : "ç¼è¾æå"); dialogVisible.value = false; if (operationType.value === "add") page.current = 1; loadTableData(); }) .catch(() => {}); src/views/environmentAccess/vehicleInfoCenter/index.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,43 @@ <template> <div class="vehicle-center"> <el-tabs v-model="activeTab" class="center-tabs"> <el-tab-pane label="ééå®¡æ ¸" name="audit" /> <el-tab-pane label="ææºç«¯éé" name="collect" /> </el-tabs> <div class="center-body"> <keep-alive> <component :is="currentComponent" /> </keep-alive> </div> </div> </template> <script setup> import { ref, computed } from "vue"; import AuditPage from "../vehicleInfoAudit/index.vue"; import CollectPage from "../vehicleInfoCollect/index.vue"; defineOptions({ name: "车è¾ä¿¡æ¯ééå®¡æ ¸" }); const activeTab = ref("audit"); const tabMap = { audit: AuditPage, collect: CollectPage, }; const currentComponent = computed(() => tabMap[activeTab.value] || AuditPage); </script> <style scoped lang="scss"> .vehicle-center { padding: 10px 12px; } .center-tabs { margin-bottom: 6px; } /* å页é¢èªå¸¦ç app-container ä¼å¤ä¸å±å è¾¹è· */ .center-body :deep(.app-container) { padding: 0; } </style> src/views/environmentAccess/vehicleInfoCollect/index.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,189 @@ <template> <div class="collect-page"> <div class="collect-header"> <h2>车è¾ä¿¡æ¯éé</h2> <p>请å¦å®å¡«å车è¾ä¿¡æ¯ï¼æäº¤åç±ä¼ä¸å®¡æ ¸</p> </div> <el-form ref="formRef" :model="form" :rules="rules" label-position="top" class="collect-form"> <el-form-item label="车çå·ç " prop="plateNo"> <el-input v-model="form.plateNo" size="large" placeholder="å¦ï¼èA12345" clearable /> </el-form-item> <el-form-item label="å·çé¢è²" prop="plateColor"> <el-select v-model="form.plateColor" size="large" placeholder="è¯·éæ©" style="width: 100%"> <el-option v-for="i in plateColorOptions" :key="i" :label="i" :value="i" /> </el-select> </el-form-item> <el-form-item label="车è¾ç±»å" prop="carType"> <el-select v-model="form.carType" size="large" placeholder="è¯·éæ©" style="width: 100%"> <el-option v-for="i in carTypeOptions" :key="i" :label="i" :value="i" /> </el-select> </el-form-item> <el-form-item label="车è¾è¯å«ä»£ç ï¼VINï¼" prop="carVin"> <el-input v-model="form.carVin" size="large" placeholder="17 ä½ VIN ç " clearable /> </el-form-item> <el-form-item label="车è¾åå·" prop="carModel"> <el-input v-model="form.carModel" size="large" placeholder="请è¾å ¥è½¦è¾åå·" clearable /> </el-form-item> <el-form-item label="å卿ºåå·" prop="engineModel"> <el-input v-model="form.engineModel" size="large" placeholder="请è¾å ¥å卿ºåå·" clearable /> </el-form-item> <el-form-item label="å卿ºç产å" prop="engineProductFactory"> <el-input v-model="form.engineProductFactory" size="large" placeholder="请è¾å ¥å卿ºç产å" clearable /> </el-form-item> <el-form-item label="å卿ºç¼å·" prop="engineNo"> <el-input v-model="form.engineNo" size="large" placeholder="请è¾å ¥å卿ºç¼å·" clearable /> </el-form-item> <el-form-item label="ææ¾æ å" prop="emissionStandard"> <el-select v-model="form.emissionStandard" size="large" placeholder="è¯·éæ©" style="width: 100%"> <el-option v-for="i in emissionOptions" :key="i" :label="i" :value="i" /> </el-select> </el-form-item> <el-form-item label="注åç»è®°æ¥æ" prop="registeDate"> <el-date-picker v-model="form.registeDate" size="large" type="date" value-format="YYYY-MM-DD" placeholder="è¯·éæ©æ³¨åç»è®°æ¥æ" style="width: 100%" /> </el-form-item> <el-form-item label="ä½¿ç¨æ§è´¨" prop="natureOfUse"> <el-select v-model="form.natureOfUse" size="large" placeholder="è¯·éæ©" style="width: 100%"> <el-option v-for="i in natureOptions" :key="i" :label="i" :value="i" /> </el-select> </el-form-item> <el-form-item label="çæç±»å" prop="fuelType"> <el-select v-model="form.fuelType" size="large" placeholder="è¯·éæ©" style="width: 100%"> <el-option v-for="i in fuelOptions" :key="i" :label="i" :value="i" /> </el-select> </el-form-item> <div class="collect-actions"> <el-button type="primary" size="large" :loading="submitting" style="width: 100%" @click="submit"> æäº¤éé </el-button> <el-button size="large" style="width: 100%; margin: 10px 0 0 0" @click="reset">éæ°å¡«å</el-button> </div> </el-form> </div> </template> <script setup> import { ref, reactive } from "vue"; import { ElMessage } from "element-plus"; import { addVehicleInfo } from "@/api/environmentAccess/vehicleInfo.js"; defineOptions({ name: "车è¾ä¿¡æ¯éé" }); const formRef = ref(); const submitting = ref(false); const plateColorOptions = ["èè²", "é»è²", "绿è²", "ç½è²", "é»è²", "å ¶ä»"]; const carTypeOptions = ["å°å汽车", "大忱½è½¦", "æ°è½æºæ±½è½¦", "æè½¦", "æ©æè½¦", "å ¶ä»"]; const emissionOptions = ["å½ä¸", "å½å", "å½äº", "å½å ", "纯çµå¨", "å ¶ä»"]; const natureOptions = ["è¥è¿", "éè¥è¿", "è´§è¿", "客è¿", "å ¶ä»"]; const fuelOptions = ["汽油", "æ´æ²¹", "å¤©ç¶æ°", "çµ", "æ··åå¨å", "å ¶ä»"]; const emptyForm = () => ({ plateNo: "", plateColor: "", carType: "", carVin: "", carModel: "", engineModel: "", engineProductFactory: "", engineNo: "", emissionStandard: "", registeDate: "", natureOfUse: "", fuelType: "", }); const form = reactive(emptyForm()); const rules = { plateNo: [{ required: true, message: "请è¾å ¥è½¦çå·ç ", trigger: "blur" }], plateColor: [{ required: true, message: "è¯·éæ©å·çé¢è²", trigger: "change" }], carType: [{ required: true, message: "è¯·éæ©è½¦è¾ç±»å", trigger: "change" }], }; const submit = () => { formRef.value?.validate((valid) => { if (!valid) return; submitting.value = true; addVehicleInfo({ ...form, reviewStatus: "pending" }) .then(() => { ElMessage.success("æäº¤æåï¼çå¾ ä¼ä¸å®¡æ ¸"); Object.assign(form, emptyForm()); formRef.value?.clearValidate(); }) .catch(() => ElMessage.error("æäº¤å¤±è´¥ï¼è¯·ç¨åéè¯")) .finally(() => { submitting.value = false; }); }); }; const reset = () => { Object.assign(form, emptyForm()); formRef.value?.clearValidate(); }; </script> <style scoped lang="scss"> .collect-page { max-width: 640px; margin: 0 auto; padding: 16px 14px 40px; background: #fff; min-height: 100vh; box-sizing: border-box; } .collect-header { padding: 8px 0 16px; border-bottom: 1px solid #ebeef5; margin-bottom: 18px; h2 { margin: 0 0 6px; font-size: 20px; color: #303133; } p { margin: 0; font-size: 13px; color: #909399; } } .collect-form { :deep(.el-form-item__label) { font-size: 15px; padding-bottom: 4px; } :deep(.el-input__inner), :deep(.el-select__placeholder) { font-size: 15px; } } .collect-actions { margin-top: 22px; } </style>