login.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <template>
  2. <div class="login flex flex-col">
  3. <div class="flex-1 flex items-center justify-center">
  4. <div class="login-card flex rounded-md">
  5. <div class="flex-1 h-full hidden md:inline-block">
  6. <image-contain :src="config.webBackdrop" :width="400" height="100%"/>
  7. </div>
  8. <div
  9. class="login-form bg-body flex flex-col justify-center px-10 py-10 md:w-[400px] w-[375px] flex-none mx-auto"
  10. >
  11. <div class="text-center text-3xl font-medium mb-8">{{ config.webName }}</div>
  12. <div v-if="!showMerchant">
  13. <el-form ref="formRef" :model="formData" size="large" :rules="rules">
  14. <el-form-item prop="account">
  15. <el-input
  16. v-model.trim="formData.account"
  17. placeholder="请输入账号"
  18. @keyup.enter="handleEnter"
  19. >
  20. <template #prepend>
  21. <icon name="el-icon-User"/>
  22. </template>
  23. </el-input>
  24. </el-form-item>
  25. <el-form-item prop="password">
  26. <el-input
  27. ref="passwordRef"
  28. v-model="formData.password"
  29. show-password
  30. placeholder="请输入密码"
  31. @keyup.enter="handleLogin"
  32. >
  33. <template #prepend>
  34. <icon name="el-icon-Lock"/>
  35. </template>
  36. </el-input>
  37. </el-form-item>
  38. </el-form>
  39. <div class="mb-5">
  40. <el-checkbox v-model="remAccount" label="记住账号"></el-checkbox>
  41. </div>
  42. <el-button class="w-80" type="primary" size="large" :loading="isLock" @click="lockLogin">
  43. 登录
  44. </el-button>
  45. </div>
  46. <!-- 商户列表 -->
  47. <div v-if="showMerchant">
  48. <el-table
  49. :data="tableData" class="w-80" height="180"
  50. highlight-current-row
  51. highlight-selection-row
  52. :showHeader="false"
  53. @current-change="handleCurrentChange">
  54. <el-table-column
  55. prop="name"
  56. label="店铺名称">
  57. </el-table-column>
  58. </el-table>
  59. <el-button class="w-80" type="primary" size="large" @click="handleEnterStore" style="margin-top: 15px">
  60. 进入店铺
  61. </el-button>
  62. </div>
  63. </div>
  64. </div>
  65. </div>
  66. <layout-footer/>
  67. </div>
  68. </template>
  69. <script lang="ts" setup>
  70. import {computed, onMounted, reactive, ref, shallowRef} from 'vue'
  71. import type {FormInstance, InputInstance} from 'element-plus'
  72. import LayoutFooter from '@/layout/components/footer.vue'
  73. import useAppStore from '@/stores/modules/app'
  74. import useUserStore from '@/stores/modules/user'
  75. import cache from '@/utils/cache'
  76. import {ACCOUNT_KEY, SHOP_ID} from '@/enums/cacheEnums'
  77. import {PageEnum} from '@/enums/pageEnum'
  78. import {useLockFn} from '@/hooks/useLockFn'
  79. import {getShopConfigList} from "@/api/shop";
  80. import feedback from "@/utils/feedback";
  81. import {clearAuthInfo} from "@/utils/auth";
  82. const passwordRef = shallowRef<InputInstance>()
  83. const formRef = shallowRef<FormInstance>()
  84. const appStore = useAppStore()
  85. const userStore = useUserStore()
  86. const route = useRoute()
  87. const router = useRouter()
  88. const remAccount = ref(false)
  89. const config = computed(() => appStore.config)
  90. const showMerchant = ref(false)
  91. const currentRow = ref({})
  92. const formData = reactive({
  93. account: '',
  94. password: '',
  95. // code: '',
  96. uuid: ''
  97. })
  98. const rules = {
  99. account: [
  100. {
  101. required: true,
  102. message: '请输入账号',
  103. trigger: ['blur']
  104. }
  105. ],
  106. password: [
  107. {
  108. required: true,
  109. message: '请输入密码',
  110. trigger: ['blur']
  111. }
  112. ]
  113. }
  114. const tableData = ref([])
  115. const handleCurrentChange = (row: any) => {
  116. currentRow.value = row
  117. }
  118. const handleEnterStore = () => {
  119. if (!currentRow.value.id) {
  120. feedback.msgWarning('请选择一个店铺进入平台')
  121. return
  122. }
  123. if (currentRow.value.id) {
  124. cache.set(SHOP_ID, currentRow.value.id)
  125. window.localStorage.setItem("like_admin_houseId", currentRow.value.houseId)
  126. config.value.webName = currentRow.name
  127. if(currentRow.image){
  128. config.value.webLogo = currentRow.image
  129. }
  130. const {
  131. query: {redirect}
  132. } = route
  133. const path = typeof redirect === 'string' ? redirect : PageEnum.INDEX
  134. router.push(path)
  135. }
  136. }
  137. // 回车按键监听
  138. const handleEnter = () => {
  139. if (!formData.password) {
  140. return passwordRef.value?.focus()
  141. }
  142. handleLogin()
  143. }
  144. const handleShopConfig = (params: any) => {
  145. getShopConfigList({"contactTel": formData.account, houseIds: params}).then((res) => {
  146. if (res && res.length > 0) {
  147. if (res.length == 1) {
  148. cache.set(SHOP_ID, res[0].id)
  149. window.localStorage.setItem("like_admin_houseId",res[0].houseId)
  150. config.value.webName = res[0].name
  151. if(res[0].image){
  152. config.value.webLogo = res[0].image
  153. }
  154. const {
  155. query: {redirect}
  156. } = route
  157. const path = typeof redirect === 'string' ? redirect : PageEnum.INDEX
  158. router.push(path)
  159. } else {
  160. showMerchant.value = true
  161. tableData.value = res.map((item: any) => {
  162. return {
  163. id: item.id,
  164. name: item.name,
  165. houseId: item.houseId,
  166. image: item.image
  167. }
  168. })
  169. }
  170. } else {
  171. clearAuthInfo()
  172. router.push(PageEnum.ERROR_403)
  173. }
  174. })
  175. }
  176. // 登录处理
  177. const handleLogin = async () => {
  178. await formRef.value?.validate()
  179. // 记住账号,缓存
  180. cache.set(ACCOUNT_KEY, {
  181. remember: remAccount.value,
  182. account: formData.account
  183. })
  184. try {
  185. let _data = {
  186. "mobile": formData.account,
  187. "passWord": formData.password,
  188. "platform": 1,//平台 1.大麦数字营销 2.大麦后台 3.麦芽 4.淘房客 5.电商中心
  189. }
  190. await userStore.login(_data).then((res: any) => {
  191. if(res.type === 1){
  192. clearAuthInfo()
  193. router.push(PageEnum.ERROR_403)
  194. } else {
  195. const houseIds = res.houseList.map((item: any) => item.houseId)
  196. handleShopConfig(houseIds)
  197. }
  198. })
  199. } catch (error) {
  200. // getLoginCaptcha()
  201. }
  202. /*const {
  203. query: {redirect}
  204. } = route
  205. const path = typeof redirect === 'string' ? redirect : PageEnum.INDEX
  206. router.push(path)*/
  207. }
  208. const {isLock, lockFn: lockLogin} = useLockFn(handleLogin)
  209. onMounted(() => {
  210. const value = cache.get(ACCOUNT_KEY)
  211. // getLoginCaptcha()
  212. if (value?.remember) {
  213. remAccount.value = value.remember
  214. formData.account = value.account
  215. }
  216. })
  217. </script>
  218. <style lang="scss" scoped>
  219. .login {
  220. background-image: url('./images/login_bg.png');
  221. @apply min-h-screen bg-no-repeat bg-center bg-cover;
  222. .login-card {
  223. height: 400px;
  224. :deep(.el-input-group__prepend) {
  225. padding: 0 15px;
  226. }
  227. }
  228. }
  229. </style>