zhouwx
2024-06-20 bc35d48bada733a0a4677cce54f3aa5ce3080be6
提交
已修改11个文件
已添加4个文件
905 ■■■■ 文件已修改
.env.development 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/onlineEducation/banner.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/onlineEducation/company.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/onlineEducation/user.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/scrollSelect/index.vue 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/menu.js 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/user.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/directive.ts 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/selectLoadMoreDirective.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/homePage.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/onlineEducation/systemManage/banner/components/bannerDialog.vue 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/onlineEducation/systemManage/banner/index.vue 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/onlineEducation/systemManage/user/components/userDialog.vue 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/onlineEducation/systemManage/user/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.development
@@ -9,7 +9,7 @@
#VITE_APP_BASE_API = 'http://192.168.0.47:8085'
#孔哥
VITE_APP_BASE_API = 'http://192.168.0.77:8082/api'
VITE_APP_BASE_API = 'http://192.168.2.15:8082/api'
#线上
#VITE_APP_BASE_API = 'http://106.15.95.149:8088/api'
src/api/onlineEducation/banner.js
对比新文件
@@ -0,0 +1,54 @@
import request from '@/utils/request'
export function delPic(path) {
    return request({
        url: '/system/common/removeFile',
        method: 'delete',
        params: path,
        timeout: 20000
    })
}
export function getBanner(params) {
    return request({
        url: '/system/carousel/list',
        method: 'get',
        params: params
    })
}
export function addBanner(data) {
    return request({
        url: '/system/carousel',
        method: 'post',
        data: data
    })
}
export function editBanner(params) {
    return request({
        url: `/system/carousel`,
        method: 'put',
        data: params
    })
}
export function delBanner(data) {
    return request({
        url: `/system/carousel/` + data,
        method: 'delete'
    })
}
export function getBannerById(params) {
    return request({
        url: '/system/carousel/' +params ,
        method: 'get',
        params: params
    })
}
src/api/onlineEducation/company.js
@@ -1,9 +1,10 @@
import request from '@/utils/request'
export function getCompany() {
export function getCompany(params) {
    return request({
        url: '/system/company/list',
        method: 'get'
        method: 'get',
        params: params
    })
}
src/api/onlineEducation/user.js
@@ -1,9 +1,10 @@
import request from '@/utils/request'
export function getUser() {
export function getUser(param) {
    return request({
        url: '/system/user/list',
        method: 'get'
        method: 'get',
        params: param
    })
}
@@ -22,18 +23,25 @@
        data: data
    })
}
export function editCompany(params) {
export function editUser(params) {
    return request({
        url: `/system/company`,
        url: `system/user`,
        method: 'put',
        data: params
    })
}
export function delCompany(data) {
export function resetPwd(params) {
    return request({
        url: `system/company/` + data,
        method: 'delete'
        url: `/system/user/resetPwd`,
        method: 'put',
        data: params
    })
}
export function delUser(userId) {
    return request({
        url: '/system/user/' + userId,
        method: 'put'
    })
}
src/components/scrollSelect/index.vue
对比新文件
@@ -0,0 +1,102 @@
<template>
  <el-select v-if="isMounted" v-bind="$attrs" :remote-method="remoteMethod" @change="selectValueUser">
    <div v-infinite-scroll="loadMore" style="overflow: hidden">
      <el-option v-for="dict in list" :key="dict.id" :label="dict.name" :value="dict.name" />
    </div>
  </el-select>
</template>
<script lang="ts" setup>
import {defineEmits, onMounted, ref} from 'vue'
import {debounce} from "@/utils";
const props = defineProps({
  // 传入对应的列表加载api
  methods: {
    type: Function,
    default: ''
  },
  // 传入查询关键字
  searchKey: {
    type: String,
    default: ''
  },
})
const list = ref([
  {
    id: '',
    name: '无上级账号'
  }
])
const queryFrom = ref({
  pageNum: 1,
  totlePage: 1,
  pageSize: 10,
  userType: null,
  companyId: null
})
const isMounted = ref(false)
onMounted(() => {
  isMounted.value = true
})
const emit = defineEmits(["getval"]);
const selectValueUser = (val) => {
  list.value.forEach(item => {
    if(item.name === val){
      emit('getval',item.id)
    }
  })
}
// 自定义远程搜索方法
const remoteMethod = (query: string) => {
  queryFrom.value.pageNum = 1
  list.value = []
  queryFrom.value[props.searchKey] = query
  getList(param.value,'')
}
// 调用props.methods获取下拉数据
const param = ref();
const getList = (val,type) => {
  if(val){
    param.value = val;
    queryFrom.value.userType = val.userType;
    queryFrom.value.companyId = val.companyId;
    props.methods(queryFrom.value).then(res => {
      const obj = {
        id: '',
        name: '无上级账号'
      }
      if(type === 'change'){
        list.value = res.data.list
        list.value.unshift(obj)
      }else {
        list.value = [...list.value, ...res.data.list]
        if(queryFrom.value.pageNum === 1){
          list.value.unshift(obj)
        }
      }
      queryFrom.value.totlePage = res.data.totalPage
    })
  }
}
// 获取初始数据
// getList(param.value,'')
// 无限滚动触底加载
const loadMore = debounce(() => {
  if (queryFrom.value.pageNum >= queryFrom.value.totlePage) return
  queryFrom.value.pageNum++
  getList(param.value,'')
}, 200)
defineExpose({
 getList
});
</script>
src/layout/components/Sidebar/menu.js
@@ -64,27 +64,61 @@
            ]
        },
    ],
    agencyMenu: [
    companyMenu: [
        {
            path: '/project',
            name: 'Project',
            meta: { title: '项目管理',icon: 'form',affix: true }
            path: '/course',
            name: 'Course',
            meta: { title: '课程管理',icon: 'documentation',affix: true }
        },
        {
            path: '/projectSupplement',
            name: 'projectSupplement',
            meta: { title: '项目补录',icon: 'form',affix: true }
            path: '/question',
            name: 'Question',
            meta: { title: '题库管理',icon: 'build',affix: true }
        },
        {
            path: '/userManage',
            redirect: '/userManage/supervise',
            meta: { title: '用户管理',icon: 'peoples'},
            path: '/class',
            name: 'Class',
            meta: { title: '课时批次',icon: 'education',affix: true }
        },
        {
            path: '/group',
            name: 'Group',
            meta: { title: '组卷考试分配',icon: 'job',affix: true }
        },
        {
            path: '/offline',
            name: 'Offline',
            meta: { title: '线下教育登记',icon: 'log',affix: true }
        },
        {
            path: '/people',
            name: 'People',
            meta: { title: '人员管理',icon: 'peoples',affix: true }
        },
        {
            path: '/count',
            name: 'Count',
            meta: { title: '数据统计',icon: 'server',affix: true }
        },
        {
            path: '/systemManage',
            redirect: '/systemManage/courseClassification',
            meta: { title: '系统管理',icon: 'dict'},
            children: [
                {
                    path: 'expertUsers',
                    name: 'expertUsers',
                    meta: { title: '专家用户管理',icon: 'logininfor'}
                    path: 'courseClassification',
                    name: 'courseClassification',
                    meta: { title: '课程分类',icon: 'form'}
                } ,
                {
                    path: 'user',
                    name: 'user',
                    meta: { title: '用户管理',icon: 'logininfor'}
                } ,
                {
                    path: 'banner',
                    name: 'banner',
                    meta: { title: '轮播图管理',icon: 'druid'}
                } ,
            ]
        },
src/router/index.js
@@ -44,7 +44,7 @@
  },
  {
    path: "/:pathMatch(.*)*",
    component: () => import('@/views/error/404'),
    component: () => import('@/views/homePage'),
    hidden: true
  },
  {
src/store/modules/user.js
@@ -2,7 +2,7 @@
import { getToken, setToken, removeToken } from '@/utils/auth'
import defAva from '@/assets/images/profile.jpg'
import Cookies from "js-cookie";
import {getUserById} from "@/api/sysUsers";
import {getUserById} from "@/api/onlineEducation/user";
const useUserStore = defineStore(
  'user',
  {
@@ -25,7 +25,11 @@
        return new Promise( (resolve, reject) => {
          login(username, password, code, uuid, identity).then( async res => {
            setToken(res.data.token)
            Cookies.set('userInfo',JSON.stringify(res.data))
            if(res.data && res.data.id){
              const info = await getUserById(res.data.id);
              if(info.data.code === 200){}
              Cookies.set('userInfo',JSON.stringify(info.data))
            }
            this.token = res.data.token
            resolve()
          }).catch(error => {
src/utils/directive.ts
对比新文件
@@ -0,0 +1,26 @@
import { Directive, DirectiveBinding } from 'vue'
const loadMore: Directive = {
    beforeMount(el: any, binding: DirectiveBinding) {
        let arg = binding.arg as any
        if (!arg) return
        const selectDom = document.querySelector(`.${arg.name} .el-select-dropdown .el-select-dropdown__wrap`)
        function loadMores(this: any) {
            const isBase = this.scrollHeight - this.scrollTop <= this.clientHeight
            if (isBase) {
                binding.value && binding.value(arg)
            }
        }
        el.selectDomInfo = selectDom
        el.userLoadMore = loadMores
        selectDom?.addEventListener('scroll', loadMores)
    },
    beforeUnmount(el: any) {
        if (el.userLoadMore) {
            el.selectDomInfo.removeEventListener('scroll', el.userLoadMore)
            delete el.selectDomInfo
            delete el.userLoadMore
        }
    }
}
export default loadMore
src/utils/selectLoadMoreDirective.ts
@@ -1,7 +1,7 @@
import {Directive, DirectiveBinding, nextTick} from 'vue'
const loadMore: Directive = {
    beforeMount(el: any, binding: DirectiveBinding) {
        console.log(el)
        console.log('111',el)
        const selectDom = (document.querySelector(".more_select_dropdown") as any).querySelector(".el-select-dropdown .el-select-dropdown__wrap");
        console.log(selectDom, 'selectDom++++++++++++++');
        function loadMores(this: any) {
src/views/homePage.vue
@@ -168,9 +168,14 @@
        //   sidebarRouters.value =  menu.agencyMenu
        //   Cookies.set('routers',JSON.stringify(sidebarRouters.value))
        // }
        sidebarRouters.value =  menu.adminMenu
        Cookies.set('routers',JSON.stringify(sidebarRouters.value))
        const userInfo = JSON.parse(Cookies.get('userInfo'))
        if(userInfo.userType === 0) {
          sidebarRouters.value =  menu.adminMenu
          Cookies.set('routers',JSON.stringify(sidebarRouters.value))
        }else {
          sidebarRouters.value =  menu.companyMenu
          Cookies.set('routers',JSON.stringify(sidebarRouters.value))
        }
        let path = ""
        if(sidebarRouters.value[0].children && sidebarRouters.value[0].children.length > 0){
          path = sidebarRouters.value[0].path + '/'+ sidebarRouters.value[0].children[0].path
src/views/onlineEducation/systemManage/banner/components/bannerDialog.vue
对比新文件
@@ -0,0 +1,238 @@
<template>
  <div class="notice">
    <el-dialog
        v-model="dialogVisible"
        :title="title"
        width="550px"
        :before-close="handleClose"
    >
      <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="100px" >
        <el-form-item label="标题:" prop="title" >
          <el-input v-model.trim="state.form.title"></el-input>
        </el-form-item>
        <el-form-item prop="imgUrl" label="图片:">
          <el-upload accept="image/*" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.imgLimit' v-model:file-list="state.imgList" list-type="picture-card" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,'证书')" >
            <el-icon><Plus /></el-icon>
            <template #tip>
              <div class="el-upload__tip">上传jpg/png图片尺寸小于5M,最多可上传1张</div>
            </template>
          </el-upload>
        </el-form-item>
        <el-form-item label="地址:" prop="webUrl">
          <el-input v-model.trim="state.form.webUrl"></el-input>
        </el-form-item>
        <el-form-item label="跳转方式:" prop="carouselTarget" >
          <el-radio-group v-model="state.form.carouselTarget" >
            <el-radio :label="0">新窗口打开</el-radio>
            <el-radio :label="1">内部打开</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="排序:" prop="sort" >
          <el-input-number v-model="state.form.sort" />
        </el-form-item>
        <el-form-item label="状态" prop="status" >
          <el-switch
              v-model="state.form.status"
              class="ml-2"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
            <el-button @click="handleClose" size="default">取 消</el-button>
            <el-button type="primary"  @click="onSubmit" size="default" v-preReClick>确认</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import {reactive, ref, toRefs} from 'vue'
import Editor from "@/components/Editor/index.vue";
import {ElMessage} from "element-plus";
import {addNotice} from "@/api/backManage/notice";
import {addDict, editDict, getDictDetail} from "@/api/backManage/evaluate";
import {addCompany, checkName, distributeCompany, editCompany} from "@/api/onlineEducation/company";
import {verifyPhone} from "@/utils/validate";
import {addBanner, delPic, editBanner, getBannerById} from "@/api/onlineEducation/banner";
import {getToken} from "@/utils/auth";
import {getUserById} from "@/api/onlineEducation/user";
const dialogVisible = ref(false);
const title = ref("");
const busRef = ref();
const length = ref()
const emit = defineEmits(["getList"]);
const startUsername = ref('');
const startPhone = ref('');
const state = reactive({
  form: {
    id: '',
    title: '',
    imgUrl: '',
    webUrl: '',
    carouselTarget: 0,
    sort: 0,
    status: true,
  },
  formRules:{
    title: [{ required: true, message: '请输入广告标题', trigger: 'blur' }],
    imgUrl: [{ required: true, message: '请上传图片', trigger: 'blur' }],
    webUrl: [{ required: true, message: '请输入地址', trigger: 'blur' }],
  },
  uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile',
  header: {
    Authorization:getToken()
  },
  imgLimit: 1,
  imgList: []
})
const handleAvatarSuccess = (res, uploadFile) => {
  if(res.code == 200){
    state.form.imgUrl = res.data.path
  }else{
    state.imgList = []
    ElMessage({
      type: 'warning',
      message: '文件上传失败'
    })
  }
}
const showTip =()=>{
  ElMessage({
    type: 'warning',
    message: '超出文件上传数量'
  });
}
const picSize = async (rawFile) => {
  if(rawFile.size / 1024 / 1024 > 5){
    ElMessage({
      type: 'warning',
      message: '文件大小不能超过5M'
    });
    return false
  }
};
const handleRemove = async (file, uploadFiles) => {
  let path = state.form.imgUrl;
  await delPic({path: path}).then(res => {
    if(res.code == 200){
      // ElMessage({
      //   type: 'success',
      //   message: '文件已删除'
      // })
      state.form.imgUrl = ''
    }else{
      ElMessage({
        type: 'warning',
        message: res.message
      })
    }
  }).catch(() => {
    state.form.imgUrl = ''
  });
}
const openDialog = async (type, value) => {
  length.value = value.listLength
  title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ;
  if(type === 'edit') {
    const res = await getBannerById(value.id);
    if(res.code === 200){
      state.form = res.data
      console.log("11",res.data)
      state.form.carouselTarget = parseInt(res.data.carouselTarget)
      state.form.status = res.data.status == 0
      if(res.data.imgUrl) {
        const obj = {
          url: import.meta.env.VITE_APP_BASE_API + "/" +  res.data.imgUrl,
          name: ''
        }
        state.imgList = [obj]
      }
      console.log('imgList',state.imgList)
    }else{
      ElMessage.warning(res.message)
    }
  }
  dialogVisible.value = true;
}
const onSubmit = async () => {
  const valid = await busRef.value.validate();
  if(valid){
    if(title.value === '新增'){
      const {id, ...data} = JSON.parse(JSON.stringify(state.form))
      data.status = data.status ? 0 : 1
      const res = await addBanner(data)
      if(res.code === 200){
        ElMessage({
          type: 'success',
          message: '新增成功'
        });
      }else{
        ElMessage.warning(res.message)
      }
      emit("getList")
      busRef.value.clearValidate();
      reset();
      dialogVisible.value = false;
    }else if(title.value === '编辑'){
      const {...data} = JSON.parse(JSON.stringify(state.form))
      data.status = data.status ? 0 : 1
      const res = await editBanner(data)
      if(res.code === 200){
        ElMessage({
          type: 'success',
          message: '编辑成功'
        });
      }else{
        ElMessage.warning(res.message)
      }
      emit("getList")
      busRef.value.clearValidate();
      reset();
      dialogVisible.value = false;
    }
  }
}
const handleClose = () => {
  busRef.value.clearValidate();
  reset();
  dialogVisible.value = false;
  emit("getList")
}
const reset = () => {
  state.form = {
    id: '',
    title: '',
    imgUrl: '',
    webUrl: '',
    carouselTarget: 0,
    sort: 0,
    status: true,
  }
  state.imgList = []
}
defineExpose({
  openDialog
});
</script>
<style scoped lang="scss">
.notice{
  :deep(.el-form .el-form-item__label) {
    font-size: 15px;
  }
  .file {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
  }
}
</style>
src/views/onlineEducation/systemManage/banner/index.vue
@@ -1,12 +1,134 @@
<template>
<div>轮播图管理</div>
  <div class="app-container">
    <div style="margin-bottom: 10px">
      <el-button
          type="primary"
          plain
          icon="Plus"
          @click="openDialog('add',{})"
      >新增</el-button>
    </div>
    <!-- 表格数据 -->
    <el-table v-loading="loading" :data="dataList" :border="true">
      <el-table-column label="序号" type="index" align="center" width="80" />
      <el-table-column label="标题" prop="title" align="center"  />
      <el-table-column label="图片" prop="imgUrl" align="center" >
        <template #default="scope">
          <div class="demo-image__preview" v-if="scope.row.imgUrl && scope.row.imgUrl.length>0">
            <el-image
                style="width: 100px; height: 100px"
                :src= "scope.row.imgUrl[0]"
                :zoom-rate="1.2"
                :max-scale="7"
                :min-scale="0.2"
                :preview-src-list="scope.row.imgUrl"
                :initial-index="0"
                fit="cover"
                :preview-teleported=true
            />
          </div>
        </template>
      </el-table-column>
      <el-table-column label="地址" prop="webUrl" align="center" />
      <el-table-column label="跳转方式" prop="carouselTarget" align="center"  >
        <template #default="scope">
         <span>{{scope.row.carouselTarget == 0 ? '新窗口打开' : '内部打开' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="排序" prop="sort" align="center"/>
      <el-table-column label="状态" prop="status" align="center" width="150"/>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" >
        <template #default="scope">
          <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button>
          <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <pagination
        v-show="total > 0"
        :total="total"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="getList"
    />
    <banner-dialog ref="dialogRef" @getList=getList></banner-dialog>
  </div>
</template>
<script setup>
import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {delCompany, getCompany} from "@/api/onlineEducation/company";
import bannerDialog from  './components/bannerDialog.vue'
import {delBanner, getBanner} from "@/api/onlineEducation/banner";
const { proxy } = getCurrentInstance();
const loading = ref(false);
const dialogRef = ref();
const data = reactive({
  queryParams: {
    pageNum: 1,
    pageSize: 10,
  },
  total: 0,
  dataList: []
});
const { queryParams, total, dataList } = toRefs(data);
onMounted(()=>{
  getList()
})
onUnmounted(()=>{
})
const getList = async () => {
  loading.value = true
  const res = await getBanner(data.queryParams)
  if(res.code == 200){
    data.dataList = res.data.list.map(item => {
      return {
        ...item,
        status: item.status === 0 ? '正常' : '停用',
        imgUrl: item.imgUrl ?[import.meta.env.VITE_APP_BASE_API + "/" +  item.imgUrl] : []
      }
    })
    console.log("ddd",data.dataList)
    data.total = res.data.total
  }else{
    ElMessage.warning(res.message)
  }
  loading.value = false
}
const openDialog = (type, value) => {
  dialogRef.value.openDialog(type, value);
}
/** 重置新增的表单以及其他数据  */
function reset() {
  proxy.resetForm("roleRef");
}
const handleDelete = (val) => {
  ElMessageBox.confirm(
      '确定删除此条数据?',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then( async() => {
        const res = await delBanner(val.id)
        if(res.code == 200){
          ElMessage.success('数据删除成功')
          await getList()
        }else{
          ElMessage.warning(res.message)
        }
      })
}
</script>
<style scoped lang="scss">
</style>
src/views/onlineEducation/systemManage/user/components/userDialog.vue
@@ -11,7 +11,13 @@
          <el-input v-model.trim="state.form.username" :disabled="state.title =='编辑' || state.title =='查看'" placeholder="请输入用户名" ></el-input>
        </el-form-item>
        <el-form-item label="名称:"  prop="name" v-if="state.title !== '修改密码'">
          <el-input v-model.trim="state.form.name" :disabled="state.title =='编辑' || state.title =='查看'" placeholder="请输入公司、部门或者车间岗位名"></el-input>
          <el-input v-model.trim="state.form.name" :disabled="disabled" placeholder="请输入公司、部门或者车间岗位名"></el-input>
        </el-form-item>
        <el-form-item label="性别:"  prop="sex" v-if="state.title !== '修改密码'">
          <el-radio-group v-model="state.form.sex"  :disabled="disabled">
            <el-radio :label="0">男</el-radio>
            <el-radio :label="1">女</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="密码:" prop="password" v-if="state.title == '新增' || state.title == '修改密码'">
          <el-input v-model.trim="state.form.password" type="password" show-password placeholder="请输入密码"></el-input>
@@ -23,47 +29,46 @@
          <el-input v-model.trim="state.form.phone" :maxlength="11" :disabled="disabled" placeholder="请输入手机号"></el-input>
        </el-form-item>
        <el-form-item label="用户类型:" v-if="state.title !== '修改密码'">
          <el-radio-group v-model="state.form.userType"  :disabled="disabled">
            <el-radio :label="0">管理员</el-radio>
          <el-radio-group v-model="state.form.userType"  :disabled="disabled" @change="changeType">
            <el-radio :label="0" v-if="state.isAdmin">管理员</el-radio>
            <el-radio :label="1">企业级</el-radio>
            <el-radio :label="2">部门级</el-radio>
            <el-radio :label="3">车间(岗位)级</el-radio>
            <el-radio :label="4">其他</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="选择所属父级账号:" prop="companyId" v-if="state.title !== '修改密码'">
          <el-select
               v-model="state.form.companyName"
               @change="selectValue"
               style="width: 45%"
               v-loadMore="loadMore"
               class="m-2"
               placeholder="请选择所属企业"
               popper-class="more_select_dropdown"
          >
            <el-option
                v-for="item in state.companyList"
                :key="item.id"
                :label="item.name"
                :value="item.name"
            />
          </el-select>
          <el-select
              v-if="state.form.userType === 2 || state.form.userType === 3 "
              v-model="state.form.userName"
              @change="selectValueUser"
              style="width: 45%;margin-left: 10px"
              class="m-2"
              placeholder="请选择所属上级账号"
              popper-class="more_select_dropdown"
          >
            <el-option
                v-for="item in state.userList"
                :key="item.id"
                :label="item.name"
                :value="item.name"
            />
          </el-select>
        <el-form-item label="选择所属父级账号:" prop="companyId" v-if="state.title !== '修改密码' && state.form.userType !== 0">
            <el-select
                v-if="state.isAdmin"
                v-model="state.form.companyName"
                @change="selectValue"
                style="width: 45%"
                v-loadMore="loadMore"
                class="m-2"
                placeholder="请选择所属企业"
                popper-class="more_select_dropdown"
            >
              <el-option
                  v-for="item in state.companyList"
                  :key="item.id"
                  :label="item.name"
                  :value="item.name"
              />
            </el-select>
          <el-input v-else disabled style="width: 45%" v-model="state.form.companyName"></el-input>
            <scorllSelect
                ref="scrollRef"
                v-if="UisMounted && (state.form.userType === 2 || state.form.userType === 3)"
                v-model="state.form.parentName"
                @getval = "getSelectUser"
                placeholder="请选择"
                clearable
                style="width: 45%;margin-left: 10px"
                filterable
                remote
                searchKey="name"
                :methods="getUser">
            </scorllSelect>
        </el-form-item>
      </el-form>
      <template #footer v-if="state.title !='查看'">
@@ -76,22 +81,27 @@
  </div>
</template>
<script setup>
import {reactive, ref, toRefs, defineEmits, nextTick} from 'vue'
import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue'
import { View } from "@element-plus/icons-vue";
import scorllSelect from '@/components/scrollSelect/index.vue'
import {ElMessage} from "element-plus";
import {verifyPhone, verifyPwd, verifyUsername} from "../../../../../utils/validate";
import { checkUserName, checkPhone } from "@/api/login"
import {getUserById} from "@/api/onlineEducation/user"
import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user"
import {Base64} from "js-base64"
import {resetUserPwd} from "../../../../../api/sysUsers";
import {getInstitutionDetail} from "@/api/backManage/insitution";
import {getCompany} from "@/api/onlineEducation/company";
import {get} from "@vueuse/core";
import {getUser} from "@/api/system/user";
import {getUser} from "@/api/onlineEducation/user";
import {debounce} from "@/utils";
import Cookies from "js-cookie";
const emit = defineEmits(["getList"]);
const dialogVisible = ref(false)
const superRef = ref(null)
const scrollRef = ref(null)
const equalToPassword = (rule, value, callback) => {
  if (state.form.password !== value) {
@@ -135,6 +145,7 @@
    confirmPassword: '',
    username: '',
    userType: 0,
    sex: 0,
    companyId: null,
    parentId: null
  },
@@ -146,16 +157,40 @@
    phone: [{ required: true, validator: validateUserPhone, trigger: 'blur' }],
  },
  companyList: [],
  userList: [],
  userList: [
  ],
  keyword:'',
  pageNum: 1,
  pageSize: 10
  pageSize: 10,
  cloading:false,
  totlePage: 0,
  userParam: {},
  isAdmin: false
})
const UisMounted = ref(false);
onMounted(() => {
  UisMounted.value = true;
});
const disabled = ref(false);
const openDialog = async (type, value) => {
  const userInfo = JSON.parse(Cookies.get('userInfo'))
  console.log("userInfo",userInfo)
  if(userInfo.userType === 0){
    state.isAdmin = true;
    state.form.userType = 0;
  }else {
    state.isAdmin = false;
    state.form.companyId = userInfo.companyId;
    state.form.companyName = userInfo.companyName;
    state.form.userType = 1;
  }
  await getCompanyList('open')
  await getUserList()
  state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : type ==='pwd' ? '修改密码' : '查看' ;
  if(type === 'edit' || type === 'view') {
    if( type === 'view'){
@@ -164,12 +199,23 @@
    const res = await getUserById(value.id);
    if(res.code === 200){
      state.form = res.data
      if(res.data.userType === 2|| res.data.userType === 3){
        if(!res.data.parentId){
          state.form.parentId = ''
          state.form.parentName = '无上级账号'
        }
      }
    }
  }
  if(type == 'pwd'){
    state.form.id = value.id
  }
  dialogVisible.value = true
  if(type === 'edit' && state.form && (state.form.userType === 2||state.form.userType === 3)){
    await nextTick(() => {
      doGetUser()
    })
  }
}
const finshed = ref(false)
@@ -199,31 +245,21 @@
    console.log("state.companyList",state.companyList)
  }
}
const getUserList = async () => {
  const queryParams = {
    userType: state.form.userType
  }
  const res = await getUser(queryParams)
  if (res.code == 200) {
    debugger
  } else {
    ElMessage.warning(res.message)
  }
}
const onSubmit = async () => {
  const valid = await superRef.value.validate();
  if(valid){
    if((state.form.userType ===1 && state.form.companyId ===null) || ((state.form.userType ===2 ||state.form.userType ===3) && (state.form.parentId ===null ||state.form.companyId===null))){
      ElMessage.warning('请选择所属父级账号')
      return;
    }
    if(state.title == '新增'){
      const {confirmPassword,id,...data} = state.form
      data.password = Base64.encode(data.password)
      const res = await addMonitor(data)
      const res = await addUser(data)
      if(res.code == 200){
        ElMessage.success(res.message)
        emit('getList')
        state.form.userType = 0
        superRef.value.clearValidate();
        superRef.value.resetFields();
        handleClose()
        dialogVisible.value = false;
      }else{
        ElMessage.warning(res.message)
@@ -231,14 +267,11 @@
    }else if(state.title == '编辑'){
      const {confirmPassword,...data} = state.form
      data.password = Base64.encode(data.password)
      const res = await editMonitor(data)
      const res = await editUser(data)
      if(res.code == 200){
        ElMessage.success(res.message)
        emit('getList')
        state.form.userType = 0
        superRef.value.clearValidate();
        superRef.value.resetFields();
        dialogVisible.value = false;
        handleClose()
      }else{
        ElMessage.warning(res.message)
      }
@@ -246,22 +279,57 @@
      const {id,password} = state.form
      const data = {id,password}
      data.password = Base64.encode(data.password)
      const res = await resetUserPwd(data)
      const res = await resetPwd(data)
      if(res.code == 200){
        ElMessage.success(res.message)
        emit('getList')
        superRef.value.clearValidate();
        superRef.value.resetFields();
        dialogVisible.value = false;
        handleClose()
      }else{
        ElMessage.warning(res.message)
      }
    }
  }
}
const doGetUser = () => {
  const param = {
    userType: state.form.userType-1,
    companyId: state.form.companyId,
  }
  scrollRef.value.getList(param,'change');
}
const changeType = () => {
  if(state.isAdmin){
    state.form.companyId = null;
    state.form.companyName = '';
  }
  state.form.parentId = null;
  state.form.parentName = '';
  if(state.form.userType === 2 || state.form.userType === 3 ){
    const param = {
      userType: state.form.userType-1,
      companyId: state.form.companyId,
    }
    scrollRef.value.getList(param,'change');
  }
}
const handleClose = () => {
  state.form.userType = 0
  state.form = {
    id: null,
    name: '',
    phone: '',
    password: '',
    confirmPassword: '',
    username: '',
    userType: 0,
    sex: 0,
    companyId: null,
    parentId: null
  }
  state.userList = [];
  state.companyList = [];
  state.pageNum = 1;
  state.pageSize = 10;
  superRef.value.clearValidate();
  superRef.value.resetFields()
  dialogVisible.value = false;
@@ -276,24 +344,32 @@
    getCompanyList('')
  }, 500)
}
const selectValue = (val) => {
  state.form.parentId = null;
  state.form.parentName = null;
  state.companyList.forEach(item => {
    if(item.name === val){
      state.form.companyId = item.id
      if(state.form.userType === 2 || state.form.userType === 3 ){
        const param = {
          userType: state.form.userType-1,
          companyId: state.form.companyId,
        }
        scrollRef.value.getList(param,'change');
      }
    }
  })
}
const selectValueUser = (val) => {
  state.userList.forEach(item => {
    if(item.name === val){
      state.form.parentId = item.id
    }
  })
const getSelectUser = (val) => {
  console.log("valllllllll",val)
  state.form.parentId = val;
}
defineExpose({
  openDialog
});
src/views/onlineEducation/systemManage/user/index.vue
@@ -41,7 +41,9 @@
import {ElMessage, ElMessageBox} from "element-plus";
import {delCompany, getCompany} from "@/api/onlineEducation/company";
import userDialog from './components/userDialog.vue'
import {getUser} from "@/api/onlineEducation/user";
import {delUser, getUser} from "@/api/onlineEducation/user";
import Cookies from "js-cookie";
const { proxy } = getCurrentInstance();
const loading = ref(false);
@@ -52,7 +54,8 @@
    pageSize: 10,
  },
  total: 0,
  dataList: []
  dataList: [],
});
const { queryParams, total, dataList } = toRefs(data);
@@ -100,7 +103,7 @@
        type: 'warning',
      })
      .then( async() => {
        const res = await delCompany(val.id)
        const res = await delUser(val.id)
        if(res.code == 200){
          ElMessage.success('数据删除成功')
          await getList()