|
@@ -0,0 +1,332 @@
|
|
|
+<template>
|
|
|
+ <el-select
|
|
|
+ v-loading.fullscreen="companyChangeLoading"
|
|
|
+ :element-loading-text="'正在切换至 ' + getUserCompany().name + ' ......'"
|
|
|
+ element-loading-background="rgba(0, 0, 0, 0.8)"
|
|
|
+ element-loading-spinner="el-icon-loading"
|
|
|
+ :value="!global ? value : currentCompany"
|
|
|
+ :remote-method="handleRemoteSearch"
|
|
|
+ :placeholder="placeholder"
|
|
|
+ style="width:380px"
|
|
|
+ :disabled="disabled"
|
|
|
+ reserve-keyword
|
|
|
+ :size="size"
|
|
|
+ filterable
|
|
|
+ remote
|
|
|
+ @change="setCurrentCompany"
|
|
|
+ >
|
|
|
+ <!-- 当selectAll为true 且为超管账号允许选择所有公司 -->
|
|
|
+ <el-option v-if="selectAll && isSupertube" :label="allCompanyLabel" value="" />
|
|
|
+
|
|
|
+ <el-option
|
|
|
+ v-for="(company, index) in companylist"
|
|
|
+ :key="index"
|
|
|
+ class="custom-company"
|
|
|
+ :label="genCompanyLabel(company)"
|
|
|
+ :value="company.code"
|
|
|
+ />
|
|
|
+
|
|
|
+ <p v-if="state.loading" class="company-loading">
|
|
|
+ <i class="el-icon-loading" />
|
|
|
+ 加载中...
|
|
|
+ </p>
|
|
|
+
|
|
|
+ <p v-if="state.noMore" class="company-more">没有更多数据了...</p>
|
|
|
+ </el-select>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { requsetSupertubeCompany, requsetUserBindingCompany } from '@/apis/user'
|
|
|
+import { isBusinessCompany, isOnlyBusinessCompanyPath } from './utils'
|
|
|
+import { accountLevels } from '@/assets/js/statusList'
|
|
|
+import { userStoreActions } from '@/store/modules/user'
|
|
|
+import { getUserCompany } from '@/utils/auth'
|
|
|
+import { convertCompanylist } from '@/utils'
|
|
|
+import { mapGetters, mapState } from 'vuex'
|
|
|
+
|
|
|
+export default {
|
|
|
+ /**
|
|
|
+ * @param placeholder
|
|
|
+ * @param size 选择器尺寸
|
|
|
+ * @param disabled 是否禁用
|
|
|
+ * @param selectAll 超管账号是否可以选择所有公司
|
|
|
+ * @param global 是否设置全局选中公司(全局使用/组件独立使用)
|
|
|
+ */
|
|
|
+ props: {
|
|
|
+ selectAll: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ size: {
|
|
|
+ type: String,
|
|
|
+ default: 'small'
|
|
|
+ },
|
|
|
+ placeholder: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ disabled: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ global: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ value: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ isSupplier: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ allCompanyLabel() { return this.currentLevel === accountLevels.supplier ? '所有供应商' : '所有业务公司' },
|
|
|
+ ...mapGetters(['currentLevel']),
|
|
|
+ ...mapState({
|
|
|
+ currentCompany: state => state.user.currentCompany,
|
|
|
+ companylist: state => state.user.companylist,
|
|
|
+ isSupertube: state => state.user.isSupertube
|
|
|
+ })
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ ScrollWrapper: null,
|
|
|
+ initialization: true,
|
|
|
+ companyChangeLoading: false,
|
|
|
+ key: 1,
|
|
|
+ state: {
|
|
|
+ loading: false,
|
|
|
+ noMore: false
|
|
|
+ },
|
|
|
+ params: {
|
|
|
+ name: '',
|
|
|
+ page: 2,
|
|
|
+ size: 10
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ currentLevel: {
|
|
|
+ handler() {
|
|
|
+ if (!this.isSupertube) return
|
|
|
+ this.params = {
|
|
|
+ name: '',
|
|
|
+ page: 1,
|
|
|
+ size: 10
|
|
|
+ }
|
|
|
+ this.state = {
|
|
|
+ loading: false,
|
|
|
+ noMore: false
|
|
|
+ }
|
|
|
+ this.initalData()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async mounted() {
|
|
|
+ await this.initalData()
|
|
|
+ this.ScrollWrapper = await this.getScrollWrapper()
|
|
|
+ this.ScrollWrapper && this.bindEvent(this.ScrollWrapper)
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ this.ScrollWrapper && this.removeEvent(this.ScrollWrapper)
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getUserCompany,
|
|
|
+ genCompanyLabel(company) {
|
|
|
+ const { name, code, type } = company
|
|
|
+ return `${code}/${name}${type === '1' ? '(已升级为业务公司)' : ''}`
|
|
|
+ },
|
|
|
+ async initalData(reset = false) {
|
|
|
+ // 区分是否超管用户请求不同接口
|
|
|
+ this.state.loading = true
|
|
|
+ const api = this.isSupertube || this.isSupplier ? requsetSupertubeCompany : requsetUserBindingCompany
|
|
|
+ const isSupplier = this.currentLevel === accountLevels.supplier
|
|
|
+ const { page, size, name } = this.params
|
|
|
+ const params = {
|
|
|
+ ...(this.isSupertube ? { type: isSupplier ? '3' : '1' } : {}),
|
|
|
+ [this.isSupertube ? 'name' : 'companyName']: name,
|
|
|
+ page,
|
|
|
+ size
|
|
|
+ }
|
|
|
+
|
|
|
+ const { code, data } = await api(params)
|
|
|
+
|
|
|
+ if (code === 0) {
|
|
|
+ if (data.list.length < 10) this.state.noMore = true
|
|
|
+ this.state.loading = false
|
|
|
+ this.params.page++
|
|
|
+ const _list = this.isSupertube ? data.list : convertCompanylist(data.list)
|
|
|
+ this.$store.commit('user/setCompanylist', reset ? [...this.companylist, ..._list] : _list)
|
|
|
+ return this.isSupertube ? data.list : convertCompanylist(data.list)
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ setCurrentCompany(currentCompany) {
|
|
|
+ this.$emit('update:value', currentCompany)
|
|
|
+ this.$emit('change', currentCompany)
|
|
|
+ // 作为通用组件使用不设置全局选中公司
|
|
|
+ if (!this.global) return null
|
|
|
+ // 只能选择业务公司的页面
|
|
|
+ const { path } = this.$route
|
|
|
+ if (isOnlyBusinessCompanyPath(path) && !isBusinessCompany(currentCompany)) {
|
|
|
+ this.$message.warning('该页面只能选择业务公司')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.$store.commit(userStoreActions.setCurrentCompany, currentCompany)
|
|
|
+ if (this.isSupertube) return null // 超管用户不刷新路由
|
|
|
+ this.changeRouterWithCompany()
|
|
|
+ },
|
|
|
+
|
|
|
+ async changeRouterWithCompany() {
|
|
|
+ const { path, query } = this.$route
|
|
|
+ query.redirect = path
|
|
|
+ const keys = Object.keys(query).filter(key => key && key !== 'error')
|
|
|
+
|
|
|
+ // 1.保存透传参数
|
|
|
+ // 1.2 是否详情页
|
|
|
+ const isDetailPath = path.indexOf('Detail') >= 0
|
|
|
+ let queryString = ''
|
|
|
+ const chunk = (qs, key, index) => {
|
|
|
+ const next = `${key}=${query[key]}${index === keys.length ? '' : '&'}`
|
|
|
+ return qs + next
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2.重新获取用户信息和菜单
|
|
|
+ this.companyChangeLoading = true
|
|
|
+ const result = await this.$store.dispatch(userStoreActions.reloadMenu)
|
|
|
+ this.companyChangeLoading = false
|
|
|
+ switch (result) {
|
|
|
+ // 登出
|
|
|
+ case 'noToken':
|
|
|
+ await this.$store.dispatch('user/logout')
|
|
|
+ await this.$router.push(`/login`)
|
|
|
+ break
|
|
|
+
|
|
|
+ // 角色异常或该公司禁用清空菜单返回首页
|
|
|
+ case 'disabled':
|
|
|
+ await this.$store.dispatch('user/disabledCompany')
|
|
|
+ break
|
|
|
+
|
|
|
+ // 切换路由
|
|
|
+ default:
|
|
|
+ queryString = isDetailPath ? this.parsePathDetail2List(path) : keys.reduce(chunk, '?')
|
|
|
+ await this.$router.replace('/reload' + queryString)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ parsePathDetail2List(path) {
|
|
|
+ const chunks = path.split('Detail')
|
|
|
+ return `?redirect=${chunks[0]}`
|
|
|
+ },
|
|
|
+
|
|
|
+ getScrollWrapper() {
|
|
|
+ return new Promise(resolve => {
|
|
|
+ setTimeout(() => {
|
|
|
+ let optionEl = document.querySelector('.custom-company')
|
|
|
+ if (optionEl && (optionEl = optionEl.parentElement)) {
|
|
|
+ resolve(optionEl.parentElement)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ resolve(null)
|
|
|
+ }, 500)
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ async handleScroll() {
|
|
|
+ const ScrollWrapper = this.ScrollWrapper
|
|
|
+ const height = ScrollWrapper.clientHeight
|
|
|
+ const scrollTop = ScrollWrapper.scrollTop
|
|
|
+ const scrollHeight = ScrollWrapper.scrollHeight
|
|
|
+ const { loading, noMore } = this.state
|
|
|
+
|
|
|
+ // 是否允许下拉加载
|
|
|
+ const isAllowLoad = !loading && !noMore
|
|
|
+ if (height + scrollTop >= scrollHeight && isAllowLoad) {
|
|
|
+ const list = await this.loadMore()
|
|
|
+ const _list = this.isSupertube ? list : convertCompanylist(list)
|
|
|
+ // 保存到全局
|
|
|
+ this.$store.commit(userStoreActions.setCompanyList, [...this.companylist, ..._list])
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ async loadMore() {
|
|
|
+ // 区分超管用户和普通用户
|
|
|
+ const api = this.isSupertube ? requsetSupertubeCompany : requsetUserBindingCompany
|
|
|
+ const isSupplier = this.currentLevel === accountLevels.supplier
|
|
|
+ this.state.loading = true
|
|
|
+ const { page, size, name } = this.params
|
|
|
+ const nameProp = this.isSupertube ? 'name' : 'companyName'
|
|
|
+
|
|
|
+ const params = {
|
|
|
+ [nameProp]: name,
|
|
|
+ page,
|
|
|
+ size
|
|
|
+ }
|
|
|
+
|
|
|
+ const { data } = await api({
|
|
|
+ ...params,
|
|
|
+ ...(this.isSupertube ? { type: isSupplier ? '3' : '1' } : {})
|
|
|
+ })
|
|
|
+ this.state.loading = false
|
|
|
+ const isTransborder = this.companylist.length >= Number(data.count) // 是否越界
|
|
|
+
|
|
|
+ if (isTransborder) {
|
|
|
+ this.state.noMore = true
|
|
|
+ this.state.loading = false
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ this.params.page++
|
|
|
+ return data.list
|
|
|
+ },
|
|
|
+
|
|
|
+ async handleRemoteSearch(name) {
|
|
|
+ // 清空全局业务公司列表
|
|
|
+ this.$store.commit(userStoreActions.setCompanyList, [])
|
|
|
+ this.params.name = name
|
|
|
+ this.params.page = 1
|
|
|
+ this.state.noMore = false
|
|
|
+ this.state.loading = false
|
|
|
+ // 获取列表数据
|
|
|
+ const result = await this.initalData()
|
|
|
+ if (result) this.$store.commit(userStoreActions.setCompanyList, result)
|
|
|
+ },
|
|
|
+
|
|
|
+ bindEvent(ScrollWrapper) {
|
|
|
+ ScrollWrapper.addEventListener('scroll', this.handleScroll)
|
|
|
+ },
|
|
|
+
|
|
|
+ removeEvent(ScrollWrapper) {
|
|
|
+ ScrollWrapper.removeEventListener('scroll', this.handleScroll)
|
|
|
+ },
|
|
|
+
|
|
|
+ selectAllCompany() {
|
|
|
+ this.value = ''
|
|
|
+ this.$nextTick(() => (this.key = this.key + 1))
|
|
|
+ this.global && this.$store.commit(userStoreActions.setCurrentCompany, '')
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.company-more {
|
|
|
+ text-align: center;
|
|
|
+ color: #999;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 38px;
|
|
|
+}
|
|
|
+
|
|
|
+.company-loading {
|
|
|
+ display: flex;
|
|
|
+ font-size: 14px;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ color: #999;
|
|
|
+ gap: 10px;
|
|
|
+ line-height: 38px;
|
|
|
+}
|
|
|
+</style>
|