Commit f99fb9c6cb3f54c4f6410fadeb36323b9980f948

Authored by wuxw
1 parent 0d6fa19e

admin完成物联网相关功能

src/api/iot/adminCarInoutApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取车辆进出记录列表
  4 +export function listAdminCarInoutDetail(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/iot.listAdminCarInoutDetail',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + if (res.code === 0) {
  13 + resolve({
  14 + data: res.data,
  15 + total: res.total,
  16 + records: res.records
  17 + })
  18 + } else {
  19 + reject(new Error(res.msg || '获取车辆进出记录失败'))
  20 + }
  21 + }).catch(error => {
  22 + reject(error)
  23 + })
  24 + })
  25 +}
  26 +
  27 +// 获取管理小区列表
  28 +export function listAdminCommunitys(params) {
  29 + return new Promise((resolve, reject) => {
  30 + request({
  31 + url: '/community.listAdminCommunitys',
  32 + method: 'get',
  33 + params
  34 + }).then(response => {
  35 + const res = response.data
  36 + if (res.code === 0) {
  37 + resolve({
  38 + data: res.data
  39 + })
  40 + } else {
  41 + reject(new Error(res.msg || '获取管理小区列表失败'))
  42 + }
  43 + }).catch(error => {
  44 + reject(error)
  45 + })
  46 + })
  47 +}
0 \ No newline at end of file 48 \ No newline at end of file
src/api/iot/adminChargeOrderApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取充电订单列表
  4 +export function listAdminChargeMachineOrder(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/iot.listAdminChargeMachineOrder',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + if (res.code === 0) {
  13 + resolve({
  14 + data: res.data,
  15 + total: res.total
  16 + })
  17 + } else {
  18 + reject(new Error(res.msg || '获取充电订单列表失败'))
  19 + }
  20 + }).catch(error => {
  21 + reject(error)
  22 + })
  23 + })
  24 +}
  25 +
  26 +// 获取小区列表
  27 +export function listAdminCommunitys(params) {
  28 + return new Promise((resolve, reject) => {
  29 + request({
  30 + url: '/community.listAdminCommunitys',
  31 + method: 'get',
  32 + params
  33 + }).then(response => {
  34 + const res = response.data
  35 + if (res.code === 0) {
  36 + resolve({
  37 + data: res.data,
  38 + total: res.total
  39 + })
  40 + } else {
  41 + reject(new Error(res.msg || '获取小区列表失败'))
  42 + }
  43 + }).catch(error => {
  44 + reject(error)
  45 + })
  46 + })
  47 +}
0 \ No newline at end of file 48 \ No newline at end of file
src/api/iot/adminMeterRechargeApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取充值明细列表
  4 +export function listAdminMeterCharge(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/iot.listAdminMeterCharge',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + if (res.code === 0) {
  13 + resolve(res)
  14 + } else {
  15 + reject(new Error(res.msg || '获取充值明细列表失败'))
  16 + }
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +// 获取管理员小区列表
  24 +export function listAdminCommunitys(params) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/community.listAdminCommunitys',
  28 + method: 'get',
  29 + params
  30 + }).then(response => {
  31 + const res = response.data
  32 + if (res.code === 0) {
  33 + resolve(res)
  34 + } else {
  35 + reject(new Error(res.msg || '获取管理员小区列表失败'))
  36 + }
  37 + }).catch(error => {
  38 + reject(error)
  39 + })
  40 + })
  41 +}
0 \ No newline at end of file 42 \ No newline at end of file
src/components/iot/selectAdminCommunity.vue
1 <template> 1 <template>
2 - <div class="border-radius"> 2 + <el-card class="border-radius">
3 <div class="margin-xs-r treeview attendance-staff" style="height: 650px;"> 3 <div class="margin-xs-r treeview attendance-staff" style="height: 650px;">
4 <ul class="list-group text-center border-radius"> 4 <ul class="list-group text-center border-radius">
5 <li 5 <li
6 class="list-group-item node-orgTree" 6 class="list-group-item node-orgTree"
7 - v-for="(item,index) in communitys" 7 + v-for="(item,index) in selectAdminCommunityInfo.communitys"
8 :key="index" 8 :key="index"
9 - @click="handleSwatchCommunity(item)"  
10 - :class="{'vc-node-selected': communityId === item.communityId}" 9 + @click="_swatchAdminCommunity(item)"
  10 + :class="{'vc-node-selected': selectAdminCommunityInfo.communityId == item.communityId}"
11 > 11 >
12 {{item.name}} 12 {{item.name}}
13 </li> 13 </li>
14 </ul> 14 </ul>
15 </div> 15 </div>
16 - </div> 16 + </el-card>
17 </template> 17 </template>
18 18
19 <script> 19 <script>
20 -import { listAdminCommunitys } from '@/api/iot/adminInoutApi'  
21 -  
22 export default { 20 export default {
23 name: 'SelectAdminCommunity', 21 name: 'SelectAdminCommunity',
24 data() { 22 data() {
25 return { 23 return {
26 - communitys: [],  
27 - communityId: '' 24 + selectAdminCommunityInfo: {
  25 + communitys: [],
  26 + communityId: ''
  27 + }
28 } 28 }
29 }, 29 },
30 created() { 30 created() {
31 - this.loadAdminCommunitys() 31 + this._loadAdminCommunitys()
32 }, 32 },
33 methods: { 33 methods: {
34 - async loadAdminCommunitys() {  
35 - try {  
36 - const params = { 34 + async _loadAdminCommunitys() {
  35 + const param = {
  36 + params: {
37 _uid: '123mlkdinkldldijdhuudjdjkkd', 37 _uid: '123mlkdinkldldijdhuudjdjkkd',
38 page: 1, 38 page: 1,
39 row: 100 39 row: 100
40 } 40 }
41 - const res = await listAdminCommunitys(params)  
42 - this.communitys = [  
43 - { name: this.$t('adminInout.allCommunities'), communityId: '' },  
44 - ...res.data  
45 - ]  
46 - this.handleSwatchCommunity(this.communitys[0]) 41 + }
  42 +
  43 + const _communistys = [{
  44 + name: this.$t('adminMeterRecharge.allCommunities'),
  45 + communityId: ''
  46 + }]
  47 +
  48 + this.selectAdminCommunityInfo.communitys = _communistys
  49 +
  50 + try {
  51 + const res = await this.$api.listAdminCommunitys(param)
  52 + res.data.forEach(c => {
  53 + _communistys.push(c)
  54 + })
  55 + this.selectAdminCommunityInfo.communitys = _communistys
  56 + this._swatchAdminCommunity(_communistys[0])
47 } catch (error) { 57 } catch (error) {
48 - console.error('Failed to load communities:', error) 58 + console.error('请求失败处理', error)
49 } 59 }
50 }, 60 },
51 - handleSwatchCommunity(community) {  
52 - this.communityId = community.communityId  
53 - this.$emit('change-community', community) 61 + _swatchAdminCommunity(_community) {
  62 + this.selectAdminCommunityInfo.communityId = _community.communityId
  63 + this.$emit('changeCommunity', _community)
54 } 64 }
55 } 65 }
56 } 66 }
57 </script> 67 </script>
58 68
59 <style scoped> 69 <style scoped>
  70 +.border-radius {
  71 + border-radius: 4px;
  72 +}
  73 +.margin-xs-r {
  74 + margin-right: 5px;
  75 +}
  76 +.treeview {
  77 + overflow-y: auto;
  78 +}
  79 +.list-group {
  80 + padding-left: 0;
  81 + margin-bottom: 0;
  82 +}
  83 +.list-group-item {
  84 + position: relative;
  85 + display: block;
  86 + padding: 10px 15px;
  87 + margin-bottom: -1px;
  88 + background-color: #fff;
  89 + border: 1px solid #ddd;
  90 + cursor: pointer;
  91 +}
  92 +.list-group-item:hover {
  93 + background-color: #f5f5f5;
  94 +}
60 .vc-node-selected { 95 .vc-node-selected {
61 - background-color: #f5f7fa;  
62 - color: #409eff; 96 + background-color: #409EFF;
  97 + color: white;
63 } 98 }
64 </style> 99 </style>
65 \ No newline at end of file 100 \ No newline at end of file
src/i18n/commonLang.js
@@ -30,7 +30,8 @@ export const messages = { @@ -30,7 +30,8 @@ export const messages = {
30 resetPwdSuccess: 'Reset password successfully, new password is {pwd}, please change it in time', 30 resetPwdSuccess: 'Reset password successfully, new password is {pwd}, please change it in time',
31 female: 'Female', 31 female: 'Female',
32 male: 'Male', 32 male: 'Male',
33 - all: 'All' 33 + all: 'All',
  34 + refresh: 'Refresh'
34 } 35 }
35 }, 36 },
36 zh: { 37 zh: {
@@ -64,7 +65,8 @@ export const messages = { @@ -64,7 +65,8 @@ export const messages = {
64 resetPwdSuccess: '修改密码成功,密码为{pwd}请及时修改密码', 65 resetPwdSuccess: '修改密码成功,密码为{pwd}请及时修改密码',
65 female: '女', 66 female: '女',
66 male: '男', 67 male: '男',
67 - all: '全部' 68 + all: '全部',
  69 + refresh: '刷新'
68 } 70 }
69 } 71 }
70 } 72 }
71 \ No newline at end of file 73 \ No newline at end of file
src/i18n/index.js
@@ -81,6 +81,9 @@ import { messages as adminBarrierMessages } from &#39;../views/iot/adminBarrierLang&#39; @@ -81,6 +81,9 @@ import { messages as adminBarrierMessages } from &#39;../views/iot/adminBarrierLang&#39;
81 import { messages as adminChargeMachineMessages } from '../views/iot/adminChargeMachineLang' 81 import { messages as adminChargeMachineMessages } from '../views/iot/adminChargeMachineLang'
82 import { messages as adminMeterMessages } from '../views/iot/adminMeterLang' 82 import { messages as adminMeterMessages } from '../views/iot/adminMeterLang'
83 import { messages as adminInoutMessages } from '../views/iot/adminInoutLang' 83 import { messages as adminInoutMessages } from '../views/iot/adminInoutLang'
  84 +import { messages as adminCarInoutMessages } from '../views/iot/adminCarInoutLang'
  85 +import { messages as adminChargeOrderMessages } from '../views/iot/adminChargeOrderLang'
  86 +import { messages as adminMeterRechargeMessages } from '../views/iot/adminMeterRechargeLang'
84 87
85 Vue.use(VueI18n) 88 Vue.use(VueI18n)
86 89
@@ -166,6 +169,9 @@ const messages = { @@ -166,6 +169,9 @@ const messages = {
166 ...adminChargeMachineMessages.en, 169 ...adminChargeMachineMessages.en,
167 ...adminMeterMessages.en, 170 ...adminMeterMessages.en,
168 ...adminInoutMessages.en, 171 ...adminInoutMessages.en,
  172 + ...adminCarInoutMessages.en,
  173 + ...adminChargeOrderMessages.en,
  174 + ...adminMeterRechargeMessages.en,
169 }, 175 },
170 zh: { 176 zh: {
171 ...loginMessages.zh, 177 ...loginMessages.zh,
@@ -247,6 +253,9 @@ const messages = { @@ -247,6 +253,9 @@ const messages = {
247 ...adminChargeMachineMessages.zh, 253 ...adminChargeMachineMessages.zh,
248 ...adminMeterMessages.zh, 254 ...adminMeterMessages.zh,
249 ...adminInoutMessages.zh, 255 ...adminInoutMessages.zh,
  256 + ...adminCarInoutMessages.zh,
  257 + ...adminChargeOrderMessages.zh,
  258 + ...adminMeterRechargeMessages.zh,
250 } 259 }
251 } 260 }
252 261
src/router/index.js
@@ -387,10 +387,25 @@ const routes = [ @@ -387,10 +387,25 @@ const routes = [
387 component: () => import('@/views/iot/adminMeterList.vue') 387 component: () => import('@/views/iot/adminMeterList.vue')
388 }, 388 },
389 { 389 {
390 - path:'/pages/iot/adminInout',  
391 - name:'/pages/iot/adminInout', 390 + path: '/pages/iot/adminInout',
  391 + name: '/pages/iot/adminInout',
392 component: () => import('@/views/iot/adminInoutList.vue') 392 component: () => import('@/views/iot/adminInoutList.vue')
  393 + },
  394 + {
  395 + path: '/pages/iot/adminCarInout',
  396 + name: '/pages/iot/adminCarInout',
  397 + component: () => import('@/views/iot/adminCarInoutList.vue')
  398 + },
  399 + {
  400 + path:'/pages/iot/adminChargeOrder',
  401 + name:'/pages/iot/adminChargeOrder',
  402 + component: () => import('@/views/iot/adminChargeOrderList.vue')
393 }, 403 },
  404 + {
  405 + path:'/pages/iot/adminMeterRecharge',
  406 + name:'/pages/iot/adminMeterRecharge',
  407 + component: () => import('@/views/iot/adminMeterRechargeList.vue')
  408 + },
394 // 其他子路由可以在这里添加 409 // 其他子路由可以在这里添加
395 ] 410 ]
396 }, 411 },
src/views/iot/adminCarInoutLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + adminCarInout: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + carNum: 'Please enter license plate number',
  7 + state: 'Please select vehicle status',
  8 + startTime: 'Please select start time',
  9 + endTime: 'Please select end time',
  10 + carType: 'Please select license plate type'
  11 + },
  12 + list: {
  13 + title: 'In/Out Records'
  14 + },
  15 + table: {
  16 + photo: 'In Photo',
  17 + communityName: 'Community Name',
  18 + ciId: 'In/Out ID',
  19 + state: 'Vehicle Status',
  20 + carNum: 'License Plate',
  21 + paNum: 'Parking Lot',
  22 + feeName: 'Billing Rule',
  23 + carTypeName: 'Plate Type',
  24 + inTime: 'In Time',
  25 + outTime: 'Out Time',
  26 + parkingTime: 'Parking Time',
  27 + charge: 'Charge Amount',
  28 + remark: 'Remark'
  29 + },
  30 + state: {
  31 + select: 'Please select vehicle status',
  32 + inStatus: 'In Status',
  33 + paid: 'Payment Completed',
  34 + outStatus: 'Out Status',
  35 + repay: 'Payment Timeout Repay',
  36 + in: 'In',
  37 + out: 'Out'
  38 + },
  39 + carType: {
  40 + select: 'Please select license plate type',
  41 + temp: 'Temporary',
  42 + sale: 'Sale',
  43 + monthly: 'Monthly',
  44 + white: 'White List',
  45 + black: 'Black List',
  46 + internal: 'Internal',
  47 + free: 'Free'
  48 + },
  49 + community: {
  50 + all: 'All Communities'
  51 + },
  52 + time: {
  53 + hour: 'hour',
  54 + min: 'min'
  55 + },
  56 + action: {
  57 + out: 'Out'
  58 + },
  59 + fetchError: 'Failed to fetch in/out records'
  60 + }
  61 + },
  62 + zh: {
  63 + adminCarInout: {
  64 + search: {
  65 + title: '查询条件',
  66 + carNum: '请输入车牌号',
  67 + state: '请选择车辆状态',
  68 + startTime: '请选择开始时间',
  69 + endTime: '请选择结束时间',
  70 + carType: '请选择车牌类型'
  71 + },
  72 + list: {
  73 + title: '进出记录'
  74 + },
  75 + table: {
  76 + photo: '进场图',
  77 + communityName: '小区名称',
  78 + ciId: '进出场编号',
  79 + state: '车辆状态',
  80 + carNum: '车牌号',
  81 + paNum: '停车场',
  82 + feeName: '计费规则',
  83 + carTypeName: '车牌类型',
  84 + inTime: '进场时间',
  85 + outTime: '出场时间',
  86 + parkingTime: '停车时间',
  87 + charge: '收费金额',
  88 + remark: '说明'
  89 + },
  90 + state: {
  91 + select: '请选择车辆状态',
  92 + inStatus: '进场状态',
  93 + paid: '支付完成',
  94 + outStatus: '离场状态',
  95 + repay: '支付超时重新支付',
  96 + in: '进场',
  97 + out: '出场'
  98 + },
  99 + carType: {
  100 + select: '请选择车牌类型',
  101 + temp: '临时车',
  102 + sale: '出售车辆',
  103 + monthly: '月租车',
  104 + white: '白名单',
  105 + black: '黑名单',
  106 + internal: '内部车',
  107 + free: '免费车'
  108 + },
  109 + community: {
  110 + all: '全部小区'
  111 + },
  112 + time: {
  113 + hour: '小时',
  114 + min: '分'
  115 + },
  116 + action: {
  117 + out: '出场'
  118 + },
  119 + fetchError: '获取进出记录失败'
  120 + }
  121 + }
  122 +}
0 \ No newline at end of file 123 \ No newline at end of file
src/views/iot/adminCarInoutList.vue 0 → 100644
  1 +<template>
  2 + <div class="admin-car-inout-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="4">
  5 + <select-admin-community @changeCommunity="handleCommunityChange" />
  6 + </el-col>
  7 + <el-col :span="20">
  8 + <el-card class="box-card">
  9 + <div slot="header" class="clearfix flex justify-between">
  10 + <span>{{ $t('adminCarInout.search.title') }}</span>
  11 + </div>
  12 + <el-row :gutter="20">
  13 + <el-col :span="4">
  14 + <el-input v-model="searchForm.carNum" :placeholder="$t('adminCarInout.search.carNum')" clearable />
  15 + </el-col>
  16 + <el-col :span="4">
  17 + <el-select v-model="searchForm.state" :placeholder="$t('adminCarInout.search.state')" clearable>
  18 + <el-option v-for="item in stateOptions" :key="item.value" :label="item.label" :value="item.value" />
  19 + </el-select>
  20 + </el-col>
  21 + <el-col :span="4">
  22 + <el-select v-model="searchForm.carType" :placeholder="$t('adminCarInout.search.carType')" clearable>
  23 + <el-option v-for="item in carTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
  24 + </el-select>
  25 + </el-col>
  26 + <el-col :span="4">
  27 + <el-date-picker v-model="searchForm.startTime" type="datetime"
  28 + :placeholder="$t('adminCarInout.search.startTime')" value-format="yyyy-MM-dd HH:mm:ss" />
  29 + </el-col>
  30 + <el-col :span="4">
  31 + <el-date-picker v-model="searchForm.endTime" type="datetime"
  32 + :placeholder="$t('adminCarInout.search.endTime')" value-format="yyyy-MM-dd HH:mm:ss" />
  33 + </el-col>
  34 + <el-col :span="4" class="text-right">
  35 + <el-button type="primary" @click="handleSearch">
  36 + <i class="el-icon-search"></i>
  37 + {{ $t('common.search') }}
  38 + </el-button>
  39 + </el-col>
  40 + </el-row>
  41 + </el-card>
  42 +
  43 + <el-card class="box-card">
  44 + <div slot="header" class="clearfix flex justify-between">
  45 + <span>{{ $t('adminCarInout.list.title') }}</span>
  46 + </div>
  47 + <el-table v-loading="loading" :data="tableData" border style="width: 100%">
  48 + <el-table-column :label="$t('adminCarInout.table.photo')" align="center" width="100">
  49 + <template slot-scope="scope">
  50 + <el-image style="width: 60px; height: 60px; cursor: pointer;"
  51 + :src="scope.row.photoJpg || '/img/noPhoto.jpg'" :preview-src-list="[scope.row.photoJpg]" fit="cover" />
  52 + </template>
  53 + </el-table-column>
  54 + <el-table-column prop="communityName" :label="$t('adminCarInout.table.communityName')" align="center" />
  55 + <el-table-column prop="ciId" :label="$t('adminCarInout.table.ciId')" align="center" />
  56 + <el-table-column :label="$t('adminCarInout.table.state')" align="center">
  57 + <template slot-scope="scope">
  58 + <div>{{ scope.row.carInout === '3306' ? $t('adminCarInout.state.in') : $t('adminCarInout.state.out') }}({{
  59 + scope.row.stateName }})</div>
  60 + <div>{{ scope.row.machineName }}</div>
  61 + </template>
  62 + </el-table-column>
  63 + <el-table-column prop="carNum" :label="$t('adminCarInout.table.carNum')" align="center" />
  64 + <el-table-column prop="paNum" :label="$t('adminCarInout.table.paNum')" align="center" />
  65 + <el-table-column prop="feeName" :label="$t('adminCarInout.table.feeName')" align="center">
  66 + <template slot-scope="scope">
  67 + {{ scope.row.feeName }}
  68 + <i class="el-icon-info"></i>
  69 + </template>
  70 + </el-table-column>
  71 + <el-table-column prop="carTypeName" :label="$t('adminCarInout.table.carTypeName')" align="center" />
  72 + <el-table-column prop="inTime" :label="$t('adminCarInout.table.inTime')" align="center" />
  73 + <el-table-column :label="$t('adminCarInout.table.outTime')" align="center">
  74 + <template slot-scope="scope">
  75 + {{ scope.row.carInout !== '3307' ? '-' : scope.row.openTime }}
  76 + </template>
  77 + </el-table-column>
  78 + <el-table-column :label="$t('adminCarInout.table.parkingTime')" align="center">
  79 + <template slot-scope="scope">
  80 + {{ scope.row.hours }}{{ $t('adminCarInout.time.hour') }}{{ scope.row.min }}{{ $t('adminCarInout.time.min')
  81 + }}
  82 + </template>
  83 + </el-table-column>
  84 + <el-table-column :label="$t('adminCarInout.table.charge')" align="center">
  85 + <template slot-scope="scope">
  86 + <span v-if="scope.row.carType === '1001'">-</span>
  87 + <span v-else>
  88 + {{ scope.row.payCharge }}
  89 + <span v-if="['100300', '100400', '100600'].includes(scope.row.inState)">
  90 + (<a href="javascript:void(0)" @click="handleCarOut(scope.row)">{{ $t('adminCarInout.action.out')
  91 + }}</a>)
  92 + </span>
  93 + </span>
  94 + </template>
  95 + </el-table-column>
  96 + <el-table-column prop="remark" :label="$t('adminCarInout.table.remark')" align="center" />
  97 + </el-table>
  98 + <el-pagination :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  99 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  100 + @current-change="handleCurrentChange" />
  101 + </el-card>
  102 + </el-col>
  103 + </el-row>
  104 + </div>
  105 +</template>
  106 +
  107 +<script>
  108 +import { listAdminCarInoutDetail } from '@/api/iot/adminCarInoutApi'
  109 +import SelectAdminCommunity from '@/components/community/selectAdminCommunity'
  110 +
  111 +export default {
  112 + name: 'AdminCarInoutList',
  113 + components: {
  114 + SelectAdminCommunity
  115 + },
  116 + data() {
  117 + return {
  118 + loading: false,
  119 + searchForm: {
  120 + communityId: '',
  121 + carNum: '',
  122 + state: '',
  123 + startTime: '',
  124 + endTime: '',
  125 + carType: '',
  126 + paId: '',
  127 + boxId: ''
  128 + },
  129 + tableData: [],
  130 + pagination: {
  131 + current: 1,
  132 + size: 10,
  133 + total: 0
  134 + },
  135 + stateOptions: [
  136 + { value: '', label: this.$t('adminCarInout.state.select') },
  137 + { value: '100300', label: this.$t('adminCarInout.state.inStatus') },
  138 + { value: '100400', label: this.$t('adminCarInout.state.paid') },
  139 + { value: '100500', label: this.$t('adminCarInout.state.outStatus') },
  140 + { value: '100600', label: this.$t('adminCarInout.state.repay') }
  141 + ],
  142 + carTypeOptions: [
  143 + { value: '', label: this.$t('adminCarInout.carType.select') },
  144 + { value: 'T', label: this.$t('adminCarInout.carType.temp') },
  145 + { value: 'S', label: this.$t('adminCarInout.carType.sale') },
  146 + { value: 'H', label: this.$t('adminCarInout.carType.monthly') },
  147 + { value: 'W', label: this.$t('adminCarInout.carType.white') },
  148 + { value: 'B', label: this.$t('adminCarInout.carType.black') },
  149 + { value: 'I', label: this.$t('adminCarInout.carType.internal') },
  150 + { value: 'NM', label: this.$t('adminCarInout.carType.free') }
  151 + ]
  152 + }
  153 + },
  154 + created() {
  155 + this.getList()
  156 + },
  157 + methods: {
  158 + async getList() {
  159 + try {
  160 + this.loading = true
  161 + const params = {
  162 + page: this.pagination.current,
  163 + row: this.pagination.size,
  164 + ...this.searchForm
  165 + }
  166 + const { data, records } = await listAdminCarInoutDetail(params)
  167 + this.tableData = data
  168 + this.pagination.total = records
  169 + } catch (error) {
  170 + this.$message.error(this.$t('adminCarInout.fetchError'))
  171 + } finally {
  172 + this.loading = false
  173 + }
  174 + },
  175 + handleCommunityChange(community) {
  176 + this.searchForm.communityId = community.communityId
  177 + this.handleSearch()
  178 + },
  179 + handleSearch() {
  180 + this.pagination.current = 1
  181 + this.getList()
  182 + },
  183 + handleSizeChange(val) {
  184 + this.pagination.size = val
  185 + this.getList()
  186 + },
  187 + handleCurrentChange(val) {
  188 + this.pagination.current = val
  189 + this.getList()
  190 + },
  191 + handleCarOut(row) {
  192 + // TODO: Implement car out logic
  193 + console.log('Car out:', row)
  194 + }
  195 + }
  196 +}
  197 +</script>
  198 +
  199 +<style lang="scss" scoped>
  200 +.admin-car-inout-container {
  201 + padding: 20px;
  202 +
  203 + .box-card {
  204 + margin-bottom: 20px;
  205 + }
  206 +
  207 + .text-right {
  208 + text-align: right;
  209 + }
  210 +}
  211 +</style>
0 \ No newline at end of file 212 \ No newline at end of file
src/views/iot/adminChargeOrderLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + adminChargeOrder: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + orderId: 'Order ID',
  7 + orderIdPlaceholder: 'Please enter order ID',
  8 + personName: 'Name',
  9 + personNamePlaceholder: 'Please enter name',
  10 + personTel: 'Phone',
  11 + personTelPlaceholder: 'Please enter phone number',
  12 + machineName: 'Charger Name',
  13 + machineNamePlaceholder: 'Please enter charger name',
  14 + portName: 'Port',
  15 + portNamePlaceholder: 'Please enter port name',
  16 + state: 'Status',
  17 + statePlaceholder: 'Please select status',
  18 + startTime: 'Start Time',
  19 + startTimePlaceholder: 'Please select start time',
  20 + endTime: 'End Time',
  21 + endTimePlaceholder: 'Please select end time'
  22 + },
  23 + table: {
  24 + title: 'Charging Orders',
  25 + orderId: 'Order ID',
  26 + personName: 'Name',
  27 + personTel: 'Phone',
  28 + machineName: 'Charger',
  29 + portName: 'Port',
  30 + chargeHours: 'Charging Hours',
  31 + byQuantity: 'By Quantity',
  32 + hours: 'hours',
  33 + energy: 'Energy',
  34 + startTime: 'Start Time',
  35 + endTime: 'End Time',
  36 + acctDetailId: 'Account',
  37 + durationPrice: 'Electricity Fee',
  38 + servicePrice: 'Service Fee',
  39 + amount: 'Amount',
  40 + stateName: 'Status',
  41 + remark: 'Remark',
  42 + createTime: 'Create Time'
  43 + },
  44 + state: {
  45 + all: 'All Status',
  46 + charging: 'Charging',
  47 + completed: 'Completed',
  48 + failed: 'Failed'
  49 + },
  50 + community: {
  51 + all: 'All Communities',
  52 + fetchError: 'Failed to load communities'
  53 + },
  54 + fetchError: 'Failed to load charging orders'
  55 + }
  56 + },
  57 + zh: {
  58 + adminChargeOrder: {
  59 + search: {
  60 + title: '查询条件',
  61 + orderId: '订单编号',
  62 + orderIdPlaceholder: '请输入订单编号',
  63 + personName: '名称',
  64 + personNamePlaceholder: '请输入名称',
  65 + personTel: '手机号',
  66 + personTelPlaceholder: '请输入手机号',
  67 + machineName: '充电桩名称',
  68 + machineNamePlaceholder: '请输入充电桩名称',
  69 + portName: '插槽',
  70 + portNamePlaceholder: '请输入插槽',
  71 + state: '状态',
  72 + statePlaceholder: '请选择状态',
  73 + startTime: '开始时间',
  74 + startTimePlaceholder: '请选择开始时间',
  75 + endTime: '结束时间',
  76 + endTimePlaceholder: '请选择结束时间'
  77 + },
  78 + table: {
  79 + title: '充电订单',
  80 + orderId: '编号',
  81 + personName: '名称',
  82 + personTel: '手机号',
  83 + machineName: '充电桩',
  84 + portName: '插槽',
  85 + chargeHours: '充电小时',
  86 + byQuantity: '按量充电',
  87 + hours: '小时',
  88 + energy: '充电量',
  89 + startTime: '开始时间',
  90 + endTime: '结束时间',
  91 + acctDetailId: '扣款账户',
  92 + durationPrice: '电费',
  93 + servicePrice: '服务费',
  94 + amount: '扣款金额',
  95 + stateName: '插座状态',
  96 + remark: '说明',
  97 + createTime: '创建时间'
  98 + },
  99 + state: {
  100 + all: '全部状态',
  101 + charging: '充电中',
  102 + completed: '充电完成',
  103 + failed: '充电失败'
  104 + },
  105 + community: {
  106 + all: '全部小区',
  107 + fetchError: '获取小区列表失败'
  108 + },
  109 + fetchError: '获取充电订单失败'
  110 + }
  111 + }
  112 +}
0 \ No newline at end of file 113 \ No newline at end of file
src/views/iot/adminChargeOrderList.vue 0 → 100644
  1 +<template>
  2 + <div class="admin-charge-order-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="4">
  5 + <select-admin-community @changeCommunity="handleCommunityChange" />
  6 + </el-col>
  7 + <el-col :span="20">
  8 + <el-card class="search-card">
  9 + <div slot="header" class="clearfix flex justify-between">
  10 + <span>{{ $t('adminChargeOrder.search.title') }}</span>
  11 + </div>
  12 + <el-form :inline="true" :model="searchForm" class="search-form">
  13 + <el-form-item :label="$t('adminChargeOrder.search.orderId')">
  14 + <el-input v-model="searchForm.orderId" :placeholder="$t('adminChargeOrder.search.orderIdPlaceholder')"
  15 + clearable />
  16 + </el-form-item>
  17 + <el-form-item :label="$t('adminChargeOrder.search.personName')">
  18 + <el-input v-model="searchForm.personName" :placeholder="$t('adminChargeOrder.search.personNamePlaceholder')"
  19 + clearable />
  20 + </el-form-item>
  21 + <el-form-item :label="$t('adminChargeOrder.search.personTel')">
  22 + <el-input v-model="searchForm.personTel" :placeholder="$t('adminChargeOrder.search.personTelPlaceholder')"
  23 + clearable />
  24 + </el-form-item>
  25 + <el-form-item :label="$t('adminChargeOrder.search.machineName')">
  26 + <el-input v-model="searchForm.machineName"
  27 + :placeholder="$t('adminChargeOrder.search.machineNamePlaceholder')" clearable />
  28 + </el-form-item>
  29 + <el-form-item :label="$t('adminChargeOrder.search.portName')">
  30 + <el-input v-model="searchForm.portName" :placeholder="$t('adminChargeOrder.search.portNamePlaceholder')"
  31 + clearable />
  32 + </el-form-item>
  33 + <el-form-item>
  34 + <el-button type="primary" @click="handleSearch">{{ $t('common.search') }}</el-button>
  35 + </el-form-item>
  36 + </el-form>
  37 + <el-form :inline="true" :model="searchForm" class="search-form">
  38 + <el-form-item :label="$t('adminChargeOrder.search.state')">
  39 + <el-select v-model="searchForm.state" :placeholder="$t('adminChargeOrder.search.statePlaceholder')"
  40 + clearable>
  41 + <el-option v-for="item in stateOptions" :key="item.value" :label="item.label" :value="item.value" />
  42 + </el-select>
  43 + </el-form-item>
  44 + <el-form-item :label="$t('adminChargeOrder.search.startTime')">
  45 + <el-date-picker v-model="searchForm.queryStartTime" type="datetime"
  46 + :placeholder="$t('adminChargeOrder.search.startTimePlaceholder')" value-format="yyyy-MM-dd HH:mm:ss" />
  47 + </el-form-item>
  48 + <el-form-item :label="$t('adminChargeOrder.search.endTime')">
  49 + <el-date-picker v-model="searchForm.queryEndTime" type="datetime"
  50 + :placeholder="$t('adminChargeOrder.search.endTimePlaceholder')" value-format="yyyy-MM-dd HH:mm:ss" />
  51 + </el-form-item>
  52 + </el-form>
  53 + </el-card>
  54 +
  55 + <el-card class="table-card">
  56 + <div slot="header" class="clearfix flex justify-between">
  57 + <span>{{ $t('adminChargeOrder.table.title') }}</span>
  58 + </div>
  59 + <el-table v-loading="loading" :data="tableData" border style="width: 100%">
  60 + <el-table-column prop="orderId" :label="$t('adminChargeOrder.table.orderId')" align="center" />
  61 + <el-table-column prop="personName" :label="$t('adminChargeOrder.table.personName')" align="center" />
  62 + <el-table-column prop="personTel" :label="$t('adminChargeOrder.table.personTel')" align="center" />
  63 + <el-table-column prop="machineName" :label="$t('adminChargeOrder.table.machineName')" align="center" />
  64 + <el-table-column prop="portName" :label="$t('adminChargeOrder.table.portName')" align="center" />
  65 + <el-table-column :label="$t('adminChargeOrder.table.chargeHours')" align="center">
  66 + <template slot-scope="scope">
  67 + {{ scope.row.chargeHours === 999 ? $t('adminChargeOrder.table.byQuantity') :
  68 + `${scope.row.chargeHours}${$t('adminChargeOrder.table.hours')}` }}
  69 + </template>
  70 + </el-table-column>
  71 + <el-table-column prop="energy" :label="$t('adminChargeOrder.table.energy')" align="center" />
  72 + <el-table-column prop="startTime" :label="$t('adminChargeOrder.table.startTime')" align="center" />
  73 + <el-table-column prop="endTime" :label="$t('adminChargeOrder.table.endTime')" align="center" />
  74 + <el-table-column prop="acctDetailId" :label="$t('adminChargeOrder.table.acctDetailId')" align="center"
  75 + class-name="pointer" />
  76 + <el-table-column prop="durationPrice" :label="$t('adminChargeOrder.table.durationPrice')" align="center" />
  77 + <el-table-column prop="servicePrice" :label="$t('adminChargeOrder.table.servicePrice')" align="center" />
  78 + <el-table-column prop="amount" :label="$t('adminChargeOrder.table.amount')" align="center" />
  79 + <el-table-column prop="stateName" :label="$t('adminChargeOrder.table.stateName')" align="center" />
  80 + <el-table-column :label="$t('adminChargeOrder.table.remark')" align="center">
  81 + <template slot-scope="scope">
  82 + <div style="width: 100px;">{{ scope.row.remark || '-' }}</div>
  83 + </template>
  84 + </el-table-column>
  85 + <el-table-column prop="createTime" :label="$t('adminChargeOrder.table.createTime')" align="center" />
  86 + </el-table>
  87 + <el-pagination :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  88 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  89 + @current-change="handleCurrentChange" />
  90 + </el-card>
  91 + </el-col>
  92 + </el-row>
  93 + </div>
  94 +</template>
  95 +
  96 +<script>
  97 +import { listAdminChargeMachineOrder } from '@/api/iot/adminChargeOrderApi'
  98 +import SelectAdminCommunity from '@/components/community/selectAdminCommunity'
  99 +
  100 +export default {
  101 + name: 'AdminChargeOrderList',
  102 + components: {
  103 + SelectAdminCommunity
  104 + },
  105 + data() {
  106 + return {
  107 + loading: false,
  108 + searchForm: {
  109 + orderId: '',
  110 + personName: '',
  111 + personTel: '',
  112 + machineName: '',
  113 + portName: '',
  114 + communityId: '',
  115 + state: '',
  116 + queryStartTime: '',
  117 + queryEndTime: '',
  118 + chargeType: ''
  119 + },
  120 + tableData: [],
  121 + pagination: {
  122 + current: 1,
  123 + size: 10,
  124 + total: 0
  125 + },
  126 + stateOptions: [
  127 + { value: '', label: this.$t('adminChargeOrder.state.all') },
  128 + { value: '1001', label: this.$t('adminChargeOrder.state.charging') },
  129 + { value: '2002', label: this.$t('adminChargeOrder.state.completed') },
  130 + { value: '3003', label: this.$t('adminChargeOrder.state.failed') }
  131 + ]
  132 + }
  133 + },
  134 + created() {
  135 + this.getList()
  136 + },
  137 + methods: {
  138 + async getList() {
  139 + try {
  140 + this.loading = true
  141 + const params = {
  142 + ...this.searchForm,
  143 + page: this.pagination.current,
  144 + row: this.pagination.size
  145 + }
  146 + const { data, total } = await listAdminChargeMachineOrder(params)
  147 + this.tableData = data
  148 + this.pagination.total = total
  149 + } catch (error) {
  150 + this.$message.error(this.$t('adminChargeOrder.fetchError'))
  151 + } finally {
  152 + this.loading = false
  153 + }
  154 + },
  155 + handleSearch() {
  156 + this.pagination.current = 1
  157 + this.getList()
  158 + },
  159 + handleCommunityChange(community) {
  160 + this.searchForm.communityId = community.communityId
  161 + this.getList()
  162 + },
  163 + handleSizeChange(val) {
  164 + this.pagination.size = val
  165 + this.getList()
  166 + },
  167 + handleCurrentChange(val) {
  168 + this.pagination.current = val
  169 + this.getList()
  170 + }
  171 + }
  172 +}
  173 +</script>
  174 +
  175 +<style lang="scss" scoped>
  176 +.admin-charge-order-container {
  177 + padding: 20px;
  178 +
  179 + .search-card {
  180 + margin-bottom: 20px;
  181 +
  182 + .search-form {
  183 + margin-bottom: -18px;
  184 + }
  185 + }
  186 +
  187 + .table-card {
  188 + margin-bottom: 20px;
  189 + }
  190 +
  191 + .pointer {
  192 + cursor: pointer;
  193 + }
  194 +}
  195 +</style>
0 \ No newline at end of file 196 \ No newline at end of file
src/views/iot/adminMeterRechargeLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + adminMeterRecharge: {
  4 + search: {
  5 + title: 'Search Conditions'
  6 + },
  7 + list: {
  8 + title: 'Recharge Details'
  9 + },
  10 + allCommunities: 'All Communities',
  11 + machineName: 'Machine Name',
  12 + machineNamePlaceholder: 'Please enter machine name',
  13 + address: 'Address',
  14 + addressPlaceholder: 'Please enter address',
  15 + state: 'State',
  16 + statePlaceholder: 'Please select recharge state',
  17 + stateWaiting: 'Waiting',
  18 + stateFailed: 'Failed',
  19 + stateCompleted: 'Completed',
  20 + roomName: 'Room',
  21 + roomNamePlaceholder: 'Please enter room number (Building-Unit-Room)',
  22 + startTime: 'Start Time',
  23 + startTimePlaceholder: 'Please enter start time',
  24 + endTime: 'End Time',
  25 + endTimePlaceholder: 'Please enter end time',
  26 + table: {
  27 + communityName: 'Community Name',
  28 + roomName: 'Room',
  29 + typeName: 'Meter Type',
  30 + machineName: 'Meter Name',
  31 + address: 'Meter Number',
  32 + chargeMoney: 'Charge Amount',
  33 + chargeDegrees: 'Charge Degrees',
  34 + createTime: 'Charge Time',
  35 + state: 'Charge State',
  36 + remark: 'Remark'
  37 + },
  38 + fetchError: 'Failed to fetch recharge details'
  39 + }
  40 + },
  41 + zh: {
  42 + adminMeterRecharge: {
  43 + search: {
  44 + title: '查询条件'
  45 + },
  46 + list: {
  47 + title: '充值明细'
  48 + },
  49 + allCommunities: '全部小区',
  50 + machineName: '表名称',
  51 + machineNamePlaceholder: '请填写名称',
  52 + address: '表号',
  53 + addressPlaceholder: '请填写表号',
  54 + state: '充值状态',
  55 + statePlaceholder: '请选择充值状态',
  56 + stateWaiting: '等待',
  57 + stateFailed: '失败',
  58 + stateCompleted: '完成',
  59 + roomName: '房屋',
  60 + roomNamePlaceholder: '请填写房屋编号 楼栋-单元-房屋',
  61 + startTime: '开始时间',
  62 + startTimePlaceholder: '请输入开始时间',
  63 + endTime: '结束时间',
  64 + endTimePlaceholder: '请输入结束时间',
  65 + table: {
  66 + communityName: '小区名称',
  67 + roomName: '房屋',
  68 + typeName: '表类型',
  69 + machineName: '表名称',
  70 + address: '表号',
  71 + chargeMoney: '充值金额',
  72 + chargeDegrees: '充值度数',
  73 + createTime: '充值时间',
  74 + state: '充值状态',
  75 + remark: '说明'
  76 + },
  77 + fetchError: '获取充值明细失败'
  78 + }
  79 + }
  80 +}
0 \ No newline at end of file 81 \ No newline at end of file
src/views/iot/adminMeterRechargeList.vue 0 → 100644
  1 +<template>
  2 + <div class="admin-meter-recharge-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="4">
  5 + <select-admin-community @changeCommunity="handleCommunityChange" />
  6 + </el-col>
  7 + <el-col :span="20">
  8 + <el-card class="box-card">
  9 + <div slot="header" class="clearfix flex justify-between">
  10 + <span>{{ $t('adminMeterRecharge.search.title') }}</span>
  11 + </div>
  12 + <el-row :gutter="20">
  13 + <el-col :span="4">
  14 + <el-input v-model="searchForm.machineNameLike"
  15 + :placeholder="$t('adminMeterRecharge.machineNamePlaceholder')" clearable />
  16 + </el-col>
  17 + <el-col :span="4">
  18 + <el-input v-model="searchForm.addressLike" :placeholder="$t('adminMeterRecharge.addressPlaceholder')"
  19 + clearable />
  20 + </el-col>
  21 + <el-col :span="4">
  22 + <el-select v-model="searchForm.state" :placeholder="$t('adminMeterRecharge.statePlaceholder')" clearable>
  23 + <el-option v-for="item in stateOptions" :key="item.value" :label="item.label" :value="item.value" />
  24 + </el-select>
  25 + </el-col>
  26 + <el-col :span="4">
  27 + <el-input v-model="searchForm.roomNameLike" :placeholder="$t('adminMeterRecharge.roomNamePlaceholder')"
  28 + clearable />
  29 + </el-col>
  30 + <el-col :span="4" class="text-right">
  31 + <el-button type="primary" @click="handleSearch">
  32 + <i class="el-icon-search"></i>
  33 + {{ $t('common.search') }}
  34 + </el-button>
  35 + <el-button @click="handleReset">
  36 + {{ $t('common.reset') }}
  37 + </el-button>
  38 + </el-col>
  39 + </el-row>
  40 +
  41 + <el-row :gutter="20" style="margin-top: 15px;">
  42 + <el-col :span="4">
  43 + <el-date-picker v-model="searchForm.queryStartTime" type="datetime"
  44 + :placeholder="$t('adminMeterRecharge.startTimePlaceholder')" value-format="yyyy-MM-dd HH:mm:ss"
  45 + style="width: 100%;" />
  46 + </el-col>
  47 + <el-col :span="4">
  48 + <el-date-picker v-model="searchForm.queryEndTime" type="datetime"
  49 + :placeholder="$t('adminMeterRecharge.endTimePlaceholder')" value-format="yyyy-MM-dd HH:mm:ss"
  50 + style="width: 100%;" />
  51 + </el-col>
  52 +
  53 + </el-row>
  54 + </el-card>
  55 +
  56 + <el-card class="box-card" style="margin-top: 20px;">
  57 + <div slot="header" class="flex justify-between">
  58 + <span>{{ $t('adminMeterRecharge.list.title') }}</span>
  59 + <el-button type="primary" size="mini" @click="handleSearch">
  60 + {{ $t('common.refresh') }}
  61 + </el-button>
  62 + </div>
  63 +
  64 + <el-table v-loading="loading" :data="tableData" border style="width: 100%">
  65 + <el-table-column prop="communityName" :label="$t('adminMeterRecharge.table.communityName')" align="center" />
  66 + <el-table-column prop="roomName" :label="$t('adminMeterRecharge.table.roomName')" align="center" />
  67 + <el-table-column prop="typeName" :label="$t('adminMeterRecharge.table.typeName')" align="center" />
  68 + <el-table-column prop="machineName" :label="$t('adminMeterRecharge.table.machineName')" align="center" />
  69 + <el-table-column prop="address" :label="$t('adminMeterRecharge.table.address')" align="center" />
  70 + <el-table-column prop="chargeMoney" :label="$t('adminMeterRecharge.table.chargeMoney')" align="center" />
  71 + <el-table-column prop="chargeDegrees" :label="$t('adminMeterRecharge.table.chargeDegrees')" align="center" />
  72 + <el-table-column prop="createTime" :label="$t('adminMeterRecharge.table.createTime')" align="center" />
  73 + <el-table-column prop="state" :label="$t('adminMeterRecharge.table.state')" align="center">
  74 + <template slot-scope="scope">
  75 + <el-tag :type="getStateTagType(scope.row.state)" size="small">
  76 + {{ getStateText(scope.row.state) }}
  77 + </el-tag>
  78 + </template>
  79 + </el-table-column>
  80 + <el-table-column prop="remark" :label="$t('adminMeterRecharge.table.remark')" align="center">
  81 + <template slot-scope="scope">
  82 + {{ scope.row.remark || '-' }}
  83 + </template>
  84 + </el-table-column>
  85 + </el-table>
  86 +
  87 + <el-pagination :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  88 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  89 + @current-change="handleCurrentChange" style="margin-top: 20px;" />
  90 + </el-card>
  91 + </el-col>
  92 + </el-row>
  93 + </div>
  94 +</template>
  95 +
  96 +<script>
  97 +import SelectAdminCommunity from '@/components/community/selectAdminCommunity'
  98 +import { listAdminMeterCharge } from '@/api/iot/adminMeterRechargeApi'
  99 +
  100 +export default {
  101 + name: 'AdminMeterRechargeList',
  102 + components: {
  103 + SelectAdminCommunity
  104 + },
  105 + data() {
  106 + return {
  107 + loading: false,
  108 + searchForm: {
  109 + machineNameLike: '',
  110 + addressLike: '',
  111 + state: '',
  112 + roomNameLike: '',
  113 + communityId: '',
  114 + detailType: '1001',
  115 + queryStartTime: '',
  116 + queryEndTime: '',
  117 + page: 1,
  118 + row: 10
  119 + },
  120 + tableData: [],
  121 + pagination: {
  122 + current: 1,
  123 + size: 10,
  124 + total: 0
  125 + },
  126 + stateOptions: [
  127 + { value: '', label: this.$t('adminMeterRecharge.statePlaceholder') },
  128 + { value: 'W', label: this.$t('adminMeterRecharge.stateWaiting') },
  129 + { value: 'F', label: this.$t('adminMeterRecharge.stateFailed') },
  130 + { value: 'C', label: this.$t('adminMeterRecharge.stateCompleted') }
  131 + ]
  132 + }
  133 + },
  134 + created() {
  135 + this.getList()
  136 + },
  137 + methods: {
  138 + async getList() {
  139 + try {
  140 + this.loading = true
  141 + const params = {
  142 + ...this.searchForm,
  143 + page: this.pagination.current,
  144 + row: this.pagination.size
  145 + }
  146 +
  147 + const res = await listAdminMeterCharge(params)
  148 + this.tableData = res.data
  149 + this.pagination.total = res.total
  150 + } catch (error) {
  151 + this.$message.error(this.$t('adminMeterRecharge.fetchError'))
  152 + } finally {
  153 + this.loading = false
  154 + }
  155 + },
  156 + handleCommunityChange(community) {
  157 + this.searchForm.communityId = community.communityId
  158 + this.handleSearch()
  159 + },
  160 + handleSearch() {
  161 + this.pagination.current = 1
  162 + this.getList()
  163 + },
  164 + handleReset() {
  165 + this.searchForm = {
  166 + machineNameLike: '',
  167 + addressLike: '',
  168 + state: '',
  169 + roomNameLike: '',
  170 + communityId: this.searchForm.communityId,
  171 + detailType: '1001',
  172 + queryStartTime: '',
  173 + queryEndTime: '',
  174 + page: 1,
  175 + row: 10
  176 + }
  177 + this.handleSearch()
  178 + },
  179 + handleSizeChange(val) {
  180 + this.pagination.size = val
  181 + this.getList()
  182 + },
  183 + handleCurrentChange(val) {
  184 + this.pagination.current = val
  185 + this.getList()
  186 + },
  187 + getStateTagType(state) {
  188 + switch (state) {
  189 + case 'W': return 'warning'
  190 + case 'F': return 'danger'
  191 + case 'C': return 'success'
  192 + default: return 'info'
  193 + }
  194 + },
  195 + getStateText(state) {
  196 + switch (state) {
  197 + case 'W': return this.$t('adminMeterRecharge.stateWaiting')
  198 + case 'F': return this.$t('adminMeterRecharge.stateFailed')
  199 + case 'C': return this.$t('adminMeterRecharge.stateCompleted')
  200 + default: return '-'
  201 + }
  202 + }
  203 + }
  204 +}
  205 +</script>
  206 +
  207 +<style scoped>
  208 +.admin-meter-recharge-container {
  209 + padding: 20px;
  210 +}
  211 +
  212 +.search-form {
  213 + margin-bottom: 0;
  214 +}
  215 +</style>
0 \ No newline at end of file 216 \ No newline at end of file