login.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <template>
  2. <div class="loginView w-screen h-screen overflow-hidden flex">
  3. <div class="w-96 bg-white m-auto border-t-8 border-[#075985] shadow-xl rounded-md pl-9 pr-9" v-if="!isCorpWX">
  4. <div class="m-auto pt-4">
  5. <img class="w-1/5 m-auto" :src="loginLogo" alt="">
  6. </div>
  7. <h2 class="text-xl text-center pt-4 font-bold">智能客户管家</h2>
  8. <el-form class="pt-4" ref="ruleFormRef" :model="ruleForm" :rules="rules">
  9. <el-form-item prop="username">
  10. <el-input clearable :prefix-icon="UserFilled" size="large" class="mt-2" v-model.trim="ruleForm.username"
  11. autocomplete="off" placeholder="账号/手机号" />
  12. </el-form-item>
  13. <el-form-item prop="password">
  14. <el-input clearable :prefix-icon="Lock" show-password size="large" class="mt-4"
  15. v-model.trim="ruleForm.password" autocomplete="off" placeholder="密码" />
  16. </el-form-item>
  17. <div class="pt-4">
  18. <el-button type="primary" size="large" class="w-full" :loading="loginLoading"
  19. @click="login(ruleFormRef)">登录</el-button>
  20. </div>
  21. </el-form>
  22. <el-divider content-position="center">或</el-divider>
  23. <div class="m-auto mb-5" @click="wxworkCli()">
  24. <img class="w-9 m-auto p-1 rounded-full border-blue-300 border-2 cursor-pointer" :src="qiyeweixin" alt="">
  25. </div>
  26. <div class="flex justify-between pb-5">
  27. <!-- <el-link type="primary" :underline="false">联系客服</el-link> -->
  28. <el-link type="primary" class="btn" style="float:left;" :underline="false">联系客服
  29. <div class="service">
  30. <p style="color: #333">联系客服</p>
  31. <img src="../assets/code.jpg">
  32. <p><span style="color: #333">QQ:</span><span id="QQ">3052894409</span></p>
  33. </div>
  34. </el-link>
  35. <div class="flex justify-around">
  36. <el-link class="mr-4" type="primary" :underline="false" @click="useHelp()">使用说明</el-link>
  37. <el-link type="primary" :underline="false" @click="toRegister()">企业注册</el-link>
  38. </div>
  39. </div>
  40. <el-dialog v-model="helpDialog" width="30%" title="使用说明">
  41. <div class="p-2 text-xl">
  42. <a style="color:#075985;text-decoration:none" href="upload/客户管家使用说明书.docx" download="客户管家使用说明书.docx"
  43. target="_blank">客户管家使用说明书.docx</a>
  44. </div>
  45. </el-dialog>
  46. </div>
  47. <div v-else class="w-full flex justify-center py-[50px] text-[40px] colo-[#505458]">
  48. 正在进入系统中...
  49. </div>
  50. </div>
  51. </template>
  52. <script lang="ts" setup>
  53. import { reactive, ref, inject, onMounted } from "vue";
  54. import { useRouter } from "vue-router";
  55. import loginLogo from "@/assets/login/login_logo.png";
  56. import qiyeweixin from "@/assets/login/qiyeweixin.png";
  57. import { UserFilled, Lock } from '@element-plus/icons-vue'
  58. import { type FormInstance, type FormRules } from 'element-plus'
  59. import { useStore } from '@/store/index'
  60. import { post } from "@/utils/request";
  61. import { LOGIN } from "./api";
  62. const { setRouters, setValue } = useStore()
  63. const router = useRouter();
  64. const globalPopup = inject<GlobalPopup>('globalPopup')
  65. const ruleFormRef = ref<FormInstance>();
  66. const ruleForm = ref({
  67. username: "18122222222",
  68. password: "000000",
  69. // username: "",
  70. // password: "",
  71. });
  72. const loginLoading = ref(false);
  73. const rules = reactive<FormRules<typeof ruleForm>>({
  74. username: [{ required: true, trigger: "blur", message: "请输入账号/手机号" }],
  75. password: [{ required: true, trigger: "blur", message: "请输入密码" }],
  76. })
  77. const helpDialog = ref(false);
  78. const isCorpWX = ref(false)
  79. const login = (formEl: FormInstance | undefined) => {
  80. if (!formEl) {
  81. return
  82. }
  83. formEl.validate((valid: boolean) => {
  84. if (!valid) {
  85. return false as any;
  86. }
  87. loginLoading.value = true;
  88. post(LOGIN, { ...ruleForm.value }).then(res => {
  89. if (res.code == 'error') {
  90. globalPopup?.showError(res.msg)
  91. loginLoading.value = false;
  92. return
  93. }
  94. globalPopup?.showSuccess('登录成功')
  95. loginLogic(res.data)
  96. // sessionStorage.setItem('token', res.data.id)
  97. // setValue(res.data, 'userInfo')
  98. // // 将数据分析放到第一位
  99. // const index = res.data?.moduleList.findIndex((obj: any) => obj.path === '/analysis');
  100. // if (index !== -1) {
  101. // const item = res.data?.moduleList.splice(index, 1)[0];
  102. // res.data?.moduleList.unshift(item);
  103. // }
  104. // console.log(res.data?.moduleList)
  105. // setValue(res.data?.moduleList, 'routers')
  106. // setTimeout(() => {
  107. // loginLoading.value = false;
  108. // // router.push(res.data?.moduleList[0].path);
  109. // router.push('/analysis');
  110. // }, 100)
  111. }).catch(_err => {
  112. loginLoading.value = false;
  113. })
  114. return
  115. // let newRouter = [
  116. // {
  117. // path: '/thread',
  118. // name: 'thread'
  119. // }
  120. // ]
  121. // setRouters(newRouter)
  122. // setTimeout(() => {
  123. // loginLoading.value = false;
  124. // router.push(newRouter[0].path);
  125. // }, 1000);
  126. })
  127. };
  128. const loginLogic = (data: any) => {
  129. if(data.moduleList.length <= 0) {
  130. alert('无权访问,请联系管理员为您分配权限')
  131. return
  132. }
  133. sessionStorage.setItem('token', data.id)
  134. setValue(data, 'userInfo')
  135. // 将数据分析放到第一位
  136. const index = data?.moduleList.findIndex((obj: any) => obj.path === '/analysis');
  137. if (index !== -1) {
  138. const item = data?.moduleList.splice(index, 1)[0];
  139. data?.moduleList.unshift(item);
  140. }
  141. setValue(data?.moduleList, 'routers')
  142. setTimeout(() => {
  143. loginLoading.value = false;
  144. // router.push(data?.moduleList[0].path);
  145. router.push('/analysis');
  146. }, 100)
  147. }
  148. const useHelp = () => {
  149. helpDialog.value = true;
  150. }
  151. const toRegister = () => {
  152. router.push("/register");
  153. }
  154. // 涉及第三方登录
  155. const checkLogin = () => { // 检查登录
  156. const userAgent = navigator.userAgent.toLowerCase();
  157. const href = window.location.href;
  158. const isCorpWXs = userAgent.includes("wxwork");
  159. if (isCorpWXs) {
  160. isCorpWX.value = true;
  161. }
  162. if (isCorpWX.value) {
  163. //企业微信环境下,尝试自动登录
  164. //判断企业微信,是否存在授权
  165. //尝试自动登录
  166. if (href.indexOf('hasTriedAutoLogin') == -1) {
  167. tryAutoLogin()
  168. } else if (href.indexOf("userId") > 0) {
  169. //后台经过验证后,重定向过来带上了userId
  170. var loginUserId = href.substring(href.indexOf("userId=") + "userId=".length);
  171. if (loginUserId.includes('#/')) {
  172. loginUserId = loginUserId.substring(0, loginUserId.indexOf('#/'));
  173. }
  174. if (loginUserId.includes('&')) {
  175. loginUserId = loginUserId.substring(0, loginUserId.indexOf('&'));
  176. }
  177. loginByUserId(loginUserId);
  178. }
  179. }
  180. }
  181. const loginByUserId = (userId: any) => {
  182. post(`/user/loginByUserId`, { userId }).then(res => {
  183. if (res.code == 'error') {
  184. globalPopup?.showError(res.msg)
  185. return
  186. }
  187. loginLogic(res.data)
  188. }).catch(err => {
  189. console.log(err)
  190. })
  191. }
  192. const tryAutoLogin = () => {
  193. var appId = "wwdd1137a65ce0fc87";//企业微信第三方的SUIT ID
  194. var url = "https://crm.ttkuaiban.com/api/corpWXAuth";//授权回调页面
  195. var weixinUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + encodeURI(url) + "&response_type=code&scope=snsapi_base&state=1#wechat_redirect";
  196. window.location.href = weixinUrl;
  197. }
  198. const wxworkCli = () => {
  199. var appId = "wwdd1137a65ce0fc87";//企业微信第三方的SUIT ID
  200. var url = "https://crm.ttkuaiban.com/api/corpWXScanningAuth";//授权回调页面
  201. // var weixinUrl=`https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect?appid=${appId}&redirect_uri=${url}&state=0&usertype=member`;
  202. var weixinUrl=`https://login.work.weixin.qq.com/wwlogin/sso/login?login_type=ServiceApp&appid=${appId}&redirect_uri=${url}&state=0`;
  203. window.location.href = weixinUrl;
  204. }
  205. onMounted(() => {
  206. checkLogin()
  207. })
  208. </script>
  209. <style lang="scss" scoped>
  210. .loginView {
  211. background: #f0f2f5 url("../assets/login/background.png") no-repeat;
  212. }
  213. .service {
  214. display: none;
  215. width: 120px;
  216. position: absolute;
  217. background: #fff;
  218. text-align: center;
  219. padding: 10px;
  220. left: -30px;
  221. top: -210px;
  222. border-radius: 5px;
  223. box-shadow: 3px 3px 10px #dfdfdf;
  224. img {
  225. width: 80px;
  226. }
  227. }
  228. .btn:hover .service {
  229. display: block;
  230. }
  231. </style>