| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- <script setup lang="ts">
- import { reactive, ref } from "vue";
- import { formUpload } from "@/api/mock";
- import { message } from "@/utils/message";
- import { type UserInfo, getMine } from "@/api/user";
- import type { FormInstance, FormRules } from "element-plus";
- import ReCropperPreview from "@/components/ReCropperPreview";
- import { createFormData, deviceDetection } from "@pureadmin/utils";
- import uploadLine from "~icons/ri/upload-line";
- defineOptions({
- name: "Profile"
- });
- const imgSrc = ref("");
- const cropperBlob = ref();
- const cropRef = ref();
- const uploadRef = ref();
- const isShow = ref(false);
- const userInfoFormRef = ref<FormInstance>();
- const userInfos = reactive({
- avatar: "",
- nickname: "",
- email: "",
- phone: "",
- description: ""
- });
- const rules = reactive<FormRules<UserInfo>>({
- nickname: [{ required: true, message: "昵称必填", trigger: "blur" }]
- });
- function queryEmail(queryString, callback) {
- const emailList = [
- { value: "@qq.com" },
- { value: "@126.com" },
- { value: "@163.com" }
- ];
- let results = [];
- let queryList = [];
- emailList.map(item =>
- queryList.push({ value: queryString.split("@")[0] + item.value })
- );
- results = queryString
- ? queryList.filter(
- item =>
- item.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
- )
- : queryList;
- callback(results);
- }
- const onChange = uploadFile => {
- const reader = new FileReader();
- reader.onload = e => {
- imgSrc.value = e.target.result as string;
- isShow.value = true;
- };
- reader.readAsDataURL(uploadFile.raw);
- };
- const handleClose = () => {
- cropRef.value.hidePopover();
- uploadRef.value.clearFiles();
- isShow.value = false;
- };
- const onCropper = ({ blob }) => (cropperBlob.value = blob);
- const handleSubmitImage = () => {
- const formData = createFormData({
- files: new File([cropperBlob.value], "avatar")
- });
- formUpload(formData)
- .then(({ success, data }) => {
- if (success) {
- message("更新头像成功", { type: "success" });
- handleClose();
- } else {
- message("更新头像失败");
- }
- })
- .catch(error => {
- message(`提交异常 ${error}`, { type: "error" });
- });
- };
- // 更新信息
- const onSubmit = async (formEl: FormInstance) => {
- await formEl.validate((valid, fields) => {
- if (valid) {
- console.log(userInfos);
- message("更新信息成功", { type: "success" });
- } else {
- console.log("error submit!", fields);
- }
- });
- };
- getMine().then(res => {
- Object.assign(userInfos, res.data);
- });
- </script>
- <template>
- <div
- :class="[
- 'min-w-[180px]',
- deviceDetection() ? 'max-w-[100%]' : 'max-w-[70%]'
- ]"
- >
- <h3 class="my-8!">个人信息</h3>
- <el-form
- ref="userInfoFormRef"
- label-position="top"
- :rules="rules"
- :model="userInfos"
- >
- <el-form-item label="头像">
- <el-avatar :size="80" :src="userInfos.avatar" />
- <el-upload
- ref="uploadRef"
- accept="image/*"
- action="#"
- :limit="1"
- :auto-upload="false"
- :show-file-list="false"
- :on-change="onChange"
- >
- <el-button plain class="ml-4!">
- <IconifyIconOffline :icon="uploadLine" />
- <span class="ml-2">更新头像</span>
- </el-button>
- </el-upload>
- </el-form-item>
- <el-form-item label="昵称" prop="nickname">
- <el-input v-model="userInfos.nickname" placeholder="请输入昵称" />
- </el-form-item>
- <el-form-item label="邮箱" prop="email">
- <el-autocomplete
- v-model="userInfos.email"
- :fetch-suggestions="queryEmail"
- :trigger-on-focus="false"
- placeholder="请输入邮箱"
- clearable
- class="w-full"
- />
- </el-form-item>
- <el-form-item label="联系电话">
- <el-input
- v-model="userInfos.phone"
- placeholder="请输入联系电话"
- clearable
- />
- </el-form-item>
- <el-form-item label="简介">
- <el-input
- v-model="userInfos.description"
- placeholder="请输入简介"
- type="textarea"
- :autosize="{ minRows: 6, maxRows: 8 }"
- maxlength="56"
- show-word-limit
- />
- </el-form-item>
- <el-button type="primary" @click="onSubmit(userInfoFormRef)">
- 更新信息
- </el-button>
- </el-form>
- <el-dialog
- v-model="isShow"
- width="40%"
- title="编辑头像"
- destroy-on-close
- :closeOnClickModal="false"
- :before-close="handleClose"
- :fullscreen="deviceDetection()"
- >
- <ReCropperPreview ref="cropRef" :imgSrc="imgSrc" @cropper="onCropper" />
- <template #footer>
- <div class="dialog-footer">
- <el-button bg text @click="handleClose">取消</el-button>
- <el-button bg text type="primary" @click="handleSubmitImage">
- 确定
- </el-button>
- </div>
- </template>
- </el-dialog>
- </div>
- </template>
|