perf:修复大多数文件的 linter(首次)

This commit is contained in:
YunaiV
2025-12-15 23:12:42 +08:00
parent f9fc5a8abe
commit d971aba582
39 changed files with 286 additions and 278 deletions

View File

@@ -52,63 +52,63 @@
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { useToast } from "wot-design-uni";
import { FORGET_PASSWORD_PAGE, LOGIN_PAGE } from "@/router/config";
import { useTokenStore } from "@/store/token";
import { ensureDecodeURIComponent, redirectAfterLogin } from "@/utils";
import { isMobile } from "@/utils/validator";
import CodeInput from "./components/code-input.vue";
import Header from "./components/header.vue";
import TenantPicker from "./components/tenant-picker.vue";
import { Verify } from '@/components/verifition';
import { reactive, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { Verify } from '@/components/verifition'
import { FORGET_PASSWORD_PAGE, LOGIN_PAGE } from '@/router/config'
import { useTokenStore } from '@/store/token'
import { ensureDecodeURIComponent, redirectAfterLogin } from '@/utils'
import { isMobile } from '@/utils/validator'
import CodeInput from './components/code-input.vue'
import Header from './components/header.vue'
import TenantPicker from './components/tenant-picker.vue'
defineOptions({
name: "SmsLoginPage",
});
name: 'SmsLoginPage',
})
definePage({
style: {
navigationStyle: "custom",
navigationStyle: 'custom',
},
excludeLoginPath: true,
});
})
const toast = useToast();
const loading = ref(false); // 加载状态
const redirectUrl = ref<string>(); // 重定向地址
const tenantPickerRef = ref<InstanceType<typeof TenantPicker>>(); // 租户选择器引用
const captchaEnabled = import.meta.env.VITE_APP_CAPTCHA_ENABLE === 'true'; // 验证码开关
const verifyRef = ref();
const captchaType = ref('blockPuzzle'); // 滑块验证码 blockPuzzle|clickWord
const toast = useToast()
const loading = ref(false) // 加载状态
const redirectUrl = ref<string>() // 重定向地址
const tenantPickerRef = ref<InstanceType<typeof TenantPicker>>() // 租户选择器引用
const captchaEnabled = import.meta.env.VITE_APP_CAPTCHA_ENABLE === 'true' // 验证码开关
const verifyRef = ref()
const captchaType = ref('blockPuzzle') // 滑块验证码 blockPuzzle|clickWord
const formData = reactive({
mobile: "",
code: "",
captchaVerification: "", // 验证码校验值
}); // 表单数据
mobile: '',
code: '',
captchaVerification: '', // 验证码校验值
}) // 表单数据
/** 页面加载时处理重定向 */
onLoad((options) => {
if (options?.redirect) {
redirectUrl.value = ensureDecodeURIComponent(options.redirect);
redirectUrl.value = ensureDecodeURIComponent(options.redirect)
}
});
})
/** 发送验证码前的校验 */
function validateBeforeSend(): boolean {
return tenantPickerRef.value?.validate() ?? false;
return tenantPickerRef.value?.validate() ?? false
}
/** 获取验证码 */
async function getCode() {
// 情况一,未开启:则直接登录
if (!captchaEnabled) {
await verifySuccess({});
await verifySuccess({})
} else {
// 情况二,已开启:则展示验证码;只有完成验证码的情况,才进行登录
// 弹出验证码
verifyRef.value.show();
verifyRef.value.show()
}
}
@@ -116,52 +116,52 @@ async function getCode() {
async function handleLogin() {
// 校验租户
if (!tenantPickerRef.value?.validate()) {
return;
return
}
if (!formData.mobile) {
toast.warning("请输入手机号");
return;
toast.warning('请输入手机号')
return
}
if (!isMobile(formData.mobile)) {
toast.warning("请输入正确的手机号");
return;
toast.warning('请输入正确的手机号')
return
}
if (!formData.code) {
toast.warning("请输入验证码");
return;
toast.warning('请输入验证码')
return
}
await getCode();
await getCode()
}
/** 验证码验证成功回调 */
async function verifySuccess(params: any) {
loading.value = true;
loading.value = true
try {
// 调用短信登录接口
const tokenStore = useTokenStore();
formData.captchaVerification = params.captchaVerification;
const tokenStore = useTokenStore()
formData.captchaVerification = params.captchaVerification
await tokenStore.login({
type: "sms",
type: 'sms',
...formData,
});
})
// 处理跳转
redirectAfterLogin(redirectUrl.value);
redirectAfterLogin(redirectUrl.value)
} finally {
loading.value = false;
loading.value = false
}
}
/** 跳转到账号密码登录 */
function goToLogin() {
uni.navigateTo({ url: LOGIN_PAGE });
uni.navigateTo({ url: LOGIN_PAGE })
}
/** 跳转到忘记密码 */
function goToForgetPassword() {
uni.navigateTo({ url: FORGET_PASSWORD_PAGE });
uni.navigateTo({ url: FORGET_PASSWORD_PAGE })
}
</script>
<style lang="scss" scoped>
@import "./styles/auth.scss";
@import './styles/auth.scss';
</style>

View File

@@ -23,68 +23,68 @@
</template>
<script lang="ts" setup>
import { onUnmounted, ref } from "vue";
import { useToast } from "wot-design-uni";
import { sendSmsCode } from "@/api/login";
import { isMobile } from "@/utils/validator";
import { onUnmounted, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { sendSmsCode } from '@/api/login'
import { isMobile } from '@/utils/validator'
defineOptions({
name: "CodeInput",
});
name: 'CodeInput',
})
const props = defineProps<{
modelValue: string; // 验证码值 (v-model)
mobile: string; // 手机号
scene: number; // 短信场景21-登录 23-重置密码
beforeSend?: () => boolean; // 发送前的校验函数,返回 false 则不发送
}>();
modelValue: string // 验证码值 (v-model)
mobile: string // 手机号
scene: number // 短信场景21-登录 23-重置密码
beforeSend?: () => boolean // 发送前的校验函数,返回 false 则不发送
}>()
defineEmits<{
"update:modelValue": [value: string];
}>();
'update:modelValue': [value: string]
}>()
const toast = useToast();
const countdown = ref(0); // 验证码倒计时,单位秒
let countdownTimer: ReturnType<typeof setInterval> | null = null; // 倒计时定时器
const toast = useToast()
const countdown = ref(0) // 验证码倒计时,单位秒
let countdownTimer: ReturnType<typeof setInterval> | null = null // 倒计时定时器
/** 页面卸载时清除倒计时定时器 */
onUnmounted(() => {
if (countdownTimer) {
clearInterval(countdownTimer);
countdownTimer = null;
clearInterval(countdownTimer)
countdownTimer = null
}
});
})
/** 发送验证码 */
async function handleSendCode() {
// 执行前置校验
if (props.beforeSend && !props.beforeSend()) {
return;
return
}
if (countdown.value > 0) {
return;
return
}
if (!props.mobile) {
toast.warning("请输入手机号");
return;
toast.warning('请输入手机号')
return
}
if (!isMobile(props.mobile)) {
toast.warning("请输入正确的手机号");
return;
toast.warning('请输入正确的手机号')
return
}
// 发送验证码
await sendSmsCode({ mobile: props.mobile, scene: props.scene });
toast.success("验证码已发送");
await sendSmsCode({ mobile: props.mobile, scene: props.scene })
toast.success('验证码已发送')
// 开始倒计时
countdown.value = 60;
countdown.value = 60
countdownTimer = setInterval(() => {
countdown.value--;
countdown.value--
if (countdown.value <= 0) {
clearInterval(countdownTimer!);
countdownTimer = null;
clearInterval(countdownTimer!)
countdownTimer = null
}
}, 1000);
}, 1000)
}
</script>

View File

@@ -14,121 +14,122 @@
</template>
<script lang="ts" setup>
import { computed, onMounted, ref } from "vue";
import { useToast } from "wot-design-uni";
import type { TenantVO } from '@/api/login'
import { computed, onMounted, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import {
getTenantByWebsite,
getTenantSimpleList,
type TenantVO,
} from "@/api/login";
import { useUserStore } from "@/store/user";
const toast = useToast();
const userStore = useUserStore();
} from '@/api/login'
import { useUserStore } from '@/store/user'
const toast = useToast()
const userStore = useUserStore()
const tenantEnabled = computed(
() => import.meta.env.VITE_APP_TENANT_ENABLE === "true",
); // 租户开关:通过环境变量控制
const tenantList = ref<TenantVO[]>([]); // 租户列表数据
() => import.meta.env.VITE_APP_TENANT_ENABLE === 'true',
) // 租户开关:通过环境变量控制
const tenantList = ref<TenantVO[]>([]) // 租户列表数据
const tenantId = computed(
() =>
userStore.tenantId ||
Number(import.meta.env.VITE_APP_DEFAULT_LOGIN_TENANT_ID) ||
undefined,
); // 当前选中的租户
userStore.tenantId
|| Number(import.meta.env.VITE_APP_DEFAULT_LOGIN_TENANT_ID)
|| undefined,
) // 当前选中的租户
/** 获取租户列表,并根据域名/appId 自动选中租户 */
async function fetchTenantList() {
if (!tenantEnabled.value) {
return;
return
}
try {
// 1. 并行获取租户列表和域名对应的租户
const websiteTenantPromise = fetchTenantByWebsite();
const list = await getTenantSimpleList();
tenantList.value = list || [];
const websiteTenantPromise = fetchTenantByWebsite()
const list = await getTenantSimpleList()
tenantList.value = list || []
// 2. 确定选中的租户:域名/appId > store 中的租户 > 列表第一个
let selectedTenantId: number | null = null;
let selectedTenantId: number | null = null
// 2.1 优先使用域名/appId 对应的租户
const websiteTenant = await websiteTenantPromise;
const websiteTenant = await websiteTenantPromise
if (websiteTenant?.id) {
selectedTenantId = websiteTenant.id;
selectedTenantId = websiteTenant.id
}
// 2.2 如果没有从域名获取到,使用 store 中的租户
if (!selectedTenantId && userStore.tenantId) {
selectedTenantId = userStore.tenantId;
selectedTenantId = userStore.tenantId
}
// 2.3 如果还是没有,使用列表第一个
if (!selectedTenantId && tenantList.value.length > 0) {
selectedTenantId = tenantList.value[0].id;
selectedTenantId = tenantList.value[0].id
}
// 3. 设置选中的租户
if (selectedTenantId && selectedTenantId !== userStore.tenantId) {
userStore.setTenantId(selectedTenantId);
userStore.setTenantId(selectedTenantId)
}
} catch (error) {
console.error("获取租户列表失败:", error);
console.error('获取租户列表失败:', error)
}
}
/** 根据域名或 appId 获取租户 */
async function fetchTenantByWebsite(): Promise<TenantVO | null> {
try {
let website: string | null = null;
let website: string | null = null
// #ifdef H5
// H5 环境:使用域名
if (window?.location?.hostname) {
website = window.location.hostname;
website = window.location.hostname
}
// #endif
// #ifdef MP
// 小程序环境:使用 appId
const appId = uni.getAccountInfoSync?.()?.miniProgram?.appId;
const appId = uni.getAccountInfoSync?.()?.miniProgram?.appId
if (appId) {
website = appId;
website = appId
}
// #endif
if (website) {
return await getTenantByWebsite(website);
return await getTenantByWebsite(website)
}
} catch (error) {
// 域名未配置租户时会报错,忽略即可
console.debug("根据域名获取租户失败:", error);
console.debug('根据域名获取租户失败:', error)
}
return null;
return null
}
/** 租户选择确认 */
function handleConfirm({ value }: { value: number }) {
userStore.setTenantId(value);
userStore.setTenantId(value)
}
/** 校验租户是否已选择 */
function validate(): boolean {
if (!tenantEnabled.value) {
return true;
return true
}
if (!tenantId.value) {
toast.warning("请选择租户");
return false;
toast.warning('请选择租户')
return false
}
return true;
return true
}
/** 页面加载时获取租户列表 */
onMounted(() => {
fetchTenantList();
});
fetchTenantList()
})
defineExpose({ validate });
defineExpose({ validate })
</script>
<style lang="scss" scoped>
@import "../styles/auth.scss";
@import '../styles/auth.scss';
</style>

View File

@@ -64,97 +64,97 @@
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { useToast } from "wot-design-uni";
import { smsResetPassword } from "@/api/login";
import { LOGIN_PAGE } from "@/router/config";
import { isMobile } from "@/utils/validator";
import CodeInput from "./components/code-input.vue";
import Header from "./components/header.vue";
import TenantPicker from "./components/tenant-picker.vue";
import { reactive, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { smsResetPassword } from '@/api/login'
import { LOGIN_PAGE } from '@/router/config'
import { isMobile } from '@/utils/validator'
import CodeInput from './components/code-input.vue'
import Header from './components/header.vue'
import TenantPicker from './components/tenant-picker.vue'
defineOptions({
name: "ForgetPasswordPage",
});
name: 'ForgetPasswordPage',
})
definePage({
style: {
navigationStyle: "custom",
navigationStyle: 'custom',
},
excludeLoginPath: true,
});
})
const toast = useToast();
const loading = ref(false); // 加载状态
const tenantPickerRef = ref<InstanceType<typeof TenantPicker>>(); // 租户选择器引用
const toast = useToast()
const loading = ref(false) // 加载状态
const tenantPickerRef = ref<InstanceType<typeof TenantPicker>>() // 租户选择器引用
const formData = reactive({
mobile: "",
code: "",
password: "",
confirmPassword: "",
}); // 表单数据
mobile: '',
code: '',
password: '',
confirmPassword: '',
}) // 表单数据
/** 发送验证码前的校验 */
function validateBeforeSend(): boolean {
return tenantPickerRef.value?.validate() ?? false;
return tenantPickerRef.value?.validate() ?? false
}
/** 重置密码处理 */
async function handleResetPassword() {
// 校验租户
if (!tenantPickerRef.value?.validate()) {
return;
return
}
if (!formData.mobile) {
toast.warning("请输入手机号");
return;
toast.warning('请输入手机号')
return
}
if (!isMobile(formData.mobile)) {
toast.warning("请输入正确的手机号");
return;
toast.warning('请输入正确的手机号')
return
}
if (!formData.code) {
toast.warning("请输入验证码");
return;
toast.warning('请输入验证码')
return
}
if (!formData.password) {
toast.warning("请输入新密码");
return;
toast.warning('请输入新密码')
return
}
if (!formData.confirmPassword) {
toast.warning("请确认新密码");
return;
toast.warning('请确认新密码')
return
}
if (formData.password !== formData.confirmPassword) {
toast.warning("两次输入的密码不一致");
return;
toast.warning('两次输入的密码不一致')
return
}
loading.value = true;
loading.value = true
try {
// 调用重置密码接口
await smsResetPassword({
mobile: formData.mobile,
code: formData.code,
password: formData.password,
});
toast.success("密码重置成功");
})
toast.success('密码重置成功')
// 跳转到登录页
setTimeout(() => {
goToLogin();
}, 500);
goToLogin()
}, 500)
} finally {
loading.value = false;
loading.value = false
}
}
/** 跳转到登录页面 */
function goToLogin() {
uni.navigateTo({ url: LOGIN_PAGE });
uni.navigateTo({ url: LOGIN_PAGE })
}
</script>
<style lang="scss" scoped>
@import "./styles/auth.scss";
@import './styles/auth.scss';
</style>

View File

@@ -82,6 +82,7 @@
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { Verify } from '@/components/verifition'
import {
CODE_LOGIN_PAGE,
FORGET_PASSWORD_PAGE,
@@ -91,7 +92,6 @@ import { useTokenStore } from '@/store/token'
import { ensureDecodeURIComponent, redirectAfterLogin } from '@/utils'
import Header from './components/header.vue'
import TenantPicker from './components/tenant-picker.vue'
import { Verify } from '@/components/verifition';
defineOptions({
name: 'LoginPage',

View File

@@ -92,120 +92,120 @@
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { useToast } from "wot-design-uni";
import { LOGIN_PAGE } from "@/router/config";
import { useTokenStore } from "@/store/token";
import { redirectAfterLogin } from "@/utils";
import Header from "./components/header.vue";
import TenantPicker from "./components/tenant-picker.vue";
import { Verify } from '@/components/verifition';
import { reactive, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { Verify } from '@/components/verifition'
import { LOGIN_PAGE } from '@/router/config'
import { useTokenStore } from '@/store/token'
import { redirectAfterLogin } from '@/utils'
import Header from './components/header.vue'
import TenantPicker from './components/tenant-picker.vue'
defineOptions({
name: "RegisterPage",
});
name: 'RegisterPage',
})
definePage({
style: {
navigationStyle: "custom",
navigationStyle: 'custom',
},
});
})
const toast = useToast();
const loading = ref(false); // 加载状态
const agreePolicy = ref(false); // 用户协议勾选
const tenantPickerRef = ref<InstanceType<typeof TenantPicker>>(); // 租户选择器引用
const captchaEnabled = import.meta.env.VITE_APP_CAPTCHA_ENABLE === 'true'; // 验证码开关
const verifyRef = ref();
const captchaType = ref('blockPuzzle'); // 滑块验证码 blockPuzzle|clickWord
const toast = useToast()
const loading = ref(false) // 加载状态
const agreePolicy = ref(false) // 用户协议勾选
const tenantPickerRef = ref<InstanceType<typeof TenantPicker>>() // 租户选择器引用
const captchaEnabled = import.meta.env.VITE_APP_CAPTCHA_ENABLE === 'true' // 验证码开关
const verifyRef = ref()
const captchaType = ref('blockPuzzle') // 滑块验证码 blockPuzzle|clickWord
const formData = reactive({
username: "",
nickname: "",
password: "",
confirmPassword: "",
captchaVerification: "", // 验证码校验值
}); // 表单数据
username: '',
nickname: '',
password: '',
confirmPassword: '',
captchaVerification: '', // 验证码校验值
}) // 表单数据
/** 获取验证码 */
async function getCode() {
// 情况一,未开启:则直接注册
if (!captchaEnabled) {
await verifySuccess({});
await verifySuccess({})
} else {
// 情况二,已开启:则展示验证码;只有完成验证码的情况,才进行注册
// 弹出验证码
verifyRef.value.show();
verifyRef.value.show()
}
}
/** 注册处理 */
async function handleRegister() {
if (!tenantPickerRef.value?.validate()) {
return;
return
}
if (!agreePolicy.value) {
toast.warning("请阅读并同意《用户协议》与《隐私政策》");
return;
toast.warning('请阅读并同意《用户协议》与《隐私政策》')
return
}
if (!formData.username) {
toast.warning("请输入用户名");
return;
toast.warning('请输入用户名')
return
}
if (!formData.nickname) {
toast.warning("请输入昵称");
return;
toast.warning('请输入昵称')
return
}
if (!formData.password) {
toast.warning("请输入密码");
return;
toast.warning('请输入密码')
return
}
if (!formData.confirmPassword) {
toast.warning("请确认密码");
return;
toast.warning('请确认密码')
return
}
if (formData.password !== formData.confirmPassword) {
toast.warning("两次输入的密码不一致");
return;
toast.warning('两次输入的密码不一致')
return
}
await getCode();
await getCode()
}
/** 验证码验证成功回调 */
async function verifySuccess(params: any) {
loading.value = true;
loading.value = true
try {
// 调用注册接口
const tokenStore = useTokenStore();
formData.captchaVerification = params.captchaVerification;
const tokenStore = useTokenStore()
formData.captchaVerification = params.captchaVerification
await tokenStore.login({
type: "register",
type: 'register',
...formData,
});
toast.success("注册成功");
})
toast.success('注册成功')
// 处理跳转
redirectAfterLogin();
redirectAfterLogin()
} finally {
loading.value = false;
loading.value = false
}
}
/** 跳转到登录页面 */
function goToLogin() {
uni.navigateTo({ url: LOGIN_PAGE });
uni.navigateTo({ url: LOGIN_PAGE })
}
/** 跳转到用户协议 */
function goToUserAgreement() {
uni.navigateTo({ url: "/pages/user/settings/agreement/index" });
uni.navigateTo({ url: '/pages/user/settings/agreement/index' })
}
/** 跳转到隐私政策 */
function goToPrivacyPolicy() {
uni.navigateTo({ url: "/pages/user/settings/privacy/index" });
uni.navigateTo({ url: '/pages/user/settings/privacy/index' })
}
</script>
<style lang="scss" scoped>
@import "./styles/auth.scss";
@import './styles/auth.scss';
</style>