Skip to content
本页目录

六、后台管理端【商家信息】页面逻辑

6.1 用户登录逻辑

核心逻辑: 登录成功后存储Token、 获取用户信息、 有用户信息 ? 跳转首页 : 跳转上传商家信息页

vue
<script>
export default {
 	methods: {
        // 登录
		async login() {
			this.loading = true
			try {
				const { data } = await loginApi(userInfo)
                // 保存token
                setToken(data)
                // 获取用户信息
                const { data: info } = await getShopInfoApi()
                this.$message.success('登录成功')
				this.loading = false
                // 判断是否有用户信息
                if (!info) {
					next('/modify-info')
				} else {
					next('/dashboard')
				}
			} catch (error) {
				this.loading = false
			}
		}
    }   
}
</script>

6.2 上传商家信息页

src/views/settings/modify-info.vue

核心逻辑: 收集商家信息, 图片上传, 提交商家信息

  • 收集商家信息
vue
<template>
	<!-- 店铺名称 -->
    <div class="image-view-title">
        <div class="image-list">店铺名称</div>
        <el-input v-model="formInput.name" placeholder="请输入店铺名称"></el-input>
    </div>
    <!-- 店铺地址 -->
    <div class="image-view-title">
        <div class="image-list">店铺地址</div>
        <el-input v-model="formInput.address" type="text" placeholder="请输入店铺地址"></el-input>
    </div>
    <!-- 店铺logo -->
    <div class="image-view-title">
        <div class="image-list">店铺logo</div>
        <el-input v-model="formInput.logo" placeholder="请输入Logo"></el-input>
    </div>

    <!-- 提交 -->
    <div class="image-button">
        <el-button type="success" size="medium" @click="submitForm" :loading="loading">提交</el-button>
    </div>
</template>

<script>
export default {
	data() {
		return {
			formInput: {
				name: '',
				address: '',
				logo: ''
			},
      loading: false
		}
	},
}
</script>
  • 上传图片
vue
<template>
	<el-upload
        class="avatar-uploader"
        :action="actions"
        :headers="{ authorization: 'Bearer ' + token }"
        :show-file-list="false"
        :on-success="handleAvatarSuccess"
        :before-upload="beforeAvatarUpload"
    >
        <img v-if="formInput.logo" :src="formInput.logo" class="avatar" />
        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
</template>

<script>
export default {
    methods: {
		handleAvatarSuccess(res, file) {
      		this.formInput.logo = res.data
		},
		beforeAvatarUpload(file) {
			const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'
			const isLt2M = file.size / 1024 / 1024 < 2

			if (!isJPG) {
				this.$message.error('上传头像图片只能是 JPG、PNG 格式!')
			}
			if (!isLt2M) {
				this.$message.error('上传头像图片大小不能超过 2MB!')
			}
			return isJPG && isLt2M
		}
    }
}
</script>
  • 提交商家信息
js
async submitForm() {
  this.loading = true
  const requestApi = addShopInfoApi
  try {
    await requestApi(this.formInput)
    this.$message.success('操作成功')
    this.loading = false
    // 新增则跳转首页  修改则返回信息页
    this.$router.push(this.shopInfo ? '/settings' : '/')
  } catch (error) {
    this.loading = false
  }
}

6.3 路由验证文件

核心逻辑: 未登录用户禁止进入主页, 未设置商家信息禁止进入主页, 进入后拉取商家信息

修改登录逻辑 将登录逻辑改写到vuex中


store/index.js

js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'

Vue.use(Vuex)

export default new Vuex.Store({
	modules: { user },
  	getters: {
    	shopName: state => state.user.shopInfo?.name,
    	token: state => state.user.token
  	}
})

store/module/user.js

修改登录逻辑获取商家信息方法, 用户退出登录方法

js
// 用户模块(商家)
import { loginApi } from "@/api/auth"
import { getShopInfoApi } from "@/api/merchant-info"
import { getToken, removeToken, setToken } from "@/utils/auth"

const defaultState = () => ({
  token: getToken(),
  shopInfo: null
})

const mutations = {
  SET_TOKEN (state, token) {
    state.token = token
  },
  SET_INFO (state, info) {
    state.shopInfo = info
  }
}

const actions = {
  // 登录
  async login({ commit, dispatch }, userInfo) {
    const { data } = await loginApi(userInfo)
    setToken(data)
    commit('SET_TOKEN', data)
  },
  // 获取商家信息
  async getShopInfo ({ commit }) {
    const { data } = await getShopInfoApi()
    commit('SET_INFO', data)
    return data
  },
  // 退出登录
  logout({ commit }) {
    removeToken()
    commit('SET_TOKEN', '')
    commit('SET_INFO', '')
  }
}

const getters = {}

export default {
	namespaced: true,
	state: defaultState(),
	mutations,
	actions,
	getters
}

views/login.vue

js
// 登录
async login() {
    this.loading = true
    try {
        await this.$store.dispatch('user/login', this.formInput)
        this.$message.success('登录成功')
        this.loading = false
        this.$router.push('/dashboard')
    } catch (error) {
        this.loading = false
    }
}

permission.js 核心代码

js
// 路由前置守卫
router.beforeEach(async (to, from, next) => {
	console.log('路由进入前')
	// 开启加载进度条
	NProgress.start()

	// 设置页面标题
	document.title = getPageTitle(to.meta.title)

	// 判断用户是否登录?  ->  登录 放行  -> 未登录 跳转登录页面
	// 1. 取出token值【登录凭证】
	const token = store.getters.token
	// 2. 判断是否有token
	if (token) {
		// 3. 验证是否有商家信息【商家信息页 不需要验证】
		if (store.getters.shopName || to.path === '/modify-info') {
			// 4. 有商家信息
			next()
		} else {
			try {
				// 5. 无商家信息  重新拉取商家信息
				const info = await store.dispatch('user/getShopInfo')
				// 6. 拉取后还是无商家信息【跳转商家信息页】
				if (!info) {
					next('/modify-info')
				} else {
					next()
				}
			} catch (error) {
				// 5. 拉取信息失败
				store.dispatch('user/logout')
				next('/login')
			}
		}
	} else {
		// 3. 无token  判断当前页面是否为登录【直接放行 / 跳转登录】
		if (to.path === '/login') {
          next()
        } else {
          next('/login')
        }
	}
  	// 关闭加载进度条
	NProgress.done()
})

6.4 商家信息页

商家信息页 主要为展示页面 展示商家信息

核心逻辑: 通过vuex拉取信息 跳转修改商家信息页

6.5 修改商家信息页

需要的逻辑: 返回上一页 渲染商家信息 提交商家信息修改

  • 返回上一页: 判断是否有商家信息 有则显示返回上一页
vue
<p @click="$router.push('/settings')" v-if="shopInfo">返回上一页</p>
  • 渲染商家信息: 从vuex拉取商家信息 有则渲染到formInput
js
computed: {
    ...mapState('user', ['shopInfo', 'token']),
    title() {
        return this.shopInfo ? '修改店铺信息' : '设置店铺信息'
    }
},
mounted() {
    // 判断是否为信息
    if (this.shopInfo.name) {
      this.formInput = { ...this.shopInfo }
    }
}
  • 提交商家信息修改: 判断shopInfo是否有值 ? 修改 : 设置