login.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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">
  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>
  48. </template>
  49. <script lang="ts" setup>
  50. import { reactive, ref, inject, onMounted } from "vue";
  51. import { useRouter } from "vue-router";
  52. import loginLogo from "@/assets/login/login_logo.png";
  53. import qiyeweixin from "@/assets/login/qiyeweixin.png";
  54. import { UserFilled, Lock } from '@element-plus/icons-vue'
  55. import { type FormInstance, type FormRules } from 'element-plus'
  56. import { useStore } from '@/store/index'
  57. import { post } from "@/utils/request";
  58. import { LOGIN } from "./api";
  59. const { setRouters, setValue } = useStore()
  60. const router = useRouter();
  61. const globalPopup = inject<GlobalPopup>('globalPopup')
  62. const ruleFormRef = ref<FormInstance>();
  63. const ruleForm = ref({
  64. username: "18122222222",
  65. password: "000000",
  66. });
  67. const loginLoading = ref(false);
  68. const rules = reactive<FormRules<typeof ruleForm>>({
  69. username: [{ required: true, trigger: "blur", message: "请输入账号/手机号" }],
  70. password: [{ required: true, trigger: "blur", message: "请输入密码" }],
  71. })
  72. const helpDialog = ref(false);
  73. const isCorpWX = ref(false)
  74. const login = (formEl: FormInstance | undefined) => {
  75. if (!formEl) {
  76. return
  77. }
  78. formEl.validate((valid: boolean) => {
  79. if (!valid) {
  80. return false as any;
  81. }
  82. loginLoading.value = true;
  83. post(LOGIN, { ...ruleForm.value }).then(res => {
  84. if (res.code == 'error') {
  85. globalPopup?.showError(res.msg)
  86. loginLoading.value = false;
  87. return
  88. }
  89. globalPopup?.showSuccess('登录成功')
  90. loginLogic(res.data)
  91. // sessionStorage.setItem('token', res.data.id)
  92. // setValue(res.data, 'userInfo')
  93. // // 将数据分析放到第一位
  94. // const index = res.data?.moduleList.findIndex((obj: any) => obj.path === '/analysis');
  95. // if (index !== -1) {
  96. // const item = res.data?.moduleList.splice(index, 1)[0];
  97. // res.data?.moduleList.unshift(item);
  98. // }
  99. // console.log(res.data?.moduleList)
  100. // setValue(res.data?.moduleList, 'routers')
  101. // setTimeout(() => {
  102. // loginLoading.value = false;
  103. // // router.push(res.data?.moduleList[0].path);
  104. // router.push('/analysis');
  105. // }, 100)
  106. }).catch(_err => {
  107. loginLoading.value = false;
  108. })
  109. return
  110. // let newRouter = [
  111. // {
  112. // path: '/thread',
  113. // name: 'thread'
  114. // }
  115. // ]
  116. // setRouters(newRouter)
  117. // setTimeout(() => {
  118. // loginLoading.value = false;
  119. // router.push(newRouter[0].path);
  120. // }, 1000);
  121. })
  122. };
  123. const loginLogic = (data: any) => {
  124. if(data.moduleList.length <= 0) {
  125. alert('无权访问,请联系管理员为您分配权限')
  126. return
  127. }
  128. sessionStorage.setItem('token', data.id)
  129. setValue(data, 'userInfo')
  130. // 将数据分析放到第一位
  131. const index = data?.moduleList.findIndex((obj: any) => obj.path === '/analysis');
  132. if (index !== -1) {
  133. const item = data?.moduleList.splice(index, 1)[0];
  134. data?.moduleList.unshift(item);
  135. }
  136. setValue(data?.moduleList, 'routers')
  137. setTimeout(() => {
  138. loginLoading.value = false;
  139. // router.push(data?.moduleList[0].path);
  140. router.push('/analysis');
  141. }, 100)
  142. }
  143. const useHelp = () => {
  144. helpDialog.value = true;
  145. }
  146. const toRegister = () => {
  147. router.push("/register");
  148. }
  149. // 涉及第三方登录
  150. const checkLogin = () => { // 检查登录
  151. const userAgent = navigator.userAgent.toLowerCase();
  152. const href = window.location.href;
  153. const isCorpWXs = userAgent.includes("wxwork");
  154. if (isCorpWXs) {
  155. isCorpWX.value = true;
  156. }
  157. if (isCorpWX.value) {
  158. //企业微信环境下,尝试自动登录
  159. //判断企业微信,是否存在授权
  160. //尝试自动登录
  161. if (href.indexOf('hasTriedAutoLogin') == -1) {
  162. tryAutoLogin()
  163. } else if (href.indexOf("userId") > 0) {
  164. //后台经过验证后,重定向过来带上了userId
  165. var loginUserId = href.substring(href.indexOf("userId=") + "userId=".length);
  166. if (loginUserId.includes('#/')) {
  167. loginUserId = loginUserId.substring(0, loginUserId.indexOf('#/'));
  168. }
  169. if (loginUserId.includes('&')) {
  170. loginUserId = loginUserId.substring(0, loginUserId.indexOf('&'));
  171. }
  172. loginByUserId(loginUserId);
  173. }
  174. }
  175. }
  176. const loginByUserId = (userId: any) => {
  177. post(`/user/loginByUserId`, { userId }).then(res => {
  178. if (res.code == 'error') {
  179. globalPopup?.showError(res.msg)
  180. return
  181. }
  182. loginLogic(res.data)
  183. }).catch(err => {
  184. console.log(err)
  185. })
  186. }
  187. const tryAutoLogin = () => {
  188. var appId = "wwdd1137a65ce0fc87";//企业微信第三方的SUIT ID
  189. var url = "https://crm.ttkuaiban.com/api/corpWXAuth";//授权回调页面
  190. 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";
  191. window.location.href = weixinUrl;
  192. }
  193. const wxworkCli = () => {
  194. var appId = "wwdd1137a65ce0fc87";//企业微信第三方的SUIT ID
  195. var url = "https://crm.ttkuaiban.com/api/corpWXScanningAuth";//授权回调页面
  196. // var weixinUrl=`https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect?appid=${appId}&redirect_uri=${url}&state=0&usertype=member`;
  197. var weixinUrl=`https://login.work.weixin.qq.com/wwlogin/sso/login?login_type=ServiceApp&appid=${appId}&redirect_uri=${url}&state=0`;
  198. window.location.href = weixinUrl;
  199. }
  200. onMounted(() => {
  201. checkLogin()
  202. })
  203. </script>
  204. <style lang="scss" scoped>
  205. .loginView {
  206. background: #f0f2f5 url("../assets/login/background.png") no-repeat;
  207. }
  208. .service {
  209. display: none;
  210. width: 120px;
  211. position: absolute;
  212. background: #fff;
  213. text-align: center;
  214. padding: 10px;
  215. left: -30px;
  216. top: -210px;
  217. border-radius: 5px;
  218. box-shadow: 3px 3px 10px #dfdfdf;
  219. img {
  220. width: 80px;
  221. }
  222. }
  223. .btn:hover .service {
  224. display: block;
  225. }
  226. </style>