Selaa lähdekoodia

Merge branch 'xinyan' into dev

xinyan 6 kuukautta sitten
vanhempi
commit
00583bec3f

+ 6 - 0
package-lock.json

@@ -19,6 +19,7 @@
 				"@vitejs/plugin-vue-jsx": "^3.0.0",
 				"@wangeditor/editor": "^5.1.23",
 				"@wangeditor/editor-for-vue": "^5.1.12",
+				"@wecom/jssdk": "^2.2.3",
 				"autoprefixer": "^10.4.14",
 				"axios": "^1.2.1",
 				"countup.js": "^2.3.2",
@@ -4298,6 +4299,11 @@
 				"snabbdom": "^3.1.0"
 			}
 		},
+		"node_modules/@wecom/jssdk": {
+			"version": "2.2.3",
+			"resolved": "https://registry.npmmirror.com/@wecom/jssdk/-/jssdk-2.2.3.tgz",
+			"integrity": "sha512-4oxhM5zQKEcZ5sq6EVaaqE6DLqZl+wbFwjSnXIuJvbIuIThVQwtZBpUExwG7rzEx3QNedrDqtg47VoCpeX5R9g=="
+		},
 		"node_modules/abort-controller": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmmirror.com/abort-controller/-/abort-controller-3.0.0.tgz",

+ 1 - 0
package.json

@@ -20,6 +20,7 @@
 		"@vitejs/plugin-vue-jsx": "^3.0.0",
 		"@wangeditor/editor": "^5.1.23",
 		"@wangeditor/editor-for-vue": "^5.1.12",
+		"@wecom/jssdk": "^2.2.3",
 		"autoprefixer": "^10.4.14",
 		"axios": "^1.2.1",
 		"countup.js": "^2.3.2",

BIN
src/assets/ansjer_image.png


BIN
src/assets/bg-main.jpg


+ 8 - 0
src/views/system/login/api.ts

@@ -19,3 +19,11 @@ export function getUserInfo() {
         method: 'get',
     });
 }
+
+export function WeComLogin (data) {
+    return request({
+        url: '/api/system/wechat/login/',
+        method: 'post',
+        data
+    })
+}

+ 70 - 31
src/views/system/login/component/scan.vue

@@ -1,59 +1,98 @@
+<script lang="ts" setup>
+import { onMounted } from 'vue';
+import * as ww from '@wecom/jssdk';
+import { WeComLogin } from '../api';
+import emitter from '/@/utils/emitter';
+
+const props = defineProps({
+	isScan: {
+		type: Boolean,
+		default: false,
+	},
+});
+
+// 初始化企业微信扫码登录
+function initWeComQRCode() {
+	ww.createWWLoginPanel({
+		el: '#wx_qrcode',
+		params: {
+			login_type: 'CorpApp',
+			appid: 'ww467ec1685e8262e6', // 企业微信企业 ID
+			agentid: '1000071', // 应用 AgentID
+			redirect_uri: 'http://operate.zosi.com.cn/web/', //正式环境网址
+			state: 'Wechat',
+			scope: 'snsapi_privateinfo',
+			redirect_type: 'callback',
+		},
+		onCheckWeComLogin({ isWeComLogin }) {
+			// console.log(isWeComLogin)
+		},
+		onLoginSuccess({ code }) {
+			handleWeComLogin({ code: code, state: 'Wechat' });
+		},
+		onLoginFail(err) {
+			// console.log(err)
+		},
+	});
+}
+
+async function handleWeComLogin(query: any) {
+	// console.log('扫码成功')
+	try {
+		const res = await WeComLogin(query);
+		if (res) {
+			emitter.emit('scan-wecomLogin', { loginInfo: res });
+			// console.log('发送跳转')
+		}
+	} catch (error) {
+		console.log('error:', error);
+	}
+}
+
+onMounted(() => {
+	if (props.isScan) {
+		initWeComQRCode();
+	}
+});
+</script>
+
 <template>
 	<div class="login-scan-container">
-		<div ref="qrcodeRef"></div>
-		<div class="font12 mt20 login-msg">{{ $t('message.scan.text') }}</div>
+		<div id="wx_qrcode"></div>
+		<!--<div class="font12 mt20 login-msg">{{ $t('message.scan.text') }}</div>-->
 	</div>
 </template>
 
-<script lang="ts">
-import { ref, defineComponent, onMounted } from 'vue';
-import QRCode from 'qrcodejs2-fixes';
-
-export default defineComponent({
-	name: 'loginScan',
-	setup() {
-		const qrcodeRef = ref<HTMLElement | null>(null);
-		// 初始化生成二维码
-		const initQrcode = () => {
-			(qrcodeRef.value as HTMLElement).innerHTML = '';
-			new QRCode(qrcodeRef.value, {
-				text: `https://jq.qq.com/?_wv=1027&k=hUu2GeU1`,
-				width: 260,
-				height: 260,
-				colorDark: '#000000',
-				colorLight: '#ffffff',
-			});
-		};
-		// 页面加载时
-		onMounted(() => {
-			initQrcode();
-		});
-		return { qrcodeRef };
-	},
-});
-</script>
 
-<style scoped lang="scss">
+<style lang="scss" scoped>
 .login-scan-animation {
 	opacity: 0;
 	animation-name: error-num;
 	animation-duration: 0.5s;
 	animation-fill-mode: forwards;
 }
+
 .login-scan-container {
-	padding: 20px;
+	//padding: 20px;
 	display: flex;
+	align-items: center;
 	flex-direction: column;
 	text-align: center;
 	@extend .login-scan-animation;
 	animation-delay: 0.1s;
+
 	:deep(img) {
 		margin: auto;
 	}
+
 	.login-msg {
 		color: var(--el-text-color-placeholder);
 		@extend .login-scan-animation;
 		animation-delay: 0.2s;
 	}
 }
+
+:deep(#wx_qrcode iframe) {
+	height: 365px;
+}
 </style>

+ 88 - 89
src/views/system/login/index.vue

@@ -1,26 +1,85 @@
+<script setup lang="ts" name="loginIndex">
+import { computed, defineAsyncComponent, onMounted, reactive, ref } from 'vue'
+import { storeToRefs } from 'pinia'
+import { useThemeConfig } from '/@/stores/themeConfig'
+import { NextLoading } from '/@/utils/loading'
+import loginMain from '/src/assets/login-main.svg'
+import loginBg from '/@/assets/login-bg.svg'
+import loginOne from '/@/assets/login11.jpg'
+import AnsjerImg from '/@/assets/ansjer_image.png'
+
+// 引入组件
+const Account = defineAsyncComponent(() => import('/@/views/system/login/component/account.vue'));
+const Mobile = defineAsyncComponent(() => import('/@/views/system/login/component/mobile.vue'));
+const Scan = defineAsyncComponent(() => import('/@/views/system/login/component/scan.vue'));
+
+// 定义变量内容
+const storesThemeConfig = useThemeConfig();
+const { themeConfig } = storeToRefs(storesThemeConfig);
+const state = reactive({
+	tabsActiveName: 'account',
+	isScan: false,
+});
+
+// 获取布局配置信息
+const getThemeConfig = computed(() => {
+	return themeConfig.value;
+});
+
+// 切换登录方式
+function showScan() {
+	state.isScan = !state.isScan
+}
+
+// const systemConfigStore = SystemConfigStore()
+// const { systemConfig } = storeToRefs(systemConfigStore)
+// const getSystemConfig = computed(() => {
+// 	return systemConfig.value
+// })
+//
+// const siteLogo = computed(() => {
+// 	if (!_.isEmpty(getSystemConfig.value['login.site_logo'])) {
+// 		return getSystemConfig.value['login.site_logo']
+// 	}
+// 	return logoMini
+// });
+//
+// const siteBg = computed(() => {
+// 	if (!_.isEmpty(getSystemConfig.value['login.login_background'])) {
+// 		return getSystemConfig.value['login.login_background']
+// 	}
+// });
+
+// 页面加载时
+onMounted(() => {
+	NextLoading.done();
+});
+</script>
+
 <template>
-	<div class="login-container flex z-10">
+	<div class="login-container flex">
 		<div class="login-left">
-			<div class="login-left-logo">
-				<img :src="siteLogo" />
-				<div class="login-left-logo-text">
-					<span>{{ getSystemConfig['login.site_title'] || getThemeConfig.globalViceTitle }}</span>
-					<span class="login-left-logo-text-msg">{{
-						getSystemConfig['login.site_name'] || getThemeConfig.globalViceTitleMsg }}</span>
-				</div>
-			</div>
-			<div class="login-left-img">
-				<img :src="loginMain" />
-			</div>
-			<img :src="loginBg" class="login-left-waves" />
+			<!--<div class="login-left-logo">-->
+				<!-- <img src="src/assets/ansjer_image.png"/> -->
+				<!--<el-image style="width: 110px; height: 110px" :src="AnsjerImg" fit="contain" />-->
+				<!-- 登录页左上角logo后面的文字 -->
+				<!-- <div class="login-left-logo-text">
+					<span>{{ getThemeConfig.globalViceTitle }}</span>
+					<span class="login-left-logo-text-msg">{{ getThemeConfig.globalViceTitleMsg }}</span>
+				</div> -->
+			<!--</div>-->
+			<!--<div class="login-left-img">-->
+			<!--	<img :src="loginMain" alt="" />-->
+			<!--</div>-->
+			<!--<img :src="loginBg" class="login-left-waves" alt="" />-->
 		</div>
-		<div class="login-right flex z-10">
+		<!--<img :src="loginOne" alt="" />-->
+		<div class="login-right flex">
 			<div class="login-right-warp flex-margin">
 				<span class="login-right-warp-one"></span>
 				<span class="login-right-warp-two"></span>
 				<div class="login-right-warp-mian">
-					<div class="login-right-warp-main-title">{{ getSystemConfig['login.site_title'] ||
-						getThemeConfig.globalTitle }} 欢迎您!</div>
+					<div class="login-right-warp-main-title">{{ getThemeConfig.globalTitle }} 欢迎您!</div>
 					<div class="login-right-warp-main-form">
 						<div v-if="!state.isScan">
 							<el-tabs v-model="state.tabsActiveName">
@@ -33,8 +92,8 @@
 								</el-tab-pane> -->
 							</el-tabs>
 						</div>
-						<Scan v-if="state.isScan" />
-						<div class="login-content-main-sacn" @click="state.isScan = !state.isScan">
+						<Scan v-if="state.isScan" :isScan="state.isScan" />
+						<div class="login-content-main-sacn" @click="showScan">
 							<i class="iconfont" :class="state.isScan ? 'icon-diannao1' : 'icon-barcode-qr'"></i>
 							<div class="login-content-main-sacn-delta"></div>
 						</div>
@@ -43,91 +102,31 @@
 			</div>
 		</div>
 
-		<div class="login-authorization z-10">
-			<p>Copyright © {{ getSystemConfig['login.copyright'] || '2021-2024 django-vue-admin.com' }} 版权所有</p>
-			<p class="la-other">
-				<a href="https://beian.miit.gov.cn" target="_blank">{{ getSystemConfig['login.keep_record'] ||
-					'晋ICP备18005113号-3' }}</a>
+		<div class="login-authorization">
+			<p>Copyright © 2023-2024 Ansjer 版权所有</p>
+			<!-- <p class="la-other">
+				<a href="https://beian.miit.gov.cn" target="_blank">晋ICP备18005113号-3</a>
 				|
-				<a :href="getSystemConfig['login.help_url'] ? getSystemConfig['login.help_url'] : 'https://django-vue-admin.com'"
-					target="_blank">帮助</a>
+				<a href="https://django-vue-admin.com" target="_blank">帮助</a>
 				|
-				<a
-					:href="getSystemConfig['login.privacy_url'] ? getBaseURL(getSystemConfig['login.privacy_url']) : '#'">隐私</a>
+				<a href="#">隐私</a>
 				|
-				<a
-					:href="getSystemConfig['login.clause_url'] ? getBaseURL(getSystemConfig['login.clause_url']) : '#'">条款</a>
-			</p>
+				<a href="#">条款</a>
+			</p> -->
 		</div>
 	</div>
-	<div v-if="siteBg">
-		<img :src="siteBg" class="fixed inset-0 z-1 w-full h-full" />
-	</div>
 </template>
 
-<script setup lang="ts" name="loginIndex">
-import { defineAsyncComponent, onMounted, reactive, computed } from 'vue';
-import { storeToRefs } from 'pinia';
-import { useThemeConfig } from '/@/stores/themeConfig';
-import { NextLoading } from '/@/utils/loading';
-import logoMini from '/@/assets/logo-mini.svg';
-import loginMain from '/@/assets/login-main.svg';
-import loginBg from '/@/assets/login-bg.svg';
-import { SystemConfigStore } from '/@/stores/systemConfig'
-import { getBaseURL } from "/@/utils/baseUrl";
-// 引入组件
-const Account = defineAsyncComponent(() => import('/@/views/system/login/component/account.vue'));
-const Mobile = defineAsyncComponent(() => import('/@/views/system/login/component/mobile.vue'));
-const Scan = defineAsyncComponent(() => import('/@/views/system/login/component/scan.vue'));
-import _ from "lodash-es";
-
-// 定义变量内容
-const storesThemeConfig = useThemeConfig();
-const { themeConfig } = storeToRefs(storesThemeConfig);
-const state = reactive({
-	tabsActiveName: 'account',
-	isScan: false,
-});
-
-// 获取布局配置信息
-const getThemeConfig = computed(() => {
-	return themeConfig.value;
-});
-
-const systemConfigStore = SystemConfigStore()
-const { systemConfig } = storeToRefs(systemConfigStore)
-const getSystemConfig = computed(() => {
-	return systemConfig.value
-})
-
-const siteLogo = computed(() => {
-	if (!_.isEmpty(getSystemConfig.value['login.site_logo'])) {
-		return getSystemConfig.value['login.site_logo']
-	}
-	return logoMini
-});
-
-const siteBg = computed(() => {
-	if (!_.isEmpty(getSystemConfig.value['login.login_background'])) {
-		return getSystemConfig.value['login.login_background']
-	}
-});
-
-// 页面加载时
-onMounted(() => {
-	NextLoading.done();
-});
-</script>
 
 <style scoped lang="scss">
 .login-container {
 	height: 100%;
-	background: var(--el-color-white);
-
+	// background: var(--el-color-white);
+	background-image: url('/src/assets/bg-main.jpg');
 	.login-left {
 		flex: 1;
 		position: relative;
-		background-color: rgba(211, 239, 255, 1);
+		// background-color: rgba(211, 239, 255, 1);
 		margin-right: 100px;
 
 		.login-left-logo {