pyt
2025-03-31 ce4987c482702cd152acdcceeb61a8ea1061a376
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/H5/shehong-vehicle-supervision
1 文件已复制
2 文件已重命名
8个文件已修改
13个文件已添加
4973 ■■■■■ 已修改文件
package-lock.json 2620 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/notice@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ShowDelConfirm/index.vue 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layouts/index.vue 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/router.js 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/car-manage/components/detailModal.vue 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/car-manage/detail.vue 263 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/car-manage/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/car-type/index.vue 82 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/home/index.vue 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/login/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/order/component/detailModal.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/driver/component/detailModal.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/driver/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/role/addEdit.vue 354 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/role/detail.vue 350 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/role/index.vue 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/role/service.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/user/components/addEdit.vue 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/user/components/disb.vue 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/user/components/resetPassWord.vue 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/user/components/viewData.vue 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/user/index.vue 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/systemManage/user/service.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
Diff too large
src/assets/notice@2x.png
src/components/ShowDelConfirm/index.vue
New file
@@ -0,0 +1,108 @@
<template>
  <div>
    <el-dialog top="40vh" :visible.sync="show" :show-close="false" :append-to-body="true" :close-on-click-modal="false"
      width="433px">
      <div class="top-con a-center" slot="title">
        <div class="left">
          <img src="@/assets/notice@2x.png" style="width: 24px;height: 24px;margin-right: 14px;" />
          <div class="title">{{ title }}</div>
        </div>
      </div>
      <div class="lh--32 fs--20">
        {{ tip }}
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="$emit('close')">取消</el-button>
        <el-button :type="btnType" @click="$emit('confirm')">{{ okText }}</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
export default {
  components: {},
  props: {
    show: {
      type: Boolean,
      default: false,
    },
    title: {
      type: String,
      default: '确认要删除这条信息吗?',
    },
    tip: {
      type: String,
      default: '删除后信息将无法找回',
    },
    okText: {
      type: String,
      default: '确认',
    },
    btnType: {
      type: String,
      default: 'danger',
    }
  },
  data() {
    return {};
  },
  computed: {},
  watch: {},
  created() { },
  mounted() { },
  methods: {},
};
</script>
<style scoped lang="less">
.left {
  display: flex;
}
::v-deep .el-dialog {
  border-radius: 12px;
  .el-dialog__header {
    padding-top: 28px;
    padding-right: 27px;
    padding-left: 34px;
    padding-bottom: 11px;
  }
  .el-dialog__body {
    border-top: unset;
    padding: unset;
    padding-left: 73px;
    padding-right: 20px;
  }
  .el-dialog__footer {
    border-top: unset;
    padding-top: 18px;
    padding-right: 27px;
    padding-bottom: 29px;
  }
}
.bgcolor1 {
  background: rgba(22, 119, 255, 1);
}
.top-con {
  display: flex;
  justify-content: space-between;
  .title {
    font-family: PingFangSC, PingFang SC;
    font-weight: 600;
    font-size: 16px;
    color: rgba(0, 0, 0, 1);
    margin-bottom: 13px;
  }
}
.dialog-footer {
  display: flex;
  justify-content: flex-end;
}
</style>
src/layouts/index.vue
@@ -23,15 +23,36 @@
        </div>
        <div class="menu w100 bgColor1">
            <div v-for="(item, index) in routesList" :key="index" class="flex a-center h100">
                <div v-for="(item2, index2) in item.children" :key="index2" class="h100">
                    <div @click="$router.push(item2.path)" v-if="!item2.meta.hide"
                        class="flex a-center j-center h100 w--160 menuItemHover pointer"
                        :class="item2.path == $route.path && 'bgColor2'">
                        <img v-if="item2.meta.icon" :src="require(`@/assets/routerIcon/${item2.meta.icon}.png`)"
                <div v-if="!item.meta || !item.meta.title" class="h100">
                    <template v-for="(item2, index2) in item.children">
                        <div :key="index2" @click="pushPath(item2.path)" v-if="!item2.meta.hide"
                            class="flex a-center j-center h100 w--160 menuItemHover pointer"
                            :class="item2.path == $route.path && 'bgColor2'">
                            <img v-if="item2.meta.icon" :src="require(`@/assets/routerIcon/${item2.meta.icon}.png`)"
                                class="w--15 h--15 mr--12 shrink0" />
                            <div class="color1">
                                {{ item2.meta.title }}
                            </div>
                        </div>
                    </template>
                </div>
                <div v-else :class="$route.path.includes('systemManage') && 'bgColor2'"
                    class="h100 w--160 menuItemHover dropdown" @mouseenter="routerDropdown(true)"
                    @mouseleave="routerDropdown(false)">
                    <div class="flex a-center j-center h100">
                        <img :src="require(`@/assets/routerIcon/${item.meta.icon}.png`)"
                            class="w--15 h--15 mr--12 shrink0" />
                        <div class="color1">
                            {{ item2.meta.title }}
                            {{ item.meta.title }}
                        </div>
                    </div>
                    <div v-if="routerIsOpen" class="dropdown-menu positionTwo">
                        <template v-for="(item2, index2) in item.children">
                            <div v-if="!item2.meta.hide" :key="index2" @click="pushPath(item.path + '/' + item2.path)"
                                class="dropdown-item flex a-center">
                                {{ item2.meta.title }}
                            </div>
                        </template>
                    </div>
                </div>
            </div>
@@ -49,6 +70,7 @@
        return {
            routesList: routes,
            isOpen: false,
            routerIsOpen: false,
            menuItems: [
                { text: '密码设置' },
                { text: '退出登录' },
@@ -58,8 +80,15 @@
    created() {
    },
    methods: {
        pushPath(path) {
            this.$router.push(path)
            if (this.routerIsOpen) this.routerIsOpen = false
        },
        toggleDropdown(state) {
            this.isOpen = state;
        },
        routerDropdown(state) {
            this.routerIsOpen = state;
        }
    }
}
@@ -135,6 +164,11 @@
    cursor: pointer;
}
.positionTwo {
    transform: unset !important;
    width: 160px !important;
}
.dropdown-menu {
    position: absolute;
    top: 100%;
src/router/router.js
@@ -47,20 +47,6 @@
        ]
    },
    {
        path: '/driver',
        component: Layout,
        children: [
            {
                path: '/driver',
                component: () => import('@/view/driver'),
                meta: {
                    title: '驾驶员管理',
                    icon: 'driver'
                }
            }
        ]
    },
    {
        path: '/car',
        component: Layout,
        children: [
@@ -132,6 +118,60 @@
                }
            }
        ]
    },
    {
        path: '/systemManage',
        meta: {
            title: "系统管理",
            icon: 'sys',
        },
        component: Layout,
        children: [
            {
                path: 'driver',
                component: () => import('@/view/systemManage/driver'),
                meta: {
                    title: '驾驶员列表',
                }
            },
            {
                path: 'type',
                component: () => import('@/view/car-type'),
                meta: {
                    title: '车辆分类',
                }
            },
            {
                path: 'user',
                component: () => import('@/view/systemManage/user'),
                meta: {
                    title: '用户管理',
                }
            },
            {
                path: 'role',
                component: () => import('@/view/systemManage/role'),
                meta: {
                    title: '角色管理',
                }
            },
            {
                path: 'add-role',
                component: () => import('@/view/systemManage/role/addEdit.vue'),
                meta: {
                    title: '添加角色',
                    hide: true
                }
            },
            {
                path: 'role-detail',
                component: () => import('@/view/systemManage/role/detail'),
                meta: {
                    title: '角色详情',
                    hide: true
                }
            }
        ]
    }
]
src/view/car-manage/components/detailModal.vue
New file
@@ -0,0 +1,63 @@
<template>
    <div>
        <el-dialog title="车辆基础信息" :visible.sync="dialogVisible" width="80%" :modal-append-to-body="false">
            <el-descriptions title="" :column="3">
                <el-descriptions-item label="公司名称">射洪洪达出租车有限公司</el-descriptions-item>
                <el-descriptions-item label="车牌号码">91510922769973987B</el-descriptions-item>
                <el-descriptions-item label="车辆颜色">四川省遂宁市射洪市太和街道万洪二路33、35、37号</el-descriptions-item>
                <el-descriptions-item label="核定载客位">14725836902</el-descriptions-item>
                <el-descriptions-item label="车辆厂牌">射洪洪达出租车有限公司</el-descriptions-item>
                <el-descriptions-item label="车辆型号">91510922769973987B</el-descriptions-item>
                <el-descriptions-item label="车辆类型">四川省遂宁市射洪市太和街道万洪二路33、35、37号</el-descriptions-item>
                <el-descriptions-item label="所属车主">14725836902</el-descriptions-item>
                <el-descriptions-item label="车身颜色">射洪洪达出租车有限公司</el-descriptions-item>
                <el-descriptions-item label="发动机号">91510922769973987B</el-descriptions-item>
                <el-descriptions-item label="车辆VIN码">四川省遂宁市射洪市太和街道万洪二路33、35、37号</el-descriptions-item>
                <el-descriptions-item label="车辆注册日期">14725836902</el-descriptions-item>
                <el-descriptions-item label="车辆燃料类型">射洪洪达出租车有限公司</el-descriptions-item>
                <el-descriptions-item label="发动机排量">91510922769973987B</el-descriptions-item>
                <el-descriptions-item label="车辆运输证发证机构">四川省遂宁市射洪市太和街道万洪二路33、35、37号</el-descriptions-item>
                <el-descriptions-item label="车辆经营区域">14725836902</el-descriptions-item>
                <el-descriptions-item label="运输证字号">射洪洪达出租车有限公司</el-descriptions-item>
                <el-descriptions-item label="车辆运输证有效期起">91510922769973987B</el-descriptions-item>
                <el-descriptions-item label="车辆运输证有效期止">四川省遂宁市射洪市太和街道万洪二路33、35、37号</el-descriptions-item>
                <el-descriptions-item label="车辆初次登记日期">14725836902</el-descriptions-item>
                <el-descriptions-item label="车辆检修状态">射洪洪达出租车有限公司</el-descriptions-item>
                <el-descriptions-item label="车辆年度审验状态">91510922769973987B</el-descriptions-item>
                <el-descriptions-item label="卫星定位装置品牌">四川省遂宁市射洪市太和街道万洪二路33、35、37号</el-descriptions-item>
                <el-descriptions-item label="卫星定位装置型号">14725836902</el-descriptions-item>
                <el-descriptions-item label="卫星定位装置IMEI号">射洪洪达出租车有限公司</el-descriptions-item>
                <el-descriptions-item label="卫星定位设备安装日期">91510922769973987B</el-descriptions-item>
                <el-descriptions-item label="注册日期">四川省遂宁市射洪市太和街道万洪二路33、35、37号</el-descriptions-item>
                <el-descriptions-item label="营运类型">14725836902</el-descriptions-item>
                <el-descriptions-item label="运价类型编码">射洪洪达出租车有限公司</el-descriptions-item>
            </el-descriptions>
        </el-dialog>
    </div>
</template>
<script>
export default {
    components: {},
    props: {},
    data() {
        return {
            dialogVisible: false
        };
    },
    computed: {},
    watch: {},
    created() { },
    mounted() { },
    methods: {
        closeClick() {
            this.dialogVisible = false
        }
    },
};
</script>
<style scoped lang="less">
::v-deep .el-descriptions .el-descriptions-item__cell {
    padding-bottom: 20px;
}
</style>
src/view/car-manage/detail.vue
@@ -1,18 +1,214 @@
<template>
    <div class="container">
        <div class=""></div>
    <div class="containers">
        <div class="info-content flex">
            <div class="info-left flex3 flex">
                <div class="info-back flex shrink0">
                    <span class="back-size"><i class="el-icon-back"></i>返回</span>
                </div>
                <div class="info-content-left ml--100">
                    <el-descriptions :column="2">
                        <el-descriptions-item label="公司名称">kooriookami</el-descriptions-item>
                        <el-descriptions-item label="车牌号码">18100000000</el-descriptions-item>
                        <el-descriptions-item label="车牌颜色">苏州市</el-descriptions-item>
                        <el-descriptions-item label="车辆营运类型">kooriookami</el-descriptions-item>
                        <el-descriptions-item label="所属车主">18100000000</el-descriptions-item>
                        <el-descriptions-item label="联系电话">苏州市</el-descriptions-item>
                        <el-descriptions-item label="经营区域">kooriookami</el-descriptions-item>
                        <el-descriptions-item label="车辆年度审验">18100000000</el-descriptions-item>
                        <el-descriptions-item label="驾驶证">
                            <img class="img-size" src="../../assets/homeImg/img1.png"></img>
                        </el-descriptions-item>
                        <el-descriptions-item label="行驶证">
                            <img class="img-size" src="../../assets/homeImg/img2.png"></img>
                        </el-descriptions-item>
                    </el-descriptions>
                    <div class="info-btn" @click="showDetail">
                        车辆详细信息<i class="el-icon-arrow-right"></i>
                    </div>
                </div>
            </div>
            <div class="info-right flex2">
                <video style="width: 100%;height: 100%;" src="../../assets/homeImg/QQ20241223-103023.mp4"></video>
            </div>
        </div>
        <div class="tab-content ml--100 mr--30">
            <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
                <el-tab-pane label="订单记录" name="first">
                    <div class="table-box mt--23">
                        <el-table :data="tableData" border stripe style="width: 100%">
                            <el-table-column prop="date" label="序号"></el-table-column>
                            <el-table-column prop="name" label="订单编号"></el-table-column>
                            <el-table-column prop="name" label="车牌号"></el-table-column>
                            <el-table-column prop="name" label="车辆颜色"></el-table-column>
                            <el-table-column prop="name" label="车辆所属公司"></el-table-column>
                            <el-table-column prop="name" label="上车地点"></el-table-column>
                            <el-table-column prop="name" label="下车地点"></el-table-column>
                            <el-table-column prop="name" label="载客里程"></el-table-column>
                            <el-table-column prop="name" label="驾驶员姓名"></el-table-column>
                            <el-table-column prop="name" label="驾驶员电话"></el-table-column>
                            <el-table-column prop="name" label="派单时间"></el-table-column>
                            <el-table-column prop="name" label="订单金额"></el-table-column>
                            <el-table-column prop="name" label="操作">
                                <template slot-scope="scope">
                                    <el-button type="text" @click="handle(scope.$index, scope.row)">详情</el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                        <div class="pagination-box relative mt--23 flex j-end">
                            <el-pagination :popper-append-to-body="false" @size-change="handleSizeChange"
                                @current-change="handleCurrentChange" :current-page="searchForm.page" background
                                layout="total,sizes,prev, pager, next,jumper" :total="searchForm.total">
                            </el-pagination>
                        </div>
                    </div>
                </el-tab-pane>
                <el-tab-pane label="预警记录" name="second">
                    <div class="table-box mt--23">
                        <el-table :data="tableData" border stripe style="width: 100%">
                            <el-table-column prop="date" label="序号" fixed width="80"></el-table-column>
                            <el-table-column prop="name" label="车辆名称" width="120" fixed></el-table-column>
                            <el-table-column prop="name" label="车牌号码" width="120" fixed></el-table-column>
                            <el-table-column prop="name" label="持续报警" width="120"></el-table-column>
                            <el-table-column prop="name" label="近15分钟情况" width="120"></el-table-column>
                            <el-table-column prop="name" label="驾驶员名称" width="120"></el-table-column>
                            <el-table-column prop="name" label="所属公司" width="120"></el-table-column>
                            <el-table-column prop="name" label="终端编号" width="120"></el-table-column>
                            <el-table-column prop="name" label="开始报警时间" width="120"></el-table-column>
                            <el-table-column prop="name" label="结束报警时间" width="120"></el-table-column>
                            <el-table-column prop="name" label="持续时长" width="120"></el-table-column>
                            <el-table-column prop="name" label="持续里程数" width="120"></el-table-column>
                            <el-table-column prop="name" label="报警类型" width="120"></el-table-column>
                            <el-table-column prop="name" label="报警次数" width="120"></el-table-column>
                            <el-table-column prop="name" label="处理状态" width="120"></el-table-column>
                            <el-table-column prop="name" label="处理人" width="120"></el-table-column>
                            <el-table-column prop="name" label="处理时间" width="120"></el-table-column>
                            <el-table-column prop="name" label="处理描述" width="240"></el-table-column>
                        </el-table>
                        <div class="pagination-box relative mt--23 flex j-end">
                            <el-pagination :popper-append-to-body="false" @size-change="handleSizeChange"
                                @current-change="handleCurrentChange" :current-page="searchForm.page" background
                                layout="total,sizes,prev, pager, next,jumper" :total="searchForm.total">
                            </el-pagination>
                        </div>
                    </div>
                </el-tab-pane>
                <el-tab-pane label="行驶轨迹" name="third">
                    <div class="form flex j-between mt--23" style="align-items: end;">
                        <div class="form-left ml--30">
                            <el-form :inline="true" :model="searchForm" class="demo-form-inline">
                                <el-form-item label="选择轨迹时间范围:" prop="level" class="unset_m"
                                    style="margin-right: 15px;">
                                    <el-date-picker v-model="searchForm.date" type="daterange" range-separator="至"
                                        start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd"
                                        >
                                    </el-date-picker>
                                </el-form-item>
                            </el-form>
                        </div>
                        <div class="form-right shrink0 mr--24 mb--23">
                            <el-button class="search-button h--40 w--90 fs--14" icon="el-icon-search" type="primary"
                                size="small" @click="search">查询</el-button>
                            <el-button @click="reset" icon="el-icon-refresh-right"
                                class="reset-button h--40 w--90 fs--14" size="small">重置</el-button>
                        </div>
                    </div>
                    <div class="mapContainer" id="mapContainer"></div>
                </el-tab-pane>
            </el-tabs>
        </div>
        <DetailModal ref="detailModal" />
    </div>
</template>
<script>
import AMapLoader from "@amap/amap-jsapi-loader";
import DetailModal from "./components/detailModal.vue";
export default {
    name: "detail",
    components: { DetailModal },
    data() {
        return {
            id: ''
            id: '',
            tableData: [],
            searchForm: {
                date: '',
                type: '',
                level: '',
                name: '',
                total: 40,
                page: 1,
                pageSize: 10
            },
            activeName: 'first'
        }
    },
    mounted() {
        this.initMap();
    },
    methods: {
        handleClick(){
        },
        search(){},
        reset() {
        },
        showDetail() {
            this.$refs.detailModal.dialogVisible = true
        },
        initMap() {
            window._AMapSecurityConfig = {
                securityJsCode: this.$secretKey,
            };
            AMapLoader.load({
                key: this.$mapKey,
                version: "2.0",
                plugins: [
                    "AMap.ToolBar",
                ],
            })
                .then((AMap) => {
                    this.map = new AMap.Map("mapContainer", {
                        center: [105.574542, 30.5061493],
                        zoom: 15,
                    });
                    this.map.addControl(new AMap.ToolBar());
                    let path = [
                        new AMap.LngLat(105.57, 30.51),
                        new AMap.LngLat(116.382122, 39.901176),
                        new AMap.LngLat(116.387271, 39.912501),
                        new AMap.LngLat(116.398258, 39.9046),
                    ]
                    const content = `<div class="custom-content-marker">
                                        <img src="${require("@/assets/logo.png")}">
                                    </div>`;
                    const marker = new AMap.Marker({
                        content: content, //自定义点标记覆盖物内容
                        position: [105.57, 30.51], //基点位置
                        offset: new AMap.Pixel(-30, -15), //相对于基点的偏移位置
                    });
                    this.map.add(marker);
                    let polyline = new AMap.Polyline({
                        path: path,
                        strokeWeight: 2, //线条宽度
                        strokeColor: "red", //线条颜色
                        lineJoin: "round", //折线拐点连接处样式
                    });
                    this.map.add(polyline);
                })
                .catch((e) => {
                });
        },
        handleSizeChange(e) {
            this.searchForm.pageSize = e
        },
        handleCurrentChange(e) {
            this.searchForm.page = e
        },
        // getDetail() {
        //     this.$axios.get(`/api/complaint/detail/${this.id}`).then(res => {
        //         console.log(res);
@@ -24,5 +220,66 @@
}
</script>
<style scoped lang="less">
.containers {
    height: 100vh;
    overflow-y: auto;
}
.info-back {
    cursor: pointer;
    // flex-shrink: ;
}
.info-content {
    padding: 30px;
}
::v-deep .el-descriptions-item__container {
    font-size: 18px;
    .el-descriptions-item__label {
        font-weight: 600;
    }
    .el-descriptions-item__content {
        width: 200px;
    }
}
.img-size {
    width: 169px;
    height: 99px;
}
.info-btn {
    display: flex;
    align-items: center;
    justify-content: center;
}
.info-btn {
    font-size: 18px;
    color: #0E6EFD;
    cursor: pointer;
    margin-top: 60px;
}
.flex3 {
    flex: 3;
}
.flex2 {
    flex: 2;
}
.back-size {
    font-size: 24px;
    color: #0E6EFD;
    cursor: pointer;
}
#mapContainer {
    width: 100%;
    height: 600px;
}
</style>
src/view/car-manage/index.vue
@@ -52,9 +52,7 @@
                <el-button @click="reset" icon="el-icon-refresh-right" class="reset-button h--40 w--90 fs--14"
                    size="small">重置</el-button>
            </div>
        </div>
        <div class="table-box-btn mt--23 ml--30">
            <el-button class="search-button h--40 w--90 fs--14" icon="el-icon-top" type="primary" size="small"
                @click="exportExcell">导出</el-button>
src/view/car-type/index.vue
copy from src/view/driver/index.vue copy to src/view/car-type/index.vue
File was copied from src/view/driver/index.vue
@@ -3,10 +3,10 @@
        <div class="form flex a-center j-between mt--23">
            <div class="form-left ml--30">
                <el-form :inline="true" :model="searchForm" class="demo-form-inline">
                    <el-form-item label="公司名称:" prop="level" class="unset_m" style="margin-right: 15px;">
                    <el-form-item label="类型名称:" prop="level" class="unset_m" style="margin-right: 15px;">
                        <el-input v-model="searchForm.level" placeholder="请输入"></el-input>
                    </el-form-item>
                    <el-form-item label="驾驶员手机号:" prop="name" class="unset_m" style="margin-right: 15px;">
                    <!-- <el-form-item label="驾驶员手机号:" prop="name" class="unset_m" style="margin-right: 15px;">
                        <el-input v-model="searchForm.name" placeholder="请输入"></el-input>
                    </el-form-item>
                    <el-form-item label="驾驶员姓名:" prop="name" class="unset_m" style="margin-right: 15px;">
@@ -14,7 +14,7 @@
                    </el-form-item>
                    <el-form-item label="紧急联系人姓名:" prop="date" class="unset_m" style="margin-right: 15px;">
                        <el-input v-model="searchForm.name" placeholder="请输入"></el-input>
                    </el-form-item>
                    </el-form-item> -->
                </el-form>
            </div>
            <div class="form-right mr--24 mb--22">
@@ -27,10 +27,14 @@
        <div class="table-box ml--30 mt--23 mr--30">
            <el-table :data="tableData" border stripe style="width: 100%" :height="height">
                <el-table-column prop="date" label="序号"></el-table-column>
                <el-table-column prop="name" label="机动车驾驶员姓名"></el-table-column>
                <el-table-column prop="name" label="车辆所属公司"></el-table-column>
                <el-table-column prop="name" label="机动车驾驶证号"></el-table-column>
                <el-table-column prop="name" label="驾驶员通信地址"></el-table-column>
                <el-table-column prop="name" label="图标">
                    <template slot-scope="scope">
                        <img :src="scope.row.img" alt="" style="width: 40px;height: 40px;" />
                    </template>
                </el-table-column>
                <el-table-column prop="name" label="类型"></el-table-column>
                <el-table-column prop="name" label="车辆数"></el-table-column>
                <!-- <el-table-column prop="name" label="驾驶员通信地址"></el-table-column>
                <el-table-column prop="name" label="紧急情况联系人"></el-table-column>
                <el-table-column prop="name" label="紧急情况联系人电话"></el-table-column>
                <el-table-column prop="name" label="驾驶员手机号"></el-table-column>
@@ -39,7 +43,7 @@
                    <template slot-scope="scope">
                        <el-button @click="showDetail">详情</el-button>
                    </template>
                </el-table-column>
                </el-table-column> -->
            </el-table>
            <div class="relative mt--23 flex j-end">
                <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
@@ -48,52 +52,44 @@
                </el-pagination>
            </div>
        </div>
        <DetailModal ref="detailModal" />
    </div>
</template>
<script>
import DetailModal from "./component/detailModal"
export default {
    components: {
        DetailModal
  data() {
    return {
      searchForm: {
        total: 0,
        page: 1,
        pageSize: 10,
      },
      tableData: [],
    };
  },
  computed: {
    height() {
      return this.$baseTableHeight();
    },
    data() {
        return {
            searchForm: {
                total: 0,
                page: 1,
                pageSize: 10
            },
            tableData: [],
        };
  },
  methods: {
    showDetail() {
      this.$refs.detailModal.dialogVisible = true;
    },
    computed: {
        height() {
            return this.$baseTableHeight()
        },
    reset() {},
    search() {},
    handleSizeChange(e) {
      this.searchForm.pageSize = e;
    },
    methods: {
        showDetail() {
            this.$refs.detailModal.dialogVisible = true
        },
        reset() {
        },
        search() {
        },
        handleSizeChange(e) {
            this.searchForm.pageSize = e
        },
        handleCurrentChange(e) {
            this.searchForm.page = e
        },
    }
}
    handleCurrentChange(e) {
      this.searchForm.page = e;
    },
  },
};
</script>
<style scoped lang="less">
::v-deep .el-form-item .el-input__inner {
    width: 240px;
  width: 240px;
}
</style>
src/view/home/index.vue
@@ -251,7 +251,6 @@
  created() {
    //初始化窗口点击事件
    window.toCarDetail = (record) => {
      console.log("111111111111222222", record);
      this.toCarDetail(record);
    };
    window.fullScreen = () => {
@@ -468,6 +467,16 @@
            infoWindow.setContent(e.target.content);
            infoWindow.open(this.map, e.target.getPosition());
          });
          // // 监听地图缩放事件
          // map.on("zoomchange", ()=> {
          //   var zoom = map.getZoom();
          //   var size = 30 + (zoom - 3) * 2; // 根据缩放级别计算 marker 大小
          //   var size1 = 20 + (zoom - 3) * 2;
          //   marker.setIcon({
          //     // image: "https://example.com/marker.png",
          //     size: new AMap.Size(size, size1),
          //   });
          // });
        });
      }
    },
@@ -482,12 +491,13 @@
              <canvas ref="canvas" id="myCanvas" style="width: 460px; height: 330px;display:none" crossOrigin="anonymous"></canvas>
              <video
              ref="video"
               crossorigin="anonymous"
               style="width: 460px; height: 330px; border-radius: 9px" 
               id="monitoringCard"
               ref="monitoringCard"
                :controls="false"
                autoPlay
                src="${require("../../assets/homeImg/QQ20241223-103023.mp4")}"
                src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
                width="620">
              </video>
            <div style="position: absolute; right: 11px; top: 10px">
@@ -534,18 +544,8 @@
      }
    },
    chartTnit(x, y1, y2) {
      // 基于准备好的dom,初始化echarts实例 grid: {
      //   width: "auto",
      //   height: "auto",
      //   left: "0",
      //   right: "5%",
      //   bottom: "0",
      //   top: "15%",
      //   containLabel: true,
      // },
      // 基于准备好的dom,初始化echarts实例
      const myChart = echarts.init(document.getElementById("countChart"));
      console.log("22222222222222222", myChart);
      // 绘制数量图表
      myChart.setOption({
        tooltip: {
@@ -590,7 +590,6 @@
            itemStyle: {
              borderRadius: [20, 20, 20, 20],
              color: (params) => {
                console.log("111111", params);
                return ["#5B8FF9", "#5AD8A6", "#F6BD16", "#6DC8EC", "#945FB9"][
                  params.dataIndex
                ];
@@ -600,123 +599,6 @@
          },
        ],
      });
      // myChart.setOption({
      //   tooltip: {
      //     trigger: "axis",
      //     axisPointer: {
      //       // 坐标轴指示器,坐标轴触发有效
      //       type: "cross", // 默认为直线,可选为:'line' | 'cross'
      //     },
      //     //  formatter: '{b}月\n'
      //   },
      //   legend: {
      //     x: "right",
      //     itemWidth: 12,
      //     itemHeight: 12,
      //     itemGap: 56, // 设置间距
      //     textStyle: {
      //       color: "rgba(68, 68, 68, 0.65)",
      //       fontSize: 16,
      //       padding: [0, 0, 0, 8],
      //     },
      //     data: ["充电电费", "充电服务费"],
      //   },
      //   xAxis: {
      //     type: "category",
      //     axisLabel: {
      //       color: "rgba(80, 105, 122, 1)",
      //       fontSize: 15,
      //       lineHeight: 23,
      //       fontFamily: "PingFangSC, PingFang SC",
      //       // formatter:'{value}月'
      //     },
      //     axisTick: {
      //       show: true,
      //     },
      //     axisLine: {
      //       lineStyle: {
      //         color: "RGBA(234, 234, 234, 1)",
      //       },
      //     },
      //     splitLine: {
      //       // 去掉网格线
      //       show: false,
      //     },
      //     data: x,
      //   },
      //   yAxis: {
      //     type: "value",
      //     axisLabel: {
      //       color: "rgba(80, 105, 122, 1)",
      //       fontSize: 15,
      //       lineHeight: 23,
      //       fontFamily: "PingFangSC, PingFang SC",
      //       formatter: "{value} 元",
      //     },
      //     splitLine: {
      //       // show: false  // 去掉网格线
      //       color: "rgb(242, 242, 242, 1)",
      //     },
      //     axisTick: {
      //       alignWithLabel: true,
      //     },
      //   },
      //   series: [
      //     {
      //       name: "充电服务费",
      //       type: "bar",
      //       barMaxWidth: 13,
      //       // showBackground: true,
      //       itemStyle: {
      //         color: new echarts.graphic.LinearGradient(
      //           0,
      //           0,
      //           0,
      //           1, // x0, y0, x1, y1
      //           [
      //             { offset: 0, color: "rgba(157, 245, 144, 1)" }, // 0% 处的颜色
      //             { offset: 1, color: "rgba(107, 228, 178, 1)" }, // 100% 处的颜色
      //           ]
      //         ),
      //       },
      //       // label: {
      //       //     show: true,
      //       //     fontSize: 12,
      //       //     lineHeight: 17,
      //       //     // align:'right',
      //       //     color: 'rgba(123, 123, 123, 1)',
      //       //     position: 'right', // 设置标签显示在柱状条右侧
      //       //     // formatter: function (params) {
      //       //     //     return params.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + '户'
      //       //     // } // 使用模板字符串保留两位小数
      //       // },
      //       data: y1,
      //     },
      //     {
      //       name: "充电电费",
      //       type: "bar",
      //       barMaxWidth: 13,
      //       // showBackground: true,
      //       itemStyle: {
      //         color: new echarts.graphic.LinearGradient(
      //           0,
      //           0,
      //           0,
      //           1, // x0, y0, x1, y1
      //           [
      //             { offset: 0, color: "rgba(98, 251, 255, 1)" }, // 0% 处的颜色
      //             { offset: 1, color: "rgba(61, 221, 255, 1)" }, // 100% 处的颜色
      //           ]
      //         ),
      //       },
      //       data: y2,
      //     },
      //   ],
      // });
      myChart.resize();
    },
    // 获取预警排行榜数据
@@ -726,7 +608,6 @@
      console.log("跳转车辆详情");
    },
    fullScreen() {
      console.log("全屏");
      const video = document.getElementById("monitoringCard");
      if (video.requestFullscreen) {
        video.requestFullscreen();
@@ -742,8 +623,6 @@
      }
    },
    shotScreen() {
      console.log("截图");
      // 获取video和canvas元素
      const video = document.getElementById("monitoringCard");
      const canvas = document.getElementById("myCanvas");
src/view/login/index.vue
@@ -20,7 +20,8 @@
          </div>
          <div @click="resetCodeStr" class="fs--18 lh--40 border1 pointer">{{ codeStr }}</div>
        </div>
        <div @click="login" class="mt--40 br--5 lh--50 pointer bgcolor1 color1">登录</div>
        <el-button :loading="loginLoading" @click="login"
          class="mt--40 w100 br--5 pointer bgcolor1 color1">登录</el-button>
      </div>
    </div>
  </div>
@@ -28,11 +29,13 @@
<script>
import { generateVerificationCode } from '@/utils/utils';
import { mapMutations } from 'vuex';
export default {
  components: {},
  props: {},
  data() {
    return {
      loginLoading: false,//登录loading
      account: '',
      password: '',
      code: '',
@@ -49,7 +52,10 @@
    document.removeEventListener("keydown", this.handleKeyDown);
  },
  methods: {
    ...mapMutations(['setToken', 'clearToken']),
    login() {
      this.loginLoading = false;
      // this.setToken(res.access_token);
      this.$router.push('/home')
    },
    handleKeyDown(event) {
src/view/order/component/detailModal.vue
@@ -119,6 +119,6 @@
#mapContainer {
    width: 100%;
    height: 600px;
    height: 300px;
}
</style>
src/view/systemManage/driver/component/detailModal.vue
src/view/systemManage/driver/index.vue
File was renamed from src/view/driver/index.vue
@@ -2,7 +2,7 @@
    <div>
        <div class="form flex a-center j-between mt--23">
            <div class="form-left ml--30">
                <el-form :inline="true" :model="searchForm" class="demo-form-inline">
                <el-form :inline="true" :model="searchForm">
                    <el-form-item label="公司名称:" prop="level" class="unset_m" style="margin-right: 15px;">
                        <el-input v-model="searchForm.level" placeholder="请输入"></el-input>
                    </el-form-item>
@@ -36,7 +36,7 @@
                <el-table-column prop="name" label="驾驶员手机号"></el-table-column>
                <el-table-column prop="name" label="驾驶员合同签订公司"></el-table-column>
                <el-table-column prop="name" label="操作">
                    <template slot-scope="scope">
                    <template slot-scope="{row}">
                        <el-button @click="showDetail">详情</el-button>
                    </template>
                </el-table-column>
src/view/systemManage/role/addEdit.vue
New file
@@ -0,0 +1,354 @@
<template>
  <div>
    <el-card class="box_card">
      <div class="title_box">
        <div></div>
        <div>角色信息</div>
      </div>
      <el-form ref="form" :inline="true" :model="form" :rules="rules" label-width="80px" class="demo-form-inline">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="form.roleName" placeholder="请输入角色名称"></el-input>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" placeholder="请输入备注"></el-input>
        </el-form-item>
      </el-form>
      <div class="title_box">
        <div></div>
        <div>操作权限</div>
      </div>
      <div>
        <div class="header">
          <div class="w20">模块名称</div>
          <div class="sconed">
            <div class="subpage">
              <div class="title">页面名称</div>
              <div class="btns">权限</div>
            </div>
          </div>
        </div>
        <div v-for="item in menu" :key="item.menuId">
          <div class="row">
            <div class="w20">
              <el-checkbox v-model="item.selected" @change="(e) => {
                setCheckStatus1(item.menuId, e)
              }" :checked="item.selected">
                {{ item.menuName }}
              </el-checkbox>
            </div>
            <div class="sconed">
              <div class="subpage"
                v-if="(item.children.length > 0 && item.children[0].children.length > 0) || item.children[0].children.menuType != 'F'">
                <div v-for="item1 in item.children" :key="item1.menuId" class="two">
                  <div class="left">
                    <el-checkbox v-model="item1.selected" @change="(e) => {
                      setCheckStatus2(item1.menuId, e, item.menuId)
                    }" :checked="item1.selected">
                      {{ item1.menuName }}
                    </el-checkbox>
                  </div>
                  <div class="right">
                    <div v-for="item2 in item1.children" :key="item2.menuId">
                      <el-checkbox v-model="item2.selected" @change="(e) => {
                        setCheckStatus3(item2.menuId, e, item1.menuId, item.menuId)
                      }" :checked="item2.selected">
                        {{ item2.menuName }}
                      </el-checkbox>
                    </div>
                  </div>
                </div>
              </div>
              <div class="subpage" v-else>
                <div class="two">
                  <!-- <div class="left">
                  </div> -->
                  <div class="right">
                    <div v-for="item1 in item.children" :key="item1.menuId">
                      <el-checkbox v-model="item1.selected" @change="(e) => {
                        setCheckStatus2(item1.menuId, e, item.menuId,)
                      }" :checked="item1.selected">
                        {{ item1.menuName }}
                      </el-checkbox>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="btn_box">
        <el-button @click="$router.go(-1)">返回</el-button>
        <el-button type="primary" @click="onSubmit">保存</el-button>
      </div>
    </el-card>
  </div>
</template>
<script>
import { roleInfoFromUserId, getRoleInfo, add, edit } from './service.js'
export default {
  components: {},
  props: {},
  data() {
    return {
      form: {
        roleName: "",
        remark: "",
      },
      rules: {
        roleName: [
          { required: true, message: "请输入角色名称", trigger: "blur" },
        ],
      },
      menu: [],
    };
  },
  computed: {},
  watch: {},
  created() {
    // roleInfoFromUserId({ userId: 1 }).then(res => {
    //   if (this.$route.query.roleId) {
    //     getRoleInfo({ roleId: this.$route.query.roleId }).then(resp => {
    //       this.menu = this.setSelectedIds(res.data.data, resp.data.data.menus || []);
    //       this.form = {
    //         roleName: resp.data.data.roleName,
    //         remark: resp.data.data.remark,
    //         roleId: resp.data.data.roleId
    //       }
    //     })
    //   } else {
    //     this.menu = res.data.data
    //   }
    // })
  },
  mounted() { },
  methods: {
    setSelectedIds(arr, selectKeyList) {
      function traverse(item) {
        item.selected = selectKeyList.includes(item.menuId);
        if (item.children && item.children.length > 0) {
          item.children.forEach(traverse);
        }
      }
      arr.forEach(traverse);
      return arr;
    },
    onSubmit() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          if (this.getSelectedIds(this.menu).length == 0) {
            this.$baseMessage('请勾选操作权限', 'warning')
            return
          }
          let obj = {
            ...this.form,
            menuIds: this.getSelectedIds(this.menu)
          }
          if (this.$route.query && this.$route.query.roleId) {
            obj.roleId = this.$route.query.roleId
            edit(obj).then(() => {
              this.$baseMessage('保存成功', 'success')
              this.$router.go(-1)
            })
          } else {
            add(obj).then(() => {
              this.$baseMessage('保存成功', 'success')
              this.$router.go(-1)
            })
          }
        }
      })
    },
    getSelectedIds(arr) {
      let result = [];
      function traverse(item) {
        if (item.selected) {
          result.push(item.menuId);
        }
        if (item.children && item.children.length > 0) {
          for (let children of item.children) {
            traverse(children);
          }
        }
      }
      for (let item of arr) {
        traverse(item);
      }
      return result;
    },
    setCheckStatus1(id, status) { //点击第1级
      if (!status) {
        this.menu = this.menu.map(item => {
          if (item.menuId == id) {
            item.selected = status
            if (item.children.length > 0) {
              item.children = item.children.map(item1 => {
                item1.selected = status
                if (item1.children.length > 0) {
                  item1.children = item1.children.map(item2 => {
                    item2.selected = status
                    return { ...item2 }
                  })
                }
                return { ...item1 }
              })
            }
          }
          return { ...item }
        })
      } else {
        this.menu = this.menu.map(item => {
          if (item.menuId == id) {
            item.selected = true
          }
          return { ...item }
        })
      }
    },
    setCheckStatus2(id, status, aId) { //点击第2级
      this.menu = this.menu.map(item => {
        if (item.menuId == aId) {
          item.selected = true
          if (item.children.length > 0) {
            item.children = item.children.map(item1 => {
              if (item1.menuId == id) {
                item1.selected = status
              }
              return { ...item1 }
            })
          }
        }
        return { ...item }
      })
    },
    setCheckStatus3(id, status, bId, aId) {//点击第3级
      this.menu = this.menu.map(item => {
        if (item.menuId == aId) {
          item.selected = true
          if (item.children.length > 0) {
            item.children = item.children.map(item1 => {
              if (item1.menuId == bId) {
                item1.selected = true
                if (item1.children.length > 0) {
                  item1.children = item1.children.map(item2 => {
                    if (item2.menuId == id) {
                      item2.selected = status
                    }
                    return { ...item2 }
                  })
                }
              }
              return { ...item1 }
            })
          }
        }
        return { ...item }
      })
    }
  },
};
</script>
<style lang="less" scoped>
.box_card {
  margin-bottom: 0;
  .title_box {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
    font-weight: bold;
    div:first-child {
      width: 4px;
      height: 16px;
      background: #598DEC;
      margin-right: 8px;
    }
  }
  .btn_box {
    margin-top: 40px;
    text-align: center;
  }
}
.el-checkbox {
  display: flex;
  align-items: center;
}
.row,
.header {
  display: flex;
  align-items: center;
  border: 1px solid #e8e8e8;
  .w20 {
    width: 15%;
    padding: 8px 20px;
  }
  .sconed {
    flex: 1;
    .subpage {
      .title {
        border: 1px solid #e8e8e8;
        border-top: none;
        border-bottom: none;
      }
      .two {
        display: flex;
        align-items: center;
        border: 1px solid #e8e8e8;
        border-top: none;
        border-right: none;
        .left {
          width: 200px;
          padding: 13px 20px;
          border-right: 1px solid #e8e8e8;
        }
        .right {
          display: flex;
          flex: 1;
          div {
            padding: 13px 0 13px 20px;
          }
        }
      }
      .two:last-child {
        border-bottom: none;
      }
      .btns {
        display: flex;
        align-items: center;
        padding: 0 20px;
      }
    }
  }
}
.header {
  background-color: #e8e8e8;
  .subpage {
    display: flex;
  }
  .title {
    width: 200px;
    padding: 8px 20px;
  }
}
</style>
src/view/systemManage/role/detail.vue
New file
@@ -0,0 +1,350 @@
<template>
  <div>
    <el-card class="box_card">
      <div>{{ form.roleName }}</div>
      <div>备注:{{ form.remark }}</div>
    </el-card>
    <el-card>
      <el-tabs v-model="activeName">
        <el-tab-pane label="操作权限" name="first">
          <div class="header">
            <div class="w20">模块名称</div>
            <div class="sconed">
              <div class="subpage">
                <div class="title">页面名称</div>
                <div class="btns">权限</div>
              </div>
            </div>
          </div>
          <div v-for="item in menu" :key="item.menuId">
            <div class="row">
              <div class="w20">
                <el-checkbox disabled :checked="item.selected">
                  {{ item.menuName }}
                </el-checkbox>
              </div>
              <div class="sconed">
                <div class="subpage"
                  v-if="(item.children.length > 0 && item.children[0].children.length > 0) || item.children[0].children.menuType != 'F'">
                  <div v-for="item1 in item.children" :key="item1.menuId" class="two">
                    <div class="left">
                      <el-checkbox disabled :checked="item1.selected">
                        {{ item1.menuName }}
                      </el-checkbox>
                    </div>
                    <div class="right">
                      <div v-for="item2 in item1.children" :key="item2.menuId">
                        <el-checkbox disabled :checked="item2.selected">
                          {{ item2.menuName }}
                        </el-checkbox>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="subpage" v-else>
                  <div class="two">
                    <!-- <div class="left">
                    </div> -->
                    <div class="right">
                      <div v-for="item1 in item.children" :key="item1.menuId">
                        <el-checkbox disabled :checked="item1.selected">
                          {{ item1.menuName }}
                        </el-checkbox>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </el-tab-pane>
        <el-tab-pane label="人员列表" name="second">
          <el-form :inline="true" class="demo-form-inline">
            <div style="display: flex;justify-content: space-between;">
              <el-form-item label="人员搜索">
                <el-input v-model="nickNameOrPhone" placeholder="请输入姓名/联系电话"></el-input>
              </el-form-item>
              <el-form-item label="所属部门">
                <el-select v-model="deptId" placeholder="请选择(多选)" multiple>
                  <el-option v-for="item in deptList" :key="item.id" :label="item.deptName" :value="item.id">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="登陆状态">
                <el-select v-model="status" placeholder="请选择">
                  <el-option
                    v-for="item in [{ label: '全部', value: '' }, { label: '启用', value: 0 }, { label: '禁用', value: 1 }]"
                    :key="item.value" :label="item.label" :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item>
                <el-button @click="reset">重置</el-button>
                <el-button type="primary" @click="onSubmit">查询</el-button>
              </el-form-item>
            </div>
          </el-form>
          <el-table ref="tableSort" v-loading="listLoading" stripe :data="data"
            :element-loading-text="elementLoadingText" :height="height">
            <el-table-column label="序号" type="index" width="50">
            </el-table-column>
            <el-table-column prop="nickName" label="姓名"></el-table-column>
            <el-table-column prop="phonenumber" label="联系电话">
            </el-table-column>
            <el-table-column prop="deptList" label="所属部门">
              <template slot-scope="{ row }">
                <el-tag v-for="(item, index) in row.deptList" :key="index">{{ item }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="roleName" label="角色">
            </el-table-column>
            <el-table-column prop="userName" label="登陆账号">
            </el-table-column>
            <el-table-column prop="remark" label="备注">
            </el-table-column>
            <el-table-column prop="status" label="登录状态">
              <template slot-scope="{row}">
                <div class="status_class">
                  <div :class="row.status == 0 ? 'green' : 'red'"></div>
                  <div>{{ row.status == 0 ? '正常' : '停用' }}</div>
                  <div v-if="row.status == 1" style="cursor: pointer;" @click="dialogVisibleView = true, rowView = row">
                    <i class="el-icon-warning"></i>
                  </div>
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="createTime" label="创建时间"></el-table-column>
          </el-table>
          <div class="pagination">
            <el-pagination layout="slot,sizes,prev,pager,next,jumper" :page-size="pagination.pageSize"
              :current-page="pagination.pageNum" @current-change="handleCurrentChange" @size-change="handleSizeChange"
              :total="pagination.total">
              <span>共{{ pagination.total }}条</span>
            </el-pagination>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-card>
    <ViewData v-if="dialogVisibleView" :row="rowView" :dialogVisible="dialogVisibleView"
      @close="dialogVisibleView = false, rowView = {}" />
  </div>
</template>
<script>
import { getRoleInfo, roleInfoFromUserId, getUserList, getDeptList } from './service.js'
import ViewData from '../user/components/viewData.vue'
export default {
  components: {
    ViewData
  },
  props: {},
  data() {
    return {
      form: {},
      activeName: 'first',
      menu: [],
      data: [],
      nickNameOrPhone: '',
      deptId: [],
      deptList: [],
      status: '',
      pagination: {
        total: 10,
        pageNum: 1,
        pageSize: 10,
      },
      rowView: {},
      dialogVisibleView: false,
      listLoading: true,
      timeOutID: null,
      elementLoadingText: '正在加载...',
    };
  },
  computed: {
    height() {
      return this.$baseTableHeight()
    },
  },
  watch: {},
  created() {
    roleInfoFromUserId({ userId: 1 }).then(res => {
      getRoleInfo({ roleId: this.$route.query.roleId }).then(resp => {
        this.menu = this.setSelectedIds(res.data.data, resp.data.data.menus);
        this.form = {
          roleName: resp.data.data.roleName,
          remark: resp.data.data.remark,
        }
      })
    })
    this.getListData()
    getDeptList().then((res) => {
      this.deptList = res.data.data
    })
  },
  mounted() { },
  methods: {
    async getListData() {
      let obj = {
        ...this.pagination,
        nickNameOrPhone: this.nickNameOrPhone,
        deptIds: this.deptId,
        status: this.status,
        roleIds: [this.$route.query.roleId]
      }
      this.listLoading = true
      const { data: { data: { records, total } } } = await getUserList(obj)
      this.data = records
      this.pagination.total = total
      this.timeOutID = setTimeout(() => {
        this.listLoading = false
      }, 500)
    },
    setSelectedIds(arr, selectKeyList) {
      function traverse(item) {
        item.selected = selectKeyList.includes(item.menuId);
        if (item.children && item.children.length > 0) {
          item.children.forEach(traverse);
        }
      }
      arr.forEach(traverse);
      return arr;
    },
    reset() {
      this.nickNameOrPhone = ''
      this.deptId = []
      this.status = ''
      this.pagination.pageNum = 1
      this.getListData()
    },
    onSubmit() {
      this.pagination.pageNum = 1
      this.getListData()
    },
    handleCurrentChange(e) {
      this.pagination.pageNum = e;
      this.getListData()
    },
    handleSizeChange(e) {
      this.pagination.pageSize = e
      this.getListData()
    },
  },
};
</script>
<style lang="less" scoped>
.box_card {
  div:first-child {
    font-size: 18px;
    font-weight: bold;
    margin-bottom: 15px;
  }
  div:last-child {
    font-size: 16px;
    color: rgba(0, 0, 0, 0.65);
  }
}
.row,
.header {
  display: flex;
  align-items: center;
  border: 1px solid #e8e8e8;
  .w20 {
    width: 15%;
    padding: 8px 20px;
  }
  .sconed {
    flex: 1;
    .subpage {
      .title {
        border: 1px solid #e8e8e8;
        border-top: none;
        border-bottom: none;
      }
      .two {
        display: flex;
        align-items: center;
        border: 1px solid #e8e8e8;
        border-top: none;
        border-right: none;
        .left {
          width: 200px;
          padding: 13px 20px;
          border-right: 1px solid #e8e8e8;
        }
        .right {
          display: flex;
          flex: 1;
          div {
            padding: 13px 0 13px 20px;
          }
        }
      }
      .two:last-child {
        border-bottom: none;
      }
      .btns {
        display: flex;
        align-items: center;
        padding: 0 20px;
      }
    }
  }
}
.header {
  background-color: #e8e8e8;
  .subpage {
    display: flex;
  }
  .title {
    width: 200px;
    padding: 8px 20px;
  }
}
.status_class {
  display: flex;
  align-items: center;
  div:nth-child(1) {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    margin-right: 5px;
  }
  div:nth-child(2) {
    margin-right: 8px;
  }
}
/* 当复选框禁用时覆盖默认样式 */
::v-deep .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner {
  background-color: #409eff;
  border-color: #409eff;
}
::v-deep .el-checkbox.is-disabled .el-checkbox__inner::after {
  border-color: #fff;
}
</style>
src/view/systemManage/role/index.vue
New file
@@ -0,0 +1,173 @@
<template>
  <div>
    <el-card>
      <el-form :inline="true" class="demo-form-inline">
        <el-form-item label="角色名称">
          <el-input v-model="roleName" placeholder="请输入角色名称"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button @click="reset">重置</el-button>
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card style="margin-top: 20px;">
      <div class="add_btn">
        <el-button  icon="el-icon-plus" @click="add"
          type="primary">添加角色</el-button>
      </div>
      <el-table ref="tableSort" v-loading="listLoading" stripe :data="data" :element-loading-text="elementLoadingText"
        >
        <el-table-column type="index" width="55" label="序号"></el-table-column>
        <el-table-column prop="roleName" label="角色名称"></el-table-column>
        <el-table-column prop="remark" label="备注"></el-table-column>
        <el-table-column prop="createTime" label="创建时间"></el-table-column>
        <el-table-column label="操作" width="300">
          <template slot-scope="{row}">
            <div>
              <el-button  type="text"
                @click="$router.push(`/systemManage/role-detail?roleId=${row.roleId}`)">详情</el-button>
              <el-button  type="text"
                @click="$router.push(`/systemManage/add-role?roleId=${row.roleId}`)">编辑</el-button>
              <el-button  type="text"
                @click="del(row)">删除</el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <div class="pagination">
        <el-pagination layout="slot,sizes,prev,pager,next,jumper" :page-size="pagination.pageSize"
          :current-page="pagination.pageNum" @current-change="handleCurrentChange" @size-change="handleSizeChange"
          :total="pagination.total">
          <span>共{{ pagination.total }}条</span>
        </el-pagination>
      </div>
    </el-card>
    <ShowDelConfirm :show="delShow" @close="delShow = false" @confirm="delConfirm" />
  </div>
</template>
<script>
import { getList, delRole } from './service'
import ShowDelConfirm from '@/components/ShowDelConfirm'
export default {
  components: {
    ShowDelConfirm,
  },
  data() {
    return {
      delShow: false,
      data: [],
      roleName: '',
      pagination: {
        total: 10,
        pageNum: 1,
        pageSize: 10,
      },
      delId: '',
      listLoading: true,
      timeOutID: null,
      elementLoadingText: '正在加载...',
    };
  },
  computed: {
    // height() {
    //   // return this.$baseTableHeight()
    // },
  },
  watch: {},
  created() {
    this.getListData()
  },
  mounted() { },
  methods: {
    add() {
      this.$router.push('/systemManage/add-role')
    },
    delConfirm() {
      delRole(this.delId).then(() => {
        this.delShow = false
        this.disbRow = {}
        this.getListData()
        this.$baseMessage('删除成功', 'success')
      })
    },
    del(row) {
      this.delShow = true
      this.delId = row.roleId
    },
    async getListData() {
      let obj = {
        roleName: this.roleName,
        pageNum: this.pagination.pageNum,
        pageSize: this.pagination.pageSize
      }
      this.listLoading = true
      // const { data: { data: { records, total } } } = await getList(obj)
      // this.data = records
      this.pagination.total = 10||total
      this.timeOutID = setTimeout(() => {
        this.listLoading = false
      }, 500)
    },
    reset() {
      this.roleName = ''
      this.pagination.pageNum = 1
      this.getListData()
    },
    onSubmit() {
      this.pagination.pageNum = 1
      this.getListData()
    },
    handleCurrentChange(e) {
      this.pagination.pageNum = e;
      this.getListData()
    },
    handleSizeChange(e) {
      this.pagination.pageSize = e
      this.getListData()
    },
  },
};
</script>
<style lang="less" scoped>
.green {
  background-color: green;
}
.red {
  background-color: red;
}
.demo-form-inline {
  display: flex;
  justify-content: space-between;
}
.add_btn {
  margin-bottom: 20px;
}
.pagination {
  display: flex;
  justify-content: flex-end;
  margin-top: 20px;
}
.status_class {
  display: flex;
  align-items: center;
  div:nth-child(1) {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    margin-right: 5px;
  }
  div:nth-child(2) {
    margin-right: 8px;
  }
}
</style>
src/view/systemManage/role/service.js
New file
@@ -0,0 +1,41 @@
import axios from '@/utils/request';
// 列表
export const getList = (data) => {
  return axios.post('/system/role/list', { ...data })
}
// 添加
export const add = (data) => {
  return axios.post('/system/role/add', { ...data })
}
// 编辑
export const edit = (data) => {
  return axios.put('/system/role', { ...data })
}
// 删除
export const delRole = (id) => {
  return axios.delete(`/system/role/deleteById/${id}`)
}
// 获取菜单树
export const roleInfoFromUserId = (params) => {
  return axios.get(`/system/role/roleInfoFromUserId`, { params })
}
// 获取角色详情
export const getRoleInfo = (params) => {
  return axios.get(`/system/role/roleInfo`, { params })
}
// 列表
export const getUserList = (data) => {
  return axios.post('/system/user/list', { ...data })
}
export const getDeptList = (params) => {
  return axios.post('/t-dept/listAll')
}
src/view/systemManage/user/components/addEdit.vue
New file
@@ -0,0 +1,111 @@
<template>
    <div>
        <el-dialog :visible.sync="dialogVisible" @close="$emit('close')" :title="row.deptId ? '编辑人员' : '添加人员'"
            width="30%">
            <el-form ref="form" :model="form" :rules="rules" label-width="80px">
                <el-form-item label="姓名" prop="nickName">
                    <el-input v-model="form.nickName" placeholder="请输入" style="width: 50%;"></el-input>
                </el-form-item>
                <el-form-item label="联系电话" prop="phonenumber">
                    <el-input v-model="form.phonenumber" placeholder="请输入" style="width: 50%;"></el-input>
                </el-form-item>
                <el-form-item label="登陆账号" prop="userName">
                    <el-input v-model="form.userName" :disabled="form.userId" placeholder="请输入"
                        style="width: 50%;"></el-input>
                </el-form-item>
                <el-form-item label="所属部门" prop="deptId">
                    <el-select v-model="form.deptId" placeholder="请选择">
                        <el-option v-for="item in deptList" :key="item.deptId" :label="item.deptName"
                            :value="item.deptId">
                        </el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="角色" prop="roleId">
                    <el-select v-model="form.roleId" placeholder="请选择">
                        <el-option v-for="item in roleList" :key="item.roleId" :label="item.roleName"
                            :value="item.roleId">
                        </el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="登录状态" prop="status">
                    <el-switch v-model="form.status"></el-switch>
                </el-form-item>
                <el-form-item label="备注" prop="remark">
                    <el-input type="textarea" v-model="form.remark" placeholder="请输入" style="width: 50%;"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer">
                <el-button @click="$emit('close')">关闭</el-button>
                <el-button type="primary" @click="submit">保存</el-button>
            </div>
        </el-dialog>
    </div>
</template>
<script>
export default {
    props: {
        dialogVisible: {
            type: Boolean,
            default: false
        },
        row: {
            type: Object,
            default: () => { }
        },
        deptList: {
            type: Array,
            default: () => []
        },
        roleList: {
            type: Array,
            default: () => []
        }
    },
    data() {
        return {
            form: { status: true },
            rules: {
                nickName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
                phonenumber: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
                deptId: [{ required: true, message: '请选择所属部门', trigger: 'blur' }],
                roleId: [{ required: true, message: '请选择角色', trigger: 'blur' }],
                userName: [{ required: true, message: '请输入登陆账号', trigger: 'blur' }],
            }
        };
    },
    created() {
        this.form = { status: true }
        if (Object.keys(this.row).length) {
            this.form = {
                userId: this.row.userId,
                nickName: this.row.nickName,
                phonenumber: this.row.phonenumber,
                deptId: this.row.deptId,
                roleId: this.row.roleId,
                userName: this.row.userName,
                remark: this.row.remark,
                status: this.row.status == 0 ? true : false,
            }
        } else {
            this.form = {}
        }
    },
    mounted() { },
    methods: {
        submit() {
            this.$refs['form'].validate((valid) => {
                if (valid) {
                    let obj = {
                        ...this.form,
                        status: this.form.status ? 0 : 1
                    }
                    this.$emit('confirm', obj)
                }
            })
        }
    },
};
</script>
<style scoped></style>
src/view/systemManage/user/components/disb.vue
New file
@@ -0,0 +1,69 @@
<template>
    <div>
        <el-dialog :visible.sync="dialogVisible" @close="$emit('close')" title="禁用人员" width="30%">
            <el-form ref="form" :model="form" label-width="80px">
                <el-form-item label="姓名" prop="nickName">
                    {{ form.nickName }}
                </el-form-item>
                <el-form-item label="登陆账号" prop="userName">
                    {{ form.userName }}
                </el-form-item>
                <el-form-item label="禁用备注" prop="disableRemark">
                    <el-input type="textarea" v-model="form.disableRemark" placeholder="请输入备注"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer">
                <el-button @click="$emit('close')">关闭</el-button>
                <el-button type="primary" @click="submit">确定</el-button>
            </div>
        </el-dialog>
    </div>
</template>
<script>
export default {
    props: {
        dialogVisible: {
            type: Boolean,
            default: false
        },
        row: {
            type: Object,
            default: () => { }
        }
    },
    data() {
        return {
            form: { status: false },
        };
    },
    created() {
        this.form = { status: false }
        if (Object.keys(this.row).length) {
            this.form = {
                ...this.row,
                userId: this.row.userId,
                nickName: this.row.nickName,
                userName: this.row.userName,
                status: 1,
                disableRemark: this.row.disableRemark
            }
        }
    },
    mounted() { },
    methods: {
        submit() {
            this.$refs['form'].validate((valid) => {
                if (valid) {
                    this.form.deptId = this.row.deptId
                    this.form.orderNum = 0
                    this.form.ancestors = 0
                    this.form.parentId = 100
                    this.$emit('confirm', this.form)
                }
            })
        }
    },
};
</script>
<style scoped></style>
src/view/systemManage/user/components/resetPassWord.vue
New file
@@ -0,0 +1,84 @@
<template>
    <div>
        <el-dialog :visible.sync="dialogVisible" @close="$emit('close')" title="重置密码"
            width="30%">
            <el-form ref="form" :model="form" :rules="rules" label-width="80px">
                <el-form-item label="姓名" prop="nickName">
                    <el-input :disabled="true" v-model="form.nickName" placeholder="请输入" style="width: 50%;"></el-input>
                </el-form-item>
                <el-form-item label="登陆账号" prop="account">
                    <el-input :disabled="true" v-model="form.account" placeholder="请输入" style="width: 50%;"></el-input>
                </el-form-item>
                <el-form-item label="新密码" prop="password">
                    <el-input v-model="form.password" placeholder="请输入" style="width: 50%;"></el-input>
                </el-form-item>
                <el-form-item label="确认密码" prop="confirmPassword">
                    <el-input v-model="form.confirmPassword" placeholder="请输入" style="width: 50%;"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer">
                <el-button @click="$emit('close')">关闭</el-button>
                <el-button type="primary" @click="submit">保存</el-button>
            </div>
        </el-dialog>
    </div>
</template>
<script>
export default {
    props: {
        dialogVisible: {
            type: Boolean,
            default: false
        },
        row: {
            type: Object,
            default: () => { }
        }
    },
    data() {
        return {
            form: { status: true },
            rules: {
                password: [{ required: true, message: '请新密码', trigger: 'blur' }],
                confirmPassword: [{ required: true, message: '请确认密码', trigger: 'blur' },{
                    validator: (rule, value, callback) => {
                        if (value !== this.form.password) {
                            callback(new Error('两次输入密码不一致!'));
                        } else {
                            callback();
                        }
                }}],
            }
        };
    },
    created() {
        this.form = { status: true }
        if (Object.keys(this.row).length) {
            this.form = {
                userId: this.row.userId,
                nickName: this.row.nickName,
                account: this.row.userName,
            }
        }
    },
    mounted() { },
    methods: {
        submit() {
            this.$refs['form'].validate((valid) => {
                if (valid) {
                    if (this.row.deptId) {
                        this.form.deptId = this.row.deptId
                    }
                    this.form.orderNum = 0
                    this.form.ancestors = 0
                    this.form.parentId = 100
                    this.$emit('confirm', this.form)
                }
            })
        }
    },
};
</script>
<style scoped></style>
src/view/systemManage/user/components/viewData.vue
New file
@@ -0,0 +1,49 @@
<template>
    <div>
        <el-dialog :visible.sync="dialogVisible" @close="$emit('close')" title="禁用信息" width="30%">
            <el-form ref="form" label-width="80px">
                <el-form-item label="禁用原因" prop="disableRemark">
                    {{form.disableRemark}}
                </el-form-item>
                <el-form-item label="操作时间" prop="updateTime">
                    {{form.updateTime}}
                </el-form-item>
                <el-form-item label="操作人" prop="updateBy">
                    {{form.updateName }}
                </el-form-item>
            </el-form>
            <div slot="footer">
                <el-button @click="$emit('close')">关闭</el-button>
            </div>
        </el-dialog>
    </div>
</template>
<script>
export default {
    props: {
        dialogVisible: {
            type: Boolean,
            default: false
        },
        row: {
            type: Object,
            default: () => { }
        }
    },
    data() {
        return {
            form: {},
        };
    },
    created() {
        if (Object.keys(this.row).length) {
            this.form = {...this.row}
        }
    },
    mounted() { },
    methods: {
    },
};
</script>
<style scoped></style>
src/view/systemManage/user/index.vue
New file
@@ -0,0 +1,293 @@
<template>
  <div>
    <div class="form flex a-center j-between mt--23">
      <div class="form-left ml--30">
        <el-form :inline="true">
          <el-form-item label="人员搜索">
            <el-input v-model="nickNameOrPhone" placeholder="请输入姓名/联系电话"></el-input>
          </el-form-item>
          <el-form-item label="人员角色">
            <el-select v-model="roleId" placeholder="请选择(多选)" multiple>
              <el-option v-for="item in roleList" :key="item.roleId" :label="item.roleName" :value="item.roleId">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="账号状态">
            <el-select v-model="status" placeholder="请选择">
              <el-option
                v-for="item in [{ label: '全部', value: '' }, { label: '启用', value: 0 }, { label: '禁用', value: 1 }]"
                :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
        </el-form>
      </div>
      <div style="text-align: right;">
        <el-button class="search-button h--40 w--90 fs--14" icon="el-icon-search" type="primary" size="small"
          @click="onSubmit">查询</el-button>
        <el-button @click="reset" icon="el-icon-refresh-right" class="reset-button h--40 w--90 fs--14"
          size="small">重置</el-button>
      </div>
    </div>
    <div class="table-box-btn mt--23 ml--30">
      <el-button class="search-button h--40 w--90 fs--14" icon="el-icon-plus" type="primary" size="small"
        @click="dialogVisible = true">添加</el-button>
      <el-button class="search-button h--40 w--90 fs--14" icon="el-icon-delete" type="danger" size="small"
        @click="dialogVisible = true">删除</el-button>
    </div>
    <div class="table-box ml--30 mt--23 mr--30">
      <el-table :data="tableData" border stripe style="width: 100%" :height="height">
        <el-table-column prop="nickName" label="姓名"></el-table-column>
        <el-table-column prop="phonenumber" label="联系电话">
        </el-table-column>
        <el-table-column prop="roleName" label="角色"></el-table-column>
        <el-table-column prop="userName" label="登陆账号">
        </el-table-column>
        <el-table-column prop="remark" label="备注">
        </el-table-column>
        <el-table-column prop="status" label="账号状态">
          <template slot-scope="{row}">
            <div class="status_class">
              <div :class="row.status == 0 ? 'green' : 'red'"></div>
              <div>{{ row.status == 0 ? '正常' : '停用' }}</div>
              <div v-if="row.status == 1" style="cursor: pointer;" @click="dialogVisibleView = true, rowView = row">
                <i class="el-icon-warning"></i>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间"></el-table-column>
        <el-table-column label="操作" width="300">
          <template slot-scope="{row}">
            <div>
              <el-button type="text" @click="edit(row)">编辑</el-button>
              <el-button v-if="row.status != 0" type="text" @click="updateStatus(row, true)">启用</el-button>
              <el-button v-if="row.status == 0" type="text" @click="updateStatus(row, false)">禁用</el-button>
              <el-button type="text" @click="detail(row)">重置密码</el-button>
              <el-button type="text" @click="del(row)">删除</el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <div class="relative mt--23 flex j-end">
        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
          :current-page="searchForm.pageNum" background layout="total,sizes,prev, pager, next,jumper"
          :total="searchForm.total">
        </el-pagination>
      </div>
    </div>
    <AddEdit v-if="dialogVisible" :row="row" :deptList="deptList" :roleList="roleList" :dialogVisible="dialogVisible"
      @close="dialogVisible = false, row = {}" @confirm="confirm" />
    <ResetPassword v-if="passwordVisible" :row="row" :dialogVisible="passwordVisible"
      @close="passwordVisible = false, row = {}" @confirm="passwordConfirm" />
    <ViewData v-if="dialogVisibleView" :row="rowView" :dialogVisible="dialogVisibleView"
      @close="dialogVisibleView = false, rowView = {}" />
    <Disb v-if="disbDialogVisible" :row="disbRow" :dialogVisible="disbDialogVisible"
      @close="disbDialogVisible = false, disbRow = {}" @confirm="disbConfirm" />
    <ShowDelConfirm :show="delShow" @close="delShow = false" @confirm="delConfirm" title="确认要删除该人员吗?"
      tip="删除人员后,该人员不可登录。如非必要,系统建议您使用禁用功能。" okText="确定删除" />
  </div>
</template>
<script>
import { getList, add, edit, delDept, deptList, roleList, updatePwd } from './service'
import AddEdit from './components/addEdit.vue'
import ViewData from './components/viewData.vue'
import Disb from './components/disb.vue'
import ResetPassword from './components/resetPassWord.vue'
import ShowDelConfirm from '@/components/ShowDelConfirm'
export default {
  components: {
    AddEdit,
    ViewData,
    Disb,
    ResetPassword,
    ShowDelConfirm,
  },
  data() {
    return {
      dialogVisible: false,
      passwordVisible: false,
      dialogVisibleView: false,
      disbDialogVisible: false,
      delShow: false,
      data: [],
      nickNameOrPhone: '',
      deptId: [],
      roleId: [],
      status: '',
      roleList: [],
      deptList: [],
      searchForm: {
        total: 0,
        pageNum: 1,
        pageSize: 10
      },
      row: {},
      rowView: {},
      disbRow: {},
      delId: '',
    };
  },
  computed: {
    height() {
      return this.$baseTableHeight()
    },
  },
  watch: {},
  created() {
    // this.getRoleList()
    // this.getListData()
    // this.getdeptList()
  },
  mounted() { },
  methods: {
    getdeptList() {
      deptList({ status: 0 }).then((res) => {
        this.deptList = res
      })
    },
    getRoleList() {
      roleList().then((res) => {
        this.roleList = res
      })
    },
    delConfirm() {
      delDept(this.delId).then(() => {
        this.delShow = false
        this.disbRow = {}
        this.getListData()
        this.msgsuccess('删除成功')
      })
    },
    disbConfirm(form) {
      edit(form).then(() => {
        this.disbDialogVisible = false
        this.msgsuccess('禁用成功')
        this.getListData()
      })
    },
    confirm(form) {
      if (form.userId) {
        edit(form).then(() => {
          this.row = {}
          this.dialogVisible = false
          this.msgsuccess('修改成功')
          this.getListData()
        })
      } else {
        add(form).then(() => {
          this.row = {}
          this.dialogVisible = false
          this.msgsuccess('添加成功')
          this.getListData()
        })
      }
    },
    passwordConfirm(form) {
      updatePwd(form).then(() => {
        this.row = {}
        this.passwordVisible = false
        this.msgsuccess('修改密码成功')
        this.getListData()
      })
    },
    detail(row) {
      this.passwordVisible = true
      this.row = row
    },
    edit(row) {
      this.row = row
      this.dialogVisible = true
    },
    updateStatus(row, type) {
      if (type == true) {
        edit({ ...row, status: 0 }).then(() => {
          this.msgsuccess('启用成功')
          this.getListData()
        })
      } else {
        this.disbRow = row
        this.disbDialogVisible = true
      }
    },
    del(row) {
      this.delShow = true
      this.delId = row.userId
    },
    getListData() {
      let obj = {
        ...this.pagination,
        nickNameOrPhone: this.nickNameOrPhone,
        deptId: this.deptId,
        roleIds: this.roleId,
        status: this.status,
      }
      getList(obj).then((res) => {
        this.pagination.total = res.total
        this.data = res.records
      })
    },
    reset() {
      this.nickNameOrPhone = ''
      this.roleId = []
      this.deptId = []
      this.status = ''
      this.pagination.pageNum = 1
      this.getListData()
    },
    onSubmit() {
      this.pagination.pageNum = 1
      this.getListData()
    },
    handleCurrentChange(e) {
      this.pagination.pageNum = e;
      this.getListData()
    },
    handleSizeChange(e) {
      this.pagination.pageSize = e
      this.getListData()
    },
    // paginate(data, pageSize, currentPage) {
    //   if (data.length === 0) {
    //     return [];
    //   }
    //   const start = (currentPage - 1) * pageSize;
    //   const end = start + pageSize;
    //   return data.slice(start, end);
    // }
  },
};
</script>
<style lang="less" scoped>
::v-deep .el-form-item .el-input__inner {
  width: 240px;
  height: unset !important;
}
.green {
  background-color: green;
}
.red {
  background-color: red;
}
.status_class {
  display: flex;
  align-items: center;
  div:nth-child(1) {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    margin-right: 5px;
  }
  div:nth-child(2) {
    margin-right: 8px;
  }
}
</style>
src/view/systemManage/user/service.js
New file
@@ -0,0 +1,36 @@
import axios from '@/utils/request';
// 列表
export const getList = (data) => {
    return axios.post('/system/user/list', { ...data })
}
// 添加
export const add = (data) => {
    return axios.post('/system/user/add', { ...data })
}
// 编辑
export const edit = (data) => {
    return axios.post('/system/user/edit', { ...data })
}
// 删除
export const delDept = (id) => {
    return axios.delete(`/system/user/deleteById/${id}`)
}
// 部门
export const deptList = (data) => {
    return axios.get(`/system/dept/list?status=${data.status}`,{...data})
}
export const roleList = () => {
    return axios.post(`/system/role/listNotPage`)
}
//
export const changeStatus = (data) => {
    return axios.put(`/system/user/changeStatus`,{...data})
}
export const updatePwd = (data) => {
    return axios.post(`/system/user/updatePwd`,{...data})
}