123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727 |
- <template>
- <div class="single-window-login">
- <div class="swl-head">
- <div class="swl-head-center">
- <a href="https://www.singlewindow.cn" target="_blank"><img src="./img/swLogo.png"></a>
- <div class="swl-head-lang">
- <div class="__hover" :class="{ active: config.lang === 'zh-cn' }" @click="configLang('zh-cn')">简体中文</div>
- <div>/</div>
- <div class="__hover" :class="{ active: config.lang === 'en' }" @click="configLang('en')">English</div>
- </div>
- </div>
- </div>
- <div class="swl-content">
- <div class="swl-content-login">
- <div class="swl-content-login-left"/>
- <div class="swl-content-login-right">
- <div class="swlclr-login">
- <div class="swlclr-login-div">
- <div class="swlclr-login-div-title">
- <div class="swlclr-login-div-title-1 __hover" :class="{active: loginMode === 'account'}" @click="loginMode = 'account'">{{ $t('login.signInTitle') }}</div>
- <template v-if="config.lang === 'zh-cn'">
- <div class="swlclr-login-div-title-line"/>
- <div class="swlclr-login-div-title-2 __hover" :class="{active: loginMode === 'card'}" @click="loginMode = 'card'">卡介质登录</div>
- </template>
- </div>
- <template v-if="loginMode === 'account'">
- <a-form class="login-form" ref="loginForm" :model="ruleForm" :rules="rules">
- <a-form-item name="account">
- <a-input
- v-model:value="ruleForm.account"
- :placeholder="$t('login.accountPlaceholder')"
- size="large"
- @keyup.enter="login"
- >
- <template #prefix>
- <UserOutlined class="login-icon-gray" />
- </template>
- <template #addonAfter v-if="config.lang === 'zh-cn'">
- <a class="__hover" href="https://app.singlewindow.cn/userserver/user/findusername/choseFindUserNameType" target="_blank">忘记用户名</a>
- </template>
- </a-input>
- </a-form-item>
- <a-form-item name="password">
- <a-input-password
- v-model:value="ruleForm.password"
- :placeholder="$t('login.PWPlaceholder')"
- size="large"
- autocomplete="off"
- @keyup.enter="login"
- >
- <template #prefix>
- <LockOutlined class="login-icon-gray" />
- </template>
- <template #addonAfter>
- <template v-if="config.lang === 'zh-cn'">
- <a class="__hover" href="https://app.singlewindow.cn/nuserwebserver/static/#/resetPwd?projectFlag=0" target="_blank">忘记密码</a>
- </template>
- <template v-else>
- <a class="__hover" href="https://app.singlewindow.cn/userserver/rest/userNra/find/findPWIndex" target="_blank">Forgot Password</a>
- </template>
- </template>
- </a-input-password>
- </a-form-item>
- <a-form-item name="validCode" v-if="captchaOpen === 'true'">
- <a-row :gutter="8">
- <a-col :span="17">
- <a-input
- v-model:value="ruleForm.validCode"
- :placeholder="$t('login.validLaceholder')"
- size="large"
- @keyup.enter="login"
- >
- <template #prefix>
- <verified-outlined class="login-icon-gray" />
- </template>
- </a-input>
- </a-col>
- <a-col :span="7">
- <img :src="validCodeBase64" class="login-validCode-img" @click="loginCaptcha" />
- </a-col>
- </a-row>
- </a-form-item>
- </a-form>
- </template>
- <template v-else-if="loginMode === 'card'">
- <a-form class="login-form" ref="cardForm" :model="cardRuleForm">
- <a-form-item name="password">
- <a-input-password
- v-model:value="cardRuleForm.password"
- placeholder="卡介质密码"
- size="large"
- autocomplete="off"
- @keyup.enter="cardLogin"
- >
- <template #prefix>
- <LockOutlined class="login-icon-gray" />
- </template>
- <template #addonAfter>
- <a class="__hover" href="https://www.singlewindow.cn/#/detail?breadNum=bc9&articleId=0000000000002256" target="_blank">忘记卡密码?</a>
- </template>
- </a-input-password>
- </a-form-item>
- </a-form>
- </template>
- <div class="agree" v-if="config.lang === 'zh-cn'">
- <a-checkbox v-model:checked="loginAgree"/>
- <span style="color:#222222">已阅读并同意</span>
- <span style="color: #096ac6;text-decoration:underline dotted; cursor:pointer;" @click="agreeTipsYhfwxy = true">《用户服务协议》</span>
- <span>和</span>
- <span style="color: #096ac6;text-decoration:underline dotted; cursor:pointer;" @click="agreeTipsYhyszc = true">《用户隐私政策》</span>
- </div>
- <a-button type="primary" class="w-full mt-4" style="background-color: #00599c;border-radius: 4px;" :loading="loading" round size="large" @click="loginMode === 'account' ? login() : cardLogin()">
- {{ $t('login.signIn') }}
- </a-button>
- <div class="card-tips" v-if="loginMode === 'card'">
- <div>请按照以下步骤进行:</div>
- <div><div class="index">1</div>请确认已下载并启动了 <a class="__hover" href="https://update.singlewindow.cn/downloads/EportClientSetup_V1.5.50.exe" target="_blank">客户端控件</a></div>
- <div><div class="index">2</div>插入中国电子口岸卡介质</div>
- <div><div class="index">3</div>输入卡介质密码</div>
- </div>
- <div class="tips">
- <template v-if="config.lang === 'zh-cn'">
- <template v-if="loginMode === 'account'">
- <div class="zhuce">卡介质丢失/损坏?<a class="__hover" href="https://app.singlewindow.cn/nuserwebserver/static/#/corp/accountActive?projectFlag=0" target="_blank">账号激活</a></div>
- </template>
- <template v-else-if="loginMode === 'card'">
- <div class="zhuce">卡介质有问题?<a class="__hover" href="https://www.singlewindow.cn/#/detail?breadNum=bc9&articleId=0000000000002287" target="_blank">制卡电话</a></div>
- </template>
- </template>
- <div class="zhuce">
- {{ $t('login.noAccount') }}
- <a class="__hover" :href="config.lang === 'zh-cn' ? 'https://app.singlewindow.cn/nuserwebserver/static/#/corp/accountActive?projectFlag=0' : 'https://app.singlewindow.cn/userserver/user/abroad/index'" target="_blank">{{ $t('login.registerAccount') }}</a></div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="swl-foot" v-if="config.lang === 'zh-cn'">
- <div class="swl-foot-main">
- <div class="swl-foot-main-left">
- <div class="swl-foot-main-left-top">
- <div class="swlfmlt-item __hover"><a class="textUnderline footer-nav-text" href="https://www.singlewindow.cn/#/aboutUs" target="_blank">关于我们</a></div>
- <div class="swlfmlt-split">|</div>
- <div class="swlfmlt-item __hover"><a class="textUnderline footer-nav-text" href="https://www.singlewindow.cn/#/sitemap" target="_blank">网站地图</a></div>
- <div class="swlfmlt-split">|</div>
- <a-popover>
- <template #content>
- <a class="textUnderline footer-nav-text" target="_blank" href="http://www.gov.cn/hudong/ducha/2021-01/26/content_5582430.htm">
- <img class="nav-img" src="./img/hlwjd.jpg" alt="互联网+督查">
- </a>
- </template>
- <div class="swlfmlt-item __hover"><a class="textUnderline footer-nav-text" target="_blank" href="http://www.gov.cn/hudong/ducha/2021-01/26/content_5582430.htm">互联网+督查</a></div>
- </a-popover>
- <div class="swlfmlt-split">|</div>
- <a-popover>
- <template #content>
- <img class="nav-img" src="./img/zwfw.jpg" alt="政务服务投诉">
- </template>
- <div class="swlfmlt-item __hover"><div class="swlfmlt-item __hover">政务服务投诉</div></div>
- </a-popover>
- </div>
- <div class="swl-foot-main-left-bottom">
- <div class="swlfmlb-item">主办单位:国家口岸管理办公室</div>
- <div class="swlfmlb-item">承办单位:中国电子口岸数据中心</div>
- <div class="swlfmlb-item">京ICP备12005222号-2</div>
- <div class="swlfmlb-item"><a target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11011302001653">京公网安备11011302001653号</a></div>
- </div>
- </div>
- <div class="swl-foot-main-right">
- <div class="footer-code">
- <div class="footer-code-top">
- <a-popover>
- <template #content>
- <div style="display: flex;flex-direction: column;">
- <img class="code-img" src="./img/wechat-cl.jpg" alt="">
- <span style="font-size: 12px;color: #333;line-height: 24px; text-align: center;">关注微信公众号</span>
- </div>
- </template>
- <div class="wct-wechat"/>
- </a-popover>
- <a-popover>
- <template #content>
- <div style="display: flex;flex-direction: column;">
- <img class="code-img" src="./img/weibo-cl.jpg" alt="">
- <span style="font-size: 12px;color: #333;line-height: 24px; text-align: center;">关注微博</span>
- </div>
- </template>
- <div class="wct-weibo"></div>
- </a-popover>
- </div>
- <div class="footer-code-bottom">
- <div class="fcb-phone"/>服务热线:<span>95198</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <a-modal
- v-model:open="agreeTipsYhfwxy"
- title="用户服务协议"
- centered
- width="730px"
- @ok="agreeTipsYhfwxy = false, loginAgree = true"
- >
- <iframe src="https://app.singlewindow.cn/userserver/user/document/nraServiceAgreement" style="width: 100%; height: 530px;"/>
- </a-modal>
- <a-modal
- v-model:open="agreeTipsYhyszc"
- title="用户隐私政策"
- centered
- width="730px"
- @ok="agreeTipsYhyszc = false, loginAgree = true"
- >
- <iframe src="https://app.singlewindow.cn/userserver/user/document/nraPrivacyPolicy" style="width: 100%; height: 530px;"/>
- </a-modal>
- </div>
- </template>
- <script setup>
- import loginApi from '@/api/auth/loginApi'
- import smCrypto from '@/utils/smCrypto'
- import { required } from '@/utils/formRules'
- import { afterLogin } from './util'
- import configData from '@/config'
- import configApi from '@/api/dev/configApi'
- import tool from '@/utils/tool'
- import { globalStore, iframeStore, keepAliveStore, viewTagsStore } from '@/store'
- import {message, Modal} from "ant-design-vue";
- import {createVNode} from "vue";
- import {ExclamationCircleOutlined} from "@ant-design/icons-vue";
- import router from "@/router";
- const { proxy } = getCurrentInstance()
- const activeKey = ref('userAccount')
- const captchaOpen = ref(configData.SYS_BASE_CONFIG.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN)
- const validCodeBase64 = ref('')
- const loading = ref(false)
- const loginAgree = ref(false)
- const agreeTipsYhfwxy = ref(false)
- const agreeTipsYhyszc = ref(false)
- const loginMode = ref('account')
- const ruleForm = reactive({
- account: '', // superAdmin
- password: '', // 123456
- validCode: '',
- validCodeReqNo: '',
- autologin: false
- })
- const cardRuleForm = reactive({
- password: '',
- })
- const rules = reactive({
- account: [required(proxy.$t('login.accountError'), 'blur')],
- password: [required(proxy.$t('login.PWError'), 'blur')]
- })
- const lang = ref([
- {
- name: '简体中文',
- value: 'zh-cn'
- },
- {
- name: 'English',
- value: 'en'
- }
- ])
- const config = ref({
- lang: tool.data.get('APP_LANG') || proxy.$CONFIG.LANG,
- theme: tool.data.get('APP_THEME') || 'default'
- })
- const store = globalStore()
- const kStore = keepAliveStore()
- const iStore = iframeStore()
- const vStore = viewTagsStore()
- const setSysBaseConfig = store.setSysBaseConfig
- const clearKeepLive = kStore.clearKeepLive
- const clearIframeList = iStore.clearIframeList
- const clearViewTags = vStore.clearViewTags
- const sysBaseConfig = computed(() => {
- return store.sysBaseConfig
- })
- onMounted(() => {
- let formData = ref(configData.SYS_BASE_CONFIG)
- configApi.configSysBaseList().then((data) => {
- if (data) {
- data.forEach((item) => {
- formData.value[item.configKey] = item.configValue
- })
- captchaOpen.value = formData.value.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN
- tool.data.set('SNOWY_SYS_BASE_CONFIG', formData.value)
- setSysBaseConfig(formData.value)
- refreshSwitch()
- }
- })
- })
- onBeforeMount(() => {
- clearViewTags()
- clearKeepLive()
- clearIframeList()
- })
- // 监听语言
- watch(
- () => config.value.lang,
- (newValue) => {
- proxy.$i18n.locale = newValue
- tool.data.set('APP_LANG', newValue)
- }
- )
- // 主题
- watch(
- () => config.value.theme,
- (newValue) => {
- document.body.setAttribute('data-theme', newValue)
- }
- )
- // 通过开关加载内容
- const refreshSwitch = () => {
- // 判断是否开启验证码
- if (captchaOpen.value === 'true') {
- // 加载验证码
- loginCaptcha()
- // 加入校验
- rules.validCode = [required(proxy.$t('login.validError'), 'blur')]
- }
- }
- // 获取验证码
- const loginCaptcha = () => {
- loginApi.getPicCaptcha().then((data) => {
- validCodeBase64.value = data.validCodeBase64
- ruleForm.validCodeReqNo = data.validCodeReqNo
- })
- }
- //登陆
- const loginForm = ref()
- const cardForm = ref()
- const login = async () => {
- if (loginAgree.value || config.value.lang === 'en') {
- loginForm.value
- .validate()
- .then(async () => {
- loading.value = true
- const loginData = {
- account: ruleForm.account,
- // 密码进行SM2加密,传输过程中看到的只有密文,后端存储使用hash
- password: smCrypto.doSm2Encrypt(ruleForm.password),
- validCode: ruleForm.validCode,
- validCodeReqNo: ruleForm.validCodeReqNo
- }
- // 获取token
- try {
- const loginToken = await loginApi.login(loginData)
- const loginAfter = afterLogin(loginToken)
- } catch (err) {
- loading.value = false
- loginCaptcha()
- }
- })
- .catch(() => {})
- } else {
- Modal.confirm({
- title: '提示',
- content: '请阅读并勾选《用户服务协议》和《用户隐私政策》!',
- centered: true,
- width: 420,
- icon: createVNode(ExclamationCircleOutlined),
- maskClosable: false,
- onOk() {},
- onCancel() {}
- })
- }
- }
- const cardLogin = async () => {
- if (loginAgree.value) {
- if (!cardRuleForm.password) {
- alert('IC卡/Key密码不允许为空')
- } else {
- loading.value = true
- const loginData = {
- account: 'yqyc',
- // 密码进行SM2加密,传输过程中看到的只有密文,后端存储使用hash
- password: smCrypto.doSm2Encrypt(cardRuleForm.password),
- validCode: 'szzf',
- validCodeReqNo: 'szzf'
- }
- // 获取token
- try {
- const loginToken = await loginApi.login(loginData)
- const loginAfter = afterLogin(loginToken)
- } catch (err) {
- loading.value = false
- // loginCaptcha()
- }
- }
- } else {
- Modal.confirm({
- title: '提示',
- content: '请阅读并勾选《用户服务协议》和《用户隐私政策》!',
- centered: true,
- width: 420,
- icon: createVNode(ExclamationCircleOutlined),
- maskClosable: false,
- onOk() {},
- onCancel() {}
- })
- }
- }
- const configLang = (key) => {
- config.value.lang = key
- loginMode.value = 'account'
- }
- </script>
- <style lang="less" scoped>
- .single-window-login {
- display: flex;
- flex-direction: column;
- width: 100%;
- height: 100%;
- .swl-head {
- background-color: #ffffff;
- min-width: 1200px;
- height: 90px;
- line-height: 90px;
- display: flex;
- .swl-head-center {
- width: 1200px;
- display: flex;
- align-items: center;
- margin: 0 auto;
- .swl-head-lang {
- margin-left: auto;
- display: flex;
- align-items: center;
- gap: 10px;
- color: #00599C;
- font-size: 15px;
- &:nth-child(2) {
- font-size: 12px;
- color: #00599C;
- }
- .active {
- color: #00599C;
- font-weight: bold;
- font-size: 16px;
- }
- }
- }
- }
- .swl-content {
- flex: 1;
- background-image: url('./img/icon_bgNew.png');
- background-repeat: no-repeat;
- background-size: 100% 100%;
- .swl-content-login {
- height: 659px;
- max-width: 1200px;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- margin: 0 auto;
- .swl-content-login-left {
- width: 553px;
- height: 478px;
- background-image: url('./img/leftimg_04.png');
- background-repeat: no-repeat;
- background-position: center;
- }
- .swl-content-login-right {
- width: 600px;
- height: 478px;
- .swlclr-login {
- width: 412px;
- height: auto;
- background-color: #FFFFFF;
- border: solid #ccc 0px;
- border-radius: 8px;
- margin: 0px auto;
- color: #666666;
- padding-bottom: 12px;
- .swlclr-login-div {
- width: 410px;
- height: 420px;
- background: #ffffff;
- border-radius: 10px;
- margin: 20px auto;
- padding: 26px 41px 0 39px;
- box-sizing: border-box;
- position: relative;
- .swlclr-login-div-title {
- font-weight: 400;
- color: #999999;
- font-size: 18px;
- margin-top: 18px;
- margin-bottom: 28px;
- text-align: center;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 20px;
- .swlclr-login-div-title-line {
- width: 1px;
- height: 16px;
- background-color: #c4c4c4;
- }
- .active {
- color: #00599c;
- font-weight: 700;
- }
- }
- :deep(.login-form) {
- .ant-form-item-control-input-content {
- border-bottom: 1px solid #e5e5e5;
- .ant-input-affix-wrapper {
- border: none;
- box-shadow: none;
- }
- .ant-input-group-addon {
- background-color: transparent;
- border: none;
- color: #096AC6;
- font-size: 13px;
- font-weight: 400;
- }
- }
- }
- .agree {
- font-size: 12px;
- }
- .card-tips {
- margin-top: 12px;
- width: 330px;
- height: 120px;
- background: rgba(222, 235, 247, 0.60);
- border-radius: 3px;
- padding-left: 20px;
- padding-top: 12px;
- cursor: default;
- font-size: 13px;
- color: #333333;
- line-height: 25px;
- >div {
- display: flex;
- align-items: center;
- .index {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 15px;
- height: 15px;
- border-radius: 50%;
- color: #ffffff;
- line-height: 15px;
- margin-right: 8px;
- background-color: #00599C;
- font-size: 12px;
- }
- >a {
- color: #096AC6;
- font-weight: 700;
- }
- }
- }
- .tips {
- margin-top: 40px;
- width: 100%;
- display: flex;
- .zhuce {
- font-size: 13px;
- color: #999999;
- >a {
- color: #096AC6;
- font-weight: 700;
- }
- &:last-child {
- margin-left: auto;
- }
- }
- }
- }
- }
- }
- }
- }
- .swl-foot {
- width: 100%;
- height: 170px;
- background-color: rgba(230, 230, 230, 1);
- display: flex;
- .swl-foot-main {
- width: 1200px;
- margin: 0 auto;
- display: flex;
- justify-content: space-between;
- .swl-foot-main-left {
- .swl-foot-main-left-top {
- display: flex;
- gap: 15px;
- margin-top: 30px;
- line-height: 40px;
- .swlfmlt-item {
- display: flex;
- align-items: center;
- line-height: 40px;
- font-weight: 400;
- font-style: normal;
- font-size: 16px;
- color: #0C3D65;
- >a {
- color: #0C3D65;
- text-decoration: none;
- &:hover {
- text-decoration: underline;
- }
- }
- }
- .swlfmlt-split {
- color: #bbbbbb;
- }
- }
- .swl-foot-main-left-bottom {
- margin-top: 10px;
- display: grid;
- grid-template-columns: repeat(2, 220px);
- column-gap: 8px;
- .swlfmlb-item {
- display: block;
- line-height: 26px;
- color: #666;
- font-size: 14px;
- >a {
- color: #666;
- text-decoration: none;
- &:hover {
- text-decoration: underline;
- }
- }
- }
- }
- }
- .swl-foot-main-right {
- .footer-code {
- margin-top: 42px;
- .footer-code-top {
- display: flex;
- justify-content: flex-end;
- gap: 18px;
- .wct-wechat {
- width: 40px;
- height: 40px;
- background: #9eaebb;
- line-height: 40px;
- border-radius: 50%;
- cursor: pointer;
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- &:after {
- position: absolute;
- content: '';
- background-image: url('./img/bg.png');
- width: 30px;
- height: 26px;
- background-position: -49px -83px;
- transform: scale(.8);
- }
- }
- .wct-weibo {
- width: 40px;
- height: 40px;
- background: #9eaebb;
- line-height: 40px;
- border-radius: 50%;
- cursor: pointer;
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- &:after {
- position: absolute;
- content: '';
- background-image: url('./img/bg.png');
- width: 32px;
- height: 25px;
- background-position: -3px -83px;
- transform: scale(.8);
- }
- }
- }
- .footer-code-bottom {
- display: flex;
- align-items: center;
- margin-top: 10px;
- font-weight: 700;
- font-size: 20px;
- color: #0C3D65;
- vertical-align: top;
- height: 34px;
- line-height: 34px;
- .fcb-phone {
- background-image: url('./img/bg.png');
- width: 34px;
- height: 34px;
- background-position: -1px -364px;
- margin-right: 12px;
- margin-top: -2px;
- transform: scale(.8);
- }
- >span {
- font-size: 24px;
- }
- }
- }
- }
- }
- }
- }
- </style>
|