liwei19941102 2 лет назад
Родитель
Сommit
74f9080212

+ 3 - 2
package.json

@@ -23,19 +23,20 @@
     "animate.css": "4.1.1",
     "await-to-js": "^3.0.0",
     "axios": "^1.3.4",
+    "crypto-js": "^4.1.1",
     "echarts": "5.4.0",
     "element-plus": "2.2.27",
     "file-saver": "2.0.5",
     "fuse.js": "6.6.2",
     "js-cookie": "3.0.1",
     "jsencrypt": "3.3.1",
-    "crypto-js": "^4.1.1",
     "nprogress": "0.2.0",
     "path-browserify": "1.0.1",
     "path-to-regexp": "6.2.0",
     "pinia": "2.0.22",
     "screenfull": "6.0.0",
     "vform3-builds": "3.0.8",
+    "video.js": "^8.10.0",
     "vue": "3.2.45",
     "vue-cropper": "1.0.3",
     "vue-i18n": "9.2.2",
@@ -73,10 +74,10 @@
     "unplugin-auto-import": "0.13.0",
     "unplugin-icons": "0.15.1",
     "unplugin-vue-components": "0.23.0",
+    "unplugin-vue-setup-extend-plus": "0.4.9",
     "vite": "4.3.1",
     "vite-plugin-compression": "0.5.1",
     "vite-plugin-svg-icons": "2.0.1",
-    "unplugin-vue-setup-extend-plus": "0.4.9",
     "vitest": "^0.29.7",
     "vue-eslint-parser": "9.1.0",
     "vue-tsc": "0.35.0"

+ 1 - 0
src/api/login.ts

@@ -16,6 +16,7 @@ export function login(data: LoginData): AxiosPromise<LoginResult> {
     clientId: data.clientId || clientId,
     grantType: data.grantType || 'password'
   };
+  console.log(params);
   return request({
     url: '/auth/login',
     headers: {

BIN
src/assets/images/icon/九宫格.png


BIN
src/assets/images/icon/四宫格.png


BIN
src/assets/images/icon/容器.png


BIN
src/assets/images/map.png


+ 1 - 0
src/components/DictTag/index.vue

@@ -11,6 +11,7 @@
           :disable-transitions="true"
           :key="item.value + ''"
           :index="index"
+          :effect="item.elTagClass"
           :type="(item.elTagType === 'primary' || item.elTagType === 'default')? '' : item.elTagType"
           :class="item.elTagClass"
         >

+ 103 - 0
src/components/Public/table.vue

@@ -0,0 +1,103 @@
+<template>
+    <el-table :data="tableData" :border="true">
+        <el-table-column type="selection" width="55" />
+        <el-table-column v-for="item in columns.filter(i => i.visible)" :prop="item.prop" :label="item.label">
+            <template #default="scope" v-if="item.isTemplate">
+                <span>
+                    {{ getData(item.func, scope.row, item.prop) }}
+                    <!-- {{ eval(item.prop)}} -->
+                </span>
+            </template>
+            <template #default="scope" v-if="item.isTemplateJson">
+                <span>
+                    {{ getJsonData(scope.row, item.pprop, item.prop) }}
+                    <!-- {{ eval(item.prop)}} -->
+                </span>
+            </template>
+            <template #default="scope" v-if="item.isTemplateTag">
+                <div style="display: flex;flex-direction: row;">
+                <dict-tag :options="energy_type" :value="getObjectData(scope.row.ext1, 'energyType')" />
+                <dict-tag style="margin-left: 5px;" :options="business_type" :value="getObjectData(scope.row.ext1, 'bussinessType')" />
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="操作" v-show="showButton">
+            <template #default="scope" >
+                <div>
+                    <el-button v-for="button in buttons" :key="button.text" :type="button.type" link @click="Clickbutton(button.func)">{{ button.text
+                    }}</el-button>
+                </div>
+            </template>
+        </el-table-column>
+    </el-table>
+</template>
+  
+<script setup lang="ts">
+import { getType } from 'vue-types/dist/utils';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance
+const { energy_type,business_type } = toRefs<any>(proxy?.useDict("energy_type","business_type"));
+
+const route = useRoute();
+const router = useRouter();
+
+
+const props = defineProps({
+    columns: {
+        type: [Object],
+        default: ""
+    },
+    showButton:{
+        type: [Boolean],
+        default: true
+    }
+});
+
+const buttons = ref([
+  { type: 'primary', text: '管理',func:"goAdd" },
+  { type: 'primary', text: '删除' },
+])
+
+
+
+const tableData = ref([])
+
+const getData = (str, data, prop) => {
+    let value = eval(str + "(data." + prop + ")")
+    return value
+}
+
+const getObjectData = (data, prop) => {
+    console.log(data);
+    var obj = JSON.parse(data);
+    return eval("obj." + prop)
+}
+
+const getJsonData = (data, pprop, prop) => {
+    var data = eval("data." + pprop)
+    return getObjectData(data, prop)
+}
+
+const setDataList = (data) => {
+    console.log(data)
+    tableData.value = data
+}
+
+const setButton = (data) =>{
+    buttons.value = data
+}
+
+// getType(){
+
+// }
+
+defineExpose({
+    setDataList,
+    setButton
+})
+
+onMounted(() => {
+
+});
+</script>
+  

+ 27 - 1
src/router/index.ts

@@ -88,7 +88,33 @@ export const constantRoutes: RouteOption[] = [
         meta: { title: '个人中心', icon: 'user' }
       }
     ]
-  }
+  },
+  {
+    path: "/car/carInfo/add",
+    hidden: true,
+    component: Layout,
+    children: [
+      {
+        path: "",
+        component: () => import("@/views/car/carInfo/add"),
+        name: "CarInfoAdd",
+        meta: { title: "车辆信息新增", activeMenu: "/car/carInfo" },
+      },
+    ],
+  },
+  {
+    path: "/car/work/addWork",
+    hidden: true,
+    component: Layout,
+    children: [
+      {
+        path: "",
+        component: () => import("@/views/car/work/addCarWork"),
+        name: "CarWorkoAdd",
+        meta: { title: "车辆作业新增", activeMenu: "/car/work" },
+      },
+    ],
+  },
 ];
 
 // 动态路由,基于用户权限动态去加载

+ 3 - 1
src/utils/request.ts

@@ -40,7 +40,8 @@ service.interceptors.request.use(
     // 是否需要防止数据重复提交
     const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
     // 是否需要加密
-    const isEncrypt = (config.headers || {}).isEncrypt === 'true';
+    // const isEncrypt = (config.headers || {}).isEncrypt === 'true';
+    const isEncrypt = false
     if (getToken() && !isToken) {
       config.headers['Authorization'] = 'Bearer ' + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
     }
@@ -58,6 +59,7 @@ service.interceptors.request.use(
         data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
         time: new Date().getTime()
       };
+      console.log(requestObj);
       const sessionObj = cache.session.getJSON('sessionObj');
       if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
         cache.session.setJSON('sessionObj', requestObj);

+ 352 - 0
src/views/car/carInfo/add.vue

@@ -0,0 +1,352 @@
+<template>
+    <div style="padding: 10px 15px">
+        <el-card class="box-card">
+            <template #header>
+                <div class="card-header">
+                    <span>车辆信息</span>
+                    <div>
+                        <el-button type="warning" @click="">取消</el-button>
+                        <el-button type="primary" @click="submit()">保存</el-button>
+                    </div>
+                </div>
+
+            </template>
+            <el-row>
+                <el-col :span="24">
+                    <el-descriptions :column="3">
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    <span style="color: red">*</span> 车牌
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    <span style="color: red">*</span> 车辆分类
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-select v-model="value" class="m-2" placeholder="Select" style="width: 240px">
+                                    <el-option v-for="item in options" :key="item.value" :label="item.label"
+                                        :value="item.value" />
+                                </el-select>
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    <span style="color: red">*</span> 业务分类
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-select v-model="value" class="m-2" placeholder="Select" style="width: 240px">
+                                    <el-option v-for="item in options" :key="item.value" :label="item.label"
+                                        :value="item.value" />
+                                </el-select>
+                            </div>
+                        </el-descriptions-item>
+
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    <span style="color: red">*</span> 所属网格
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    <span style="color: red">*</span> 能耗类型
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-select v-model="value" class="m-2" placeholder="Select" style="width: 240px">
+                                    <el-option v-for="item in options" :key="item.value" :label="item.label"
+                                        :value="item.value" />
+                                </el-select>
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    <span style="color: red">*</span> 所属单位
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-select v-model="value" class="m-2" placeholder="Select" style="width: 240px">
+                                    <el-option v-for="item in options" :key="item.value" :label="item.label"
+                                        :value="item.value" />
+                                </el-select>
+                            </div>
+                        </el-descriptions-item>
+
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    车辆编号
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    车辆识别号
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <div class="content-w">
+                                    <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                                </div>
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    发动机号
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <div class="content-w">
+                                    <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                                </div>
+                            </div>
+                        </el-descriptions-item>
+
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    行驶证编号
+                                </div>
+
+                            </template>
+                            <div class="content-w">
+                                <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    行驶证保管人
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <div class="content-w">
+                                    <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                                </div>
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    采购审批单号
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <div class="content-w">
+                                    <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                                </div>
+                            </div>
+                        </el-descriptions-item>
+
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    车辆品牌
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    车辆信号
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <div class="content-w">
+                                    <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                                </div>
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    购置日期
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <div class="content-w">
+                                    <!-- <el-date-picker value-format="YYYY-MM-DD HH:mm:ss"
+                                        v-model="queryParams.endOfWarrantyPeriod" type="date" placeholder="请选择" /> -->
+                                </div>
+                            </div>
+                        </el-descriptions-item>
+
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    购置金额
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    使用年限
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <div class="content-w">
+                                    <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                                </div>
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    额定载重
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <div class="content-w">
+                                    <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                                </div>
+                            </div>
+                        </el-descriptions-item>
+
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 100px;text-align: right">
+                                    使用单位
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <div class="content-w">
+                                    <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                                </div>
+                            </div>
+                        </el-descriptions-item>
+                    </el-descriptions>
+                </el-col>
+
+                <el-col :span="24">
+                    <el-tabs type="card" class="demo-tabs" active-name="first">
+                        <el-tab-pane label="车辆设备" name="1">
+
+                        </el-tab-pane>
+                        <el-tab-pane label="维修记录" name="2">
+                            <tableElm :columns="wsColumns" ref="wsTable"></tableElm>
+                        </el-tab-pane>
+                        <el-tab-pane label="保养记录" name="3">
+
+                        </el-tab-pane>
+                        <el-tab-pane label="保险记录" name="4">
+
+                        </el-tab-pane>
+                        <el-tab-pane label="年检记录" name="5">
+
+                        </el-tab-pane>
+                        <el-tab-pane label="交通事故记录" name="6">
+
+                        </el-tab-pane>
+                        <el-tab-pane label="违章记录" name="7">
+
+                        </el-tab-pane>
+                        <el-tab-pane label="车辆变更记录" name="8">
+
+                        </el-tab-pane>
+                    </el-tabs>
+                </el-col>
+            </el-row>
+        </el-card>
+
+
+    </div>
+</template>
+  
+<script setup lang="ts">
+import { ref, toRaw } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { CarInfoVO, CarInfoQuery, CarInfoForm } from '@/api/carInfo/types';
+import tableElm from "@/components/Public/table.vue";
+
+const initFormData: CarInfoForm = {
+    id: undefined,
+    carNum: undefined,
+    carType: undefined,
+    deviceInfos: undefined,
+    repairInfo: undefined,
+    maintenanceInfo: undefined,
+    insuranceInfo: undefined,
+    inspectionInfo: undefined,
+    trafficAccidentInfo: undefined,
+    violationInfo: undefined,
+    changeInfo: undefined,
+    ext1: undefined,
+    ext2: undefined
+}
+
+const options = [
+    {
+        value: 'Option1',
+        label: 'Option1',
+    },
+    {
+        value: 'Option2',
+        label: 'Option2',
+    },
+    {
+        value: 'Option3',
+        label: 'Option3',
+    },
+    {
+        value: 'Option4',
+        label: 'Option4',
+    },
+    {
+        value: 'Option5',
+        label: 'Option5',
+    },
+]
+
+const wsColumns = ref([
+  // {label: '上层位置', prop: 'v', visible: true},
+  { label: '日期', prop: 'carNum', visible: true, isTemplate: false },
+  { label: '维修内容', prop: 'carNum', visible: true, isTemplate: false },
+  { label: '金额', prop: 'carNum', visible: true, isTemplate: false },
+])
+
+const submit =()=>{
+    
+}
+</script>
+  
+<style lang="scss" scoped>
+.card-header {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+}
+
+.content-w {
+    display: inline-flex;
+    max-width: 160px;
+}
+</style>
+  

+ 285 - 0
src/views/car/carInfo/index.vue

@@ -0,0 +1,285 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
+      :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch" style="display: flex;flex-direction: row;">
+        <div style="width: 85%;">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="车牌号" prop="carNum">
+            <el-input v-model="queryParams.carNum" placeholder="请输入车牌号" clearable style="width: 160px"
+              @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="驾驶员" prop="carNum">
+            <el-input v-model="queryParams.carNum" placeholder="请输入车牌号" clearable style="width: 160px"
+              @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="业务类型" prop="carNum">
+            <el-input v-model="queryParams.carNum" placeholder="请输入车牌号" clearable style="width: 160px"
+              @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="能耗类型" prop="carNum">
+            <el-input v-model="queryParams.carNum" placeholder="请输入车牌号" clearable style="width: 160px"
+              @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="网格" prop="carNum">
+            <el-input v-model="queryParams.carNum" placeholder="请输入车牌号" clearable style="width: 160px"
+              @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="单位" prop="carNum">
+            <el-input v-model="queryParams.carNum" placeholder="请输入车牌号" clearable style="width: 160px"
+              @keyup.enter="handleQuery" />
+          </el-form-item>
+        </el-form>
+        </div>
+        <div style="width: 15%;">
+        <el-form-item>
+            <el-button type="primary" @click="goadd">新增</el-button>
+            <el-button type="primary" @click="resetQuery">查询</el-button>
+          </el-form-item>
+        </div>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+
+      <tableElm :columns="columns" ref="table"></tableElm>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 添加或修改车辆信息对话框 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="carInfoFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="车牌号" prop="carNum">
+          <el-input v-model="form.carNum" placeholder="请输入车牌号" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup name="CarInfo" lang="ts">
+import { listCarInfo, getCarInfo, delCarInfo, addCarInfo, updateCarInfo } from '@/api/carInfo';
+import { CarInfoVO, CarInfoQuery, CarInfoForm } from '@/api/carInfo/types';
+import tableElm from "@/components/Public/table.vue";
+import { useRoute, useRouter } from "vue-router";
+
+const route = useRoute();
+const router = useRouter();
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const carInfoList = ref<CarInfoVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+
+const queryFormRef = ref<ElFormInstance>();
+const carInfoFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const table = ref(tableElm)
+
+const columns = ref([
+  // {label: '上层位置', prop: 'v', visible: true},
+  { label: '车牌号', prop: 'carNum', visible: true, isTemplate: false },
+  { label: '能源类型、业务类型', prop: 'ext1', visible: true, isTemplate: false, isTemplateTag: true },
+  { label: '车辆分类', prop: 'type',pprop:"ext1",visible: true, isTemplate: false,isTemplateJson:true },
+  { label: '网格', prop: 'wangge',pprop:"ext1",visible: true, isTemplate: false,isTemplateJson:true },
+  { label: '单位', prop: 'dept',pprop:"ext1",visible: true, isTemplate: false,isTemplateJson:true },
+  { label: '驾驶员、联系方式', prop: 'people',pprop:"ext1",visible: true, isTemplate: false,isTemplateJson:true},
+])
+
+const initFormData: CarInfoForm = {
+  id: undefined,
+  carNum: undefined,
+  carType: undefined,
+  deviceInfos: undefined,
+  repairInfo: undefined,
+  maintenanceInfo: undefined,
+  insuranceInfo: undefined,
+  inspectionInfo: undefined,
+  trafficAccidentInfo: undefined,
+  violationInfo: undefined,
+  changeInfo: undefined,
+  ext1: undefined,
+  ext2: undefined
+}
+const data = reactive<PageData<CarInfoForm, CarInfoQuery>>({
+  form: { ...initFormData },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    carNum: undefined,
+    carType: undefined,
+    deviceInfos: undefined,
+    repairInfo: undefined,
+    maintenanceInfo: undefined,
+    insuranceInfo: undefined,
+    inspectionInfo: undefined,
+    trafficAccidentInfo: undefined,
+    violationInfo: undefined,
+    changeInfo: undefined,
+    ext1: undefined,
+    ext2: undefined,
+    params: {
+    }
+  },
+  rules: {
+    id: [
+      { required: true, message: "编号不能为空", trigger: "blur" }
+    ],
+    carNum: [
+      { required: true, message: "车牌号不能为空", trigger: "blur" }
+    ],
+    carType: [
+      { required: true, message: "车类型不能为空", trigger: "change" }
+    ],
+    deviceInfos: [
+      { required: true, message: "所有车载设备信息不能为空", trigger: "blur" }
+    ],
+    repairInfo: [
+      { required: true, message: "维修信息不能为空", trigger: "blur" }
+    ],
+    maintenanceInfo: [
+      { required: true, message: "保养信息不能为空", trigger: "blur" }
+    ],
+    insuranceInfo: [
+      { required: true, message: "保险信息不能为空", trigger: "blur" }
+    ],
+    inspectionInfo: [
+      { required: true, message: "年检信息不能为空", trigger: "blur" }
+    ],
+    trafficAccidentInfo: [
+      { required: true, message: "交通事故信息不能为空", trigger: "blur" }
+    ],
+    violationInfo: [
+      { required: true, message: "违章信息不能为空", trigger: "blur" }
+    ],
+    changeInfo: [
+      { required: true, message: "车辆变更信息不能为空", trigger: "blur" }
+    ],
+    ext1: [
+      { required: true, message: "扩展1不能为空", trigger: "blur" }
+    ],
+    ext2: [
+      { required: true, message: "扩展2不能为空", trigger: "blur" }
+    ]
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+const goadd = () => {
+  router.push("/car/carInfo/add")
+}
+
+/** 查询车辆信息列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listCarInfo(queryParams.value);
+  table.value.setDataList(res.rows);
+  total.value = res.total;
+  loading.value = false;
+}
+
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+  form.value = { ...initFormData };
+  carInfoFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: CarInfoVO[]) => {
+  ids.value = selection.map(item => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = "添加车辆信息";
+}
+
+/** 修改按钮操作 */
+const handleUpdate = async (row?: CarInfoVO) => {
+  reset();
+  const _id = row?.id || ids.value[0]
+  const res = await getCarInfo(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改车辆信息";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+  carInfoFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateCarInfo(form.value).finally(() => buttonLoading.value = false);
+      } else {
+        await addCarInfo(form.value).finally(() => buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("修改成功");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: CarInfoVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('是否确认删除车辆信息编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+  await delCarInfo(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download('system/carInfo/export', {
+    ...queryParams.value
+  }, `carInfo_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+  getList();
+});
+</script>
+  

+ 266 - 0
src/views/car/work/addCarWork.vue

@@ -0,0 +1,266 @@
+<template>
+    <div style="padding: 10px 15px">
+        <el-card class="box-card">
+            <template #header>
+                <div class="card-header">
+                    <div style="display: flex;flex-direction: row;">
+                        <div style="width: 8px;height: 19px;opacity: 1;background: #409EFF"></div>
+                        <span
+                            style="font-family: PingFang SC;font-size: 14px;font-weight: normal;line-height: 19px;height: 19px;margin-left: 8px;">路线作业</span>
+                    </div>
+                    <div>
+                        <el-button type="warning" @click="">取消</el-button>
+                        <el-button type="primary" @click="submit()">保存</el-button>
+                    </div>
+                </div>
+
+            </template>
+            <el-row>
+                <el-col :span="24">
+                    <el-descriptions :column="3">
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 60px;text-align: right">
+                                    <span style="color: red">*</span> 作业名称
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-input v-model="initFormData.carNum" placeholder="请输入车牌" />
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 60px;text-align: right">
+                                    <span style="color: red">*</span> 作业类型
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-select v-model="value" class="m-2" placeholder="Select" style="width: 240px">
+                                    <el-option v-for="item in options" :key="item.value" :label="item.label"
+                                        :value="item.value" />
+                                </el-select>
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 60px;text-align: right">
+                                    <span style="color: red">*</span> 所属网格
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-select v-model="value" class="m-2" placeholder="Select" style="width: 240px">
+                                    <el-option v-for="item in options" :key="item.value" :label="item.label"
+                                        :value="item.value" />
+                                </el-select>
+                            </div>
+                        </el-descriptions-item>
+
+                    </el-descriptions>
+                    <el-descriptions :column="4" style="width: 70%;">
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 60px;text-align: right">
+                                    <span style="color: red">*</span> 关联车辆
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-select v-model="value" class="m-2" placeholder="Select" style="width: 240px">
+                                    <el-option v-for="item in options" :key="item.value" :label="item.label"
+                                        :value="item.value" />
+                                </el-select>
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 60px;text-align: right">
+                                    <span style="color: red">*</span> 司机
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-select v-model="value" class="m-2" placeholder="Select" style="width: 240px">
+                                    <el-option v-for="item in options" :key="item.value" :label="item.label"
+                                        :value="item.value" />
+                                </el-select>
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <template #label>
+                                <div style="display: inline-block;min-width: 60px;text-align: right">
+                                    <span style="color: red">*</span> 跟车人员
+                                </div>
+                            </template>
+                            <div class="content-w">
+                                <el-select v-model="value" class="m-2" placeholder="Select" style="width: 240px">
+                                    <el-option v-for="item in options" :key="item.value" :label="item.label"
+                                        :value="item.value" />
+                                </el-select>
+                            </div>
+                        </el-descriptions-item>
+                        <el-descriptions-item>
+                            <div class="content-w">
+                                <el-icon style="line-height: 45px;height: 45x;">
+                                    <CirclePlus />
+                                </el-icon>
+                            </div>
+                        </el-descriptions-item>
+                    </el-descriptions>
+                    <tableElm :columns="columns" ref="table"></tableElm>
+                </el-col>
+            </el-row>
+        </el-card>
+        <el-card class="box-card">
+            <template #header>
+                <div class="card-header">
+                    <div style="display: flex;flex-direction: row;">
+                        <div style="width: 8px;height: 19px;opacity: 1;background: #409EFF"></div>
+                        <span
+                            style="font-family: PingFang SC;font-size: 14px;font-weight: normal;line-height: 19px;height: 19px;margin-left: 8px;">路线站点</span>
+                    </div>
+                </div>
+            </template>
+            <div style="display: flex;flex-direction: row;width: 100%;">
+            <div style="width:25%">
+                <el-timeline>
+                    <el-timeline-item v-for="(activity, index) in activities" :key="index" :icon="activity.icon"
+                        :type="activity.type" :color="activity.color" :size="activity.size" :hollow="activity.hollow">
+                        <!-- {{ activity.content }} -->
+                        <div style="display: flex;flex-direction: column;" v-show="!activity.isadd"> 
+                            {{ activity.content }}
+                            <el-button style="width: 60px;">请选择</el-button>
+                        </div>
+                        <div v-show="activity.isadd">
+                            <el-button type="primary" style="width: 80px;">新增站点</el-button>
+                        </div>
+                    </el-timeline-item>
+                </el-timeline>
+            </div>
+            <div style="width: 75%;">
+                <!-- <mapDiv></mapDiv> -->
+                <img style="width:90%" src="@/assets/images/map.png"/>
+            </div>
+            </div>
+        </el-card>
+
+    </div>
+</template>
+  
+<script setup lang="ts">
+import { ref, toRaw } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { CarInfoVO, CarInfoQuery, CarInfoForm } from '@/api/carInfo/types';
+import tableElm from "@/components/Public/table.vue";
+import { MoreFilled } from '@element-plus/icons-vue'
+import content from "vform3-builds";
+// import mapDiv from "@/components/Map/index.vue";
+
+const initFormData: CarInfoForm = {
+    id: undefined,
+    carNum: undefined,
+    carType: undefined,
+    deviceInfos: undefined,
+    repairInfo: undefined,
+    maintenanceInfo: undefined,
+    insuranceInfo: undefined,
+    inspectionInfo: undefined,
+    trafficAccidentInfo: undefined,
+    violationInfo: undefined,
+    changeInfo: undefined,
+    ext1: undefined,
+    ext2: undefined
+}
+
+const options = [
+    {
+        value: 'Option1',
+        label: 'Option1',
+    },
+    {
+        value: 'Option2',
+        label: 'Option2',
+    },
+    {
+        value: 'Option3',
+        label: 'Option3',
+    },
+    {
+        value: 'Option4',
+        label: 'Option4',
+    },
+    {
+        value: 'Option5',
+        label: 'Option5',
+    },
+]
+
+const activities = [
+  {
+    content: '起点',
+    timestamp: '2018-04-12 20:46',
+    size: 'large',
+    color: '#0bbd87',
+  },
+  {
+    content: '1',
+    timestamp: '2018-04-03 20:46',
+    color:'#409EFF'
+  },
+  {
+    content: '1',
+    timestamp: '2018-04-03 20:46',
+    isadd:true
+  },
+  {
+    content: '终点',
+    timestamp: '2018-04-03 20:46',
+    size: 'large',
+    color:'#E37318'
+  },
+]
+
+const columns = ref([
+    // {label: '上层位置', prop: 'v', visible: true},
+    { label: '车牌号', prop: 'carNum', visible: true, isTemplate: false },
+    { label: '司机', prop: 'people', visible: true, isTemplate: false },
+    { label: '跟车人员', prop: 'gpeople', visible: true, isTemplate: false },
+])
+
+const table = ref(tableElm)
+
+const submit = () => {
+
+}
+
+onMounted(() => {
+    var res = {
+        rows: [
+            {
+                carNum: '苏A69213',
+                workTime: "2024-11-11 12:00:00",
+                workName: "运输钢铁",
+                type: "大件运输",
+                wangge: "仙林",
+                gpeople: "陈武",
+                people: "刘晨(13898219932)"
+
+            }
+        ],
+        total: 12
+    }
+    table.value.setDataList(res.rows);
+});
+
+</script>
+  
+<style lang="scss" scoped>
+.card-header {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+}
+
+.content-w {
+    display: inline-flex;
+    max-width: 160px;
+}
+</style>
+  

+ 276 - 0
src/views/car/work/carWork.vue

@@ -0,0 +1,276 @@
+<template>
+    <div class="p-2">
+        <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
+            :leave-active-class="proxy?.animate.searchAnimate.leave">
+            <div class="search" v-show="showSearch" style="display: flex;flex-direction: row;">
+                <div style="width: 85%;">
+                    <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+                        <el-form-item label="车牌号" prop="carNum">
+                            <el-input v-model="queryParams.carNum" placeholder="请输入车牌号" clearable style="width: 160px"
+                                @keyup.enter="handleQuery" />
+                        </el-form-item>
+                        <el-form-item label="站点" prop="carNum">
+                            <el-input v-model="queryParams.carNum" placeholder="请输入车牌号" clearable style="width: 160px"
+                                @keyup.enter="handleQuery" />
+                        </el-form-item>
+                        <el-form-item label="时间" prop="carNum">
+                            <el-date-picker v-model="value2" type="datetimerange" :shortcuts="shortcuts"
+                                range-separator="To" start-placeholder="Start date" end-placeholder="End date" />
+                        </el-form-item>
+                    </el-form>
+                </div>
+                <div style="width: 15%;">
+                    <el-form-item>
+                        <el-button type="primary" @click="goadd">新增</el-button>
+                        <el-button type="primary" @click="resetQuery">查询</el-button>
+                    </el-form-item>
+                </div>
+            </div>
+        </transition>
+        <el-card shadow="never">
+
+            <tableElm :columns="columns" ref="table"></tableElm>
+
+            <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
+                v-model:limit="queryParams.pageSize" @pagination="getList" />
+        </el-card>
+    </div>
+</template>
+
+<script setup name="CarInfo" lang="ts">
+import { listCarInfo, getCarInfo, delCarInfo, addCarInfo, updateCarInfo } from '@/api/carInfo';
+import { CarInfoVO, CarInfoQuery, CarInfoForm } from '@/api/carInfo/types';
+import tableElm from "@/components/Public/table.vue";
+import { useRoute, useRouter } from "vue-router";
+
+const route = useRoute();
+const router = useRouter();
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const carInfoList = ref<CarInfoVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const value2 = ref('')
+
+const queryFormRef = ref<ElFormInstance>();
+const carInfoFormRef = ref<ElFormInstance>();
+
+
+const dialog = reactive<DialogOption>({
+    visible: false,
+    title: ''
+});
+
+const table = ref(tableElm)
+
+const columns = ref([
+    // {label: '上层位置', prop: 'v', visible: true},
+    { label: '车牌号', prop: 'carNum', visible: true, isTemplate: false },
+    { label: '作业时间', prop: 'workTime', visible: true, isTemplate: false, },
+    { label: '作业名称', prop: 'workName', pprop: "ext1", visible: true, isTemplate: false },
+    { label: '作业类型', prop: 'type', pprop: "ext1", visible: true, isTemplate: false,},
+    { label: '网格', prop: 'wangge', pprop: "ext1", visible: true, isTemplate: false, },
+    { label: '跟车人员', prop: 'gpeople', pprop: "ext1", visible: true, isTemplate: false,  },
+    { label: '驾驶员、联系方式', prop: 'people', pprop: "ext1", visible: true, isTemplate: false, },
+])
+
+const initFormData: CarInfoForm = {
+    id: undefined,
+    carNum: undefined,
+    carType: undefined,
+    deviceInfos: undefined,
+    repairInfo: undefined,
+    maintenanceInfo: undefined,
+    insuranceInfo: undefined,
+    inspectionInfo: undefined,
+    trafficAccidentInfo: undefined,
+    violationInfo: undefined,
+    changeInfo: undefined,
+    ext1: undefined,
+    ext2: undefined
+}
+const data = reactive<PageData<CarInfoForm, CarInfoQuery>>({
+    form: { ...initFormData },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        carNum: undefined,
+        carType: undefined,
+        deviceInfos: undefined,
+        repairInfo: undefined,
+        maintenanceInfo: undefined,
+        insuranceInfo: undefined,
+        inspectionInfo: undefined,
+        trafficAccidentInfo: undefined,
+        violationInfo: undefined,
+        changeInfo: undefined,
+        ext1: undefined,
+        ext2: undefined,
+        params: {
+        }
+    },
+    rules: {
+        id: [
+            { required: true, message: "编号不能为空", trigger: "blur" }
+        ],
+        carNum: [
+            { required: true, message: "车牌号不能为空", trigger: "blur" }
+        ],
+        carType: [
+            { required: true, message: "车类型不能为空", trigger: "change" }
+        ],
+        deviceInfos: [
+            { required: true, message: "所有车载设备信息不能为空", trigger: "blur" }
+        ],
+        repairInfo: [
+            { required: true, message: "维修信息不能为空", trigger: "blur" }
+        ],
+        maintenanceInfo: [
+            { required: true, message: "保养信息不能为空", trigger: "blur" }
+        ],
+        insuranceInfo: [
+            { required: true, message: "保险信息不能为空", trigger: "blur" }
+        ],
+        inspectionInfo: [
+            { required: true, message: "年检信息不能为空", trigger: "blur" }
+        ],
+        trafficAccidentInfo: [
+            { required: true, message: "交通事故信息不能为空", trigger: "blur" }
+        ],
+        violationInfo: [
+            { required: true, message: "违章信息不能为空", trigger: "blur" }
+        ],
+        changeInfo: [
+            { required: true, message: "车辆变更信息不能为空", trigger: "blur" }
+        ],
+        ext1: [
+            { required: true, message: "扩展1不能为空", trigger: "blur" }
+        ],
+        ext2: [
+            { required: true, message: "扩展2不能为空", trigger: "blur" }
+        ]
+    }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+const goadd = () => {
+    router.push("/car/work/addWork")
+}
+
+/** 查询车辆信息列表 */
+const getList = async () => {
+    // loading.value = true;
+    // const res = await listCarInfo(queryParams.value);
+    var res = {
+          rows:[
+            {
+                carNum:'苏A69213',
+                workTime:"2024-11-11 12:00:00",
+                workName:"运输钢铁",
+                type:"大件运输",
+                wangge:"仙林",
+                gpeople:"陈武",
+                people:"刘晨(13898219932)"
+
+            }
+          ],
+          total:12
+    }
+    table.value.setDataList(res.rows);
+    total.value = res.total;
+    loading.value = false;
+}
+
+/** 取消按钮 */
+const cancel = () => {
+    reset();
+    dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+    form.value = { ...initFormData };
+    carInfoFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+    queryParams.value.pageNum = 1;
+    getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+    queryFormRef.value?.resetFields();
+    handleQuery();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: CarInfoVO[]) => {
+    ids.value = selection.map(item => item.id);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+    reset();
+    dialog.visible = true;
+    dialog.title = "添加车辆信息";
+}
+
+/** 修改按钮操作 */
+const handleUpdate = async (row?: CarInfoVO) => {
+    reset();
+    const _id = row?.id || ids.value[0]
+    const res = await getCarInfo(_id);
+    Object.assign(form.value, res.data);
+    dialog.visible = true;
+    dialog.title = "修改车辆信息";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+    carInfoFormRef.value?.validate(async (valid: boolean) => {
+        if (valid) {
+            buttonLoading.value = true;
+            if (form.value.id) {
+                await updateCarInfo(form.value).finally(() => buttonLoading.value = false);
+            } else {
+                await addCarInfo(form.value).finally(() => buttonLoading.value = false);
+            }
+            proxy?.$modal.msgSuccess("修改成功");
+            dialog.visible = false;
+            await getList();
+        }
+    });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: CarInfoVO) => {
+    const _ids = row?.id || ids.value;
+    await proxy?.$modal.confirm('是否确认删除车辆信息编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+    await delCarInfo(_ids);
+    proxy?.$modal.msgSuccess("删除成功");
+    await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+    proxy?.download('system/carInfo/export', {
+        ...queryParams.value
+    }, `carInfo_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+    getList();
+});
+</script>
+    

+ 237 - 0
src/views/car/work/index.vue

@@ -0,0 +1,237 @@
+<template>
+    <div class="p-2">
+        <el-tabs type="card" class="demo-tabs" active-name="first">
+            <el-tab-pane label="车辆作业" name="1">
+                  <carWork></carWork>
+            </el-tab-pane>
+            <el-tab-pane label="车辆排班" name="2">
+
+            </el-tab-pane>
+            <el-tab-pane label="人员请假" name="3">
+                   <peopleLeave></peopleLeave>
+            </el-tab-pane>
+        </el-tabs>
+    </div>
+</template>
+    
+<script setup name="CarInfo" lang="ts">
+import { listCarInfo, getCarInfo, delCarInfo, addCarInfo, updateCarInfo } from '@/api/carInfo';
+import { CarInfoVO, CarInfoQuery, CarInfoForm } from '@/api/carInfo/types';
+import tableElm from "@/components/Public/table.vue";
+import { useRoute, useRouter } from "vue-router";
+import carWork from './carWork.vue';
+import peopleLeave from './peopleLeave.vue';
+
+const route = useRoute();
+const router = useRouter();
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const carInfoList = ref<CarInfoVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+
+const queryFormRef = ref<ElFormInstance>();
+const carInfoFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+    visible: false,
+    title: ''
+});
+
+const table = ref(tableElm)
+
+const columns = ref([
+    // {label: '上层位置', prop: 'v', visible: true},
+    { label: '车牌号', prop: 'carNum', visible: true, isTemplate: false },
+    { label: '能源类型、业务类型', prop: 'ext1', visible: true, isTemplate: false, isTemplateTag: true },
+    { label: '车辆分类', prop: 'type', pprop: "ext1", visible: true, isTemplate: false, isTemplateJson: true },
+    { label: '网格', prop: 'wangge', pprop: "ext1", visible: true, isTemplate: false, isTemplateJson: true },
+    { label: '单位', prop: 'dept', pprop: "ext1", visible: true, isTemplate: false, isTemplateJson: true },
+    { label: '驾驶员、联系方式', prop: 'people', pprop: "ext1", visible: true, isTemplate: false, isTemplateJson: true },
+])
+
+const initFormData: CarInfoForm = {
+    id: undefined,
+    carNum: undefined,
+    carType: undefined,
+    deviceInfos: undefined,
+    repairInfo: undefined,
+    maintenanceInfo: undefined,
+    insuranceInfo: undefined,
+    inspectionInfo: undefined,
+    trafficAccidentInfo: undefined,
+    violationInfo: undefined,
+    changeInfo: undefined,
+    ext1: undefined,
+    ext2: undefined
+}
+const data = reactive<PageData<CarInfoForm, CarInfoQuery>>({
+    form: { ...initFormData },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        carNum: undefined,
+        carType: undefined,
+        deviceInfos: undefined,
+        repairInfo: undefined,
+        maintenanceInfo: undefined,
+        insuranceInfo: undefined,
+        inspectionInfo: undefined,
+        trafficAccidentInfo: undefined,
+        violationInfo: undefined,
+        changeInfo: undefined,
+        ext1: undefined,
+        ext2: undefined,
+        params: {
+        }
+    },
+    rules: {
+        id: [
+            { required: true, message: "编号不能为空", trigger: "blur" }
+        ],
+        carNum: [
+            { required: true, message: "车牌号不能为空", trigger: "blur" }
+        ],
+        carType: [
+            { required: true, message: "车类型不能为空", trigger: "change" }
+        ],
+        deviceInfos: [
+            { required: true, message: "所有车载设备信息不能为空", trigger: "blur" }
+        ],
+        repairInfo: [
+            { required: true, message: "维修信息不能为空", trigger: "blur" }
+        ],
+        maintenanceInfo: [
+            { required: true, message: "保养信息不能为空", trigger: "blur" }
+        ],
+        insuranceInfo: [
+            { required: true, message: "保险信息不能为空", trigger: "blur" }
+        ],
+        inspectionInfo: [
+            { required: true, message: "年检信息不能为空", trigger: "blur" }
+        ],
+        trafficAccidentInfo: [
+            { required: true, message: "交通事故信息不能为空", trigger: "blur" }
+        ],
+        violationInfo: [
+            { required: true, message: "违章信息不能为空", trigger: "blur" }
+        ],
+        changeInfo: [
+            { required: true, message: "车辆变更信息不能为空", trigger: "blur" }
+        ],
+        ext1: [
+            { required: true, message: "扩展1不能为空", trigger: "blur" }
+        ],
+        ext2: [
+            { required: true, message: "扩展2不能为空", trigger: "blur" }
+        ]
+    }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+const goadd = () => {
+    router.push("/car/carInfo/add")
+}
+
+/** 查询车辆信息列表 */
+const getList = async () => {
+    loading.value = true;
+    const res = await listCarInfo(queryParams.value);
+    table.value.setDataList(res.rows);
+    total.value = res.total;
+    loading.value = false;
+}
+
+/** 取消按钮 */
+const cancel = () => {
+    reset();
+    dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+    form.value = { ...initFormData };
+    carInfoFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+    queryParams.value.pageNum = 1;
+    getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+    queryFormRef.value?.resetFields();
+    handleQuery();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: CarInfoVO[]) => {
+    ids.value = selection.map(item => item.id);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+    reset();
+    dialog.visible = true;
+    dialog.title = "添加车辆信息";
+}
+
+/** 修改按钮操作 */
+const handleUpdate = async (row?: CarInfoVO) => {
+    reset();
+    const _id = row?.id || ids.value[0]
+    const res = await getCarInfo(_id);
+    Object.assign(form.value, res.data);
+    dialog.visible = true;
+    dialog.title = "修改车辆信息";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+    carInfoFormRef.value?.validate(async (valid: boolean) => {
+        if (valid) {
+            buttonLoading.value = true;
+            if (form.value.id) {
+                await updateCarInfo(form.value).finally(() => buttonLoading.value = false);
+            } else {
+                await addCarInfo(form.value).finally(() => buttonLoading.value = false);
+            }
+            proxy?.$modal.msgSuccess("修改成功");
+            dialog.visible = false;
+            await getList();
+        }
+    });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: CarInfoVO) => {
+    const _ids = row?.id || ids.value;
+    await proxy?.$modal.confirm('是否确认删除车辆信息编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+    await delCarInfo(_ids);
+    proxy?.$modal.msgSuccess("删除成功");
+    await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+    proxy?.download('system/carInfo/export', {
+        ...queryParams.value
+    }, `carInfo_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+   // getList();
+});
+</script>
+    

+ 277 - 0
src/views/car/work/peopleLeave.vue

@@ -0,0 +1,277 @@
+<template>
+    <div class="p-2">
+        <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
+            :leave-active-class="proxy?.animate.searchAnimate.leave">
+            <div class="search" v-show="showSearch" style="display: flex;flex-direction: row;">
+                <div style="width: 85%;">
+                    <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+                        <el-form-item label="时间" prop="carNum">
+                            <el-date-picker v-model="value2" type="datetimerange" :shortcuts="shortcuts"
+                                range-separator="To" start-placeholder="Start date" end-placeholder="End date" />
+                        </el-form-item>
+                        <el-form-item label="状态" prop="carNum">
+                            <el-select v-model="value" class="m-2" placeholder="Select" style="width: 240px">
+                                    <el-option v-for="item in options" :key="item.value" :label="item.label"
+                                        :value="item.value" />
+                                </el-select>
+                        </el-form-item>
+                    </el-form>
+                </div>
+                <div style="width: 15%;">
+                    <el-form-item>
+                        <el-button type="primary" @click="goadd">新增</el-button>
+                        <el-button type="primary" @click="resetQuery">查询</el-button>
+                    </el-form-item>
+                </div>
+            </div>
+        </transition>
+        <el-card shadow="never">
+
+            <tableElm :columns="columns" ref="table"></tableElm>
+
+            <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
+                v-model:limit="queryParams.pageSize" @pagination="getList" />
+        </el-card>
+    </div>
+</template>
+
+<script setup name="CarInfo" lang="ts">
+import { listCarInfo, getCarInfo, delCarInfo, addCarInfo, updateCarInfo } from '@/api/carInfo';
+import { CarInfoVO, CarInfoQuery, CarInfoForm } from '@/api/carInfo/types';
+import tableElm from "@/components/Public/table.vue";
+import { useRoute, useRouter } from "vue-router";
+import carWork from './carWork.vue';
+
+const route = useRoute();
+const router = useRouter();
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const carInfoList = ref<CarInfoVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const value2 = ref('')
+
+const queryFormRef = ref<ElFormInstance>();
+const carInfoFormRef = ref<ElFormInstance>();
+
+
+const dialog = reactive<DialogOption>({
+    visible: false,
+    title: ''
+});
+
+const table = ref(tableElm)
+
+const columns = ref([
+    // {label: '上层位置', prop: 'v', visible: true},
+    { label: '姓名', prop: 'carNum', visible: true, isTemplate: false },
+    { label: '请假时间', prop: 'workTime', visible: true, isTemplate: false, },
+    { label: '事由', prop: 'workName', pprop: "ext1", visible: true, isTemplate: false },
+    { label: '状态', prop: 'type', pprop: "ext1", visible: true, isTemplate: false,},
+])
+
+const initFormData: CarInfoForm = {
+    id: undefined,
+    carNum: undefined,
+    carType: undefined,
+    deviceInfos: undefined,
+    repairInfo: undefined,
+    maintenanceInfo: undefined,
+    insuranceInfo: undefined,
+    inspectionInfo: undefined,
+    trafficAccidentInfo: undefined,
+    violationInfo: undefined,
+    changeInfo: undefined,
+    ext1: undefined,
+    ext2: undefined
+}
+const data = reactive<PageData<CarInfoForm, CarInfoQuery>>({
+    form: { ...initFormData },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        carNum: undefined,
+        carType: undefined,
+        deviceInfos: undefined,
+        repairInfo: undefined,
+        maintenanceInfo: undefined,
+        insuranceInfo: undefined,
+        inspectionInfo: undefined,
+        trafficAccidentInfo: undefined,
+        violationInfo: undefined,
+        changeInfo: undefined,
+        ext1: undefined,
+        ext2: undefined,
+        params: {
+        }
+    },
+    rules: {
+        id: [
+            { required: true, message: "编号不能为空", trigger: "blur" }
+        ],
+        carNum: [
+            { required: true, message: "车牌号不能为空", trigger: "blur" }
+        ],
+        carType: [
+            { required: true, message: "车类型不能为空", trigger: "change" }
+        ],
+        deviceInfos: [
+            { required: true, message: "所有车载设备信息不能为空", trigger: "blur" }
+        ],
+        repairInfo: [
+            { required: true, message: "维修信息不能为空", trigger: "blur" }
+        ],
+        maintenanceInfo: [
+            { required: true, message: "保养信息不能为空", trigger: "blur" }
+        ],
+        insuranceInfo: [
+            { required: true, message: "保险信息不能为空", trigger: "blur" }
+        ],
+        inspectionInfo: [
+            { required: true, message: "年检信息不能为空", trigger: "blur" }
+        ],
+        trafficAccidentInfo: [
+            { required: true, message: "交通事故信息不能为空", trigger: "blur" }
+        ],
+        violationInfo: [
+            { required: true, message: "违章信息不能为空", trigger: "blur" }
+        ],
+        changeInfo: [
+            { required: true, message: "车辆变更信息不能为空", trigger: "blur" }
+        ],
+        ext1: [
+            { required: true, message: "扩展1不能为空", trigger: "blur" }
+        ],
+        ext2: [
+            { required: true, message: "扩展2不能为空", trigger: "blur" }
+        ]
+    }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+const goadd = () => {
+    router.push("/car/work/addWork")
+}
+
+/** 查询车辆信息列表 */
+const getList = async () => {
+    // loading.value = true;
+    // const res = await listCarInfo(queryParams.value);
+    var res = {
+          rows:[
+            {
+                carNum:'苏A69213',
+                workTime:"2024-11-11 12:00:00",
+                workName:"探亲",
+                type:"待审核",
+                wangge:"仙林",
+                gpeople:"陈武",
+                people:"刘晨(13898219932)"
+
+            }
+          ],
+          total:12
+    }
+    var buttons = [
+  { type: 'primary', text: '批准',func:"goAdd" },
+  { type: 'primary', text: '拒绝' },
+]
+    table.value.setDataList(res.rows);
+    table.value.setButton(buttons);
+    total.value = res.total;
+    loading.value = false;
+}
+
+/** 取消按钮 */
+const cancel = () => {
+    reset();
+    dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+    form.value = { ...initFormData };
+    carInfoFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+    queryParams.value.pageNum = 1;
+    getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+    queryFormRef.value?.resetFields();
+    handleQuery();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: CarInfoVO[]) => {
+    ids.value = selection.map(item => item.id);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+    reset();
+    dialog.visible = true;
+    dialog.title = "添加车辆信息";
+}
+
+/** 修改按钮操作 */
+const handleUpdate = async (row?: CarInfoVO) => {
+    reset();
+    const _id = row?.id || ids.value[0]
+    const res = await getCarInfo(_id);
+    Object.assign(form.value, res.data);
+    dialog.visible = true;
+    dialog.title = "修改车辆信息";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+    carInfoFormRef.value?.validate(async (valid: boolean) => {
+        if (valid) {
+            buttonLoading.value = true;
+            if (form.value.id) {
+                await updateCarInfo(form.value).finally(() => buttonLoading.value = false);
+            } else {
+                await addCarInfo(form.value).finally(() => buttonLoading.value = false);
+            }
+            proxy?.$modal.msgSuccess("修改成功");
+            dialog.visible = false;
+            await getList();
+        }
+    });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: CarInfoVO) => {
+    const _ids = row?.id || ids.value;
+    await proxy?.$modal.confirm('是否确认删除车辆信息编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+    await delCarInfo(_ids);
+    proxy?.$modal.msgSuccess("删除成功");
+    await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+    proxy?.download('system/carInfo/export', {
+        ...queryParams.value
+    }, `carInfo_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+    getList();
+});
+</script>
+    

+ 177 - 0
src/views/yunying/video/index.vue

@@ -0,0 +1,177 @@
+<template>
+  <div class="p-2">
+    <div style="display: flex;flex-direction: row;">
+      <div style="width:20%">
+        <div class="card-header">
+          <div style="display: flex;flex-direction: row;">
+            <div style="width: 8px;height: 19px;opacity: 1;background: #409EFF"></div>
+            <span
+              style="font-family: PingFang SC;font-size: 14px;font-weight: normal;line-height: 19px;height: 19px;margin-left: 2px;">车辆信息</span>
+          </div>
+        </div>
+        <div style="margin-top: 1vh;">
+          <el-input v-model="filterText" placeholder="输入车牌号" />
+          <el-tree show-checkbox ref="treeRef" class="filter-tree" :data="data" :props="defaultProps" default-expand-all
+            :filter-node-method="filterNode" />
+        </div>
+      </div>
+      <div style="width: 77%;margin-left: 2%;">
+        <div class="card-header">
+          <div style="display: flex;flex-direction: row;">
+            <div style="width: 8px;height: 19px;opacity: 1;background: #409EFF"></div>
+            <span
+              style="font-family: PingFang SC;font-size: 14px;font-weight: normal;line-height: 19px;height: 19px;margin-left: 2px;">视频</span>
+          </div>
+          <div>
+            <img style="width: 14.5px;height:14.5px;" @click="videoType = 1" src="@/assets/images/icon/容器.png" />
+            <img style="width: 14.5px;height:14.5px;margin-left: 5px" @click="videoType = 4" src="@/assets/images/icon/四宫格.png" />
+            <img style="width: 14.5px;height:14.5px;margin-left: 5px;" @click="videoType = 9" src="@/assets/images/icon/九宫格.png" />
+          </div>
+        </div>
+        <div style="margin-top: 5vh;">
+          <div style="width: 100%;" v-if="videoType == 1">
+            <!-- <div v-for="item in 9"> -->
+            <video v-for="item in 1" style="width: 99%;margin-left:0.5%" controls="controls" :autoplay="false"
+              muted="muted" :ref="`videoref${item}`"></video>
+            <!-- </div> -->
+          </div>
+          <div style="width: 100%;" v-if="videoType == 4">
+            <!-- <div v-for="item in 9"> -->
+            <video v-for="item in 4" style="width: 49%;margin-left:0.5%" controls="controls" :autoplay="false"
+              muted="muted" :ref="`videoref${item}`"></video>
+            <!-- </div> -->
+          </div>
+          <div style="width: 100%;" v-if="videoType == 9">
+            <!-- <div v-for="item in 9"> -->
+            <video v-for="item in 9" style="width: 32%;margin-left:0.5%" controls="controls" :autoplay="false"
+              muted="muted" :ref="`videoref${item}`"></video>
+            <!-- </div> -->
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+    
+<script setup name="CarInfo" lang="ts">
+import { listCarInfo, getCarInfo, delCarInfo, addCarInfo, updateCarInfo } from '@/api/carInfo';
+import { CarInfoVO, CarInfoQuery, CarInfoForm } from '@/api/carInfo/types';
+import tableElm from "@/components/Public/table.vue";
+import { useRoute, useRouter } from "vue-router";
+
+import videojs from "video.js"
+import "video.js/dist/video-js.css"
+
+const route = useRoute();
+const router = useRouter();
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const carInfoList = ref<CarInfoVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+
+const queryFormRef = ref<ElFormInstance>();
+const carInfoFormRef = ref<ElFormInstance>();
+
+const videoPlayer = ref(null)
+
+const myPlayer = ref(null)
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const table = ref(tableElm)
+
+const videoType = ref(4)
+
+
+const initFormData: CarInfoForm = {
+  id: undefined,
+  carNum: undefined,
+  carType: undefined,
+  deviceInfos: undefined,
+  repairInfo: undefined,
+  maintenanceInfo: undefined,
+  insuranceInfo: undefined,
+  inspectionInfo: undefined,
+  trafficAccidentInfo: undefined,
+  violationInfo: undefined,
+  changeInfo: undefined,
+  ext1: undefined,
+  ext2: undefined
+}
+
+interface Tree {
+  [key: string]: any
+}
+
+const filterText = ref('')
+const treeRef = ref<InstanceType<typeof ElTree>>()
+
+const defaultProps = {
+  children: 'children',
+  label: 'carNum',
+}
+
+watch(filterText, (val) => {
+  treeRef.value!.filter(val)
+})
+
+const filterNode = (value: string, data: Tree) => {
+  if (!value) return true
+  return data.label.includes(value)
+}
+
+const data: Tree[] = [
+  {
+    id: 1,
+    carNum: '在线车辆',
+    children: [
+      {carNum:'苏A8762'},
+      {carNum:'苏A8762'},
+    ],
+  },
+]
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 查询车辆信息列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listCarInfo({ pageSize:1000 });
+  for(var index in res.rows){
+      data[0].children.push(res.rows[index]);
+  }
+  console.log(data);
+}
+
+onMounted(() => {
+  getList();
+});
+
+onUnmounted(() => {
+  if (myPlayer.value) {
+    myPlayer.value.dispose()
+  }
+})
+
+
+</script>
+
+
+<style lang="scss" scoped>
+.card-header {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+}
+</style>
+    

+ 1 - 1
vite.config.ts

@@ -26,7 +26,7 @@ export default defineConfig(({ mode, command }: ConfigEnv): UserConfig => {
       open: true,
       proxy: {
         [env.VITE_APP_BASE_API]: {
-          target: 'http://localhost:8080',
+          target: 'http://localhost:8089',
           changeOrigin: true,
           ws: true,
           rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')