提交 bb5ba490 authored 作者: kxjia's avatar kxjia

完善首页配置

上级 91425094
<template>
<div class="aui-content">
<div class="aui-container">
<div class="aui-form">
<div class="aui-image">
<div class="aui-image-text">
<img :src="adTextImg" alt="" />
</div>
</div>
<div class="aui-formBox aui-formEwm">
<div class="aui-formWell">
<form>
<div class="aui-flex aui-form-nav investment_title" style="padding-bottom: 19px">
<div class="aui-flex-box activeNav">{{t('sys.login.qrSignInFormTitle')}}</div>
</div>
<div class="aui-form-box">
<div class="aui-account" style="padding: 30px 0">
<div class="aui-ewm">
<QrCode :value="qrCodeUrl" class="enter-x flex justify-center xl:justify-start" :width="280" />
</div>
</div>
</div>
<div class="aui-formButton">
<a class="aui-linek-code aui-link-register" @click="goBackHandleClick">{{t('sys.login.backSignIn')}}</a>
</div>
</form>
</div>
<div class="aui-flex aui-third-text">
<div class="aui-flex-box aui-third-border">
<span>{{ t('sys.login.otherSignIn') }}</span>
</div>
</div>
<div class="aui-flex" :class="`${prefixCls}-sign-in-way`">
<div class="aui-flex-box">
<div class="aui-third-login">
<a href="" title="github" @click="onThirdLogin('github')"><GithubFilled /></a>
</div>
</div>
<div class="aui-flex-box">
<div class="aui-third-login">
<a href="" title="企业微信" @click="onThirdLogin('wechat_enterprise')"><icon-font class="item-icon" type="icon-qiyeweixin3" /></a>
</div>
</div>
<div class="aui-flex-box">
<div class="aui-third-login">
<a href="" title="钉钉" @click="onThirdLogin('dingtalk')"><DingtalkCircleFilled /></a>
</div>
</div>
<div class="aui-flex-box">
<div class="aui-third-login">
<a href="" title="微信" @click="onThirdLogin('wechat_open')"><WechatFilled /></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 第三方登录相关弹框 -->
<ThirdModal ref="thirdModalRef"></ThirdModal>
</template>
<script lang="ts" setup name="mini-code-login">
import { ref, onUnmounted } from 'vue';
import { getLoginQrcode, getQrcodeToken } from '/@/api/sys/user';
import { useUserStore } from '/@/store/modules/user';
import { QrCode } from '/@/components/Qrcode/index';
import ThirdModal from '/@/views/sys/login/ThirdModal.vue';
import logoImg from '/@/assets/loginmini/icon/jeecg_logo.png';
import adTextImg from '/@/assets/loginmini/icon/jeecg_ad_text.png';
import { useI18n } from '/@/hooks/web/useI18n';
import { useDesign } from "/@/hooks/web/useDesign";
import { GithubFilled, WechatFilled, DingtalkCircleFilled, createFromIconfontCN } from '@ant-design/icons-vue';
const IconFont = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/font_2316098_umqusozousr.js',
});
const { prefixCls } = useDesign('minilogin');
const { t } = useI18n();
const qrCodeUrl = ref<string>('');
let timer: IntervalHandle;
const state = ref('0');
const thirdModalRef = ref();
const userStore = useUserStore();
const emit = defineEmits(['go-back', 'success', 'register']);
//加载二维码信息
function loadQrCode() {
state.value = '0';
getLoginQrcode().then((res) => {
qrCodeUrl.value = res.qrcodeId;
if (res.qrcodeId) {
openTimer(res.qrcodeId);
}
});
}
//监控扫码状态
function watchQrcodeToken(qrcodeId) {
getQrcodeToken({ qrcodeId: qrcodeId }).then((res) => {
let token = res.token;
if (token == '-2') {
//二维码过期重新获取
loadQrCode();
clearInterval(timer);
}
//扫码成功
if (res.success) {
state.value = '2';
clearInterval(timer);
setTimeout(() => {
userStore.qrCodeLogin(token);
}, 500);
}
});
}
/** 开启定时器 */
function openTimer(qrcodeId) {
watchQrcodeToken(qrcodeId);
closeTimer();
timer = setInterval(() => {
watchQrcodeToken(qrcodeId);
}, 1500);
}
/** 关闭定时器 */
function closeTimer() {
if (timer) clearInterval(timer);
}
/**
* 第三方登录
* @param type
*/
function onThirdLogin(type) {
thirdModalRef.value.onThirdLogin(type);
}
/**
* 初始化表单
*/
function initFrom() {
loadQrCode();
}
/**
* 返回
*/
function goBackHandleClick() {
emit('go-back');
closeTimer();
}
onUnmounted(() => {
closeTimer();
});
defineExpose({
initFrom,
});
</script>
<style lang="less" scoped>
@import '/@/assets/loginmini/style/home.less';
@import '/@/assets/loginmini/style/base.less';
</style>
<template>
<div class="aui-content">
<div class="aui-container">
<div class="aui-form">
<div class="aui-image">
<div class="aui-image-text">
<img :src="adTextImg" alt="" />
</div>
</div>
<div class="aui-formBox">
<div class="aui-formWell">
<div class="aui-step-box">
<div class="aui-step-item" :class="activeKey === 1 ? 'activeStep' : ''">
<div class="aui-step-tags">
<em>1</em>
<p>{{t('sys.login.authentication')}}</p>
</div>
</div>
<div class="aui-step-item" :class="activeKey === 2 ? 'activeStep' : ''">
<div class="aui-step-tags">
<em>2</em>
<p>{{t('sys.login.resetLoginPassword')}}</p>
</div>
</div>
<div class="aui-step-item" :class="activeKey === 3 ? 'activeStep' : ''">
<div class="aui-step-tags">
<em>3</em>
<p>{{t('sys.login.resetSuccess')}}</p>
</div>
</div>
</div>
<div class="" style="height: 230px; position: relative">
<a-form ref="formRef" :model="formData" v-if="activeKey === 1">
<!-- 身份验证 begin -->
<div class="aui-account aui-account-line aui-forgot">
<a-form-item>
<div class="aui-input-line">
<a-input type="text" :placeholder="t('sys.login.mobile')" v-model:value="formData.mobile" />
</div>
</a-form-item>
<div class="aui-input-line">
<a-form-item>
<a-input type="text" :placeholder="t('sys.login.smsCode')" v-model:value="formData.smscode" />
</a-form-item>
<div v-if="showInterval" class="aui-code-line" @click="getLoginCode">{{t('component.countdown.normalText')}}</div>
<div v-else class="aui-code-line">{{t('component.countdown.sendText',[unref(timeRuning)])}}</div>
</div>
</div>
<!-- 身份验证 end -->
</a-form>
<a-form ref="pwdFormRef" :model="pwdFormData" v-else-if="activeKey === 2">
<!-- 重置密码 begin -->
<div class="aui-account aui-account-line aui-forgot">
<a-form-item>
<div class="aui-input-line">
<a-input type="password" :placeholder="t('sys.login.passwordPlaceholder')" v-model:value="pwdFormData.password" />
</div>
</a-form-item>
<a-form-item>
<div class="aui-input-line">
<a-input type="password" :placeholder="t('sys.login.confirmPassword')" v-model:value="pwdFormData.confirmPassword" />
</div>
</a-form-item>
</div>
<!-- 重置密码 end -->
</a-form>
<!-- 重置成功 begin -->
<div class="aui-success" v-else>
<div class="aui-success-icon">
<img :src="successImg"/>
</div>
<h3>恭喜您,重置密码成功!</h3>
</div>
<!-- 重置成功 end -->
</div>
<div class="aui-formButton" style="padding-bottom: 40px">
<div class="aui-flex" v-if="activeKey === 1 || activeKey === 2">
<a class="aui-link-login aui-flex-box" @click="nextStepClick">{{t('sys.login.nextStep')}}</a>
</div>
<div class="aui-flex" v-else>
<a class="aui-linek-code aui-flex-box" @click="toLogin">{{t('sys.login.goToLogin')}}</a>
</div>
<div class="aui-flex">
<a class="aui-linek-code aui-flex-box" @click="goBack"> {{ t('sys.login.backSignIn') }}</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 图片验证码弹窗 -->
<CaptchaModal @register="captchaRegisterModal" @ok="getLoginCode" />
</template>
<script lang="ts" name="mini-forgotpad" setup>
import { reactive, ref, toRaw, unref } from 'vue';
import { useI18n } from '/@/hooks/web/useI18n';
import { SmsEnum, useFormRules, useFormValid, useLoginState } from '/@/views/sys/login/useLogin';
import { useMessage } from '/@/hooks/web/useMessage';
import { getCaptcha, passwordChange, phoneVerify } from '/@/api/sys/user';
import logoImg from '/@/assets/loginmini/icon/jeecg_logo.png'
import adTextImg from '/@/assets/loginmini/icon/jeecg_ad_text.png'
import successImg from '/@/assets/loginmini/icon/icon-success.png'
import CaptchaModal from '@/components/jeecg/captcha/CaptchaModal.vue';
import { useModal } from "@/components/Modal";
import { ExceptionEnum } from "@/enums/exceptionEnum";
const [captchaRegisterModal, { openModal: openCaptchaModal }] = useModal();
//下一步控制
const activeKey = ref<number>(1);
const { t } = useI18n();
const { handleBackLogin } = useLoginState();
const { notification, createMessage, createErrorModal } = useMessage();
//是否显示获取验证码
const showInterval = ref<boolean>(true);
//60s
const timeRuning = ref<number>(60);
//定时器
const timer = ref<any>(null);
const formRef = ref();
const pwdFormRef = ref();
//账号数据
const accountInfo = reactive<any>({});
//手机号表单
const formData = reactive({
mobile: '',
smscode: '',
});
//密码表单
const pwdFormData = reactive<any>({
password: '',
confirmPassword: '',
});
const emit = defineEmits(['go-back', 'success', 'register']);
/**
* 下一步
*/
async function handleNext() {
if (!formData.mobile) {
createMessage.warn(t('sys.login.mobilePlaceholder'));
return;
}
if (!formData.smscode) {
createMessage.warn(t('sys.login.smsPlaceholder'));
return;
}
const resultInfo = await phoneVerify(
toRaw({
phone: formData.mobile,
smscode: formData.smscode,
})
);
if (resultInfo.success) {
Object.assign(accountInfo, {
username: resultInfo.result.username,
phone: formData.mobile,
smscode: formData.smscode,
});
activeKey.value = 2;
setTimeout(()=>{
pwdFormRef.value.resetFields();
},300)
} else {
notification.error({
message: '错误提示',
description: resultInfo.message || t('sys.api.networkExceptionMsg'),
duration: 3,
});
}
}
/**
* 完成修改密码
*/
async function finishedPwd() {
if (!pwdFormData.password) {
createMessage.warn(t('sys.login.passwordPlaceholder'));
return;
}
if (!pwdFormData.confirmPassword) {
createMessage.warn(t('sys.login.confirmPassword'));
return;
}
if (pwdFormData.password !== pwdFormData.confirmPassword) {
createMessage.warn(t('sys.login.diffPwd'));
return;
}
const resultInfo = await passwordChange(
toRaw({
username: accountInfo.username,
password: pwdFormData.password,
smscode: accountInfo.smscode,
phone: accountInfo.phone,
})
);
if (resultInfo.success) {
accountInfo.password = pwdFormData.password;
//修改密码
activeKey.value = 3;
} else {
//错误提示
createErrorModal({
title: t('sys.api.errorTip'),
content: resultInfo.message || t('sys.api.networkExceptionMsg'),
});
}
}
/**
* 下一步
*/
function nextStepClick() {
if (unref(activeKey) == 1) {
handleNext();
} else if (unref(activeKey) == 2) {
finishedPwd();
}
}
/**
* 去登录
*/
function toLogin() {
emit('success', { username: accountInfo.username, password: accountInfo.password });
initForm();
}
/**
* 返回
*/
function goBack() {
emit('go-back');
initForm();
}
/**
* 获取手机验证码
*/
async function getLoginCode() {
if (!formData.mobile) {
createMessage.warn(t('sys.login.mobilePlaceholder'));
return;
}
//update-begin---author:wangshuai---date:2024-04-18---for:【QQYUN-9005】同一个IP,1分钟超过5次短信,则提示需要验证码---
const result = await getCaptcha({ mobile: formData.mobile, smsmode: SmsEnum.FORGET_PASSWORD }).catch((res) =>{
if(res.code === ExceptionEnum.PHONE_SMS_FAIL_CODE){
openCaptchaModal(true, {});
}
});
//update-end---author:wangshuai---date:2024-04-18---for:【QQYUN-9005】同一个IP,1分钟超过5次短信,则提示需要验证码---
if (result) {
const TIME_COUNT = 60;
if (!unref(timer)) {
timeRuning.value = TIME_COUNT;
showInterval.value = false;
timer.value = setInterval(() => {
if (unref(timeRuning) > 0 && unref(timeRuning) <= TIME_COUNT) {
timeRuning.value = timeRuning.value - 1;
} else {
showInterval.value = true;
clearInterval(unref(timer));
timer.value = null;
}
}, 1000);
}
}
}
/**
* 初始化表单
*/
function initForm() {
activeKey.value = 1;
Object.assign(formData, { phone: '', smscode: '' });
Object.assign(pwdFormData, { password: '', confirmPassword: '' });
Object.assign(accountInfo, {});
if(unref(timer)){
clearInterval(unref(timer));
timer.value = null;
showInterval.value = true;
}
setTimeout(()=>{
formRef.value.resetFields();
},300)
}
defineExpose({
initForm,
});
</script>
<style lang="less" scoped>
@import '/@/assets/loginmini/style/home.less';
@import '/@/assets/loginmini/style/base.less';
</style>
<template>
<div :class="prefixCls" class="login-background-img">
<AppLocalePicker class="absolute top-4 right-4 enter-x xl:text-gray-600" :showText="false"/>
<AppDarkModeToggle class="absolute top-3 right-7 enter-x" />
<div class="aui-logo" v-if="!getIsMobile">
</div>
<div v-else class="aui-phone-logo">
<img :src="logoImg" alt="jeecg" />
</div>
<div v-show="type === 'login'">
<div class="aui-content">
<div class="aui-container">
<div class="aui-form">
<div class="aui-image">
<div class="aui-image-text">
<MiniLoginAd></MiniLoginAd>
</div>
</div>
<div class="aui-formBox">
<div class="aui-formWell">
<div class="aui-flex aui-form-nav investment_title">
<div class="aui-flex-box" :class="activeIndex === 'accountLogin' ? 'activeNav on' : ''" @click="loginClick('accountLogin')"
>{{ t('sys.login.signInFormTitle') }}
</div>
<div class="aui-flex-box" :class="activeIndex === 'phoneLogin' ? 'activeNav on' : ''" @click="loginClick('phoneLogin')"
>{{ t('sys.login.mobileSignInFormTitle') }}
</div>
</div>
<div class="aui-form-box" style="height: 180px">
<a-form ref="loginRef" :model="formData" v-if="activeIndex === 'accountLogin'" @keyup.enter.native="loginHandleClick">
<div class="aui-account">
<div class="aui-inputClear">
<i class="icon icon-code"></i>
<a-form-item>
<a-input class="fix-auto-fill" :placeholder="t('sys.login.userName')" v-model:value="formData.username" />
</a-form-item>
</div>
<div class="aui-inputClear">
<i class="icon icon-password"></i>
<a-form-item>
<a-input class="fix-auto-fill" type="password" :placeholder="t('sys.login.password')" v-model:value="formData.password" />
</a-form-item>
</div>
<div class="aui-inputClear">
<i class="icon icon-code"></i>
<a-form-item>
<a-input class="fix-auto-fill" type="text" :placeholder="t('sys.login.inputCode')" v-model:value="formData.inputCode" />
</a-form-item>
<div class="aui-code">
<img v-if="randCodeData.requestCodeSuccess" :src="randCodeData.randCodeImage" @click="handleChangeCheckCode" />
<img v-else style="margin-top: 2px; max-width: initial" :src="codeImg" @click="handleChangeCheckCode" />
</div>
</div>
<div class="aui-flex">
<div class="aui-flex-box">
<div class="aui-choice">
<a-input class="fix-auto-fill" type="checkbox" v-model:value="rememberMe" />
<span style="margin-left: 5px">{{ t('sys.login.rememberMe') }}</span>
</div>
</div>
<div class="aui-forget">
<a @click="forgetHandelClick"> {{ t('sys.login.forgetPassword') }}</a>
</div>
</div>
</div>
</a-form>
<a-form v-else ref="phoneFormRef" :model="phoneFormData" @keyup.enter.native="loginHandleClick">
<div class="aui-account phone">
<div class="aui-inputClear phoneClear">
<a-input class="fix-auto-fill" :placeholder="t('sys.login.mobile')" v-model:value="phoneFormData.mobile" />
</div>
<div class="aui-inputClear">
<a-input class="fix-auto-fill" :maxlength="6" :placeholder="t('sys.login.smsCode')" v-model:value="phoneFormData.smscode" />
<div v-if="showInterval" class="aui-code" @click="getLoginCode">
<a>{{ t('component.countdown.normalText') }}</a>
</div>
<div v-else class="aui-code">
<span class="aui-get-code code-shape">{{ t('component.countdown.sendText', [unref(timeRuning)]) }}</span>
</div>
</div>
</div>
</a-form>
</div>
<div class="aui-formButton">
<div class="aui-flex">
<a-button :loading="loginLoading" class="aui-link-login" type="primary" @click="loginHandleClick">
{{ t('sys.login.loginButton') }}</a-button>
</div>
<div class="aui-flex">
<a class="aui-linek-code aui-flex-box" @click="codeHandleClick">{{ t('sys.login.qrSignInFormTitle') }}</a>
</div>
<div class="aui-flex">
<a class="aui-linek-code aui-flex-box" @click="registerHandleClick">{{ t('sys.login.registerButton') }}</a>
</div>
</div>
</div>
<a-form @keyup.enter.native="loginHandleClick">
<div class="aui-flex aui-third-text">
<div class="aui-flex-box aui-third-border">
<span>{{ t('sys.login.otherSignIn') }}</span>
</div>
</div>
<div class="aui-flex" :class="`${prefixCls}-sign-in-way`">
<div class="aui-flex-box">
<div class="aui-third-login">
<a title="github" @click="onThirdLogin('github')"><GithubFilled /></a>
</div>
</div>
<div class="aui-flex-box">
<div class="aui-third-login">
<a title="企业微信" @click="onThirdLogin('wechat_enterprise')"><icon-font class="item-icon" type="icon-qiyeweixin3" /></a>
</div>
</div>
<div class="aui-flex-box">
<div class="aui-third-login">
<a title="钉钉" @click="onThirdLogin('dingtalk')"><DingtalkCircleFilled /></a>
</div>
</div>
<div class="aui-flex-box">
<div class="aui-third-login">
<a title="微信" @click="onThirdLogin('wechat_open')"><WechatFilled /></a>
</div>
</div>
</div>
</a-form>
</div>
</div>
</div>
</div>
</div>
<div v-show="type === 'forgot'" :class="`${prefixCls}-form`">
<MiniForgotpad ref="forgotRef" @go-back="goBack" @success="handleSuccess" />
</div>
<div v-show="type === 'register'" :class="`${prefixCls}-form`">
<MiniRegister ref="registerRef" @go-back="goBack" @success="handleSuccess" />
</div>
<div v-show="type === 'codeLogin'" :class="`${prefixCls}-form`">
<MiniCodelogin ref="codeRef" @go-back="goBack" @success="handleSuccess" />
</div>
<!-- 第三方登录相关弹框 -->
<ThirdModal ref="thirdModalRef"></ThirdModal>
<!-- 图片验证码弹窗 -->
<CaptchaModal @register="captchaRegisterModal" @ok="getLoginCode" />
</div>
</template>
<script lang="ts" setup name="login-mini">
import { getCaptcha, getCodeInfo } from '/@/api/sys/user';
import { computed, onMounted, reactive, ref, toRaw, unref } from 'vue';
import codeImg from '/@/assets/images/checkcode.png';
import { Rule } from '/@/components/Form';
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
import { useI18n } from '/@/hooks/web/useI18n';
import { SmsEnum } from '/@/views/sys/login/useLogin';
import ThirdModal from '/@/views/sys/login/ThirdModal.vue';
import MiniForgotpad from './MiniForgotpad.vue';
import MiniRegister from './MiniRegister.vue';
import MiniCodelogin from './MiniCodelogin.vue';
import logoImg from '/@/assets/loginmini/icon/jeecg_logo.png';
import adTextImg from '/@/assets/loginmini/icon/jeecg_ad_text.png';
import { AppLocalePicker, AppDarkModeToggle } from '/@/components/Application';
import { useLocaleStore } from '/@/store/modules/locale';
import { useDesign } from "/@/hooks/web/useDesign";
import { useAppInject } from "/@/hooks/web/useAppInject";
import { GithubFilled, WechatFilled, DingtalkCircleFilled, createFromIconfontCN } from '@ant-design/icons-vue';
import CaptchaModal from '@/components/jeecg/captcha/CaptchaModal.vue';
import { useModal } from "@/components/Modal";
import { ExceptionEnum } from "@/enums/exceptionEnum";
import MiniLoginAd from "./MiniLoginAd.vue"
const IconFont = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/font_2316098_umqusozousr.js',
});
const { prefixCls } = useDesign('mini-login');
const { notification, createMessage } = useMessage();
const userStore = useUserStore();
const { t } = useI18n();
const localeStore = useLocaleStore();
const showLocale = localeStore.getShowPicker;
const randCodeData = reactive<any>({
randCodeImage: '',
requestCodeSuccess: false,
checkKey: null,
});
const rememberMe = ref<string>('0');
//手机号登录还是账号登录
const activeIndex = ref<string>('accountLogin');
const type = ref<string>('login');
//账号登录表单字段
const formData = reactive<any>({
});
//手机登录表单字段
const phoneFormData = reactive<any>({
mobile: '',
smscode: '',
});
const loginRef = ref();
//第三方登录弹窗
const thirdModalRef = ref();
//扫码登录
const codeRef = ref();
//是否显示获取验证码
const showInterval = ref<boolean>(true);
//60s
const timeRuning = ref<number>(60);
//定时器
const timer = ref<any>(null);
//忘记密码
const forgotRef = ref();
//注册
const registerRef = ref();
const loginLoading = ref<boolean>(false);
const { getIsMobile } = useAppInject();
const [captchaRegisterModal, { openModal: openCaptchaModal }] = useModal();
defineProps({
sessionTimeout: {
type: Boolean,
},
});
/**
* 获取验证码
*/
function handleChangeCheckCode() {
formData.inputCode = '';
//update-begin---author:chenrui ---date:2025/1/7 for:[QQYUN-10775]验证码可以复用 #7674------------
randCodeData.checkKey = new Date().getTime() + Math.random().toString(36).slice(-4); // 1629428467008;
//update-end---author:chenrui ---date:2025/1/7 for:[QQYUN-10775]验证码可以复用 #7674------------
getCodeInfo(randCodeData.checkKey).then((res) => {
randCodeData.randCodeImage = res;
randCodeData.requestCodeSuccess = true;
});
}
/**
* 切换登录方式
*/
function loginClick(type) {
activeIndex.value = type;
}
/**
* 账号或者手机登录
*/
async function loginHandleClick() {
if (unref(activeIndex) === 'accountLogin') {
accountLogin();
} else {
//手机号登录
phoneLogin();
}
}
async function accountLogin() {
if (!formData.username) {
createMessage.warn(t('sys.login.accountPlaceholder'));
return;
}
if (!formData.password) {
createMessage.warn(t('sys.login.passwordPlaceholder'));
return;
}
try {
loginLoading.value = true;
const { userInfo } = await userStore.login(
toRaw({
password: formData.password,
username: formData.username,
captcha: formData.inputCode,
checkKey: randCodeData.checkKey,
mode: 'none', //不要默认的错误提示
})
);
if (userInfo) {
notification.success({
message: t('sys.login.loginSuccessTitle'),
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realname}`,
duration: 3,
});
}
} catch (error) {
notification.error({
message: t('sys.api.errorTip'),
description: error.message || t('sys.login.networkExceptionMsg'),
duration: 3,
});
handleChangeCheckCode();
} finally {
loginLoading.value = false;
}
}
/**
* 手机号登录
*/
async function phoneLogin() {
if (!phoneFormData.mobile) {
createMessage.warn(t('sys.login.mobilePlaceholder'));
return;
}
if (!phoneFormData.smscode) {
createMessage.warn(t('sys.login.smsPlaceholder'));
return;
}
try {
loginLoading.value = true;
const { userInfo }: any = await userStore.phoneLogin({
mobile: phoneFormData.mobile,
captcha: phoneFormData.smscode,
mode: 'none', //不要默认的错误提示
});
if (userInfo) {
notification.success({
message: t('sys.login.loginSuccessTitle'),
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realname}`,
duration: 3,
});
}
} catch (error) {
notification.error({
message: t('sys.api.errorTip'),
description: error.message || t('sys.login.networkExceptionMsg'),
duration: 3,
});
} finally {
loginLoading.value = false;
}
}
/**
* 获取手机验证码
*/
async function getLoginCode() {
if (!phoneFormData.mobile) {
createMessage.warn(t('sys.login.mobilePlaceholder'));
return;
}
//update-begin---author:wangshuai---date:2024-04-18---for:【QQYUN-9005】同一个IP,1分钟超过5次短信,则提示需要验证码---
//update-begin---author:wangshuai---date:2025-07-15---for:【issues/8567】严重:修改密码存在水平越权问题:登录应该用登录模板不应该用忘记密码的模板---
const result = await getCaptcha({ mobile: phoneFormData.mobile, smsmode: SmsEnum.LOGIN }).catch((res) =>{
//update-end---author:wangshuai---date:2025-07-15---for:【issues/8567】严重:修改密码存在水平越权问题:登录应该用登录模板不应该用忘记密码的模板---
if(res.code === ExceptionEnum.PHONE_SMS_FAIL_CODE){
openCaptchaModal(true, {});
}
});
//update-end---author:wangshuai---date:2024-04-18---for:【QQYUN-9005】同一个IP,1分钟超过5次短信,则提示需要验证码---
if (result) {
const TIME_COUNT = 60;
if (!unref(timer)) {
timeRuning.value = TIME_COUNT;
showInterval.value = false;
timer.value = setInterval(() => {
if (unref(timeRuning) > 0 && unref(timeRuning) <= TIME_COUNT) {
timeRuning.value = timeRuning.value - 1;
} else {
showInterval.value = true;
clearInterval(unref(timer));
timer.value = null;
}
}, 1000);
}
}
}
/**
* 第三方登录
* @param type
*/
function onThirdLogin(type) {
thirdModalRef.value.onThirdLogin(type);
}
/**
* 忘记密码
*/
function forgetHandelClick() {
type.value = 'forgot';
setTimeout(() => {
forgotRef.value.initForm();
}, 300);
}
/**
* 返回登录页面
*/
function goBack() {
activeIndex.value = 'accountLogin';
type.value = 'login';
}
/**
* 忘记密码/注册账号回调事件
* @param value
*/
function handleSuccess(value) {
Object.assign(formData, value);
Object.assign(phoneFormData, { mobile: "", smscode: "" });
type.value = 'login';
activeIndex.value = 'accountLogin';
handleChangeCheckCode();
}
/**
* 注册
*/
function registerHandleClick() {
type.value = 'register';
setTimeout(() => {
registerRef.value.initForm();
}, 300);
}
/**
* 注册
*/
function codeHandleClick() {
type.value = 'codeLogin';
setTimeout(() => {
codeRef.value.initFrom();
}, 300);
}
onMounted(() => {
//加载验证码
handleChangeCheckCode();
});
</script>
<style lang="less" scoped>
@import '/@/assets/loginmini/style/home.less';
@import '/@/assets/loginmini/style/base.less';
:deep(.ant-input:focus) {
box-shadow: none;
}
.aui-get-code {
float: right;
position: relative;
z-index: 3;
background: #ffffff;
color: #1573e9;
border-radius: 100px;
padding: 5px 16px;
margin: 7px;
border: 1px solid #1573e9;
top: 12px;
}
.aui-get-code:hover {
color: #1573e9;
}
.code-shape {
border-color: #dadada !important;
color: #aaa !important;
}
:deep(.jeecg-dark-switch){
position:absolute;
margin-right: 10px;
}
.aui-link-login{
height: 42px;
padding: 10px 15px;
font-size: 14px;
border-radius: 8px;
margin-top: 15px;
margin-bottom: 8px;
flex: 1;
color: #fff;
}
.aui-phone-logo{
position: absolute;
margin-left: 10px;
width: 60px;
top:2px;
z-index: 4;
}
.top-3{
top: 0.45rem;
}
</style>
<style lang="less">
@prefix-cls: ~'@{namespace}-mini-login';
@dark-bg: #293146;
html[data-theme='dark'] {
.@{prefix-cls} {
background-color: @dark-bg !important;
background-image: none;
&::before {
background-image: url(/@/assets/svg/login-bg-dark.svg);
}
.aui-inputClear{
background-color: #232a3b !important;
}
.ant-input,
.ant-input-password {
background-color: #232a3b !important;
}
.ant-btn:not(.ant-btn-link):not(.ant-btn-primary) {
border: 1px solid #4a5569 !important;
}
&-form {
background: @dark-bg !important;
}
.app-iconify {
color: #fff !important;
}
.aui-inputClear input,.aui-input-line input,.aui-choice{
color: #c9d1d9 !important;
}
.aui-formBox{
background-color: @dark-bg !important;
}
.aui-third-text span{
background-color: @dark-bg !important;
}
.aui-form-nav .aui-flex-box{
color: #c9d1d9 !important;
}
.aui-formButton .aui-linek-code{
background: @dark-bg !important;
color: white !important;
}
.aui-code-line{
border-left: none !important;
}
.ant-checkbox-inner,.aui-success h3{
border-color: #c9d1d9;
}
//update-begin---author:wangshuai ---date:20230828 for:【QQYUN-6363】这个样式代码有问题,不在里面,导致表达式有问题------------
&-sign-in-way {
.anticon {
font-size: 22px !important;
color: #888 !important;
cursor: pointer !important;
&:hover {
color: @primary-color !important;
}
}
}
//update-end---author:wangshuai ---date:20230828 for:【QQYUN-6363】这个样式代码有问题,不在里面,导致表达式有问题------------
}
input.fix-auto-fill,
.fix-auto-fill input {
-webkit-text-fill-color: #c9d1d9 !important;
box-shadow: inherit !important;
}
.ant-divider-inner-text {
font-size: 12px !important;
color: @text-color-secondary !important;
}
.aui-third-login a{
background: transparent;
}
}
</style>
<template>
<div class="aui-image-text">
<!-- 图片容器 - 完全透明,水平居中,下边距50px -->
<div style="text-align: center; margin-bottom: 50px;">
<img src="../../../assets/loginmini/icon/logo.png" style="height: 160px; margin: 0 auto; opacity: 50;" />
</div>
<div class="company-logo">
<i class="fas fa-shield-alt"></i>
</div>
<div class="company-description">
金融科技风险管理平台,为西部矿业集团财务有限公司提供专业的风险分析、安全保障和智能风控平台。
</div>
<div class="feature-list">
<div class="feature-item">
<i class="fas fa-chart-line"></i>
<span>专业风险分析</span>
</div>
<div class="feature-item">
<i class="fas fa-lock"></i>
<span>安全保障体系</span>
</div>
<div class="feature-item">
<i class="fas fa-cogs"></i>
<span>智能风控平台</span>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
// 公司特色数据
const features = ref([
{ icon: 'chart-line', text: '专业风险分析' },
{ icon: 'lock', text: '安全保障体系' },
{ icon: 'cogs', text: '智能风控平台' }
]);
</script>
<style lang="less" scoped>
.aui-image-text {
// 完全透明,不添加任何背景或样式干扰
}
.company-logo {
font-size: 48px;
margin-bottom: 20px;
color: rgba(255, 255, 255, 0.9);
animation: pulse 2s infinite;
}
.company-title {
font-size: 28px;
font-weight: 700;
margin-bottom: 20px;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
letter-spacing: 1px;
}
.company-description {
font-size: 16px;
line-height: 1.6;
margin-bottom: 30px;
opacity: 0.95;
}
.feature-list {
display: flex;
justify-content: center;
gap: 30px;
flex-wrap: wrap;
}
.feature-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
transition: transform 0.3s ease;
&:hover {
transform: translateY(-5px);
}
i {
font-size: 24px;
background: rgba(255, 255, 255, 0.2);
width: 50px;
height: 50px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 5px;
}
span {
font-size: 14px;
font-weight: 500;
}
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
@keyframes float {
0%, 100% {
transform: translateY(0) rotate(0deg);
}
50% {
transform: translateY(-10px) rotate(180deg);
}
}
// 响应式设计
@media (max-width: 768px) {
.aui-image-text {
padding: 30px 20px;
margin: 20px;
}
.company-title {
font-size: 24px;
}
.company-description {
font-size: 15px;
}
.feature-list {
gap: 20px;
}
.feature-item {
i {
font-size: 20px;
width: 40px;
height: 40px;
}
span {
font-size: 13px;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="aui-content">
<div class="aui-container">
<div class="aui-form">
<div class="aui-image">
<div class="aui-image-text">
<img :src="jeecgAdTextImg" alt="" />
</div>
</div>
<div class="aui-formBox">
<div class="aui-formWell">
<a-form ref="formRef" :model="formData">
<div class="aui-flex aui-form-nav aui-clear-left" style="padding-bottom: 21px">
<div class="aui-flex-box activeNav on">{{t('sys.login.signUpFormTitle')}}</div>
</div>
<div class="aui-form-box">
<div class="aui-account aui-account-line">
<a-form-item>
<div class="aui-input-line">
<Icon class="aui-icon" icon="ant-design:user-outlined"/>
<a-input class="fix-auto-fill" type="text" :placeholder="t('sys.login.userName')" v-model:value="formData.username" />
</div>
</a-form-item>
<a-form-item>
<div class="aui-input-line">
<Icon class="aui-icon" icon="ant-design:mobile-outlined"/>
<a-input class="fix-auto-fill" type="text" :placeholder="t('sys.login.mobile')" v-model:value="formData.mobile" />
</div>
</a-form-item>
<a-form-item>
<div class="aui-input-line">
<Icon class="aui-icon" icon="ant-design:mail-outlined"/>
<a-input class="fix-auto-fill" type="text" :placeholder="t('sys.login.smsCode')" v-model:value="formData.smscode" />
<div v-if="showInterval" class="aui-code-line" @click="getLoginCode">{{t('component.countdown.normalText')}}</div>
<div v-else class="aui-code-line">{{t('component.countdown.sendText',[unref(timeRuning)])}}</div>
</div>
</a-form-item>
<a-form-item>
<div class="aui-input-line">
<Icon class="aui-icon" icon="ant-design:lock-outlined"/>
<a-input class="fix-auto-fill" :type="pwdIndex==='close'?'password':'text'" :placeholder="t('sys.login.password')" v-model:value="formData.password" />
<div class="aui-eye">
<img :src="eyeKImg" alt="开启" v-if="pwdIndex==='open'" @click="pwdClick('close')" />
<img :src="eyeGImg" alt="关闭" v-else-if="pwdIndex==='close'" @click="pwdClick('open')" />
</div>
</div>
</a-form-item>
<a-form-item>
<div class="aui-input-line">
<Icon class="aui-icon" icon="ant-design:lock-outlined"/>
<a-input class="fix-auto-fill" :type="confirmPwdIndex==='close'?'password':'text'" :placeholder="t('sys.login.confirmPassword')" v-model:value="formData.confirmPassword" />
<div class="aui-eye">
<img :src="eyeKImg" alt="开启" v-if="confirmPwdIndex==='open'" @click="confirmPwdClick('close')" />
<img :src="eyeGImg" alt="关闭" v-else-if="confirmPwdIndex==='close'" @click="confirmPwdClick('open')" />
</div>
</div>
</a-form-item>
<a-form-item name="policy">
<div class="aui-flex">
<div class="aui-flex-box">
<div class="aui-choice">
<a-checkbox v-model:checked="formData.policy" />
<span style="color: #1b90ff;margin-left: 4px">{{ t('sys.login.policy') }}</span>
</div>
</div>
</div>
</a-form-item>
</div>
</div>
<div class="aui-formButton">
<div class="aui-flex">
<a class="aui-link-login aui-flex-box" @click="registerHandleClick"> {{ t('sys.login.registerButton') }}</a>
</div>
<div class="aui-flex">
<a class="aui-linek-code aui-flex-box" @click="goBackHandleClick">{{ t('sys.login.backSignIn') }}</a>
</div>
</div>
</a-form>
</div>
</div>
</div>
</div>
</div>
<!-- 图片验证码弹窗 -->
<CaptchaModal @register="captchaRegisterModal" @ok="getLoginCode" />
</template>
<script lang="ts" setup name="mini-register">
import { ref, reactive, unref, toRaw } from 'vue';
import { getCaptcha, register } from '/@/api/sys/user';
import { SmsEnum } from '/@/views/sys/login/useLogin';
import { useMessage } from '/@/hooks/web/useMessage';
import logoImg from '/@/assets/loginmini/icon/jeecg_logo.png';
import jeecgAdTextImg from '/@/assets/loginmini/icon/jeecg_ad_text.png';
import eyeKImg from '/@/assets/loginmini/icon/icon-eye-k.png';
import eyeGImg from '/@/assets/loginmini/icon/icon-eye-g.png';
import { useI18n } from "/@/hooks/web/useI18n";
import CaptchaModal from '@/components/jeecg/captcha/CaptchaModal.vue';
import { useModal } from "@/components/Modal";
import { ExceptionEnum } from "@/enums/exceptionEnum";
const { t } = useI18n();
const { notification, createErrorModal, createMessage } = useMessage();
const emit = defineEmits(['go-back', 'success', 'register']);
const formRef = ref();
const formData = reactive<any>({
username: '',
mobile: '',
smscode: '',
password: '',
confirmPassword: '',
policy: false,
});
//是否显示获取验证码
const showInterval = ref<boolean>(true);
//60s
const timeRuning = ref<number>(60);
//定时器
const timer = ref<any>(null);
//密码眼睛打开关闭
const pwdIndex = ref<string>('close');
//确认密码眼睛打开关闭
const confirmPwdIndex = ref<string>('close');
const [captchaRegisterModal, { openModal: openCaptchaModal }] = useModal();
/**
* 返回
*/
function goBackHandleClick() {
emit('go-back');
initForm();
}
/**
* 获取手机验证码
*/
async function getLoginCode() {
if (!formData.mobile) {
createMessage.warn(t('sys.login.mobilePlaceholder'));
return;
}
//update-begin---author:wangshuai---date:2024-04-18---for:【QQYUN-9005】同一个IP,1分钟超过5次短信,则提示需要验证码---
const result = await getCaptcha({ mobile: formData.mobile, smsmode: SmsEnum.REGISTER }).catch((res) =>{
if(res.code === ExceptionEnum.PHONE_SMS_FAIL_CODE){
openCaptchaModal(true, {});
}
});
//update-end---author:wangshuai---date:2024-04-18---for:【QQYUN-9005】同一个IP,1分钟超过5次短信,则提示需要验证码---
if (result) {
const TIME_COUNT = 60;
if (!unref(timer)) {
timeRuning.value = TIME_COUNT;
showInterval.value = false;
timer.value = setInterval(() => {
if (unref(timeRuning) > 0 && unref(timeRuning) <= TIME_COUNT) {
timeRuning.value = timeRuning.value - 1;
} else {
showInterval.value = true;
clearInterval(unref(timer));
timer.value = null;
}
}, 1000);
}
}
}
function registerHandleClick() {
if (!formData.username) {
createMessage.warn(t('sys.login.accountPlaceholder'));
return;
}
if (!formData.mobile) {
createMessage.warn(t('sys.login.mobilePlaceholder'));
return;
}
if (!formData.smscode) {
createMessage.warn(t('sys.login.smsPlaceholder'));
return;
}
if (!formData.password) {
createMessage.warn(t('sys.login.passwordPlaceholder'));
return;
}
if (!formData.confirmPassword) {
createMessage.warn(t('sys.login.confirmPassword'));
return;
}
if (formData.password !== formData.confirmPassword) {
createMessage.warn(t('sys.login.diffPwd'));
return;
}
if(!formData.policy){
createMessage.warn(t('sys.login.policyPlaceholder'));
return;
}
registerAccount();
}
/**
* 注册账号
*/
async function registerAccount() {
try {
const resultInfo = await register(
toRaw({
username: formData.username,
password: formData.password,
phone: formData.mobile,
smscode: formData.smscode,
})
);
if (resultInfo && resultInfo.data.success) {
notification.success({
description: resultInfo.data.message || t('sys.api.registerMsg'),
duration: 3,
});
emit('success', { username: formData.username, password: formData.password });
initForm();
} else {
notification.warning({
message: t('sys.api.errorTip'),
description: resultInfo.data.message || t('sys.api.networkExceptionMsg'),
duration: 3,
});
}
} catch (error) {
notification.error({
message: t('sys.api.errorTip'),
description: error.message || t('sys.api.networkExceptionMsg'),
duration: 3,
});
}
}
/**
* 初始化表单
*/
function initForm() {
Object.assign(formData,{username:'',mobile: '', smscode: '', password: '', confirmPassword: '', policy: false})
if(!unref(timer)){
showInterval.value = true;
clearInterval(unref(timer));
timer.value = null;
}
formRef.value.resetFields();
}
/**
* 密码打开或关闭
* @param value
*/
function pwdClick(value) {
pwdIndex.value = value;
}
/**
* 确认密码打开或关闭
* @param value
*/
function confirmPwdClick(value) {
confirmPwdIndex.value = value;
}
defineExpose({
initForm
})
</script>
<style lang="less" scoped>
@import '/@/assets/loginmini/style/home.less';
@import '/@/assets/loginmini/style/base.less';
.aui-input-line .aui-icon{
position: absolute;
z-index: 2;
top: 10px;
left: 10px;
font-size: 20px !important;
}
</style>
<template>
<div> </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { isOAuth2AppEnv, sysOAuth2Callback, sysOAuth2Login } from '/@/views/sys/login/useLogin';
import { useRouter } from 'vue-router';
import { PageEnum } from '/@/enums/pageEnum';
import { router } from '/@/router';
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
import { useI18n } from '/@/hooks/web/useI18n';
import { getAuthCache, getTenantId, getToken } from "/@/utils/auth";
import { requestAuthCode } from 'dingtalk-jsapi';
import { defHttp } from '/@/utils/http/axios';
import { OAUTH2_THIRD_LOGIN_TENANT_ID } from "/@/enums/cacheEnum";
const isOAuth = ref<boolean>(isOAuth2AppEnv());
const env = ref<any>({ thirdApp: false, wxWork: false, dingtalk: false });
const { currentRoute } = useRouter();
const route = currentRoute.value;
if (!isOAuth2AppEnv()) {
router.replace({ path: PageEnum.BASE_LOGIN, query: route.query });
}
if (isOAuth.value) {
checkEnv();
}
/**
* 检测当前的环境
*/
function checkEnv() {
// 判断当时是否是企业微信环境
if (/wxwork/i.test(navigator.userAgent)) {
env.value.thirdApp = true;
env.value.wxWork = true;
}
// 判断当时是否是钉钉环境
if (/dingtalk/i.test(navigator.userAgent)) {
env.value.thirdApp = true;
env.value.dingtalk = true;
}
doOAuth2Login();
}
/**
* 进行OAuth2登录操作
*/
function doOAuth2Login() {
if (env.value.thirdApp) {
// 判断是否携带了Token,是就说明登录成功
if (route.query.oauth2LoginToken) {
let token = route.query.oauth2LoginToken;
//执行登录操作
thirdLogin({ token, thirdType: route.query.thirdType,tenantId: getTenantId });
} else if (env.value.wxWork) {
sysOAuth2Login('wechat_enterprise');
} else if (env.value.dingtalk) {
//新版钉钉登录
dingdingLogin();
}
}
}
/**
* 第三方登录
* @param params
*/
function thirdLogin(params) {
const userStore = useUserStore();
const { notification } = useMessage();
const { t } = useI18n();
userStore.ThirdLogin(params).then((res) => {
if (res && res.userInfo) {
notification.success({
message: t('sys.login.loginSuccessTitle'),
description: `${t('sys.login.loginSuccessDesc')}: ${res.userInfo.realname}`,
duration: 3,
});
} else {
notification.error({
message: t('sys.login.errorTip'),
description: ((res.response || {}).data || {}).message || res.message || t('sys.login.networkExceptionMsg'),
duration: 4,
});
}
});
}
/**
* 钉钉登录
*/
function dingdingLogin() {
//先获取钉钉的企业id,如果没有配置 还是走原来的逻辑,走原来的逻辑 需要判断存不存在token,存在token直接去首页
let tenantId = getAuthCache(OAUTH2_THIRD_LOGIN_TENANT_ID) || 0;
let url = `/sys/thirdLogin/get/corpId/clientId?tenantId=${tenantId}`;
//update-begin---author:wangshuai---date:2024-12-09---for:不要使用getAction online里面的,要用defHttp---
defHttp.get({ url:url },{ isTransformResponse: false }).then((res) => {
//update-end---author:wangshuai---date:2024-12-09---for:不要使用getAction online里面的,要用defHttp---
if (res.success) {
if(res.result && res.result.corpId && res.result.clientId){
requestAuthCode({ corpId: res.result.corpId, clientId: res.result.clientId }).then((res) => {
let { code } = res;
sysOAuth2Callback(code);
});
}else{
toOldAuthLogin();
}
} else {
toOldAuthLogin();
}
}).catch((err) => {
toOldAuthLogin();
});
}
/**
* 旧版钉钉登录
*/
function toOldAuthLogin() {
let token = getToken();
if (token) {
router.replace({ path: PageEnum.BASE_HOME });
} else {
sysOAuth2Login('dingtalk');
}
}
</script>
......@@ -262,19 +262,6 @@
queryParam.value.pageSize = pageSize;
onSearch();
}
function handlerGotoPage(item) {
if (item.sctype == '1') {
router.push({ path: '/standardlib/compliane/fl', query: { bizNo: item.bizNo, querName: queryParam.value.name } });
} else if (item.sctype == '2') {
router.push({ path: '/standardlib/compliane/fg', query: { bizNo: item.bizNo, querName: queryParam.value.name } });
} else if (item.sctype == '3') {
router.push({ path: '/standardlib/compliane/jg', query: { bizNo: item.bizNo, querName: queryParam.value.name } });
} else if (item.sctype == '4') {
router.push({ path: '/standardlib/compliane/fx', query: { bizNo: item.bizNo, querName: queryParam.value.name } });
} else if (item.sctype == '5') {
router.push({ path: '/standardlib/compliane/cf', query: { bizNo: item.bizNo, querName: queryParam.value.name } });
}
}
function handelCreateDocLib() {
loading.value = true;
......
......@@ -10,6 +10,7 @@
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="default" @click="updateAllNewValue" style="margin-left: 8px"> 获取指标最新值</a-button>
<!-- <a-tag v-if="dataList.length>=8" color="orange" style="padding:5px;margin-left:3px">
最多只能添加8条记录
</a-tag> -->
......@@ -34,7 +35,7 @@
import PageTitleconfigModal from './components/PageTitleconfigModal.vue'
import TplItemModal from './components/TplItemModal.vue'
import {columns, searchFormSchema} from './PageTitleconfig.data';
import {list, deleteOne, batchDelete, saveOrUpdate} from './PageTitleconfig.api';
import {list, deleteOne, batchDelete, saveOrUpdate,updateNewValue} from './PageTitleconfig.api';
import { JEllipsis } from '/@/components/Form';
const checkedKeys = ref<Array<string | number>>([]);
......@@ -78,7 +79,6 @@
const [registerTable, {reload,getDataSource},{ rowSelection, selectedRowKeys }] = tableContext
function handleAdd() {
openModal(true, {
isUpdate: false,
......@@ -111,7 +111,6 @@
}
async function handleDelete(record) {
await deleteOne({id: record.id}, handleSuccess);
}
......@@ -179,6 +178,14 @@
//handleSuccess()
}
/**
* 获取指标最新值
*/
async function updateAllNewValue() {
const result = await updateNewValue({});
handleSuccess()
}
</script>
<style scoped>
......
......@@ -14,6 +14,7 @@ enum Api {
queryFxcTplTree = '/page/pageTitleconfig/queryFxcTplTree',
pagetitleall = '/page/pageTitleconfig/pagetitleall',
updateAllNewValue = '/page/pageTitleconfig/updateAllNewValue',
}
/**
......@@ -80,3 +81,10 @@ export const pagetitleall = (params) =>
export const queryItemDtById = (params) =>
defHttp.get({url: Api.queryItemDtById, params});
export const updateNewValue = (params) =>
defHttp.get({url: Api.updateAllNewValue, params});
......@@ -29,6 +29,13 @@ export const columns: BasicColumn[] = [
edit: true,
dataIndex: 'showName',
},
{
title: '关联指标',
align: 'left',
width: 100,
edit: true,
dataIndex: 'tplItemName',
},
{
title: '值',
align: 'center',
......@@ -49,6 +56,7 @@ export const columns: BasicColumn[] = [
dataIndex: 'defaultIcon',
edit: true,
width: 80,
ifShow: false,
},
{
title: '分类',
......
......@@ -107,14 +107,36 @@
});
const curdata = ref({});
const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
const [registerTable, {reload, getForm},{ rowSelection, selectedRowKeys }] = tableContext
// 模态框配置
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
curdata.value = data.record;
// searchFormSchema[0].componentProps = {
// placeholder: '请输入模板名称',
// }
// searchFormSchema[1].componentProps = {
// placeholder: '请输入指标名称',
// }
// 重置表格
await reload();
// 设置模板名称到搜索表单
if (curdata.value.tplName) {
const form = getForm();
if (form) {
form.setFieldsValue(
{
tplName: curdata.value.tplName,
title: curdata.value.tplItemName||curdata.value.showName,
});
}
}
// 设置模态框属性
setModalProps({
confirmLoading: false,
......@@ -135,6 +157,7 @@
console.error('请选择指标');
return;
}
saveOrUpdate({
id: curdata.value.id,
tplItemId: tplItem.id,
......@@ -143,6 +166,7 @@
tplName:tplItem.tplName,
tplId:tplItem.tplid,
}, true);
emit('success');
}
......
......@@ -91,6 +91,14 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
proxy: createProxy(VITE_PROXY),
// 合并 server 配置
...serverOptions,
// 预热常用文件,提高首次加载速度
warmup: {
clientFiles: ['./index.html', './src/main.ts', './src/App.vue'],
},
// 启用更快的源文件变更检测
fs: {
strict: false,
},
},
build: {
minify: 'esbuild',
......@@ -160,24 +168,20 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
'dynamic-import': true,
'import-meta': true,
},
// 解决默认导出问题
//banner: 'import { createRequire } from "module"; const require = createRequire(import.meta.url);',
},
// 强制重新预构建,确保缓存是最新的
force: false, // 设置为 false,避免每次都重新预构建
exclude: [
//升级vite4后,需要排除online依赖
'@jeecg/online',
'@jeecg/aiflow',
],
// 明确包含可能需要预构建的依赖
// 只包含最核心的依赖,让 Vite 自动处理其他依赖
include: [
'vue',
'vue-router',
'pinia',
'ant-design-vue',
'@ant-design/icons-vue',
'moment',
'dayjs',
// 尝试包含 form-create
'@form-create/ant-design-vue'
]
},
};
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论