forked from github/dataease
Merge pull request #3038 from dataease/pr@dev@perf_wecom
perf(系统管理-系统参数): 优化企业微信设置
This commit is contained in:
commit
80fb7b5666
@ -62,6 +62,11 @@ public interface AuthApi {
|
||||
@PostMapping("/isOpenCas")
|
||||
boolean isOpenCas();
|
||||
|
||||
|
||||
@ApiOperation("是否开启企业微信")
|
||||
@PostMapping("/isOpenWecom")
|
||||
boolean isOpenWecom();
|
||||
|
||||
@ApiIgnore
|
||||
@PostMapping("/isPluginLoaded")
|
||||
boolean isPluginLoaded();
|
||||
|
@ -282,11 +282,19 @@ public class AuthServer implements AuthApi {
|
||||
Boolean licValid = PluginUtils.licValid();
|
||||
if (!licValid)
|
||||
return false;
|
||||
Boolean supportCas = authUserService.supportCas();
|
||||
|
||||
return authUserService.supportCas();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpenWecom() {
|
||||
Boolean licValid = PluginUtils.licValid();
|
||||
if (!licValid)
|
||||
return false;
|
||||
|
||||
return authUserService.supportWecom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPluginLoaded() {
|
||||
Boolean licValid = PluginUtils.licValid();
|
||||
|
@ -16,7 +16,7 @@ public interface AuthUserService {
|
||||
|
||||
SysUserEntity getCasUserByName(String username);
|
||||
|
||||
SysUserEntity getUserBySub(String sub);
|
||||
SysUserEntity getUserBySub(String sub, Integer from);
|
||||
|
||||
List<String> roles(Long userId);
|
||||
|
||||
@ -32,6 +32,8 @@ public interface AuthUserService {
|
||||
|
||||
Boolean supportCas();
|
||||
|
||||
Boolean supportWecom();
|
||||
|
||||
Boolean pluginLoaded();
|
||||
|
||||
void checkAdmin(String uname, String pwd);
|
||||
|
@ -18,6 +18,7 @@ import io.dataease.plugins.xpack.cas.service.CasXpackService;
|
||||
import io.dataease.plugins.xpack.ldap.service.LdapXpackService;
|
||||
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
|
||||
|
||||
import io.dataease.plugins.xpack.wecom.service.WecomXpackService;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
@ -76,8 +77,8 @@ public class AuthUserServiceImpl implements AuthUserService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysUserEntity getUserBySub(String sub) {
|
||||
return authMapper.findUserBySub(sub);
|
||||
public SysUserEntity getUserBySub(String sub, Integer from) {
|
||||
return authMapper.findUserBySub(sub, from);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -166,6 +167,15 @@ public class AuthUserServiceImpl implements AuthUserService {
|
||||
return casXpackService.suuportCas();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean supportWecom() {
|
||||
Map<String, WecomXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((WecomXpackService.class));
|
||||
if (beansOfType.keySet().size() == 0) return false;
|
||||
WecomXpackService wecomXpackService = SpringContextUtil.getBean(WecomXpackService.class);
|
||||
if (ObjectUtils.isEmpty(wecomXpackService)) return false;
|
||||
return wecomXpackService.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean pluginLoaded() {
|
||||
Map<String, PluginCommonService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((PluginCommonService.class));
|
||||
|
@ -81,12 +81,17 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
filterChainDefinitionMap.put("/api/auth/validateName", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/isOpenLdap", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/isOpenOidc", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/isOpenWecom", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/isOpenDingtalk", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/isOpenLark", ANON);
|
||||
filterChainDefinitionMap.put("/api/auth/getPublicKey", ANON);
|
||||
filterChainDefinitionMap.put("/api/pluginCommon/component/*", ANON);
|
||||
filterChainDefinitionMap.put("/api/pluginCommon/staticInfo/**", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/oidc/authInfo", ANON);
|
||||
filterChainDefinitionMap.put("/sso/callBack*", ANON);
|
||||
filterChainDefinitionMap.put("/cas/callBack*", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/wecom/callBack*", ANON);
|
||||
filterChainDefinitionMap.put("/plugin/wecom/getQrParam", ANON);
|
||||
filterChainDefinitionMap.put("/cas/reset/**", ANON);
|
||||
|
||||
filterChainDefinitionMap.put("/unauth", ANON);
|
||||
|
@ -29,7 +29,7 @@ public interface AuthMapper {
|
||||
|
||||
SysUserEntity findCasUserByName(@Param("username") String username);
|
||||
|
||||
SysUserEntity findUserBySub(@Param("sub") String sub);
|
||||
SysUserEntity findUserBySub(@Param("sub") String sub, @Param("userFrom") Integer userFrom);
|
||||
|
||||
|
||||
List<CurrentRoleDto> roles(@Param("userId") Long userId);
|
||||
|
@ -55,7 +55,7 @@
|
||||
</select>
|
||||
|
||||
<select id="findUserBySub" resultMap="baseMap">
|
||||
select user_id, username,nick_name, dept_id, password, enabled,email, phone, language ,is_admin, `from` from sys_user where sub = #{sub}
|
||||
select user_id, username,nick_name, dept_id, password, enabled,email, phone, language ,is_admin, `from` from sys_user where sub = #{sub} and `from` = #{userFrom}
|
||||
</select>
|
||||
|
||||
<select id="roleCodes" resultType="String">
|
||||
|
@ -71,11 +71,11 @@ public class SSOServer {
|
||||
SSOUserInfo ssoUserInfo = oidcXpackService.requestUserInfo(config, ssoToken.getAccessToken());
|
||||
|
||||
|
||||
SysUserEntity sysUserEntity = authUserService.getUserBySub(ssoUserInfo.getSub());
|
||||
SysUserEntity sysUserEntity = authUserService.getUserBySub(ssoUserInfo.getSub(), 2);
|
||||
if (null == sysUserEntity) {
|
||||
sysUserService.validateExistUser(ssoUserInfo.getUsername(), ssoUserInfo.getNickName(), ssoUserInfo.getEmail());
|
||||
sysUserService.saveOIDCUser(ssoUserInfo);
|
||||
sysUserEntity = authUserService.getUserBySub(ssoUserInfo.getSub());
|
||||
sysUserEntity = authUserService.getUserBySub(ssoUserInfo.getSub(), 2);
|
||||
}
|
||||
TokenInfo tokenInfo = TokenInfo.builder().userId(sysUserEntity.getUserId()).username(sysUserEntity.getUsername()).build();
|
||||
String realPwd = sysUserEntity.getPassword();
|
||||
|
@ -1,34 +1,62 @@
|
||||
package io.dataease.plugins.server;
|
||||
|
||||
|
||||
import io.dataease.auth.entity.SysUserEntity;
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import io.dataease.auth.service.AuthUserService;
|
||||
import io.dataease.auth.util.JWTUtils;
|
||||
import io.dataease.commons.constants.SysLogConstants;
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.utils.DeLogUtils;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.commons.utils.ServletUtils;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.xpack.display.dto.response.SysSettingDto;
|
||||
|
||||
import io.dataease.plugins.xpack.wecom.dto.entity.BaseQrResult;
|
||||
import io.dataease.plugins.xpack.wecom.dto.entity.WecomAuthResult;
|
||||
import io.dataease.plugins.xpack.wecom.dto.response.WecomInfo;
|
||||
import io.dataease.plugins.xpack.wecom.service.WecomXpackService;
|
||||
import io.dataease.service.sys.SysUserService;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ApiIgnore
|
||||
@RequestMapping("/plugin/wecom")
|
||||
@RestController
|
||||
@Controller
|
||||
public class XWecomServer {
|
||||
|
||||
@Resource
|
||||
private AuthUserService authUserService;
|
||||
@Resource
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/info")
|
||||
public WecomInfo getWecomInfo() {
|
||||
WecomXpackService wecomXpackService = SpringContextUtil.getBean(WecomXpackService.class);
|
||||
return wecomXpackService.info();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequiresPermissions("sysparam:read")
|
||||
@PostMapping("/save")
|
||||
public void save(@RequestBody List<SysSettingDto> settings) {
|
||||
WecomXpackService wecomXpackService = SpringContextUtil.getBean(WecomXpackService.class);
|
||||
wecomXpackService.save(settings);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/testConn")
|
||||
public void testConn(@RequestBody WecomInfo wecomInfo) {
|
||||
WecomXpackService wecomXpackService = SpringContextUtil.getBean(WecomXpackService.class);
|
||||
@ -38,4 +66,73 @@ public class XWecomServer {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@ResponseBody
|
||||
@PostMapping("/getQrParam")
|
||||
public BaseQrResult getQrParam() {
|
||||
WecomXpackService wecomXpackService = SpringContextUtil.getBean(WecomXpackService.class);
|
||||
return wecomXpackService.getQrParam();
|
||||
}
|
||||
|
||||
@GetMapping("/callBack")
|
||||
public ModelAndView callBack(@RequestParam("code") String code, @RequestParam("state") String state) {
|
||||
ModelAndView modelAndView = new ModelAndView("redirect:/");
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
WecomXpackService wecomXpackService = null;
|
||||
String idToken = null;
|
||||
try {
|
||||
Map<String, WecomXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((WecomXpackService.class));
|
||||
if (beansOfType.keySet().size() == 0) {
|
||||
DEException.throwException("缺少企业微信插件");
|
||||
}
|
||||
wecomXpackService = SpringContextUtil.getBean(WecomXpackService.class);
|
||||
Boolean isOpen = wecomXpackService.isOpen();
|
||||
if (!isOpen) {
|
||||
DEException.throwException("未开启企业微信");
|
||||
}
|
||||
WecomAuthResult authResult = wecomXpackService.auth(code);
|
||||
|
||||
String userId = authResult.getUserId();
|
||||
Map<String, Object> userMap = wecomXpackService.userInfo(userId);
|
||||
|
||||
SysUserEntity sysUserEntity = authUserService.getUserBySub(userId, 4);
|
||||
if (null == sysUserEntity) {
|
||||
Object emailObj = ObjectUtils.isEmpty(userMap.get("biz_mail")) ? userMap.get("email") : userMap.get("biz_mail");
|
||||
String email = ObjectUtils.isEmpty(emailObj) ? "demo@wecom.work" : emailObj.toString();
|
||||
sysUserService.validateExistUser(userId, userMap.get("name").toString(), email);
|
||||
sysUserService.saveWecomCUser(userMap, userId, email);
|
||||
sysUserEntity = authUserService.getUserBySub(userId, 4);
|
||||
}
|
||||
TokenInfo tokenInfo = TokenInfo.builder().userId(sysUserEntity.getUserId()).username(sysUserEntity.getUsername()).build();
|
||||
String realPwd = sysUserEntity.getPassword();
|
||||
String token = JWTUtils.sign(tokenInfo, realPwd);
|
||||
ServletUtils.setToken(token);
|
||||
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.LOGIN, SysLogConstants.SOURCE_TYPE.USER, sysUserEntity.getUserId(), null, null, null);
|
||||
|
||||
Cookie cookie_token = new Cookie("Authorization", token);
|
||||
cookie_token.setPath("/");
|
||||
|
||||
response.addCookie(cookie_token);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
String msg = e.getMessage();
|
||||
if (null != e.getCause()) {
|
||||
msg = e.getCause().getMessage();
|
||||
}
|
||||
try {
|
||||
msg = URLEncoder.encode(msg, "UTF-8");
|
||||
LogUtil.error(e);
|
||||
Cookie cookie_error = new Cookie("OidcError", msg);
|
||||
cookie_error.setPath("/");
|
||||
|
||||
return modelAndView;
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return modelAndView;
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import javax.annotation.Resource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@ -126,6 +127,34 @@ public class SysUserService {
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void saveWecomCUser(Map<String, Object> userMap , String userId, String email) {
|
||||
long now = System.currentTimeMillis();
|
||||
SysUser sysUser = new SysUser();
|
||||
|
||||
sysUser.setUsername(userId);
|
||||
sysUser.setNickName(userMap.get("name").toString());
|
||||
sysUser.setEmail(email);
|
||||
sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD));
|
||||
sysUser.setCreateTime(now);
|
||||
sysUser.setUpdateTime(now);
|
||||
|
||||
sysUser.setEnabled((ObjectUtils.isNotEmpty(userMap.get("status")) && 1 == Integer.parseInt(userMap.get("status").toString())) ? 1L : 0L);
|
||||
sysUser.setGender((ObjectUtils.isEmpty(userMap.get("gender")) || "1".equals(userMap.get("gender"))) ? "男" : "女");
|
||||
sysUser.setLanguage("zh_CN");
|
||||
sysUser.setFrom(4);
|
||||
sysUser.setIsAdmin(false);
|
||||
sysUser.setSub(userId);
|
||||
sysUserMapper.insert(sysUser);
|
||||
SysUser dbUser = findOne(sysUser);
|
||||
if (null != dbUser && null != dbUser.getUserId()) {
|
||||
// 默认角色是普通员工
|
||||
List<Long> roleIds = new ArrayList<Long>();
|
||||
roleIds.add(2L);
|
||||
saveUserRoles( dbUser.getUserId(), roleIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void saveCASUser(String name, String email) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
8
backend/src/main/resources/db/migration/V40__1.15.sql
Normal file
8
backend/src/main/resources/db/migration/V40__1.15.sql
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
DROP TABLE IF EXISTS `sys_external_token`;
|
||||
CREATE TABLE `sys_external_token` (
|
||||
`type` int(4) NOT NULL COMMENT '类型ID',
|
||||
`token` varchar(255) NOT NULL COMMENT 'token',
|
||||
`exp_time` bigint(13) NOT NULL COMMENT '过期时间',
|
||||
PRIMARY KEY (`type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
@ -100,6 +100,13 @@ export function casStatus() {
|
||||
})
|
||||
}
|
||||
|
||||
export function wecomStatus() {
|
||||
return request({
|
||||
url: '/api/auth/isOpenWecom',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function pluginLoaded() {
|
||||
return request({
|
||||
url: '/api/auth/isPluginLoaded',
|
||||
|
BIN
frontend/src/assets/dingding01.png
Normal file
BIN
frontend/src/assets/dingding01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
BIN
frontend/src/assets/fark.png
Normal file
BIN
frontend/src/assets/fark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
BIN
frontend/src/assets/qrcode.png
Normal file
BIN
frontend/src/assets/qrcode.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
frontend/src/assets/wecom.png
Normal file
BIN
frontend/src/assets/wecom.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
@ -1,10 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<div v-show="contentShow" class="login-background">
|
||||
|
||||
<div class="login-container">
|
||||
<el-row v-loading="loading" type="flex">
|
||||
<el-col :span="12">
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" size="default">
|
||||
<div v-show="qrTypes.length" class="trans" @click="showQr">
|
||||
<div v-show="imgAppShow" class="imgApp" />
|
||||
</div>
|
||||
<el-form v-show="!codeShow" ref="loginForm" :model="loginForm" :rules="loginRules" size="default">
|
||||
|
||||
<div class="login-logo">
|
||||
<svg-icon v-if="!loginLogoUrl && axiosFinished" icon-class="DataEase" custom-class="login-logo-icon" />
|
||||
<img v-if="loginLogoUrl && axiosFinished" :src="loginLogoUrl" alt="">
|
||||
@ -16,8 +22,8 @@
|
||||
{{ $t('login.welcome') + (uiInfo && uiInfo['ui.title'] && uiInfo['ui.title'].paramValue || ' DataEase') }}
|
||||
</div>
|
||||
<div class="login-form">
|
||||
<el-form-item v-if="loginTypes.length > 1">
|
||||
<el-radio-group v-if="loginTypes.length > 1" v-model="loginForm.loginType" @change="changeLoginType">
|
||||
<el-form-item v-if="radioTypes.length > 1">
|
||||
<el-radio-group v-if="radioTypes.length > 1" v-model="loginForm.loginType" @change="changeLoginType">
|
||||
<el-radio :label="0" size="mini">{{ $t('login.default_login') }}</el-radio>
|
||||
<el-radio v-if="loginTypes.includes(1)" :label="1" size="mini">LDAP</el-radio>
|
||||
<el-radio v-if="loginTypes.includes(2)" :label="2" size="mini">OIDC</el-radio>
|
||||
@ -51,6 +57,20 @@
|
||||
{{ msg }}
|
||||
</div>
|
||||
</el-form>
|
||||
<div v-show="codeShow" class="code">
|
||||
<el-row>
|
||||
<plugin-com v-if="loginTypes.includes(4) && codeIndex === 4" ref="WecomQr" component-name="WecomQr" />
|
||||
<plugin-com v-if="loginTypes.includes(5) && codeIndex === 5" ref="DingtalkQr" component-name="DingtalkQr" />
|
||||
<plugin-com v-if="loginTypes.includes(6) && codeIndex === 6" ref="FarkQr" component-name="FarkQr" />
|
||||
</el-row>
|
||||
|
||||
<div v-if="qrTypes.length > 1" class="login-third-items">
|
||||
<span v-if="qrTypes.includes(4)" class="login-third-item login-third-wecom" @click="switchCodeIndex(4)" />
|
||||
<span v-if="qrTypes.includes(5)" class="login-third-item login-third-dingtalk" @click="switchCodeIndex(5)" />
|
||||
<span v-if="qrTypes.includes(6)" class="login-third-item login-third-fark" @click="switchCodeIndex(6)" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col v-loading="!axiosFinished" :span="12">
|
||||
<div v-if="!loginImageUrl && axiosFinished" class="login-image" />
|
||||
@ -69,7 +89,7 @@
|
||||
<script>
|
||||
|
||||
import { encrypt } from '@/utils/rsaEncrypt'
|
||||
import { ldapStatus, oidcStatus, getPublicKey, pluginLoaded, defaultLoginType } from '@/api/user'
|
||||
import { ldapStatus, oidcStatus, getPublicKey, pluginLoaded, defaultLoginType, wecomStatus } from '@/api/user'
|
||||
import { getSysUI } from '@/utils/auth'
|
||||
import { changeFavicon } from '@/utils/index'
|
||||
import { initTheme } from '@/utils/ThemeUtil'
|
||||
@ -107,12 +127,21 @@ export default {
|
||||
],
|
||||
defaultType: 0,
|
||||
showFoot: false,
|
||||
footContent: ''
|
||||
footContent: '',
|
||||
codeShow: false,
|
||||
imgAppShow: true,
|
||||
codeIndex: 4
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
msg() {
|
||||
return this.$store.state.user.loginMsg
|
||||
},
|
||||
qrTypes() {
|
||||
return this.loginTypes && this.loginTypes.filter(item => item > 3) || []
|
||||
},
|
||||
radioTypes() {
|
||||
return this.loginTypes && this.loginTypes.filter(item => item < 4) || []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -145,6 +174,13 @@ export default {
|
||||
}
|
||||
this.setDefaultType()
|
||||
})
|
||||
|
||||
wecomStatus().then(res => {
|
||||
if (res.success && res.data) {
|
||||
this.loginTypes.push(4)
|
||||
}
|
||||
this.setDefaultType()
|
||||
})
|
||||
getPublicKey().then(res => {
|
||||
if (res.success && res.data) {
|
||||
// 保存公钥
|
||||
@ -179,6 +215,12 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
switchCodeIndex(codeIndex) {
|
||||
this.codeIndex = codeIndex
|
||||
},
|
||||
showQr() {
|
||||
this.codeShow = !this.codeShow
|
||||
},
|
||||
setDefaultType() {
|
||||
if (this.loginTypes.includes(this.defaultType)) {
|
||||
this.loginForm.loginType = this.defaultType
|
||||
@ -412,4 +454,50 @@ export default {
|
||||
zoom: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.trans {
|
||||
position: absolute;
|
||||
left: calc(50% - 64px);
|
||||
top: 0;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
background-image: url(../../assets/qrcode.png) ;
|
||||
// background-color: var(--primary,#3370ff); //图标优化 -- 换为白色线条图标 背景层添加背景色
|
||||
cursor:pointer;
|
||||
}
|
||||
.imgApp {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
background: linear-gradient(225deg,transparent 45px, #fff 0);
|
||||
}
|
||||
.code{
|
||||
width: 100%;
|
||||
height: 100%; //将登录框挤出显示区域
|
||||
text-align: center;
|
||||
padding-top: 70px;
|
||||
img {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
.login-third-item {
|
||||
display: inline-block;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50% 50%;
|
||||
background: #ccc;
|
||||
cursor: pointer;
|
||||
margin: 0 10px;
|
||||
}
|
||||
.login-third-wecom {
|
||||
background: url(../../assets/wecom.png) no-repeat 50%/cover;
|
||||
}
|
||||
.login-third-dingtalk {
|
||||
background: url(../../assets/dingding01.png) no-repeat 50%/cover;
|
||||
}
|
||||
.login-third-fark {
|
||||
background: url(../../assets/fark.png) no-repeat 50%/cover;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user