|
@@ -1,24 +1,11 @@
|
|
|
<template>
|
|
|
<div class="login-container">
|
|
|
- <!-- 顶部 -->
|
|
|
- <!-- <div class="absolute-lt flex-x-end p-3 w-full">
|
|
|
- <el-switch
|
|
|
- v-model="isDark"
|
|
|
- inline-prompt
|
|
|
- :active-icon="Moon"
|
|
|
- :inactive-icon="Sunny"
|
|
|
- @change="toggleTheme"
|
|
|
- />
|
|
|
- <lang-select class="ml-2 cursor-pointer" />
|
|
|
- </div> -->
|
|
|
- <!-- 登录表单 -->
|
|
|
- <el-card
|
|
|
- class="!border-none !rounded-4% w-100 <sm:w-85"
|
|
|
- style="background-color: #a0a8b2"
|
|
|
- >
|
|
|
- <div class="text-center relative">
|
|
|
+ <el-card class="form-container">
|
|
|
+ <div class="login-title">
|
|
|
<h2>{{ defaultSettings.title }}</h2>
|
|
|
- <el-tag class="ml-2 absolute-rt">{{ defaultSettings.version }}</el-tag>
|
|
|
+ <div @click="showJobNumber = !showJobNumber">
|
|
|
+ {{ showJobNumber ? "账号密码登录" : "扫码登录" }}
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
<el-form
|
|
@@ -26,44 +13,60 @@
|
|
|
:model="loginData"
|
|
|
:rules="loginRules"
|
|
|
class="login-form"
|
|
|
+ size="large"
|
|
|
>
|
|
|
- <!-- 用户名 -->
|
|
|
- <el-form-item prop="userName">
|
|
|
+ <el-form-item v-if="showJobNumber" prop="jobNumber">
|
|
|
<div class="flex-y-center w-full">
|
|
|
- <svg-icon class="mx-2" icon-class="user" />
|
|
|
+ <svg-icon class="mx-2" icon-class="document" />
|
|
|
<el-input
|
|
|
ref="username"
|
|
|
- v-model="loginData.userName"
|
|
|
- :placeholder="$t('login.username')"
|
|
|
+ v-model="loginData.jobNumber"
|
|
|
class="h-[48px]"
|
|
|
- name="userName"
|
|
|
+ name="jobNumber"
|
|
|
+ placeholder="请扫码或输入工号"
|
|
|
size="large"
|
|
|
/>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
-
|
|
|
- <!-- 密码 -->
|
|
|
- <el-tooltip
|
|
|
- :content="$t('login.capsLock')"
|
|
|
- :visible="isCapslock"
|
|
|
- placement="right"
|
|
|
- >
|
|
|
- <el-form-item prop="password">
|
|
|
+ <div v-else>
|
|
|
+ <!-- 用户名 -->
|
|
|
+ <el-form-item prop="userName">
|
|
|
<div class="flex-y-center w-full">
|
|
|
- <svg-icon class="mx-2" icon-class="lock" />
|
|
|
+ <svg-icon class="mx-2" icon-class="user" />
|
|
|
<el-input
|
|
|
- v-model="loginData.password"
|
|
|
- :placeholder="$t('login.password')"
|
|
|
- class="h-[48px] pr-2"
|
|
|
- name="password"
|
|
|
- show-password
|
|
|
+ ref="username"
|
|
|
+ v-model="loginData.userName"
|
|
|
+ class="h-[48px]"
|
|
|
+ name="userName"
|
|
|
+ placeholder="请输入用户名"
|
|
|
size="large"
|
|
|
- type="password"
|
|
|
- @keyup="checkCapslock"
|
|
|
/>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
- </el-tooltip>
|
|
|
+
|
|
|
+ <!-- 密码 -->
|
|
|
+ <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">
|
|
@@ -74,7 +77,6 @@
|
|
|
class="no-border"
|
|
|
placeholder="请选择组织"
|
|
|
size="large"
|
|
|
- @keyup.enter="handleLogin"
|
|
|
>
|
|
|
<el-option
|
|
|
v-for="item in orgList"
|
|
@@ -86,21 +88,53 @@
|
|
|
</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"
|
|
|
+ >
|
|
|
+ <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="w-full"
|
|
|
+ class="login-btn"
|
|
|
size="large"
|
|
|
type="primary"
|
|
|
@click.prevent="handleLogin"
|
|
|
>{{ $t("login.login") }}
|
|
|
</el-button>
|
|
|
-
|
|
|
- <!-- 账号密码提示 -->
|
|
|
- <!-- <div class="mt-10 text-sm">
|
|
|
- <span>{{ $t("login.username") }}: admin</span>
|
|
|
- <span class="ml-4"> {{ $t("login.password") }}: 123456</span>
|
|
|
- </div> -->
|
|
|
</el-form>
|
|
|
</el-card>
|
|
|
|
|
@@ -113,12 +147,18 @@
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
import { useSettingsStore, useUserStore } from "@/store";
|
|
|
-import { getCaptchaApi, getOrgListApi } from "@/api/auth";
|
|
|
+import {
|
|
|
+ getCaptchaApi,
|
|
|
+ getOrgListApi,
|
|
|
+ getProductionList,
|
|
|
+ stationListByCode,
|
|
|
+} from "@/api/auth";
|
|
|
import { LoginData } from "@/api/auth/types";
|
|
|
import { LocationQuery, LocationQueryValue, useRoute } from "vue-router";
|
|
|
import router from "@/router";
|
|
|
import defaultSettings from "@/settings";
|
|
|
import { ThemeEnum } from "@/enums/ThemeEnum";
|
|
|
+import { watch } from "vue";
|
|
|
// Stores
|
|
|
const userStore = useUserStore();
|
|
|
const settingsStore = useSettingsStore();
|
|
@@ -129,7 +169,10 @@ const { t } = useI18n();
|
|
|
// Reactive states
|
|
|
const isDark = ref(settingsStore.theme === ThemeEnum.DARK);
|
|
|
const icpVisible = ref(true);
|
|
|
-const orgList = ref([]);
|
|
|
+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字符串
|
|
@@ -169,6 +212,27 @@ const loginRules = computed?.(() => {
|
|
|
message: t("login.message.orgId.required"),
|
|
|
},
|
|
|
],
|
|
|
+ proCode: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ trigger: "blur",
|
|
|
+ message: "请选择产线",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ stationId: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ trigger: "blur",
|
|
|
+ message: "请选择工位",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ jobNumber: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ trigger: "blur",
|
|
|
+ message: "请输入工号",
|
|
|
+ },
|
|
|
+ ],
|
|
|
};
|
|
|
});
|
|
|
|
|
@@ -247,6 +311,20 @@ watchEffect?.(() => {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+watch(
|
|
|
+ () => loginData.value.proCode,
|
|
|
+ (newValue) => {
|
|
|
+ if (newValue) {
|
|
|
+ stationListByCode(newValue).then((data: any) => {
|
|
|
+ stationList.value = data.data;
|
|
|
+ if (stationList.value) {
|
|
|
+ loginData.value.stationId = stationList.value[0].id;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
/**
|
|
|
* 检查输入大小写
|
|
|
*/
|
|
@@ -257,6 +335,12 @@ function checkCapslock(e: any) {
|
|
|
onMounted?.(() => {
|
|
|
getOrgList();
|
|
|
toggleTheme();
|
|
|
+ getProductionList().then((data: any) => {
|
|
|
+ productionList.value = data.data;
|
|
|
+ if (productionList.value) {
|
|
|
+ loginData.value.proCode = productionList.value[0].code;
|
|
|
+ }
|
|
|
+ });
|
|
|
});
|
|
|
</script>
|
|
|
|
|
@@ -269,12 +353,36 @@ html.dark .login-container {
|
|
|
overflow-y: auto;
|
|
|
background: url("@/assets/images/login-bg.png") no-repeat center right;
|
|
|
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: 673px;
|
|
|
+ position: absolute;
|
|
|
+ right: 10%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .login-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: 50px;
|
|
|
+ border-radius: 25px;
|
|
|
+ margin-top: 15px;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.el-form-item {
|
|
@@ -301,6 +409,22 @@ html.dark .login-container {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+: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;
|