hzj18279462576@163.com пре 8 месеци
комит
09c3c95a4b
93 измењених фајлова са 24951 додато и 0 уклоњено
  1. 24 0
      .gitignore
  2. 3 0
      .vscode/extensions.json
  3. 36 0
      README.en.md
  4. 7 0
      README.md
  5. 17 0
      index.html
  6. 1462 0
      package-lock.json
  7. 34 0
      package.json
  8. 33 0
      src/App.vue
  9. 87 0
      src/api/admin.js
  10. 14 0
      src/api/home.js
  11. 110 0
      src/api/vidicons.js
  12. BIN
      src/assets/account.png
  13. BIN
      src/assets/accountA.png
  14. BIN
      src/assets/back.png
  15. BIN
      src/assets/bg-video.png
  16. BIN
      src/assets/blacklist.png
  17. BIN
      src/assets/blacklistA.png
  18. BIN
      src/assets/busquery.png
  19. BIN
      src/assets/busqueryA.png
  20. BIN
      src/assets/car.png
  21. BIN
      src/assets/carA.png
  22. BIN
      src/assets/carnumber.png
  23. BIN
      src/assets/carnumberA.png
  24. BIN
      src/assets/classes.png
  25. BIN
      src/assets/classesA.png
  26. BIN
      src/assets/driverPath.png
  27. BIN
      src/assets/driverPathA.png
  28. BIN
      src/assets/import.png
  29. BIN
      src/assets/log.png
  30. BIN
      src/assets/logA.png
  31. BIN
      src/assets/login.png
  32. BIN
      src/assets/login2.png
  33. BIN
      src/assets/login3.png
  34. BIN
      src/assets/logo.png
  35. BIN
      src/assets/logoBg.jpg
  36. BIN
      src/assets/nanchang.png
  37. BIN
      src/assets/news.png
  38. BIN
      src/assets/news1.png
  39. BIN
      src/assets/nodata.png
  40. BIN
      src/assets/path.png
  41. BIN
      src/assets/pathA.png
  42. BIN
      src/assets/read.png
  43. BIN
      src/assets/report.png
  44. BIN
      src/assets/reportA.png
  45. BIN
      src/assets/staff.png
  46. BIN
      src/assets/staffA.png
  47. BIN
      src/assets/statement.png
  48. BIN
      src/assets/statementA.png
  49. BIN
      src/assets/system.png
  50. BIN
      src/assets/system111.png
  51. BIN
      src/assets/systemA.png
  52. 1 0
      src/assets/vite.svg
  53. BIN
      src/assets/waiting.png
  54. BIN
      src/assets/waitingA.png
  55. 42 0
      src/components/HelloWorld.vue
  56. 202 0
      src/layout/index.vue
  57. 481 0
      src/layout/sidebar/Navbar.vue
  58. 324 0
      src/layout/sidebar/SidevarItem copy.vue
  59. 420 0
      src/layout/sidebar/SidevarItem.vue
  60. 28 0
      src/main.js
  61. 147 0
      src/router/index.js
  62. 5 0
      src/store/getters.js
  63. 22 0
      src/store/index.js
  64. 150 0
      src/store/modules/user.js
  65. 89 0
      src/style.css
  66. 1 0
      src/style/mixin.scss
  67. 46 0
      src/utils/request.js
  68. 22 0
      src/utils/rsa.js
  69. 763 0
      src/views/account/account.vue
  70. 1759 0
      src/views/blacklist/blacklist.vue
  71. 742 0
      src/views/bus/bus.vue
  72. 822 0
      src/views/busnumber/busnumber.vue
  73. 947 0
      src/views/buspath/buspath.vue
  74. 2262 0
      src/views/busquery/busquery.vue
  75. 1842 0
      src/views/classes/classes.vue
  76. 716 0
      src/views/driver/audit.vue
  77. 1099 0
      src/views/driver/coupon.vue
  78. 590 0
      src/views/driver/couponRecord.vue
  79. 701 0
      src/views/driver/deposit.vue
  80. 704 0
      src/views/driver/management.vue
  81. 641 0
      src/views/driver/order.vue
  82. 835 0
      src/views/driver/path.vue
  83. 439 0
      src/views/driver/rule copy.vue
  84. 525 0
      src/views/driver/rule.vue
  85. 517 0
      src/views/log/log.vue
  86. 303 0
      src/views/login/index.vue
  87. 655 0
      src/views/news/news.vue
  88. 879 0
      src/views/report/report.vue
  89. 797 0
      src/views/staff/staff.vue
  90. 1690 0
      src/views/statement/statement.vue
  91. 801 0
      src/views/waiting/waiting.vue
  92. 22 0
      text.json
  93. 93 0
      vite.config.js

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 3 - 0
.vscode/extensions.json

@@ -0,0 +1,3 @@
+{
+  "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
+}

+ 36 - 0
README.en.md

@@ -0,0 +1,36 @@
+# 校车预约管理系统
+
+#### Description
+{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
+
+#### Software Architecture
+Software architecture description
+
+#### Installation
+
+1.  xxxx
+2.  xxxx
+3.  xxxx
+
+#### Instructions
+
+1.  xxxx
+2.  xxxx
+3.  xxxx
+
+#### Contribution
+
+1.  Fork the repository
+2.  Create Feat_xxx branch
+3.  Commit your code
+4.  Create Pull Request
+
+
+#### Gitee Feature
+
+1.  You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
+2.  Gitee blog [blog.gitee.com](https://blog.gitee.com)
+3.  Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
+4.  The most valuable open source project [GVP](https://gitee.com/gvp)
+5.  The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
+6.  The most popular members  [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+# Vue 3 + Vite
+
+This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
+
+## Recommended IDE Setup
+
+- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).

+ 17 - 0
index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="zh">
+
+<head>
+  <meta charset="UTF-8" />
+  <link rel="icon" type="image/svg+xml" href="./src/assets/vite.svg" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <title>校团约车管理系统</title>
+
+</head>
+
+<body>
+  <div id="app"></div>
+  <script type="module" src="/src/main.js"></script>
+</body>
+
+</html>

Разлика између датотеке није приказан због своје велике величине
+ 1462 - 0
package-lock.json


+ 34 - 0
package.json

@@ -0,0 +1,34 @@
+{
+  "name": "vite-project",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "@easydarwin/easyplayer": "^5.0.7",
+    "@element-plus/icons-vue": "^2.0.10",
+    "@liveqing/liveplayer-v3": "^3.7.10",
+    "axios": "^1.3.2",
+    "dayjs": "^1.11.8",
+    "element-plus": "^2.2.29",
+    "hls.js": "^1.3.4",
+    "js-md5": "^0.8.3",
+    "jsencrypt": "^3.3.1",
+    "lodash": "^4.17.21",
+    "sass": "^1.58.0",
+    "sass-loader": "^13.2.0",
+    "terser": "^5.16.5",
+    "vue": "^3.2.45",
+    "vue-router": "^4.0.10",
+    "vuex": "^4.0.2",
+    "vuex-persistedstate": "^4.1.0"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^4.0.0",
+    "vite": "^4.1.0"
+  }
+}

+ 33 - 0
src/App.vue

@@ -0,0 +1,33 @@
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+onBeforeMount(() => {
+  store.dispatch("pathSelect");
+  store.dispatch("busNum");
+  store.dispatch("newsAsync");
+  store.dispatch("sm_time");
+});
+</script>
+
+<template>
+  <router-view></router-view>
+</template>
+
+<style lang="scss">
+#app {
+  max-width: 1920px;
+  width: 1920px;
+  min-height: 100vh;
+  max-height: 1080px;
+  margin: 0;
+  padding: 0;
+  text-align: unset;
+  // width: 100%;
+  // height: 100%;
+  // margin: 0;
+  // padding: 0;
+}
+</style>

+ 87 - 0
src/api/admin.js

@@ -0,0 +1,87 @@
+import request from "@/utils/request";
+const requests = '/api'// 线上
+// const requests = '/video/transcoding/transcoding'//线下
+export default {
+    // 登录账号
+    // async adminLogin(data) {
+    //     let requestData = await request({
+    //         url: `${requests}/carBook/adminlogin.action`,
+    //         method: "POST",
+    //         // headers: { "Content-Type": "application/json;charset=utf-8" },
+    //         data: data,
+    //     });
+    //     return requestData;
+    // },
+
+    // 账号列表
+    // async adminList(params) {
+    //     let requestData = await request({
+    //         url: `${requests}/carBook/adminlist.action`,
+    //         method: "GET",
+    //         headers: { "Content-Type": "multipart/form-data" },
+    //         params,
+    //     });
+    //     return requestData;
+    // },
+
+    // 新增管理员
+    async adminAdd(data) {
+        let requestData = await request({
+            url: `${requests}/carBook/admininsert.action`,
+            method: "POST",
+            data,
+        });
+        return requestData;
+    },
+    // 修改管理员
+    async adminUpdate(data) {
+        let requestData = await request({
+            url: `${requests}/carBook/adminupdate.action`,
+            method: "POST",
+            data,
+        });
+        return requestData;
+    },
+    // 修改密码
+    // async updatePassword(data) {
+    //     let requestData = await request({
+    //         url: `${requests}/videoAdmin/updatePassword`,
+    //         method: "PUT",
+    //         data,
+    //     });
+    //     return requestData;
+    // },
+    // 删除管理员
+    async adminDel(data) {
+        let requestData = await request({
+            url: `${requests}/carBook/admindel.action`,
+            method: "POST",
+            data,
+        });
+        return requestData;
+    },
+
+    // 导出管理员信息
+    async download(params) {
+        let requestData = await request({
+            url: `${requests}/carBook/admintoExcel.action`,
+            method: "GET",
+            headers: { "Content-Type": "application/x-www-form-urlencoded;charset=utf-8" },
+            responseType: "blob",
+            params,
+        });
+        return requestData;
+    },
+
+    // 导入监控信息
+    // async importByExcel(data) {
+    //     let requestData = await request({
+    //         // url: "/api/video/videoAdmin/importByExcel",
+    //         url: `${requests}/camera/importByExcel`,
+    //         method: "POST",
+    //         headers: { "Content-Type": "multipart/form-data" },
+    //         data: data,
+    //     });
+    //     return requestData;
+    // },
+};

+ 14 - 0
src/api/home.js

@@ -0,0 +1,14 @@
+import request from "@/utils/request";
+// const request='/api'
+export default {
+    /*搜索*/
+
+    async getHomeList(data) {
+        let requestData = await request({
+            url: "/api",
+            method: "POST",
+            data: data,
+        });
+        return requestData;
+    }
+}

+ 110 - 0
src/api/vidicons.js

@@ -0,0 +1,110 @@
+import request from "@/utils/request";
+const requests = '/video/transcoding'// 线上
+// const requests = '/video/transcoding/transcoding'// 线下
+export default {
+    // 添加监控信息
+    async addCamera(data) {
+        let requestData = await request({
+            url: `${requests}/camera/addCamera`,
+            method: "POST",
+            headers: { "Content-Type": "application/json; charset=utf-8" },
+            data: data,
+        });
+        return requestData;
+    },
+
+    // 删除监控信息
+    async delCamera(data) {
+        let requestData = await request({
+            url: `${requests}/camera/delete`,
+            method: "DELETE",
+            data
+        });
+        return requestData;
+    },
+
+    // 修改监控信息
+    async updateCamera(data) {
+        let requestData = await request({
+            url: `${requests}/camera/updateCamera`,
+            method: "PUT",
+            headers: { "Content-Type": "application/json; charset=utf-8" },
+            data,
+        });
+        return requestData;
+    },
+
+    // 监控信息列表
+    async queryCamera(data) {
+        let requestData = await request({
+            url: `${requests}/camera/queryCamera`,
+            method: "POST",
+            headers: { "Content-Type": "application/x-www-form-urlencoded;charset=utf-8" },
+            params: data,
+        });
+        return requestData;
+    },
+    // 导出监控信息
+    async download(params) {
+        let requestData = await request({
+            url: `${requests}/camera/download`,
+            method: "GET",
+            headers: { "Content-Type": "application/x-www-form-urlencoded;charset=utf-8" },
+            responseType: "blob",
+            params,
+        });
+        return requestData;
+    },
+    // 导入监控信息
+    async importByExcel(data) {
+        let requestData = await request({
+            url: `${requests}/camera/importByExcel`,
+            method: "POST",
+            headers: { "Content-Type": "multipart/form-data" },
+            data,
+        });
+        return requestData;
+    },
+
+    // 使用Stream推拉流
+    async addStreamSource(data) {
+        let requestData = await request({
+            url: `${requests}/stream/addStreamSource`,
+            method: "POST",
+            headers: { "Content-Type": "application/json; charset=utf-8" },
+            data,
+        });
+        return requestData;
+    },
+
+    // 关闭Stream推拉流
+    async delStreamSource(data) {
+        let requestData = await request({
+            url: `${requests}/stream/delStreamSource`,
+            method: "POST",
+            headers: { "Content-Type": "application/json; charset=utf-8" },
+            data,
+        });
+        return requestData;
+    },
+    // 更新输出链接
+    async updateCameraLink(params) {
+        let requestData = await request({
+            url: `${requests}/camera/updateCameraLink`,
+            method: "GET",
+            headers: { "Content-Type": "application/x-www-form-urlencoded;charset=utf-8" },
+            params,
+        });
+        return requestData;
+    },
+    // 关闭当前播放回写剩下的播放链接、
+    async delAndUpdateLink(params) {
+        let requestData = await request({
+            url: `${requests}/stream/delAndUpdateLink`,
+            method: "GET",
+            headers: { "Content-Type": "application/x-www-form-urlencoded;charset=utf-8" },
+            params,
+        });
+        return requestData;
+    },
+};

BIN
src/assets/account.png


BIN
src/assets/accountA.png


BIN
src/assets/back.png


BIN
src/assets/bg-video.png


BIN
src/assets/blacklist.png


BIN
src/assets/blacklistA.png


BIN
src/assets/busquery.png


BIN
src/assets/busqueryA.png


BIN
src/assets/car.png


BIN
src/assets/carA.png


BIN
src/assets/carnumber.png


BIN
src/assets/carnumberA.png


BIN
src/assets/classes.png


BIN
src/assets/classesA.png


BIN
src/assets/driverPath.png


BIN
src/assets/driverPathA.png


BIN
src/assets/import.png


BIN
src/assets/log.png


BIN
src/assets/logA.png


BIN
src/assets/login.png


BIN
src/assets/login2.png


BIN
src/assets/login3.png


BIN
src/assets/logo.png


BIN
src/assets/logoBg.jpg


BIN
src/assets/nanchang.png


BIN
src/assets/news.png


BIN
src/assets/news1.png


BIN
src/assets/nodata.png


BIN
src/assets/path.png


BIN
src/assets/pathA.png


BIN
src/assets/read.png


BIN
src/assets/report.png


BIN
src/assets/reportA.png


BIN
src/assets/staff.png


BIN
src/assets/staffA.png


BIN
src/assets/statement.png


BIN
src/assets/statementA.png


BIN
src/assets/system.png


BIN
src/assets/system111.png


BIN
src/assets/systemA.png


Разлика између датотеке није приказан због своје велике величине
+ 1 - 0
src/assets/vite.svg


BIN
src/assets/waiting.png


BIN
src/assets/waitingA.png


+ 42 - 0
src/components/HelloWorld.vue

@@ -0,0 +1,42 @@
+<template>
+  <h1>{{ msg }}</h1>
+
+  <div class="card">
+    <button type="button" @click="count++">count is {{ count }}</button>
+    <p>
+      Edit
+      <code>components/HelloWorld.vue</code> to test HMR
+    </p>
+  </div>
+
+  <p>
+    Check out
+    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank">create-vue</a
+    >, the official Vue + Vite starter
+  </p>
+  <p>
+    Install
+    <a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
+    in your IDE for a better DX
+  </p>
+  <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
+  <div class="ul">
+    <div class="li">文字</div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from "vue";
+
+defineProps({
+  msg: String,
+});
+
+const count = ref(0);
+</script>
+
+<style scoped lang="scss">
+.read-the-docs {
+  color: #888;
+}
+</style>

+ 202 - 0
src/layout/index.vue

@@ -0,0 +1,202 @@
+<template>
+  <div class="body-box">
+    <SidevarItem></SidevarItem>
+    <div class="content">
+      <Navbar></Navbar>
+      <router-view></router-view>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onBeforeMount, onMounted, watch } from "vue";
+import Navbar from "./sidebar/Navbar.vue";
+import SidevarItem from "./sidebar/SidevarItem.vue";
+import { useStore } from "vuex";
+import axios from "axios";
+import { useRouter } from "vue-router";
+const store = useStore();
+const router = useRouter();
+const api = ref("");
+watch(
+  () => router.currentRoute.value.fullPath,
+  (newValue, oldValue) => {
+    console.log(newValue);
+    if (newValue == "/schoolBus/statement") {
+      store.commit("indexUp", 1);
+      sessionStorage.setItem("sidevarItem", 1);
+    }
+    if (newValue == "/schoolBus/staff") {
+      store.commit("indexUp", 2);
+      sessionStorage.setItem("sidevarItem", 2);
+    }
+    if (newValue == "/schoolBus/account") {
+      store.commit("indexUp", 3);
+      sessionStorage.setItem("sidevarItem", 3);
+    }
+    if (newValue == "/schoolBus/bus") {
+      store.commit("indexUp", 4);
+      sessionStorage.setItem("sidevarItem", 4);
+    }
+    if (newValue == "/schoolBus/classes") {
+      store.commit("indexUp", 6);
+      sessionStorage.setItem("sidevarItem", 6);
+    }
+    if (newValue == "/schoolBus/buspath") {
+      store.commit("indexUp", 5);
+      sessionStorage.setItem("sidevarItem", 5);
+    }
+    if (newValue == "/schoolBus/system") {
+      store.commit("indexUp", 8);
+      sessionStorage.setItem("sidevarItem", 8);
+    }
+    if (newValue == "/schoolBus/blacklist") {
+      store.commit("indexUp", 7);
+      sessionStorage.setItem("sidevarItem", 7);
+    }
+    if (newValue == "/schoolBus/busquery") {
+      store.commit("indexUp", 9);
+      sessionStorage.setItem("sidevarItem", 9);
+    }
+    if (newValue == "/schoolBus/log") {
+      store.commit("indexUp", 10);
+      sessionStorage.setItem("sidevarItem", 10);
+    }
+    if (newValue == "/schoolBus/report") {
+      store.commit("indexUp", 11);
+      sessionStorage.setItem("sidevarItem", 11);
+    }
+
+    if (newValue == "/schoolBus/driverAudit") {
+      store.commit("indexUp", 17);
+      sessionStorage.setItem("sidevarItem", 17);
+    }
+    if (newValue == "/schoolBus/driverManagement") {
+      store.commit("indexUp", 18);
+      sessionStorage.setItem("sidevarItem", 18);
+    }
+    if (newValue == "/schoolBus/driverDeposit") {
+      store.commit("indexUp", 19);
+      sessionStorage.setItem("sidevarItem", 19);
+    }
+    if (newValue == "/schoolBus/driverPath") {
+      store.commit("indexUp", 20);
+      sessionStorage.setItem("sidevarItem", 20);
+    }
+    if (newValue == "/schoolBus/driverOrder") {
+      store.commit("indexUp", 21);
+      sessionStorage.setItem("sidevarItem", 21);
+    }
+    if (newValue == "/schoolBus/driverRule") {
+      store.commit("indexUp", 22);
+      sessionStorage.setItem("sidevarItem", 22);
+    }
+
+    if (newValue == "/schoolBus/news") {
+      store.commit("indexUp", 0);
+      sessionStorage.setItem("sidevarItem", 0);
+    }
+  }
+);
+const tableData = reactive({
+  list: [],
+});
+onBeforeMount(async () => {
+  api.value = store.state.user.api;
+
+  // {
+  //   let res = await axios({
+  //     method: "post",
+  //     url: api.value + "/carBook/cnqueryHb.action",
+  //     headers: {
+  //       token: sessionStorage.getItem("token"),
+  //     },
+  //   });
+  //   console.log(res, "系统配置");
+  //   sessionStorage.setItem("waiting", JSON.stringify(res.data.data));
+  // }
+});
+</script>
+
+<style scoped lang="scss">
+.body-box {
+  display: flex;
+  .content {
+    // min-width: 1740px;
+    max-width: calc(100vw - 72px);
+    min-width: calc(100vw - 200px);
+    width: 100%;
+    height: calc(100vh);
+    background-color: rgba(238, 238, 238, 1);
+    :deep(.el-dialog__header .el-dialog__headerbtn) {
+      outline: none;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.is-message-box {
+  .el-message-box__header {
+    .el-message-box__headerbtn {
+      outline: none;
+    }
+  }
+  .el-message-box__btns {
+    .el-button--primary {
+      background-color: rgba(61, 81, 232, 1);
+      border: 0.5px solid rgba(61, 81, 232, 1);
+    }
+    .el-button--primary:hover {
+      background-color: rgb(119, 133, 239);
+      border: 0.5px solid rgb(119, 133, 239);
+    }
+  }
+}
+.el-dialog__body {
+  .el-input {
+    .el-input__suffix-inner {
+      color: rgba(61, 81, 232, 1);
+    }
+  }
+}
+.pw {
+  .el-dialog__body {
+    .el-form {
+      .el-form-item {
+        .queding {
+          background-color: rgba(61, 81, 232, 1);
+          border: 0.5px solid rgba(61, 81, 232, 1);
+        }
+        .queding:hover {
+          background-color: rgb(119, 133, 239);
+          border: 0.5px solid rgb(119, 133, 239);
+        }
+      }
+    }
+  }
+}
+#notification_1 {
+  .el-notification__group {
+    .el-notification__title {
+      color: red;
+    }
+  }
+}
+
+*::-webkit-scrollbar-track {
+  background-color: #fff;
+}
+
+*::-webkit-scrollbar {
+  background-color: #57b2ff;
+  height: 0;
+  width: 0;
+}
+
+*::-webkit-scrollbar-thumb {
+  background: #57b2ff;
+  border-radius: 4px;
+  height: 0;
+  width: 0;
+}
+</style>

+ 481 - 0
src/layout/sidebar/Navbar.vue

@@ -0,0 +1,481 @@
+<template>
+  <el-menu
+    :default-active="activeIndex"
+    class="el-menu-demo"
+    mode="horizontal"
+    background-color=""
+    text-color="#000"
+    active-text-color="#4392f7"
+    @select="handleSelect"
+  >
+    <el-icon
+      :size="20"
+      v-show="!menuclose"
+      class="fold"
+      @click="SpreadMenu(true)"
+      ><Fold
+    /></el-icon>
+    <el-icon
+      :size="20"
+      v-show="menuclose"
+      class="fold"
+      @click="SpreadMenu(false)"
+      ><Expand
+    /></el-icon>
+    <div class="logo">
+      <img src="@/assets/nanchang.png" style="width: 30px; height: 30px" />
+      <span>校团约车管理系统</span>
+    </div>
+    <div class="login">
+      <span class="dateTime">{{ dateTime }}</span>
+      <el-badge :value="titlenumber" class="item" v-if="titlenumber">
+        <img
+          src="@/assets/news.png"
+          @click="newsClick"
+          style="width: 20px; height: 20px; cursor: pointer"
+          alt=""
+        />
+        <!-- <el-icon><Bell /></el-icon> -->
+      </el-badge>
+      <img
+        v-else
+        src="@/assets/news.png"
+        @click="newsClick"
+        style="width: 20px; height: 20px; cursor: pointer"
+        alt=""
+      />
+      <div class="flex flex-wrap items-center" style="cursor: pointer">
+        <el-dropdown :hide-on-click="false" trigger="click">
+          <el-avatar :size="30">
+            <img
+              src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
+            />
+          </el-avatar>
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item @click="uppassword">
+                <el-icon class="switchButton" :size="20" color="#000">
+                  <Lock />
+                </el-icon>
+                <span>修改密码</span>
+              </el-dropdown-item>
+              <el-dialog
+                :append-to-body="true"
+                custom-class="pw"
+                v-model="uppasswordShow"
+                title="修改密码"
+                width="30%"
+                :before-close="uppasswordClose"
+                align-center
+                :close-on-click-modal="false"
+              >
+                <el-form
+                  ref="ruleFormRef"
+                  :model="ruleForm"
+                  :rules="rules"
+                  label-width="100px"
+                  class="demo-ruleForm"
+                  :size="formSize"
+                  label-position="left"
+                  status-icon
+                >
+                  <el-form-item label="原密码" prop="oldpass">
+                    <el-input
+                      v-model="ruleForm.oldpass"
+                      placeholder="请输入原密码"
+                      clearable
+                    />
+                  </el-form-item>
+                  <el-form-item label="新密码" prop="nowpass">
+                    <el-input
+                      v-model="ruleForm.nowpass"
+                      placeholder="请输入新密码"
+                      clearable
+                    />
+                  </el-form-item>
+                  <el-form-item
+                    label="确定新密码"
+                    prop="correctpass"
+                    style="
+                      padding-bottom: 40px;
+                      border-bottom: 1px solid rgba(230, 230, 230, 1);
+                    "
+                  >
+                    <el-input
+                      v-model="ruleForm.correctpass"
+                      placeholder="请再次输入新密码"
+                      clearable
+                    />
+                  </el-form-item>
+
+                  <el-form-item class="options">
+                    <el-button
+                      class="queding"
+                      type="primary"
+                      @click="submitForm(ruleFormRef)"
+                    >
+                      确定
+                    </el-button>
+                    <el-button class="congzhi" @click="resetForm(ruleFormRef)"
+                      >重置</el-button
+                    >
+                  </el-form-item>
+                </el-form>
+                <!-- <template #footer>
+                  <span class="dialog-footer">
+                    <el-button @click="dialogVisible = false">取消</el-button>
+                    <el-button type="primary" @click="dialogVisible = false">
+                      确定
+                    </el-button>
+                  </span>
+                </template> -->
+              </el-dialog>
+              <el-dropdown-item @click="loginOut">
+                <el-icon class="switchButton" :size="20" color="#000">
+                  <SwitchButton />
+                </el-icon>
+                <span>退出登录</span>
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </div>
+      <span class="name">{{ username }}</span>
+    </div>
+  </el-menu>
+</template>
+
+<script setup>
+import { ref, reactive, onBeforeMount, onMounted, watch } from "vue";
+import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
+import { useStore } from "vuex";
+import { useRouter } from "vue-router";
+import { dayjs } from "element-plus";
+import axios from "axios";
+
+const store = useStore();
+const router = useRouter();
+const username = ref(); // 账号名称
+const titlenumber = ref(1); //  消息条数
+const activeIndex = ref(); // 路由路径
+const loginOutDialogVisible = ref(false); // 退出按钮
+const menuclose = ref(false); // 左边状态栏展开按钮状态
+const uppasswordShow = ref(false); // 修改密码展示框
+const ruleForm = reactive({
+  oldpass: "",
+  nowpass: "",
+  correctpass: "",
+});
+const ruleFormRef = ref();
+// 表单验证
+const rules = reactive({
+  oldpass: [
+    {
+      required: true,
+      message: "密码不能为空",
+      trigger: "blur",
+    },
+  ],
+  nowpass: [
+    {
+      required: true,
+      message: "新密码不能为空",
+      trigger: "blur",
+    },
+  ],
+  correctpass: [
+    {
+      required: true,
+      message: "两次密码是否输入正确",
+      trigger: "blur",
+    },
+  ],
+  // desc: [{ required: true, message: "Please input activity form", trigger: "blur" }],
+});
+
+// 监控消息通知数量
+watch(
+  () => store.state.user.newsNum,
+  (newValue, oldValue) => {
+    titlenumber.value = newValue;
+    console.log(newValue, "监控消息数量");
+  }
+);
+
+// 点击消息通知
+const newsClick = () => {
+  store.commit("indexUp", 0);
+  sessionStorage.setItem("sidevarItem", 0);
+  router.push({
+    path: `/schoolBus/news`,
+  });
+};
+const dateTime = ref(
+  dayjs().format("YYYY-MM-DD") + ` 星期四 ` + dayjs().format("HH:mm:ss")
+); // 时间
+
+// 选择菜单
+const handleSelect = (key, keyPath) => {
+  store.commit("navbarUpdata", key);
+  activeIndex.value = key;
+};
+
+// 展开按钮
+const SpreadMenu = (flag) => {
+  store.commit("menuClose", flag);
+  menuclose.value = flag;
+};
+// 修改密码
+const uppassword = () => {
+  uppasswordShow.value = true;
+  // ruleForm.oldpass = store.state.user.password;
+};
+const uppasswordClose = () => {
+  uppasswordShow.value = false;
+  // ruleForm.oldpass = "";
+  // ruleForm.nowpass = "";
+  // ruleForm.correctpass = "";
+  ruleFormRef.value.resetFields();
+};
+// 提交修改密码表单
+const submitForm = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      let data = new FormData();
+      data.set("page", 1);
+      data.set("rows", 2000); //前面的key记得对应!
+      let res = await axios({
+        method: "post",
+        url: "/api/carBook/adminlist.action",
+        headers: {
+          token: sessionStorage.getItem("token"),
+        },
+        data,
+      });
+      // console.log(res.data.rows);
+      let account = res.data.rows.filter((item) => {
+        return item.number == sessionStorage.getItem("username");
+      });
+      console.log(account);
+      let dataUpdata = {
+        name: account[0].name,
+        number: account[0].number,
+        password: ruleForm.correctpass,
+        id: account[0].id,
+      };
+      if (ruleForm.oldpass == account[0].password) {
+        if (ruleForm.nowpass == ruleForm.correctpass) {
+          let resUpdata = await axios({
+            method: "post",
+            url: "/api/carBook/adminupdate.action",
+            headers: {
+              "Content-Type": "application/json;charset=utf-8",
+              token: sessionStorage.getItem("token"),
+            },
+            data: dataUpdata,
+          });
+          console.log(resUpdata);
+          if (resUpdata.data.code == 200) {
+            ElMessage({
+              type: "success",
+              showClose: true,
+              message: resUpdata.data.message,
+              center: true,
+            });
+            sessionStorage.removeItem("token");
+            localStorage.removeItem("pass");
+            uppasswordShow.value = false;
+            ruleFormRef.value.resetFields();
+            ElNotification({
+              type: "warning",
+              title: "提示!!!",
+              message: "密码已修改,请重新登录页面",
+              // duration: 0,
+              // position: "top-right",
+            });
+          } else {
+            ElMessage({
+              type: "error",
+              showClose: true,
+              message: res.data.message,
+              center: true,
+            });
+          }
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: "两次密码输入不正确",
+            center: true,
+          });
+        }
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: "原密码输入错误",
+          center: true,
+        });
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+// 重置表单
+const resetForm = (formEl) => {
+  // console.log("重置表单");
+  if (!formEl) return;
+  formEl.resetFields();
+};
+
+const loginOut = () => {
+  ElMessageBox.confirm("是否退出登录?", "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(() => {
+      sessionStorage.removeItem("token");
+      router.push({
+        path: `/login`,
+      });
+      ElMessage({
+        type: "success",
+        message: "退出成功",
+      });
+    })
+    .catch(() => {
+      ElMessage({
+        type: "info",
+        message: "已取消登录",
+      });
+    });
+};
+
+onMounted(() => {
+  activeIndex.value = store.state.user.navbar;
+  if (sessionStorage.getItem("newsNum") == 0) {
+    titlenumber.value = "";
+  } else {
+    titlenumber.value = sessionStorage.getItem("newsNum");
+  }
+
+  username.value = sessionStorage.getItem("username");
+  // handleSelect("vidicons");
+  setInterval(() => {
+    var week = ["日", "一", "二", "三", "四", "五", "六"];
+    var datas = dayjs().day();
+    dateTime.value =
+      dayjs().format("YYYY-MM-DD") +
+      ` 星期${week[datas]} ` +
+      dayjs().format("HH:mm:ss");
+  }, 1000);
+});
+</script>
+
+<style scoped lang="scss">
+.el-menu--horizontal {
+  border-bottom: none;
+  display: flex;
+  align-items: center;
+  height: 65px;
+  // width: 100%;
+  background-color: #fff;
+  box-shadow: 5px 5px 10px 0px rgba(213, 228, 252, 1);
+  .logo {
+    left: 90px;
+    display: flex;
+    align-items: center;
+    span {
+      margin-left: 10px;
+      font-size: 24px;
+      font-weight: 600;
+    }
+  }
+  .login {
+    color: #000;
+    display: flex;
+    align-items: center;
+    position: absolute;
+    right: 10px;
+    top: 17px;
+
+    .dateTime {
+      margin-right: 20px;
+    }
+    .el-badge {
+      display: flex;
+      align-items: center;
+      // :deep(.el-badge__content) {
+      //   width: 2px;
+      //   height: 14px;
+      // }
+    }
+    .items-center {
+      margin-left: 20px;
+    }
+    .name {
+      height: 20px;
+      line-height: 20px;
+      text-decoration: underline;
+      padding: 0 10px;
+      margin: 0 10px;
+      border-left: 2px solid #ccc;
+    }
+    .switchButton {
+      cursor: pointer;
+    }
+  }
+  .login:focus {
+    outline: none;
+  }
+  .fold {
+    width: 46px;
+    height: 65px;
+  }
+  .fold:hover {
+    cursor: pointer;
+    background-color: rgba(67, 146, 249, 0.1);
+  }
+}
+.el-dialog__body {
+  .options {
+    display: flex;
+    flex-direction: row-reverse;
+    :deep(.el-form-item__content) {
+      margin-left: 0 !important;
+      flex: none;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.el-overlay {
+  .el-overlay-dialog {
+    .pw {
+      border-radius: 11px;
+
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 30px 20px 10px 20px;
+        .el-input {
+          width: 200px;
+        }
+        .options {
+          margin-left: 170px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 324 - 0
src/layout/sidebar/SidevarItem copy.vue

@@ -0,0 +1,324 @@
+<template>
+  <div class="box-item">
+    <el-menu
+      class="el-menu-vertical-demo"
+      text-color="#fff"
+      active-color="#000"
+      :default-active="activeIndex"
+      :collapse="menuClose"
+      @select="handleSelect"
+    >
+      <!-- <div class="logo">logo</div> -->
+      <div class="logo el-menu-item">
+        <el-icon :size="20"
+          ><img src="@/assets/logo.png" style="width: 30px; height: 24px"
+        /></el-icon>
+      </div>
+      <el-menu-item :index="9">
+        <img
+          v-if="activeIndex == 9"
+          src="@/assets/busqueryA.png"
+          alt=""
+          style="width: 22px; height: 22px; margin: 0 18px"
+        />
+        <img
+          v-else
+          src="@/assets/busquery.png "
+          alt=""
+          style="width: 22px; height: 22px; margin: 0 18px"
+        />
+        <span>车辆调度</span>
+      </el-menu-item>
+      <el-menu-item :index="1">
+        <img v-if="activeIndex == 1" src="@/assets/statementA.png" alt="" />
+        <img v-else src="@/assets/statement.png " alt="" />
+        <span>报表统计</span>
+      </el-menu-item>
+      <el-menu-item :index="2">
+        <img v-if="activeIndex == 2" src="@/assets/staffA.png" alt="" />
+        <img v-else src="@/assets/staff.png" alt="" />
+        <span>驾驶员管理</span>
+      </el-menu-item>
+      <el-menu-item :index="11">
+        <img
+          v-if="activeIndex == 11"
+          style="width: 22px; height: 22px; margin: 0 20px 0 18px"
+          src="@/assets/reportA.png"
+          alt=""
+        />
+        <img
+          v-else
+          style="width: 22px; height: 22px; margin: 0 20px 0 18px"
+          src="@/assets/report.png"
+          alt=""
+        />
+        <span>报备管理</span>
+      </el-menu-item>
+      <el-menu-item :index="3">
+        <img v-if="activeIndex == 3" src="@/assets/accountA.png" alt="" />
+        <img v-else src="@/assets/account.png" alt="" />
+        <span>账号管理</span>
+      </el-menu-item>
+      <el-menu-item :index="4">
+        <img v-if="activeIndex == 4" src="@/assets/carA.png" alt="" />
+        <img v-else src="@/assets/car.png" alt="" />
+        <span>车辆管理</span>
+      </el-menu-item>
+      <el-menu-item :index="5">
+        <img v-if="activeIndex == 5" src="@/assets/pathA.png" alt="" />
+        <img v-else src="@/assets/path.png" alt="" />
+        <span>路线管理</span>
+      </el-menu-item>
+      <el-menu-item :index="6">
+        <img v-if="activeIndex == 6" src="@/assets/classesA.png" alt="" />
+        <img v-else src="@/assets/classes.png" alt="" />
+        <span>班次管理</span>
+      </el-menu-item>
+      <el-menu-item :index="7">
+        <img v-if="activeIndex == 7" src="@/assets/blacklistA.png" alt="" />
+        <img v-else src="@/assets/blacklist.png" alt="" />
+        <span>黑名单管理</span>
+      </el-menu-item>
+      <el-menu-item :index="10">
+        <img
+          v-if="activeIndex == 10"
+          src="@/assets/logA.png"
+          alt=""
+          style="width: 21px; height: 21px; margin: 0 20px"
+        />
+        <img
+          v-else
+          src="@/assets/log.png"
+          alt=""
+          style="width: 21px; height: 21px; margin: 0 20px"
+        />
+        <span>操作日志</span>
+      </el-menu-item>
+      <el-sub-menu index="1">
+        <template #title>
+          <el-icon style="font-size: 28px;"><location /></el-icon>
+          <span>顺风车模块</span>
+        </template>
+        <el-sub-menu index="1-4">
+          <template #title>顺风车司机</template>
+          <el-menu-item index="1-4-1">司机思考</el-menu-item>
+          <el-menu-item index="1-3">司机管理</el-menu-item>
+        </el-sub-menu>
+        <el-menu-item index="1-3">路线管理</el-menu-item>
+      </el-sub-menu>
+      <el-menu-item :index="8">
+        <img
+          v-if="activeIndex == 8"
+          src="@/assets/systemA.png"
+          alt=""
+          style="width: 20px; height: 20px"
+        />
+        <img
+          v-else
+          src="@/assets/system.png"
+          alt=""
+          style="width: 20px; height: 20px"
+        />
+        <span>系统设置</span>
+      </el-menu-item>
+    </el-menu>
+  </div>
+</template>
+
+<script setup>
+import { ref, onBeforeMount, onMounted, watch, reactive } from "vue";
+import { useStore } from "vuex";
+
+import { useRouter } from "vue-router";
+
+const store = useStore();
+const router = useRouter();
+
+const menuClose = ref(false);
+const activeIndex = ref(9);
+const acitveItems = reactive({ list: [] });
+
+watch(
+  () => store.state.user.collapse,
+  (newValue, oldValue) => {
+    menuClose.value = newValue;
+  }
+);
+watch(
+  () => store.state.user.activeIndex,
+  (newValue, oldValue) => {
+    console.log(newValue);
+
+    activeIndex.value = newValue;
+  }
+);
+
+const handleSelect = (key) => {
+  store.commit("indexUp", key);
+  activeIndex.value = key;
+  sessionStorage.setItem("sidevarItem", key);
+
+  if (activeIndex.value == 1) {
+    router.push({
+      path: `/schoolBus/statement`,
+    });
+  }
+  if (activeIndex.value == 2) {
+    router.push({
+      path: `/schoolBus/staff`,
+    });
+  }
+  if (activeIndex.value == 3) {
+    router.push({
+      path: `/schoolBus/account`,
+    });
+  }
+  if (activeIndex.value == 4) {
+    router.push({
+      path: `/schoolBus/bus`,
+    });
+  }
+  if (activeIndex.value == 6) {
+    router.push({
+      path: `/schoolBus/classes`,
+    });
+  }
+  if (activeIndex.value == 5) {
+    router.push({
+      path: `/schoolBus/buspath`,
+    });
+  }
+  if (activeIndex.value == 8) {
+    router.push({
+      path: `/schoolBus/system`,
+    });
+  }
+  if (activeIndex.value == 7) {
+    router.push({
+      path: `/schoolBus/blacklist`,
+    });
+  }
+  if (activeIndex.value == 9) {
+    router.push({
+      path: `/schoolBus/busquery`,
+    });
+  }
+  if (activeIndex.value == 10) {
+    router.push({
+      path: `/schoolBus/log`,
+    });
+  }
+  if (activeIndex.value == 11) {
+    router.push({
+      path: `/schoolBus/report`,
+    });
+  }
+  if (activeIndex.value == 0) {
+    router.push({
+      path: `/schoolBus/news`,
+    });
+  }
+};
+onBeforeMount(() => {
+  activeIndex.value = Number(sessionStorage.getItem("sidevarItem"));
+  store.commit("indexUp", Number(sessionStorage.getItem("sidevarItem")));
+});
+</script>
+
+<style lang="scss" scoped>
+.el-menu-vertical-demo:not(.el-menu--collapse) {
+  width: 220px;
+  // min-height: 400px;
+}
+.box-item {
+  // width: 220px !important;
+  height: calc(100vh);
+}
+.el-menu {
+  width: 100%;
+  height: 100%;
+  overflow: auto;
+  background: linear-gradient(
+    0deg,
+    rgba(134, 132, 255, 1) 0%,
+    rgba(60, 80, 232, 1) 100%
+  );
+  box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.16);
+
+  .logo {
+    height: 65px;
+    color: rgb(255, 255, 255);
+    cursor: default;
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+  }
+  .logo:hover {
+    background-color: transparent !important;
+  }
+  .el-menu-item {
+    // border-left: 3px solid rgba(248, 220, 38);
+    padding: 0 10px;
+  }
+  .el-menu-item:hover {
+    background-color: rgba(255, 255, 255, 0.4);
+  }
+  .el-menu-item.is-active:hover {
+    background-color: #fff;
+  }
+  .el-menu-item img {
+    width: 18px;
+    height: 18px;
+    margin: 0 20px;
+  }
+
+  :deep(.el-sub-menu) {
+    .el-sub-menu__title:hover{
+      background-color: rgba(255, 255, 255, 0.4);
+    }
+    .el-sub-menu__title{
+      display: flex;
+      align-items: center;
+      .el-icon{
+        margin: 0 18px;
+      }
+      .el-sub-menu__icon-arrow{
+        margin: 0 0 0 0px;
+        top: 40%;
+      }
+    }
+    .el-menu {
+      background-color: transparent;
+    }
+    .el-menu--inline{
+      .el-sub-menu{
+        .el-sub-menu__title{
+          padding-left: 40px;
+        }
+      }
+      .el-menu-item{
+        padding-left: 40px;
+      }
+    }
+  }
+  .el-sub-menu.is-active:hover {
+    background-color: #fff;
+  }
+}
+.el-menu--collapse{
+  :deep(.el-sub-menu){
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    .el-sub-menu__title{
+      padding: 0;
+    }
+  }
+}
+
+.el-menu-item.is-active {
+  box-sizing: border-box;
+  background-color: #fff;
+  color: #000;
+}
+</style>

+ 420 - 0
src/layout/sidebar/SidevarItem.vue

@@ -0,0 +1,420 @@
+<template>
+  <div class="box-item">
+    <el-menu
+      class="el-menu-vertical-demo"
+      text-color="#fff"
+      active-color="#000"
+      :default-active="activeIndex"
+      :collapse="menuClose"
+      @select="handleSelect"
+    >
+      <!-- <div class="logo">logo</div> -->
+      <div class="logo el-menu-item">
+        <el-icon :size="20"
+          ><img src="@/assets/logo.png" style="width: 30px; height: 24px"
+        /></el-icon>
+      </div>
+      <el-menu-item :index="9">
+        <img
+          v-if="activeIndex == 9"
+          src="@/assets/busqueryA.png"
+          alt=""
+          style="width: 22px; height: 22px"
+        />
+        <img
+          v-else
+          src="@/assets/busquery.png "
+          alt=""
+          style="width: 22px; height: 22px"
+        />
+        <span>车辆调度</span>
+      </el-menu-item>
+      <el-menu-item :index="1">
+        <img v-if="activeIndex == 1" src="@/assets/statementA.png" alt="" />
+        <img v-else src="@/assets/statement.png " alt="" />
+        <span>报表统计</span>
+      </el-menu-item>
+      <el-menu-item :index="2">
+        <img v-if="activeIndex == 2" src="@/assets/staffA.png" alt="" />
+        <img v-else src="@/assets/staff.png" alt="" />
+        <span>驾驶员管理</span>
+      </el-menu-item>
+      <!-- <el-menu-item :index="11">
+        <img
+          v-if="activeIndex == 11"
+          style="width: 22px; height: 22px"
+          src="@/assets/reportA.png"
+          alt=""
+        />
+        <img
+          v-else
+          style="width: 22px; height: 22px"
+          src="@/assets/report.png"
+          alt=""
+        />
+        <span>报备管理</span>
+      </el-menu-item> -->
+      <el-menu-item :index="3">
+        <img v-if="activeIndex == 3" src="@/assets/accountA.png" alt="" />
+        <img v-else src="@/assets/account.png" alt="" />
+        <span>账号管理</span>
+      </el-menu-item>
+      <el-menu-item :index="4">
+        <img v-if="activeIndex == 4" src="@/assets/carA.png" alt="" />
+        <img v-else src="@/assets/car.png" alt="" />
+        <span>车辆管理</span>
+      </el-menu-item>
+      <el-menu-item :index="5">
+        <img v-if="activeIndex == 5" src="@/assets/pathA.png" alt="" />
+        <img v-else src="@/assets/path.png" alt="" />
+        <span>路线管理</span>
+      </el-menu-item>
+      <el-menu-item :index="6">
+        <img v-if="activeIndex == 6" src="@/assets/classesA.png" alt="" />
+        <img v-else src="@/assets/classes.png" alt="" />
+        <span>班次管理</span>
+      </el-menu-item>
+      <!-- <el-menu-item :index="7">
+        <img v-if="activeIndex == 7" src="@/assets/blacklistA.png" alt="" />
+        <img v-else src="@/assets/blacklist.png" alt="" />
+        <span>黑名单管理</span>
+      </el-menu-item> -->
+      <el-menu-item :index="10">
+        <img
+          v-if="activeIndex == 10"
+          src="@/assets/logA.png"
+          alt=""
+          style="width: 21px; height: 21px"
+        />
+        <img
+          v-else
+          src="@/assets/log.png"
+          alt=""
+          style="width: 21px; height: 21px"
+        />
+        <span>操作日志</span>
+      </el-menu-item>
+      <!-- <el-sub-menu index="15" popper-class="ceshi">
+        <template #title>
+          <img
+            v-if="
+              activeIndex == 17 ||
+              activeIndex == 18 ||
+              activeIndex == 19 ||
+              activeIndex == 20 ||
+              activeIndex == 21 ||
+              activeIndex == 22 ||
+              activeIndex == 23 ||
+              activeIndex == 24
+            "
+            src="@/assets/driverPathA.png"
+            alt=""
+            style="width: 21px; height: 21px; margin-right: 13px"
+          />
+          <img
+            v-else
+            src="@/assets/driverPath.png"
+            alt=""
+            style="width: 21px; height: 21px; margin-right: 13px"
+          />
+          <span>顺风车模块</span>
+        </template>
+        <el-sub-menu index="16">
+          <template #title>顺风车司机</template>
+          <el-menu-item :index="17">司机审核</el-menu-item>
+          <el-menu-item :index="18">司机管理</el-menu-item>
+          <el-menu-item :index="19">司机提现管理</el-menu-item>
+        </el-sub-menu>
+        <el-menu-item :index="23">优惠券管理</el-menu-item>
+        <el-menu-item :index="24">优惠券记录</el-menu-item>
+        <el-menu-item :index="20">路线管理</el-menu-item>
+        <el-menu-item :index="21">订单管理</el-menu-item>
+        <el-menu-item :index="22">规则设置</el-menu-item>
+      </el-sub-menu> -->
+      <el-menu-item :index="8">
+        <img
+          v-if="activeIndex == 8"
+          src="@/assets/systemA.png"
+          alt=""
+          style="width: 20px; height: 20px"
+        />
+        <img
+          v-else
+          src="@/assets/system.png"
+          alt=""
+          style="width: 20px; height: 20px"
+        />
+        <span>系统设置</span>
+      </el-menu-item>
+    </el-menu>
+  </div>
+</template>
+
+<script setup>
+import { ref, onBeforeMount, onMounted, watch, reactive } from "vue";
+import { useStore } from "vuex";
+
+import { useRouter } from "vue-router";
+
+const store = useStore();
+const router = useRouter();
+
+const menuClose = ref(false);
+const activeIndex = ref(9);
+const acitveItems = reactive({ list: [] });
+
+watch(
+  () => store.state.user.collapse,
+  (newValue, oldValue) => {
+    menuClose.value = newValue;
+  }
+);
+watch(
+  () => store.state.user.activeIndex,
+  (newValue, oldValue) => {
+    console.log(newValue);
+
+    activeIndex.value = newValue;
+  }
+);
+
+const handleSelect = (key) => {
+  store.commit("indexUp", key);
+  activeIndex.value = key;
+  sessionStorage.setItem("sidevarItem", key);
+
+  if (activeIndex.value == 1) {
+    router.push({
+      path: `/schoolBus/statement`,
+    });
+  }
+  if (activeIndex.value == 2) {
+    router.push({
+      path: `/schoolBus/staff`,
+    });
+  }
+  if (activeIndex.value == 3) {
+    router.push({
+      path: `/schoolBus/account`,
+    });
+  }
+  if (activeIndex.value == 4) {
+    router.push({
+      path: `/schoolBus/bus`,
+    });
+  }
+  if (activeIndex.value == 6) {
+    router.push({
+      path: `/schoolBus/classes`,
+    });
+  }
+  if (activeIndex.value == 5) {
+    router.push({
+      path: `/schoolBus/buspath`,
+    });
+  }
+  if (activeIndex.value == 8) {
+    router.push({
+      path: `/schoolBus/system`,
+    });
+  }
+  if (activeIndex.value == 7) {
+    router.push({
+      path: `/schoolBus/blacklist`,
+    });
+  }
+  if (activeIndex.value == 9) {
+    router.push({
+      path: `/schoolBus/busquery`,
+    });
+  }
+  if (activeIndex.value == 10) {
+    router.push({
+      path: `/schoolBus/log`,
+    });
+  }
+  if (activeIndex.value == 11) {
+    router.push({
+      path: `/schoolBus/report`,
+    });
+  }
+
+  if (activeIndex.value == 17) {
+    router.push({
+      path: `/schoolBus/driverAudit`,
+    });
+  }
+  if (activeIndex.value == 18) {
+    router.push({
+      path: `/schoolBus/driverManagement`,
+    });
+  }
+  if (activeIndex.value == 19) {
+    router.push({
+      path: `/schoolBus/driverDeposit`,
+    });
+  }
+  if (activeIndex.value == 20) {
+    router.push({
+      path: `/schoolBus/driverPath`,
+    });
+  }
+  if (activeIndex.value == 21) {
+    router.push({
+      path: `/schoolBus/driverOrder`,
+    });
+  }
+  if (activeIndex.value == 22) {
+    router.push({
+      path: `/schoolBus/driverRule`,
+    });
+  }
+  if (activeIndex.value == 23) {
+    router.push({
+      path: `/schoolBus/coupon`,
+    });
+  }
+  if (activeIndex.value == 24) {
+    router.push({
+      path: `/schoolBus/couponRecord`,
+    });
+  }
+
+  if (activeIndex.value == 0) {
+    router.push({
+      path: `/schoolBus/news`,
+    });
+  }
+};
+onBeforeMount(() => {
+  activeIndex.value = Number(sessionStorage.getItem("sidevarItem"));
+  store.commit("indexUp", Number(sessionStorage.getItem("sidevarItem")));
+});
+</script>
+
+<style lang="scss" scoped>
+.el-menu-vertical-demo:not(.el-menu--collapse) {
+  width: 200px;
+  // min-height: 400px;
+}
+.box-item {
+  // width: 220px !important;
+  height: calc(100vh);
+}
+.el-menu {
+  width: 100%;
+  height: 100%;
+  overflow: auto;
+  background: linear-gradient(
+    0deg,
+    rgba(134, 132, 255, 1) 0%,
+    rgba(60, 80, 232, 1) 100%
+  );
+  box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.16);
+
+  .logo {
+    height: 65px;
+    color: rgb(255, 255, 255);
+    cursor: default;
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+  }
+  .logo:hover {
+    background-color: transparent !important;
+  }
+  .el-menu-item {
+    // border-left: 3px solid rgba(248, 220, 38);
+    padding: 0 10px;
+  }
+  .el-menu-item:hover {
+    background-color: rgba(255, 255, 255, 0.4);
+  }
+  .el-menu-item.is-active:hover {
+    background-color: #fff;
+  }
+  .el-menu-item img {
+    width: 18px;
+    height: 18px;
+    margin: 0 15px 0 0;
+  }
+
+  :deep(.el-sub-menu) {
+    .el-sub-menu__title:hover {
+      background-color: rgba(255, 255, 255, 0.4);
+    }
+
+    &.is-active.is-opened > .el-sub-menu__title {
+      background-color: #fff;
+      color: #000 !important;
+    }
+    &.is-active > .el-sub-menu__title {
+      background-color: #fff;
+      color: #000 !important;
+    }
+
+    .el-menu {
+      background-color: transparent;
+    }
+    // .el-menu--inline{
+
+    // }
+  }
+}
+.el-menu--collapse {
+  width:72px;
+  img {
+    width: 18px;
+    height: 18px;
+    margin: 0 !important;
+    padding: 0 15px;
+  }
+  :deep(.el-sub-menu) {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    .el-sub-menu__title {
+      padding: 0;
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+  }
+}
+
+.el-menu-item.is-active {
+  box-sizing: border-box;
+  background-color: #fff;
+  color: #000;
+}
+</style>
+
+<style lang="scss">
+.ceshi {
+  &.is-light {
+    border: none !important;
+    background: linear-gradient(
+      90deg,
+      rgba(38, 151, 255, 1) 0%,
+      rgba(102, 182, 255, 1) 100%
+    );
+    .el-menu {
+      background: rgb(38, 38, 38);
+      // rgba(60, 80, 232, 1)
+      .el-sub-menu__title:hover {
+        background: rgba(255, 255, 255, 0.4);
+      }
+      .el-sub-menu.is-active {
+        background: #fff;
+        .el-sub-menu__title {
+          color: #000 !important;
+        }
+      }
+    }
+  }
+  .el-menu-item.is-active {
+    background: #fff;
+    color: #000 !important;
+  }
+}
+</style>

+ 28 - 0
src/main.js

@@ -0,0 +1,28 @@
+import { createApp } from 'vue'
+import './style.css'
+import ElementPlus from 'element-plus'
+import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
+import 'element-plus/dist/index.css'
+import * as ElementPlusIconsVue from '@element-plus/icons-vue'
+import App from './App.vue'
+
+
+import router from "@/router";
+import store from '@/store'
+
+
+
+const app = createApp(App)
+for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
+    app.component(key, component)
+}
+
+app.use(ElementPlus, {
+    locale: zhCn,
+})
+app.use(router)
+app.use(store)
+
+
+app.mount('#app')
+app.config.devtools = true;

+ 147 - 0
src/router/index.js

@@ -0,0 +1,147 @@
+import {
+  createRouter,
+  createWebHistory,
+  createWebHashHistory,
+} from "vue-router";
+import Layout from "@/layout/index.vue";
+const router = createRouter({
+  // history: createWebHashHistory("/carstop/dist6"), // 线上地址
+  history: createWebHashHistory("/ride-sharing/pc"), // 校团环境发布地址
+  routes: [
+    {
+      path: "/login",
+      component: () => import("@/views/login/index.vue"),
+    },
+    {
+      path: "/",
+      redirect: "/login",
+    },
+    {
+      path: "/schoolBus",
+      component: Layout,
+      children: [
+        {
+          path: "news",
+          component: () => import("@/views/news/news.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        {
+          path: "statement",
+          component: () => import("@/views/statement/statement.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        {
+          path: "staff",
+          component: () => import("@/views/staff/staff.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        {
+          path: "account",
+          component: () => import("@/views/account/account.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        {
+          path: "bus",
+          component: () => import("@/views/bus/bus.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        {
+          path: "classes",
+          component: () => import("@/views/classes/classes.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        {
+          path: "buspath",
+          component: () => import("@/views/buspath/buspath.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        // {
+        //   path: "blacklist",
+        //   component: () => import("@/views/blacklist/blacklist.vue"),
+        //   meta: { title: "Dashboard", icon: "dashboard" },
+        // },
+        {
+          path: "system",
+          component: () => import("@/views/waiting/waiting.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        {
+          path: "busquery",
+          component: () => import("@/views/busquery/busquery.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        {
+          path: "log",
+          component: () => import("@/views/log/log.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        // 司机审核
+        {
+          path: "driverAudit",
+          component: () => import("@/views/driver/audit.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        // 司机管理
+        {
+          path: "driverManagement",
+          component: () => import("@/views/driver/management.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        // 司机提现管理
+        {
+          path: "driverDeposit",
+          component: () => import("@/views/driver/deposit.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        // 优惠券管理
+        {
+          path: "coupon",
+          component: () => import("@/views/driver/coupon.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        // 优惠券记录
+        {
+          path: "couponRecord",
+          component: () => import("@/views/driver/couponRecord.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        // 路线管理
+        {
+          path: "driverPath",
+          component: () => import("@/views/driver/path.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        // 订单管理
+        {
+          path: "driverOrder",
+          component: () => import("@/views/driver/order.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        // 规则设置
+        {
+          path: "driverRule",
+          component: () => import("@/views/driver/rule.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+        {
+          path: "report",
+          component: () => import("@/views/report/report.vue"),
+          meta: { title: "Dashboard", icon: "dashboard" },
+        },
+      ],
+    },
+  ],
+});
+export default router;
+router.beforeEach((to, from, next) => {
+  // 判断 如果cook是否存在,可以进去
+  if (sessionStorage.getItem("token")) {
+    next(); //放行
+  } else {
+    if (to.path == "/login") {
+      next();
+    } else {
+      next(`/login`);
+    }
+  }
+});

+ 5 - 0
src/store/getters.js

@@ -0,0 +1,5 @@
+//store/getters
+const getters = {
+    age: state => state.user.age //导出age
+}
+export default getters;

+ 22 - 0
src/store/index.js

@@ -0,0 +1,22 @@
+//store/index.js
+
+import createPersistedstate from 'vuex-persistedstate' //持久化插件
+import { createStore } from 'vuex'; //引入vuex
+import user from './modules/user'; //引入modules的方法;
+import getters from './getters' //引入getters
+const store = createStore({
+    modules: {
+        user
+    },
+    getters,
+    // plugins: [
+    //     createPersistedstate({
+    //         // key: 'userStore', //存储持久状态的键。(默认:vuex)
+    //         paths: ['user'], //部分持续状态的任何路径的数组。如果不加,默认所有。
+    //         storage: window.sessionStorage //默认存储到localStorage,想要存储到sessionStorage
+    //     })
+    // ]
+
+})
+
+export default store;

+ 150 - 0
src/store/modules/user.js

@@ -0,0 +1,150 @@
+import axios from "axios";
+
+//store/modules/user.js
+
+// 声明变量
+const state = {
+  collapse: false,
+  activeIndex: 0,
+  username: "",
+  password: "",
+  // api: "/carstop/carBuy", // 线上
+  // api: "/carstop/carbook", // 线上
+  api: "/ride-sharing/carBuy", // 校团
+  newsNum: "",
+};
+
+// 修改变量(state不能直接赋值修改,只能通过mutations)
+const mutations = {
+  menuClose: (state, value) => {
+    state.collapse = value;
+  },
+  indexUp: (state, value) => {
+    state.activeIndex = value;
+  },
+  userName: (state, value) => {
+    state.username = value;
+  },
+  passWord: (state, value) => {
+    state.password = value;
+  },
+  newsUp: (state, value) => {
+    state.newsNum = value;
+  },
+};
+// mutations的值由actions传入(异步)
+const actions = {
+  addAsync: ({ commit }) => {
+    setTimeout(() => {
+      commit("add");
+    }, 1000);
+  },
+  newsAsync: async ({ commit, state }) => {
+    let data = new FormData();
+    let res = await axios({
+      method: "post",
+      url: state.api + "/carBook/usermesUnRead.action",
+      headers: {
+        token: sessionStorage.getItem("token"),
+      },
+      data: data,
+    });
+    console.log(res, "系统消息");
+
+    commit("newsUp", res.data.u_count);
+    sessionStorage.setItem("newsNum", res.data.u_count);
+    console.log("vuex", res.data.u_count);
+  },
+  // 车辆管理
+  busNum: async ({ commit, state }) => {
+    let data = new FormData();
+    // let res = await adminApi.adminLogin(data);
+    let res = await axios({
+      method: "post",
+      url: state.api + "/carBook/cinfoqueryAll.action",
+      headers: {
+        token: sessionStorage.getItem("token"),
+      },
+      data: data,
+    });
+    console.log(res, "车辆管理");
+    if (res.status == 200) {
+      sessionStorage.setItem("busSelect", JSON.stringify(res.data.data));
+    } else {
+      // ElMessage({
+      //   type: "error",
+      //   showClose: true,
+      //   message: res.data.message,
+      //   center: true,
+      // });
+      // if (res.data.message == "token错误") {
+      //   router.push({
+      //     path: `/login`,
+      //   });
+      // }
+    }
+  },
+  // 路线管理
+  pathSelect: async ({ commit, state }) => {
+    let data = new FormData();
+    let res = await axios({
+      method: "post",
+      url: state.api + "/carBook/routequeryAll.action",
+      headers: {
+        token: sessionStorage.getItem("token"),
+      },
+      data: data,
+    });
+    res.data.data.forEach((item) => {
+      if (item.is_repair == 0) {
+        item.state = false;
+      } else if (item.is_repair == 1) {
+        item.state = true;
+      }
+      if (item.repair_end == "null") {
+        item.repair_end = "";
+      }
+    });
+    console.log(res, "路线管理");
+    if (res.status == 200) {
+      sessionStorage.setItem("route_endSelect", JSON.stringify(res.data.data));
+      let obj2 = {};
+      var reduce2 = res.data.data.reduce((curr, next) => {
+        /*判断对象中是否已经有该属性  没有的话 push 到 curr数组*/
+        obj2[next.route] ? "" : (obj2[next.route] = curr.push(next));
+        return curr;
+      }, []);
+      sessionStorage.setItem("pathSelect", JSON.stringify(reduce2));
+    } else {
+      ElMessage({
+        type: "error",
+        showClose: true,
+        message: res.data.message,
+        center: true,
+      });
+    }
+  },
+  // 系统扫码时间
+  sm_time: async ({ commit, state }) => {
+    let res = await axios({
+      method: "post",
+      url: state.api + "/carBook/cnqueryHb.action",
+      headers: {
+        token: sessionStorage.getItem("token"),
+      },
+    });
+    console.log(res.data, "系统扫码时间");
+
+    if (res.data.code == 200) {
+      sessionStorage.setItem("sm_start", res.data.data.sm_start);
+      sessionStorage.setItem("sm_end", res.data.data.sm_end);
+      sessionStorage.setItem("yy_end", res.data.data.yy_end);
+    }
+  },
+};
+
+export default {
+  state,
+  mutations,
+  actions,
+};

+ 89 - 0
src/style.css

@@ -0,0 +1,89 @@
+:root {
+  font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+  line-height: 1.5;
+  font-weight: 400;
+
+  color-scheme: light dark;
+  color: rgba(255, 255, 255, 0.87);
+  background-color: #242424;
+
+  font-synthesis: none;
+  text-rendering: optimizeLegibility;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  -webkit-text-size-adjust: 100%;
+}
+
+a {
+  font-weight: 500;
+  color: #646cff;
+  text-decoration: inherit;
+}
+a:hover {
+  color: #535bf2;
+}
+
+a {
+  font-weight: 500;
+  color: #646cff;
+  text-decoration: inherit;
+}
+a:hover {
+  color: #535bf2;
+}
+
+body {
+  margin: 0;
+  display: flex;
+  place-items: center;
+  min-width: 320px;
+  min-height: 100vh;
+}
+
+h1 {
+  font-size: 3.2em;
+  line-height: 1.1;
+}
+
+button {
+  border-radius: 8px;
+  border: 1px solid transparent;
+  padding: 0.6em 1.2em;
+  font-size: 1em;
+  font-weight: 500;
+  font-family: inherit;
+  background-color: #1a1a1a;
+  cursor: pointer;
+  transition: border-color 0.25s;
+}
+button:hover {
+  border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+  outline: 4px auto -webkit-focus-ring-color;
+}
+
+.card {
+  padding: 2em;
+}
+
+/* #app {
+  max-width: 1280px;
+  margin: 0 auto;
+  padding: 2rem;
+  text-align: center;
+} */
+
+@media (prefers-color-scheme: light) {
+  :root {
+    color: #213547;
+    background-color: #ffffff;
+  }
+  a:hover {
+    color: #747bff;
+  }
+  button {
+    background-color: #f9f9f9;
+  }
+}

+ 1 - 0
src/style/mixin.scss

@@ -0,0 +1 @@
+$default: red

+ 46 - 0
src/utils/request.js

@@ -0,0 +1,46 @@
+import axios from "axios";
+const service = axios.create({
+    baseURL: import.meta.env.VITE_BASE_API, //接口统一域名
+    timeout: 6000, //设置超时
+   
+});
+
+// request拦截器
+service.interceptors.request.use(
+    (config) => {
+        config.data = JSON.stringify(config.data); //数据转化,也可以使用qs转换
+        // config.headers = {
+        //     'Content-Type': 'application/json' //配置请求头
+        // }
+        // config.headers = { 'Content-Type': 'application/x-www-form-urlencoded' } //配置请求头
+        //如有需要:注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookie
+        // const token = sessionStorage.getItem("token"); //这里取token之前,你肯定需要先拿到token,存一下
+        // if (token) {
+        //     // config.params = { 'admin_token': token } //如果要求携带在参数中
+        //     config.headers["token"] = token; //如果要求携带在请求头中
+        // }
+        return config;
+    },
+    (error) => {
+        Promise.reject(error);
+    }
+);
+// 响应拦截器
+service.interceptors.response.use(
+    (response) => {
+        const res = response.data;
+
+        return response.data;
+    },
+    (error) => {
+        /* Message({
+                      message: '服务器调用错误',
+                      type: 'error',
+                      duration: 5 * 1000
+                    }) */
+        console.log(error);
+
+        return Promise.reject(error);
+    }
+);
+export default service;

+ 22 - 0
src/utils/rsa.js

@@ -0,0 +1,22 @@
+import { JSEncrypt } from 'jsencrypt';
+let publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMOcPB06u5yKyQsPjfVWiWgbEIrd14kiXNNihciaVKb6HnkQvq7zpQuZ80WEX94spnUMI3iOAl/GmIvHrpGwcbB4hJbznm+PajiwnUSPuCCXA68YJF640cJKb/8KeM7WVz69OFkIEPHhVxOy4FFF5QWe/kt6zOZ19HmE+ak+5x/QIDAQAB'
+let privateKey = '这里是封装的私钥'
+//加密方法
+export function RSAencrypt(pas) {
+    //实例化jsEncrypt对象
+    let jse = new JSEncrypt();
+    //设置公钥
+    jse.setPublicKey(publicKey);
+    console.log('加密:' + jse.encrypt(pas))
+    return jse.encrypt(pas);
+}
+
+//解密方法
+export function RSAdecrypt(pas) {
+    let jse = new JSEncrypt();
+    // 私钥
+    jse.setPrivateKey(privateKey)
+    console.log('解密:' + jse.decrypt(pas))
+    return jse.decrypt(pas);
+}
+

+ 763 - 0
src/views/account/account.vue

@@ -0,0 +1,763 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">账号管理</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>账号 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.carnumber"
+            class="w-50 m-2"
+            placeholder="请输入账号"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>创建时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="date"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            :prefix-icon="Calendar"
+            placeholder="请选择时间"
+          />
+        </div>
+
+        <el-button
+          style="margin-left: 20px"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          style="margin-left: 20px !important"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+      </div>
+      <!-- 按钮列表 -->
+      <div class="gongneng">
+        <el-button type="primary" color="rgba(61, 81, 232, 1)" @click="addlist"
+          ><el-icon><CirclePlus /></el-icon><span>新增账号</span></el-button
+        >
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          class="import"
+          type="primary"
+          @click="importExcel"
+          ><img
+            src="@/assets/import.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>导出表单</span></el-button
+        >
+      </div>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          width="150"
+          align="center"
+          label="序号"
+          type="index"
+          index="1"
+        />
+        <el-table-column align="center" prop="name" label="姓名" />
+        <el-table-column align="center" prop="number" label="账号" />
+        <el-table-column align="center" prop="create_time" label="创建时间" />
+
+        <el-table-column align="center" label="操作" width="220">
+          <template #default="scope">
+            <el-button link type="primary" @click="edit(scope.row)"
+              ><div class="look">编辑</div></el-button
+            >
+            <el-button link type="danger" @click="del(scope.row)"
+              ><div class="looks">删除</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 添加车辆弹窗 -->
+      <el-dialog
+        class="addStaff"
+        v-model="addDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :title="dialongTitle"
+        align-center
+        width="609"
+        :before-close="cancelAdd"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="100px"
+          class="demo-ruleForm"
+          :size="formSize"
+          label-position="left"
+          status-icon
+        >
+          <el-form-item label="账号 :" prop="account">
+            <el-input
+              :value="ruleForm.account"
+              placeholder="请输入账号"
+              clearable
+              :disabled="true"
+              v-if="dialongTitle == '编辑信息'"
+            />
+            <el-input
+              v-else
+              v-model="ruleForm.account"
+              placeholder="请输入账号"
+              clearable
+            />
+          </el-form-item>
+          <el-form-item label="密码 :" prop="pass">
+            <el-input
+              v-model="ruleForm.pass"
+              placeholder="请输入密码"
+              clearable
+            />
+          </el-form-item>
+          <el-form-item
+            label="昵称 :"
+            prop="name"
+            style="
+              padding-bottom: 40px;
+              border-bottom: 1px solid rgba(230, 230, 230, 1);
+            "
+          >
+            <el-input
+              v-model="ruleForm.name"
+              placeholder="请输入昵称"
+              clearable
+            />
+          </el-form-item>
+
+          <el-form-item class="options">
+            <el-button class="congzhi" @click="cancelAdd()">取消</el-button>
+            <el-button
+              color="rgba(61, 81, 232, 1)"
+              class="queding"
+              type="primary"
+              @click="submitAdd(ruleFormRef)"
+            >
+              确定
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增账号"); // 弹窗标题
+
+const searchInput = reactive({
+  carnumber: "",
+  createTime: "",
+}); // 搜索按钮数据
+5;
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+const api = ref("");
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  name: "",
+  account: "",
+  pass: "",
+  id: "",
+});
+// 表单验证
+const rules = reactive({
+  account: [
+    { required: true, message: "账号不能为空", trigger: "blur" },
+    // { min: 3, max: 5, message: "Length should be 3 to 5", trigger: "blur" },
+    {
+      pattern: /^[a-zA-z]\w{3,15}$/,
+      message: "请输入正确账号",
+      trigger: "blur",
+    },
+  ],
+  // ^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*,\._\+(){}])[0-9a-zA-Z!@#$%^&*,\\._\+(){}]{8,20}$
+  pass: [
+    {
+      required: true,
+      message: "密码不能为空",
+      trigger: "blur",
+    },
+    {
+      min: 8,
+      max: 20,
+      pattern:
+        /^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*,\._\+(){}])[0-9a-zA-Z!@#$%^&*,\\._\+(){}]{8,20}$/,
+      message: "请输入8-20位正确密码(大小写字母·字符·数字)",
+      trigger: "blur",
+    },
+  ],
+  name: [
+    {
+      required: true,
+      message: "昵称不能为空",
+      trigger: "blur",
+    },
+  ],
+
+  // desc: [{ required: true, message: "Please input activity form", trigger: "blur" }],
+});
+// 获取账户列表
+const getList = async (message) => {
+  // let res = await vidiconsApi.queryCamera(data);
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("number", searchInput.carnumber);
+  data.set("create_time", searchInput.createTime); //前面的key记得对应!
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  // let res = await adminApi.adminLogin(data);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/adminlist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  if (res.status == 200) {
+    if (message) {
+      ElMessage({
+        type: "success",
+        showClose: true,
+        message: message,
+        center: true,
+      });
+    }
+    tableData.list = res.data.rows;
+    // currentPage.value = res.data.currentPage;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.carnumber = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+
+//导出功能
+const importExcel = async () => {
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  let data = new FormData();
+  data.set("number", searchInput.carnumber);
+  data.set("create_time", searchInput.createTime);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/admintoExcel.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  // console.log(res, "导出账号");
+  if (res.data.code == 200) {
+    // const elt = document.createElement("a");
+    // elt.setAttribute(
+    //   "href",
+    //   "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl
+    // );
+    // // elt.setAttribute("download", "file.xlsx");
+    // // elt.style.display = "none";
+    // document.body.appendChild(elt);
+    var downloadPath = "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl;
+    console.log("获得地址数据:", downloadPath);
+    var downloadLink = document.createElement("a");
+    downloadLink.style.display = "none"; // 使其隐藏
+    downloadLink.href = downloadPath;
+    downloadLink.download = "";
+    downloadLink.click();
+    document.body.appendChild(downloadLink);
+    document.body.removeChild(downloadLink);
+    elt.click();
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+// 添加员工
+const addlist = () => {
+  dialongTitle.value = "新增账号";
+  addDialogVisible.value = true;
+  ruleForm.name = "";
+  ruleForm.account = "";
+  ruleForm.pass = "";
+};
+// 取消添加员工
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+  ruleFormRef.value.resetFields();
+};
+// 确认添加员工
+const submitAdd = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (dialongTitle.value == "新增账号") {
+        let data = {
+          name: ruleForm.name,
+          number: ruleForm.account,
+          password: ruleForm.pass,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/admininsert.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "添加账号");
+        if (res.data.code == 200) {
+          getList();
+
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      } else {
+        let data = {
+          name: ruleForm.name,
+          number: ruleForm.account,
+          password: ruleForm.pass,
+          id: ruleForm.id,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/adminupdate.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "修改账号");
+        if (res.data.code == 200) {
+          getList();
+
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+//编辑按钮
+const edit = (row) => {
+  dialongTitle.value = "编辑信息";
+  addDialogVisible.value = true;
+  console.log(row);
+  ruleForm.pass = row.password;
+  ruleForm.name = row.name;
+  ruleForm.account = row.number;
+  ruleForm.id = row.id;
+};
+//删除按钮
+const del = (row) => {
+  console.log(row);
+  ElMessageBox.confirm(`是否删除 ${row.number} 账号?`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      let data = new FormData();
+      data.set("id", row.id);
+      // let res = await adminApi.adminLogin(data);
+      let res = await axios({
+        method: "post",
+        url: api.value + "/carBook/admindel.action",
+        headers: {
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      if (res.data.code == 200) {
+        if (tableData.list.length == 1 && currentPage.value != 1) {
+          currentPage.value = currentPage.value - 1;
+        }
+        getList();
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+      console.log(res);
+    })
+    .catch(() => {
+      ElMessage({
+        type: "info",
+        message: "已取消删除",
+      });
+    });
+};
+
+// 多选框功能
+// const handleSelectionChange = (val) => {
+//   console.log(val);
+//   selectData.list = val;
+// };
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 60px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        :deep(.el-input .el-input__inner) {
+          font-size: 16px;
+        }
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex:1;
+    margin: 10px auto 10px;
+    overflow: auto;
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 30px 20px 10px 20px;
+        .el-input {
+          width: 200px;
+          .el-input__suffix-inner {
+            color: rgba(61, 81, 232, 1);
+          }
+        }
+
+        .options {
+          margin-left: 320px;
+        }
+      }
+    }
+  }
+  .el-pagination {
+    // width: 1600px;
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 30px;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

Разлика између датотеке није приказан због своје велике величине
+ 1759 - 0
src/views/blacklist/blacklist.vue


+ 742 - 0
src/views/bus/bus.vue

@@ -0,0 +1,742 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">车辆管理</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>车牌 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.carnumber"
+            class="w-50 m-2"
+            placeholder="请输入车牌号"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>创建时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="date"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            :prefix-icon="Calendar"
+            placeholder="请选择时间"
+          />
+        </div>
+
+        <el-button
+          style="margin-left: 20px"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          style="margin-left: 20px !important"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+      </div>
+      <!-- 按钮列表 -->
+      <div class="gongneng">
+        <el-button type="primary" color="rgba(61, 81, 232, 1)" @click="addlist"
+          ><el-icon><CirclePlus /></el-icon><span>新增车辆</span></el-button
+        >
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          class="import"
+          type="primary"
+          @click="importExcel"
+          ><img
+            src="@/assets/import.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>导出表单</span></el-button
+        >
+      </div>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          width="150"
+          align="center "
+          prop="device_number"
+          label="序列号"
+        />
+        <el-table-column align="center" prop="car_number" label="车牌" />
+        <el-table-column
+          align="center"
+          prop="contain"
+          label="容量"
+          width="200"
+        />
+
+        <el-table-column align="center" prop="create_time" label="创建时间" />
+
+        <el-table-column align="center" label="操作" width="220">
+          <template #default="scope">
+            <el-button link type="primary" @click="edit(scope.row)"
+              ><div class="look">编辑</div></el-button
+            >
+            <el-button link type="danger" @click="del(scope.row)"
+              ><div class="looks">删除</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 添加车辆弹窗 -->
+      <el-dialog
+        class="addStaff"
+        v-model="addDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :title="dialongTitle"
+        align-center
+        width="609"
+        :before-close="handleVideoClose"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="100px"
+          class="demo-ruleForm"
+          :size="formSize"
+          label-position="left"
+          status-icon
+        >
+          <el-form-item label="序列号 :" prop="serial">
+            <el-input
+              clearable
+              v-model="ruleForm.serial"
+              placeholder="请输入序列号"
+            />
+          </el-form-item>
+          <el-form-item label="车牌 :" prop="buslicence">
+            <el-input
+              clearable
+              v-model="ruleForm.buslicence"
+              placeholder="请输入车牌"
+            />
+          </el-form-item>
+          <el-form-item
+            label="容量 :"
+            prop="volume"
+            style="
+              padding-bottom: 40px;
+              border-bottom: 1px solid rgba(230, 230, 230, 1);
+            "
+          >
+            <el-input
+              clearable
+              v-model="ruleForm.volume"
+              placeholder="请输入容量"
+            />
+          </el-form-item>
+
+          <el-form-item class="options">
+            <el-button class="congzhi" @click="cancelAdd(ruleFormRef)"
+              >取消</el-button
+            >
+            <el-button
+              color="rgba(61, 81, 232, 1)"
+              class="queding"
+              type="primary"
+              @click="submitAdd(ruleFormRef)"
+            >
+              确定
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const api = ref("");
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增车辆"); // 弹窗标题
+
+const searchInput = reactive({
+  carnumber: "",
+  createTime: "",
+}); // 搜索按钮数据
+5;
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  serial: "",
+  buslicence: "",
+  volume: "",
+  id: "",
+});
+// 表单验证
+const rules = reactive({
+  // serial: [{ required: true, message: "序列号不能为空", trigger: "blur" }],
+  buslicence: [
+    { required: true, message: "请输入车牌号", trigger: "blur" },
+    {
+      pattern:
+        /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/,
+      message: "请输入合法车牌号",
+      trigger: "blur",
+    },
+  ],
+  volume: [
+    {
+      required: true,
+      message: "容量不能为空",
+      trigger: "blur",
+    },
+    {
+      pattern: /^(0|[1-9][0-9]*)$/,
+      message: "请输入正确数字",
+      trigger: "blur",
+    },
+  ],
+
+  // desc: [{ required: true, message: "Please input activity form", trigger: "blur" }],
+});
+// 查看车辆管理列表
+const getList = async (flag) => {
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("car_number", searchInput.carnumber);
+  data.set("create_time", searchInput.createTime); //前面的key记得对应!
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  // let res = await adminApi.adminLogin(data);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/cinfolist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    tableData.list = res.data.rows;
+    if (flag == 1) {
+      sessionStorage.setItem("busSelect", JSON.stringify(tableData.list));
+    }
+    // currentPage.value = res.data.currentPage;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.carnumber = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+//新增车辆
+const addlist = () => {
+  dialongTitle.value = "新增车辆";
+  addDialogVisible.value = true;
+  ruleForm.serial = "";
+  ruleForm.buslicence = "";
+  ruleForm.volume = "";
+};
+//编辑按钮
+const edit = (row) => {
+  dialongTitle.value = "编辑车辆";
+  addDialogVisible.value = true;
+  ruleForm.serial = row.device_number;
+  ruleForm.buslicence = row.car_number;
+  ruleForm.volume = row.contain;
+  ruleForm.id = row.id;
+};
+// 取消新增车辆
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+  ruleFormRef.value.resetFields();
+};
+// 确认新增车辆
+const submitAdd = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (dialongTitle.value == "新增车辆") {
+        let data = {
+          device_number: ruleForm.serial,
+          car_number: ruleForm.buslicence,
+          contain: ruleForm.volume,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/cinfoinsert.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "添加账号");
+        if (res.data.code == 200) {
+          getList();
+          store.dispatch("busNum");
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      } else {
+        let data = {
+          device_number: ruleForm.serial,
+          car_number: ruleForm.buslicence,
+          contain: ruleForm.volume,
+          id: ruleForm.id,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/cinfoupdate.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "修改账号");
+        if (res.data.code == 200) {
+          getList();
+          store.dispatch("busNum");
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+//删除按钮
+const del = (row) => {
+  ElMessageBox.confirm(`是否删除 ${row.car_number} 车?`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      let data = new FormData();
+      data.set("id", row.id);
+      // let res = await adminApi.adminLogin(data);
+      let res = await axios({
+        method: "post",
+        url: api.value + "/carBook/cinfodel.action",
+        headers: {
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      if (res.data.code == 200) {
+        if (tableData.list.length == 1 && currentPage.value != 1) {
+          currentPage.value = currentPage.value - 1;
+        }
+        getList();
+        store.dispatch("busNum");
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+      console.log(res);
+    })
+    .catch(() => {
+      ElMessage({
+        type: "info",
+        message: "已取消删除",
+      });
+    });
+};
+
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+//导出功能
+const importExcel = async () => {
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  let data = new FormData();
+  data.set("car_number", searchInput.carnumber);
+  data.set("create_time", searchInput.createTime);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/cinfotoExcel.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  // console.log(res, "导出账号");
+  if (res.data.code == 200) {
+    // const elt = document.createElement("a");
+    // elt.setAttribute(
+    //   "href",
+    //   "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl
+    // );
+    // elt.setAttribute("download", "file.png");
+    // elt.style.display = "none";
+    // document.body.appendChild(elt);
+    // elt.click();
+    var downloadPath = "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl;
+    console.log("获得地址数据:", downloadPath);
+    var downloadLink = document.createElement("a");
+    downloadLink.style.display = "none"; // 使其隐藏
+    downloadLink.href = downloadPath;
+    downloadLink.download = "";
+    downloadLink.click();
+    document.body.appendChild(downloadLink);
+    document.body.removeChild(downloadLink);
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 40px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        :deep(.el-input .el-input__inner) {
+          font-size: 16px;
+        }
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex:1;
+    margin: 10px auto 10px;
+    overflow: auto;
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 30px 20px 10px 20px;
+        .el-input {
+          width: 200px;
+        }
+        .options {
+          margin-left: 320px;
+        }
+      }
+    }
+  }
+  .el-pagination {
+    // width: 1600px;
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 30px;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 822 - 0
src/views/busnumber/busnumber.vue

@@ -0,0 +1,822 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">车次管理</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>车牌 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.carnumber"
+            class="w-50 m-2"
+            placeholder="请输入车牌号"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>创建时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="date"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            :prefix-icon="Calendar"
+            placeholder="请选择时间"
+          />
+        </div>
+
+        <el-button
+          style="margin-left: 20px"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          style="margin-left: 20px !important"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+      </div>
+      <!-- 按钮列表 -->
+      <div class="gongneng">
+        <el-button type="primary" color="rgba(61, 81, 232, 1)" @click="addlist"
+          ><el-icon><CirclePlus /></el-icon><span>新增车次</span></el-button
+        >
+        <!-- <el-button
+          color="rgba(61, 81, 232, 1)"
+          class="import"
+          type="primary"
+          @click="resetInput"
+          ><img
+            src="@/assets/import.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>导出表单</span></el-button
+        > -->
+      </div>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          align="center"
+          prop="car_number"
+          width="180"
+          label="车牌"
+        />
+        <el-table-column
+          align="center"
+          width="100"
+          prop="contain"
+          label="容量"
+        />
+        <el-table-column align="center " prop="ci_time" label="发车时间" />
+        <el-table-column align="center" prop="route" label="路线" width="200" />
+
+        <el-table-column
+          align="center"
+          prop="create_time"
+          width="250"
+          label="创建时间"
+        />
+        <el-table-column
+          align="center"
+          prop="ci_time"
+          label="截止时间"
+          width="120"
+        />
+        <el-table-column
+          align="center"
+          width="250"
+          prop="work_duration"
+          label="生效日期"
+        />
+        <el-table-column
+          align="center"
+          prop="notice_time"
+          label="提前通知时间"
+          width="100"
+        />
+        <el-table-column align="center" label="操作" width="220">
+          <template #default="scope">
+            <el-button link type="primary" @click="edit(scope.row)"
+              ><div class="look">编辑</div></el-button
+            >
+            <el-button link type="primary" @click="del(scope.row)"
+              ><div class="look">删除</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 添加车辆弹窗 -->
+      <el-dialog
+        class="addStaff"
+        v-model="addDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :title="dialongTitle"
+        align-center
+        width="609"
+        :before-close="cancelAdd"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="100px"
+          class="demo-ruleForm"
+          :size="formSize"
+          label-position="left"
+          status-icon
+        >
+          <el-form-item label="车牌 :" prop="carnumber">
+            <el-select
+              v-model="ruleForm.carnumber"
+              class="m-2"
+              placeholder="请输入车牌"
+            >
+              <el-option label="赣A11111" value="赣A11111" />
+              <el-option label="赣A22222" value="赣A22222" />
+              <el-option label="赣A33333" value="赣A33333" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="容量 :" prop="contain">
+            <el-input
+              clearable
+              v-model="ruleForm.contain"
+              placeholder="请输入容量"
+            />
+          </el-form-item>
+          <el-form-item label="生效日期 :" prop="workduration">
+            <el-date-picker
+              v-model="ruleForm.workduration"
+              type="daterange"
+              format="YYYY-MM-DD"
+              value-format="YYYY-MM-DD"
+              :prefix-icon="Calendar"
+              start-placeholder="开始时间"
+              end-placeholder="结束时间"
+            />
+          </el-form-item>
+          <el-form-item label="发车时间 :" prop="startytime">
+            <!-- <el-time-picker
+              v-model="ruleForm.startytime"
+              format="HH:mm"
+              value-format="HH:mm"
+              placeholder="请选择发车时间"
+            /> -->
+            <el-select
+              v-model="ruleForm.startytime"
+              class="m-2"
+              placeholder="请选择发车时间"
+            >
+              <el-option label="14:30" value="14:30" />
+              <el-option label="16:30" value="16:30" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="路线 :" prop="route">
+            <el-select
+              v-model="ruleForm.route"
+              class="m-2"
+              placeholder="请选择路线"
+            >
+              <el-option label="墨轩湖-黄家湖" value="墨轩湖-黄家湖" />
+              <el-option label="南昌校区" value="南昌校区" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="截止时间 :" prop="citime">
+            <el-select
+              v-model="ruleForm.citime"
+              class="m-2"
+              placeholder="请选择截止时间"
+            >
+              <el-option label="16:30" value="16:30" />
+              <el-option label="18:30" value="18:30" />
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            label="提前通知时间 :"
+            prop="noticetime"
+            type="Number"
+            style="
+              padding-bottom: 40px;
+              border-bottom: 1px solid rgba(230, 230, 230, 1);
+            "
+          >
+            <div class="informTime">
+              <el-input v-model="ruleForm.noticetime" clearable />
+              <span> 分钟</span>
+            </div>
+          </el-form-item>
+
+          <el-form-item class="options">
+            <el-button class="congzhi" @click="cancelAdd(ruleFormRef)"
+              >取消</el-button
+            >
+            <el-button
+              color="rgba(61, 81, 232, 1)"
+              class="queding"
+              type="primary"
+              @click="submitAdd(ruleFormRef)"
+            >
+              确定
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增车次"); // 弹窗标题
+
+const searchInput = reactive({
+  carnumber: "",
+  createTime: "",
+  route: "",
+  citime: "",
+}); // 搜索按钮数据
+5;
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  carnumber: "",
+  contain: "",
+  citime: "",
+  route: "",
+  startytime: "",
+  workduration: "",
+  noticetime: "10",
+  id: "",
+});
+// 表单验证
+const rules = reactive({
+  workduration: [
+    { required: true, message: "生效日期不能为空", trigger: "blur" },
+    // { min: 3, max: 5, message: "Length should be 3 to 5", trigger: "blur" },
+  ],
+  carnumber: [
+    {
+      required: true,
+      message: "车牌号不能为空",
+      trigger: "change",
+    },
+  ],
+  contain: [
+    {
+      required: true,
+      message: "容量不能为空",
+      trigger: "blur",
+    },
+  ],
+  startytime: [
+    {
+      required: true,
+      message: "发车时间不能为空",
+      trigger: "change",
+    },
+  ],
+  route: [
+    {
+      required: true,
+      message: "路线不能为空",
+      trigger: "change",
+    },
+  ],
+  citime: [
+    {
+      required: true,
+      message: "截止时间不能为空",
+      trigger: "change",
+    },
+  ],
+  noticetime: [
+    {
+      required: true,
+      message: "提前通知时间不能为空",
+      trigger: "blur",
+    },
+    {
+      pattern: /^[1-720]*$/,
+      message: "请填写正确的时间 (整数)",
+      trigger: "blur",
+    },
+  ],
+});
+// 获取车次信息
+const getList = async () => {
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("car_number", searchInput.carnumber);
+  data.set("ci_time", searchInput.citime);
+  data.set("route", searchInput.route);
+  data.set("create_time", searchInput.createTime);
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value);
+  let res = await axios({
+    method: "post",
+    url: "/api/carBook/cclist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.data.code == 200) {
+    // ElMessage({
+    //   type: "success",
+    //   showClose: true,
+    //   message: "请求数据成功",
+    //   center: true,
+    // });
+    tableData.list = res.data.rows;
+    currentPage.value = res.data.currentPage;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: "暂无数据",
+      center: true,
+    });
+  }
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList();
+}, 300);
+
+// 添加车次
+const addlist = () => {
+  dialongTitle.value = "新增车次";
+  addDialogVisible.value = true;
+  ruleForm.carnumber = "";
+  ruleForm.contain = "";
+  ruleForm.citime = "";
+  ruleForm.route = "";
+  ruleForm.startytime = "";
+  ruleForm.workduration = "";
+  ruleForm.noticetime = "";
+};
+//编辑按钮
+const edit = (row) => {
+  dialongTitle.value = "编辑车次";
+  addDialogVisible.value = true;
+  ruleForm.carnumber = row.car_number;
+  ruleForm.contain = row.contain;
+  ruleForm.citime = row.ci_time;
+  ruleForm.route = row.route;
+  ruleForm.startytime = row.starty_time;
+  ruleForm.workduration = row.work_duration.split("~");
+  ruleForm.noticetime = row.notice_time;
+  ruleForm.id = row.id;
+};
+// 取消添加车次
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+  ruleFormRef.value.resetFields();
+};
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.carnumber = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+// 确认新增车次
+const submitAdd = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (dialongTitle.value == "新增车次") {
+        let data = {
+          car_number: ruleForm.carnumber,
+          contain: ruleForm.contain,
+          ci_time: ruleForm.citime,
+          route: ruleForm.route,
+          starty_time: ruleForm.startytime,
+          work_duration:
+            ruleForm.workduration[0] + "~" + ruleForm.workduration[1],
+          notice_time: ruleForm.noticetime,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: "/api/carBook/ccinsert.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "添加账号");
+        if (res.data.code == 200) {
+          getList();
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      } else {
+        let data = {
+          car_number: ruleForm.carnumber,
+          contain: ruleForm.contain,
+          ci_time: ruleForm.citime,
+          route: ruleForm.route,
+          starty_time: ruleForm.startytime,
+          work_duration:
+            ruleForm.workduration[0] + "~" + ruleForm.workduration[1],
+          notice_time: ruleForm.noticetime,
+          id: ruleForm.id,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: "/api/carBook/ccupdate.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "修改账号");
+        if (res.data.code == 200) {
+          getList();
+
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+//删除按钮
+const del = (row) => {
+  ElMessageBox.confirm(`是否删除 ${row.car_number} 车次?`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      let data = new FormData();
+      data.set("id", row.id);
+      // let res = await adminApi.adminLogin(data);
+      let res = await axios({
+        method: "post",
+        url: "/api/carBook/ccdel.action",
+        headers: {
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      if (res.data.code == 200) {
+        if (tableData.list.length == 1 && currentPage.value != 1) {
+          currentPage.value = currentPage.value - 1;
+        }
+        getList();
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+      console.log(res);
+    })
+    .catch(() => {
+      ElMessage({
+        type: "info",
+        message: "已取消删除",
+      });
+    });
+};
+
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList(value);
+};
+
+onBeforeMount(() => {
+  getList(1);
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: 97.5%;
+  height: 89%;
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    // width: calc(100wh - 40px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: 96%;
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: 96%;
+    height: 550px;
+    margin: 10px auto 30px;
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 30px 20px 10px 20px;
+        .el-form-item {
+          label {
+            width: 120px !important;
+          }
+          .el-form-item__label {
+            width: 120px !important;
+          }
+          .informTime {
+            display: flex;
+            align-items: center;
+            .el-input {
+              width: 120px;
+              margin-right: 10px;
+              .el-input__inner {
+                text-align: center;
+              }
+            }
+          }
+        }
+        .el-form-item__content {
+          flex: none;
+          .el-input {
+            width: 370px;
+          }
+        }
+        .el-input {
+          width: 200px;
+        }
+        .options {
+          margin-left: 320px;
+        }
+      }
+    }
+  }
+  .el-pagination {
+    // width: 1600px;
+    width: 96%;
+    margin: 0 auto 18px;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 947 - 0
src/views/buspath/buspath.vue

@@ -0,0 +1,947 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">路线管理</span>
+    </div>
+    <div class="middles">
+      <div class="middle">
+        <!-- 路线管理 -->
+        <div class="filter">
+          <!-- <div class="addRoute">
+            <el-button
+              type="primary"
+              color="rgba(61, 81, 232, 1)"
+              @click="addroute"
+              ><el-icon><CirclePlus /></el-icon><span>新增路线</span></el-button
+            >
+          </div> -->
+          <el-table
+            :data="pathNum.list"
+            @selection-change="handleSelectionChange"
+            style="
+              width: 100%;
+              --el-table-border-color: none;
+              font-size: 16px;
+              color: #000;
+            "
+            height="138"
+            :header-cell-style="{
+              height: '40px',
+              border: 0,
+              fontSize: '16px',
+              color: '#000',
+            }"
+          >
+            <el-table-column
+              align="left"
+              prop="route"
+              label="出发路线名称"
+              width="300"
+            />
+            <el-table-column align="left" label="候补截止时间" width="300"
+              ><template #default="scope">
+                <el-time-picker
+                  ref="hb_time"
+                  v-model="scope.row.repair_end"
+                  placeholder="请选择时间"
+                  format="HH:mm"
+                  value-format="HH:mm"
+                  :clearable="false"
+                  :editable="false"
+                  @change="savePath(scope.row, '是否修改候补截止时间')"
+                />
+                <!-- @change="savePath(scope.row, '是否修改候补截止时间')" -->
+              </template>
+            </el-table-column>
+            <el-table-column label="是否候补" width="150" align="center">
+              <template #default="scope">
+                <el-switch
+                  :disabled="
+                    scope.row.repair_end == '' || scope.row.repair_end == 'null'
+                      ? true
+                      : false
+                  "
+                  v-model="scope.row.state"
+                  class="ml-2"
+                  style="
+                    --el-switch-on-color: rgba(
+                      61,
+                      81,
+                      232,
+                      1
+                    ); /*
+                --el-switch-off-color: rgba(61, 81, 232, 1); */
+                  "
+                  @change="savePath(scope.row, '是否启用候补')"
+                />
+                <!-- @change="savePath(scope.row, '是否启用/取消候补')" -->
+              </template>
+            </el-table-column>
+          </el-table>
+          <!-- <div class="route">
+            <div class="startRoute">
+              <div class="name">出发路线名称</div>
+            </div>
+            <div class="startRoute waiting">
+              <div class="name">是否候补</div>
+            </div>
+          </div>
+          <div class="routes">
+            <div class="route" v-for="item in pathNum.list">
+              <div class="startRoute">
+                <el-input
+                  clearable
+                  v-model="item.route"
+                  placeholder="请输入路线名称"
+                />
+              </div>
+              <div class="startRoute waiting">
+                <el-switch
+                  style="
+                    --el-switch-on-color: rgba(61, 81, 232, 1);
+                    /* --el-switch-off-color: rgba(61, 81, 232, 1); */
+                  "
+                  v-model="item.is_repair"
+                  :active-value="1"
+                  :inactive-value="0"
+                  size="large"
+                />
+              </div>
+              <div class="startRoute save">
+                <el-button
+                  type="primary"
+                  color="rgba(61, 81, 232, 1)"
+                  @click="savePath(item.id)"
+                  ><span>保存</span></el-button
+                >
+              </div>
+            </div>
+          </div> -->
+        </div>
+      </div>
+    </div>
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">站点管理</span>
+    </div>
+    <div class="gongneng">
+      <el-button type="primary" color="rgba(61, 81, 232, 1)" @click="addlist"
+        ><el-icon><CirclePlus /></el-icon><span>新增站点</span></el-button
+      >
+    </div>
+    <!-- 站点管理 -->
+
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '45px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column align="center" prop="route" label="路线名称" />
+        <el-table-column align="center" prop="route_end" label="站点" />
+        <el-table-column align="center" prop="price" label="金额" />
+        <el-table-column align="center" prop="create_time" label="创建时间" />
+
+        <el-table-column align="center" label="操作" width="220">
+          <template #default="scope">
+            <el-button link type="primary" @click="edit(scope.row)"
+              ><div class="look">编辑</div></el-button
+            >
+            <el-button link type="danger" @click="del(scope.row)"
+              ><div class="looks">删除</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 添加路线弹窗 -->
+      <el-dialog
+        class="addStaff"
+        v-model="addDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :title="dialongTitle"
+        align-center
+        width="609"
+        :before-close="cancelAdd"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="100px"
+          class="demo-ruleForm"
+          :size="formSize"
+          label-position="left"
+          status-icon
+        >
+          <el-form-item label="线路名称 :" prop="route">
+            <el-select
+              v-model="ruleForm.route"
+              class="m-2"
+              placeholder="请选择线路名称"
+            >
+              <el-option
+                :label="item.route"
+                :value="item.route"
+                v-for="item in pathNum.list"
+                :key="item.route"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="终点站 :" prop="route_end">
+            <el-input
+              clearable
+              v-model="ruleForm.route_end"
+              placeholder="请输入终点站"
+            />
+          </el-form-item>
+          <el-form-item label="金额 :" prop="price">
+            <el-input
+              clearable
+              v-model="ruleForm.price"
+              placeholder="请输入金额"
+            />
+          </el-form-item>
+
+          <el-form-item class="options">
+            <el-button class="congzhi" @click="cancelAdd(ruleFormRef)"
+              >取消</el-button
+            >
+            <el-button
+              color="rgba(61, 81, 232, 1)"
+              class="queding"
+              type="primary"
+              @click="submitAdd(ruleFormRef)"
+            >
+              确定
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import {
+  ref,
+  reactive,
+  watch,
+  nextTick,
+  onBeforeMount,
+  onUnmounted,
+} from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const api = ref("");
+const router = useRouter();
+const hb_time = ref(); // 路线管理候补截止时间组件 ref
+// 表格数据
+const tableData = reactive({
+  list: [],
+});
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增站点"); // 弹窗标题
+
+const searchInput = reactive({
+  carnumber: "",
+  createTime: "",
+  route: "",
+  citime: "",
+}); // 搜索按钮数据
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(6);
+const total = ref(10); // 当前总数
+const selectData = reactive({
+  list: [],
+}); // 多选框选择的数据
+
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  route: [],
+  route_end: "",
+  id: "",
+  is_repair: "",
+  price: "",
+});
+const pathNum = reactive({ list: [] });
+// 表单验证
+const rules = reactive({
+  route: [{ required: true, message: "线路名称不能为空", trigger: "blur" }],
+  route_end: [
+    {
+      required: true,
+      message: "终点站不能为空",
+      trigger: "blur",
+    },
+  ],
+  price: [
+    { required: true, message: "金额不能为空", trigger: "blur" },
+    {
+      pattern: /^(0|([1-9]\d*)(\.\d{1,2})?)$|^(0\.\d{1,2})$/,
+      message: "金额输入有误,请重新输入",
+      trigger: "blur",
+    },
+  ],
+});
+
+watch(
+  () => pathNum.list,
+  (newValue, oldValue) => {
+    newValue.forEach(async (item) => {
+      if (item.repair_end == "" || item.repair_end == "null") {
+        console.log("时间为空");
+        item.state = false;
+        item.is_repair = "0";
+        let data = new FormData();
+        data.set("route", item.route);
+        data.set("is_repair", item.is_repair);
+        data.set("repair_end", item.repair_end);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/routeupdateState.action",
+          headers: {
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        console.log(res, "修改路线候补时间和是否开启");
+        if (res.data.code == 200) {
+          store.dispatch("pathSelect");
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      }
+    });
+  }
+);
+
+// 获取车次信息
+const getList = async (flag) => {
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("create_time", searchInput.createTime);
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/routelist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  // console.log(res);
+
+  if (res.status == 200) {
+    tableData.list = res.data.rows;
+    tableData.list.forEach((item) => {
+      item.route2 = item.route;
+      item.route_end2 = item.route_end;
+      item.path_start = item.route.split("-")[0];
+      item.path_end = item.route.split("-")[1];
+      if (item.is_repair == "" || item.is_repair == 0) {
+        item.state = false;
+      } else if (item.is_repair == 1) {
+        item.state = true;
+      }
+    });
+    // let pathSelect = tableData.list.filter((item) => {
+    //   return item.is_repair == 1;
+    // });
+    // console.log(pathSelect);
+    // pathNum.list = pathSelect;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+
+// 修改路线候补时间和是否开启
+const savePath = async (row, title) => {
+  ElMessageBox.confirm(`${title}`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      let augment = pathNum.list.filter((item) => {
+        return item.id == row.id;
+      });
+      if (augment[0].state == false) {
+        augment[0].is_repair = 0;
+      } else if (augment[0].state == true) {
+        augment[0].is_repair = 1;
+      }
+      let data = new FormData();
+      data.set("route", augment[0].route);
+      data.set("is_repair", augment[0].is_repair);
+      data.set("repair_end", augment[0].repair_end);
+      let res = await axios({
+        method: "post",
+        url: api.value + "/carBook/routeupdateState.action",
+        headers: {
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      // console.log(res, "修改路线候补时间和是否开启");
+      if (res.data.code == 200) {
+        getList();
+        store.dispatch("pathSelect");
+        console.log(hb_time.value);
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+    })
+    .catch((action) => {
+      ElMessage({
+        type: "info",
+        message: "已取消",
+      });
+      pathNum.list = JSON.parse(sessionStorage.getItem("pathSelect"));
+      if (row.is_repair == 0) {
+        row.state = false;
+      } else if (row.is_repair == 1) {
+        row.state = true;
+      }
+    });
+};
+// 确定修改路线候补时间时选择时间框没有关闭的bug
+const handleClose = (val) => {
+  console.log(val);
+};
+
+// 确定截止时间
+const timeUpdata = (row) => {
+  console.log(row);
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+
+// 添加车次
+const addlist = () => {
+  dialongTitle.value = "新增站点";
+  addDialogVisible.value = true;
+  ruleForm.route = [];
+  ruleForm.route_end = "";
+  ruleForm.price = "";
+};
+//编辑按钮
+const edit = (row) => {
+  dialongTitle.value = "编辑站点";
+  addDialogVisible.value = true;
+  ruleForm.route = row.route;
+  ruleForm.route_end = row.route_end;
+  ruleForm.id = row.id;
+  ruleForm.is_repair = row.is_repair;
+  ruleForm.repair_end = row.repair_end;
+  ruleForm.price = row.price;
+};
+// 取消添加车次
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+  ruleFormRef.value.resetFields();
+};
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+// 确认新增车次
+const submitAdd = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (dialongTitle.value == "新增站点") {
+        let data = {
+          route: ruleForm.route,
+          route_end: ruleForm.route_end,
+          price: ruleForm.price,
+          // repair_end: ruleForm.repair_end,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/routeinsert.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "添加账号");
+        if (res.data.code == 200) {
+          getList();
+          store.dispatch("pathSelect");
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      } else {
+        let data = {
+          route: ruleForm.route,
+          route_end: ruleForm.route_end,
+          id: ruleForm.id,
+          is_repair: ruleForm.is_repair,
+          repair_end: ruleForm.repair_end,
+          price: ruleForm.price,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/routeupdate.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "修改账号");
+        if (res.data.code == 200) {
+          getList();
+          store.dispatch("pathSelect");
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      }
+    } else {
+      console.log("错误提交", fields);
+    }
+  });
+};
+
+//删除按钮
+const del = (row) => {
+  ElMessageBox.confirm(`是否删除 ${row.route} 这条路线?`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      let data = new FormData();
+      data.set("id", row.id);
+      // let res = await adminApi.adminLogin(data);
+      let res = await axios({
+        method: "post",
+        url: api.value + "/carBook/routedel.action",
+        headers: {
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      if (res.data.code == 200) {
+        if (tableData.list.length == 1 && currentPage.value != 1) {
+          currentPage.value = currentPage.value - 1;
+        }
+
+        getList();
+        store.dispatch("pathSelect");
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+      console.log(res);
+    })
+    .catch(() => {
+      ElMessage({
+        type: "info",
+        message: "已取消删除",
+      });
+    });
+};
+
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  console.log(value);
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  pathNum.list = JSON.parse(sessionStorage.getItem("pathSelect"));
+  console.log(pathNum.list);
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+::-webkit-scrollbar {
+  /* 对应纵向滚动条的宽度 */
+  width: 10px;
+  /* 对应横向滚动条的宽度 */
+  height: 10px;
+}
+
+/* 滚动条上的滚动滑块 */
+::-webkit-scrollbar-thumb {
+  background-color: rgba(61, 81, 232, 1);
+  border-radius: 32px;
+}
+
+/* 滚动条轨道 */
+::-webkit-scrollbar-track {
+  background-color: rgba(61, 81, 232, 0.2);
+  border-radius: 32px;
+}
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 60px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middles {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+    .middle {
+      width: 100%;
+      color: #000;
+      // border-bottom: 1px solid rgb(231, 231, 231);
+      .filter {
+        // display: flex;
+        // flex-wrap: wrap;
+        // align-items: center;
+        .route {
+          display: flex;
+          align-items: center;
+          margin: 10px 0 0 0;
+          .startRoute {
+            width: 200px;
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+            .name {
+              margin: 10px 0;
+              font-size: 14px;
+            }
+          }
+          .waiting {
+            align-items: center;
+            margin: 0 40px;
+          }
+          .line {
+            // transform: translateY(48px);
+            padding: 0 20px;
+          }
+          .save {
+            .el-button {
+              width: 100px;
+            }
+          }
+        }
+        .routes {
+          height: 100px;
+          overflow: auto;
+        }
+      }
+
+      :deep(.cont) {
+        width: 60%;
+        margin: 20px auto;
+      }
+      :deep(.download) {
+        display: flex;
+        align-items: center;
+        margin: 10px;
+      }
+      :deep(.download span) {
+        font-size: 16px;
+        margin-left: 20px;
+      }
+      :deep(.cont .el-button) {
+        margin-left: 60px;
+        margin-bottom: 30px;
+      }
+
+      :deep(.cont .accomplish) {
+        width: 100%;
+        display: flex;
+        justify-content: center;
+      }
+      :deep(.cont .accomplish .el-button) {
+        width: 50%;
+        margin: 0;
+      }
+    }
+  }
+  .gongneng {
+    width: calc(100% - 60px);
+    margin: 15px auto;
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex: 1;
+    margin: 10px auto 10px;
+    overflow: auto;
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 45px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 30px 20px 10px 20px;
+        .el-form-item {
+          label {
+            width: 120px !important;
+          }
+          .el-form-item__label {
+            width: 120px !important;
+          }
+          .informTime {
+            display: flex;
+            align-items: center;
+            .el-input {
+              width: 120px;
+              margin-right: 10px;
+              .el-input__inner {
+                text-align: center;
+              }
+            }
+          }
+        }
+        .el-form-item__content {
+          flex: none;
+          .el-input {
+            width: 370px;
+          }
+        }
+        .el-input {
+          width: 200px;
+        }
+        .options {
+          margin-left: 320px;
+        }
+      }
+    }
+  }
+  .el-pagination {
+    // width: 1600px;
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 30px;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

Разлика између датотеке није приказан због своје велике величине
+ 2262 - 0
src/views/busquery/busquery.vue


Разлика између датотеке није приказан због своје велике величине
+ 1842 - 0
src/views/classes/classes.vue


+ 716 - 0
src/views/driver/audit.vue

@@ -0,0 +1,716 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">司机审核</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>状态 : </span>
+          <el-select
+            style="width: 180px"
+            v-model="searchInput.car_number"
+            class="m-2"
+            placeholder="请选择状态"
+            :clearable="true"
+          >
+            <el-option label="全部" value="全部" />
+            <el-option label="待审核" value="待审核" />
+            <el-option label="审核成功" value="审核成功" />
+            <el-option label="拒绝" value="拒绝" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>司机姓名 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.name"
+            class="w-50 m-2"
+            placeholder="请输入司机姓名"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>手机号码 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入手机号码"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>车牌号 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入车牌号"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>提交时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="date"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            :prefix-icon="Calendar"
+            placeholder="请选择日期"
+          />
+        </div>
+      </div>
+      <!-- 按钮列表 -->
+      <div class="gongneng">
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          class="import"
+          type="primary"
+          @click="importExcel"
+          ><img
+            src="@/assets/import.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>导出表单</span></el-button
+        >
+      </div>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          type="index"
+          width="100"
+          align="center"
+          label="序号"
+          index="1"
+        />
+        <el-table-column align="center" prop="user_name" label="司机姓名" />
+        <el-table-column align="center" prop="user_phone" label="手机号码" />
+        <el-table-column align="center" prop="user_phone" label="证件号码" />
+        <el-table-column
+          align="center"
+          prop="user_phone"
+          label="身份证正面图"
+          width="200"
+        />
+        <el-table-column
+          align="center"
+          prop="user_phone"
+          label="身份证反面图"
+          width="200"
+        />
+        <el-table-column align="center" prop="user_phone" label="车辆型号" />
+        <el-table-column align="center" prop="user_phone" label="颜色" />
+        <el-table-column align="center" prop="user_phone" label="车牌号" />
+        <el-table-column align="center" prop="user_phone" label="驾驶证" />
+        <el-table-column align="center" prop="user_phone" label="行驶证" />
+        <el-table-column
+          align="center"
+          prop="user_phone"
+          label="车辆年检照片"
+          width="200"
+        />
+        <el-table-column
+          align="center"
+          prop="user_phone"
+          width="200"
+          label="车辆保险照片"
+        />
+        <el-table-column align="center" prop="user_phone" label="保证金" />
+        <el-table-column align="center" prop="user_zz" label="审核内容" />
+        <el-table-column align="center" prop="create_time" label="提交时间" />
+        <el-table-column align="center" prop="create_time" label="审核时间" />
+        <el-table-column align="center" prop="create_time" label="状态" />
+        <el-table-column align="center" label="操作" width="220">
+          <template #default="scope">
+            <el-button link type="primary" @click="pass(scope.row)"
+              ><div class="look">通过</div></el-button
+            >
+            <el-button link type="danger" @click="refuse(scope.row)"
+              ><div class="looks">拒绝</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 添加员工弹窗 -->
+      <el-dialog
+        class="addStaff"
+        v-model="addDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :title="dialongTitle"
+        align-center
+        width="550"
+        :before-close="cancelAdd"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="100px"
+          class="demo-ruleForm"
+          :size="formSize"
+          label-position="left"
+          status-icon
+        >
+          <el-form-item label="审核内容 :" prop="textarea">
+            <el-input
+              v-model="ruleForm.textarea"
+              style="width: 360px"
+              :rows="5"
+              type="textarea"
+              placeholder="请输入审核内容"
+            />
+          </el-form-item>
+
+          <el-form-item class="options">
+            <el-button class="congzhi" @click="cancelAdd(ruleFormRef)"
+              >取消</el-button
+            >
+            <el-button
+              color="rgba(61, 81, 232, 1)"
+              class="queding"
+              type="primary"
+              @click="submitAdd(ruleFormRef)"
+            >
+              确定
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增驾驶员"); // 弹窗标题
+const api = ref("");
+const searchInput = reactive({
+  name: "",
+  phone: "",
+  createTime: "",
+}); // 搜索按钮数据
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  textarea: "",
+  id: "",
+});
+// 表单验证
+const rules = reactive({
+  textarea: [{ required: true, message: "审核内容不能为空", trigger: "blur" }],
+  // phone: [
+  //   { required: true, message: "请输入手机号", trigger: "blur" },
+  //   {
+  //     // pattern: /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/,
+  //     pattern: /^((\(\+86\))|(\(86\)))?[1][3456789][0-9]{9}$/,
+  //     message: "请输入合法手机号/电话号",
+  //     trigger: "blur",
+  //   },
+  // ],
+});
+// 获取摄像头列表
+const getList = async (message) => {
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime); //前面的key记得对应!
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userlist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    if (message) {
+      ElMessage({
+        type: "success",
+        showClose: true,
+        message: message,
+        center: true,
+      });
+    }
+    tableData.list = res.data.rows;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.name = "";
+  searchInput.phone = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+// 拒绝
+const refuse = () => {
+  dialongTitle.value = "拒绝审核";
+  addDialogVisible.value = true;
+  ruleForm.textarea = "";
+};
+
+// 取消拒绝
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+  ruleFormRef.value.resetFields();
+};
+// 确认添加员工
+const submitAdd = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      let data = {
+        user_name: ruleForm.name,
+        user_phone: ruleForm.phone,
+        user_zz: ruleForm.post,
+        id: ruleForm.id,
+      };
+      let res = await axios({
+        method: "post",
+        url: api.value + "/carBook/userupdate.action",
+        headers: {
+          "Content-Type": "application/json;charset=utf-8",
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      // console.log(res, "修改账号");
+      if (res.data.code == 200) {
+        getList();
+
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+        addDialogVisible.value = false;
+        ruleFormRef.value.resetFields();
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+// 通过
+const pass = (row) => {
+  ElMessageBox.confirm(`是否通过审核`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      // let data = new FormData();
+      // data.set("id", row.id);
+      // let res = await axios({
+      //   method: "post",
+      //   url: api.value + "/carBook/userdel.action",
+      //   headers: {
+      //     token: sessionStorage.getItem("token"),
+      //   },
+      //   data: data,
+      // });
+      // if (res.data.code == 200) {
+      //   if (tableData.list.length == 1 && currentPage.value != 1) {
+      //     currentPage.value = currentPage.value - 1;
+      //   }
+      //   getList();
+      //   ElMessage({
+      //     type: "success",
+      //     showClose: true,
+      //     message: res.data.message,
+      //     center: true,
+      //   });
+      // } else {
+      //   ElMessage({
+      //     type: "error",
+      //     showClose: true,
+      //     message: res.data.message,
+      //     center: true,
+      //   });
+      // }
+    })
+    .catch(() => {});
+};
+//导出功能
+const importExcel = async () => {
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  let data = new FormData();
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/usertoExcel.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  // console.log(res, "导出账号");
+  if (res.data.code == 200) {
+    // const elt = document.createElement("a");
+    // elt.setAttribute(
+    //   "href",
+    //   "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl
+    // );
+    // // elt.setAttribute("download", "file.xlsx");
+    // // elt.style.display = "none";
+    // document.body.appendChild(elt);
+    // elt.click();
+    var downloadPath = "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl;
+    console.log("获得地址数据:", downloadPath);
+    var downloadLink = document.createElement("a");
+    downloadLink.style.display = "none"; // 使其隐藏
+    downloadLink.href = downloadPath;
+    downloadLink.download = "";
+    downloadLink.click();
+    document.body.appendChild(downloadLink);
+    document.body.removeChild(downloadLink);
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 60px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        :deep(.el-input .el-input__inner) {
+          font-size: 16px;
+        }
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex: 1;
+    margin: 10px auto;
+    overflow: auto;
+
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 25px 20px 10px 20px;
+        .el-input {
+          width: 200px;
+        }
+        .options {
+          margin: 30px 0 10px 350px;
+          .el-form-item__content {
+            margin: 0 !important;
+          }
+        }
+      }
+    }
+  }
+  .el-pagination {
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 auto;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

Разлика између датотеке није приказан због своје велике величине
+ 1099 - 0
src/views/driver/coupon.vue


+ 590 - 0
src/views/driver/couponRecord.vue

@@ -0,0 +1,590 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">优惠券记录</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>状态 : </span>
+          <el-select
+            style="width: 180px"
+            v-model="searchInput.car_number"
+            class="m-2"
+            placeholder="请选择状态"
+            :clearable="true"
+          >
+            <el-option label="全部" value="全部" />
+            <el-option label="启用中" value="启用中" />
+            <el-option label="未开启" value="未开启" />
+            <el-option label="已过期" value="已过期" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>优惠券类型 : </span>
+          <el-select
+            style="width: 200px"
+            v-model="searchInput.car_number"
+            class="m-2"
+            placeholder="请选择优惠券类型"
+            :clearable="true"
+          >
+            <el-option label="全部" value="全部" />
+            <el-option label="平台赠送" value="平台赠送" />
+            <el-option label="司机赔偿" value="司机赔偿" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>手机号 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.name"
+            class="w-50 m-2"
+            placeholder="请输入手机号"
+            style="width: 20 0px"
+          />
+        </div>
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          style="margin-left: 20px !important;"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+      </div>
+      <!-- <div class="gongneng"></div> -->
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          type="index"
+          width="80"
+          align="center"
+          label="序号"
+          index="1"
+        />
+        <el-table-column align="center" prop="user_name" label="昵称" />
+        <el-table-column align="center" prop="user_name" label="头像" />
+        <el-table-column align="center" prop="user_name" label="手机号" />
+        <el-table-column align="center" prop="user_name" label="优惠券名称" />
+        <el-table-column align="center" prop="user_name" label="图片" />
+        <el-table-column align="center" prop="user_name" label="优惠券类型" />
+        <el-table-column align="center" prop="user_name" label="优惠券金额" />
+        <el-table-column align="center" prop="user_name" label="最低消费金额" />
+        <el-table-column align="center" prop="user_name" label="发放时间" />
+        <el-table-column align="center" prop="user_name" label="过期时间" />
+        <el-table-column align="center" prop="user_zz" label="状态" />
+      </el-table>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增驾驶员"); // 弹窗标题
+const api = ref("");
+const searchInput = reactive({
+  name: "",
+  phone: "",
+  createTime: "",
+}); // 搜索按钮数据
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+// 获取摄像头列表
+const getList = async (message) => {
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime); //前面的key记得对应!
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userlist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    if (message) {
+      ElMessage({
+        type: "success",
+        showClose: true,
+        message: message,
+        center: true,
+      });
+    }
+    tableData.list = res.data.rows;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.name = "";
+  searchInput.phone = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+// 拒绝
+const edit = () => {
+  dialongTitle.value = "编辑优惠券";
+  addDialogVisible.value = true;
+  ruleForm.textarea = "";
+};
+const addCoupon = () => {
+  dialongTitle.value = "添加优惠券";
+  addDialogVisible.value = true;
+  ruleForm.textarea = "";
+};
+// 照片上传
+const pictureRemove = (uploadFile, uploadFiles) => {
+  console.log(uploadFile, uploadFiles);
+  ruleForm.picture = "";
+};
+// 限制上传图片的大小
+const beforeAvatarPicture = (rawFile) => {
+  console.log(rawFile, 33333);
+  if (rawFile.type !== "image/jpeg" && rawFile.type !== "image/png") {
+    ElMessage.error("图片格式必须为JPG/PNG格式!");
+    return false;
+  } else if (rawFile.size / 1024 > 500) {
+    ElMessage.error("图片的大小不能超过500kb!");
+    return false;
+  }
+  return true;
+};
+
+const pictureImportChange = async (file, fileLists) => {
+  console.log(file, "1111");
+  // if (!beforeAvatarPicture(file.raw)) {
+  //   // 如果 beforeAvatarPicture 返回了 false,直接退出
+  //   return;
+  // }
+  // let srcImg = file.raw;
+  // let data = new FormData();
+  // data.set("file", srcImg);
+  // let res = await https.post(
+  //   "/welcome/api/welcomeFile/uploadFile",
+  //   "data",
+  //   data
+  // );
+  // console.log(res, "导入照片");
+  // if (res.code == 200) {
+  //   ruleForm.picture = res.data.url;
+  //   ElMessage({
+  //     type: "success",
+  //     showClose: true,
+  //     message: res.message,
+  //     center: true,
+  //   });
+  // } else {
+  //   ElMessage({
+  //     type: "error",
+  //     showClose: true,
+  //     message: res.message,
+  //     center: true,
+  //   });
+  // }
+};
+
+// 取消拒绝
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+  ruleFormRef.value.resetFields();
+};
+// 确认添加员工
+const submitAdd = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      let data = {
+        user_name: ruleForm.name,
+        user_phone: ruleForm.phone,
+        user_zz: ruleForm.post,
+        id: ruleForm.id,
+      };
+      let res = await axios({
+        method: "post",
+        url: api.value + "/carBook/userupdate.action",
+        headers: {
+          "Content-Type": "application/json;charset=utf-8",
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      // console.log(res, "修改账号");
+      if (res.data.code == 200) {
+        getList();
+
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+        addDialogVisible.value = false;
+        ruleFormRef.value.resetFields();
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+// 赠送优惠券 --------------------------------------------------------
+const give = () => {
+  giveCouponTitle.value = "赠送优惠券";
+  giveCouponVisible.value = true;
+  ruleFormCoupon.textarea = "";
+};
+const cancelCoupon = () => {
+  giveCouponVisible.value = false;
+};
+const submitCoupon = () => {};
+// --------------------------------------------------------
+
+// 用户列表 =================================================================
+const userSelect = () => {
+  userListVisible.value = true;
+};
+const userListCancel = () => {
+  userListVisible.value = false;
+};
+// 分页
+const userCurrentChange = (value) => {
+  // console.log(value);
+  currentPageUser.value = value;
+};
+// =================================================================
+
+// 用户列表 ------------------------------------------------------------------
+const lookCoupon = () => {
+  lookVisible.value = true;
+};
+const lookCancel = () => {
+  lookVisible.value = false;
+};
+// 分页
+const lookCurrentChange = (value) => {
+  // console.log(value);
+  currentPageLook.value = value;
+};
+// ------------------------------------------------------------------
+
+// 删除 --------------------------------------------------------
+const pass = (row) => {
+  ElMessageBox.confirm(`是否删除此优惠券`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      // let data = new FormData();
+      // data.set("id", row.id);
+      // let res = await axios({
+      //   method: "post",
+      //   url: api.value + "/carBook/userdel.action",
+      //   headers: {
+      //     token: sessionStorage.getItem("token"),
+      //   },
+      //   data: data,
+      // });
+      // if (res.data.code == 200) {
+      //   if (tableData.list.length == 1 && currentPage.value != 1) {
+      //     currentPage.value = currentPage.value - 1;
+      //   }
+      //   getList();
+      //   ElMessage({
+      //     type: "success",
+      //     showClose: true,
+      //     message: res.data.message,
+      //     center: true,
+      //   });
+      // } else {
+      //   ElMessage({
+      //     type: "error",
+      //     showClose: true,
+      //     message: res.data.message,
+      //     center: true,
+      //   });
+      // }
+    })
+    .catch(() => {});
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 60px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        :deep(.el-input .el-input__inner) {
+          font-size: 16px;
+        }
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex: 1;
+    margin: 10px auto;
+    overflow: auto;
+
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+  }
+  .el-pagination {
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 auto;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 701 - 0
src/views/driver/deposit.vue

@@ -0,0 +1,701 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">司机提现管理</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>状态 : </span>
+          <el-select
+            style="width: 180px"
+            v-model="searchInput.car_number"
+            class="m-2"
+            placeholder="请选择状态"
+            :clearable="true"
+          >
+            <el-option label="已拒绝" value="已拒绝" />
+            <el-option label="已转账" value="已转账" />
+            <el-option label="待转账" value="待转账" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>司机姓名 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.name"
+            class="w-50 m-2"
+            placeholder="请输入司机姓名"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>手机号码 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入手机号码"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>申请时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="datetimerange"
+            format="YYYY-MM-DD HH:mm:ss"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            range-separator="-"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
+            :prefix-icon="Calendar"
+          />
+        </div>
+        <div class="condition">
+          <span>操作时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="datetimerange"
+            format="YYYY-MM-DD HH:mm:ss"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            range-separator="-"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
+            :prefix-icon="Calendar"
+          />
+        </div>
+        <el-button
+          style="margin-left: 20px"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          style="margin-left: 20px !important"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          class="import"
+          type="primary"
+          @click="importExcel"
+          ><img
+            src="@/assets/import.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>导出表单</span></el-button
+        >
+      </div>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          type="index"
+          width="80"
+          align="center"
+          label="序号"
+          index="1"
+        />
+        <el-table-column align="center" prop="user_name" label="司机姓名" />
+        <el-table-column align="center" prop="user_phone" label="手机号码" />
+        <el-table-column align="center" prop="user_phone" label="身份证号" />
+        <el-table-column align="center" prop="user_phone" label="银行卡号" />
+        <el-table-column align="center" prop="user_phone" label="开户行" />
+        <el-table-column align="center" prop="user_phone" label="开户人姓名" />
+        <el-table-column align="center" prop="user_phone" label="提现金额" />
+        <el-table-column align="center" prop="user_phone" label="状态" />
+        <el-table-column align="center" prop="user_phone" label="手续费" />
+        <el-table-column align="center" prop="user_phone" label="当前余额" />
+        <el-table-column align="center" prop="user_phone" label="拒绝原因" />
+        <el-table-column align="center" prop="user_zz" label="申请时间" width="200"/>
+        <el-table-column
+          align="center"
+          prop="create_time"
+          label="转账拒绝时间"
+          width="200"
+        />
+        <el-table-column align="center" prop="create_time" label="转账订单号" />
+        <el-table-column align="center" label="操作" width="220">
+          <template #default="scope">
+            <el-button link type="primary" @click="pass(scope.row)"
+              ><div class="look">转账</div></el-button
+            >
+            <el-button link type="danger" @click="refuse(scope.row)"
+              ><div class="looks">拒绝</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 添加员工弹窗 -->
+      <el-dialog
+        class="addStaff"
+        v-model="addDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :title="dialongTitle"
+        align-center
+        width="550"
+        :before-close="cancelAdd"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="100px"
+          class="demo-ruleForm"
+          :size="formSize"
+          label-position="left"
+          status-icon
+        >
+          <el-form-item label="审核内容 :" prop="textarea">
+            <el-input
+              v-model="ruleForm.textarea"
+              style="width: 360px"
+              :rows="5"
+              type="textarea"
+              placeholder="请输入审核内容"
+            />
+          </el-form-item>
+
+          <el-form-item class="options">
+            <el-button class="congzhi" @click="cancelAdd(ruleFormRef)"
+              >取消</el-button
+            >
+            <el-button
+              color="rgba(61, 81, 232, 1)"
+              class="queding"
+              type="primary"
+              @click="submitAdd(ruleFormRef)"
+            >
+              确定
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增驾驶员"); // 弹窗标题
+const api = ref("");
+const searchInput = reactive({
+  name: "",
+  phone: "",
+  createTime: "",
+}); // 搜索按钮数据
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  textarea: "",
+  id: "",
+});
+// 表单验证
+const rules = reactive({
+  textarea: [{ required: true, message: "审核内容不能为空", trigger: "blur" }],
+  // phone: [
+  //   { required: true, message: "请输入手机号", trigger: "blur" },
+  //   {
+  //     // pattern: /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/,
+  //     pattern: /^((\(\+86\))|(\(86\)))?[1][3456789][0-9]{9}$/,
+  //     message: "请输入合法手机号/电话号",
+  //     trigger: "blur",
+  //   },
+  // ],
+});
+// 获取摄像头列表
+const getList = async (message) => {
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime); //前面的key记得对应!
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userlist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    if (message) {
+      ElMessage({
+        type: "success",
+        showClose: true,
+        message: message,
+        center: true,
+      });
+    }
+    tableData.list = res.data.rows;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.name = "";
+  searchInput.phone = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+// 拒绝
+const refuse = () => {
+  dialongTitle.value = "拒绝审核";
+  addDialogVisible.value = true;
+  ruleForm.textarea = "";
+};
+
+// 取消拒绝
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+  ruleFormRef.value.resetFields();
+};
+// 确认添加员工
+const submitAdd = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      let data = {
+        user_name: ruleForm.name,
+        user_phone: ruleForm.phone,
+        user_zz: ruleForm.post,
+        id: ruleForm.id,
+      };
+      let res = await axios({
+        method: "post",
+        url: api.value + "/carBook/userupdate.action",
+        headers: {
+          "Content-Type": "application/json;charset=utf-8",
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      // console.log(res, "修改账号");
+      if (res.data.code == 200) {
+        getList();
+
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+        addDialogVisible.value = false;
+        ruleFormRef.value.resetFields();
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+// 通过
+const pass = (row) => {
+  ElMessageBox.confirm(`是否通过审核`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      // let data = new FormData();
+      // data.set("id", row.id);
+      // let res = await axios({
+      //   method: "post",
+      //   url: api.value + "/carBook/userdel.action",
+      //   headers: {
+      //     token: sessionStorage.getItem("token"),
+      //   },
+      //   data: data,
+      // });
+      // if (res.data.code == 200) {
+      //   if (tableData.list.length == 1 && currentPage.value != 1) {
+      //     currentPage.value = currentPage.value - 1;
+      //   }
+      //   getList();
+      //   ElMessage({
+      //     type: "success",
+      //     showClose: true,
+      //     message: res.data.message,
+      //     center: true,
+      //   });
+      // } else {
+      //   ElMessage({
+      //     type: "error",
+      //     showClose: true,
+      //     message: res.data.message,
+      //     center: true,
+      //   });
+      // }
+    })
+    .catch(() => {});
+};
+//导出功能
+const importExcel = async () => {
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  let data = new FormData();
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/usertoExcel.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  // console.log(res, "导出账号");
+  if (res.data.code == 200) {
+    // const elt = document.createElement("a");
+    // elt.setAttribute(
+    //   "href",
+    //   "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl
+    // );
+    // // elt.setAttribute("download", "file.xlsx");
+    // // elt.style.display = "none";
+    // document.body.appendChild(elt);
+    // elt.click();
+    var downloadPath = "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl;
+    console.log("获得地址数据:", downloadPath);
+    var downloadLink = document.createElement("a");
+    downloadLink.style.display = "none"; // 使其隐藏
+    downloadLink.href = downloadPath;
+    downloadLink.download = "";
+    downloadLink.click();
+    document.body.appendChild(downloadLink);
+    document.body.removeChild(downloadLink);
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 60px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        :deep(.el-input .el-input__inner) {
+          font-size: 16px;
+        }
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex: 1;
+    margin: 10px auto;
+    overflow: auto;
+
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 25px 20px 10px 20px;
+        .el-input {
+          width: 200px;
+        }
+        .options {
+          margin: 30px 0 10px 350px;
+          .el-form-item__content {
+            margin: 0 !important;
+          }
+        }
+      }
+    }
+  }
+  .el-pagination {
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 auto;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 704 - 0
src/views/driver/management.vue

@@ -0,0 +1,704 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">司机管理</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>司机姓名 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.name"
+            class="w-50 m-2"
+            placeholder="请输入司机姓名"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>手机号码 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入手机号码"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>车牌号 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入车牌号"
+            style="width: 150px"
+          />
+        </div>
+        <el-button
+          style="margin-left: 20px"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          style="margin-left: 20px !important"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          class="import"
+          type="primary"
+          @click="importExcel"
+          ><img
+            src="@/assets/import.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>导出表单</span></el-button
+        >
+      </div>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          type="index"
+          width="80"
+          align="center"
+          label="序号"
+          index="1"
+        />
+        <el-table-column align="center" prop="user_name" label="司机姓名" />
+        <el-table-column align="center" prop="user_phone" label="手机号码" />
+        <el-table-column align="center" prop="user_phone" label="车辆型号" />
+        <el-table-column align="center" prop="user_phone" label="颜色" />
+        <el-table-column align="center" prop="user_phone" label="车牌号" />
+        <el-table-column align="center" prop="user_phone" label="接单状态" />
+        <el-table-column align="center" prop="user_phone" label="保证金" />
+        <el-table-column align="center" prop="user_phone" label="订单数量" />
+        <el-table-column align="center" prop="user_phone" label="保证金" />
+        <el-table-column align="center" prop="user_zz" label="订单数量" />
+        <el-table-column align="center" prop="create_time" label="审核时间" />
+        <el-table-column align="center" prop="create_time" label="创建时间" />
+        <el-table-column align="center" label="操作" width="320">
+          <template #default="scope">
+            <el-button link type="primary" @click="money(scope.row)"
+              ><div class="look">保证金明细</div></el-button
+            >
+            <el-button link type="primary" @click="account(scope.row)"
+              ><div class="look">司机账户明细</div></el-button
+            >
+            <el-button link type="danger" @click="banned(scope.row)"
+              ><div class="looks">封禁</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 保证金明细 -->
+      <el-dialog
+        class="addStaff"
+        v-model="addDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        title="保证金明细"
+        align-center
+        width="1250"
+        :before-close="cancelAdd"
+      >
+        <el-table
+          :row-class-name="tableRowClassName"
+          :data="tableData.list"
+          @selection-change="handleSelectionChange"
+          style="width: 100%"
+          :header-cell-style="{
+            background: 'rgba(240, 243, 247, 1)',
+            height: '50px',
+            border: 0,
+          }"
+        >
+          <el-table-column
+            type="index"
+            width="100"
+            align="center"
+            label="序号"
+            index="1"
+          />
+          <el-table-column align="center" prop="user_name" label="保证金" />
+          <el-table-column align="center" prop="user_phone" label="标题" />
+          <el-table-column align="center" prop="user_phone" label="内容" />
+          <el-table-column align="center" prop="create_time" label="创建时间" />
+          <el-table-column align="center" prop="create_time" label="状态" />
+        </el-table>
+        <el-pagination
+          background
+          :current-page="currentPage1"
+          :page-size="pageSize1"
+          layout="total, prev, pager, next, jumper, slot"
+          :total="total1"
+          @update:current-page="handleCurrentChange1"
+        />
+      </el-dialog>
+
+      <!-- 司机账户明细 -->
+      <el-dialog
+        class="accountStaff"
+        v-model="accountDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        title="司机账户明细"
+        align-center
+        width="1250"
+        :before-close="cancelAccount"
+      >
+        <div class="money">
+          <span>可提现金额</span>
+          <span>400元</span>
+        </div>
+        <div class="table">
+          <el-table
+            :row-class-name="tableRowClassName"
+            :data="tableData.list"
+            @selection-change="handleSelectionChange"
+            style="width: 100%"
+            :header-cell-style="{
+              background: 'rgba(240, 243, 247, 1)',
+              height: '50px',
+              border: 0,
+            }"
+          >
+            <el-table-column
+              type="index"
+              width="100"
+              align="center"
+              label="序号"
+              index="1"
+            />
+            <el-table-column align="center" prop="user_phone" label="标题" />
+            <el-table-column align="center" prop="user_phone" label="内容" />
+            <el-table-column align="center" prop="create_time" label="金额" />
+            <el-table-column
+              align="center"
+              prop="create_time"
+              label="创建时间"
+            />
+          </el-table>
+          <el-pagination
+            background
+            :current-page="currentPage2"
+            :page-size="pageSize2"
+            layout="total, prev, pager, next, jumper, slot"
+            :total="total2"
+            @update:current-page="handleCurrentChange2"
+          />
+        </div>
+      </el-dialog>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增驾驶员"); // 弹窗标题
+const api = ref("");
+const searchInput = reactive({
+  name: "",
+  phone: "",
+  createTime: "",
+}); // 搜索按钮数据
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(10); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+const currentPage1 = ref(1); // 当前页
+const pageSize1 = ref(10);
+const total1 = ref(10); // 当前总数
+
+const accountDialogVisible = ref(false); // 控制添加员工弹窗
+const currentPage2 = ref(1); // 当前页
+const pageSize2 = ref(10);
+const total2 = ref(10); // 当前总数
+
+// 获取摄像头列表
+const getList = async (message) => {
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime); //前面的key记得对应!
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userlist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    if (message) {
+      ElMessage({
+        type: "success",
+        showClose: true,
+        message: message,
+        center: true,
+      });
+    }
+    tableData.list = res.data.rows;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.name = "";
+  searchInput.phone = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+// 保证金明细
+const money = () => {
+  addDialogVisible.value = true;
+};
+// 取消保证金明细
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+};
+
+// 司机账户明细
+const account = () => {
+  accountDialogVisible.value = true;
+};
+// 取消保证金明细
+const cancelAccount = () => {
+  accountDialogVisible.value = false;
+};
+
+// 通过
+const banned = (row) => {
+  ElMessageBox.confirm(`是否封禁`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      // let data = new FormData();
+      // data.set("id", row.id);
+      // let res = await axios({
+      //   method: "post",
+      //   url: api.value + "/carBook/userdel.action",
+      //   headers: {
+      //     token: sessionStorage.getItem("token"),
+      //   },
+      //   data: data,
+      // });
+      // if (res.data.code == 200) {
+      //   if (tableData.list.length == 1 && currentPage.value != 1) {
+      //     currentPage.value = currentPage.value - 1;
+      //   }
+      //   getList();
+      //   ElMessage({
+      //     type: "success",
+      //     showClose: true,
+      //     message: res.data.message,
+      //     center: true,
+      //   });
+      // } else {
+      //   ElMessage({
+      //     type: "error",
+      //     showClose: true,
+      //     message: res.data.message,
+      //     center: true,
+      //   });
+      // }
+    })
+    .catch(() => {});
+};
+//导出功能
+const importExcel = async () => {
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  let data = new FormData();
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/usertoExcel.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  // console.log(res, "导出账号");
+  if (res.data.code == 200) {
+    // const elt = document.createElement("a");
+    // elt.setAttribute(
+    //   "href",
+    //   "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl
+    // );
+    // // elt.setAttribute("download", "file.xlsx");
+    // // elt.style.display = "none";
+    // document.body.appendChild(elt);
+    // elt.click();
+    var downloadPath = "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl;
+    console.log("获得地址数据:", downloadPath);
+    var downloadLink = document.createElement("a");
+    downloadLink.style.display = "none"; // 使其隐藏
+    downloadLink.href = downloadPath;
+    downloadLink.download = "";
+    downloadLink.click();
+    document.body.appendChild(downloadLink);
+    document.body.removeChild(downloadLink);
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList();
+};
+// 分页
+const handleCurrentChange1 = (value) => {
+  // console.log(value);
+  currentPage1.value = value;
+  getList();
+};
+// 分页
+const handleCurrentChange2 = (value) => {
+  // console.log(value);
+  currentPage2.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 60px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        :deep(.el-input .el-input__inner) {
+          font-size: 16px;
+        }
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex: 1;
+    margin: 10px auto;
+    overflow: auto;
+
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 25px 25px 10px 25px;
+        
+      }
+    }
+
+    :deep(.accountStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 25px 25px 10px 25px;
+        display: flex;
+        .money {
+          width: 180px;
+          height: 100px;
+          border: 1px solid #000;
+          margin-right: 20px;
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          justify-content: center;
+        }
+        .table {
+          flex: 1;
+        }
+        .el-table--fit {
+          height: 600px;
+        }
+      }
+    }
+  }
+  .el-pagination {
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 auto;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+// .el-input {
+//   width: 192px;
+// }
+</style>

+ 641 - 0
src/views/driver/order.vue

@@ -0,0 +1,641 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">订单管理</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>状态 : </span>
+          <el-select
+            style="width: 180px"
+            v-model="searchInput.car_number"
+            class="m-2"
+            placeholder="请选择状态"
+            :clearable="true"
+          >
+            <el-option label="全部" value="全部" />
+            <el-option label="队列中" value="队列中" />
+            <el-option label="待出发" value="待出发" />
+            <el-option label="行程中" value="行程中" />
+            <el-option label="已完成" value="已完成" />
+            <el-option label="已取消" value="已取消" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>用户手机号 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入用户手机号"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>出发地 : </span>
+          <el-select
+            style="width: 180px"
+            v-model="searchInput.car_number"
+            class="m-2"
+            placeholder="请选择出发地"
+            :clearable="true"
+          >
+            <el-option label="全部" value="全部" />
+            <el-option label="队列中" value="队列中" />
+            <el-option label="待出发" value="待出发" />
+            <el-option label="行程中" value="行程中" />
+            <el-option label="已完成" value="已完成" />
+            <el-option label="已取消" value="已取消" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>目的地 : </span>
+          <el-select
+            style="width: 180px"
+            v-model="searchInput.car_number"
+            class="m-2"
+            placeholder="请选择目的地"
+            :clearable="true"
+          >
+            <el-option label="全部" value="全部" />
+            <el-option label="队列中" value="队列中" />
+            <el-option label="待出发" value="待出发" />
+            <el-option label="行程中" value="行程中" />
+            <el-option label="已完成" value="已完成" />
+            <el-option label="已取消" value="已取消" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>订单号 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入订单号"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>司机姓名 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入司机姓名"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>司机手机号 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入司机手机号"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>车牌号 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入车牌号"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>乘车时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="datetimerange"
+            format="YYYY-MM-DD HH:mm:ss"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            range-separator="-"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
+            :prefix-icon="Calendar"
+          />
+        </div>
+      </div>
+      <!-- 按钮列表 -->
+      <div class="gongneng">
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          class="import"
+          type="primary"
+          @click="importExcel"
+          ><img
+            src="@/assets/import.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>导出表单</span></el-button
+        >
+      </div>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          type="index"
+          width="80"
+          align="center"
+          label="序号"
+          index="1"
+        />
+        <el-table-column align="center" prop="user_name" label="用户手机号" />
+        <el-table-column
+          align="center"
+          prop="user_zz"
+          label="出发地"
+        />
+        <el-table-column align="center" prop="user_phone" label="目的地" />
+        <el-table-column align="center" prop="user_phone" width="200" label="乘车时间" />
+        <el-table-column align="center" prop="user_phone" label="乘车人数" />
+        <el-table-column align="center" prop="user_phone" width="200"  label="报名时间" />
+        <el-table-column align="center" prop="user_phone" label="订单号" />
+        <el-table-column align="center" prop="user_phone" label="订单价格" />
+        <el-table-column align="center" prop="user_phone" width="200"  label="司机接单时间" />
+        <el-table-column align="center" prop="user_phone" label="司机姓名" />
+        <el-table-column align="center" prop="user_phone" label="司机手机号" />
+        <el-table-column align="center" prop="user_phone" label="车辆型号" />
+        <el-table-column align="center" prop="user_phone" label="车辆颜色" />
+        <el-table-column align="center" prop="user_phone" label="车牌号" />
+        <el-table-column align="center" prop="user_phone" width="200"  label="行程开始时间" />
+        <el-table-column align="center" prop="user_phone" width="200"  label="行程结束时间" />
+        <el-table-column align="center" prop="user_phone" label="状态" />
+        <el-table-column align="center" label="操作" width="220">
+          <template #default="scope">
+            <el-button link type="primary" @click="depart(scope.row)"
+              ><div class="look">发车</div></el-button
+            >
+            <el-button link type="danger" @click="departCancel(scope.row)"
+              ><div class="looks">取消</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增驾驶员"); // 弹窗标题
+const api = ref("");
+const searchInput = reactive({
+  name: "",
+  phone: "",
+  createTime: "",
+}); // 搜索按钮数据
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+
+// 获取摄像头列表
+const getList = async (message) => {
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime); //前面的key记得对应!
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  // let res = await adminApi.adminLogin(data);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userlist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    if (message) {
+      ElMessage({
+        type: "success",
+        showClose: true,
+        message: message,
+        center: true,
+      });
+    }
+    // ElMessage({
+    //   type: "success",
+    //   showClose: true,
+    //   message: res.data.message,
+    //   center: true,
+    // });
+    tableData.list = res.data.rows;
+    // currentPage.value = res.data.currentPage;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+  // console.log(res);
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.name = "";
+  searchInput.phone = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+
+//删除按钮
+const departCancel = (row) => {
+  ElMessageBox.confirm(`是否取消此订单?`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      // let data = new FormData();
+      // data.set("id", row.id);
+      // let res = await axios({
+      //   method: "post",
+      //   url: api.value + "/carBook/userdel.action",
+      //   headers: {
+      //     token: sessionStorage.getItem("token"),
+      //   },
+      //   data: data,
+      // });
+      // if (res.data.code == 200) {
+      //   if (tableData.list.length == 1 && currentPage.value != 1) {
+      //     currentPage.value = currentPage.value - 1;
+      //   }
+      //   getList();
+      //   ElMessage({
+      //     type: "success",
+      //     showClose: true,
+      //     message: res.data.message,
+      //     center: true,
+      //   });
+      // } else {
+      //   ElMessage({
+      //     type: "error",
+      //     showClose: true,
+      //     message: res.data.message,
+      //     center: true,
+      //   });
+      // }
+    })
+    .catch(() => {
+      
+    });
+};
+//导出功能
+const importExcel = async () => {
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  let data = new FormData();
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/usertoExcel.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  // console.log(res, "导出账号");
+  if (res.data.code == 200) {
+    // const elt = document.createElement("a");
+    // elt.setAttribute(
+    //   "href",
+    //   "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl
+    // );
+    // // elt.setAttribute("download", "file.xlsx");
+    // // elt.style.display = "none";
+    // document.body.appendChild(elt);
+    // elt.click();
+    var downloadPath = "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl;
+    console.log("获得地址数据:", downloadPath);
+    var downloadLink = document.createElement("a");
+    downloadLink.style.display = "none"; // 使其隐藏
+    downloadLink.href = downloadPath;
+    downloadLink.download = "";
+    downloadLink.click();
+    document.body.appendChild(downloadLink);
+    document.body.removeChild(downloadLink);
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 60px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        :deep(.el-input .el-input__inner) {
+          font-size: 16px;
+        }
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex:1;
+    margin: 10px auto;
+    overflow: auto;
+    
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 30px 20px 10px 20px;
+        .el-input {
+          width: 200px;
+        }
+        .options {
+          margin-left: 320px;
+        }
+      }
+    }
+  }
+  .el-pagination {
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 auto;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 835 - 0
src/views/driver/path.vue

@@ -0,0 +1,835 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">路线管理</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>地点 : </span>
+          <el-select
+            v-model="searchInput.phone"
+            multiple
+            collapse-tags
+            collapse-tags-tooltip
+            :max-collapse-tags="3"
+            placeholder="请选择地点"
+            style="width: 240px"
+          >
+            <el-option label="全部" value="全部" />
+            <el-option label="待审核" value="待审核" />
+            <el-option label="审核成功" value="审核成功" />
+            <el-option label="拒绝" value="拒绝" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>状态 : </span>
+          <el-select
+            style="width: 180px"
+            v-model="searchInput.car_number"
+            class="m-2"
+            placeholder="请选择状态"
+            :clearable="true"
+          >
+            <el-option label="全部" value="全部" />
+            <el-option label="待审核" value="待审核" />
+            <el-option label="审核成功" value="审核成功" />
+            <el-option label="拒绝" value="拒绝" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>出发地 : </span>
+          <el-select
+            style="width: 180px"
+            v-model="searchInput.car_number"
+            class="m-2"
+            placeholder="请选择出发地"
+            :clearable="true"
+          >
+            <el-option label="全部" value="全部" />
+            <el-option label="待审核" value="待审核" />
+            <el-option label="审核成功" value="审核成功" />
+            <el-option label="拒绝" value="拒绝" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>目的地 : </span>
+          <el-select
+            style="width: 180px"
+            v-model="searchInput.car_number"
+            class="m-2"
+            placeholder="请选择目的地"
+            :clearable="true"
+          >
+            <el-option label="全部" value="全部" />
+            <el-option label="待审核" value="待审核" />
+            <el-option label="审核成功" value="审核成功" />
+            <el-option label="拒绝" value="拒绝" />
+          </el-select>
+        </div>
+        <div class="condition">
+          <span>创建时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="date"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            :prefix-icon="Calendar"
+            placeholder="请选择日期"
+          />
+        </div>
+      </div>
+      <!-- 按钮列表 -->
+      <div class="gongneng">
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          style="margin-left: 10px !important"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          class="import"
+          type="primary"
+          @click="importExcel"
+          ><img
+            src="@/assets/import.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>导出表单</span></el-button
+        >
+        <el-button
+          style="margin-left: 10px !important"
+          type="primary"
+          color="rgba(61, 81, 232, 1)"
+          @click="addlist"
+          ><el-icon><CirclePlus /></el-icon><span>新增路线</span></el-button
+        >
+      </div>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          type="index"
+          width="100"
+          align="center"
+          label="序号"
+          index="1"
+        />
+        <el-table-column align="center" prop="user_name" label="出发地" />
+        <el-table-column align="center" prop="user_zz" label="目的地" />
+        <el-table-column align="center" prop="user_phone" label="每人车费" />
+        <el-table-column align="center" prop="create_time" label="创建时间" />
+
+        <el-table-column align="center" label="操作" width="220">
+          <template #default="scope">
+            <el-button link type="primary" @click="edit(scope.row)"
+              ><div class="look">编辑</div></el-button
+            >
+            <el-button link type="danger" @click="del(scope.row)"
+              ><div class="looks">删除</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 添加员工弹窗 -->
+      <el-dialog
+        class="addStaff"
+        v-model="addDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :title="dialongTitle"
+        align-center
+        width="509"
+        :before-close="cancelAdd"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="100px"
+          class="demo-ruleForm"
+          :size="formSize"
+          label-position="left"
+          status-icon
+        >
+          <el-form-item label="出发地 :" prop="name">
+            <el-select
+              style="width: 180px"
+              v-model="searchInput.car_number"
+              class="m-2"
+              placeholder="请选择出发地"
+              :clearable="true"
+            >
+              <el-option label="全部" value="全部" />
+              <el-option label="待审核" value="待审核" />
+              <el-option label="审核成功" value="审核成功" />
+              <el-option label="拒绝" value="拒绝" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="目的地 :" prop="cardnumber">
+            <el-select
+              style="width: 180px"
+              v-model="searchInput.car_number"
+              class="m-2"
+              placeholder="请选择目的地"
+              :clearable="true"
+            >
+              <el-option label="全部" value="全部" />
+              <el-option label="待审核" value="待审核" />
+              <el-option label="审核成功" value="审核成功" />
+              <el-option label="拒绝" value="拒绝" />
+            </el-select>
+          </el-form-item>
+
+          <el-form-item label="每人车费 :">
+            <el-input
+              v-model="ruleForm.phone"
+              placeholder="请输入每人车费"
+              clearable
+            />
+          </el-form-item>
+
+          <el-form-item class="options">
+            <el-button
+              color="rgba(61, 81, 232, 1)"
+              class="queding"
+              type="primary"
+              @click="submitAdd(ruleFormRef)"
+            >
+              确定
+            </el-button>
+            <el-button class="congzhi" @click="cancelAdd(ruleFormRef)"
+              >取消</el-button
+            >
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增驾驶员"); // 弹窗标题
+const api = ref("");
+const searchInput = reactive({
+  name: "",
+  phone: "",
+  createTime: "",
+}); // 搜索按钮数据
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  name: "",
+  phone: "",
+  post: "0",
+  cardnumber: "",
+  id: "",
+});
+// 表单验证
+const rules = reactive({
+  name: [
+    { required: true, message: "姓名不能为空", trigger: "blur" },
+    {
+      pattern: /[\u4e00-\u9fa5]$/,
+      message: "请输入正确姓名",
+      trigger: "blur",
+    },
+  ],
+  // /^[\u4E00-\u9FA5]$/
+  cardnumber: [
+    { required: true, message: "卡号不能为空", trigger: "blur" },
+    // {
+    //   // pattern: /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/,
+    //   // pattern: /^[0-9]*$/,
+    //   message: "请输入正确卡号(数字类型)",
+    //   trigger: "blur",
+    // },
+  ],
+  phone: [
+    { required: true, message: "请输入手机号", trigger: "blur" },
+    {
+      // pattern: /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/,
+      pattern: /^((\(\+86\))|(\(86\)))?[1][3456789][0-9]{9}$/,
+      message: "请输入合法手机号/电话号",
+      trigger: "blur",
+    },
+  ],
+  post: [
+    {
+      required: true,
+      message: "职位不能为空",
+      trigger: "blur",
+    },
+  ],
+
+  // desc: [{ required: true, message: "Please input activity form", trigger: "blur" }],
+});
+// 获取摄像头列表
+const getList = async (message) => {
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime); //前面的key记得对应!
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  // let res = await adminApi.adminLogin(data);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userlist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    if (message) {
+      ElMessage({
+        type: "success",
+        showClose: true,
+        message: message,
+        center: true,
+      });
+    }
+    // ElMessage({
+    //   type: "success",
+    //   showClose: true,
+    //   message: res.data.message,
+    //   center: true,
+    // });
+    tableData.list = res.data.rows;
+    // currentPage.value = res.data.currentPage;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+  // console.log(res);
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.name = "";
+  searchInput.phone = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+// 添加员工
+const addlist = () => {
+  dialongTitle.value = "新增路线";
+  addDialogVisible.value = true;
+  ruleForm.name = "";
+  ruleForm.phone = "";
+  ruleForm.post = "";
+  ruleForm.cardnumber = "";
+};
+//编辑按钮
+const edit = (row) => {
+  dialongTitle.value = "编辑驾驶员";
+  addDialogVisible.value = true;
+  console.log(row);
+  ruleForm.name = row.user_name;
+  ruleForm.phone = row.user_phone;
+  ruleForm.post = row.user_zz;
+  ruleForm.id = row.id;
+};
+// 取消添加员工
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+  ruleFormRef.value.resetFields();
+};
+// 确认添加员工
+const submitAdd = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (dialongTitle.value == "新增驾驶员") {
+        let data = {
+          user_name: ruleForm.name,
+          user_phone: ruleForm.phone,
+          user_zz: ruleForm.post,
+          card_number: ruleForm.cardnumber,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/userinsert.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "添加账号");
+        if (res.data.code == 200) {
+          getList();
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      } else {
+        let data = {
+          user_name: ruleForm.name,
+          user_phone: ruleForm.phone,
+          user_zz: ruleForm.post,
+          id: ruleForm.id,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/userupdate.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "修改账号");
+        if (res.data.code == 200) {
+          getList();
+
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+//删除按钮
+const del = (row) => {
+  ElMessageBox.confirm(`是否删除 ${row.user_name} 驾驶员?`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      let data = new FormData();
+      data.set("id", row.id);
+      // let res = await adminApi.adminLogin(data);
+      let res = await axios({
+        method: "post",
+        url: api.value + "/carBook/userdel.action",
+        headers: {
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      if (res.data.code == 200) {
+        if (tableData.list.length == 1 && currentPage.value != 1) {
+          currentPage.value = currentPage.value - 1;
+        }
+        getList();
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+      console.log(res);
+    })
+    .catch(() => {
+      ElMessage({
+        type: "info",
+        message: "已取消删除",
+      });
+    });
+};
+//导出功能
+const importExcel = async () => {
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  let data = new FormData();
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/usertoExcel.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  // console.log(res, "导出账号");
+  if (res.data.code == 200) {
+    // const elt = document.createElement("a");
+    // elt.setAttribute(
+    //   "href",
+    //   "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl
+    // );
+    // // elt.setAttribute("download", "file.xlsx");
+    // // elt.style.display = "none";
+    // document.body.appendChild(elt);
+    // elt.click();
+    var downloadPath = "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl;
+    console.log("获得地址数据:", downloadPath);
+    var downloadLink = document.createElement("a");
+    downloadLink.style.display = "none"; // 使其隐藏
+    downloadLink.href = downloadPath;
+    downloadLink.download = "";
+    downloadLink.click();
+    document.body.appendChild(downloadLink);
+    document.body.removeChild(downloadLink);
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 60px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        :deep(.el-input .el-input__inner) {
+          font-size: 16px;
+        }
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex: 1;
+    margin: 10px auto;
+    overflow: auto;
+
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 30px 20px 10px 20px;
+        .el-input {
+          width: 200px;
+        }
+        .options {
+          .el-form-item__content {
+            margin: 0 !important;
+            display: flex;
+            flex-direction: row-reverse;
+            .queding {
+              margin-left: 10px;
+            }
+          }
+        }
+      }
+    }
+  }
+  .el-pagination {
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 auto;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 439 - 0
src/views/driver/rule copy.vue

@@ -0,0 +1,439 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">规则设置</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <h3>可约车时间段设置</h3>
+          <div>
+            <span>约车时间段</span>
+            <el-time-picker
+              v-model="ruleForm.startTime"
+              is-range
+              range-separator="-"
+              start-placeholder="开始时间"
+              end-placeholder="结束时间"
+              format="HH:mm"
+              value-format="HH:mm"
+            />
+          </div>
+        </div>
+        <div class="condition">
+          <h3>截至取消订单时间设置</h3>
+          <div>
+            <span>乘车时间前</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.time"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>&nbsp;&nbsp;分钟</span>
+          </div>
+        </div>
+        <div class="condition">
+          <h3>顺风车须知设置</h3>
+          <div>
+            <el-input
+              v-model="ruleForm.startTime"
+              style="width: 500px"
+              :rows="5"
+              type="textarea"
+              placeholder="请输入内容"
+            />
+          </div>
+        </div>
+        <div class="condition">
+          <h3>客服联系方式设置</h3>
+          <div>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.black_count"
+              class="w-50 m-2"
+              style="width: 220px"
+              placeholder="请输入联系方式"
+            />
+          </div>
+        </div>
+        
+        <div class="condition">
+          <h3>顺风车服务条款设置</h3>
+          <div>
+            <el-input
+              v-model="ruleForm.startTime"
+              style="width: 500px"
+              :rows="5"
+              type="textarea"
+              placeholder="请输入内容"
+            />
+          </div>
+        </div>
+        <div class="condition">
+          <h3>司机取消订单保证金扣款规则设置</h3>
+          <div>
+            <span>司机取消订单,扣当前订单的</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.notice_time"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>(如0.25则是抽当前订单支付金额的25%,保留2位小数)</span>
+          </div>
+          <div style="margin: 10px 0">
+            <span>保证金低于</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.notice_time"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>&nbsp;&nbsp;则不能接单,需补交保证金</span>
+          </div>
+        </div>
+        <div class="condition">
+          <h3>用户取消订单违约金规则设置</h3>
+          <div>
+            <span>司机取消订单,扣当前订单的</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.notice_time"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>(如0.25则是抽当前订单支付金额的25%,保留2位小数)</span>
+          </div>
+        </div>
+        <div class="condition">
+          <h3>保证金规则设置</h3>
+          <div>
+            <span>保证金退款</span>
+            <div>
+              <el-input
+                v-model="ruleForm.startTime"
+                style="width: 500px"
+                :rows="5"
+                type="textarea"
+                placeholder="请输入保证金"
+              />
+            </div>
+          </div>
+          <div style="margin: 10px 0">
+            <span>保证金缴纳</span>
+            <div>
+              <el-input
+                v-model="ruleForm.startTime"
+                style="width: 500px"
+                :rows="5"
+                type="textarea"
+                placeholder="请输入保证金"
+              />
+            </div>
+          </div>
+          <div>
+            <span>充值保证金</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.notice_time"
+              class="w-50 m-2"
+              style="width: 100px"
+            />
+          </div>
+        </div>
+        <div class="condition">
+          <h3>提现设置</h3>
+          <div>
+            <span>提现时平台技术服务费抽成</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.notice_time"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>(如0.25则是抽当前订单支付金额的25%,保留2位小数)</span>
+          </div>
+          <div style="margin: 10px 0">
+            <span>提现最低额度</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.notice_time"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>&nbsp;&nbsp;元(保留2位小数)</span>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="footer"></div>
+  </div>
+</template>
+
+<script setup>
+import {
+  ref,
+  reactive,
+  watch,
+  nextTick,
+  onBeforeMount,
+  onUnmounted,
+} from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const api = ref("");
+const router = useRouter();
+// 表格数据
+const ruleForm = reactive({
+  time: "",
+  yy_duration: "",
+  hh_end: "", //截止预约时间设置
+  yy_end: "", //候补截止预约时间设置
+  black_count: "", //黑名单设置次数
+  notice_time: "", //发车前提前
+  startTime: "", // 扫码前时间
+  endTime: "", // 扫码后时间
+  scanInterval: "", // 扫码间隔
+  bb_before: "", // 报备人预约车辆时间设置
+  id: "",
+});
+
+// 获取系统设置数据
+const getlist = async (message) => {
+  // let res = await axios({
+  //   method: "post",
+  //   url: api.value + "/carBook/cnqueryHb.action",
+  //   headers: {
+  //     token: sessionStorage.getItem("token"),
+  //   },
+  // });
+  // console.log(res);
+  // if (res.data.code == 200) {
+  //   if (message) {
+  //     ElMessage({
+  //       type: "success",
+  //       showClose: true,
+  //       message: message,
+  //       center: true,
+  //     });
+  //   }
+  // } else {
+  //   ElMessage({
+  //     type: "error",
+  //     showClose: true,
+  //     message: res.data.message,
+  //     center: true,
+  //   });
+  //   if (res.data.message == "token错误") {
+  //     router.push({
+  //       path: `/login`,
+  //     });
+  //   }
+  // }
+};
+const getTimeList = async () => {
+  // let res = await axios({
+  //   method: "post",
+  //   url: api.value + "/carBook/weekConfigqueryList.action",
+  //   headers: {
+  //     token: sessionStorage.getItem("token"),
+  //   },
+  // });
+  // console.log(res, "开始时间段配置");
+  // if (res.data.code == 200) {
+  //   let resData = res.data.data;
+  // } else {
+  //   ElMessage({
+  //     type: "error",
+  //     showClose: true,
+  //     message: res.data.message,
+  //     center: true,
+  //   });
+  //   if (res.data.message == "token错误") {
+  //     router.push({
+  //       path: `/login`,
+  //     });
+  //   }
+  // }
+};
+
+// 页面数据一修改就调用函数
+const timeVerify = (val) => {
+  const regex = /^[0-9]+$/;
+  if (regex.test(val)) {
+    // timeUpdata();
+  } else {
+    // getlist();
+    ElMessage({
+      type: "warning",
+      showClose: true,
+      message: "请输入正确数值",
+      center: true,
+    });
+  }
+};
+const timeUpdata = async () => {
+  // let data = {
+  //   yy_duration: ruleForm.yy_duration,
+  //   scanInterval: ruleForm.scanInterval,
+  //   yy_end: ruleForm.yy_end,
+  //   hh_end: ruleForm.hh_end,
+  //   black_count: ruleForm.black_count,
+  //   notice_time: ruleForm.notice_time,
+  //   sm_start: ruleForm.startTime,
+  //   sm_end: ruleForm.endTime,
+  //   bb_before: ruleForm.bb_before,
+  //   id: ruleForm.id,
+  // };
+  // let res = await axios({
+  //   method: "post",
+  //   url: api.value + "/carBook/cnupdate.action",
+  //   headers: {
+  //     "Content-Type": "application/json;charset=utf-8",
+  //     token: sessionStorage.getItem("token"),
+  //   },
+  //   data: data,
+  // });
+  // console.log(res, "修改候补");
+  // if (res.data.code == 200) {
+  //   // getlist();
+  //   store.dispatch("sm_time");
+  //   ElMessage({
+  //     type: "success",
+  //     showClose: true,
+  //     message: res.data.message,
+  //     center: true,
+  //   });
+  // } else {
+  //   getlist();
+  //   ElMessage({
+  //     type: "error",
+  //     showClose: true,
+  //     message: "修改失败",
+  //     center: true,
+  //   });
+  // }
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getlist();
+  getTimeList();
+});
+onUnmounted(() => {});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    // width: calc(100wh - 40px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    height: calc(100% - 60px);
+    overflow: auto;
+    margin: 0 auto;
+    color: #000;
+
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      flex-direction: column;
+      .condition {
+        display: flex;
+        flex-direction: column;
+        margin: 10px 30px 10px 0;
+        h3 {
+          margin: 12px 12px 12px 0;
+        }
+        span {
+          margin: 0 10px 0 0;
+          font-size: 18px;
+          color: #000;
+        }
+        .addTime {
+          display: flex;
+          align-items: center;
+          .el-checkbox-group {
+            .el-checkbox {
+              margin: 0 15px 0 0;
+            }
+          }
+          :deep(.timePicker) {
+            width: 200px;
+          }
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+    .footer {
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 525 - 0
src/views/driver/rule.vue

@@ -0,0 +1,525 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">规则设置</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="0"
+          class="demo-ruleForm"
+          :size="formSize"
+          label-position="left"
+          status-icon
+        >
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <h3 style="margin: 12px 0">可约车时间段设置</h3>
+              <div>
+                <span>约车时间段</span>
+                <el-time-picker
+                  v-model="ruleForm.startTime"
+                  is-range
+                  range-separator="-"
+                  start-placeholder="开始时间"
+                  end-placeholder="结束时间"
+                  format="HH:mm"
+                  value-format="HH:mm"
+                />
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="time">
+            <div class="condition">
+              <h3>截至取消订单时间设置</h3>
+              <div>
+                <span>乘车时间前</span>
+                <el-input
+                  :clearable="false"
+                  v-model="ruleForm.time"
+                  class="w-50 m-2"
+                  style="width: 100px"
+                />
+                <span>&nbsp;&nbsp;分钟</span>
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <h3>顺风车须知设置</h3>
+              <div>
+                <el-input
+                  v-model="ruleForm.startTime"
+                  style="width: 500px"
+                  :rows="5"
+                  type="textarea"
+                  placeholder="请输入内容"
+                />
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <h3>客服联系方式设置</h3>
+              <div>
+                <el-input
+                  :clearable="false"
+                  v-model="ruleForm.black_count"
+                  class="w-50 m-2"
+                  style="width: 220px"
+                  placeholder="请输入联系方式"
+                />
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <h3>顺风车服务条款设置</h3>
+              <div>
+                <el-input
+                  v-model="ruleForm.startTime"
+                  style="width: 500px"
+                  :rows="5"
+                  type="textarea"
+                  placeholder="请输入内容"
+                />
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <h3>司机取消订单保证金扣款规则设置</h3>
+              <div>
+                <span>司机取消订单,扣当前订单的</span>
+                <el-input
+                  :clearable="false"
+                  v-model="ruleForm.notice_time"
+                  class="w-50 m-2"
+                  style="width: 100px"
+                />
+                <span>(如0.25则是抽当前订单支付金额的25%,保留2位小数)</span>
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <div>
+                <span>保证金低于</span>
+                <el-input
+                  :clearable="false"
+                  v-model="ruleForm.notice_time"
+                  class="w-50 m-2"
+                  style="width: 100px"
+                />
+                <span>&nbsp;&nbsp;则不能接单,需补交保证金</span>
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <h3>用户取消订单违约金规则设置</h3>
+              <div>
+                <span>司机取消订单,扣当前订单的</span>
+                <el-input
+                  :clearable="false"
+                  v-model="ruleForm.notice_time"
+                  class="w-50 m-2"
+                  style="width: 100px"
+                />
+                <span>(如0.25则是抽当前订单支付金额的25%,保留2位小数)</span>
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <h3>保证金规则设置</h3>
+              <div>
+                <span>保证金退款</span>
+                <div>
+                  <el-input
+                    v-model="ruleForm.startTime"
+                    style="width: 500px"
+                    :rows="5"
+                    type="textarea"
+                    placeholder="请输入保证金"
+                  />
+                </div>
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <div>
+                <span>保证金缴纳</span>
+                <div>
+                  <el-input
+                    v-model="ruleForm.startTime"
+                    style="width: 500px"
+                    :rows="5"
+                    type="textarea"
+                    placeholder="请输入保证金"
+                  />
+                </div>
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <div>
+                <span>充值保证金</span>
+                <el-input
+                  :clearable="false"
+                  v-model="ruleForm.notice_time"
+                  class="w-50 m-2"
+                  style="width: 100px"
+                />
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="textarea">
+            <div class="condition">
+              <h3>提现设置</h3>
+              <div>
+                <span>提现时平台技术服务费抽成</span>
+                <el-input
+                  :clearable="false"
+                  v-model="ruleForm.notice_time"
+                  class="w-50 m-2"
+                  style="width: 100px"
+                />
+                <span>(如0.25则是抽当前订单支付金额的25%,保留2位小数)</span>
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="" prop="quota">
+            <div class="condition">
+              <div>
+                <span>提现最低额度</span>
+                <el-input
+                  :clearable="false"
+                  v-model="ruleForm.quota"
+                  class="w-50 m-2"
+                  style="width: 100px"
+                />
+                <span>&nbsp;&nbsp;元(保留2位小数)</span>
+              </div>
+            </div>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="footer">
+        <div class="options">
+          <el-button
+            color="rgba(61, 81, 232, 1)"
+            class="queding"
+            type="primary"
+            @click="edit"
+          >
+            修改
+          </el-button>
+          <el-button
+            color="rgba(61, 81, 232, 1)"
+            class="queding"
+            type="primary"
+            @click="submit(ruleFormRef)"
+          >
+            确定
+          </el-button>
+          <el-button class="congzhi" @click="cancel">取消</el-button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import {
+  ref,
+  reactive,
+  watch,
+  nextTick,
+  onBeforeMount,
+  onUnmounted,
+} from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const api = ref("");
+const router = useRouter();
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  time: "",
+  yy_duration: "",
+  hh_end: "", //截止预约时间设置
+  yy_end: "", //候补截止预约时间设置
+  black_count: "", //黑名单设置次数
+  notice_time: "", //发车前提前
+  startTime: "", // 扫码前时间
+  endTime: "", // 扫码后时间
+  scanInterval: "", // 扫码间隔
+  bb_before: "", // 报备人预约车辆时间设置
+  id: "",
+});
+// 表单验证
+const rules = reactive({
+  time: [
+    { required: true, message: "姓名不能为空", trigger: "blur" },
+    {
+      pattern: /^(0|[1-9]\d*)$/,
+      message: "请输入正确数字",
+      trigger: "blur",
+    },
+  ],
+  quota: [
+    { required: true, message: "额度不能为空", trigger: "blur" },
+    {
+      pattern: /^(?!0\d)\d+(?:\.\d{1,2})?$/,
+      message: "请输入正确额度",
+      trigger: "blur",
+    },
+  ],
+});
+
+// 获取系统设置数据
+const getlist = async (message) => {
+  // let res = await axios({
+  //   method: "post",
+  //   url: api.value + "/carBook/cnqueryHb.action",
+  //   headers: {
+  //     token: sessionStorage.getItem("token"),
+  //   },
+  // });
+  // console.log(res);
+  // if (res.data.code == 200) {
+  //   if (message) {
+  //     ElMessage({
+  //       type: "success",
+  //       showClose: true,
+  //       message: message,
+  //       center: true,
+  //     });
+  //   }
+  // } else {
+  //   ElMessage({
+  //     type: "error",
+  //     showClose: true,
+  //     message: res.data.message,
+  //     center: true,
+  //   });
+  //   if (res.data.message == "token错误") {
+  //     router.push({
+  //       path: `/login`,
+  //     });
+  //   }
+  // }
+};
+const getTimeList = async () => {
+  // let res = await axios({
+  //   method: "post",
+  //   url: api.value + "/carBook/weekConfigqueryList.action",
+  //   headers: {
+  //     token: sessionStorage.getItem("token"),
+  //   },
+  // });
+  // console.log(res, "开始时间段配置");
+  // if (res.data.code == 200) {
+  //   let resData = res.data.data;
+  // } else {
+  //   ElMessage({
+  //     type: "error",
+  //     showClose: true,
+  //     message: res.data.message,
+  //     center: true,
+  //   });
+  //   if (res.data.message == "token错误") {
+  //     router.push({
+  //       path: `/login`,
+  //     });
+  //   }
+  // }
+};
+
+const timeUpdata = async () => {
+  // let data = {
+  //   yy_duration: ruleForm.yy_duration,
+  //   scanInterval: ruleForm.scanInterval,
+  //   yy_end: ruleForm.yy_end,
+  //   hh_end: ruleForm.hh_end,
+  //   black_count: ruleForm.black_count,
+  //   notice_time: ruleForm.notice_time,
+  //   sm_start: ruleForm.startTime,
+  //   sm_end: ruleForm.endTime,
+  //   bb_before: ruleForm.bb_before,
+  //   id: ruleForm.id,
+  // };
+  // let res = await axios({
+  //   method: "post",
+  //   url: api.value + "/carBook/cnupdate.action",
+  //   headers: {
+  //     "Content-Type": "application/json;charset=utf-8",
+  //     token: sessionStorage.getItem("token"),
+  //   },
+  //   data: data,
+  // });
+  // console.log(res, "修改候补");
+  // if (res.data.code == 200) {
+  //   // getlist();
+  //   store.dispatch("sm_time");
+  //   ElMessage({
+  //     type: "success",
+  //     showClose: true,
+  //     message: res.data.message,
+  //     center: true,
+  //   });
+  // } else {
+  //   getlist();
+  //   ElMessage({
+  //     type: "error",
+  //     showClose: true,
+  //     message: "修改失败",
+  //     center: true,
+  //   });
+  // }
+};
+
+//编辑按钮
+const edit = () => {};
+// 取消
+const cancel = () => {
+  ruleFormRef.value.resetFields();
+};
+// 确认
+const submit = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getlist();
+  getTimeList();
+});
+onUnmounted(() => {});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    // width: calc(100wh - 40px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    height: calc(100% - 60px);
+    overflow: auto;
+    margin: 0 auto;
+    color: #000;
+
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      flex-direction: column;
+      .condition {
+        display: flex;
+        flex-direction: column;
+        margin: 0;
+        h3 {
+          font-size: 19px;
+          margin: 0px 12px 12px 0;
+        }
+        span {
+          margin: 0 10px 0 0;
+          font-size: 16px;
+          color: #000;
+        }
+        .addTime {
+          display: flex;
+          align-items: center;
+          .el-checkbox-group {
+            .el-checkbox {
+              margin: 0 15px 0 0;
+            }
+          }
+          :deep(.timePicker) {
+            width: 200px;
+          }
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+    .footer {
+      margin: 10px 0 25px 0;
+      .options {
+      }
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 517 - 0
src/views/log/log.vue

@@ -0,0 +1,517 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><UserFilled /></el-icon> -->
+      <span class="cameratxt">操作日志</span>
+    </div>
+
+    <div class="filter">
+      <div class="condition">
+        <span>操作日期 : </span>
+        <el-date-picker
+          type="date"
+          placeholder="请选择日期"
+          format="YYYY-MM-DD"
+          value-format="YYYY-MM-DD"
+          v-model="searchInput.create_time"
+        />
+      </div>
+
+      <div class="condition">
+        <span>车牌号 : </span>
+        <el-select
+          v-model="searchInput.car_number"
+          class="m-2"
+          placeholder="请选择车牌号"
+          :clearable="true"
+        >
+          <el-option
+            v-for="item in busNum.list"
+            :key="item"
+            :label="item.car_number"
+            :value="item.car_number"
+          />
+        </el-select>
+      </div>
+      <!-- <div class="condition">
+            <span>发车日期 : </span>
+          
+            <el-date-picker
+              type="date"
+              placeholder="请选择日期"
+              format="YYYY-MM-DD"
+              value-format="YYYY-MM-DD"
+              v-model="searchInput.s_date"
+            />
+          </div> -->
+      <el-button
+        color="rgba(61, 81, 232, 1)"
+        type="primary"
+        class="search"
+        @click="search"
+        ><el-icon><Search /></el-icon><span>搜索</span></el-button
+      >
+      <el-button
+        style="margin-left: 20px"
+        color="rgba(61, 81, 232, 1)"
+        type="primary"
+        class="search"
+        @click="resetSearch"
+        ><el-icon><Search /></el-icon><span>重置</span></el-button
+      >
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        style="width: 100%;"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          border: 0,
+        }"
+      >
+        <el-table-column
+          width="280"
+          align="center"
+          prop="create_time"
+          label="操作日期"
+        />
+        <el-table-column
+          align="center"
+          width="100"
+          prop="admin_name"
+          label="操作账号"
+        />
+        <el-table-column
+          align="center"
+          width="150"
+          prop="car_number"
+          label="车牌"
+        />
+        <el-table-column align="center" prop="record1" label="操作详情" />
+      </el-table>
+    </div>
+
+    <!-- 分页数据 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, watch, onBeforeMount, onMounted } from "vue";
+import { useRouter } from "vue-router";
+import { Select, Pointer, Upload } from "@element-plus/icons-vue";
+import { JSEncrypt } from "jsencrypt"; // 加密密码
+import { ElMessage, ElMessageBox } from "element-plus";
+import { dayjs } from "element-plus";
+import axios from "axios";
+import lodash from "lodash";
+import adminApi from "@/api/admin.js";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+const api = ref("");
+// 搜索框数据
+const searchInput = reactive({
+  startTime: "",
+  car_number: "",
+});
+
+const busNum = reactive({ list: [] }); // 车牌号
+
+// 表格数据
+const tableData = reactive({
+  list: [], //汇总数据
+});
+
+const pageSize = ref(10);
+const currentPage = ref(1); // 当前页
+const total = ref(10); // 当前总数
+
+// 获取数据列表
+const getList = async () => {
+  {
+    let data = new FormData();
+    let time = dayjs().format("YYYY-MM-DD");
+    console.log(searchInput.car_number);
+    console.log(searchInput.create_time == null);
+
+    if (searchInput.car_number) {
+      data.set("car_number", searchInput.car_number);
+    }
+    if (
+      typeof searchInput.create_time == "undefined" ||
+      searchInput.create_time == null
+    ) {
+      data.set("create_time", "");
+    } else {
+      data.set("create_time", searchInput.create_time);
+    }
+    data.set("page", currentPage.value);
+    data.set("rows", pageSize.value);
+    let res = await axios({
+      method: "post",
+      url: api.value + "/carBook/logslist.action",
+      headers: {
+        token: sessionStorage.getItem("token"),
+      },
+      data: data,
+    });
+    console.log(res, "操作日志");
+    if (res.status == 200) {
+      tableData.list = res.data.rows;
+      // currentPage.value = res.data.currentPage;
+      total.value = res.data.total;
+    } else {
+      tableData.list = res.data.rows;
+      currentPage.value = 1;
+      total.value = res.data.total;
+      ElMessage({
+        type: "error",
+        showClose: true,
+        message: res.data.message,
+        center: true,
+      });
+      if (res.data.message == "token错误") {
+        router.push({
+          path: `/login`,
+        });
+      }
+    }
+  }
+};
+
+// 搜索按钮
+const search = lodash.debounce(() => {
+  getList();
+}, 300);
+// 重置搜索框
+const resetSearch = lodash.debounce(() => {
+  searchInput.create_time = "";
+  searchInput.car_number = "";
+  getList();
+}, 300);
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  currentPage.value = value;
+  getList();
+};
+
+onMounted(() => {
+  api.value = store.state.user.api;
+  busNum.list = JSON.parse(sessionStorage.getItem("busSelect"));
+
+  getList();
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 60px);
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    height: 60px;
+    margin: 0 30px;
+    // padding: 10px 0;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+  }
+  .filter {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+
+    //   width: 100%;
+    .condition {
+      display: flex;
+      align-items: center;
+      margin: 15px 30px 15px 30px;
+      color: #000;
+      :deep(.el-input .el-input__inner) {
+        font-size: 16px;
+      }
+      span {
+        margin: 0 10px 0 0;
+      }
+    }
+  }
+  :deep(.sendBus) {
+    //   height: 420px;
+    border-radius: 11px;
+    .el-dialog__header {
+      border-radius: 11px 11px 0 0;
+      background: rgba(237, 241, 245, 1);
+      font-weight: 600;
+      margin: 0;
+      .el-dialog__headerbtn {
+        outline: none;
+      }
+    }
+    .el-dialog__body {
+      padding: 30px 20px 10px 20px;
+      .el-form-item--feedback {
+        .el-input__validateIcon {
+          color: rgba(61, 81, 232, 1);
+        }
+      }
+      .el-form-item.is-error .el-input__validateIcon {
+        color: red;
+      }
+      .el-input {
+        width: 200px;
+      }
+
+      .options {
+        margin-left: 200px;
+      }
+    }
+  }
+
+  :deep(.mergeBus) {
+    //   height: 420px;
+    border-radius: 11px;
+    /* 去掉全选按钮 */
+
+    .el-dialog__header {
+      border-radius: 11px 11px 0 0;
+      background: rgba(237, 241, 245, 1);
+      font-weight: 600;
+      margin: 0;
+
+      .el-dialog__headerbtn {
+        outline: none;
+      }
+    }
+    .el-dialog__body {
+      padding: 30px 20px 10px 20px;
+      .el-table__header {
+        font-size: 17px;
+      }
+      .el-table__body-wrapper {
+        .el-table__row {
+          height: 48px;
+          font-size: 17px;
+          color: #000;
+          td {
+            padding: 0;
+          }
+        }
+      }
+
+      .el-table__inner-wrapper::before {
+        height: 0;
+      }
+      .el-table__inner-wrapper {
+        .el-table__header-wrapper {
+          .el-table__header {
+            .disabledsele .cell .el-checkbox__inner {
+              display: none !important;
+            }
+            .disabledsele .cell::before {
+              content: "操作";
+              text-align: center;
+              line-height: 37px;
+            }
+          }
+        }
+      }
+
+      .el-form-item--feedback {
+        .el-input__validateIcon {
+          color: rgba(61, 81, 232, 1);
+        }
+      }
+      .el-form-item.is-error .el-input__validateIcon {
+        color: red;
+      }
+      .el-input {
+        width: 200px;
+      }
+
+      .options {
+        margin-left: 200px;
+      }
+    }
+
+    .btn {
+      width: 100%;
+      height: 40px;
+      margin-bottom: 20px;
+      display: flex;
+      flex-direction: row-reverse;
+      align-items: center;
+      justify-content: space-between;
+      .txt {
+        font-size: 18px;
+        color: #000;
+      }
+    }
+  }
+
+  .footer {
+    width: calc(100% - 60px);
+    flex:1;
+    margin: 10px auto 10px;
+    overflow: auto;
+    :deep(.el-table__header-wrapper) {
+      height: 48px;
+
+      .el-table__header {
+        height: 48px;
+        font-size: 16px;
+      }
+    }
+    .el-table--fit {
+      height: 100%;
+
+      :deep(.el-table__row) {
+        height: 48px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      :deep(.el-button) {
+        width: 50px;
+        height: 26px;
+        border-radius: 40px;
+        font-size: 15px;
+      }
+      :deep(.look) {
+        padding: 3px 10px;
+        border-radius: 40px;
+        // border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.lookcar) {
+        padding: 3px 10px;
+        border-radius: 40px;
+        // border: 0.74px solid #e6a23c;
+      }
+      :deep(.lookdel) {
+        padding: 3px 5px;
+        border-radius: 40px;
+        // border: 0.74px solid #fa7070;
+      }
+      // 输出链接弹窗样式
+      :deep(.link .el-dialog__header) {
+        text-align: left;
+        font-size: 20px;
+        font-weight: 600;
+      }
+      :deep(.link .el-dialog__body) {
+        padding: 10px 20px;
+        height: 100px;
+        margin-bottom: 10px;
+      }
+      .link {
+        .linkcontent {
+          text-align: left;
+          height: 100px;
+          border: 1px solid #ccc;
+          p {
+            margin: 5px 10px;
+          }
+        }
+      }
+
+      :deep(.playVideo .el-dialog__header) {
+        text-align: left;
+        font-size: 20px;
+        font-weight: 600;
+        background-color: #ccc;
+        margin-right: 0;
+      }
+      :deep(.playVideo .el-dialog__body) {
+        height: 600px;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+    }
+  }
+  .el-pagination {
+    // width: 1600px;
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 30px;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 303 - 0
src/views/login/index.vue

@@ -0,0 +1,303 @@
+<template>
+  <div class="box">
+    <!-- <div class="middle"></div> -->
+    <div class="left">
+      <div class="loginForm">
+        <div
+          style="
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            margin-top: 104px;
+            margin-bottom: 121px;
+          "
+        >
+          <img
+            src="@/assets/nanchang.png"
+            alt=""
+            style="width: 56px; height: 56px; margin-right: 10px"
+          />
+          <span
+            style="
+              font-size: 38px;
+              font-weight: 500;
+              letter-spacing: 0px;
+              color: rgba(0, 0, 0, 1);
+            "
+          >校团约车管理系统</span>
+        </div>
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          status-icon
+          :rules="rules"
+          label-width="120px"
+          class="demo-ruleForm"
+        >
+          <el-form-item label="" prop="user">
+            <el-input
+              :prefix-icon="User"
+              v-model="ruleForm.user"
+              placeholder="请输入登录名"
+              autocomplete="off"
+            />
+          </el-form-item>
+          <el-form-item label="" prop="pass">
+            <el-input
+              :prefix-icon="Lock"
+              show-password
+              v-model="ruleForm.pass"
+              type="password"
+              autocomplete="off"
+              placeholder="请输入登录密码"
+            />
+          </el-form-item>
+          <el-checkbox v-model="checked" class="remeberPwd el-form-item">
+            记住密码</el-checkbox
+          >
+          <el-form-item>
+            <el-button
+              :loading="loading"
+              type="primary"
+              @click="submitForm(ruleFormRef)"
+              >登录</el-button
+            >
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="rLogin">
+        <img src="@/assets/login3.png" alt="" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, onUnmounted } from "vue";
+import { User, Lock } from "@element-plus/icons-vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { JSEncrypt } from "jsencrypt"; // 加密密码
+import adminApi from "@/api/admin.js";
+import { useStore } from "vuex";
+import axios from "axios";
+
+const router = useRouter();
+const api = ref("");
+const store = useStore();
+const loading = ref(false);
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  user: "",
+  pass: "",
+});
+const checked = ref(false); // 记住密码
+
+const rules = reactive({
+  user: [{ required: true, message: "请填写用户名", trigger: "blur" }],
+  pass: [{ required: true, message: "请填写密码", trigger: "blur" }],
+});
+
+const submitForm = (formEl) => {
+  if (!formEl) return;
+  formEl.validate(async (valid) => {
+    if (valid) {
+      loading.value = true;
+      // let publicKey =
+      //   "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMOcPB06u5yKyQsPjfVWiWgbEIrd14kiXNNihciaVKb6HnkQvq7zpQuZ80WEX94spnUMI3iOAl/GmIvHrpGwcbB4hJbznm+PajiwnUSPuCCXA68YJF640cJKb/8KeM7WVz69OFkIEPHhVxOy4FFF5QWe/kt6zOZ19HmE+ak+5x/QIDAQAB";
+      // let encryptor = new JSEncrypt(); // 新建JSEncrypt对象
+      // encryptor.setPublicKey(publicKey); // 设置公钥
+      // let rsaPassWord = encryptor.encrypt(ruleForm.pass); // 对密码进行加密
+      // console.log(rsaPassWord);
+      // let logincontent = {
+      //   number: ruleForm.user,
+      //   password: ruleForm.pass,
+      // };
+      let data = new FormData();
+      data.set("number", ruleForm.user);
+      data.set("password", ruleForm.pass); //前面的key记得对应!
+      // let res = await adminApi.adminLogin(data);
+      let res = await axios({
+        method: "post",
+        url: api.value + "/carBook/adminlogin.action",
+        data: data,
+      });
+
+      console.log(res);
+      if (res.data.code == 200) {
+        if (checked.value) {
+          localStorage.setItem("user", ruleForm.user);
+          localStorage.setItem("pass", ruleForm.pass);
+        } else {
+          localStorage.removeItem("user", ruleForm.user);
+          localStorage.removeItem("pass", ruleForm.pass);
+        }
+        sessionStorage.setItem("token", res.data.access_token);
+        sessionStorage.setItem("username", res.data.data[0].number);
+        sessionStorage.setItem("sidevarItem", 9);
+        store.commit("indexUp", 9);
+        store.commit("userName", res.data.data[0].number);
+        store.commit("passWord", res.data.data[0].password);
+        router.push({
+          path: `/schoolBus/busquery`,
+        });
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: "登录成功",
+          center: true,
+        });
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: "登录失败",
+          center: true,
+        });
+        loading.value = false;
+      }
+    } else {
+      return false;
+    }
+  });
+};
+const Enters = (e) => {
+  // console.log("按键:", e.key);
+  if (e.key == "Enter") {
+    submitForm(ruleFormRef.value);
+  }
+};
+onMounted(() => {
+  api.value = store.state.user.api;
+  if (localStorage.getItem("pass") && localStorage.getItem("user")) {
+    ruleForm.user = localStorage.getItem("user");
+    ruleForm.pass = localStorage.getItem("pass");
+    checked.value = true;
+  }
+  if (localStorage.getItem("user")) {
+    ruleForm.user = localStorage.getItem("user");
+  }
+  document.addEventListener("keyup", Enters);
+});
+onUnmounted(() => {
+  document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style lang="scss" scoped>
+.box {
+  width: 100%;
+  height: 100vh;
+  background: url(@/assets/login.png);
+  background-size: cover;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  // .middle {
+  //   width: 1180px;
+  //   height: 740px;
+  //   position: absolute;
+
+  // }
+  .left {
+    box-shadow: 39px 30px 58px 0px rgba(8, 53, 115, 0.55);
+
+    width: 1180px;
+    height: 740px;
+    border-radius: 18px;
+    display: flex;
+    align-items: center;
+    background-image: url(@/assets/login2.png);
+    background-size: 110% 116%;
+    background-position: -19px -28px;
+    .loginForm {
+      width: 497px;
+      height: 740px;
+      background-color: #fff;
+      border-radius: 18px 0 0 18px;
+
+      .el-form {
+        width: 500px;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        .el-form-item {
+          width: 420px;
+          height: 60px;
+          // margin-bottom: 40px;
+
+          :deep(.el-form-item__content) {
+            margin-left: 0 !important;
+
+            .el-input {
+              height: 60px;
+
+              .el-input__wrapper {
+                border-radius: 12px;
+                .el-input__prefix {
+                  margin: 0 10px 0 12px;
+                }
+              }
+
+              .el-icon {
+                width: 24px;
+                height: 24px;
+                svg {
+                  width: 24px;
+                  height: 24px;
+                }
+              }
+              .el-input__inner {
+                height: 100%;
+                font-size: 24px;
+              }
+            }
+            .el-form-item__error {
+              font-size: 16px;
+            }
+            .el-button {
+              width: 100%;
+              height: 60px;
+              font-size: 24px;
+              border-radius: 12px;
+            }
+          }
+
+          .el-button--primary {
+            width: 380px;
+          }
+        }
+        .remeberPwd {
+          height: 30px;
+          margin-bottom: 30px;
+          :deep(.el-checkbox__input) {
+            .el-checkbox__inner {
+              width: 18px;
+              height: 18px;
+            }
+            .el-checkbox__inner::after {
+              width: 6px;
+              height: 12px;
+              top: -1px;
+            }
+          }
+          :deep(.el-checkbox__label) {
+            font-size: 18px;
+          }
+        }
+      }
+    }
+    .rLogin {
+      width: 683px;
+      height: 740px;
+      border-radius: 0 18px 18px 0;
+      display: flex;
+      img {
+        width: 683px;
+        align-self: flex-end;
+      }
+    }
+  }
+}
+</style>

+ 655 - 0
src/views/news/news.vue

@@ -0,0 +1,655 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">消息通知</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>创建时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="date"
+            placeholder="请选择时间"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+          />
+        </div>
+        <div class="condition">
+          <span>状态 : </span>
+          <el-select
+            style="width: 120px"
+            v-model="searchInput.state"
+            class="m-2"
+            placeholder="请选择状态"
+          >
+            <el-option label="全部" value="2" />
+            <el-option label="已读" value="1" />
+            <el-option label="未读" value="0" />
+          </el-select>
+        </div>
+
+        <el-button
+          style="margin-left: 20px"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>搜索</span></el-button
+        >
+      </div>
+      <!-- 按钮列表 -->
+      <div class="gongneng">
+        <el-button type="primary" color="rgba(61, 81, 232, 1)" @click="reset"
+          ><el-icon><RefreshRight /></el-icon><span>刷新</span></el-button
+        >
+        <el-button type="danger" @click="allLook" color="rgba(61, 81, 232, 1)">
+          <img
+            src="@/assets/read.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>一键已读</span></el-button
+        >
+      </div>
+
+      <!-- 编辑/新增摄像头IP -->
+      <el-dialog
+        v-model="centerDialogVisible"
+        :title="dialongTitle"
+        width="40%"
+        align-center
+        :before-close="editClose"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="120px"
+          class="demo-ruleForm"
+          :size="formSize"
+          status-icon
+        >
+          <el-form-item label="厂商" prop="count">
+            <el-input v-model="ruleForm.count" placeholder="请输入厂商" />
+          </el-form-item>
+          <el-form-item label="IP地址" prop="name">
+            <el-input v-model="ruleForm.name" placeholder="请输入IP地址" />
+          </el-form-item>
+          <el-form-item label="状态" prop="region">
+            <el-select v-model="ruleForm.region" placeholder="请选择状态">
+              <el-option label="在线" value="1" />
+              <el-option label="离线" value="0" />
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            label="创建人"
+            prop="username"
+            v-show="dialongTitle == '新增摄像头IP'"
+          >
+            <el-input
+              v-model="ruleForm.username"
+              placeholder="请输入创建人姓名"
+            />
+          </el-form-item>
+          <el-form-item label="摄像头密码" prop="pass">
+            <el-input v-model="ruleForm.pass" placeholder="请输入摄像头密码" />
+          </el-form-item>
+          <el-form-item
+            label="最后更新人"
+            prop="username"
+            v-show="dialongTitle == '修改摄像头IP'"
+          >
+            <el-input
+              v-model="ruleForm.username"
+              placeholder="请输入更新人姓名"
+            />
+          </el-form-item>
+          <el-form-item label="设备型号" prop="date1">
+            <el-input v-model="ruleForm.date1" placeholder="请输入设备型号" />
+          </el-form-item>
+          <el-form-item label="协议" prop="types">
+            <el-input
+              v-model="ruleForm.types"
+              placeholder="请输入协议"
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="安装位置" prop="date2">
+            <el-input v-model="ruleForm.date2" placeholder="请输入安装位置" />
+          </el-form-item>
+
+          <el-form-item label="摄像机编码" prop="resource">
+            <el-input
+              v-model="ruleForm.resource"
+              placeholder="请输入摄像机编码"
+            >
+            </el-input>
+          </el-form-item>
+          <el-form-item label="备注" prop="desc">
+            <el-input
+              v-model="ruleForm.desc"
+              type="textarea"
+              placeholder="请输入备注"
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="submitForm(ruleFormRef)">
+              确定
+            </el-button>
+            <el-button @click="resetForm(ruleFormRef)">重置</el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          align="center"
+          prop="create_time"
+          label="创建时间"
+          width="250"
+        />
+        <el-table-column align="center" prop="message" label="消息" />
+        <el-table-column align="center" prop="state" label="状态" width="200">
+          <template #default="scope">
+            <div v-if="scope.row.state == 1">已读</div>
+            <div v-else-if="scope.row.state == 0" style="color: red">未读</div>
+          </template> </el-table-column
+        >>
+        <el-table-column align="center" label="操作" width="220">
+          <template #default="scope">
+            <el-button link type="primary" @click="look(scope.row)"
+              ><div class="look">查看</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const api = ref("");
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref(""); // 弹窗标题
+
+const searchInput = reactive({
+  state: "全部",
+  createTime: "",
+}); // 搜索按钮数据
+5;
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(10); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+const centerDialogVisible = ref(false); // 控制新增或修改弹窗开关
+const videoDialogVisible = ref(false); // 控制播放弹窗开关
+
+const urlLink = ref(); // 输出链接
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  name: "",
+  region: "",
+  count: "",
+  date1: "",
+  date2: "",
+  types: [],
+  resource: "",
+  desc: "",
+  username: "",
+  pass: "",
+  id: "",
+});
+// 表单验证
+const rules = reactive({
+  region: [
+    {
+      required: true,
+      message: "状态不能为空",
+      trigger: "blur",
+    },
+  ],
+  name: [
+    { required: true, message: "IP地址不能为空", trigger: "blur" },
+    // { min: 3, max: 5, message: "Length should be 3 to 5", trigger: "blur" },
+  ],
+  count: [
+    {
+      required: true,
+      message: "厂商不能为空",
+      trigger: "blur",
+    },
+  ],
+  date1: [
+    {
+      required: true,
+      message: "设备型号不能为空",
+      trigger: "blur",
+    },
+  ],
+  date2: [
+    {
+      required: true,
+      message: "安装位置不能为空",
+      trigger: "blur",
+    },
+  ],
+  types: [
+    {
+      required: true,
+      message: "协议不能为空",
+      trigger: "blur",
+    },
+  ],
+  username: [
+    {
+      required: true,
+      message: "更新人员姓名不能为空",
+      trigger: "blur",
+    },
+  ],
+  pass: [
+    {
+      required: true,
+      message: "密码不能为空",
+      trigger: "blur",
+    },
+  ],
+  resource: [
+    {
+      required: true,
+      message: "摄像机编码不能为空",
+      trigger: "blur",
+    },
+  ],
+  // desc: [{ required: true, message: "Please input activity form", trigger: "blur" }],
+});
+// 获取消息列表
+const getList = async () => {
+  let data = new FormData();
+  // console.log(searchInput.state === 0);
+
+  data.set("create_time", searchInput.createTime);
+  if (searchInput.state == 2 || searchInput.state == "全部") {
+  } else {
+    data.set("state", searchInput.state);
+  }
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userqueryMes.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    tableData.list = res.data.rows;
+    if (res.data.currentPage) {
+      currentPage.value = res.data.currentPage;
+    } else {
+      currentPage.value = 1;
+    }
+    // if (tableData.list) {
+    //   let newsArr = tableData.list.filter((item) => {
+    //     return item.state == 0;
+    //   });
+    //   console.log(newsArr.length);
+    //   sessionStorage.setItem("newsNum", newsArr.length);
+    // } else {
+    //   sessionStorage.setItem("newsNum", 0);
+    // }
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+// 刷新
+const reset = async () => {
+  searchInput.state = "全部";
+  searchInput.createTime = "";
+  let data = new FormData();
+  console.log(searchInput.state === 0);
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userqueryMes.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    tableData.list = res.data.rows;
+    if (res.data.currentPage) {
+      currentPage.value = res.data.currentPage;
+    } else {
+      currentPage.value = 1;
+    }
+    if (tableData.list) {
+      let newsArr = tableData.list.filter((item) => {
+        return item.state == 0;
+      });
+      console.log(newsArr.length);
+      sessionStorage.setItem("newsNum", newsArr.length);
+    } else {
+      sessionStorage.setItem("newsNum", 0);
+    }
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+// 路由
+const handleSelect = (key, keyPath) => {};
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList();
+}, 300);
+
+// 查看按钮
+const look = async (row) => {
+  let data = new FormData();
+  data.set("id", row.id);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userupdateMesState.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    store.dispatch("newsAsync");
+    router.push({
+      path: `/schoolBus/statement`,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+// 查看按钮
+const allLook = async (row) => {
+  let data = new FormData();
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userupdateAllMesState.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    getList();
+    store.dispatch("newsAsync");
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: 97.5%;
+  height: 89%;
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    // width: calc(100wh - 40px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: 96%;
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: 96%;
+    height: 550px;
+    margin: 10px auto 30px;
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 14px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+    }
+  }
+  .el-pagination {
+    // width: 1600px;
+    width: 96%;
+    margin: 0 auto 18px;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 879 - 0
src/views/report/report.vue

@@ -0,0 +1,879 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">报备管理</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>姓名 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.name"
+            class="w-50 m-2"
+            placeholder="请输入姓名"
+            style="width: 150px"
+          />
+        </div>
+        <!-- <div class="condition">
+          <span>手机号码 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入手机号码"
+            style="width: 150px"
+          />
+        </div> -->
+        <div class="condition">
+          <span>创建时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="date"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            :prefix-icon="Calendar"
+            placeholder="请选择日期"
+          />
+        </div>
+        <el-button
+          style="margin-left: 20px"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          style="margin-left: 20px !important"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+      </div>
+      <!-- 按钮列表 -->
+      <div class="gongneng">
+        <el-button type="primary" color="rgba(61, 81, 232, 1)" @click="addlist"
+          ><el-icon><CirclePlus /></el-icon><span>新增报备人员</span></el-button
+        >
+        <!-- <el-button
+          color="rgba(61, 81, 232, 1)"
+          class="import"
+          type="primary"
+          @click="importExcel"
+          ><img
+            src="@/assets/import.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>导出表单</span></el-button
+        > -->
+      </div>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <el-table-column align="center" prop="create_time" label="创建时间" />
+        <el-table-column align="center" prop="user_name" label="姓名" />
+        <el-table-column align="center" prop="card_number" label="卡号" />
+        <el-table-column align="center" width="300" label="有效时间">
+          <template #default="scope">
+            <div>{{ scope.row.start_time + " ~ " + scope.row.end_time }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column align="center" prop="user_phone" label="电话号码" />
+        <el-table-column align="center" label="操作">
+          <template #default="scope">
+            <el-button link type="primary" @click="edit(scope.row)"
+              ><div class="look">编辑</div></el-button
+            >
+            <el-button link type="danger" @click="del(scope.row)"
+              ><div class="looks">删除</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 添加报备人员弹窗 -->
+      <el-dialog
+        class="addStaff"
+        v-model="addDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :title="dialongTitle"
+        align-center
+        width="609"
+        :before-close="cancelAdd"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="100px"
+          class="demo-ruleForm"
+          :size="formSize"
+          label-position="left"
+          status-icon
+        >
+          <el-form-item label="姓名 :" prop="name">
+            <el-input
+              v-model="ruleForm.name"
+              placeholder="请输入姓名"
+              clearable
+            />
+          </el-form-item>
+          <el-form-item label="卡号 :" prop="cardnumber">
+            <!-- <el-tooltip
+              :visible="cardVisible"
+              placement="right-start"
+              effect="light"
+            >
+              <template #content>
+                <span>微校卡号</span>
+              </template>
+              <el-input
+                v-model="ruleForm.cardnumber"
+                placeholder="请输入卡号"
+                clearable
+                @focus="cardShow"
+                @blur="cardHide"
+              />
+            </el-tooltip> -->
+            <el-input
+              v-model="ruleForm.cardnumber"
+              placeholder="请输入微校卡号"
+              clearable
+            />
+          </el-form-item>
+          <el-form-item label="手机号码 :">
+            <el-input
+              v-model="ruleForm.phone"
+              placeholder="请输入手机号码"
+              clearable
+            />
+          </el-form-item>
+          <!-- <el-form-item label="类型 :" prop="post">
+            <el-select
+              v-model="ruleForm.post"
+              class="m-2"
+              placeholder="请选择职位"
+            >
+              <el-option label="临时人员" value="临时人员" />
+              <el-option label="学生" value="学生" />
+            </el-select>
+          </el-form-item> -->
+          <el-form-item
+            label="有效时间 :"
+            prop="startTime"
+            style="padding-bottom: 30px"
+          >
+            <el-date-picker
+              v-model="ruleForm.startTime"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="开始时间"
+              end-placeholder="结束时间"
+              format="YYYY-MM-DD"
+              value-format="YYYY-MM-DD"
+            />
+          </el-form-item>
+          <el-divider />
+          <el-form-item class="options">
+            <el-button class="congzhi" @click="cancelAdd(ruleFormRef)"
+              >取消</el-button
+            >
+            <el-button
+              color="rgba(61, 81, 232, 1)"
+              class="queding"
+              type="primary"
+              @click="submitAdd(ruleFormRef)"
+            >
+              确定
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增报备人员"); // 弹窗标题
+const api = ref("");
+const searchInput = reactive({
+  name: "",
+  phone: "",
+  createTime: "",
+}); // 搜索按钮数据
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+const cardVisible = ref(false); // 卡号提示文字
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  name: "",
+  phone: "",
+  post: "0",
+  cardnumber: "",
+  startTime: "",
+  id: "",
+});
+// 表单验证
+const rules = reactive({
+  name: [
+    { required: true, message: "姓名不能为空", trigger: "blur" },
+    {
+      pattern: /[\u4e00-\u9fa5]$/,
+      message: "请输入正确姓名",
+      trigger: "blur",
+    },
+  ],
+  // /^[\u4E00-\u9FA5]$/
+  cardnumber: [
+    { required: true, message: "卡号不能为空", trigger: "blur" },
+    // {
+    //   // pattern: /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/,
+    //   // pattern: /^[0-9]*$/,
+    //   message: "请输入正确卡号(数字类型)",
+    //   trigger: "blur",
+    // },
+  ],
+  phone: [
+    { required: true, message: "请输入手机号", trigger: "blur" },
+    {
+      // pattern: /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/,
+      pattern: /^((\(\+86\))|(\(86\)))?[1][3456789][0-9]{9}$/,
+      message: "请输入合法手机号/电话号",
+      trigger: "blur",
+    },
+  ],
+  post: [
+    {
+      required: true,
+      message: "职位不能为空",
+      trigger: "blur",
+    },
+  ],
+  startTime: [
+    {
+      required: true,
+      message: "请选择时间段",
+      trigger: "blur",
+    },
+  ],
+
+  // desc: [{ required: true, message: "Please input activity form", trigger: "blur" }],
+});
+// 获取摄像头列表
+const getList = async (message) => {
+  let data = new FormData();
+  data.set("user_name", searchInput.name);
+  data.set("create_time", searchInput.createTime);
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  // let res = await adminApi.adminLogin(data);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/ubblist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res, "报备数据");
+  if (res.status == 200) {
+    if (message) {
+      ElMessage({
+        type: "success",
+        showClose: true,
+        message: message,
+        center: true,
+      });
+    }
+    tableData.list = res.data.rows;
+    // currentPage.value = res.data.currentPage;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+  // console.log(res);
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.name = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+// 添加员工
+const addlist = () => {
+  dialongTitle.value = "新增报备人员";
+  addDialogVisible.value = true;
+  ruleForm.name = "";
+  ruleForm.cardnumber = "";
+  ruleForm.phone = "";
+  ruleForm.post = "";
+  ruleForm.startTime = [];
+};
+//编辑按钮
+const edit = (row) => {
+  // console.log(ruleForm.startTime, row.start_time, row.end_time);
+
+  dialongTitle.value = "编辑报备人员";
+  addDialogVisible.value = true;
+  console.log(row);
+  ruleForm.name = row.user_name;
+  ruleForm.phone = row.user_phone;
+  ruleForm.id = row.id;
+  ruleForm.cardnumber = row.card_number;
+  let data = [row.start_time, row.end_time];
+  console.log(row.start_time == "");
+  if (row.start_time != "") {
+    ruleForm.startTime = data;
+  } else {
+    ruleForm.startTime = "";
+  }
+};
+// 取消添加员工
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+  ruleFormRef.value.resetFields();
+};
+// 确认添加员工
+const submitAdd = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (dialongTitle.value == "新增报备人员") {
+        let data = {
+          start_time: ruleForm.startTime[0],
+          end_time: ruleForm.startTime[1],
+          user_name: ruleForm.name,
+          card_number: ruleForm.cardnumber,
+          user_phone: ruleForm.phone,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/ubbinsert.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        console.log(res, "添加报备");
+        if (res.data.code == 200) {
+          getList();
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      } else {
+        let data = {
+          user_name: ruleForm.name,
+          user_phone: ruleForm.phone,
+          id: ruleForm.id,
+          card_number: ruleForm.cardnumber,
+          start_time: ruleForm.startTime[0],
+          end_time: ruleForm.startTime[1],
+        };
+        let res = await axios({
+          method: "post",
+          url: api.value + "/ubbupdate.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        console.log(res, "修改报备");
+        if (res.data.code == 200) {
+          getList();
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+//删除按钮
+const del = (row) => {
+  ElMessageBox.confirm(`是否删除 ${row.user_name} 报备人员?`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      let data = new FormData();
+      data.set("id", row.id);
+      // let res = await adminApi.adminLogin(data);
+      let res = await axios({
+        method: "post",
+        url: api.value + "/ubbdel.action",
+        headers: {
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      if (res.data.code == 200) {
+        if (tableData.list.length == 1 && currentPage.value != 1) {
+          currentPage.value = currentPage.value - 1;
+        }
+        getList();
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+      console.log(res);
+    })
+    .catch(() => {
+      ElMessage({
+        type: "info",
+        message: "已取消删除",
+      });
+    });
+};
+
+// 控制卡号显示
+const cardShow = () => {
+  cardVisible.value = true;
+};
+// 控制卡号隐藏
+const cardHide = () => {
+  cardVisible.value = false;
+};
+
+//导出功能
+// const importExcel = async () => {
+//   if (searchInput.createTime == null) {
+//     searchInput.createTime = "";
+//   }
+//   let data = new FormData();
+//   data.set("user_name", searchInput.name);
+//   data.set("user_phone", searchInput.phone);
+//   data.set("create_time", searchInput.createTime);
+//   let res = await axios({
+//     method: "post",
+//     url: api.value + "/carBook/usertoExcel.action",
+//     headers: {
+//       token: sessionStorage.getItem("token"),
+//     },
+//     data: data,
+//   });
+//   // console.log(res, "导出账号");
+//   if (res.data.code == 200) {
+//     // const elt = document.createElement("a");
+//     // elt.setAttribute(
+//     //   "href",
+//     //   "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl
+//     // );
+//     // // elt.setAttribute("download", "file.xlsx");
+//     // // elt.style.display = "none";
+//     // document.body.appendChild(elt);
+//     // elt.click();
+//     var downloadPath = "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl;
+//     console.log("获得地址数据:", downloadPath);
+//     var downloadLink = document.createElement("a");
+//     downloadLink.style.display = "none"; // 使其隐藏
+//     downloadLink.href = downloadPath;
+//     downloadLink.download = "";
+//     downloadLink.click();
+//     document.body.appendChild(downloadLink);
+//     document.body.removeChild(downloadLink);
+//     ElMessage({
+//       type: "success",
+//       showClose: true,
+//       message: res.data.message,
+//       center: true,
+//     });
+//   } else {
+//     ElMessage({
+//       type: "error",
+//       showClose: true,
+//       message: res.data.message,
+//       center: true,
+//     });
+//   }
+// };
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+  // let arr = [2, 4, 6, 3, 5, 8, 7, 9, 1];
+  // for (let j = 1; j <= arr.length - 1; j++) {
+  //   for (let i = 0; i <= arr.length - j; i++) {
+  //     let a = arr[i];
+  //     if (arr[i] > arr[i + 1]) {
+  //       arr[i] = arr[i + 1];
+  //       arr[i + 1] = a;
+  //     }
+  //   }
+  // }
+  // for (let j = 0; j <= arr.length - 2; j++) {
+  //   for (let i = j + 1; i <= arr.length - 1; i++) {
+  //     let a = arr[j];
+  //     if (arr[j] < arr[i]) {
+  //       arr[j] = arr[i];
+  //       arr[i] = a;
+  //     }
+  //   }
+  // }
+  // let arr = [2, 4, 6, 3, 3, 4, 8, 9, 3, 1, 2, 5, 8, 7, 9, 1];
+  // let arr2 = [];
+  // for (let j = 0; j <= arr.length - 1; j++) {
+  //   let flag = true;
+  //   for (let i = 0; i <= arr2.length - 1; i++) {
+  //     if (arr[j] == arr2[i]) {
+  //       flag = false;
+  //       break;
+  //     }
+  //   }
+  //   if (flag) {
+  //     arr2.push(arr[j]);
+  //   }
+  // }
+  // console.log(arr2);
+
+  // let arr = [2, 4, 6, 3, 3, 4, 8, 9, 3, 1, 2, 5, 8, 7, 9, 1];
+  // var newArr = arr.reduce((pre, cur) => {
+  //   console.log(pre, cur);
+  //   if (cur in pre) {
+  //     pre[cur]++;
+  //   } else {
+  //     pre[cur] = 1;
+  //   }
+  //   return pre;
+  // }, {}); //这里注意初始值要默认赋予空对象,不然会报错
+  // console.log(newArr);
+
+  // let arr = [2, 4, 6, 3, 3, 4, 8, 9, 3, 1, 2, 5, 8, 7, 9, 1];
+  // let newArr = arr.reduce((pre, cur) => {
+  //   if (!pre.includes(cur)) {
+  //     return pre.concat(cur);
+  //   } else {
+  //     return pre;
+  //   }
+  // }, []);
+
+  // console.log(newArr);
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 40px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        :deep(.el-input .el-input__inner) {
+          font-size: 16px;
+        }
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex:1;
+    margin: 10px auto;
+    overflow: auto;
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 30px 20px 10px 20px;
+        // .el-form-item {
+        //   // width: 500px;
+        // }
+        .el-input {
+          width: 200px;
+        }
+        .options {
+          margin-left: 320px;
+        }
+      }
+    }
+  }
+  .el-pagination {
+    // width: 1600px;
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 30px;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 797 - 0
src/views/staff/staff.vue

@@ -0,0 +1,797 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">驾驶员管理</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <span>姓名 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.name"
+            class="w-50 m-2"
+            placeholder="请输入姓名"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>手机号码 : </span>
+          <el-input
+            clearable
+            v-model="searchInput.phone"
+            class="w-50 m-2"
+            placeholder="请输入手机号码"
+            style="width: 150px"
+          />
+        </div>
+        <div class="condition">
+          <span>创建时间 : </span>
+          <el-date-picker
+            v-model="searchInput.createTime"
+            type="date"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            :prefix-icon="Calendar"
+            placeholder="请选择日期"
+          />
+        </div>
+
+        <el-button
+          style="margin-left: 20px"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchBtn"
+          ><el-icon><Search /></el-icon> <span>查询</span></el-button
+        >
+        <el-button
+          style="margin-left: 20px !important"
+          color="rgba(61, 81, 232, 1)"
+          type="primary"
+          class="search"
+          @click="searchRefresh"
+          ><el-icon><Refresh /></el-icon><span>重置</span></el-button
+        >
+      </div>
+      <!-- 按钮列表 -->
+      <div class="gongneng">
+        <el-button type="primary" color="rgba(61, 81, 232, 1)" @click="addlist"
+          ><el-icon><CirclePlus /></el-icon><span>新增驾驶员</span></el-button
+        >
+        <el-button
+          color="rgba(61, 81, 232, 1)"
+          class="import"
+          type="primary"
+          @click="importExcel"
+          ><img
+            src="@/assets/import.png"
+            style="width: 14px; height: 14px; margin-right: 4px"
+            alt=""
+          />
+          <span>导出表单</span></el-button
+        >
+      </div>
+    </div>
+    <div class="footer">
+      <el-table
+        :row-class-name="tableRowClassName"
+        :data="tableData.list"
+        @selection-change="handleSelectionChange"
+        style="width: 100%"
+        :header-cell-style="{
+          background: 'rgba(240, 243, 247, 1)',
+          height: '50px',
+          border: 0,
+        }"
+      >
+        <!-- <el-table-column align="center" type="selection" width="80" /> -->
+        <el-table-column
+          type="index"
+          width="100"
+          align="center"
+          label="序号"
+          index="1"
+        />
+        <el-table-column align="center" prop="user_name" label="姓名" />
+        <el-table-column
+          align="center"
+          prop="user_zz"
+          label="职位"
+          width="200"
+        />
+        <el-table-column align="center" prop="user_phone" label="电话号码" />
+        <el-table-column align="center" prop="create_time" label="创建时间" />
+
+        <el-table-column align="center" label="操作" width="220">
+          <template #default="scope">
+            <el-button link type="primary" @click="edit(scope.row)"
+              ><div class="look">编辑</div></el-button
+            >
+            <el-button link type="danger" @click="del(scope.row)"
+              ><div class="looks">删除</div></el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 添加员工弹窗 -->
+      <el-dialog
+        class="addStaff"
+        v-model="addDialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :title="dialongTitle"
+        align-center
+        width="609"
+        :before-close="cancelAdd"
+      >
+        <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="100px"
+          class="demo-ruleForm"
+          :size="formSize"
+          label-position="left"
+          status-icon
+        >
+          <el-form-item label="姓名 :" prop="name">
+            <el-input
+              v-model="ruleForm.name"
+              placeholder="请输入姓名"
+              clearable
+            />
+          </el-form-item>
+          <el-form-item
+            label="卡号 :"
+            prop="cardnumber"
+            v-if="dialongTitle == '新增驾驶员'"
+          >
+            <el-input
+              v-model="ruleForm.cardnumber"
+              placeholder="请输入卡号"
+              clearable
+            />
+          </el-form-item>
+
+          <el-form-item label="手机号码 :">
+            <!-- prop="phone" -->
+            <el-input
+              v-model="ruleForm.phone"
+              placeholder="请输入手机号码"
+              clearable
+            />
+          </el-form-item>
+          <el-form-item
+            label="职位 :"
+            prop="post"
+            style="
+              padding-bottom: 40px;
+              border-bottom: 1px solid rgba(230, 230, 230, 1);
+            "
+          >
+            <el-select
+              v-model="ruleForm.post"
+              class="m-2"
+              placeholder="请选择职位"
+            >
+              <el-option label="车队长" value="车队长" />
+              <el-option label="司机" value="司机" />
+            </el-select>
+          </el-form-item>
+
+          <el-form-item class="options">
+            <el-button class="congzhi" @click="cancelAdd(ruleFormRef)"
+              >取消</el-button
+            >
+            <el-button
+              color="rgba(61, 81, 232, 1)"
+              class="queding"
+              type="primary"
+              @click="submitAdd(ruleFormRef)"
+            >
+              确定
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+    </div>
+
+    <!-- 分页组件 -->
+    <el-pagination
+      background
+      :current-page="currentPage"
+      :page-size="pageSize"
+      layout="total, prev, pager, next, jumper, slot"
+      :total="total"
+      @update:current-page="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, nextTick, onBeforeMount, onUnmounted } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { Calendar } from "@element-plus/icons-vue";
+import vidiconsApi from "@/api/vidicons.js";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const router = useRouter();
+// 表格数据
+const tableData = reactive({ list: [] });
+const activeIndex = ref(); // 默认跳转路由
+const dialongTitle = ref("新增驾驶员"); // 弹窗标题
+const api = ref("");
+const searchInput = reactive({
+  name: "",
+  phone: "",
+  createTime: "",
+}); // 搜索按钮数据
+
+const currentPage = ref(1); // 当前页
+const pageSize = ref(10);
+const total = ref(); // 当前总数
+const selectData = reactive({ list: [] }); // 多选框选择的数据
+
+const addDialogVisible = ref(false); // 控制添加员工弹窗
+
+// 表单数据
+const formSize = ref("default");
+const ruleFormRef = ref();
+const ruleForm = reactive({
+  name: "",
+  phone: "",
+  post: "0",
+  cardnumber: "",
+  id: "",
+});
+// 表单验证
+const rules = reactive({
+  name: [
+    { required: true, message: "姓名不能为空", trigger: "blur" },
+    {
+      pattern: /[\u4e00-\u9fa5]$/,
+      message: "请输入正确姓名",
+      trigger: "blur",
+    },
+  ],
+  // /^[\u4E00-\u9FA5]$/
+  cardnumber: [
+    { required: true, message: "卡号不能为空", trigger: "blur" },
+    // {
+    //   // pattern: /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/,
+    //   // pattern: /^[0-9]*$/,
+    //   message: "请输入正确卡号(数字类型)",
+    //   trigger: "blur",
+    // },
+  ],
+  phone: [
+    { required: true, message: "请输入手机号", trigger: "blur" },
+    {
+      // pattern: /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/,
+      pattern: /^((\(\+86\))|(\(86\)))?[1][3456789][0-9]{9}$/,
+      message: "请输入合法手机号/电话号",
+      trigger: "blur",
+    },
+  ],
+  post: [
+    {
+      required: true,
+      message: "职位不能为空",
+      trigger: "blur",
+    },
+  ],
+
+  // desc: [{ required: true, message: "Please input activity form", trigger: "blur" }],
+});
+// 获取摄像头列表
+const getList = async (message) => {
+  let data = new FormData();
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime); //前面的key记得对应!
+  data.set("page", currentPage.value);
+  data.set("rows", pageSize.value); //前面的key记得对应!
+  // let res = await adminApi.adminLogin(data);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/userlist.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res);
+  if (res.status == 200) {
+    if (message) {
+      ElMessage({
+        type: "success",
+        showClose: true,
+        message: message,
+        center: true,
+      });
+    }
+    // ElMessage({
+    //   type: "success",
+    //   showClose: true,
+    //   message: res.data.message,
+    //   center: true,
+    // });
+    tableData.list = res.data.rows;
+    // currentPage.value = res.data.currentPage;
+    total.value = res.data.total;
+  } else {
+    tableData.list = res.data.rows;
+    currentPage.value = 1;
+    total.value = res.data.total;
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+  // console.log(res);
+};
+
+// 搜索功能
+const searchBtn = lodash.debounce(async () => {
+  getList("查询成功");
+}, 300);
+// 重置搜索
+const searchRefresh = lodash.debounce(async () => {
+  searchInput.name = "";
+  searchInput.phone = "";
+  searchInput.createTime = "";
+  currentPage.value = 1;
+  getList();
+}, 300);
+// 添加员工
+const addlist = () => {
+  dialongTitle.value = "新增驾驶员";
+  addDialogVisible.value = true;
+  ruleForm.name = "";
+  ruleForm.phone = "";
+  ruleForm.post = "";
+  ruleForm.cardnumber = "";
+};
+//编辑按钮
+const edit = (row) => {
+  dialongTitle.value = "编辑驾驶员";
+  addDialogVisible.value = true;
+  console.log(row);
+  ruleForm.name = row.user_name;
+  ruleForm.phone = row.user_phone;
+  ruleForm.post = row.user_zz;
+  ruleForm.id = row.id;
+};
+// 取消添加员工
+const cancelAdd = () => {
+  addDialogVisible.value = false;
+  ruleFormRef.value.resetFields();
+};
+// 确认添加员工
+const submitAdd = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (dialongTitle.value == "新增驾驶员") {
+        let data = {
+          user_name: ruleForm.name,
+          user_phone: ruleForm.phone,
+          user_zz: ruleForm.post,
+          card_number: ruleForm.cardnumber,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/userinsert.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "添加账号");
+        if (res.data.code == 200) {
+          getList();
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      } else {
+        let data = {
+          user_name: ruleForm.name,
+          user_phone: ruleForm.phone,
+          user_zz: ruleForm.post,
+          id: ruleForm.id,
+        };
+        // let res = await admin.adminAdd(data);
+        let res = await axios({
+          method: "post",
+          url: api.value + "/carBook/userupdate.action",
+          headers: {
+            "Content-Type": "application/json;charset=utf-8",
+            token: sessionStorage.getItem("token"),
+          },
+          data: data,
+        });
+        // console.log(res, "修改账号");
+        if (res.data.code == 200) {
+          getList();
+
+          ElMessage({
+            type: "success",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+          addDialogVisible.value = false;
+          ruleFormRef.value.resetFields();
+        } else {
+          ElMessage({
+            type: "error",
+            showClose: true,
+            message: res.data.message,
+            center: true,
+          });
+        }
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+//删除按钮
+const del = (row) => {
+  ElMessageBox.confirm(`是否删除 ${row.user_name} 驾驶员?`, "提示", {
+    confirmButtonText: "确认",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(async () => {
+      let data = new FormData();
+      data.set("id", row.id);
+      // let res = await adminApi.adminLogin(data);
+      let res = await axios({
+        method: "post",
+        url: api.value + "/carBook/userdel.action",
+        headers: {
+          token: sessionStorage.getItem("token"),
+        },
+        data: data,
+      });
+      if (res.data.code == 200) {
+        if (tableData.list.length == 1 && currentPage.value != 1) {
+          currentPage.value = currentPage.value - 1;
+        }
+        getList();
+        ElMessage({
+          type: "success",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      } else {
+        ElMessage({
+          type: "error",
+          showClose: true,
+          message: res.data.message,
+          center: true,
+        });
+      }
+      console.log(res);
+    })
+    .catch(() => {
+      ElMessage({
+        type: "info",
+        message: "已取消删除",
+      });
+    });
+};
+//导出功能
+const importExcel = async () => {
+  if (searchInput.createTime == null) {
+    searchInput.createTime = "";
+  }
+  let data = new FormData();
+  data.set("user_name", searchInput.name);
+  data.set("user_phone", searchInput.phone);
+  data.set("create_time", searchInput.createTime);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/usertoExcel.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  // console.log(res, "导出账号");
+  if (res.data.code == 200) {
+    // const elt = document.createElement("a");
+    // elt.setAttribute(
+    //   "href",
+    //   "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl
+    // );
+    // // elt.setAttribute("download", "file.xlsx");
+    // // elt.style.display = "none";
+    // document.body.appendChild(elt);
+    // elt.click();
+    var downloadPath = "https://car.meiyishuoo.com/ride-sharing" + res.data.downurl;
+    console.log("获得地址数据:", downloadPath);
+    var downloadLink = document.createElement("a");
+    downloadLink.style.display = "none"; // 使其隐藏
+    downloadLink.href = downloadPath;
+    downloadLink.download = "";
+    downloadLink.click();
+    document.body.appendChild(downloadLink);
+    document.body.removeChild(downloadLink);
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+// 多选框功能
+const handleSelectionChange = (val) => {
+  console.log(val);
+  selectData.list = val;
+};
+
+// 表格斑马纹颜色修改
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex % 2 === 0) {
+    return "even";
+  } else if (rowIndex % 2 !== 0) {
+    return "odd";
+  }
+  return "";
+};
+// 分页
+const handleCurrentChange = (value) => {
+  // console.log(value);
+  currentPage.value = value;
+  getList();
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getList();
+});
+onUnmounted(() => {
+  // document.removeEventListener("keyup", Enters);
+});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    width: calc(100% - 60px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    margin: 0 auto;
+
+    color: #000;
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      margin: 10px 0 0 0;
+      .search {
+        margin-left: 0 !important;
+      }
+      .condition {
+        display: flex;
+        align-items: center;
+        margin: 10px 30px 10px 0;
+        :deep(.el-input .el-input__inner) {
+          font-size: 16px;
+        }
+        span {
+          margin: 0 10px 0 0;
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+  .footer {
+    width: calc(100% - 60px);
+    flex: 1;
+    margin: 10px auto;
+    overflow: auto;
+
+    .el-table--fit {
+      height: 100%;
+      :deep(.el-table__header-wrapper) {
+        background-color: #000;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row) {
+        height: 50px;
+        font-size: 16px;
+        color: #000;
+      }
+      :deep(.el-table__row td) {
+        padding: 0;
+        border: 0;
+      }
+
+      .el-button--primary {
+        margin-left: 5px;
+      }
+      :deep(.el-table__body .even) {
+        background-color: #fff;
+      }
+      :deep(.el-table__body .odd) {
+        background-color: rgba(240, 243, 247, 1);
+      }
+      :deep(.look) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid rgba(30, 125, 251, 1);
+      }
+      :deep(.looks) {
+        padding: 5px 10px;
+        border-radius: 45px;
+        border: 0.74px solid #f56c6c;
+      }
+    }
+
+    // 添加员工弹窗样式
+    :deep(.addStaff) {
+      //   height: 420px;
+      border-radius: 11px;
+      .el-dialog__header {
+        border-radius: 11px 11px 0 0;
+        background: rgba(237, 241, 245, 1);
+        font-weight: 600;
+        margin: 0;
+        .el-dialog__headerbtn {
+          outline: none;
+        }
+      }
+      .el-dialog__body {
+        padding: 30px 20px 10px 20px;
+        .el-input {
+          width: 200px;
+        }
+        .options {
+          margin-left: 320px;
+        }
+      }
+    }
+  }
+  .el-pagination {
+    width: calc(100% - 60px);
+    height: 60px;
+    margin: 0 auto;
+    justify-content: flex-end;
+    :deep(.el-pagination__total) {
+      color: #000;
+    }
+    :deep(.el-pagination__goto) {
+      color: #000;
+    }
+    :deep(.el-pagination__classifier) {
+      color: #000;
+    }
+    :deep(.el-input__wrapper) {
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      box-shadow: none;
+    }
+    :deep(.el-pager li) {
+      margin: 0 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.el-pager li.is-active) {
+      background-color: rgba(30, 125, 251, 1);
+    }
+    :deep(.btn-prev) {
+      margin-right: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+    :deep(.btn-next) {
+      margin-left: 5px;
+      border: 1px solid rgba(0, 0, 0, 1);
+      border-radius: 5px;
+      background-color: transparent;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

Разлика између датотеке није приказан због своје велике величине
+ 1690 - 0
src/views/statement/statement.vue


+ 801 - 0
src/views/waiting/waiting.vue

@@ -0,0 +1,801 @@
+<template>
+  <div class="content-box">
+    <div class="left">
+      <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
+      <span class="cameratxt">系统设置</span>
+    </div>
+    <div class="middle">
+      <div class="filter">
+        <div class="condition">
+          <div style="display: flex; align-items: center">
+            <h3>开始时间段设置</h3>
+            <!-- <el-button
+              color="rgba(61, 81, 232, 1)"
+              @click="editSystem"
+              v-if="timeShow"
+              type="primary"
+              >修改</el-button
+            >
+            <el-button
+              color="rgba(61, 81, 232, 1)"
+              @click="saveSystem"
+              v-if="!timeShow"
+              type="primary"
+              >保存</el-button
+            >
+            <el-button @click="cancelSystem" v-if="!timeShow" plain
+              >取消</el-button
+            > -->
+          </div>
+          <span>周期配置 :&nbsp;&nbsp;</span>
+          <div
+            style="margin-bottom: 8px"
+            v-for="(i, ind) in timeList.list"
+            :key="ind"
+          >
+            <div class="addTime">
+              <el-checkbox-group
+                @change="saveTime($event, i.id, '星期一')"
+                v-model="i.day1"
+              >
+                <el-checkbox :label="1">星期一</el-checkbox>
+              </el-checkbox-group>
+              <el-checkbox-group
+                @change="saveTime($event, i.id, '星期二')"
+                v-model="i.day2"
+              >
+                <el-checkbox :label="1">星期二</el-checkbox>
+              </el-checkbox-group>
+              <el-checkbox-group
+                @change="saveTime($event, i.id, '星期三')"
+                v-model="i.day3"
+              >
+                <el-checkbox :label="1">星期三</el-checkbox>
+              </el-checkbox-group>
+              <el-checkbox-group
+                @change="saveTime($event, i.id, '星期四')"
+                v-model="i.day4"
+              >
+                <el-checkbox :label="1">星期四</el-checkbox>
+              </el-checkbox-group>
+              <el-checkbox-group
+                @change="saveTime($event, i.id, '星期五')"
+                v-model="i.day5"
+              >
+                <el-checkbox :label="1">星期五</el-checkbox>
+              </el-checkbox-group>
+              <el-checkbox-group
+                @change="saveTime($event, i.id, '星期六')"
+                v-model="i.day6"
+              >
+                <el-checkbox :label="1">星期六</el-checkbox>
+              </el-checkbox-group>
+              <el-checkbox-group
+                @change="saveTime($event, i.id, '星期日')"
+                v-model="i.day7"
+              >
+                <el-checkbox :label="1">星期日</el-checkbox>
+              </el-checkbox-group>
+
+              <div style="margin: 0 18px">
+                <el-time-picker
+                  class="timePicker"
+                  v-model="i.timePicker"
+                  :clearable="false"
+                  is-range
+                  format="HH:mm"
+                  value-format="HH:mm"
+                  range-separator="-"
+                  start-placeholder="开始时间"
+                  end-placeholder="结束时间"
+                  @change="saveTime($event, i.id)"
+                />
+              </div>
+              <div>
+                <span
+                  @click="addTime(ind)"
+                  style="cursor: pointer; color: rgb(30, 125, 251)"
+                  >添加</span
+                >
+                <span
+                  v-if="timeList.list.length > 1"
+                  @click="delTime(ind, i.id)"
+                  style="cursor: pointer; color: #f56c6c"
+                  >删除</span
+                >
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="condition">
+          <h3>截止预约时间设置</h3>
+          <div>
+            <span>发车前</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.yy_end"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <!-- <el-time-picker
+              v-model="ruleForm.hh_end"
+              format="HH:mm"
+              value-format="HH:mm"
+              @change="timeUpdata"
+            /> -->
+            <span>&nbsp;&nbsp;分钟</span>
+          </div>
+        </div>
+        <div class="condition">
+          <h3>扫码时间设置</h3>
+          <div>
+            <span>发车前</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.startTime"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>&nbsp;&nbsp;分钟 ,</span>
+            <span>发车后</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.endTime"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>&nbsp;&nbsp;分钟可扫码核销 </span>
+          </div>
+          <div style="margin-top: 15px">
+            <span>扫码间隔</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.scanInterval"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>&nbsp;&nbsp;分钟 ,</span>
+            <span>在此时间内多次扫码均提示已预约</span>
+          </div>
+        </div>
+        <!-- <div class="condition">
+          <h3>候补截止预约时间设置</h3>
+          <div>
+            <span>候补截止时间</span>
+            <el-time-picker
+              v-model="ruleForm.hh_end"
+              placeholder="请选择时间"
+              format="HH:mm"
+              value-format="HH:mm"
+              @change="timeUpdata"
+            />
+          </div>
+        </div> -->
+        <div class="condition">
+          <h3>黑名单设置</h3>
+          <div>
+            <span>爽约</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.black_count"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>&nbsp;&nbsp;次,锁定账号</span>
+          </div>
+        </div>
+        <div class="condition">
+          <h3>通知时间</h3>
+          <div>
+            <span>发车前提前</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.notice_time"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>&nbsp;&nbsp;分钟,发送通知</span>
+          </div>
+        </div>
+        <div class="condition">
+          <h3>报备人员开始预约时间设置</h3>
+          <div>
+            <span>发车前</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.bb_before"
+              class="w-50 m-2"
+              style="width: 100px"
+              @change="timeVerify"
+            />
+            <span>&nbsp;&nbsp;分钟,可以预约车辆</span>
+          </div>
+        </div>
+      </div>
+      <div class="filter">
+        <div class="condition" style="margin: 10px 0">
+          <h3>退改设置</h3>
+          <div>
+            <span>发车前</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.refundRule.a1.start"
+              class="w-50 m-2"
+              style="width: 80px"
+              @change="refundRuleClick"
+            />
+            <span>&nbsp;&nbsp;小时以上,免收手续费</span>
+          </div>
+          <div style="margin-top: 15px">
+            <span>发车前</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.refundRule.a2.start"
+              class="w-50 m-2"
+              style="width: 80px"
+              @change="refundRuleClick"
+            />
+            <span>&nbsp;&nbsp;小时以上</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.refundRule.a2.end"
+              class="w-50 m-2"
+              style="width: 80px"
+              @change="refundRuleClick"
+            />
+            <span>&nbsp;&nbsp;小时以内,收取</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.refundRule.a2.fee"
+              class="w-50 m-2"
+              style="width: 60px"
+              @change="refundRuleClick"
+            />
+            <span>&nbsp;&nbsp;(元)手续费</span>
+          </div>
+          <div style="margin-top: 15px">
+            <span>发车前</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.refundRule.a3.end"
+              class="w-50 m-2"
+              style="width: 80px"
+              @change="refundRuleClick"
+            />
+            <span>&nbsp;&nbsp;小时以内,收取</span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.refundRule.a3.fee"
+              class="w-50 m-2"
+              style="width: 80px"
+              @change="refundRuleClick"
+            />
+            <span>&nbsp;&nbsp;(元)手续费</span>
+          </div>
+          <div style="margin-top: 15px">
+            <span>发车后不退票</span>
+          </div>
+        </div>
+        <div class="condition">
+          <h3>客服设置</h3>
+          <div>
+            <span>客服工作时间 </span>
+            <el-time-picker
+              style="width: 180px"
+              class="timePicker"
+              v-model="ruleForm.workTime"
+              :clearable="false"
+              is-range
+              format="HH:mm"
+              value-format="HH:mm"
+              range-separator="-"
+              start-placeholder="开始时间"
+              end-placeholder="结束时间"
+              @change="timeUpdata"
+            />
+          </div>
+          <div style="margin-top: 15px">
+            <span>客服手机号 </span>
+            <el-input
+              :clearable="false"
+              v-model="ruleForm.workMobile"
+              class="w-50 m-2"
+              style="width: 180px"
+              @change="timeUpdata"
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="footer"></div>
+  </div>
+</template>
+
+<script setup>
+import {
+  ref,
+  reactive,
+  watch,
+  nextTick,
+  onBeforeMount,
+  onUnmounted,
+} from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { dayjs } from "element-plus";
+import lodash from "lodash";
+import axios from "axios";
+import { useStore } from "vuex";
+const store = useStore();
+const api = ref("");
+const router = useRouter();
+// 表格数据
+const ruleForm = reactive({
+  yy_duration: "",
+  hh_end: "", //截止预约时间设置
+  yy_end: "", //候补截止预约时间设置
+  black_count: "", //黑名单设置次数
+  notice_time: "", //发车前提前
+  startTime: "", // 扫码前时间
+  endTime: "", // 扫码后时间
+  scanInterval: "", // 扫码间隔
+  bb_before: "", // 报备人预约车辆时间设置
+  workTime: [], // 客服工作时间
+  workMobile: [], // 客服手机号
+  refundRule: {
+    a1: { fee: 0, start: 0 },
+    a2: { fee: 0, start: 0, end: 0 },
+    a3: { fee: 0, end: 0 },
+  }, // 退改设置
+  id: "",
+});
+// 开始时间段配置
+const timeList = reactive({
+  list: [
+    {
+      day1: [],
+      day2: [],
+      day3: [],
+      day4: [],
+      day5: [],
+      day6: [],
+      day7: [],
+      timePicker: [],
+      id: "",
+    },
+  ],
+});
+
+const timeShow = ref(true);
+
+// 获取系统设置数据
+const getlist = async (message) => {
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/cnqueryHb.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+  });
+  console.log(res);
+  if (res.data.code == 200) {
+    ruleForm.yy_duration = res.data.data.yy_duration;
+    ruleForm.scanInterval = res.data.data.scanInterval;
+    ruleForm.yy_end = res.data.data.yy_end; //
+    ruleForm.hh_end = res.data.data.hh_end; //
+    ruleForm.black_count = res.data.data.black_count;
+    ruleForm.notice_time = res.data.data.notice_time;
+    ruleForm.startTime = res.data.data.sm_start;
+    ruleForm.endTime = res.data.data.sm_end;
+    ruleForm.bb_before = res.data.data.bb_before;
+    ruleForm.workTime = res.data.data.workTime.split("-");
+    ruleForm.workMobile = res.data.data.workMobile;
+    ruleForm.id = res.data.data.id;
+    sessionStorage.setItem("sm_start", res.data.data.sm_start);
+    sessionStorage.setItem("sm_end", res.data.data.sm_end);
+
+    ruleForm.refundRule = res.data.data.refundRule;
+    
+    if (message) {
+      ElMessage({
+        type: "success",
+        showClose: true,
+        message: message,
+        center: true,
+      });
+    }
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+const getTimeList = async () => {
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/weekConfigqueryList.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+  });
+  console.log(res, "开始时间段配置");
+  if (res.data.code == 200) {
+    let resData = res.data.data;
+    let arr = [];
+    resData.forEach((i) => {
+      arr.push({
+        day1: i.day1 ? [i.day1] : [],
+        day2: i.day2 ? [i.day2] : [],
+        day3: i.day3 ? [i.day3] : [],
+        day4: i.day4 ? [i.day4] : [],
+        day5: i.day5 ? [i.day5] : [],
+        day6: i.day6 ? [i.day6] : [],
+        day7: i.day7 ? [i.day7] : [],
+        timePicker: [i.startTime, i.endTime],
+        id: i.id,
+      });
+    });
+    timeList.list = arr;
+    console.log(arr, "开始时间段配置");
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+    if (res.data.message == "token错误") {
+      router.push({
+        path: `/login`,
+      });
+    }
+  }
+};
+
+// 页面数据一修改就调用函数
+const timeVerify = (val) => {
+  const regex = /^[0-9]+$/;
+  if (regex.test(val)) {
+    timeUpdata();
+  } else {
+    getlist();
+    ElMessage({
+      type: "warning",
+      showClose: true,
+      message: "请输入正确数值",
+      center: true,
+    });
+  }
+};
+
+// 退改设置修改就调用函数
+const refundRuleClick = (val) => {
+  const regex = /^(\d+)(\.\d{1,2})?$/;
+  if (regex.test(val)) {
+    timeUpdata();
+  } else {
+    getlist();
+    ElMessage({
+      type: "warning",
+      showClose: true,
+      message: "请输入正确数值",
+      center: true,
+    });
+  }
+};
+
+const timeUpdata = async () => {
+  if (ruleForm.black_count <= 0) {
+    ruleForm.black_count = 1;
+  }
+  let data = {
+    yy_duration: ruleForm.yy_duration,
+    scanInterval: ruleForm.scanInterval,
+    yy_end: ruleForm.yy_end,
+    hh_end: ruleForm.hh_end,
+    black_count: ruleForm.black_count,
+    notice_time: ruleForm.notice_time,
+    sm_start: ruleForm.startTime,
+    sm_end: ruleForm.endTime,
+    bb_before: ruleForm.bb_before,
+    id: ruleForm.id,
+
+    workTime:ruleForm.workTime.join("-"),
+    workMobile:ruleForm.workMobile,
+    refundRule: JSON.stringify(ruleForm.refundRule),
+  };
+  console.log(data);
+  
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/cnupdate.action",
+    headers: {
+      "Content-Type": "application/json;charset=utf-8",
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  console.log(res, "修改候补");
+  if (res.data.code == 200) {
+    // getlist();
+    store.dispatch("sm_time");
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    getlist();
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: "修改失败",
+      center: true,
+    });
+  }
+};
+
+const addTime = lodash.debounce(async (ind) => {
+  console.log("添加", ind);
+  // timeList.list.splice(ind + 1, 0, {
+  //   day1: [],
+  //   day2: [],
+  //   day3: [],
+  //   day4: [],
+  //   day5: [],
+  //   day6: [],
+  //   day7: [],
+  //   timePicker: [],
+  //   id: "",
+  // });
+  let arr = {
+    day1: 0,
+    day2: 0,
+    day3: 0,
+    day4: 0,
+    day5: 0,
+    day6: 0,
+    day7: 0,
+    timePicker: null,
+  };
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/weekConfiginsert.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: arr,
+  });
+  if (res.data.code == 200) {
+    getTimeList();
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+}, 500);
+const delTime = async (ind, id) => {
+  // timeList.list.splice(ind, 1);
+  let data = new FormData();
+  data.append("id", id);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/weekConfigdel.action",
+    headers: {
+      token: sessionStorage.getItem("token"),
+    },
+    data: data,
+  });
+  if (res.data.code == 200) {
+    getTimeList();
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+const saveTime = async (event, id, txt) => {
+  // console.log(event,'id:'+id,txt);
+  console.log(timeList.list);
+  let arr = timeList.list.map((i) => {
+    console.log(i);
+    return {
+      day1: i.day1.length ? 1 : 0,
+      day2: i.day2.length ? 1 : 0,
+      day3: i.day3.length ? 1 : 0,
+      day4: i.day4.length ? 1 : 0,
+      day5: i.day5.length ? 1 : 0,
+      day6: i.day6.length ? 1 : 0,
+      day7: i.day7.length ? 1 : 0,
+      startTime: i.timePicker[0],
+      endTime: i.timePicker[1],
+      id: i.id,
+    };
+  });
+  // console.log(arr);
+  let augment = arr.filter((i) => {
+    return i.id == id;
+  });
+  // console.log(augment);
+  let res = await axios({
+    method: "post",
+    url: api.value + "/carBook/weekConfigupdate.action",
+    headers: {
+      "Content-Type": "application/json;charset=utf-8",
+      token: sessionStorage.getItem("token"),
+    },
+    data: augment[0],
+  });
+  if (res.data.code == 200) {
+    getTimeList();
+    ElMessage({
+      type: "success",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  } else {
+    getTimeList();
+    ElMessage({
+      type: "error",
+      showClose: true,
+      message: res.data.message,
+      center: true,
+    });
+  }
+};
+
+const editSystem = () => {
+  timeShow.value = false;
+};
+const saveSystem = () => {
+  timeShow.value = true;
+};
+const cancelSystem = () => {
+  timeShow.value = true;
+};
+
+onBeforeMount(() => {
+  api.value = store.state.user.api;
+  getlist();
+  getTimeList();
+});
+onUnmounted(() => {});
+</script>
+
+<style scoped lang="scss">
+.content-box {
+  width: calc(100% - 40px);
+  height: calc(100% - 105px);
+  margin: 20px auto;
+  background-color: #fff;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+
+  .left {
+    // width: calc(100wh - 40px);
+    display: flex;
+    align-items: center;
+    height: 60px;
+    margin: 0 30px;
+    border-bottom: 1px solid #ccc;
+    color: #000;
+    font-size: 18px;
+    font-weight: 600;
+    .camera {
+      margin-right: 15px;
+      color: #4392f7;
+    }
+  }
+  .middle {
+    width: calc(100% - 60px);
+    height: calc(100% - 60px);
+    // overflow: auto;
+    margin: 0 auto;
+    color: #000;
+    display: flex;
+
+    // border-bottom: 1px solid rgb(231, 231, 231);
+    .filter {
+      height: 100%;
+      display: flex;
+      // flex-wrap: wrap;
+      flex-direction: column;
+      overflow: auto;
+      .condition {
+        display: flex;
+        flex-direction: column;
+        margin: 10px 30px 10px 0;
+        h3 {
+          margin: 12px 12px 12px 0;
+        }
+        span {
+          margin: 0 10px 0 0;
+          font-size: 18px;
+          color: #000;
+        }
+        .addTime {
+          display: flex;
+          flex-wrap: wrap;
+          align-items: center;
+          .el-checkbox-group {
+            .el-checkbox {
+              margin: 0 15px 0 0;
+            }
+          }
+          :deep(.timePicker) {
+            width: 200px;
+          }
+        }
+      }
+    }
+    .gongneng {
+      margin: 10px 0;
+    }
+    :deep(.cont) {
+      width: 60%;
+      margin: 20px auto;
+    }
+    :deep(.download) {
+      display: flex;
+      align-items: center;
+      margin: 10px;
+    }
+    :deep(.download span) {
+      font-size: 16px;
+      margin-left: 20px;
+    }
+    :deep(.cont .el-button) {
+      margin-left: 60px;
+      margin-bottom: 30px;
+    }
+
+    :deep(.cont .accomplish) {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+    }
+    :deep(.cont .accomplish .el-button) {
+      width: 50%;
+      margin: 0;
+    }
+  }
+}
+.el-input {
+  width: 192px;
+}
+</style>

+ 22 - 0
text.json

@@ -0,0 +1,22 @@
+MD5( "${HA1}:${nonce}:${nc}:${cno
+nce}:${qop}:${HA2}" ) =
+6629fae49393a05397450978507c4
+ef1
+
+
+HA1 =
+MD5( "${username}:${realm}:${pas
+sword}" ) =
+939e7578ed9e3c518a452acee763
+bce9
+HA2 = MD5( "POST:${uri}" ) =
+39aff3a2bab6126f332b942af96d33
+66
+
+username="admin",realm="127.0.0.1host .com",nonce="dcd98b7102dd2f0e8b11d0f600bfh0c093"
+,uri="/dir/index,html",gop="auth",nc=00000001, cnonce="0a4f113b",response="f8877dald712423e963da0aed9fb7cf8",opague="5ccc069c403ebaf9f0171e9517f40e41"
+
+
+qop="auth",opaque="5ccc069c403ebaf9f0171e9517f40e41",realm="127.0.0.1@host.com",nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"
+
+username="admin",realm="127.0.0.1@host.com",nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",uri="/dir/index,html",qop="auth",nc=00000001,cnonce="0a4f113b",response="f8877dald712423e963da0aed9fb7cf8",opague="5ccc069c403ebaf9f0171e9517f40e41"

+ 93 - 0
vite.config.js

@@ -0,0 +1,93 @@
+import { defineConfig } from "vite";
+import vue from "@vitejs/plugin-vue";
+import path from "path";
+import { resolve, join } from "path";
+// https://vitejs.dev/config/
+export default defineConfig({
+  plugins: [vue()],
+  resolve: {
+    alias: {
+      "@": path.resolve("./src"), // @代替src
+    },
+  },
+  css: {
+    preprocessorOptions: {
+      scss: {
+        additionalData: `@import "./src/style/mixin.scss";`, // 此处全局的scss文件
+      },
+    },
+  },
+  server: {
+    host: "0.0.0.0",
+    port: 8990,
+    // 是否开启 https
+    // https: false,
+    // 线上地址
+    // proxy: {
+    //   "/carstop/carbook": {
+    //     target: "https://chtech.ncjti.edu.cn/carstop/carbook",
+    //     changeOrigin: true,
+    //     rewrite: (path) => path.replace(/^\/carstop\/carbook/, ""),
+    //   },
+    // },
+
+    // 测试地址
+    proxy: {
+      "/ride-sharing/carBuy": {
+        // target: "https://chtech.ncjti.edu.cn/testingServertomcat/carbook", // 测试环境
+        // target: "https://chtech.ncjti.edu.cn/carstop/carBuy", // 测试环境
+        target: "https://car.meiyishuoo.com/ride-sharing/carBuy", // 校团环境
+        changeOrigin: true,
+        rewrite: (path) => path.replace(/^\/ride-sharing\/carBuy/, ""),
+      },
+    },
+    // proxy: {
+    //   "/carstop/carBuy": {
+    //     // target: "https://chtech.ncjti.edu.cn/testingServertomcat/carbook", // 测试环境
+    //     target: "https://chtech.ncjti.edu.cn/carstop/carBuy", // 测试环境
+    //     // target: "https://car.meiyishuoo.com/ride-sharing/carBuy", // 校团线上环境
+    //     changeOrigin: true,
+    //     rewrite: (path) => path.replace(/^\/carstop\/carBuy/, ""),
+    //   },
+    // },
+  },
+  publicDir: "public",
+  base: "./",
+  // 打包配置
+  build: {
+    target: "modules", //设置最终构建的浏览器兼容目标  //es2015(编译成es5) | modules
+    outDir: "dist", // 构建得包名  默认:dist
+    assetsDir: "static", // 静态资源得存放路径文件名  assets
+    // sourcemap: false, //构建后是否生成 source map 文件
+    // brotliSize: false, // 启用/禁用 brotli 压缩大小报告。 禁用该功能可能会提高大型项目的构建性能
+    chunkSizeWarningLimit: 1000, //chunk 大小警告的限制(以 kbs 为单位)默认:500
+    // cssTarget: 'chrome61' //防止 vite 将 rgba() 颜色转化为 #RGBA 十六进制符号的形式  (要兼容的场景是安卓微信中的 webview 时,它不支持 CSS 中的 #RGBA 十六进制颜色符号)
+    rollupOptions: {
+      input: {
+        index: resolve(__dirname, "index.html"),
+      },
+      output: {
+        manualChunks(id) {
+          if (id.includes("node_modules")) {
+            return id
+              .toString()
+              .split("node_modules/")[1]
+              .split("/")[0]
+              .toString();
+          }
+        },
+        chunkFileNames: "static/js/[name]-[hash].js",
+        entryFileNames: "static/js/[name]-[hash].js",
+        assetFileNames: "static/[ext]/name-[hash].[ext]",
+      },
+    },
+    minify: "terser", // 项目压缩 :boolean | 'terser' | 'esbuild'
+    terserOptions: {
+      // 生产环境移除console
+      compress: {
+        drop_console: true,
+        drop_debugger: true,
+      },
+    },
+  },
+});