|
@@ -51,6 +51,7 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
|
|
+ <!-- <view class="uni-padding-wrap">
|
|
|
<!-- <view class="uni-padding-wrap">
|
|
<!-- <view class="uni-padding-wrap">
|
|
|
<view>
|
|
<view>
|
|
|
<checkbox-group @change="handleChange">
|
|
<checkbox-group @change="handleChange">
|
|
@@ -89,6 +90,10 @@
|
|
|
<language-popup ref="languagePopupRef" />
|
|
<language-popup ref="languagePopupRef" />
|
|
|
<upgrade ref="upgradeRef" />
|
|
<upgrade ref="upgradeRef" />
|
|
|
</view>
|
|
</view>
|
|
|
|
|
+ <!-- 引用语言选择组件 -->
|
|
|
|
|
+ <language-popup ref="languagePopupRef" />
|
|
|
|
|
+ <upgrade ref="upgradeRef" />
|
|
|
|
|
+ </view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
@@ -102,20 +107,33 @@ import {
|
|
|
getInfo,
|
|
getInfo,
|
|
|
getTokenByUserId,
|
|
getTokenByUserId,
|
|
|
} from "@/api/login.js";
|
|
} from "@/api/login.js";
|
|
|
|
|
+import {
|
|
|
|
|
+ appLogin,
|
|
|
|
|
+ dingTalkLogin,
|
|
|
|
|
+ dingTalkLoginH5,
|
|
|
|
|
+ getInfo,
|
|
|
|
|
+ getTokenByUserId,
|
|
|
|
|
+} from "@/api/login.js";
|
|
|
// 引入配置文件
|
|
// 引入配置文件
|
|
|
import config from "@/utils/config";
|
|
import config from "@/utils/config";
|
|
|
|
|
+import config from "@/utils/config";
|
|
|
// 引入数据库操作
|
|
// 引入数据库操作
|
|
|
import { saveUser } from "@/utils/appDb";
|
|
import { saveUser } from "@/utils/appDb";
|
|
|
|
|
+import { saveUser } from "@/utils/appDb";
|
|
|
// 引入本地存储操作
|
|
// 引入本地存储操作
|
|
|
import { setUserId, setToken, setDeptId, setUserInfo } from "@/utils/auth.js";
|
|
import { setUserId, setToken, setDeptId, setUserInfo } from "@/utils/auth.js";
|
|
|
|
|
+import { setUserId, setToken, setDeptId, setUserInfo } from "@/utils/auth.js";
|
|
|
// 引入组件
|
|
// 引入组件
|
|
|
import Upgrade from "@/components/upgrade.vue";
|
|
import Upgrade from "@/components/upgrade.vue";
|
|
|
import LanguagePopup from "@/components/language-popup.vue";
|
|
import LanguagePopup from "@/components/language-popup.vue";
|
|
|
|
|
+import Upgrade from "@/components/upgrade.vue";
|
|
|
|
|
+import LanguagePopup from "@/components/language-popup.vue";
|
|
|
|
|
|
|
|
// 引入钉钉JSAPI -- 仅在H5环境下使用
|
|
// 引入钉钉JSAPI -- 仅在H5环境下使用
|
|
|
let dd = null;
|
|
let dd = null;
|
|
|
// #ifdef H5
|
|
// #ifdef H5
|
|
|
import * as dingTalkJsApi from "dingtalk-jsapi";
|
|
import * as dingTalkJsApi from "dingtalk-jsapi";
|
|
|
|
|
+import * as dingTalkJsApi from "dingtalk-jsapi";
|
|
|
dd = dingTalkJsApi;
|
|
dd = dingTalkJsApi;
|
|
|
// #endif
|
|
// #endif
|
|
|
|
|
|
|
@@ -125,6 +143,7 @@ const languagePopupRef = ref(null);
|
|
|
|
|
|
|
|
const openLanguagePopup = () => {
|
|
const openLanguagePopup = () => {
|
|
|
languagePopupRef.value.open();
|
|
languagePopupRef.value.open();
|
|
|
|
|
+ languagePopupRef.value.open();
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
let isChecked = ref(false);
|
|
let isChecked = ref(false);
|
|
@@ -132,6 +151,7 @@ let my_value = ref(false);
|
|
|
|
|
|
|
|
const handleChange = (val) => {
|
|
const handleChange = (val) => {
|
|
|
my_value.value = val.detail.value[0];
|
|
my_value.value = val.detail.value[0];
|
|
|
|
|
+ my_value.value = val.detail.value[0];
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// let privacyRef = ref(null);
|
|
// let privacyRef = ref(null);
|
|
@@ -150,6 +170,9 @@ const isDingTalk = () => {
|
|
|
const ua = window.navigator.userAgent.toLowerCase();
|
|
const ua = window.navigator.userAgent.toLowerCase();
|
|
|
console.log("🚀 ~ 当前环境 ~ ua:", ua);
|
|
console.log("🚀 ~ 当前环境 ~ ua:", ua);
|
|
|
return ua.includes("dingtalk") || ua.includes("dingtalkwork");
|
|
return ua.includes("dingtalk") || ua.includes("dingtalkwork");
|
|
|
|
|
+ const ua = window.navigator.userAgent.toLowerCase();
|
|
|
|
|
+ console.log("🚀 ~ 当前环境 ~ ua:", ua);
|
|
|
|
|
+ return ua.includes("dingtalk") || ua.includes("dingtalkwork");
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const dingTalkAutoLogin = async () => {
|
|
const dingTalkAutoLogin = async () => {
|
|
@@ -160,6 +183,13 @@ const dingTalkAutoLogin = async () => {
|
|
|
}
|
|
}
|
|
|
// 执行钉钉微应用免登逻辑
|
|
// 执行钉钉微应用免登逻辑
|
|
|
loginWithDingTalkH5();
|
|
loginWithDingTalkH5();
|
|
|
|
|
+ // 判断是否在钉钉环境
|
|
|
|
|
+ if (!isDingTalk()) {
|
|
|
|
|
+ console.log("当前环境不是钉钉环境,无法自动登录");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 执行钉钉微应用免登逻辑
|
|
|
|
|
+ loginWithDingTalkH5();
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 钉钉登录
|
|
// 钉钉登录
|
|
@@ -184,6 +214,26 @@ const loginWithDingTalk = async () => {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
// #endif
|
|
// #endif
|
|
|
|
|
+ // #ifdef APP
|
|
|
|
|
+ const plugin = uni.requireNativePlugin("DingTalk");
|
|
|
|
|
+ // 钉钉登录,这里无法使用async,否则java端会报参数错误
|
|
|
|
|
+ plugin.login((res) => {
|
|
|
|
|
+ console.log(res);
|
|
|
|
|
+ if (res.success === 1) {
|
|
|
|
|
+ dingTalkLogin({
|
|
|
|
|
+ type: 20,
|
|
|
|
|
+ code: res.code,
|
|
|
|
|
+ state: res.state,
|
|
|
|
|
+ }).then((res) => {
|
|
|
|
|
+ console.log(res);
|
|
|
|
|
+ handleLoginSuccess(res);
|
|
|
|
|
+ });
|
|
|
|
|
+ } else if (res.success === 2) {
|
|
|
|
|
+ uni.showToast({ title: t("login.dingTalkError"), icon: "none" });
|
|
|
|
|
+ console.error("APP端钉钉登录失败:", res);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ // #endif
|
|
|
|
|
|
|
|
// #ifdef H5
|
|
// #ifdef H5
|
|
|
if (isDingTalk()) {
|
|
if (isDingTalk()) {
|
|
@@ -197,6 +247,18 @@ const loginWithDingTalk = async () => {
|
|
|
uni.showToast({ title: t("login.h5DingTalk"), icon: "none" });
|
|
uni.showToast({ title: t("login.h5DingTalk"), icon: "none" });
|
|
|
}
|
|
}
|
|
|
// #endif
|
|
// #endif
|
|
|
|
|
+ // #ifdef H5
|
|
|
|
|
+ if (isDingTalk()) {
|
|
|
|
|
+ if (!dd) {
|
|
|
|
|
+ uni.showToast({ title: t("login.dingTalkJsapiMissing"), icon: "none" });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ loginWithDingTalkH5();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.log("当前是普通 H5 环境,无法使用钉钉登录");
|
|
|
|
|
+ uni.showToast({ title: t("login.h5DingTalk"), icon: "none" });
|
|
|
|
|
+ }
|
|
|
|
|
+ // #endif
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const loginWithDingTalkH5 = async () => {
|
|
const loginWithDingTalkH5 = async () => {
|
|
@@ -204,6 +266,10 @@ const loginWithDingTalkH5 = async () => {
|
|
|
console.log("🚀 ~ loginWithDingTalkH5 ~ corpId:", corpId);
|
|
console.log("🚀 ~ loginWithDingTalkH5 ~ corpId:", corpId);
|
|
|
const clientId = config.default.clientId;
|
|
const clientId = config.default.clientId;
|
|
|
console.log("🚀 ~ loginWithDingTalkH5 ~ clientId:", clientId);
|
|
console.log("🚀 ~ loginWithDingTalkH5 ~ clientId:", clientId);
|
|
|
|
|
+ const corpId = config.default.corpId;
|
|
|
|
|
+ console.log("🚀 ~ loginWithDingTalkH5 ~ corpId:", corpId);
|
|
|
|
|
+ const clientId = config.default.clientId;
|
|
|
|
|
+ console.log("🚀 ~ loginWithDingTalkH5 ~ clientId:", clientId);
|
|
|
|
|
|
|
|
if (!corpId || !clientId) {
|
|
if (!corpId || !clientId) {
|
|
|
console.error("缺少必要参数");
|
|
console.error("缺少必要参数");
|
|
@@ -236,6 +302,37 @@ const loginWithDingTalkH5 = async () => {
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
});
|
|
});
|
|
|
|
|
+ if (!corpId || !clientId) {
|
|
|
|
|
+ console.error("缺少必要参数");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ dd.requestAuthCode({
|
|
|
|
|
+ corpId,
|
|
|
|
|
+ clientId,
|
|
|
|
|
+ success: async (result) => {
|
|
|
|
|
+ console.log("🚀 ~ loginWithDingTalkH5 ~ result:", result);
|
|
|
|
|
+ const { code } = result;
|
|
|
|
|
+ dingTalkLoginH5({
|
|
|
|
|
+ type: 10,
|
|
|
|
|
+ state: new Date().getTime(),
|
|
|
|
|
+ code: code,
|
|
|
|
|
+ })
|
|
|
|
|
+ .then((res) => {
|
|
|
|
|
+ console.log("🚀 ~ loginWithDingTalkH5 ~ res:", res);
|
|
|
|
|
+ handleLoginSuccess(res);
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((err) => {
|
|
|
|
|
+ console.log("🚀 ~ loginWithDingTalkH5 ~ err:", err);
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ fail: (err) => {
|
|
|
|
|
+ console.log("🚀 ~ loginWithDingTalkH5 ~ err:", err);
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: "获取code失败:" + JSON.stringify(err),
|
|
|
|
|
+ icon: "none",
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
onLoad(async (options) => {
|
|
onLoad(async (options) => {
|
|
@@ -267,6 +364,25 @@ onLoad(async (options) => {
|
|
|
dingTalkAutoLogin();
|
|
dingTalkAutoLogin();
|
|
|
}
|
|
}
|
|
|
// #endif
|
|
// #endif
|
|
|
|
|
+ // 保存钉钉消息传递的参数
|
|
|
|
|
+ if (options.userId) {
|
|
|
|
|
+ uni.setStorageSync("dingTalkJson", JSON.stringify(options));
|
|
|
|
|
+ const isLoggedIn = uni.getStorageSync("userId");
|
|
|
|
|
+ if (!isLoggedIn) {
|
|
|
|
|
+ const result = await getTokenByUserId(options.userId);
|
|
|
|
|
+ await handleLoginSuccess(result);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // #ifdef H5
|
|
|
|
|
+ // 当前环境为H5时,判断是否是通过钉钉微应用打开的链接
|
|
|
|
|
+ // 获取当前Url地址
|
|
|
|
|
+ const url = window.location.href;
|
|
|
|
|
+ console.log("当前环境为H5时 当前Url地址:", url);
|
|
|
|
|
+ // 判断是否是通过钉钉微应用打开的链接
|
|
|
|
|
+ if (url.includes("/deepoil")) {
|
|
|
|
|
+ dingTalkAutoLogin();
|
|
|
|
|
+ }
|
|
|
|
|
+ // #endif
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
@@ -287,10 +403,13 @@ onMounted(() => {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+const placeholderStyle = ref("color:#797979;font-weight:500;font-size:16px");
|
|
|
const placeholderStyle = ref("color:#797979;font-weight:500;font-size:16px");
|
|
const placeholderStyle = ref("color:#797979;font-weight:500;font-size:16px");
|
|
|
const inputStyles = reactive({
|
|
const inputStyles = reactive({
|
|
|
backgroundColor: "#F0F3FB",
|
|
backgroundColor: "#F0F3FB",
|
|
|
color: "#797979",
|
|
color: "#797979",
|
|
|
|
|
+ backgroundColor: "#F0F3FB",
|
|
|
|
|
+ color: "#797979",
|
|
|
});
|
|
});
|
|
|
const loginData = reactive({
|
|
const loginData = reactive({
|
|
|
username: "",
|
|
username: "",
|
|
@@ -313,6 +432,22 @@ const loginRules = ref({
|
|
|
},
|
|
},
|
|
|
],
|
|
],
|
|
|
},
|
|
},
|
|
|
|
|
+ username: {
|
|
|
|
|
+ rules: [
|
|
|
|
|
+ {
|
|
|
|
|
+ required: true,
|
|
|
|
|
+ errorMessage: t("login.enterUsername"),
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ },
|
|
|
|
|
+ password: {
|
|
|
|
|
+ rules: [
|
|
|
|
|
+ {
|
|
|
|
|
+ required: true,
|
|
|
|
|
+ errorMessage: t("login.enterPassword"),
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ },
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const formRef = ref();
|
|
const formRef = ref();
|
|
@@ -324,6 +459,13 @@ const formSubmit = async (formEl) => {
|
|
|
// duration: 2000, // 持续时间,单位ms
|
|
// duration: 2000, // 持续时间,单位ms
|
|
|
// mask: true // 是否显示透明蒙层,防止触摸穿透
|
|
// mask: true // 是否显示透明蒙层,防止触摸穿透
|
|
|
// });
|
|
// });
|
|
|
|
|
+ // if (!my_value.value) {
|
|
|
|
|
+ // uni.showToast({
|
|
|
|
|
+ // title: '请阅读并同意隐私政策和用户服务协议',
|
|
|
|
|
+ // icon: 'none', // 可选 success/error/loading/none
|
|
|
|
|
+ // duration: 2000, // 持续时间,单位ms
|
|
|
|
|
+ // mask: true // 是否显示透明蒙层,防止触摸穿透
|
|
|
|
|
+ // });
|
|
|
|
|
|
|
|
// return;
|
|
// return;
|
|
|
// }
|
|
// }
|
|
@@ -351,9 +493,47 @@ const formSubmit = async (formEl) => {
|
|
|
.catch((err) => {
|
|
.catch((err) => {
|
|
|
console.log("err", err);
|
|
console.log("err", err);
|
|
|
});
|
|
});
|
|
|
|
|
+ // return;
|
|
|
|
|
+ // }
|
|
|
|
|
+ if (!formEl) return;
|
|
|
|
|
+ await formEl
|
|
|
|
|
+ .validate()
|
|
|
|
|
+ .then((res) => {
|
|
|
|
|
+ appLogin({
|
|
|
|
|
+ ...loginData,
|
|
|
|
|
+ // rememberMe: ,
|
|
|
|
|
+ // tenantName: ""
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(async (result) => {
|
|
|
|
|
+ console.log("result,", result.data);
|
|
|
|
|
+ if (result) {
|
|
|
|
|
+ await saveUser({
|
|
|
|
|
+ name: loginData.username,
|
|
|
|
|
+ pwd: loginData.password,
|
|
|
|
|
+ });
|
|
|
|
|
+ await handleLoginSuccess(result);
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .finally(() => {});
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((err) => {
|
|
|
|
|
+ console.log("err", err);
|
|
|
|
|
+ });
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleLoginSuccess = async (result) => {
|
|
const handleLoginSuccess = async (result) => {
|
|
|
|
|
+ if (result) {
|
|
|
|
|
+ await setUserId(result.data.userId);
|
|
|
|
|
+ await setToken(result.data);
|
|
|
|
|
+ await getInfo().then(async (res) => {
|
|
|
|
|
+ // console.log('useres', res)
|
|
|
|
|
+ const data = JSON.stringify({
|
|
|
|
|
+ user: res.data.user,
|
|
|
|
|
+ roles: res.data.roles,
|
|
|
|
|
+ });
|
|
|
|
|
+ // console.log('data', data)
|
|
|
|
|
+ await setUserInfo(data);
|
|
|
|
|
+ await setDeptId(res.data.user.deptId);
|
|
|
if (result) {
|
|
if (result) {
|
|
|
await setUserId(result.data.userId);
|
|
await setUserId(result.data.userId);
|
|
|
await setToken(result.data);
|
|
await setToken(result.data);
|
|
@@ -380,6 +560,9 @@ const handleLoginSuccess = async (result) => {
|
|
|
height: 60vh;
|
|
height: 60vh;
|
|
|
width: 85vw;
|
|
width: 85vw;
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
|
|
+ height: 60vh;
|
|
|
|
|
+ width: 85vw;
|
|
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.uni-padding-wrap {
|
|
.uni-padding-wrap {
|
|
@@ -388,19 +571,30 @@ const handleLoginSuccess = async (result) => {
|
|
|
justify-content: center;
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
padding: 0 10rpx;
|
|
padding: 0 10rpx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ z-index: 999;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ padding: 0 10rpx;
|
|
|
}
|
|
}
|
|
|
.uni-title {
|
|
.uni-title {
|
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
}
|
|
}
|
|
|
.login-top {
|
|
.login-top {
|
|
|
position: relative;
|
|
position: relative;
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
height: 422rpx;
|
|
height: 422rpx;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 422rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.back-img {
|
|
.back-img {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
height: 100%;
|
|
height: 100%;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.login-text {
|
|
.login-text {
|
|
@@ -418,6 +612,20 @@ const handleLoginSuccess = async (result) => {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
justify-content: center;
|
|
justify-content: center;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ color: #ffffff;
|
|
|
|
|
+ font-size: 40rpx;
|
|
|
|
|
+ font-family: "Negreta,PingFang SC";
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ padding: 0 56rpx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
|
|
|
.text {
|
|
.text {
|
|
|
width: 100%;
|
|
width: 100%;
|