浏览代码

添加/编辑用户弹窗

cxmo 1 年之前
父节点
当前提交
31481a612f

+ 2 - 1
src/components/searchDistPicker.vue

@@ -65,6 +65,7 @@ const areaSource = computed(() => {
     })
 })
 
+//数据回显
 watch(
     ()=>props.provinceInfo,
     (newval)=>{
@@ -82,7 +83,7 @@ watch(
                 const areaResult = Object.entries(area_sorce[city.value.cityKey]).find(([key,val])=>val===props.areaInfo)||['',props.areaInfo]
                 area.value = {areaKey:areaResult[0],areaName:areaResult[1]}
             }else{
-                area.value={areaKey:'',areaName:''}
+                area.value={areaKey:'',areaName:props.areaInfo}
             }
         }else{
             province.value={provinceKey:'',provinceName:''}

+ 309 - 7
src/views/system_manage/depart_manage/components/ModifyUserDialog.vue

@@ -1,33 +1,335 @@
 <script setup>
-import { ref, reactive } from 'vue'
-import * as $icon from '@/utils/icon'
+import { ref, reactive, watch, nextTick } from 'vue'
+import { departInterence } from '@/api/api.js';
+import $icon from '@/utils/icon'
+import {patternEmail,isMobileNo,checkPassWord} from '@/utils/commonOptions'
 import searchDistPicker from '@/components/searchDistPicker.vue'
+
 const props = defineProps({
     isShow: Boolean,
     type:String,
     userInfo:Object,
+    researchGroup:Array,
+    areaCode:Array,
+    departArr:Array,
+    roleArr:Array
+})
+const emit = defineEmits(["closeDia"],["save"])
+
+//用户表单原始信息
+const baseForm = {
+    admin_id:0,//当前编辑用户的id
+    account:'',//登录账号
+    pwd:'',//登录密码
+    name:'',//姓名
+    depart:'',//所属部门
+    role:'',//分配角色
+    direct:'',//研究方向
+    province:'',//工作地点-省
+    city:'',//工作地点-市
+    post:'',//职务
+    employeeNumber:'',//同步每刻的工号
+    areacode:'86',//号码前缀
+    mobile:'',//手机号码
+    auth:0,//表单没有用到,但是传参用到了,对应Authority字段
+    status:1,//状态 1启用 0禁用
+    email:'',//邮箱
+}
+let userForm = reactive({})
+let hasEmployeeNo = ref(false)
+watch(()=>props.isShow,(newval)=>{
+    //初始化userForm
+    Object.assign(userForm,baseForm) 
+    //清除表单校验
+    formRef.value?.resetFields()
+    if(newval&&props.type==='edit'){
+        setUserForm()
+    }
+    hasEmployeeNo.value = props.type==='add'?false:!!props.userInfo.EmployeeId
 })
-const emit = defineEmits(["closeDia"])
+//编辑用户信息时,设置userForm的值
+async function setUserForm(){
+    const {
+            AdminId,AdminName,Password,EmployeeId,Authority,Position,RealName,RoleId,Enabled,Email,
+            DepartmentId,GroupId,TeamId,TelAreaCode,Mobile,Province,City
+        } = props.userInfo
+    
+    let departArr = [];
+    departArr.push(DepartmentId)
+    GroupId?departArr.push(GroupId):''
+    TeamId ?departArr.push(TeamId):''
+
+    let ResearchGroupIds = []
+    const res = await departInterence.getResearchGroupByAdminId({AdminId})
+    if(res.Ret===200&&res.Data){
+        res.Data.forEach(item=>{
+            ResearchGroupIds.push(item.research_group_id)
+        })
+    }
+    
+    Object.assign(
+        userForm, 
+        {
+            admin_id:AdminId||0,
+            account:AdminName||'',
+            pwd:Password||'',
+            employeeNumber:EmployeeId||'',
+            name:RealName||'',
+            depart:departArr,
+            role:RoleId||'',
+            province:Province||'',
+            city:City||'',
+            post:Position||'',
+            mobile:Mobile||'',
+            auth:Authority,
+            status:Enabled,
+            direct:changeResearchGroupIdsToDirect(ResearchGroupIds,'tag_id'),
+            email:Email,
+            areacode:TelAreaCode||'86'
+        }
+    )
+}
+function roleChange(){}
+function selectRegion(){}
+//表单校验
+let formRef = ref(null)
+const formRules = reactive({
+    account:[{required: true, message: '登录账号不能为空', trigger: 'blur'}],
+    pwd:[{validator:(rule,value,callback)=>{
+        if(value===''){
+            callback(new Error('请输入新密码'))
+        }
+        if(!checkPassWord(value)){
+            callback(new Error('密码要求8位及以上,包含数字、大写字母、小写字母、特殊字符中的三个类型'))
+        }else{
+            callback()
+        }
+    }}],
+    name:[{ required: true, message: '姓名不能为空', trigger: 'blur' }],
+    mobile:[{ validator: (rule, value, callback) => {
+        if (value === ''&&!userForm.email) {
+            callback(new Error('手机号码和邮箱至少填一个'));
+        }else if(value&&userForm.areacode==='86'&&!isMobileNo(value)) {
+            callback(new Error('请输入正确的手机号格式'));
+        } else if(userForm.areacode!=='86'&&isNaN(value.trim())){
+            callback(new Error('请输入正确的手机号格式'));
+        }else {
+            callback();
+        }
+    }, trigger: 'blur'}],
+    email:[{ validator: (rule, value, callback) => {
+        if (value === ''&&!userForm.mobile) {
+            callback(new Error('手机号码和邮箱至少填一个'));
+        }else if(value&&!patternEmail.test(value)) {
+            callback(new Error('请输入正确的邮箱格式'));
+        } else {
+            callback();
+        }
+    }, trigger: 'blur'}],
+    depart:[{ required: true, message: '部门分组不能为空', trigger: 'change' }],
+    employeeNumber:[{validator:(rule,value,callback)=>{
+        if(!value){
+            callback()
+            return 
+        }
+        // 取消空格
+        let tempValue = parseInt(value.replaceAll(' ',''))
+        if(!tempValue || value.replaceAll(' ','').length!=4){
+            callback(new Error('请输入四位数字'))
+        }else{
+            callback()
+        }
+    },trigger:'blur'}],
+    role:[{ required: true, message: '角色不能为空', trigger: 'change' }],
+})
+async function handleSubmitForm(){
+    try{
+        await formRef.value?.validate()
+    }catch(e){
+        console.log(e)
+        return
+    }
+    
+    //通过
+    emit("save",{
+        type:props.type,
+        userForm
+    })
+}
+//转换研究员研究方向分组数据,用于编辑的回显
+function changeResearchGroupIdsToDirect(GroupIds,keyWord){
+    let direct = []
+    GroupIds.forEach(item=>{
+        direct.push(getResearchGroupByKeyword(item,keyWord))
+    })
+    return direct
+}
+function getResearchGroupByKeyword(GroupId,keyWord = "research_group_id"){
+    const getResearchGroupOption = (list, value) => {
+        for (let i in list) {
+            //排除掉一级
+        if (list[i].tag_id == value&&!list[i].classify_name) {
+            return [list[i]];
+        }
+        if (list[i].tags) {
+            let node = getResearchGroupOption(list[i].tags, value);
+            if (node !== undefined) {
+            return node.concat(list[i]);
+            }
+        }
+        }
+    }
+    const answer = getResearchGroupOption(props.researchGroup, GroupId)||[];
+    return answer.map((i) => i[keyWord]).reverse();
+}
+
 </script>
 
 <template>
     <el-dialog
-        v-model="props.isShow"
+        :model-value="props.isShow"
         :close-on-click-modal="false"
+        width="886px"
         @close="emit('closeDia')"
-        center
-    >
+        center>
         <template #header style="display:flex;align-items:center;">
             <img :src="type==='add'?$icon.add:$icon.edit"
                 style="color:#fff;width:16px;height:16px;margin-right:5px;">
             <span style="font-size:16px;">{{props.type==='add'?'添加用户':'编辑用户'}}</span>
         </template>
         <div class="form-content">
-            <searchDistPicker />
+            <el-form label-width="100px" class="user-form"
+                :hide-required-asterisk="true"
+                ref="formRef"
+                :model="userForm"
+                :rules="formRules" 
+            >
+                <el-form-item label="登录账号" prop="account">
+                    <el-input v-model="userForm.account" placeholder="建议使用邮箱前缀或者手机号码" clearable>
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="登录密码" prop="pwd" v-if="props.type==='add'">
+                    <el-input v-model.trim="userForm.pwd" placeholder="6-12位数字与字母的组合" 
+                        :type="props.type==='add' ? 'text' : 'password' " clearable></el-input>
+                </el-form-item>
+                <el-form-item label="姓名" prop="name">
+                    <el-input v-model="userForm.name" placeholder="请输入用户名称"  clearable>
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="手机号码" prop="mobile" class="mobile-input-item">
+                    <el-input v-model.trim="userForm.mobile" placeholder="请输入手机号码" clearable class="mobile-input">
+                    </el-input>
+                    <el-select v-model="userForm.areacode" class="mobile-select" placeholder="请选择">
+                        <el-option v-for="item in areaCode" :key="item.Value"
+                            :label="item.Name" :value="item.Value" />
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="所属部门" prop="depart" v-if="props.type==='add'">
+                    <el-cascader :options="departArr" 
+                        :props="{
+                            value:'DepartmentId',
+                            label:'DepartmentName',
+                            children:'Child',
+                            checkStrictly:true
+                        }" 
+                        v-model="userForm.depart"
+                        placeholder="请选择部门分组" clearable>
+                    </el-cascader>
+                </el-form-item>
+                <el-form-item label="邮箱" prop="email">
+                    <el-input v-model="userForm.email" placeholder="请输入邮箱"></el-input>
+                </el-form-item>
+                <el-form-item label="工号" prop="employeeNumber">
+                    <el-input :disabled="hasEmployeeNo" v-model="userForm.employeeNumber" placeholder="请输入工号"></el-input>
+                </el-form-item>
+                <el-form-item label="分配角色" prop="role">
+                    <el-select v-model="userForm.role" placeholder="分配角色" @change="roleChange">
+                        <el-option v-for="item in roleArr" :key="item.RoleId" :label="item.RoleName" :value="item.RoleId">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="研究方向" prop="direct">
+                    <el-cascader collapse-tags :show-all-levels="false" placeholder="请选择研究方向" 
+                        :options="researchGroup" 
+                        :props="{
+                            value:'tag_id',
+                            label:'tag_name',
+                            children:'tags',
+                            multiple: true
+                        }" 
+                        v-model="userForm.direct"
+                        clearable></el-cascader>
+                </el-form-item>
+                <el-form-item label="职务" prop="post">
+                    <el-input v-model="userForm.post" placeholder="请输入职务" clearable>
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="工作地点" prop="city"
+                    :rules="[2,6,18].includes(userForm.role)?{ required: true, message: '工作地点不能为空', trigger: 'change' }:{}">
+                        <search-dist-picker 
+                            :provinceInfo="userForm.province"
+                            :cityInfo="userForm.city"
+                            @selected="selectRegion"/>
+                </el-form-item>
+                <el-form-item label="状态" prop="status">
+                    <el-radio-group v-model="userForm.status">
+                        <el-radio :label="1">启用</el-radio>
+                        <el-radio :label="0">禁用</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+            </el-form>
+        </div>
+        <div class="btn-content">
+            <el-button type="primary" style="width:80px;margin-right:24px;" @click="handleSubmitForm">保存</el-button>
+            <el-button style="width:80px;" @click="emit('closeDia')">取消</el-button>
         </div>
     </el-dialog>
 </template>
 
 <style scoped lang="scss">
+.el-dialog{
+    .form-content{
+        .user-form{
+            display: flex;
+            flex-wrap: wrap;
+            gap:0 10px;
+            :deep(.el-form-item){
+                .el-input,.el-cascader,.el-select{
+                    width:300px;
+                }
+                .select-dist-picker{
+                    .el-select{
+                        width:145px;
+                        .el-input{
+                            width: 145px;
+                        }
+                    }
+                }
+            }
+            :deep(.mobile-input-item){
+                    position:relative;
+                    .mobile-select{
+                        position:absolute;
+                        top:0;
+                        left:0;
+                        width:115px !important;
+                        .el-input{
+                            width: 115px !important;
+                        }
+                    }
+                    .mobile-input{
+                        .el-input__inner{
+                            padding-left: 125px !important;
+                        }
+                    }
+                }
+        }
+    }
+    .btn-content{
+        display:flex;
+        justify-content:center;
+        margin-bottom: 20px;
+    }
+}
 
 </style>

+ 2 - 1
src/views/system_manage/depart_manage/components/UserDetail.vue

@@ -4,7 +4,8 @@ import { departInterence } from '@/api/api.js'
 const props = defineProps({
     isShow: Boolean,
     userInfo:{
-        RoleId:0
+        type:Object,
+        default:{RoleId:0}
     },
     researchGroup:Array
 })

+ 31 - 1
src/views/system_manage/depart_manage/departManage.vue

@@ -22,7 +22,7 @@ const {
         changeStatus,getUserDetail,
         openResetPassDialog,openMoveDepartDialog,
         getResearchGroup,researchGroup,
-        isModifyUserShow,openUserDialog,
+        isModifyUserShow,modifyUserType,userInfo,openUserDialog,
     } = useDepartTable()
 
 const defaultProp = {label:'DepartmentName',children:'Child'}
@@ -55,6 +55,24 @@ function synchronizationMEIKE(){
     })
 }
 
+let areaCode = ref([])
+function getAreaCode(){
+    departInterence.getPhoneAreaCode().then(res=>{
+        if(res.Ret!==200) return 
+        areaCode.value = res.Data||[]
+    })
+}
+
+//获取已有角色列表
+let roleArr = ref([])
+function getRoles() {
+    departInterence.getRole({ RoleLevel:0 }).then(res => {
+        if(res.Ret === 200) {
+            roleArr.value = res.Data.List||[];
+        }
+    })
+}
+
 
 //获取用户数据
 getTableUser()
@@ -64,6 +82,10 @@ getDepartArr()
 setShareCustomDepartId()
 //获取研究方向分组列表
 getResearchGroup()
+//获取手机区号
+getAreaCode()
+//获取已有角色列表
+getRoles()
 </script>
 
 <template>
@@ -203,6 +225,14 @@ getResearchGroup()
     <!-- 添加/编辑用户弹窗 -->
     <ModifyUserDialog 
         :isShow="isModifyUserShow"
+        :type="modifyUserType"
+        :userInfo="userInfo"
+        :researchGroup="researchGroup"
+        :areaCode="areaCode"
+        :departArr="departArr"
+        :roleArr="roleArr"
+        @save="isModifyUserShow = false"
+        @closeDia="isModifyUserShow = false"
     />
 </template>
 

+ 6 - 2
src/views/system_manage/depart_manage/hooks/use-depart.js

@@ -68,7 +68,11 @@ export function useDepart(){
         let userObj = ref(null)
         //打开添加/编辑用户弹窗 (原项目 addUser editUser 合成一个)
         let isModifyUserShow = ref(false)
-        function openUserDialog(){
+        let modifyUserType = ref('add')
+        let userInfo = ref({})
+        function openUserDialog(type,data){
+            modifyUserType.value = type
+            userInfo.value = data
             isModifyUserShow.value = true
         }
         //打开重置密码弹窗
@@ -118,7 +122,7 @@ export function useDepart(){
 
         return {
             isShowUserdtl,userObj,
-            isModifyUserShow,openUserDialog,
+            isModifyUserShow,modifyUserType,userInfo,openUserDialog,
             openResetPassDialog,openMoveDepartDialog,
             modifyUser,delUser,moveDepart,resetUserPassWord,
             getUserDetail,changeStatus,