upload project source code

This commit is contained in:
2026-04-30 18:49:43 +08:00
commit 9b394ba682
2277 changed files with 660945 additions and 0 deletions

View File

@@ -0,0 +1,753 @@
import { U as ElRow, V as ElCol, T as ElCard, a0 as ElAlert, a1 as ElUpload, h as ElButton, a2 as camera_default, r as ElText, s as ElDivider, a3 as ElDescriptions, a4 as ElDescriptionsItem, i as ElIcon, a5 as ElTabs, a6 as ElTabPane, w as ElForm, x as ElFormItem, y as ElInput, P as ElRadioGroup, E as ElMessage, a as ElNotification, C as ElAvatar, Q as ElRadio } from "./element-plus.CkEW9frc.js";
import { f as useUserStore, j as useDictStore, U as UserAPI, k as useUserStoreHook, r as router } from "./index.CMd5bD1r.js";
import { J as defineComponent, e9 as useI18n, t as onMounted, _ as createElementBlock, $ as createVNode, a0 as withCtx, ak as reactive, S as openBlock, o as unref, a1 as createBaseVNode, T as createBlock, z as isRef, aa as toDisplayString, a9 as createTextVNode, a2 as normalizeStyle, H as Fragment, ay as renderList, r as ref, j as computed, n as nextTick, aO as resolveComponent } from "./.pnpm.BW3P1y8f.js";
import { _ as _export_sfc } from "./_plugin-vue_export-helper.1tPrXgE0.js";
import "./codemirror.CvJAcn2d.js";
const _hoisted_1 = { class: "app-container" };
const _hoisted_2 = { class: "user-info-header" };
const _hoisted_3 = { class: "avatar-alert mb-10px" };
const _hoisted_4 = { class: "avatar-wrapper" };
const _hoisted_5 = { class: "user-name" };
const _hoisted_6 = { class: "cell-item" };
const _hoisted_7 = { class: "cell-item" };
const _hoisted_8 = { class: "cell-item" };
const _hoisted_9 = { class: "cell-item" };
const _hoisted_10 = { class: "cell-item" };
const _hoisted_11 = { class: "cell-item" };
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "profile",
setup(__props) {
const { t } = useI18n();
const userStore = useUserStore();
const dictStore = useDictStore();
const infoFormRef = ref();
const passwordFormRef = ref();
const loading = ref(false);
const dictDataStore = computed(() => dictStore.dictData);
const size = ref("default");
const iconStyle = computed(() => {
const marginMap = {
large: "8px",
default: "6px",
small: "4px"
};
return {
marginRight: marginMap[size.value || "default"]
};
});
const getOptions = async () => {
return await dictStore.getDict(["sys_user_sex"]);
};
const passwordChanging = ref(false);
const infoSubmitting = ref(false);
const infoFormState = reactive({
name: void 0,
gender: 1,
mobile: void 0,
email: void 0,
username: void 0,
dept_name: void 0,
dept: {},
positions: [],
roles: [],
avatar: void 0,
created_time: void 0
});
const passwordFormState = reactive({
old_password: "",
new_password: "",
confirm_password: ""
});
const fileList = ref([]);
const uploadRef = ref();
const handleBeforeUpload = (file) => {
const isImage = file.type.startsWith("image/");
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isImage) {
ElMessage.error("只能上传图片文件");
return false;
}
if (!isLt2M) {
ElMessage.error("上传图片大小不能超过 2MB!");
return false;
}
return true;
};
const handleUpload = async (options) => {
try {
const file = options.file;
const formData = new FormData();
formData.append("file", file);
const response = await UserAPI.uploadCurrentUserAvatar(formData);
if (response.data.code === 0 && response.data.data) {
const fileUrl = response.data.data.file_url;
updateAvatar(fileUrl);
options.onSuccess(response);
if (uploadRef.value) {
uploadRef.value.clearFiles();
}
fileList.value = [];
} else {
const errorMsg = response.data.msg || "上传失败";
ElMessage.error(errorMsg);
options.onError({
...new Error(errorMsg),
status: response.status || 500,
method: "POST",
url: "/system/user/current/avatar/upload"
});
}
} catch (error) {
ElMessage.error("头像上传失败,请重试");
const errorObj = error instanceof Error ? error : new Error(String(error));
options.onError({
...errorObj,
status: 500,
method: "POST",
url: "/system/user/current/avatar/upload"
});
console.error("Upload error:", error);
}
};
const handleFileChange = (file, files) => {
if (file) {
fileList.value = [...files];
if (uploadRef.value) {
uploadRef.value.submit();
}
}
};
const updateAvatar = (fileUrl) => {
if (fileUrl) {
infoFormState.avatar = fileUrl;
nextTick(() => {
console.log("头像已更新:", infoFormState.avatar);
});
} else {
ElMessage.error("无效的头像URL");
console.error("Invalid fileUrl:", fileUrl);
}
};
const rules = {
name: [{ required: true, message: "请输入用户名", trigger: "blur" }],
mobile: [
{
pattern: /^1[3-9]\d{9}$/,
message: "请输入有效的手机号格式",
trigger: "blur"
}
],
email: [
{
pattern: /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/,
message: "请输入有效的邮箱格式",
trigger: "blur"
}
]
};
const resetPasswordRules = {
old_password: [
{
required: true,
trigger: "blur",
message: t("login.password")
}
],
new_password: [
{
required: true,
trigger: "blur",
message: t("login.message.password.required")
},
{
min: 6,
message: t("login.message.password.min"),
trigger: "blur"
}
],
confirm_password: [
{
required: true,
trigger: "blur",
message: t("login.message.password.required")
},
{
min: 6,
message: t("login.message.password.min"),
trigger: "blur"
},
{
validator: (_, value) => {
return value === passwordFormState.new_password;
},
trigger: "blur",
message: t("login.message.password.inconformity")
}
]
};
const initInfoForm = () => {
const basicInfo = userStore.basicInfo;
Object.assign(infoFormState, { ...basicInfo });
};
const initPasswordForm = () => {
Object.assign(passwordFormState, {
old_password: "",
new_password: "",
confirm_password: ""
});
};
const handleSave = async () => {
var _a;
try {
infoSubmitting.value = true;
const valid = await ((_a = infoFormRef.value) == null ? void 0 : _a.validate().catch(() => false));
if (!valid) {
return;
}
const response = await UserAPI.updateCurrentUserInfo({ ...infoFormState });
await userStore.setUserInfo(response.data.data);
ElMessage.success("个人资料已保存");
} finally {
infoSubmitting.value = false;
}
};
const handlePasswordChange = async () => {
var _a;
try {
passwordChanging.value = true;
const valid = await ((_a = passwordFormRef.value) == null ? void 0 : _a.validate().catch(() => false));
if (!valid) {
return;
}
const response = await UserAPI.changeCurrentUserPassword(passwordFormState);
initPasswordForm();
await redirectToLogin(response.data.msg);
} catch (error) {
console.error(error);
} finally {
passwordChanging.value = false;
}
};
async function redirectToLogin(message = "请重新登录") {
try {
ElNotification({
title: "提示",
message,
type: "warning",
duration: 3e3
});
await useUserStoreHook().resetAllState();
const currentPath = router.currentRoute.value.fullPath;
await router.push(`/login?redirect=${encodeURIComponent(currentPath)}`);
} catch (error) {
console.error(error);
}
}
onMounted(async () => {
await getOptions();
initInfoForm();
});
return (_ctx, _cache) => {
const _component_el_alert = ElAlert;
const _component_el_avatar = ElAvatar;
const _component_el_button = ElButton;
const _component_el_upload = ElUpload;
const _component_el_text = ElText;
const _component_el_divider = ElDivider;
const _component_User = resolveComponent("User");
const _component_el_icon = ElIcon;
const _component_el_descriptions_item = ElDescriptionsItem;
const _component_Coordinate = resolveComponent("Coordinate");
const _component_OfficeBuilding = resolveComponent("OfficeBuilding");
const _component_Phone = resolveComponent("Phone");
const _component_Message = resolveComponent("Message");
const _component_Clock = resolveComponent("Clock");
const _component_el_descriptions = ElDescriptions;
const _component_el_card = ElCard;
const _component_el_col = ElCol;
const _component_el_input = ElInput;
const _component_el_form_item = ElFormItem;
const _component_el_radio = ElRadio;
const _component_el_radio_group = ElRadioGroup;
const _component_el_form = ElForm;
const _component_el_tab_pane = ElTabPane;
const _component_Lock = resolveComponent("Lock");
const _component_Key = resolveComponent("Key");
const _component_Check = resolveComponent("Check");
const _component_el_tabs = ElTabs;
const _component_el_row = ElRow;
return openBlock(), createElementBlock("div", _hoisted_1, [
createVNode(_component_el_row, { gutter: 12 }, {
default: withCtx(() => [
createVNode(_component_el_col, {
span: 6,
class: "mb-4"
}, {
default: withCtx(() => [
createVNode(_component_el_card, {
loading: unref(loading),
shadow: "hover"
}, {
header: withCtx(() => [..._cache[8] || (_cache[8] = [
createBaseVNode("div", { class: "card-header" }, [
createBaseVNode("span", null, "基本信息")
], -1)
])]),
default: withCtx(() => [
createBaseVNode("div", _hoisted_2, [
createBaseVNode("div", _hoisted_3, [
createVNode(_component_el_alert, {
type: "info",
"show-icon": "",
closable: false,
title: "头像上传,点击“保存更改”按钮使其生效"
})
]),
createBaseVNode("div", _hoisted_4, [
unref(infoFormState).avatar ? (openBlock(), createBlock(_component_el_avatar, {
key: 0,
src: unref(infoFormState).avatar,
size: 120
}, null, 8, ["src"])) : (openBlock(), createBlock(_component_el_avatar, {
key: 1,
icon: "UserFilled",
size: 120
})),
createVNode(_component_el_upload, {
ref_key: "uploadRef",
ref: uploadRef,
"file-list": unref(fileList),
"onUpdate:fileList": _cache[0] || (_cache[0] = ($event) => isRef(fileList) ? fileList.value = $event : null),
class: "el-upload",
name: "file",
"show-file-list": false,
"before-upload": handleBeforeUpload,
"http-request": handleUpload,
disabled: unref(loading),
limit: 1,
"auto-upload": false,
onChange: handleFileChange
}, {
trigger: withCtx(() => [
createVNode(_component_el_button, {
type: "primary",
icon: unref(camera_default),
class: "upload-trigger"
}, null, 8, ["icon"])
]),
_: 1
}, 8, ["file-list", "disabled"])
]),
createBaseVNode("span", _hoisted_5, toDisplayString(unref(infoFormState).name), 1),
createVNode(_component_el_text, null, {
default: withCtx(() => {
var _a;
return [
createTextVNode(toDisplayString((_a = unref(infoFormState).roles) == null ? void 0 : _a.map((item) => item.name).join("、")), 1)
];
}),
_: 1
})
]),
createVNode(_component_el_divider),
createVNode(_component_el_descriptions, {
column: 1,
border: ""
}, {
default: withCtx(() => [
createVNode(_component_el_descriptions_item, null, {
label: withCtx(() => [
createBaseVNode("div", _hoisted_6, [
createVNode(_component_el_icon, {
style: normalizeStyle(unref(iconStyle))
}, {
default: withCtx(() => [
createVNode(_component_User)
]),
_: 1
}, 8, ["style"]),
_cache[9] || (_cache[9] = createBaseVNode("span", null, "账号", -1))
])
]),
default: withCtx(() => [
createBaseVNode("span", null, toDisplayString(unref(infoFormState).username), 1)
]),
_: 1
}),
createVNode(_component_el_descriptions_item, null, {
label: withCtx(() => [
createBaseVNode("div", _hoisted_7, [
createVNode(_component_el_icon, {
style: normalizeStyle(unref(iconStyle))
}, {
default: withCtx(() => [
createVNode(_component_Coordinate)
]),
_: 1
}, 8, ["style"]),
_cache[10] || (_cache[10] = createBaseVNode("span", null, "部门", -1))
])
]),
default: withCtx(() => {
var _a;
return [
createBaseVNode("span", null, toDisplayString((_a = unref(infoFormState).dept) == null ? void 0 : _a.name), 1)
];
}),
_: 1
}),
createVNode(_component_el_descriptions_item, null, {
label: withCtx(() => [
createBaseVNode("div", _hoisted_8, [
createVNode(_component_el_icon, {
style: normalizeStyle(unref(iconStyle))
}, {
default: withCtx(() => [
createVNode(_component_OfficeBuilding)
]),
_: 1
}, 8, ["style"]),
_cache[11] || (_cache[11] = createBaseVNode("span", null, "岗位", -1))
])
]),
default: withCtx(() => {
var _a;
return [
createBaseVNode("span", null, toDisplayString((_a = unref(infoFormState).positions) == null ? void 0 : _a.map((item) => item.name).join("、")), 1)
];
}),
_: 1
}),
createVNode(_component_el_descriptions_item, null, {
label: withCtx(() => [
createBaseVNode("div", _hoisted_9, [
createVNode(_component_el_icon, {
style: normalizeStyle(unref(iconStyle))
}, {
default: withCtx(() => [
createVNode(_component_Phone)
]),
_: 1
}, 8, ["style"]),
_cache[12] || (_cache[12] = createBaseVNode("span", null, "手机", -1))
])
]),
default: withCtx(() => [
createBaseVNode("span", null, toDisplayString(unref(infoFormState).mobile), 1)
]),
_: 1
}),
createVNode(_component_el_descriptions_item, null, {
label: withCtx(() => [
createBaseVNode("div", _hoisted_10, [
createVNode(_component_el_icon, {
style: normalizeStyle(unref(iconStyle))
}, {
default: withCtx(() => [
createVNode(_component_Message)
]),
_: 1
}, 8, ["style"]),
_cache[13] || (_cache[13] = createBaseVNode("span", null, "邮箱", -1))
])
]),
default: withCtx(() => [
createBaseVNode("span", null, toDisplayString(unref(infoFormState).email), 1)
]),
_: 1
}),
createVNode(_component_el_descriptions_item, null, {
label: withCtx(() => [
createBaseVNode("div", _hoisted_11, [
createVNode(_component_el_icon, {
style: normalizeStyle(unref(iconStyle))
}, {
default: withCtx(() => [
createVNode(_component_Clock)
]),
_: 1
}, 8, ["style"]),
_cache[14] || (_cache[14] = createBaseVNode("span", null, "加入时间", -1))
])
]),
default: withCtx(() => [
createBaseVNode("span", null, toDisplayString(unref(infoFormState).created_time), 1)
]),
_: 1
})
]),
_: 1
})
]),
_: 1
}, 8, ["loading"])
]),
_: 1
}),
createVNode(_component_el_col, {
span: 18,
class: "mb-4"
}, {
default: withCtx(() => [
createVNode(_component_el_card, {
loading: unref(loading),
shadow: "hover"
}, {
default: withCtx(() => [
createVNode(_component_el_tabs, { type: "border-card" }, {
default: withCtx(() => [
createVNode(_component_el_tab_pane, null, {
label: withCtx(() => [
createVNode(_component_el_icon, null, {
default: withCtx(() => [
createVNode(_component_User)
]),
_: 1
}),
_cache[15] || (_cache[15] = createBaseVNode("span", null, "基本设置", -1))
]),
default: withCtx(() => [
createBaseVNode("div", null, [
createVNode(_component_el_form, {
ref_key: "infoFormRef",
ref: infoFormRef,
model: unref(infoFormState),
rules,
"label-width": "80px",
"label-suffix": ":"
}, {
default: withCtx(() => [
createVNode(_component_el_form_item, {
label: "用户名",
prop: "name"
}, {
default: withCtx(() => [
createVNode(_component_el_input, {
modelValue: unref(infoFormState).name,
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => unref(infoFormState).name = $event),
placeholder: "请输入用户名",
"prefix-icon": "User",
clearable: "",
style: { "width": "240px" }
}, null, 8, ["modelValue"])
]),
_: 1
}),
createVNode(_component_el_form_item, {
label: "手机号",
prop: "mobile"
}, {
default: withCtx(() => [
createVNode(_component_el_input, {
modelValue: unref(infoFormState).mobile,
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => unref(infoFormState).mobile = $event),
placeholder: "请输入手机号码",
"prefix-icon": "Phone",
clearable: "",
style: { "width": "240px" }
}, null, 8, ["modelValue"])
]),
_: 1
}),
createVNode(_component_el_form_item, {
label: "邮箱",
prop: "email"
}, {
default: withCtx(() => [
createVNode(_component_el_input, {
modelValue: unref(infoFormState).email,
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => unref(infoFormState).email = $event),
placeholder: "请输入邮箱",
"prefix-icon": "Message",
clearable: "",
style: { "width": "240px" }
}, null, 8, ["modelValue"])
]),
_: 1
}),
createVNode(_component_el_form_item, {
label: "性别",
prop: "gender"
}, {
default: withCtx(() => [
createVNode(_component_el_radio_group, {
modelValue: unref(infoFormState).gender,
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => unref(infoFormState).gender = $event)
}, {
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(dictDataStore)["sys_user_sex"], (item) => {
return openBlock(), createBlock(_component_el_radio, {
key: item.dict_value,
value: item.dict_value
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(item.dict_label), 1)
]),
_: 2
}, 1032, ["value"]);
}), 128))
]),
_: 1
}, 8, ["modelValue"])
]),
_: 1
}),
createVNode(_component_el_form_item, null, {
default: withCtx(() => [
createVNode(_component_el_button, {
type: "primary",
loading: unref(infoSubmitting),
icon: "edit",
onClick: handleSave
}, {
default: withCtx(() => [..._cache[16] || (_cache[16] = [
createTextVNode(" 保存更改 ", -1)
])]),
_: 1
}, 8, ["loading"])
]),
_: 1
})
]),
_: 1
}, 8, ["model"])
])
]),
_: 1
}),
createVNode(_component_el_tab_pane, null, {
label: withCtx(() => [
createVNode(_component_el_icon, null, {
default: withCtx(() => [
createVNode(_component_Lock)
]),
_: 1
}),
_cache[17] || (_cache[17] = createBaseVNode("span", null, "安全设置", -1))
]),
default: withCtx(() => [
createBaseVNode("div", null, [
createVNode(_component_el_form, {
ref_key: "passwordFormRef",
ref: passwordFormRef,
model: unref(passwordFormState),
rules: resetPasswordRules,
"label-width": "120px",
"label-suffix": ":"
}, {
default: withCtx(() => [
createVNode(_component_el_form_item, {
label: "当前密码",
prop: "old_password"
}, {
default: withCtx(() => [
createVNode(_component_el_input, {
modelValue: unref(passwordFormState).old_password,
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => unref(passwordFormState).old_password = $event),
modelModifiers: { trim: true },
placeholder: unref(t)("login.password"),
type: "password",
"prefix-icon": "Unlock",
"show-password": "",
clearable: "",
style: { "width": "240px" }
}, {
prefix: withCtx(() => [
createVNode(_component_Lock)
]),
_: 1
}, 8, ["modelValue", "placeholder"])
]),
_: 1
}),
createVNode(_component_el_form_item, {
label: "新密码",
prop: "new_password"
}, {
default: withCtx(() => [
createVNode(_component_el_input, {
modelValue: unref(passwordFormState).new_password,
"onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => unref(passwordFormState).new_password = $event),
modelModifiers: { trim: true },
type: "password",
placeholder: unref(t)("login.newPassword"),
"prefix-icon": "Unlock",
"show-password": "",
clearable: "",
style: { "width": "240px" }
}, {
prefix: withCtx(() => [
createVNode(_component_Key)
]),
_: 1
}, 8, ["modelValue", "placeholder"])
]),
_: 1
}),
createVNode(_component_el_form_item, {
label: "确认新密码",
prop: "confirm_password"
}, {
default: withCtx(() => [
createVNode(_component_el_input, {
modelValue: unref(passwordFormState).confirm_password,
"onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => unref(passwordFormState).confirm_password = $event),
modelModifiers: { trim: true },
type: "password",
placeholder: unref(t)("login.message.password.confirm"),
"prefix-icon": "Lock",
"show-password": "",
clearable: "",
style: { "width": "240px" }
}, {
prefix: withCtx(() => [
createVNode(_component_Check)
]),
_: 1
}, 8, ["modelValue", "placeholder"])
]),
_: 1
}),
createVNode(_component_el_form_item, null, {
default: withCtx(() => [
createVNode(_component_el_button, {
type: "primary",
loading: unref(passwordChanging),
icon: "edit",
onClick: handlePasswordChange
}, {
default: withCtx(() => [..._cache[18] || (_cache[18] = [
createTextVNode(" 更新密码 ", -1)
])]),
_: 1
}, 8, ["loading"])
]),
_: 1
})
]),
_: 1
}, 8, ["model"])
])
]),
_: 1
})
]),
_: 1
})
]),
_: 1
}, 8, ["loading"])
]),
_: 1
})
]),
_: 1
})
]);
};
}
});
const profile = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-05cb52ed"]]);
export {
profile as default
};