a1140836302 2 anni fa
parent
commit
2f3e3c630b

+ 25 - 1
src/api/log.js

@@ -47,4 +47,28 @@ export function bmsList(data) {
     method: 'post',
     data
   })
-}
+}
+//导出数据列表
+export function exportList(data) {
+  return request({
+    url: '/export/list',
+    method: 'post',
+    data
+  })
+}
+//生成导出文件
+export function exportFile(data) {
+  return request({
+    url: '/log/export',
+    method: 'post',
+    data
+  })
+}
+//删除数据导出列表
+export function deleteExportData(data) {
+  return request({
+    url: '/export/delete/'+data,
+    method: 'post',
+    data
+  })
+}

+ 6 - 2
src/router/index.js

@@ -180,6 +180,12 @@ export const asyncRoutes = [
         component: () => import('@/views/manage-log/change-record'),
         name: 'ChangeRecord',
         meta: { title: '换电记录' }
+      },
+      {
+        path: 'data-export',
+        component: () => import('@/views/manage-log/data-export'),
+        name: 'DataExport',
+        meta: { title: '数据导出' }
       }
     ]
   },
@@ -195,8 +201,6 @@ export const asyncRoutes = [
       }
     ]
   },
-  /** when your routing map is too long, you can split it into small modules **/
-
   // 404 page must be placed at the end !!!
   { path: '*', redirect: '/404', hidden: true }
 ]

+ 0 - 6
src/store/index.js

@@ -3,14 +3,8 @@ import Vuex from 'vuex'
 import getters from './getters'
 
 Vue.use(Vuex)
-
-// https://webpack.js.org/guides/dependency-management/#requirecontext
 const modulesFiles = require.context('./modules', true, /\.js$/)
-
-// you do not need `import app from './modules/app'`
-// it will auto require all vuex module from modules file
 const modules = modulesFiles.keys().reduce((modules, modulePath) => {
-  // set './app.js' => 'app'
   const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
   const value = modulesFiles(modulePath)
   modules[moduleName] = value.default

+ 12 - 7
src/store/modules/user.js

@@ -34,15 +34,19 @@ const actions = {
     const { username, password } = userInfo
     return new Promise((resolve, reject) => {
       login({ userAccount: username.trim(), passWord: password }).then(rs => {
-        commit('SET_TOKEN', rs.data.token)
-        commit('SET_USERID', rs.data.userId)
-        if(rs.data.token && rs.data.userId){
-          localStorage.setItem('userId', rs.data.userId);
-          setToken(rs.data.token)
+        if(rs.code === 0){
+          commit('SET_TOKEN', rs.data.token)
+          if(rs.data.token && rs.data.userId){
+            localStorage.setItem('userId', rs.data.userId);
+            setToken(rs.data.token)
+          }
+          resolve()
+        }else{
+          reject(rs.msg)
         }
-        resolve()
+        
       }).catch(error => {
-        reject(error)
+        reject()
       })
     })
   },
@@ -71,6 +75,7 @@ const actions = {
         commit('SET_ROLES', roles)
         commit('SET_NAME', data.userAccount)
         commit('SET_STATE', data.state)
+        commit('SET_USERID', data.id)
         resolve(data)
       }).catch(error => {
         reject('登录失败')

+ 4 - 4
src/views/control-config/components/ControlBox.vue

@@ -6,13 +6,13 @@
             </div>
             <div class="setspeed">
                 <div class="speed">速度: {{ speed }} m/s</div>
-                <el-button type="primary" class="set" @click="handleset">设置</el-button>
+                <el-button type="primary" class="set" @click="handleset('速度')">设置</el-button>
             </div>
         </div>
         <div class="left">
             <div class="setspeed" style="margin-top: 48px">
                 <div class="speed">位置: {{ position }} m/s</div>
-                <el-button type="primary" class="position" @click="handleset">设置</el-button>
+                <el-button type="primary" class="position" @click="handleset('位置')">设置</el-button>
             </div>
         </div>
     </div>
@@ -23,8 +23,8 @@ export default {
     name: 'ControlBox',
     props: ['title', 'img', 'speed', 'position', 'unit'],
     methods: {
-        handleset() {
-            this.$emit('handleset',this.img)
+        handleset(unit) {
+            this.$emit('handleset',{title:this.title,unit:unit})
         }
     }
 };

+ 6 - 4
src/views/control-config/index.vue

@@ -37,7 +37,7 @@
     <!--设置弹窗-->
     <div class="rolemanage chargeshow">
       <el-dialog
-        title="设置旋转轴-速度"
+        :title="`设置${dialogtext.title}-${dialogtext.unit}`"
         :visible.sync="dialogConfigVisible"
         :destroy-on-close="true"
       >
@@ -77,7 +77,8 @@ export default {
         yDpmt:'— — —',
         zDpmt:'— — —',
         rDpmt:'— — —',
-      }
+      },
+      dialogtext: {}
     };
   },
   mounted() {
@@ -94,8 +95,9 @@ export default {
     this.websocketOnClose();
   },
   methods: {
-    handleset(val) {
-      console.log(val)
+    handleset(obj) {
+      console.log(obj)
+      this.dialogtext=obj
       this.dialogConfigVisible = true;
     },
     websocketOnOpen() {

+ 5 - 8
src/views/login/index.vue

@@ -118,9 +118,6 @@ export default {
       immediate: true,
     },
   },
-  created() {
-    // window.addEventListener('storage', this.afterQRScan)
-  },
   mounted() {
     if (this.loginForm.username === "") {
       this.$refs.username.focus();
@@ -158,11 +155,11 @@ export default {
               });
               this.loading = false;
             })
-            .catch(() => {
-              // this.$message({
-              //   type: 'warning',
-              //   message: '用户或密码错误!'
-              // })
+            .catch(err => {
+              this.$message({
+                type: 'error',
+                message: err
+              })
               this.loading = false;
             });
         } else {

+ 64 - 23
src/views/manage-log/battery-charger.vue

@@ -100,14 +100,34 @@
           />
         </div>
       </div>
+      <!--导出弹窗-->
+      <div class="rolemanage chargeshow">
+        <el-dialog
+          title="生成导出任务"
+          :visible.sync="dialogExportVisible"
+          :destroy-on-close="true"
+        >
+          <div class="setExport">
+            <el-form :model="ruleForm" :rules="rules" ref="ExportForm">
+              <el-form-item label="任务名称" prop="exportName">
+                <el-input v-model="ruleForm.exportName" placeholder="请输入任务名称"></el-input>
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" @click="AddExport">生成</el-button>
+              </el-form-item>
+            </el-form>
+            <div class="descript">说明:导出任务生成后,你可以在数据导出列表中进行查询和下载</div>
+          </div>
+        </el-dialog>
+      </div>
+      <!--导出弹窗结束-->
     </div>
   </template>
   
   <script>
   import './log.scss'
-  import { chargeExport, getChargeCode } from '@/api/records'
-  import { chargerModel,chargerList } from '@/api/log'
-  import serverUrl from '../../../vue.config.js'
+  import { getChargeCode } from '@/api/records'
+  import { chargerModel,chargerList,exportFile } from '@/api/log'
   export default {
     name: 'BatteryCharger',
     components: {},
@@ -131,8 +151,7 @@
         },
         total: 0, // 总条数,
         tableheight: 0, // 表格高度设置
-        dialogChargeVisible: false, // 弹窗显示
-        chargeShowList: [],// 充电机明细弹窗列表
+        dialogExportVisible: false, // 弹窗显示
         checked: false,
         indeterminate: false,
         robotValue:'',
@@ -140,6 +159,15 @@
         logheader:[],
         heightTimer:false,
         loading: false,
+        ruleForm:{
+          exportName:undefined,
+        },
+        rules:{
+          exportName: [
+              { required: true, message: '请输入任务名称', trigger: 'blur' },
+              { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
+            ],
+        }
       }
     },
     watch: {
@@ -221,7 +249,6 @@
       getchargerList(){
         this.loading=true;
         chargerList(this.queryParams).then( res =>{
-          console.log(res)
           this.datalist= res.data.list
           this.total=res.data.total
           this.$nextTick(()=>{
@@ -240,12 +267,6 @@
           })
         })
       },
-      // 获取充电机ID
-      getChargeCode() {
-        getChargeCode().then(res => {
-          this.chargerArr = res.data
-        })
-      },
       /** 分页下一页 */
       handleSizeChange(val) {
         this.queryParams.pageSize = val
@@ -288,17 +309,37 @@
       },
       // 导出结果
       chargeExport() {
-        this.$confirm('确认导出结果?', '导出结果', {
-          confirmButtonText: '确认',
-          cancelButtonText: '取消',
-          type: 'warning'
-        })
-        .then(async() => {
-            const res = await chargeExport(this.queryParams)
-            const execlUrl=serverUrl.devServer.proxy['/api'].target+'/excel/'+res.data
-            window.open(execlUrl,'_blank')
-          })
-        .catch(err => { console.error(err) })
+        this.dialogExportVisible=true
+      },
+      //生成报表
+      AddExport(){
+        this.$refs.ExportForm.validate((valid) => {
+            if (valid) {
+              let addParams={
+                exportName:this.ruleForm.exportName,
+                signals:this.robotValue,
+                deviceNo:this.queryParams.deviceNo,
+                startTime:this.queryParams.startTime,
+                endTime:this.queryParams.endTime,
+                exportLogType:2
+              }
+              exportFile(addParams).then( res =>{
+                console.log(res)
+                if(res.code === 0){
+                  this.$router.push({path:"/manage-log/data-export"})
+                }else{
+                  this.$message({
+                    message: res.msg,
+                    type: "warning",
+                    duration: 1000,
+                    offset: 20,
+                  });
+                }
+              })
+            } else {
+              return false;
+            }
+          });
       }
     }
   }

+ 65 - 29
src/views/manage-log/bms.vue

@@ -22,7 +22,7 @@
             </el-select>
           </el-form-item>
           <el-form-item label="电池编号:" style="margin-left: 50px;">
-            <el-input v-model="queryParams.batteryNum" placeholder="请输入电池编号" clearable />
+            <el-input v-model.trim="queryParams.sn" placeholder="请输入电池编号" clearable />
           </el-form-item>
           <el-form-item label="时间范围:" style="margin-left: 50px">
             <el-date-picker
@@ -90,14 +90,33 @@
           />
         </div>
       </div>
+      <!--导出弹窗-->
+      <div class="rolemanage chargeshow">
+        <el-dialog
+          title="生成导出任务"
+          :visible.sync="dialogExportVisible"
+          :destroy-on-close="true"
+        >
+          <div class="setExport">
+            <el-form :model="ruleForm" :rules="rules" ref="ExportForm">
+              <el-form-item label="任务名称" prop="exportName">
+                <el-input v-model="ruleForm.exportName" placeholder="请输入任务名称"></el-input>
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" @click="AddExport">生成</el-button>
+              </el-form-item>
+            </el-form>
+            <div class="descript">说明:导出任务生成后,你可以在数据导出列表中进行查询和下载</div>
+          </div>
+        </el-dialog>
+      </div>
+      <!--导出弹窗结束-->
     </div>
   </template>
   
   <script>
   import './log.scss'
-  import { chargeExport, getChargeCode } from '@/api/records'
-  import { BmsModel,bmsList } from '@/api/log'
-  import serverUrl from '../../../vue.config.js'
+  import { BmsModel,bmsList,exportFile } from '@/api/log'
   export default {
     name: 'Bms',
     components: {},
@@ -117,12 +136,12 @@
           endTime: undefined, // 电池编号
           signals: undefined, // 排序字段
           startTime: undefined,// 排序方式
+          sn:undefined,
           sort:1
         },
         total: 0, // 总条数,
         tableheight: 0, // 表格高度设置
-        dialogChargeVisible: false, // 弹窗显示
-        chargeShowList: [],// 充电机明细弹窗列表
+        dialogExportVisible: false, // 弹窗显示
         checked: false,
         indeterminate: false,
         robotValue:'',
@@ -130,6 +149,15 @@
         logheader:[],
         heightTimer:false,
         loading: false,
+        ruleForm:{
+          exportName:undefined,
+        },
+        rules:{
+          exportName: [
+              { required: true, message: '请输入任务名称', trigger: 'blur' },
+              { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
+            ],
+        }
       }
     },
     watch: {
@@ -146,7 +174,6 @@
       }
     },
     mounted() {
-      this.getChargeCode()
       this.onLoadHeight()
       this.changeWindow()
       this.getLogModel()
@@ -225,17 +252,6 @@
           })
         })
       },
-      // 充电明细弹窗显示
-      chargeShow(list) {
-        this.dialogChargeVisible = true
-        this.chargeShowList = list
-      },
-      // 获取充电机ID
-      getChargeCode() {
-        getChargeCode().then(res => {
-          this.chargerArr = res.data
-        })
-      },
       /** 分页下一页 */
       handleSizeChange(val) {
         this.queryParams.pageSize = val
@@ -278,17 +294,37 @@
       },
       // 导出结果
       chargeExport() {
-        this.$confirm('确认导出结果?', '导出结果', {
-          confirmButtonText: '确认',
-          cancelButtonText: '取消',
-          type: 'warning'
-        })
-        .then(async() => {
-            const res = await chargeExport(this.queryParams)
-            const execlUrl=serverUrl.devServer.proxy['/api'].target+'/excel/'+res.data
-            window.open(execlUrl,'_blank')
-          })
-        .catch(err => { console.error(err) })
+        this.dialogExportVisible=true
+      },
+      //生成报表
+      AddExport(){
+        this.$refs.ExportForm.validate((valid) => {
+            if (valid) {
+              let addParams={
+                exportName:this.ruleForm.exportName,
+                signals:this.robotValue,
+                sn:this.queryParams.sn,
+                startTime:this.queryParams.startTime,
+                endTime:this.queryParams.endTime,
+                exportLogType:3
+              }
+              exportFile(addParams).then( res =>{
+                console.log(res)
+                if(res.code === 0){
+                  this.$router.push({path:"/manage-log/data-export"})
+                }else{
+                  this.$message({
+                    message: res.msg,
+                    type: "warning",
+                    duration: 1000,
+                    offset: 20,
+                  });
+                }
+              })
+            } else {
+              return false;
+            }
+          });
       }
     }
   }

+ 104 - 81
src/views/manage-log/change-record.vue

@@ -3,15 +3,15 @@
     <div class="charge-tools">
       <el-form :inline="true" :model="queryParams">
         <el-form-item label="换电编号:" style="margin-left: 35px">
-          <el-input v-model="queryParams.swapId" placeholder="请输入换电编号" clearable />
+          <el-input v-model.trim="queryParams.swapId" placeholder="请输入换电编号" clearable />
         </el-form-item>
 
         <el-form-item label="车牌号:" style="margin-left: 50px">
-          <el-input v-model="queryParams.vehiclePlate" placeholder="请输入车牌号" clearable />
+          <el-input v-model.trim="queryParams.vehiclePlate" placeholder="请输入车牌号" clearable />
         </el-form-item>
 
         <el-form-item label="车辆识别码:" style="margin-left: 50px">
-          <el-input v-model="queryParams.PlateCode" placeholder="请输入车牌号" clearable />
+          <el-input v-model.trim="queryParams.PlateCode" placeholder="请输入车牌号" clearable />
         </el-form-item>
 
         <el-form-item label="时间范围:" style="margin-left: 50px">
@@ -45,9 +45,9 @@
           <el-table-column prop="swapDuration" label="换电时长" />
           <el-table-column label="操作" align="center" width="200">
             <template v-if="scope.row.userAccount !== 'admin'" slot-scope="scope">
-              <el-button type="primary" class="handle" size="small" @click="handleEdit(scope.row)">日志查询</el-button>
+              <el-button type="primary" class="handle" size="small" @click="handleSerch(scope.row)">日志查询</el-button>
               <el-button type="primary" class="handle" size="small"
-                @click="handleDelete(scope.$index, scope.row.id)">导出日志</el-button>
+                @click="handleExport(scope.row)">导出日志</el-button>
             </template>
           </el-table-column>
         </el-table>
@@ -61,16 +61,19 @@
 
     <!--导出弹窗-->
     <div class="rolemanage">
-      <el-dialog :title="dialogType === 'find' ? '查看数据范围' : '导出数据范围'" :visible.sync="dialogexportVisible"
+      <el-dialog :title="dialogType === 'find' ? '查看日志' : '导出日志'" :visible.sync="dialogexportVisible"
         :destroy-on-close="true" @close="dialogClose">
-        <el-form ref="ruleForm" v-loading="loading">
+        <el-form :model="ruleForm" :rules="rules" ref="ExportForm" v-loading="loading">
+          <el-form-item label="任务名称:" prop="exportName" v-if="dialogType==='export'">
+            <el-input v-model="ruleForm.exportName" placeholder="请输入任务名称"></el-input>
+          </el-form-item>
           <div class="checkFirst">
             <div>日志范围:</div>
             <template>
-              <el-form-item style="margin-left: 5px; margin-top: 20px">
-                <el-select multiple v-model="robotValue" filterable clearable placeholder="请选择" @change="changeSelect"
+              <el-form-item style="margin-left:8px; margin-top: 20px">
+                <el-select multiple v-model="robotValue" filterable clearable placeholder="全部" @change="changeSelect"
                   collapse-tags @remove-tag="removeTag">
-                  <el-option label="全选" value="全选" @click.native="selectAll"></el-option>
+                  <el-option label="全部" value="全部" @click.native="selectAll"></el-option>
                   <el-option v-for="item in logOptions" :key="item.alarmCode" :label="item.alarmName"
                     :value="item.alarmCode" />
                 </el-select>
@@ -79,8 +82,8 @@
           </div>
         </el-form>
         <div slot="footer" class="dialog-footer">
-          <el-button class="exit" @click="dialogUserVisible = false">取 消</el-button>
-          <el-button type="primary" class="save" @click="AddUserinfo">确 定</el-button>
+          <el-button type="primary" class="save" @click="handleExportLog">{{ dialogType==='find' ? '查看': '生成' }}</el-button>
+          <el-button class="exit" @click="dialogexportVisible = false">取消</el-button>
         </div>
       </el-dialog>
     </div>
@@ -91,7 +94,7 @@
 <script>
 import "./log.scss";
 import { swapList } from "@/api/records";
-import { logModel } from "@/api/log";
+import { logModel,exportFile } from "@/api/log";
 export default {
   name: "ChangeRecord",
   components: {},
@@ -109,12 +112,20 @@ export default {
         page: 1, // 当前页
         pageSize: 10, // 每页条数
         vehiclePlate: undefined, // 车牌号
+        vehicleVin:undefined,//车辆识别码
         swapId: undefined, // 换电编号
         swapBeginTime: undefined,
         swapEndTime: undefined,
         orderByField: undefined, // 排序字段
         orderByWays: 'desc'// 排序方式
       },
+      //日志查询参数
+      serchParams:{
+        exchangeNo:undefined,//换电编号
+        startTime:undefined,//开始时间
+        endTime:undefined,//结束时间
+        signals:[],//日志范围
+      },
       total: 0, // 总条数,
       tableheight: 0, // 表格高度设置
       dialogexportVisible: false, // 弹窗显示
@@ -124,7 +135,16 @@ export default {
       logOptions: [],
       logheader: [],
       loading: false,
-      heightTimer: false
+      heightTimer: false,
+      ruleForm:{
+        exportName:undefined,
+      },
+      rules:{
+        exportName: [
+            { required: true, message: '请输入任务名称', trigger: 'blur' },
+            { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
+          ],
+      }
     };
   },
   watch: {
@@ -165,82 +185,31 @@ export default {
       if (this.robotValue.length < this.logOptions.length) {
         this.robotValue = [];
         this.logOptions.map((item) => {
-          this.robotValue.push(item.value);
+          this.robotValue.push(item.alarmCode);
         });
-        this.robotValue.unshift("全选");
       } else {
         this.robotValue = [];
       }
-      this.$emit("SelectedData", this.robotValue);
     },
     changeSelect(val) {
-      if (!val.includes("全选") && val.length === this.logOptions.length) {
-        this.robotValue.unshift("全选");
-      } else if (
-        val.includes("全选") &&
-        val.length - 1 < this.logOptions.length
-      ) {
+      if (!val.includes("全部") && val.length === this.logOptions.length) {
+        this.robotValue.unshift("全部");
+      } else if (val.includes("全部") && val.length - 1 < this.logOptions.length) {
         this.robotValue = this.robotValue.filter((item) => {
-          return item !== "全";
+          return item !== "全部";
         });
       }
-      this.$emit("SelectedData", this.robotValue);
     },
     removeTag(val) {
-      if (val === "全") {
+      if (val === "全") {
         this.robotValue = [];
       }
-      this.$emit("SelectedData", this.robotValue);
-    },
-    AddUserinfo() {
-      this.$refs.ruleForm.validate((valid) => {
-        if (valid) {
-          // 添加用户
-          if (this.dialogType === "new") {
-            addUserinfo(this.formData).then((res) => {
-              if (res.code === 0) {
-                this.loading = false;
-                this.dialogUserVisible = false;
-                this.$message({
-                  type: "success",
-                  message: "操作成功!",
-                });
-                this.getUserlist();
-              } else {
-                this.loading = false;
-                return this.$message.error(res.msg);
-              }
-            });
-          }
-          // 修改用户
-          else {
-            const updateFrom = this.formData;
-            delete updateFrom.pwd;
-            console.log(updateFrom);
-            updateUser(updateFrom).then((res) => {
-              if (res.code === 0) {
-                this.loading = false;
-                this.dialogUserVisible = false;
-                this.$message({
-                  type: "success",
-                  message: "操作成功!",
-                });
-                this.getUserlist();
-              } else {
-                this.loading = false;
-                return this.$message.error(res.msg);
-              }
-            });
-          }
-        }
-      });
     },
     // 清空表单数据
     dialogClose() { },
     //获取换电记录列表
     getswapList() {
       swapList(this.queryParams).then((res) => {
-        console.log(res);
         this.datalist = res.data.records;
         this.total = res.data.total;
       });
@@ -250,14 +219,8 @@ export default {
       logModel().then((res) => {
         this.logOptions = res.data;
         this.logheader = res.data;
-        console.log(this.logOptions);
       });
     },
-    // 充电明细弹窗显示
-    chargeShow(list) {
-      this.dialogChargeVisible = true;
-      this.chargeShowList = list;
-    },
     /** 分页下一页 */
     handleSizeChange(val) {
       this.queryParams.pageSize = val;
@@ -271,10 +234,10 @@ export default {
     // 搜索
     handleQuery() {
       if (this.dateTime) {
-        this.queryParams.startTime = this.$moment(this.dateTime[0]).format(
+        this.queryParams.swapBeginTime = this.$moment(this.dateTime[0]).format(
           "YYYY-MM-DD HH:mm:ss"
         );
-        this.queryParams.endTime = this.$moment(this.dateTime[1]).format(
+        this.queryParams.swapEndTime = this.$moment(this.dateTime[1]).format(
           "YYYY-MM-DD HH:mm:ss"
         );
       }
@@ -282,10 +245,70 @@ export default {
     },
     // 搜索重置
     resetForm() {
-      this.queryParams.startTime = undefined;
-      this.queryParams.endTime = undefined;
+      this.queryParams.swapBeginTime = undefined;
+      this.queryParams.swapEndTime = undefined;
       this.getswapList();
     },
+    //日志查询
+    handleSerch(val){
+      this.dialogexportVisible=true
+      this.dialogType='find'
+      this.serchParams.exchangeNo=val.swapId
+      this.serchParams.startTime=val.swapBeginTime
+      this.serchParams.endTime=val.swapEndTime
+    },
+    //导出日志
+    handleExport(val){
+      this.dialogexportVisible=true
+      this.dialogType='export'
+      this.serchParams.startTime=val.swapBeginTime
+      this.serchParams.endTime=val.swapEndTime
+      this.serchParams.exchangeNo=val.swapId
+    },
+    //查询和生成日志文件
+    handleExportLog(){
+      if(this.dialogType ==='find'){
+        this.serchParams.signals=this.robotValue
+        this.$router.push({name:"Robot",params:this.serchParams})
+      }else{
+        this.$refs.ExportForm.validate((valid) => {
+          if (valid) {
+            let addParams={
+              exportName:this.ruleForm.exportName,
+              signals:this.robotValue,
+              exchangeNo:this.serchParams.exchangeNo,
+              startTime:this.serchParams.startTime,
+              endTime:this.serchParams.endTime,
+              exportLogType:1
+            }
+            exportFile(addParams).then( res =>{
+              if(res.code === 0){
+                this.$router.push({path:"/manage-log/data-export"})
+              }else{
+                this.$message({
+                  message: res.msg,
+                  type: "warning",
+                  duration: 1000,
+                  offset: 20,
+                });
+              }
+            })
+          } else {
+            return false;
+          }
+        });
+      }
+    }
   },
 };
 </script>
+<style lang="scss" scoped>
+  .el-form{
+    .is-required{
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        padding-right: 25px;
+      }
+  }
+</style>

+ 236 - 0
src/views/manage-log/data-export.vue

@@ -0,0 +1,236 @@
+<template>
+    <div class="charge-box">
+        <div class="charge-tools">
+            <el-form :inline="true" :model="queryParams">
+                <el-form-item label="数据来源:" style="margin-left: 35px">
+                    <el-select v-model="queryParams.exportLogType" clearable placeholder="请选择">
+                        <el-option v-for="item in LogTypeArr" :key="item.id" :label="item.value" :value="item.id" />
+                    </el-select>
+                </el-form-item>
+
+                <el-form-item label="任务名称:" style="margin-left: 50px">
+                    <el-input v-model.trim="queryParams.exportName" placeholder="请输入任务名称" clearable />
+                </el-form-item>
+
+                <el-form-item label="时间范围:" style="margin-left: 50px">
+                    <el-date-picker v-model="dateTime" class="times" type="datetimerange" range-separator="至"
+                        start-placeholder="开始时间" end-placeholder="结束时间" format="yyyy-MM-dd HH:mm:ss" />
+                </el-form-item>
+
+                <el-form-item>
+                    <el-button type="primary" class="serch actve" @click="handleQuery">查询</el-button>
+                    <el-button type="primary" class="serch" @click="resetForm">重置</el-button>
+                </el-form-item>
+            </el-form>
+        </div>
+
+        <div class="charge-table">
+            <div class="charge-table-bottom">
+                <el-table :data="datalist" :header-cell-style="{
+                    background: '#1d283e',
+                    borderColor: '#2f3c86',
+                    height: '36px',
+                    lineHeight: '36px',
+                    color: 'white',
+                    fontSize: '15px',
+                }" stripe fit :height="tableheight" style="width: 100%">
+                    <el-table-column prop="exportName" label="导出任务名称" />
+                    <el-table-column label="日志类型">
+                        <template slot-scope="scope">
+                            <span v-if="scope.row.exportLogType === 1">机器人</span>
+                            <span v-else-if="scope.row.exportLogType === 2">充电机</span>
+                            <span v-else-if="scope.row.exportLogType === 3">BMS</span>
+                        </template>
+                    </el-table-column>
+                    <el-table-column prop="exporterName" label="创建人" />
+                    <el-table-column label="状态" width="400">
+                        <template slot-scope="scope">
+                            <span v-if="scope.row.exportStatus !== 2">{{ scope.row.exportStatus === 0 ? '完成' : '失败' }}</span>
+                            <span v-else><el-progress :percentage="scope.row.exportProgress"></el-progress></span>
+                        </template>
+                    </el-table-column>
+                    <el-table-column prop="createTime" label="创建时间" />
+                    <el-table-column label="操作" align="center" width="200">
+                        <template slot-scope="scope">
+                            <span v-if="scope.row.exportStatus === 0">
+                                <el-button type="primary" class="handle" size="small"
+                                @click="handleDownFile(scope.row.exportFilePath)">下载</el-button>
+                            </span>
+                            <span v-if="scope.row.exportStatus !== 2">
+                                <el-button type="primary" class="handle" size="small"
+                                @click="handleDelete(scope.row.id)">删除</el-button>
+                            </span>
+                            
+                            <span v-else>— —</span>
+                        </template>
+                    </el-table-column>
+                </el-table>
+            </div>
+            <div class="pageblock">
+                <el-pagination :current-page="queryParams.page" :page-sizes="[10, 20, 30, 40]"
+                    :page-size="queryParams.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"
+                    @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import "./log.scss";
+import { exportList,deleteExportData } from "@/api/log";
+export default {
+    name: "DataExport",
+    components: {},
+    data() {
+        return {
+            // 查询时间数组
+            dateTime: "",
+            // 导出类型
+            LogTypeArr: [
+                {
+                    id:1,
+                    value:'机器人',
+                },
+                {
+                    id:2,
+                    value:'充电机',
+                },
+                {
+                    id:3,
+                    value:'BMS',
+                }
+            ],//日志类型
+            // 数据列表
+            datalist: [],
+            exportLogType:undefined,
+            exporterId:0, //导出人id
+            // 查询参数
+            queryParams: {
+                page: 1, // 当前页
+                pageSize: 10, // 每页条数
+                exportName: undefined, // 导出任务名称
+                exporterId: undefined, // 导出人id
+                startTime: undefined,
+                endTime: undefined,
+                orderByField: 'createTime', // 排序字段
+                orderByWays: 'desc',// 排序方式
+                exporterId:this.$store.getters.userId
+            },
+            total: 0, // 总条数,
+            tableheight: 0, // 表格高度设置
+            loading: false,
+            heightTimer: false,
+            exportTimer:null,//定时器
+        };
+    },
+    watch: {
+        tableheight(val) {
+            // 为了避免频繁触发resize函数导致页面卡顿,使用定时器
+            if (!this.heightTimer) {
+                // 一旦监听到的screenWidth值改变,就将其重新赋给data里的screenWidth
+                this.screenHeight = val;
+                this.heightTimer = true;
+                setTimeout(function () {
+                    this.heightTimer = false;
+                }, 400);
+            }
+        },
+    },
+    destroyed(){
+        this.clearListTimer()
+    },
+    mounted() {
+        this.onLoadHeight()
+        this.changeWindow()
+        //清除定时器
+        this.clearListTimer()
+        //开启定时任务
+        this.setListTimer()
+    },
+    methods: {
+        //定时请求导出列表
+        setListTimer(){
+            this.getExportList()
+            this.exportTimer=setInterval(() => {
+                this.getExportList()
+            }, 1000);
+        },
+        //清除定时器
+        clearListTimer(){
+            if(this.exportTimer){
+                clearInterval(this.exportTimer)
+            }
+        },
+        /* 设置初始视窗高度*/
+        onLoadHeight() {
+            this.$nextTick(() => {
+                this.tableheight = document.body.clientHeight - 400;
+            });
+        },
+        /* 设置窗口变化高度*/
+        changeWindow() {
+            window.onresize = () => {
+                return (() => {
+                    this.tableheight = document.body.clientHeight - 400;
+                })();
+            };
+        },
+        // 清空表单数据
+        dialogClose() { },
+        //获取换电记录列表
+        getExportList() {
+            exportList(this.queryParams).then( res=> {
+                this.datalist = res.data.list;
+                this.total = res.data.total;
+            });
+        },
+        /** 分页下一页 */
+        handleSizeChange(val) {
+            this.queryParams.pageSize = val;
+            this.getExportList();
+        },
+        /** 分页选择页数 */
+        handleCurrentChange(val) {
+            this.queryParams.page = val;
+            this.getExportList();
+        },
+        // 搜索
+        handleQuery() {
+            if (this.dateTime) {
+                this.queryParams.startTime = this.$moment(this.dateTime[0]).format(
+                    "YYYY-MM-DD HH:mm:ss"
+                );
+                this.queryParams.endTime = this.$moment(this.dateTime[1]).format(
+                    "YYYY-MM-DD HH:mm:ss"
+                );
+            }
+            this.getExportList();
+        },
+        // 搜索重置
+        resetForm() {
+            window.location.reload();
+        },
+        //删除导出任务列表
+        handleDelete(id){
+            this.$confirm('删除数据将丢失,请确认是否删除', '确认删除', {
+                confirmButtonText: '确认',
+                cancelButtonText: '取消',
+                type: 'warning'
+            })
+            .then(async() => {
+            await deleteExportData(id)
+            this.$message({
+                type: 'success',
+                message: '删除成功!'
+            })
+            this.getExportList()
+            })
+            .catch(err => { console.error(err) })
+        },
+        //下载文件
+        handleDownFile(url){
+            window.location.href=url
+        }
+    },
+};
+</script>

+ 48 - 0
src/views/manage-log/log.scss

@@ -81,6 +81,15 @@
             width: 100%;
             min-height: 100%;
             background-color: #111827;
+            .el-progress-bar{
+                width: 50%;
+                .el-progress-bar__inner{
+                    background-color:#91fdb9
+                }
+            }
+            .el-progress__text{
+                color: white;
+            }
         }
 
         .pageblock {
@@ -100,4 +109,43 @@
     font-weight: 600;
     margin: 0 auto;
     justify-content: center;
+}
+.setExport {
+    margin: 35px auto;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding-bottom: 45px;
+    flex-direction: column;
+    span {
+      color: #fff;
+      font-size: 15px;
+      text-align: right;
+    }
+  
+    .el-input {
+      width: 240px;
+      margin-right: 15px;
+    }
+    .el-form{
+        display: flex;
+        .el-button{
+            background-color: #91fdb9;
+            border-color: #91fdb9;
+            font-weight: 600;
+            letter-spacing: 1px;
+            span{
+                color: #0b111d;
+            }
+        }
+        .el-form-item{
+            display: flex;
+            margin-left:0;
+        }
+    }
+    .descript{
+        color: #D9001B;
+        text-indent: 1em;
+        font-weight: normal;
+    }
 }

+ 93 - 26
src/views/manage-log/robot.vue

@@ -88,14 +88,33 @@
         />
       </div>
     </div>
+    <!--导出弹窗-->
+    <div class="rolemanage chargeshow">
+      <el-dialog
+        title="生成导出任务"
+        :visible.sync="dialogExportVisible"
+        :destroy-on-close="true"
+      >
+        <div class="setExport">
+          <el-form :model="ruleForm" :rules="rules" ref="ExportForm">
+            <el-form-item label="任务名称" prop="exportName">
+              <el-input v-model="ruleForm.exportName" placeholder="请输入任务名称"></el-input>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="AddExport">生成</el-button>
+            </el-form-item>
+          </el-form>
+          <div class="descript">说明:导出任务生成后,你可以在数据导出列表中进行查询和下载</div>
+        </div>
+      </el-dialog>
+    </div>
+    <!--导出弹窗结束-->
   </div>
 </template>
 
 <script>
 import './log.scss'
-import { chargeExport } from '@/api/records'
-import { logModel,robotList } from '@/api/log'
-import serverUrl from '../../../vue.config.js'
+import { logModel,robotList,exportFile } from '@/api/log'
 export default {
   name: 'Robot',
   components: {},
@@ -111,9 +130,10 @@ export default {
         page: 1, // 当前页
         pageSize: 10, // 每页条数
         deviceNo: undefined, 
-        endTime: undefined, // 电池编号
-        signals: undefined, // 排序字段
-        startTime: undefined,// 排序方式
+        endTime: undefined, 
+        signals: undefined, 
+        startTime: undefined,
+        exchangeNo:undefined,
         sort:1
       },
       total: 0, // 总条数,
@@ -125,6 +145,16 @@ export default {
       logheader:[],
       heightTimer:false,
       loading: false,
+      dialogExportVisible:false,
+      ruleForm:{
+        exportName:undefined,
+      },
+      rules:{
+        exportName: [
+            { required: true, message: '请输入任务名称', trigger: 'blur' },
+            { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
+          ],
+      }
     }
   },
   watch: {
@@ -145,6 +175,7 @@ export default {
     this.getLogModel()
     this.onLoadHeight()
     this.changeWindow()
+    this.getRecordParams()
   },
   methods: {
     labelHead(h,{column,index}){
@@ -198,7 +229,6 @@ export default {
     getrobotList(){
       this.loading=true;
       robotList(this.queryParams).then( res =>{
-        // console.log(res)
         this.datalist= res.data.list
         this.total=res.data.total
         this.$nextTick(()=>{
@@ -212,6 +242,14 @@ export default {
       logModel().then( res =>{
         this.logOptions= res.data
         this.logheader=res.data
+        //接收换电记录传过来得参数
+        if(this.$route.params.signals && this.$route.params.signals.length > 0){
+          let differenceSet = Array.from(new Set([...this.logOptions].filter(x => this.$route.params.signals.includes(x.alarmCode))));
+          this.logheader=differenceSet
+          this.robotValue=this.$route.params.signals
+          this.queryParams.signals=this.$route.params.signals
+          this.dateTime=[this.$route.params.startTime,this.$route.params.endTime]
+        }
         this.$nextTick(()=>{
           this.$refs.tblist.doLayout()
         })
@@ -236,9 +274,10 @@ export default {
         }
         if(this.robotValue.length > 0){
           this.queryParams.signals=this.robotValue
-          let differenceABSet = Array.from(new Set([...this.logOptions].filter(x => this.robotValue.includes(x.alarmCode))));
-          this.logheader=differenceABSet
+          let differenceSet = Array.from(new Set([...this.logOptions].filter(x => this.robotValue.includes(x.alarmCode))));
+          this.logheader=differenceSet
         }
+        delete this.queryParams.exchangeNo
         this.getrobotList()
       }else{
         this.$message({
@@ -248,28 +287,56 @@ export default {
           offset: 20,
         });
       }
+      this.$nextTick(()=>{
+        this.$refs.tblist.doLayout()
+      })
     },
     // 搜索重置
     resetForm() {
-      this.queryParams.startTime = undefined
-      this.queryParams.endTime = undefined
-      this.queryParams.signals = undefined
-      this.getrobotList()
+      window.location.reload();
     },
-    // 导出结果
+    // 导出弹窗显示
     chargeExport() {
-      this.$confirm('确认导出结果?', '导出结果', {
-        confirmButtonText: '确认',
-        cancelButtonText: '取消',
-        type: 'warning'
-      })
-      .then(async() => {
-          const res = await chargeExport(this.queryParams)
-          const execlUrl=serverUrl.devServer.proxy['/api'].target+'/excel/'+res.data
-          window.open(execlUrl,'_blank')
-        })
-      .catch(err => { console.error(err) })
+      this.dialogExportVisible=true
+    },
+    //生成报表
+    AddExport(){
+      this.$refs.ExportForm.validate((valid) => {
+          if (valid) {
+            let addParams={
+              exportName:this.ruleForm.exportName,
+              signals:this.robotValue,
+              startTime:this.queryParams.startTime,
+              endTime:this.queryParams.endTime,
+              exportLogType:1
+            }
+            exportFile(addParams).then( res =>{
+              if(res.code === 0){
+                this.$router.push({path:"/manage-log/data-export"})
+              }else{
+                this.$message({
+                  message: res.msg,
+                  type: "warning",
+                  duration: 1000,
+                  offset: 20,
+                });
+              }
+            })
+          } else {
+            return false;
+          }
+        });
+    },
+    //获取换电记录日志查询参数
+    getRecordParams(){
+      if(JSON.stringify(this.$route.params)=='{}'){
+      }else{
+        this.queryParams.exchangeNo=this.$route.params.exchangeNo
+        this.queryParams.startTime=this.$route.params.startTime
+        this.queryParams.endTime=this.$route.params.endTime
+        this.getrobotList()
+      }
     }
   }
 }
-</script>
+</script>

+ 2 - 2
vue.config.js

@@ -12,7 +12,7 @@ module.exports = {
   lintOnSave: false,
   productionSourceMap: false,
   devServer: {
-    host: '192.168.0.85',
+    host: '192.168.0.86',
     port: 808,
     open: true,
     overlay: {
@@ -21,7 +21,7 @@ module.exports = {
     },
     proxy: {
       '/api': {
-        target: `http://192.168.0.125:8080`,
+        target: `https://5jp3670392.yicp.fun`,
         // target: `http://172.16.12.146:8080`,
         ws: true,
         changeOrigin: true,