Browse Source

添加用户管理和分组管理的静态页面

lm 6 ngày trước cách đây
mục cha
commit
3af0b9f6e9

+ 5 - 2
src/baseComponents/MultipleBarCharts.vue

@@ -27,6 +27,9 @@ import * as echarts from 'echarts';
           return [];
         }
       },//x轴数据
+      xAxisLabelFormatter:{
+        type:Function,
+      }, //x轴标签格式(传参为 xAxis的value)
       datay:{
         type:Array,
         default:()=>[]
@@ -374,7 +377,7 @@ import * as echarts from 'echarts';
                             interval: 0, // 确保所有刻度标签都显示
                             fontWeight: 400,
                             rotate: singleSeriesWidth < 80 ? 45 : 0,
-                            formatter:function(value) {
+                            formatter:this.xAxisLabelFormatter ? this.xAxisLabelFormatter : function(value) {
                                 // console.log(value)
                                 
                                 // 文字大小设置为14px  按14算
@@ -450,7 +453,7 @@ import * as echarts from 'echarts';
                 },
                 series: [
                     {
-                        name: '阅卷进度',
+                        name: '',
                         type: 'bar',
                         // showBackground: true,
                         

+ 3 - 3
src/router/index.ts

@@ -47,9 +47,9 @@ const routes: Array<RouteRecordRaw> = [
         component: () => import('../views/customerFollowUp/index.vue')
       },
       {
-        path: 'userManagement',
-        name: 'userManagement',   //用户管理
-        component: () => import('../views/userManagement/index.vue')
+        path: 'userPrivilegeManagement',
+        name: 'userPrivilegeManagement',   //用户权限
+        component: () => import('../views/userPrivilegeManagement/index.vue')
       },
       {
         path: 'parameterConfig',

+ 4 - 4
src/store/index.ts

@@ -41,13 +41,13 @@ const store = createStore<RootState>({
         svgIcon:undefined,
       },
       {
-        title: '用户管理',
-        route: '/main/userManagement',
+        title: '参数配置',
+        route: '/main/parameterConfig',
         svgIcon:undefined,
       },
       {
-        title: '参数配置',
-        route: '/main/parameterConfig',
+        title: '用户权限',
+        route: '/main/userPrivilegeManagement',
         svgIcon:undefined,
       },
     ]

+ 0 - 15
src/views/userManagement/index.vue

@@ -1,15 +0,0 @@
-<template>
-    <div>
-        用户管理
-    </div>
-</template>
-
-
-<script setup lang="ts">
-
-</script>
-
-
-<style lang="scss" scoped>
-
-</style>

+ 20 - 0
src/views/userPrivilegeManagement/groupManage/formSearch.ts

@@ -0,0 +1,20 @@
+import { ref } from "vue";
+
+
+export const  accountFormSearhList = ref([
+    {
+        key:'queryStr',
+        type:'input',
+        placeholder:'请输入',
+        defaultValue:'',
+    }
+])
+
+export const  formSearhList = ref([
+    {
+        key:'queryStr',
+        type:'input',
+        placeholder:'请输入',
+        defaultValue:'',
+    }
+])

+ 285 - 0
src/views/userPrivilegeManagement/groupManage/index.vue

@@ -0,0 +1,285 @@
+<template>
+    <div class="end_item container">
+        <div class="container_left end_item">
+            <FormSearchGroup :searchList="accountFormSearhList" />
+            <div class="page_jg_20"/>
+            <Table 
+                :hidePagination="true"
+                class="teacher_table"
+                :tableColumns="userTableColumns" 
+                :tableData="userAccountData"
+                :tableRowClassName="tableRowClassName"
+                @rowClick="HandleSelectUser"
+            ></Table>
+        </div>
+        <div  class="container_right end_item">
+            <div class="page_search">
+                <div class="search_content">
+                    <div class="content_left">
+                        <TabSearch :tabList="provinceTablist" 
+                            :defaultTabKey="defaultProvince" tabType="line" />
+                    </div>
+                    <div class="content_right">
+                        <span v-if="isConfigMode" class="config_switch_desc">
+                            {{ selectedUser?.id ? `当前选中的用户:${selectedUser.name}` : '暂无选中的用户' }}
+                            </span>
+                        <el-switch v-model="isConfigMode" 
+                            style="--el-switch-on-color: #2E64FA"
+                            active-text="选中用户配置任课关系" />
+                        <el-button class="button_border">分组管理</el-button>
+                    </div>
+                </div>
+            </div>
+            <div class="page_jg_20" />
+            <Table :tableColumns="tableColumns" :tableData="groupTableData">
+                 <template v-for="column in tableColumns.slice(1)" :key="column.name"   v-slot:[column.name]="{row}"> 
+                    <div class="cell_container" @click="HandleAddUser(row, column.name)">
+                        <template v-if="row?.[column.name]">
+                            <el-tooltip
+                            effect="dark"
+                            :content="`${row?.[column.name].name}`"
+                            placement="top-start"
+                            >
+                            <div v-if="isConfigMode" class="teacher_tag">
+                                <span :title="row?.[column.name].name">{{ row?.[column.name].name }}</span>
+                                <el-icon class="delete_icon" @click.stop="HandleRemoveUser(row, column.name, idx,'administrative')"><Close /></el-icon>
+                            </div>
+                            <div v-else class="disabled_teacher">
+                                <span :title="row?.[column.name].name">{{ row?.[column.name].name}}</span>
+                            </div>
+                            </el-tooltip>
+                        </template>
+                        <template v-else>
+                            <span v-if="isConfigMode" class="placeholder_text" >请选择用户</span>
+                            <span v-else>-</span>
+                        </template>
+                  </div>
+                </template>
+            </Table>
+        </div>
+    </div>
+</template>
+
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import FormSearchGroup from '@/baseComponents/FormSearchGroup.vue';
+import {formSearhList,accountFormSearhList} from './formSearch'
+import Table from '@/baseComponents/Table.vue';
+import TabSearch from '@/baseComponents/TabSearch.vue';
+
+import {tableColumns,userTableColumns} from './table'
+import {provinceTablist} from './tabSearch'
+
+
+// 用户账号信息
+const userAccountData = ref([
+    {
+        account:'xxx',
+        name:'xx',
+        id:'1',
+    },
+    {
+        account:'xxx',
+        name:'xx2',
+        id:'2',
+    },
+])
+
+// 分组信息
+const isConfigMode = ref(false)
+const defaultProvince = ref('beijing')
+const groupTableData = ref([
+    {
+        id:'1',
+        region:'xxx',
+        project1:{id:'1',name:'xxx'},
+        project2:{id:'1',name:'xxx'},
+        project3:{id:'1',name:'xxx'},
+        project4:{id:'1',name:'xxx'},
+        project5:{id:'1',name:'xxx'},
+        project6:{id:'1',name:'xxx'},
+        project7:{id:'1',name:'xxx'},
+    },
+    {
+        id:'2',
+        region:'xxx',
+        project1:{id:'1',name:'xxx'},
+        project2:{id:'1',name:'xxx'},
+        project3:{id:'1',name:'xxx'},
+        project4:{id:'1',name:'xxx'},
+        project5:{id:'1',name:'xxx'},
+        project6:{id:'1',name:'xxx'},
+        project7:{id:'1',name:'xxx'},
+    },
+])
+
+const selectedUser = ref({})
+
+// 设置表行选中 样式
+const tableRowClassName = ({row,rowIndex})=>{
+  if(row.id == selectedUser.value?.id){
+    return 'active_row'
+  }
+}
+// 行选中 选择用户
+const HandleSelectUser = (user) => {
+  selectedUser.value = {
+    id:user.id,
+    name:user.name,
+    account:user.account,
+  };
+};
+
+// 添加用户
+const HandleAddUser = async (row, cell) => {
+    if (!isConfigMode.value) return;
+    if (!selectedUser.value) return;
+
+    let teacherMsg = { 
+        id: selectedUser.value?.id, 
+        name: selectedUser.value?.name,
+        account:selectedUser.value?.account 
+    }
+
+    if (!row[cell]) {
+        row[cell] = [];
+    
+    }
+    row[cell] = teacherMsg;
+
+    // let res = await saveTeachingRelationshipApi({
+    //     ...teacherMsg,
+    //     evaluationId:route.query.id,
+    //     evaluationGradeId:searchParmams.value.gradeId,
+    //     evaluationSubjectId:cell,
+    //     evaluationClassId:row.className.evaluationClassId,
+    //     classType:searchParmams.value.classType == 'teach' ? 1 : 0  //班级类型,0-行政班,1-教学班
+    // })
+    // if(res?.code == 200){
+        // ElMessage.success(res?.msg)
+        // row[cell].push({...teacherMsg,id:res?.data});
+    // }
+};
+
+
+// 移除用户
+const HandleRemoveUser = async (row, cell, index,type) => {
+    if (!isConfigMode.value) return;
+    let id = null
+    let res = undefined
+    row[cell] = '';
+
+    // id = row[cell][index].id
+    // res = await deleteTeachingRelationshipApi(id)
+    // if(res?.code == 200){
+    //     ElMessage.success(res?.msg)
+    //     row[cell].splice(index, 1);
+    // }
+};
+
+
+
+</script>
+
+
+<style lang="scss" scoped>
+
+.container{
+    width: 100%;
+    overflow: auto;
+    flex-direction: row;
+    gap:20px;
+
+    .container_left{
+        width: 200px;
+
+        :deep(.el-table__body){
+            tr.active_row td
+            {
+                background-color: rgba(46, 100, 250,0.1) !important;
+                border:none;
+                color: #2e64fa;
+            }
+        }
+
+
+    }
+
+    .container_right{
+        width: calc(100% - 220px);
+        .content_left{
+            line-height: 1.5;
+        }
+        .content_right{
+            align-items: center;
+        }
+        .config_switch_desc{
+            font-size: 14px;
+        }
+
+        .cell_container {
+            width: 100%;
+            height: 100%;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+     
+            text-align: center;
+            flex-wrap: wrap;
+            padding: 8px;
+            gap: 8px;
+
+            .placeholder_text,
+            .disabled_teacher{
+                width: 90px;
+                height: 34px;
+                font-weight: 400;
+                font-size: 14px;
+                text-align: center;
+                line-height: 34px;
+                background-color: #f3f3f3;
+                border-radius: 4px;
+                cursor: pointer;
+            }
+            .placeholder_text {
+                color: #CCCCCC;
+            }
+            .disabled_teacher {
+                color: #666666;
+            }
+
+            // 教师标签样式
+            .teacher_tag {
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+                padding: 0 8px;
+
+                min-width: 90px;
+                height: 34px;
+                font-weight: 400;
+                font-size: 14px;
+                color: #2E64FA;
+                text-align: center;
+                line-height: 34px;
+                background: rgba(46, 100, 250, 0.1);
+                border-radius: 4px;
+
+                // 删除图标样式 (对应原 img 标签样式)
+                .delete_icon {
+                width: 12px;
+                height: 12px;
+                cursor: pointer;
+                font-size: 12px;
+                margin-left: 10px; /* 保留原代码中 i 标签的 margin-left 习惯 */
+                }
+            }
+        }
+
+
+
+    }
+}
+
+</style>

+ 25 - 0
src/views/userPrivilegeManagement/groupManage/tabSearch.ts

@@ -0,0 +1,25 @@
+import { ref } from "vue";
+
+
+export const  provinceTablist = ref([
+    {
+        label:'北京市',
+        key:'beijing',
+    },
+    {
+        label:'上海市',
+        key:'shanghai',
+    },
+    {
+        label:'天津市',
+        key:'tianjin',
+    },
+    {
+        label:'河北',
+        key:'hebei',
+    },
+    {
+        label:'辽宁',
+        key:'liaoning',
+    },
+])

+ 101 - 0
src/views/userPrivilegeManagement/groupManage/table.ts

@@ -0,0 +1,101 @@
+import { ref } from "vue";
+
+
+
+export const userTableColumns = ref([
+    {
+        name:'account',
+        label:'账号',
+        width:'80',
+        fixed:'',
+        align:'center',
+        minWidth:'',
+        custom:false,
+    },
+    {
+        name:'name',
+        label:'姓名',
+        width:'80',
+        fixed:'',
+        align:'center',
+        minWidth:'',
+        custom:false,
+    },
+])
+
+
+
+export const tableColumns = ref([
+    {
+        name: 'region', // 对应“项目组”列,通常作为行头
+        label: '项目组',
+        width: '120',
+        fixed: 'left', // 建议固定首列,防止横向滚动时看不清区域
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'project1',
+        label: '项目1组',
+        width: '120',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: true,
+    },
+    {
+        name: 'project2',
+        label: '项目2组',
+        width: '120',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: true,
+    },
+    {
+        name: 'project3',
+        label: '项目3组',
+        width: '120',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: true,
+    },
+    {
+        name: 'project4',
+        label: '项目4组',
+        width: '120',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: true,
+    },
+    {
+        name: 'project5',
+        label: '项目5组',
+        width: '120',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: true,
+    },
+    {
+        name: 'project6',
+        label: '项目6组',
+        width: '120',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: true,
+    },
+    {
+        name: 'project7',
+        label: '项目7组',
+        width: '120',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: true,
+    },
+]);

+ 40 - 0
src/views/userPrivilegeManagement/index.vue

@@ -0,0 +1,40 @@
+<template>
+    <div class="main_container">
+        <div class="page_item end_item">
+            <TabSearch :tabList="tabList" 
+                tabType="line" 
+                :defaultTabKey="defaultTabKey" 
+                @tabChange="HandleTabChange"/>
+
+            <div class="page_solid_line" />
+            <div class="page_jg_20" />
+
+            <!-- 不同的模块 -->
+            <UserManage  v-if="defaultTabKey == 'userManage'"/>
+            <GroupManage  v-if="defaultTabKey == 'groupManage'"/>
+
+
+        </div>
+    </div>
+</template>
+
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import TabSearch from '@/baseComponents/TabSearch.vue';
+import { tabList } from './tabSearch';
+
+import UserManage from './userManage/index.vue';
+import GroupManage from './groupManage/index.vue'
+
+const defaultTabKey = ref('userManage')
+
+const HandleTabChange = (val)=>{
+    defaultTabKey.value = val
+}
+</script>
+
+
+<style lang="scss" scoped>
+
+</style>

+ 24 - 0
src/views/userPrivilegeManagement/tabSearch.ts

@@ -0,0 +1,24 @@
+import { ref } from "vue"
+
+export const tabList = ref([
+    {
+        label:'用户管理',
+        key:'userManage',
+    },
+    {
+        label:'分组管理',
+        key:'groupManage',
+    },
+    {
+        label:'分组列表',
+        key:'groupList',
+    },
+    {
+        label:'权限管理',
+        key:'permissionManage',
+    },
+    {
+        label:'权限列表',
+        key:'permissionList',
+    },
+])

+ 11 - 0
src/views/userPrivilegeManagement/userManage/formSearch.ts

@@ -0,0 +1,11 @@
+import { ref } from "vue";
+
+
+export const  formSearhList = ref([
+    {
+        key:'queryStr',
+        type:'input',
+        placeholder:'请输入',
+        defaultValue:'',
+    }
+])

+ 59 - 0
src/views/userPrivilegeManagement/userManage/index.vue

@@ -0,0 +1,59 @@
+<template>
+    <div class="end_item">
+        <div class="page_search">
+            <div class="search_content">
+                <div class="content_left">
+                    <el-button class="button_background">启用用户</el-button>
+                    <el-button class="button_refresh">禁用用户</el-button>
+                    <FormSearchGroup :searchList="formSearhList"></FormSearchGroup>
+                </div>
+                <div class="content_right">
+                    <el-button class="button_border">新增用户</el-button>
+                </div>
+            </div>
+        </div>
+
+        <div class="page_jg_20" />
+        <Table :tableColumns="tableColumns" :tableData="userTableData" 
+            :pageNum = "pageNum" :pageSize = "pageSize" :totalNum = "totalNum">
+            <template #num="{row,currentIndex}">
+                {{ (currentIndex - 1 ) * pageSize + pageNum }}
+            </template>
+        </Table>
+    </div>
+</template>
+
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import FormSearchGroup from '@/baseComponents/FormSearchGroup.vue';
+import {formSearhList} from './formSearch'
+import Table from '@/baseComponents/Table.vue';
+
+import {tableColumns} from './table'
+
+const pageNum = ref(1)
+const pageSize = ref(20)
+const totalNum = ref(0)
+
+const userTableData = ref([
+    {
+        account:'xxx',
+        name:'xxx',
+        gender:'xxx',
+        phone:'xxx',
+        status:'xxx',
+        publicFollow:'xxx',
+        historyFollow:'xxx',
+        holdLimit:'xxx',
+        dailyReturnLimit:'xxx',
+        returnDays:'xxx',
+        action:'xxx',
+    }
+])
+</script>
+
+
+<style lang="scss" scoped>
+
+</style>

+ 114 - 0
src/views/userPrivilegeManagement/userManage/table.ts

@@ -0,0 +1,114 @@
+import { ref } from "vue";
+
+
+
+export const tableColumns = ref([
+    {
+        name: 'num',
+        label: '序号',
+        width: '80',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: true,
+    },
+    {
+        name: 'account',
+        label: '账号',
+        width: '',
+        fixed: '',
+        align: 'center', 
+        minWidth: '120',
+        custom: false,
+    },
+    {
+        name: 'name',
+        label: '姓名',
+        width: '',
+        fixed: '',
+        align: 'center',
+        minWidth: '100',
+        custom: false,
+    },
+    {
+        name: 'gender',
+        label: '性别',
+        width: '80',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'phone',
+        label: '手机号',
+        width: '',
+        fixed: '',
+        align: 'center',
+        minWidth: '120',
+        custom: false,
+    },
+    {
+        name: 'status',
+        label: '账号状态',
+        width: '100',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'publicFollow',
+        label: '公海跟进',
+        width: '100',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'historyFollow',
+        label: '历史跟进',
+        width: '100',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'holdLimit',
+        label: '持有上限',
+        width: '100',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'dailyReturnLimit',
+        label: '日退上限',
+        width: '100',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'returnDays',
+        label: '退回公海天数',
+        width: '120',
+        fixed: '',
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+    {
+        name: 'operation',
+        label: '操作',
+        width: '260',
+        fixed: 'right', 
+        align: 'center',
+        minWidth: '',
+        custom: false,
+    },
+])