login.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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">电话:</span><span id="QQ">15895914665</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. data.moduleList = data.moduleList.filter((item: any) => item.path != '/corpreport')
  134. sessionStorage.setItem('isExistBusiness', data.company.isExistBusiness || 0)
  135. sessionStorage.setItem('token', data.id)
  136. localStorage.setItem('SUPERSONIC_TOKEN', data.supersonicToken)
  137. setValue(data, 'userInfo')
  138. // 将数据分析放到第一位
  139. const index = data?.moduleList.findIndex((obj: any) => obj.path === '/analysis');
  140. if (index !== -1) {
  141. const item = data?.moduleList.splice(index, 1)[0];
  142. data?.moduleList.unshift(item);
  143. }
  144. setValue(data?.moduleList, 'routers')
  145. setTimeout(() => {
  146. loginLoading.value = false;
  147. // router.push(data?.moduleList[0].path);
  148. router.push('/analysis');
  149. }, 100)
  150. }
  151. const useHelp = () => {
  152. helpDialog.value = true;
  153. }
  154. const toRegister = () => {
  155. router.push("/register");
  156. }
  157. // 涉及第三方登录
  158. const checkLogin = () => { // 检查登录
  159. const userAgent = navigator.userAgent.toLowerCase();
  160. const href = window.location.href;
  161. const isCorpWXs = userAgent.includes("wxwork");
  162. if (isCorpWXs) {
  163. isCorpWX.value = true;
  164. }
  165. //直接使用userId进入系统,可能是后端授权成功后跳转过来的,也能方便开发人员调试
  166. if (href.indexOf("userId") > 0) {
  167. isCorpWX.value = true;
  168. //后台经过验证后,重定向过来带上了userId
  169. var loginUserId = href.substring(href.indexOf("userId=") + "userId=".length);
  170. if (loginUserId.includes('#/')) {
  171. loginUserId = loginUserId.substring(0, loginUserId.indexOf('#/'));
  172. }
  173. if (loginUserId.includes('&')) {
  174. loginUserId = loginUserId.substring(0, loginUserId.indexOf('&'));
  175. }
  176. loginByUserId(loginUserId);
  177. }
  178. }
  179. const loginByUserId = (userId: any) => {
  180. post(`/user/loginByUserId`, { userId }).then(res => {
  181. if (res.code == 'error') {
  182. globalPopup?.showError(res.msg)
  183. return
  184. }
  185. loginLogic(res.data)
  186. }).catch(err => {
  187. console.log(err)
  188. })
  189. }
  190. const tryAutoLogin = () => {
  191. var appId = "wwdd1137a65ce0fc87";//企业微信第三方的SUIT ID
  192. var url = "https://crm.ttkuaiban.com/api/corpWXAuth";//授权回调页面
  193. 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";
  194. window.location.href = weixinUrl;
  195. }
  196. const wxworkCli = () => {
  197. var appId = "ww19f9868980b9bb43";//服务商新版登录授权suitId
  198. var url = "https://crm.ttkuaiban.com/api/corpWXScanningAuth";//授权回调页面
  199. // var weixinUrl=`https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect?appid=${appId}&redirect_uri=${url}&state=0&usertype=member`;
  200. var weixinUrl=`https://login.work.weixin.qq.com/wwlogin/sso/login?login_type=ServiceApp&appid=${appId}&redirect_uri=${url}&state=0`;
  201. window.location.href = weixinUrl;
  202. }
  203. onMounted(() => {
  204. checkLogin()
  205. })
  206. </script>
  207. <style lang="scss" scoped>
  208. .loginView {
  209. background: #f0f2f5 url("../assets/login/background.png") no-repeat;
  210. }
  211. .service {
  212. display: none;
  213. width: 120px;
  214. position: absolute;
  215. background: #fff;
  216. text-align: center;
  217. padding: 10px;
  218. left: -30px;
  219. top: -210px;
  220. border-radius: 5px;
  221. box-shadow: 3px 3px 10px #dfdfdf;
  222. img {
  223. width: 80px;
  224. }
  225. }
  226. .btn:hover .service {
  227. display: block;
  228. }
  229. </style>