115 lines
3.6 KiB
Vue
115 lines
3.6 KiB
Vue
<script setup>
|
|
import { onMounted, ref, watch, inject } from "vue";
|
|
import { Login } from "@/apis/login";
|
|
import Image from "@/assets/img/logo.svg";
|
|
import * as yup from "yup";
|
|
import useFormErrorMessage from "@/hooks/useFormErrorMessage";
|
|
import { useRouter } from "vue-router";
|
|
import useUserInfoStore from "@/stores/useUserInfoStore";
|
|
import useBuildingStore from "@/stores/useBuildingStore";
|
|
import { useI18n } from "vue-i18n";
|
|
const { t } = useI18n();
|
|
const { openToast } = inject("app_toast");
|
|
const store = useUserInfoStore();
|
|
const storeBuild = useBuildingStore();
|
|
const router = useRouter();
|
|
|
|
let schema = yup.object({
|
|
account: yup.string().required("必填"),
|
|
password: yup.string().required("必填"),
|
|
});
|
|
const { formErrorMsg, handleSubmit, handleErrorReset } =
|
|
useFormErrorMessage(schema);
|
|
|
|
const formState = ref({
|
|
account: "",
|
|
password: "",
|
|
});
|
|
const showPassword = ref(false);
|
|
const togglePasswordVisibility = () => {
|
|
showPassword.value = !showPassword.value;
|
|
};
|
|
|
|
const imageSrc = import.meta.env.MODE === "production" ? "./logo.svg" : Image;
|
|
|
|
const doLogin = async () => {
|
|
const value = await handleSubmit(schema, formState.value);
|
|
const res = await Login(value);
|
|
if (res.isSuccess) {
|
|
store.user = res.data;
|
|
localStorage.setItem(
|
|
"CviBuildingList",
|
|
JSON.stringify(res.data.building_infos)
|
|
);
|
|
if (res.data.building_infos.map((b) => b.is_headquarter).includes(true)) {
|
|
router.replace({ path: "/headquarters" });
|
|
} else {
|
|
router.replace({ path: "/dashboard" });
|
|
}
|
|
} else {
|
|
openToast("error", res.msg);
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="absolute top-10 left-1/2 -translate-x-1/2 z-20 border-4 rounded-3xl p-5 bg-white bg-opacity-60"
|
|
>
|
|
<div class="flex flex-col items-start w-96">
|
|
<div
|
|
class="flex items-center justify-center w-full mb-5 text-4xl font-bold text-red-600"
|
|
>
|
|
<img :src="imageSrc" alt="logo" class="w-12 me-2" />
|
|
CviLux Group
|
|
</div>
|
|
<div class="w-full flex flex-col items-end my-2">
|
|
<div class="w-full flex justify-between">
|
|
<label class="mr-2 text-2xl text-black" for="account">{{
|
|
$t("account")
|
|
}}</label>
|
|
<input
|
|
name="account"
|
|
class="w-5/6 border-2 rounded-full bg-white text-black px-4 py-1"
|
|
v-model="formState.account"
|
|
autocomplete="none"
|
|
/>
|
|
</div>
|
|
<span class="text-error text-base">
|
|
{{ formErrorMsg.account }}
|
|
</span>
|
|
</div>
|
|
<div class="w-full flex flex-col items-end my-2">
|
|
<div class="w-full flex justify-between relative">
|
|
<label class="mr-2 text-2xl text-black" for="password">{{
|
|
$t("password")
|
|
}}</label>
|
|
<input
|
|
name="password"
|
|
class="w-5/6 border-2 rounded-full bg-white text-black px-4 py-1"
|
|
:type="showPassword ? 'text' : 'password'"
|
|
v-model="formState.password"
|
|
autocomplete="off"
|
|
/>
|
|
<FontAwesomeIcon
|
|
:icon="['fas', showPassword ? 'eye-slash' : 'eye']"
|
|
class="text-gray-400 text-2xl absolute top-1/2 right-4 transform -translate-y-1/2 cursor-pointer"
|
|
@click="togglePasswordVisibility"
|
|
/>
|
|
</div>
|
|
<span class="text-error text-base">
|
|
{{ formErrorMsg.password }}
|
|
</span>
|
|
</div>
|
|
<button
|
|
class="mt-3 px-6 py-2 bg-red-800 text-white rounded-full self-end hover:bg-red-900"
|
|
@click.stop.prevent="doLogin"
|
|
>
|
|
{{ $t("log_in") }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped></style>
|