123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519 |
- <template>
- <div class="login-container">
- <el-card class="form-container">
- <el-scrollbar class="scrollbar">
- <div class="login-title">
- <h2>{{ defaultSettings.title }}</h2>
- <div @click="showJobNumber = !showJobNumber">
- {{ showJobNumber ? "账号密码登录" : "扫码登录" }}
- </div>
- </div>
- <el-form
- ref="loginFormRef"
- :model="loginData"
- :rules="loginRules"
- class="login-form"
- size="default"
- >
- <el-form-item v-if="showJobNumber" prop="jobNumber">
- <div class="flex-y-center w-full">
- <svg-icon class="mx-2" icon-class="document" />
- <el-input
- ref="username"
- v-model="loginData.jobNumber"
- class="h-[48px]"
- name="jobNumber"
- placeholder="请扫码或输入工号"
- size="large"
- />
- </div>
- </el-form-item>
- <div v-else>
- <el-form-item prop="userName">
- <div class="flex-y-center w-full">
- <svg-icon class="mx-2" icon-class="user" />
- <el-input
- ref="username"
- v-model="loginData.userName"
- class="h-[48px]"
- name="userName"
- placeholder="请输入用户名"
- size="large"
- />
- </div>
- </el-form-item>
- <el-tooltip
- :content="$t('login.capsLock')"
- :visible="isCapslock"
- placement="right"
- >
- <el-form-item prop="password">
- <div class="flex-y-center w-full">
- <svg-icon class="mx-2" icon-class="lock" />
- <el-input
- v-model="loginData.password"
- :placeholder="$t('login.password')"
- class="h-[48px] pr-2"
- name="password"
- show-password
- size="large"
- type="password"
- @keyup="checkCapslock"
- />
- </div>
- </el-form-item>
- </el-tooltip>
- </div>
- <el-form-item prop="orgId">
- <div class="flex-y-center w-full">
- <svg-icon class="mx-2" icon-class="captcha" />
- <el-select
- v-model="loginData.orgId"
- class="no-border"
- placeholder="请选择组织"
- size="large"
- >
- <el-option
- v-for="item in orgList"
- :key="item.id"
- :label="item.deptName"
- :value="item.id"
- />
- </el-select>
- </div>
- </el-form-item>
- <el-form-item prop="proCode">
- <div class="flex-y-center w-full">
- <svg-icon class="mx-2" icon-class="cascader" />
- <el-select
- v-model="loginData.proCode"
- class="no-border"
- placeholder="请选择产线"
- size="large"
- >
- <el-option
- v-for="item in productionList"
- :key="item.code"
- :label="item.name"
- :value="item.code"
- />
- </el-select>
- </div>
- </el-form-item>
- <el-form-item prop="stationId">
- <div class="flex-y-center w-full">
- <svg-icon class="mx-2" icon-class="client" />
- <el-select
- v-model="loginData.stationId"
- class="no-border"
- placeholder="请选择工位"
- size="large"
- @change="onStationChange"
- >
- <el-option
- v-for="item in stationList"
- :key="item.id"
- :label="item.name"
- :value="item.id"
- />
- </el-select>
- </div>
- </el-form-item>
- <el-button
- :loading="loading"
- class="login-btn"
- size="large"
- type="primary"
- @click.prevent="handleLogin"
- >{{ $t("login.login") }}
- </el-button>
- </el-form>
- </el-scrollbar>
- </el-card>
- <!-- ICP备案 -->
- <div v-show="icpVisible" class="absolute bottom-1 text-[10px] text-center">
- <p>Copyright © 2022-2025 jgai.com All Rights Reserved.</p>
- </div>
- <div>
- <svg-icon
- class="activeNotice"
- style="right: 20px; top: 20px; position: absolute"
- icon-class="shutdown"
- size="40"
- @click="toExitApp"
- />
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { useSettingsStore, useUserStore } from "@/store";
- import {
- getCaptchaApi,
- getOrgListApi,
- getProductionList,
- stationListByCode,
- } from "@/api/auth";
- import { LoginData } from "@/api/auth/types";
- import { useRoute } from "vue-router";
- import defaultSettings from "@/settings";
- import { ThemeEnum } from "@/enums/ThemeEnum";
- import { watch } from "vue";
- // Stores
- const userStore = useUserStore();
- const settingsStore = useSettingsStore();
- // Internationalization
- const { t } = useI18n();
- // Reactive states
- const isDark = ref(settingsStore.theme === ThemeEnum.DARK);
- const icpVisible = ref(true);
- const showJobNumber = ref(false);
- const orgList = ref<any>([]);
- const productionList = ref<any>([]);
- const stationList = ref<any>([]);
- const loading = ref(false); // 按钮loading
- const isCapslock = ref(false); // 是否大写锁定
- const captchaBase64 = ref(); // 验证码图片Base64字符串
- const loginFormRef = ref(ElForm); // 登录表单ref
- const { height } = useWindowSize();
- const loginData = ref<LoginData>({
- userName: "",
- password: "",
- });
- const toExitApp = () => {
- if (window.openHarmonyBridge && window.openHarmonyBridge.exitApp) {
- window.openHarmonyBridge.exitApp("");
- }
- };
- const loginRules = computed?.(() => {
- return {
- userName: [
- {
- required: true,
- trigger: "blur",
- message: t("login.message.username.required"),
- },
- ],
- password: [
- {
- required: true,
- trigger: "blur",
- message: t("login.message.password.required"),
- },
- {
- min: 6,
- message: t("login.message.password.min"),
- trigger: "blur",
- },
- ],
- orgId: [
- {
- required: true,
- trigger: "blur",
- message: t("login.message.orgId.required"),
- },
- ],
- proCode: [
- {
- required: true,
- trigger: "blur",
- message: "请选择产线",
- },
- ],
- stationId: [
- {
- required: true,
- trigger: "blur",
- message: "请选择工位",
- },
- ],
- jobNumber: [
- {
- required: true,
- trigger: "blur",
- message: "请输入工号",
- },
- ],
- };
- });
- let stationType = ""; //工位类型
- let stationName = ""; //工位名称
- const onStationChange = (val: any) => {
- const stationArray = stationList.value.filter((item: any) => {
- return item.id === val;
- });
- stationType = stationArray[0].stationDictValue;
- stationName = stationArray[0].name;
- loginData.value.stationType = stationArray[0].stationDictValue;
- };
- /**
- * 获取验证码
- */
- function getCaptcha() {
- getCaptchaApi().then(({ data }) => {
- loginData.value.captchaKey = data.captchaKey;
- captchaBase64.value = data.captchaBase64;
- });
- }
- function getOrgList() {
- getOrgListApi().then((data: any) => {
- orgList.value = data.data;
- if (orgList.value) {
- loginData.value.orgId = orgList.value[0].id;
- }
- });
- }
- /**
- * 登录
- */
- const route = useRoute();
- const router = useRouter();
- function handleLogin() {
- loginFormRef.value.validate((valid: boolean) => {
- if (valid) {
- //保存用户名和密码
- localStorage.setItem("local_name", loginData.value.userName);
- loading.value = true;
- let numberP = {
- proCode: loginData.value.proCode,
- orgId: loginData.value.orgId,
- jobNumber: loginData.value.jobNumber,
- stationId: loginData.value.stationId,
- stationType: loginData.value.stationType,
- };
- let acountP = {
- userName: loginData.value.userName,
- password: loginData.value.password,
- proCode: loginData.value.proCode,
- orgId: loginData.value.orgId,
- stationId: loginData.value.stationId,
- stationType: loginData.value.stationType,
- };
- localStorage.setItem("local_stationId", loginData.value.stationId);
- userStore
- .login(showJobNumber.value ? numberP : acountP)
- .then(() => {
- userStore.user.station = stationName;
- userStore.user.proCode = loginData.value.proCode;
- // 捡选 装配 测试 维修站 预齐套
- // if (stationType == "5") {
- // router.replace({ name: "PrepareMain" });
- // } else {
- router.replace({ name: "ProcessMain" });
- // }
- })
- .catch(() => {
- // getCaptcha();
- console.log("catch");
- })
- .finally(() => {
- loading.value = false;
- });
- }
- });
- }
- /**
- * 主题切换
- */
- const toggleTheme = () => {
- //const newTheme = settingsStore.theme === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
- //settingsStore.changeTheme(newTheme);
- };
- /**
- * 根据屏幕宽度切换设备模式
- */
- watchEffect?.(() => {
- if (height.value < 600) {
- icpVisible.value = false;
- } else {
- icpVisible.value = true;
- }
- });
- watch(
- () => loginData.value.proCode,
- (newValue) => {
- if (newValue) {
- stationListByCode(newValue, 0).then((data: any) => {
- stationList.value = data.data;
- if (stationList.value && stationList.value.length > 0) {
- // 根据保存的工位id,获得工位信息
- let index = 0;
- for (let i = 0; i < stationList.value.length; i++) {
- if (
- localStorage.getItem("local_stationId") ===
- stationList.value[i].id
- ) {
- index = i;
- break;
- }
- }
- let station = stationList.value[index];
- loginData.value.stationId = station.id;
- stationType = station.stationDictValue;
- stationName = station.name;
- loginData.value.stationType = station.stationDictValue;
- }
- });
- }
- }
- );
- /**
- * 检查输入大小写
- */
- function checkCapslock(e: any) {
- isCapslock.value = e.getModifierState("CapsLock");
- }
- onMounted?.(() => {
- getOrgList();
- toggleTheme();
- getProductionList().then((data: any) => {
- productionList.value = data.data;
- if (productionList.value) {
- loginData.value.proCode = productionList.value[0].code;
- }
- });
- if (
- localStorage.getItem("local_name") &&
- localStorage.getItem("local_name") !== "null"
- ) {
- loginData.value.userName = localStorage.getItem("local_name");
- }
- });
- </script>
- <style lang="scss" scoped>
- .login-container {
- overflow-y: auto;
- background: url("@/assets/images/login-bg.png");
- background-position: center;
- background-size: cover;
- position: relative;
- @apply wh-full flex-center;
- .login-form {
- padding: 30px 10px;
- }
- .login-title {
- color: white;
- margin-left: 10px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .form-container {
- background: #a0a8b2;
- border-radius: 16px;
- width: 500px;
- position: absolute;
- right: 10%;
- }
- .login-btn {
- width: 100%;
- height: 50px;
- border-radius: 25px;
- margin-top: 15px;
- }
- }
- .el-form-item {
- background: var(--el-input-bg-color);
- border: 1px solid var(--el-border-color);
- border-radius: 5px;
- }
- :deep(.el-input) {
- .el-input__wrapper {
- padding: 0;
- background-color: transparent;
- box-shadow: none;
- &.is-focus,
- &:hover {
- box-shadow: none !important;
- }
- input:-webkit-autofill {
- /* 通过延时渲染背景色变相去除背景颜色 */
- transition: background-color 1000s ease-in-out 0s;
- }
- }
- }
- :deep(.el-select__placeholder) {
- color: rgba(0, 0, 0, 0.9);
- }
- :deep(.el-select__placeholder.is-transparent) {
- color: rgba(0, 0, 0, 0.3);
- }
- :deep(.el-input__inner::placeholder) {
- color: rgba(0, 0, 0, 0.3);
- }
- :deep(.el-input__inner) {
- color: rgba(0, 0, 0, 0.9);
- }
- :deep(.el-select) {
- .el-select__wrapper {
- padding: 0;
- background-color: transparent;
- box-shadow: none;
- &.is-focus,
- &:hover {
- box-shadow: none !important;
- }
- input:-webkit-autofill {
- /* 通过延时渲染背景色变相去除背景颜色 */
- transition: background-color 1000s ease-in-out 0s;
- }
- }
- }
- @media (max-height: 540px) {
- /* 在页面高度低于500px时应用的样式 */
- .form-container {
- height: 100vh;
- }
- .scrollbar {
- height: 100vh;
- }
- }
- </style>
|