无人机管理后台前端(已迁走)
罗广辉
2025-10-11 02409bfbe15f22fc3b5dccadabfd860a660a49d9
src/views/system/userinfo.vue
@@ -1,295 +1,299 @@
<template>
      <div class="user-info-new">
      <div class="titleBoxs">
         <div
            class="titleItem"
            :class="index === checked ? 'activeItem' : ''"
            v-for="(item, index) in titleList"
            :key="index"
            @click="titleClick(item, index)"
         >
            {{ item }}
         </div>
      </div>
      <!-- 个人信息 -->
      <div class="message" v-if="checked === 0">
         <div class="info">
            <div class="section">
               <el-form label-width="120px">
                  <el-form-item label="头像:">
                     <el-upload
                        class="avatar-uploader"
                        :http-request="customUpload"
                        :show-file-list="false"
                        :before-upload="beforeAvatarUpload"
                        :disabled="uploadLoading"
                        action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
                     >
                        <img v-if="userInfo.avatar" :src="userInfo.avatar" class="avatar" />
                        <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
  <div class="user-info-new">
    <div class="titleBoxs">
      <div
        class="titleItem"
        :class="index === checked ? 'activeItem' : ''"
        v-for="(item, index) in titleList"
        :key="index"
        @click="titleClick(item, index)"
      >
        {{ item }}
      </div>
    </div>
    <!-- 个人信息 -->
    <div class="message" v-if="checked === 0">
      <div class="info">
        <div class="section">
          <el-form label-width="120px">
            <el-form-item label="头像:">
              <el-upload
                class="avatar-uploader"
                :http-request="customUpload"
                :show-file-list="false"
                :before-upload="beforeAvatarUpload"
                :disabled="uploadLoading"
                action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
              >
                <img v-if="userInfo.avatar" :src="userInfo.avatar" class="avatar" />
                <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
                        <template #tip>
                           <div class="upload-tip">只能上传jpg/png用户头像,且不超过500kb</div>
                        </template>
                     </el-upload>
                     <!-- <el-dialog v-model="dialogVisible">
                <template #tip>
                  <div class="upload-tip">只能上传jpg/png用户头像,且不超过500kb</div>
                </template>
              </el-upload>
              <!-- <el-dialog v-model="dialogVisible">
                        <img w-full :src="dialogImageUrl" alt="Preview Image" />
                     </el-dialog> -->
                  </el-form-item>
               </el-form>
            </div>
            </el-form-item>
          </el-form>
        </div>
            <div class="section">
               <el-form :model="userInfo" label-width="120px">
                  <el-form-item label="姓名:">
                     <el-input class="ztzf-input" :style="{ width: pxToRem(230) }" v-model="userInfo.realName" disabled />
                  </el-form-item>
                  <!--                  <el-form-item label="昵称:">
        <div class="section">
          <el-form :model="userInfo" label-width="120px">
            <el-form-item label="姓名:">
              <el-input
                class="ztzf-input"
                :style="{ width: pxToRem(230) }"
                v-model="userInfo.realName"
                disabled
              />
            </el-form-item>
            <!--                  <el-form-item label="昵称:">
                                       <el-input class="ztzf-input" v-model="userInfo.name" />
                                    </el-form-item>-->
                  <el-form-item label="所属单位:">
                     <el-input class="ztzf-input" v-model="userInfo.deptName" disabled />
                  </el-form-item>
                  <el-form-item label="手机号:">
                     <el-input class="ztzf-input" v-model="userInfo.phone" />
                  </el-form-item>
                  <el-form-item label="邮箱:">
                     <el-input class="ztzf-input" v-model="userInfo.email" />
                  </el-form-item>
               </el-form>
            </div>
         </div>
         <div class="butn">
            <!-- <img @click="reset" :style="{ marginRight: pxToRem(23) }" :src="cancel1" alt="" />
            <el-form-item label="所属单位:">
              <el-input class="ztzf-input" v-model="userInfo.deptName" disabled />
            </el-form-item>
            <el-form-item label="手机号:">
              <el-input class="ztzf-input" v-model="userInfo.phone" />
            </el-form-item>
            <el-form-item label="邮箱:">
              <el-input class="ztzf-input" v-model="userInfo.email" />
            </el-form-item>
          </el-form>
        </div>
      </div>
      <div class="butn">
        <!-- <img @click="reset" :style="{ marginRight: pxToRem(23) }" :src="cancel1" alt="" />
            <img @click="submit" :style="{ marginRight: pxToRem(23) }" :src="publish1" alt="" /> -->
        <el-button type="primary" @click="submit" style="margin-right: 10px;">提交</el-button>
        <el-button type="primary" @click="submit" style="margin-right: 10px">提交</el-button>
        <el-button @click="reset">重置</el-button>
         </div>
      </div>
      <!-- 修改密码 -->
      <div class="passwordBox" v-else-if="checked === 1">
         <div class="password">
            <el-form :model="passwordForm" label-width="120px">
               <el-form-item label="原始密码:" prop="oldPassword">
                  <el-input class="ztzf-input" v-model="passwordForm.oldPassword" type="password" show-password />
               </el-form-item>
               <el-form-item label="新密码:" prop="newPassword">
                  <el-input class="ztzf-input" v-model="passwordForm.newPassword" type="password" show-password />
               </el-form-item>
               <el-form-item label="确认密码:" prop="newPassword1">
                  <el-input class="ztzf-input" v-model="passwordForm.newPassword1" type="password" show-password />
               </el-form-item>
            </el-form>
         </div>
         <div class="butn">
            <!-- <img @click="reset" :style="{ marginRight: pxToRem(23) }" :src="cancel1" alt="" />
            <img @click="submit" :style="{ marginRight: pxToRem(23) }" :src="publish1" alt="" /> -->
      <el-button type="primary" @click="submit" style="margin-right: 10px;">提交</el-button>
        <el-button @click="reset">重置</el-button>
         </div>
      </div>
      <!-- 密钥上传 -->
      <div class="upload-file" v-else-if="checked === 2">
         <img v-if="isSuccess === 'success'" :src="uploadSuccess" alt="" />
         <img v-if="isSuccess === 'error'" :src="uploadError" alt="" />
         <el-upload action="/upload" accept=".lic" :show-file-list="false" :before-upload="handleUpload">
            <div class="upload-btn">密钥上传</div>
         </el-upload>
         <div class="password-time">密钥有效期:{{ passwordTime || '永久有效' }}</div>
      </div>
      </div>
    </div>
    <!-- 修改密码 -->
    <div class="passwordBox" v-else-if="checked === 1">
      <div class="password">
        <el-form :model="passwordForm" label-width="120px">
          <el-form-item label="原始密码:" prop="oldPassword">
            <el-input
              class="ztzf-input"
              v-model="passwordForm.oldPassword"
              type="password"
              show-password
            />
          </el-form-item>
          <el-form-item label="新密码:" prop="newPassword">
            <el-input
              class="ztzf-input"
              v-model="passwordForm.newPassword"
              type="password"
              show-password
            />
          </el-form-item>
          <el-form-item label="确认密码:" prop="newPassword1">
            <el-input
              class="ztzf-input"
              v-model="passwordForm.newPassword1"
              type="password"
              show-password
            />
          </el-form-item>
        </el-form>
      </div>
      <div class="butn">
        <!-- <img @click="reset" :style="{ marginRight: pxToRem(23) }" :src="cancel1" alt="" />
            <img @click="submit" :style="{ marginRight: pxToRem(23) }" :src="publish1" alt="" /> -->
        <el-button type="primary" @click="submit" style="margin-right: 10px">提交</el-button>
        <el-button @click="reset">重置</el-button>
      </div>
    </div>
  </div>
</template>
<script setup>
import { pxToRem } from '@/utils/rem'
import { useStore } from 'vuex'
import { ElMessage } from 'element-plus'
import { getToken } from '@/utils/auth'
import md5 from 'js-md5'
import request from '@/axios'
import { getUserInfo, updateInfo, updatePassword } from '@/api/system/user'
import { findLicenseDate } from '@/api/system/dict'
import { uploadLicense } from '@/api/license/uploadLicense';
import { pxToRem } from '@/utils/rem';
import { useStore } from 'vuex';
import { ElMessage } from 'element-plus';
import { getToken } from '@/utils/auth';
import md5 from 'js-md5';
import request from '@/axios';
import { getUserInfo, updateInfo, updatePassword } from '@/api/system/user';
import { findLicenseDate } from '@/api/system/dict';
import uploadSuccess from '@/assets/images/uoload-success.png';
import uploadError from '@/assets/images/upload-error.png';
import cancel1 from '@/assets/images/task/cancel1.png';
import publish1 from '@/assets/images/task/publish1.png';
const store = useStore()
const token = getToken()
const userinforShow = defineModel('show')
const userInfoAs = computed(() => store.state.user.userInfo)
const titleList = ref(['个人信息', '修改密码', '密钥上传'])
const checked = ref(0)
const uploadUrl = computed(() => `${import.meta.env.VITE_APP_API_URL}/blade-resource/oss/endpoint/put-file`)
const store = useStore();
const token = getToken();
const userinforShow = defineModel('show');
const userInfoAs = computed(() => store.state.user.userInfo);
const titleList = ref(['个人信息', '修改密码']);
const checked = ref(0);
const uploadUrl = computed(
  () => `${import.meta.env.VITE_APP_API_URL}/blade-resource/oss/endpoint/put-file`
);
// 表单数据
const userInfo = ref({
   id: '',
   avatar: '',
   realName: '',
   name: '',
   phone: '',
   email: '',
   deptName: '',
})
  id: '',
  avatar: '',
  realName: '',
  name: '',
  phone: '',
  email: '',
  deptName: '',
});
// 校验手机号
const validatePhone = () => {
   const phoneRegex = /^1[3-9]\d{9}$/
   if (!phoneRegex.test(userInfo.value.phone)) {
      ElMessage.error('请输入正确的手机号码')
  const phone = userInfo.value.phone
  if (!phone) return true
  const phoneRegex = /^1[3-9]\d{9}$/
  if (!phoneRegex.test(phone)) {
    ElMessage.error('请输入正确的手机号码')
    return false
  }
  return true
}
// 校验邮箱
const validateEmail = () => {
   if (!userInfo.value.email) return true // 允许为空
   const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
   if (!emailRegex.test(userInfo.value.email)) {
      ElMessage.error('请输入正确的邮箱地址')
      return false
   }
   return true
}
const passwordForm = ref({
   oldPassword: '',
   newPassword: '',
   newPassword1: '',
})
  oldPassword: '',
  newPassword: '',
  newPassword1: '',
});
// 头像
const beforeAvatarUpload = file => {
   const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
   const isLt500KB = file.size / 1024 < 500
   if (!isJpgOrPng) {
      ElMessage.error('头像图片只能是 JPG/PNG 格式!')
      return false
   }
   if (!isLt500KB) {
      ElMessage.error('头像图片大小不能超过 500KB!')
      return false
   }
   return true
}
const uploadLoading = ref(false)
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  const isLt500KB = file.size / 1024 < 500;
  if (!isJpgOrPng) {
    ElMessage.error('头像图片只能是 JPG/PNG 格式!');
    return false;
  }
  if (!isLt500KB) {
    ElMessage.error('头像图片大小不能超过 500KB!');
    return false;
  }
  return true;
};
const uploadLoading = ref(false);
const customUpload = async options => {
   const { file } = options
   uploadLoading.value = true
  const { file } = options;
  uploadLoading.value = true;
   const formData = new FormData()
   formData.append('file', file) // 根据后端API调整字段名
   try {
      const res = await request.post('/blade-resource/oss/endpoint/put-file', formData, {
         headers: {
            'Content-Type': 'multipart/form-data',
         },
      })
  const formData = new FormData();
  formData.append('file', file); // 根据后端API调整字段名
  try {
    const res = await request.post('/blade-resource/oss/endpoint/put-file', formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
      if (res.data.code === 200) {
         ElMessage.success('头像上传成功')
         userInfo.value.avatar = res.data.data.link
         return res.data
      } else {
         throw new Error(res.data.msg || '上传失败')
      }
   } catch (error) {
      ElMessage.error(error.response?.data?.msg || error.message || '上传失败')
      return Promise.reject(error)
   } finally {
      uploadLoading.value = false
   }
}
    if (res.data.code === 200) {
      ElMessage.success('头像上传成功');
      userInfo.value.avatar = res.data.data.link;
      return res.data;
    } else {
      throw new Error(res.data.msg || '上传失败');
    }
  } catch (error) {
    ElMessage.error(error.response?.data?.msg || error.message || '上传失败');
    return Promise.reject(error);
  } finally {
    uploadLoading.value = false;
  }
};
const titleClick = (item, index) => {
   checked.value = index
   if (index === 2) {
      getFindLicenseDate()
   }
}
  checked.value = index;
};
const getUserInfoData = () => {
   getUserInfo().then(res => {
      const user = res.data.data
      userInfo.value = {
         id: user.id,
         avatar: user.avatar,
         name: user.name,
         realName: user.realName,
         phone: user.phone,
         email: user.email,
         deptName: user.deptName,
      }
   })
}
const emit = defineEmits(['logout'])
  getUserInfo().then(res => {
    const user = res.data.data;
    userInfo.value = {
      id: user.id,
      avatar: user.avatar,
      name: user.name,
      realName: user.realName,
      phone: user.phone,
      email: user.email,
      deptName: user.deptName,
    };
  });
};
const emit = defineEmits(['logout']);
const submit = () => {
   if (checked.value === 0) {
      // if (!validatePhone()) return
      userInfo.value.name = userInfo.value.realName
      updateInfo(userInfo.value).then(res => {
         if (res.data.code === 200) {
            ElMessage.success('修改信息成功!')
            userinforShow.value = false
         } else {
            ElMessage.error(res.msg)
         }
      })
   } else if (checked.value === 1) {
      updatePassword(
         md5(passwordForm.value.oldPassword),
         md5(passwordForm.value.newPassword),
         md5(passwordForm.value.newPassword1)
      ).then(res => {
         if (res.data.code === 200) {
            ElMessage.success('修改密码成功!')
            // 调用父组件方法
            userinforShow.value = false
            emit('logout')
         } else {
            ElMessage.error(res.msg)
         }
      })
   }
}
  if (checked.value === 0) {
   if (!validatePhone() || !validateEmail()) return
    userInfo.value.name = userInfo.value.realName;
    updateInfo(userInfo.value).then(res => {
      if (res.data.code === 200) {
        ElMessage.success('修改信息成功!');
        userinforShow.value = false;
      } else {
        ElMessage.error(res.msg);
      }
    });
  } else if (checked.value === 1) {
    updatePassword(
      md5(passwordForm.value.oldPassword),
      md5(passwordForm.value.newPassword),
      md5(passwordForm.value.newPassword1)
    ).then(res => {
      if (res.data.code === 200) {
        ElMessage.success('修改密码成功!');
        // 调用父组件方法
        userinforShow.value = false;
        emit('logout');
      } else {
        ElMessage.error(res.msg);
      }
    });
  }
};
const reset = () => {
   if (checked.value === 0) {
      getUserInfoData()
      userinforShow.value = false
   } else if (checked.value === 1) {
      passwordForm.value = {
         id: userInfoAs.value.userId,
         oldPassword: '',
         newPassword: '',
         newPassword1: '',
      }
      userinforShow.value = false
   }
}
const isSuccess = ref('')
const passwordTime = ref('')
const handleUpload = file => {
   const formData = new FormData()
   formData.append('file', file)
   uploadLicense(formData)
      .then(res => {
         if (res.data.code !== 200) return ElMessage.error('上传失败')
         ElMessage.success('上传成功')
         isSuccess.value = 'success'
         getFindLicenseDate()
      })
      .catch(err => {
         isSuccess.value = 'error'
         ElMessage.error('上传失败')
      })
}
  if (checked.value === 0) {
    getUserInfoData();
    userinforShow.value = false;
  } else if (checked.value === 1) {
    passwordForm.value = {
      id: userInfoAs.value.userId,
      oldPassword: '',
      newPassword: '',
      newPassword1: '',
    };
    userinforShow.value = false;
  }
};
const isSuccess = ref('');
const passwordTime = ref('');
const getFindLicenseDate = () => {
   findLicenseDate()
      .then(res => {
         if (res.data.code !== 0) return ElMessage.error('获取失败')
         passwordTime.value = res.data.data
      })
      .catch(err => {
         ElMessage.error('获取失败')
      })
}
  findLicenseDate()
    .then(res => {
      if (res.data.code !== 0) return ElMessage.error('获取失败');
      passwordTime.value = res.data.data;
    })
    .catch(err => {
      ElMessage.error('获取失败');
    });
};
// const dialogImageUrl = ref('')
// const dialogVisible = ref(false)
// const handlePictureCardPreview = () => {}
// const handleRemove = () => {}
onMounted(() => {
   getUserInfoData()
})
  getUserInfoData();
});
</script>
<style scoped lang="scss">
.user-info-new {
@@ -298,119 +302,95 @@
  background-color: #ffffff;
}
.titleBoxs {
   margin: 0 24px;
   margin-bottom: 10px;
   // background: url('/src/assets/images/signMachineNest/machineRight/detailtitle.png') no-repeat center;
   // background-size: 100% 100%;
   p {
      display: inline-block;
      margin-left: 30px;
      font-size: 16px;
      color: #000;
      line-height: 20px;
      text-align: left;
      margin-bottom: 8px;
   }
  margin: 0 24px;
  margin-bottom: 10px;
  // background: url('/src/assets/images/signMachineNest/machineRight/detailtitle.png') no-repeat center;
  // background-size: 100% 100%;
  p {
    display: inline-block;
    margin-left: 30px;
    font-size: 16px;
    color: #000;
    line-height: 20px;
    text-align: left;
    margin-bottom: 8px;
  }
}
:deep(.el-form-item__label) {
   color: #000 !important;
  color: #000 !important;
}
:deep(.el-button) {
   width: 150px !important;
  width: 150px !important;
}
.info {
   display: flex;
   justify-content: space-between;
   align-items: center;
   padding: 0 80px 0 50px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 80px 0 50px;
}
.password {
   padding: 0 120px 0 50px;
  padding: 0 120px 0 50px;
}
.butn {
   // position: absolute;
   // bottom: 20px;
   // left: 50%;
   // transform: translate(-50%);
  // position: absolute;
  // bottom: 20px;
  // left: 50%;
  // transform: translate(-50%);
  display: flex;
  justify-content: center;
   cursor: pointer;
   img {
      width: 96px;
      height: 32px;
   }
  cursor: pointer;
  img {
    width: 96px;
    height: 32px;
  }
}
.titleBoxs {
   display: flex;
   padding: 0 20px;
  display: flex;
  padding: 0 20px;
}
.titleItem {
   color: #61809c;
   font-size: 16px;
   margin-right: 50px;
   cursor: pointer;
  color: #61809c;
  font-size: 16px;
  margin-right: 50px;
  cursor: pointer;
}
.activeItem {
   border-radius: 0px 0px 0px 0px;
   color: #51abff;
   border-bottom: 2px solid #198cff;
  border-radius: 0px 0px 0px 0px;
  color: #51abff;
  border-bottom: 2px solid #198cff;
}
.avatar-uploader .el-upload {
   border: 1px dashed #d9d9d9;
   border-radius: 6px;
   cursor: pointer;
   position: relative;
   overflow: hidden;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
   border-color: #409eff;
  border-color: #409eff;
}
.avatar-uploader-icon {
   font-size: 28px;
   color: #8c939d;
   width: 178px;
   height: 178px;
   line-height: 178px;
   text-align: center;
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar {
   width: 178px;
   height: 178px;
   display: block;
  width: 178px;
  height: 178px;
  display: block;
}
.upload-tip {
   margin-top: 10px;
   color: #999;
   font-size: 12px;
   text-align: center;
  margin-top: 10px;
  color: #999;
  font-size: 12px;
  text-align: center;
}
.message,
.passwordBox {
   margin-top: 40px;
  margin-top: 40px;
}
.upload-file {
   text-align: center;
   margin-top: 60px;
   .upload-btn {
      width: 93px;
      height: 38px;
      line-height: 38px;
      background: #1b3e6c;
      border-radius: 8px 8px 8px 8px;
      border: 1px solid #ffffff;
      color: #fff;
      text-align: center;
   }
   .password-time {
      margin-top: 50px;
      width: 100%;
      height: 16px;
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 400;
      font-size: 14px;
      color: #2d9dff;
      line-height: 16px;
      // text-align: left;
   }
}
</style>