Merge branch 'main' of http://114.55.169.15:3000/qiushanhe/ss-crm-manage-web into dev-cl
This commit is contained in:
@@ -2,19 +2,19 @@
|
|||||||
import { isDark } from '@/utils/is'
|
import { isDark } from '@/utils/is'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
import routerSearch from '@/components/RouterSearch/index.vue'
|
import routerSearch from '@/components/RouterSearch/index.vue'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
const { getPrefixCls } = useDesign()
|
const { getPrefixCls } = useDesign()
|
||||||
const prefixCls = getPrefixCls('app')
|
const prefixCls = getPrefixCls('app')
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const currentSize = computed(() => appStore.getCurrentSize)
|
const currentSize = computed(() => appStore.getCurrentSize)
|
||||||
const greyMode = computed(() => appStore.getGreyMode)
|
const greyMode = computed(() => appStore.getGreyMode)
|
||||||
const { wsCache } = useCache()
|
|
||||||
|
|
||||||
// 根据浏览器当前主题设置系统主题色
|
// 根据浏览器当前主题设置系统主题色
|
||||||
const setDefaultTheme = () => {
|
const setDefaultTheme = () => {
|
||||||
let isDarkTheme = wsCache.get(CACHE_KEY.IS_DARK)
|
let isDarkTheme = cache.local.get(CACHE_KEY.IS_DARK)
|
||||||
if (isDarkTheme === null) {
|
if (isDarkTheme === null) {
|
||||||
isDarkTheme = isDark()
|
isDarkTheme = isDark()
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/api/clue/extraFee.js
Normal file
30
src/api/clue/extraFee.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// 获得列表
|
||||||
|
export const getExtraFeePage = (params) => {
|
||||||
|
return request.get({ url: '/admin-api/crm/extra-pay/page', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建
|
||||||
|
export const createExtraFee = (data) => {
|
||||||
|
return request.post({ url: '/admin-api/crm/extra-pay/create', data, isSubmitForm: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新
|
||||||
|
export const updateExtraFee = (data) => {
|
||||||
|
return request.put({ url: '/admin-api/crm/extra-pay/update', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
export const deleteExtraFee = (id) => {
|
||||||
|
return request.delete({ url: `/admin-api/crm/extra-pay/delete?id=${id}` })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得
|
||||||
|
export const getExtraFee = (id) => {
|
||||||
|
return request.get({ url: `/admin-api/crm/extra-pay/get?id=${id}` })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getExtraFeeSimpleList = async () => {
|
||||||
|
return await request.get({ url: '/admin-api/crm/extra-pay/simple-list' })
|
||||||
|
}
|
||||||
@@ -58,3 +58,7 @@ export const getPublicClue = async (data) => {
|
|||||||
export const getFollowUserList = async (params) => {
|
export const getFollowUserList = async (params) => {
|
||||||
return await request.get({ url: '/admin-api/crm/sch-clue/get-follow-user', params })
|
return await request.get({ url: '/admin-api/crm/sch-clue/get-follow-user', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const batchUpdateFollowUser = async (data) => {
|
||||||
|
return await request.put({ url: '/admin-api/crm/sch-clue/batchUpdateFollowUser', data })
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-table :data="tableObject.tableList" border style="flex: 1">
|
<el-table
|
||||||
|
:data="tableObject.tableList"
|
||||||
|
border
|
||||||
|
style="flex: 1"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-button
|
<el-button
|
||||||
@@ -56,7 +61,7 @@ const props = defineProps({
|
|||||||
tableColumns: { type: Array, default: () => [] }
|
tableColumns: { type: Array, default: () => [] }
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:tableObject', 'getList', 'getCheckedColumns'])
|
const emit = defineEmits(['update:tableObject', 'getList', 'getCheckedColumns', 'selection-change'])
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const pageNo = ref(props.tableObject?.pageNo || 1)
|
const pageNo = ref(props.tableObject?.pageNo || 1)
|
||||||
@@ -110,6 +115,10 @@ function onDragEnd() {
|
|||||||
emitColumns()
|
emitColumns()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleSelectionChange(val) {
|
||||||
|
emit('selection-change', val)
|
||||||
|
}
|
||||||
|
|
||||||
// 勾选确认
|
// 勾选确认
|
||||||
function confirm() {
|
function confirm() {
|
||||||
ClueCacheApi.setClueCache({
|
ClueCacheApi.setClueCache({
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import {
|
|||||||
import errorCode from './errorCode'
|
import errorCode from './errorCode'
|
||||||
|
|
||||||
import { resetRouter } from '@/router'
|
import { resetRouter } from '@/router'
|
||||||
import { useCache } from '@/hooks/web/useCache'
|
|
||||||
import cache from '@/plugins/cache'
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
const { result_code, base_url, request_timeout } = config
|
const { result_code, base_url, request_timeout } = config
|
||||||
@@ -213,11 +212,10 @@ service.interceptors.response.use(
|
|||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
// 无访问权限,退出登录
|
// 无访问权限,退出登录
|
||||||
const { wsCache } = useCache()
|
const tenantId = cache.local.get('TENANT_ID')
|
||||||
const tenantId = wsCache.get('TENANT_ID')
|
const appId = cache.local.get('App_ID')
|
||||||
const appId = wsCache.get('App_ID')
|
|
||||||
resetRouter() // 重置静态路由表
|
resetRouter() // 重置静态路由表
|
||||||
wsCache.clear()
|
cache.local.clear()
|
||||||
removeToken()
|
removeToken()
|
||||||
window.location.href = `/crm/login?tenantId=${tenantId}&appId=${appId}`
|
window.location.href = `/crm/login?tenantId=${tenantId}&appId=${appId}`
|
||||||
})
|
})
|
||||||
@@ -259,11 +257,10 @@ const handleAuthorized = () => {
|
|||||||
confirmButtonText: t('login.relogin'),
|
confirmButtonText: t('login.relogin'),
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
const { wsCache } = useCache()
|
const tenantId = cache.local.get('TENANT_ID')
|
||||||
const tenantId = wsCache.get('TENANT_ID')
|
const appId = cache.local.get('App_ID')
|
||||||
const appId = wsCache.get('App_ID')
|
|
||||||
resetRouter() // 重置静态路由表
|
resetRouter() // 重置静态路由表
|
||||||
wsCache.clear()
|
cache.local.clear()
|
||||||
removeToken()
|
removeToken()
|
||||||
isRelogin.show = false
|
isRelogin.show = false
|
||||||
// 干掉token后再走一次路由让它过router.beforeEach的校验
|
// 干掉token后再走一次路由让它过router.beforeEach的校验
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import type { App } from 'vue'
|
import type { App } from 'vue'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
export function hasPermi(app: App<Element>) {
|
export function hasPermi(app: App<Element>) {
|
||||||
app.directive('hasPermi', (el, binding) => {
|
app.directive('hasPermi', (el, binding) => {
|
||||||
const { wsCache } = useCache()
|
|
||||||
const { value } = binding
|
const { value } = binding
|
||||||
const all_permission = '*:*:*'
|
const all_permission = '*:*:*'
|
||||||
const permissions = wsCache.get(CACHE_KEY.USER)?.permissions || []
|
const permissions = cache.local.get(CACHE_KEY.USER)?.permissions || []
|
||||||
|
|
||||||
if (value && value instanceof Array && value.length > 0) {
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
const permissionFlag = value
|
const permissionFlag = value
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import type { App } from 'vue'
|
import type { App } from 'vue'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
export function hasRole(app: App<Element>) {
|
export function hasRole(app: App<Element>) {
|
||||||
app.directive('hasRole', (el, binding) => {
|
app.directive('hasRole', (el, binding) => {
|
||||||
const { wsCache } = useCache()
|
|
||||||
const { value } = binding
|
const { value } = binding
|
||||||
const super_admin = 'admin'
|
const super_admin = 'admin'
|
||||||
const roles = wsCache.get(CACHE_KEY.USER).roles
|
const roles = cache.local.get(CACHE_KEY.USER).roles
|
||||||
|
|
||||||
if (value && value instanceof Array && value.length > 0) {
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
const roleFlag = value
|
const roleFlag = value
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
// import { ElMessage } from 'element-plus'
|
// import { ElMessage } from 'element-plus'
|
||||||
// import { useClipboard, useCssVar } from '@vueuse/core'
|
// import { useClipboard, useCssVar } from '@vueuse/core'
|
||||||
import { useCssVar } from '@vueuse/core'
|
import { useCssVar } from '@vueuse/core'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
import { setCssVar, trim } from '@/utils'
|
import { setCssVar, trim } from '@/utils'
|
||||||
import { colorIsDark, hexToRGB, lighten } from '@/utils/color'
|
import { colorIsDark, hexToRGB, lighten } from '@/utils/color'
|
||||||
@@ -195,10 +196,9 @@ watch(
|
|||||||
|
|
||||||
// 清空缓存
|
// 清空缓存
|
||||||
const clear = () => {
|
const clear = () => {
|
||||||
const { wsCache } = useCache()
|
cache.local.delete(CACHE_KEY.LAYOUT)
|
||||||
wsCache.delete(CACHE_KEY.LAYOUT)
|
cache.local.delete(CACHE_KEY.THEME)
|
||||||
wsCache.delete(CACHE_KEY.THEME)
|
cache.local.delete(CACHE_KEY.IS_DARK)
|
||||||
wsCache.delete(CACHE_KEY.IS_DARK)
|
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
<script lang="ts" name="UserInfo" setup>
|
<script lang="ts" name="UserInfo" setup>
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus'
|
||||||
|
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import avatarImg from '@/assets/imgs/avatar.gif'
|
import avatarImg from '@/assets/imgs/avatar.gif'
|
||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/store/modules/user'
|
||||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
import { useTagsViewStore } from '@/store/modules/tagsView'
|
||||||
import { getTenantId, getAppId } from '@/utils/auth'
|
import { getTenantId, getAppId } from '@/utils/auth'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
import { Setting } from '@/layout/components/Setting'
|
import { Setting } from '@/layout/components/Setting'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const { wsCache } = useCache()
|
|
||||||
|
|
||||||
const { push, replace } = useRouter()
|
const { push, replace } = useRouter()
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
@@ -24,7 +23,7 @@ const { getPrefixCls } = useDesign()
|
|||||||
|
|
||||||
const prefixCls = getPrefixCls('user-info')
|
const prefixCls = getPrefixCls('user-info')
|
||||||
|
|
||||||
const user = wsCache.get(CACHE_KEY.USER)
|
const user = cache.local.get(CACHE_KEY.USER)
|
||||||
|
|
||||||
const avatar = user.user.avatar ? user.user.avatar : avatarImg
|
const avatar = user.user.avatar ? user.user.avatar : avatarImg
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import router from './router'
|
import router from './router'
|
||||||
import { isRelogin } from '@/config/axios/service'
|
import { isRelogin } from '@/config/axios/service'
|
||||||
import { getAccessToken } from '@/utils/auth'
|
import { getAccessToken, removeToken } from '@/utils/auth'
|
||||||
import { useTitle } from '@/hooks/web/useTitle'
|
import { useTitle } from '@/hooks/web/useTitle'
|
||||||
import { useNProgress } from '@/hooks/web/useNProgress'
|
import { useNProgress } from '@/hooks/web/useNProgress'
|
||||||
import { usePageLoading } from '@/hooks/web/usePageLoading'
|
import { usePageLoading } from '@/hooks/web/usePageLoading'
|
||||||
@@ -8,6 +8,7 @@ import { useDictStoreWithOut } from '@/store/modules/dict'
|
|||||||
import { useUserStoreWithOut } from '@/store/modules/user'
|
import { useUserStoreWithOut } from '@/store/modules/user'
|
||||||
import { usePermissionStoreWithOut } from '@/store/modules/permission'
|
import { usePermissionStoreWithOut } from '@/store/modules/permission'
|
||||||
import { getTenantId, getAppId } from '@/utils/auth'
|
import { getTenantId, getAppId } from '@/utils/auth'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
const { start, done } = useNProgress()
|
const { start, done } = useNProgress()
|
||||||
|
|
||||||
@@ -19,44 +20,53 @@ const whiteList = ['/login', '/social-login', '/auth-redirect', '/bind', '/regis
|
|||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
start()
|
start()
|
||||||
loadStart()
|
loadStart()
|
||||||
if (getAccessToken()) {
|
if (getAppId() && to.query?.appId && getAppId() != to.query?.appId) {
|
||||||
if (to.path === '/login') {
|
removeToken()
|
||||||
next({ path: '/' })
|
cache?.local?.delete('appInfo')
|
||||||
} else {
|
cache?.local?.delete('roleRouters')
|
||||||
// 获取所有字典
|
cache?.local?.delete('user')
|
||||||
const dictStore = useDictStoreWithOut()
|
cache?.local?.delete('App_ID')
|
||||||
const userStore = useUserStoreWithOut()
|
next(`/login?tenantId=${to.query?.tenantId}&appId=${to.query?.appId}`)
|
||||||
const permissionStore = usePermissionStoreWithOut()
|
|
||||||
if (!dictStore.getIsSetDict) {
|
|
||||||
await dictStore.setDictMap()
|
|
||||||
}
|
|
||||||
if (!userStore.getIsSetUser) {
|
|
||||||
isRelogin.show = true
|
|
||||||
await userStore.setUserInfoAction()
|
|
||||||
isRelogin.show = false
|
|
||||||
// 后端过滤菜单
|
|
||||||
await permissionStore.generateRoutes()
|
|
||||||
permissionStore.getAddRouters.forEach((route) => {
|
|
||||||
router.addRoute(route) // 动态添加可访问路由表
|
|
||||||
})
|
|
||||||
const redirectPath = from.query.redirect || to.path
|
|
||||||
const redirect = decodeURIComponent(redirectPath)
|
|
||||||
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect }
|
|
||||||
next(nextData)
|
|
||||||
} else {
|
|
||||||
next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (whiteList.indexOf(to.path) !== -1) {
|
if (getAccessToken()) {
|
||||||
next()
|
if (to.path === '/login') {
|
||||||
} else {
|
next({ path: '/' })
|
||||||
const tenantId = getTenantId()
|
|
||||||
const appId = getAppId()
|
|
||||||
if (tenantId && appId) {
|
|
||||||
next(`/crm/login?tenantId=${tenantId}&appId=${appId}&redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
|
||||||
} else {
|
} else {
|
||||||
next(`/crm/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
// 获取所有字典
|
||||||
|
const dictStore = useDictStoreWithOut()
|
||||||
|
const userStore = useUserStoreWithOut()
|
||||||
|
const permissionStore = usePermissionStoreWithOut()
|
||||||
|
if (!dictStore.getIsSetDict) {
|
||||||
|
await dictStore.setDictMap()
|
||||||
|
}
|
||||||
|
if (!userStore.getIsSetUser) {
|
||||||
|
isRelogin.show = true
|
||||||
|
await userStore.setUserInfoAction()
|
||||||
|
isRelogin.show = false
|
||||||
|
// 后端过滤菜单
|
||||||
|
await permissionStore.generateRoutes()
|
||||||
|
permissionStore.getAddRouters.forEach((route) => {
|
||||||
|
router.addRoute(route) // 动态添加可访问路由表
|
||||||
|
})
|
||||||
|
const redirectPath = from.query.redirect || to.path
|
||||||
|
const redirect = decodeURIComponent(redirectPath)
|
||||||
|
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect }
|
||||||
|
next(nextData)
|
||||||
|
} else {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (whiteList.indexOf(to.path) !== -1) {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
const tenantId = getTenantId()
|
||||||
|
const appId = getAppId()
|
||||||
|
if (tenantId && appId) {
|
||||||
|
next(`/crm/login?tenantId=${tenantId}&appId=${appId}&redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
||||||
|
} else {
|
||||||
|
next(`/crm/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/plugins/cache/index.js
vendored
8
src/plugins/cache/index.js
vendored
@@ -26,7 +26,7 @@ const sessionCache = {
|
|||||||
let storage = storageStr ? JSON.parse(storageStr) : {}
|
let storage = storageStr ? JSON.parse(storageStr) : {}
|
||||||
return storage[key]
|
return storage[key]
|
||||||
},
|
},
|
||||||
remove(key) {
|
delete(key) {
|
||||||
if (!sessionStorage) {
|
if (!sessionStorage) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ const localCache = {
|
|||||||
let storage = storageStr ? JSON.parse(storageStr) : {}
|
let storage = storageStr ? JSON.parse(storageStr) : {}
|
||||||
return storage[key]
|
return storage[key]
|
||||||
},
|
},
|
||||||
remove(key) {
|
delete(key) {
|
||||||
if (!localStorage) {
|
if (!localStorage) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -73,6 +73,10 @@ const localCache = {
|
|||||||
let storage = storageStr ? JSON.parse(storageStr) : {}
|
let storage = storageStr ? JSON.parse(storageStr) : {}
|
||||||
delete storage[key]
|
delete storage[key]
|
||||||
localStorage.setItem(name, JSON.stringify(storage))
|
localStorage.setItem(name, JSON.stringify(storage))
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
let storage = {}
|
||||||
|
localStorage.setItem(name, JSON.stringify(storage))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,12 @@ import { defineStore } from 'pinia'
|
|||||||
import { store } from '../index'
|
import { store } from '../index'
|
||||||
import { setCssVar, humpToUnderline } from '@/utils'
|
import { setCssVar, humpToUnderline } from '@/utils'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
import { ElementPlusSize } from '@/types/elementPlus'
|
import { ElementPlusSize } from '@/types/elementPlus'
|
||||||
import { LayoutType } from '@/types/layout'
|
import { LayoutType } from '@/types/layout'
|
||||||
import { ThemeTypes } from '@/types/theme'
|
import { ThemeTypes } from '@/types/theme'
|
||||||
import { getAppInfo } from '@/api/login'
|
import { getAppInfo } from '@/api/login'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
const { wsCache } = useCache()
|
|
||||||
|
|
||||||
interface AppState {
|
interface AppState {
|
||||||
breadcrumb: boolean
|
breadcrumb: boolean
|
||||||
@@ -46,7 +45,7 @@ export const useAppStore = defineStore('app', {
|
|||||||
sizeMap: ['default', 'large', 'small'],
|
sizeMap: ['default', 'large', 'small'],
|
||||||
mobile: false, // 是否是移动端
|
mobile: false, // 是否是移动端
|
||||||
title: import.meta.env.VITE_APP_TITLE, // 标题
|
title: import.meta.env.VITE_APP_TITLE, // 标题
|
||||||
appInfo: wsCache.get('appInfo'),
|
appInfo: cache.local.get('appInfo'),
|
||||||
pageLoading: false, // 路由跳转loading
|
pageLoading: false, // 路由跳转loading
|
||||||
|
|
||||||
breadcrumb: true, // 面包屑
|
breadcrumb: true, // 面包屑
|
||||||
@@ -64,12 +63,12 @@ export const useAppStore = defineStore('app', {
|
|||||||
fixedHeader: true, // 固定toolheader
|
fixedHeader: true, // 固定toolheader
|
||||||
footer: false, // 显示页脚
|
footer: false, // 显示页脚
|
||||||
greyMode: false, // 是否开始灰色模式,用于特殊悼念日
|
greyMode: false, // 是否开始灰色模式,用于特殊悼念日
|
||||||
fixedMenu: wsCache.get('fixedMenu') || false, // 是否固定菜单
|
fixedMenu: cache.local.get('fixedMenu') || false, // 是否固定菜单
|
||||||
|
|
||||||
layout: wsCache.get(CACHE_KEY.LAYOUT) || 'classic', // layout布局
|
layout: cache.local.get(CACHE_KEY.LAYOUT) || 'classic', // layout布局
|
||||||
isDark: wsCache.get(CACHE_KEY.IS_DARK) || false, // 是否是暗黑模式
|
isDark: cache.local.get(CACHE_KEY.IS_DARK) || false, // 是否是暗黑模式
|
||||||
currentSize: wsCache.get('default') || 'default', // 组件尺寸
|
currentSize: cache.local.get('default') || 'default', // 组件尺寸
|
||||||
theme: wsCache.get(CACHE_KEY.THEME) || {
|
theme: cache.local.get(CACHE_KEY.THEME) || {
|
||||||
// 主题色
|
// 主题色
|
||||||
elColorPrimary: '#409eff',
|
elColorPrimary: '#409eff',
|
||||||
// 左侧菜单边框颜色
|
// 左侧菜单边框颜色
|
||||||
@@ -225,7 +224,7 @@ export const useAppStore = defineStore('app', {
|
|||||||
this.greyMode = greyMode
|
this.greyMode = greyMode
|
||||||
},
|
},
|
||||||
setFixedMenu(fixedMenu: boolean) {
|
setFixedMenu(fixedMenu: boolean) {
|
||||||
wsCache.set('fixedMenu', fixedMenu)
|
cache.local.set('fixedMenu', fixedMenu)
|
||||||
this.fixedMenu = fixedMenu
|
this.fixedMenu = fixedMenu
|
||||||
},
|
},
|
||||||
setPageLoading(pageLoading: boolean) {
|
setPageLoading(pageLoading: boolean) {
|
||||||
@@ -237,7 +236,7 @@ export const useAppStore = defineStore('app', {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.layout = layout
|
this.layout = layout
|
||||||
wsCache.set(CACHE_KEY.LAYOUT, this.layout)
|
cache.local.set(CACHE_KEY.LAYOUT, this.layout)
|
||||||
},
|
},
|
||||||
setTitle(title: string) {
|
setTitle(title: string) {
|
||||||
this.title = title
|
this.title = title
|
||||||
@@ -251,18 +250,18 @@ export const useAppStore = defineStore('app', {
|
|||||||
document.documentElement.classList.add('light')
|
document.documentElement.classList.add('light')
|
||||||
document.documentElement.classList.remove('dark')
|
document.documentElement.classList.remove('dark')
|
||||||
}
|
}
|
||||||
wsCache.set(CACHE_KEY.IS_DARK, this.isDark)
|
cache.local.set(CACHE_KEY.IS_DARK, this.isDark)
|
||||||
},
|
},
|
||||||
setCurrentSize(currentSize: ElementPlusSize) {
|
setCurrentSize(currentSize: ElementPlusSize) {
|
||||||
this.currentSize = currentSize
|
this.currentSize = currentSize
|
||||||
wsCache.set('currentSize', this.currentSize)
|
cache.local.set('currentSize', this.currentSize)
|
||||||
},
|
},
|
||||||
setMobile(mobile: boolean) {
|
setMobile(mobile: boolean) {
|
||||||
this.mobile = mobile
|
this.mobile = mobile
|
||||||
},
|
},
|
||||||
setTheme(theme: ThemeTypes) {
|
setTheme(theme: ThemeTypes) {
|
||||||
this.theme = Object.assign(this.theme, theme)
|
this.theme = Object.assign(this.theme, theme)
|
||||||
wsCache.set(CACHE_KEY.THEME, this.theme)
|
cache.local.set(CACHE_KEY.THEME, this.theme)
|
||||||
},
|
},
|
||||||
setCssVarTheme() {
|
setCssVarTheme() {
|
||||||
for (const key in this.theme) {
|
for (const key in this.theme) {
|
||||||
@@ -274,7 +273,7 @@ export const useAppStore = defineStore('app', {
|
|||||||
},
|
},
|
||||||
async setAppInfo(appId: number) {
|
async setAppInfo(appId: number) {
|
||||||
const appInfo = await getAppInfo(appId)
|
const appInfo = await getAppInfo(appId)
|
||||||
wsCache.set('appInfo', appInfo)
|
cache.local.set('appInfo', appInfo)
|
||||||
this.appInfo = appInfo
|
this.appInfo = appInfo
|
||||||
return appInfo
|
return appInfo
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { defineStore } from 'pinia'
|
|||||||
import { store } from '../index'
|
import { store } from '../index'
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { DictDataVO } from '@/api/system/dict/types'
|
import { DictDataVO } from '@/api/system/dict/types'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
const { wsCache } = useCache('sessionStorage')
|
import cache from '@/plugins/cache'
|
||||||
import { listSimpleDictData } from '@/api/system/dict/dict.data'
|
import { listSimpleDictData } from '@/api/system/dict/dict.data'
|
||||||
|
|
||||||
export interface DictValueType {
|
export interface DictValueType {
|
||||||
@@ -28,7 +28,7 @@ export const useDictStore = defineStore('dict', {
|
|||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
getDictMap(): Recordable {
|
getDictMap(): Recordable {
|
||||||
const dictMap = wsCache.get(CACHE_KEY.DICT_CACHE)
|
const dictMap = cache.session.get(CACHE_KEY.DICT_CACHE)
|
||||||
if (dictMap) {
|
if (dictMap) {
|
||||||
this.dictMap = dictMap
|
this.dictMap = dictMap
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ export const useDictStore = defineStore('dict', {
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async setDictMap() {
|
async setDictMap() {
|
||||||
const dictMap = wsCache.get(CACHE_KEY.DICT_CACHE)
|
const dictMap = cache.session.get(CACHE_KEY.DICT_CACHE)
|
||||||
if (dictMap) {
|
if (dictMap) {
|
||||||
this.dictMap = dictMap
|
this.dictMap = dictMap
|
||||||
this.isSetDict = true
|
this.isSetDict = true
|
||||||
@@ -64,7 +64,7 @@ export const useDictStore = defineStore('dict', {
|
|||||||
})
|
})
|
||||||
this.dictMap = dictDataMap
|
this.dictMap = dictDataMap
|
||||||
this.isSetDict = true
|
this.isSetDict = true
|
||||||
wsCache.set(CACHE_KEY.DICT_CACHE, dictDataMap, { exp: 60 }) // 60 秒 过期
|
cache.session.set(CACHE_KEY.DICT_CACHE, dictDataMap) // 60 秒 过期
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getDictByType(type: string) {
|
getDictByType(type: string) {
|
||||||
@@ -74,7 +74,7 @@ export const useDictStore = defineStore('dict', {
|
|||||||
return this.dictMap[type]
|
return this.dictMap[type]
|
||||||
},
|
},
|
||||||
async resetDict() {
|
async resetDict() {
|
||||||
wsCache.delete(CACHE_KEY.DICT_CACHE)
|
cache.session.delete(CACHE_KEY.DICT_CACHE)
|
||||||
const res = await listSimpleDictData()
|
const res = await listSimpleDictData()
|
||||||
// 设置数据
|
// 设置数据
|
||||||
const dictDataMap = new Map<string, any>()
|
const dictDataMap = new Map<string, any>()
|
||||||
@@ -94,7 +94,7 @@ export const useDictStore = defineStore('dict', {
|
|||||||
})
|
})
|
||||||
this.dictMap = dictDataMap
|
this.dictMap = dictDataMap
|
||||||
this.isSetDict = true
|
this.isSetDict = true
|
||||||
wsCache.set(CACHE_KEY.DICT_CACHE, dictDataMap, { exp: 60 }) // 60 秒 过期
|
cache.session.set(CACHE_KEY.DICT_CACHE, dictDataMap) // 60 秒 过期
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,9 +3,8 @@ import { store } from '../index'
|
|||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import remainingRouter from '@/router/modules/remaining'
|
import remainingRouter from '@/router/modules/remaining'
|
||||||
import { generateRoute, flatMultiLevelRoutes } from '@/utils/routerHelper'
|
import { generateRoute, flatMultiLevelRoutes } from '@/utils/routerHelper'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
const { wsCache } = useCache()
|
|
||||||
|
|
||||||
export interface PermissionState {
|
export interface PermissionState {
|
||||||
routers: AppRouteRecordRaw[]
|
routers: AppRouteRecordRaw[]
|
||||||
@@ -34,8 +33,8 @@ export const usePermissionStore = defineStore('permission', {
|
|||||||
async generateRoutes(): Promise<unknown> {
|
async generateRoutes(): Promise<unknown> {
|
||||||
return new Promise<void>(async (resolve) => {
|
return new Promise<void>(async (resolve) => {
|
||||||
let res: AppCustomRouteRecordRaw[] = []
|
let res: AppCustomRouteRecordRaw[] = []
|
||||||
if (wsCache.get(CACHE_KEY.ROLE_ROUTERS)) {
|
if (cache.local.get(CACHE_KEY.ROLE_ROUTERS)) {
|
||||||
res = wsCache.get(CACHE_KEY.ROLE_ROUTERS) as AppCustomRouteRecordRaw[]
|
res = cache.local.get(CACHE_KEY.ROLE_ROUTERS) as AppCustomRouteRecordRaw[]
|
||||||
}
|
}
|
||||||
const routerMap: AppRouteRecordRaw[] = generateRoute(res)
|
const routerMap: AppRouteRecordRaw[] = generateRoute(res)
|
||||||
// 动态路由,404一定要放到最后面
|
// 动态路由,404一定要放到最后面
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { store } from '../index'
|
import { store } from '../index'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { getAccessToken, removeToken } from '@/utils/auth'
|
import { getAccessToken, removeToken } from '@/utils/auth'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
import { getInfo, loginOut } from '@/api/login'
|
import { getInfo, loginOut } from '@/api/login'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
const { wsCache } = useCache()
|
|
||||||
|
|
||||||
interface UserVO {
|
interface UserVO {
|
||||||
id: number
|
id: number
|
||||||
@@ -49,7 +48,7 @@ export const useUserStore = defineStore('admin-user', {
|
|||||||
this.resetState()
|
this.resetState()
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
let userInfo = wsCache.get(CACHE_KEY.USER)
|
let userInfo = cache.local.get(CACHE_KEY.USER)
|
||||||
if (!userInfo) {
|
if (!userInfo) {
|
||||||
userInfo = await getInfo({})
|
userInfo = await getInfo({})
|
||||||
}
|
}
|
||||||
@@ -57,13 +56,13 @@ export const useUserStore = defineStore('admin-user', {
|
|||||||
this.roles = userInfo.roles
|
this.roles = userInfo.roles
|
||||||
this.user = userInfo.user
|
this.user = userInfo.user
|
||||||
this.isSetUser = true
|
this.isSetUser = true
|
||||||
wsCache.set(CACHE_KEY.USER, userInfo)
|
cache.local.set(CACHE_KEY.USER, userInfo)
|
||||||
wsCache.set(CACHE_KEY.ROLE_ROUTERS, userInfo.menus)
|
cache.local.set(CACHE_KEY.ROLE_ROUTERS, userInfo.menus)
|
||||||
},
|
},
|
||||||
async loginOut() {
|
async loginOut() {
|
||||||
await loginOut()
|
await loginOut()
|
||||||
removeToken()
|
removeToken()
|
||||||
wsCache.clear()
|
cache.local.clear()
|
||||||
this.resetState()
|
this.resetState()
|
||||||
},
|
},
|
||||||
resetState() {
|
resetState() {
|
||||||
@@ -77,7 +76,7 @@ export const useUserStore = defineStore('admin-user', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
refresh() {
|
refresh() {
|
||||||
wsCache.delete(CACHE_KEY.USER)
|
cache.local.delete(CACHE_KEY.USER)
|
||||||
this.resetState()
|
this.resetState()
|
||||||
window.location.href = ''
|
window.location.href = ''
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { useCache } from '@/hooks/web/useCache'
|
|
||||||
import { TokenType } from '@/api/login/types'
|
import { TokenType } from '@/api/login/types'
|
||||||
import { decrypt, encrypt } from '@/utils/jsencrypt'
|
import { decrypt, encrypt } from '@/utils/jsencrypt'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
const { wsCache } = useCache()
|
|
||||||
|
|
||||||
const AccessTokenKey = 'ACCESS_TOKEN'
|
const AccessTokenKey = 'ACCESS_TOKEN'
|
||||||
const RefreshTokenKey = 'REFRESH_TOKEN'
|
const RefreshTokenKey = 'REFRESH_TOKEN'
|
||||||
@@ -10,24 +8,26 @@ const RefreshTokenKey = 'REFRESH_TOKEN'
|
|||||||
// 获取token
|
// 获取token
|
||||||
export const getAccessToken = () => {
|
export const getAccessToken = () => {
|
||||||
// 此处与TokenKey相同,此写法解决初始化时Cookies中不存在TokenKey报错
|
// 此处与TokenKey相同,此写法解决初始化时Cookies中不存在TokenKey报错
|
||||||
return wsCache.get(AccessTokenKey) ? wsCache.get(AccessTokenKey) : wsCache.get('ACCESS_TOKEN')
|
return cache.local.get(AccessTokenKey)
|
||||||
|
? cache.local.get(AccessTokenKey)
|
||||||
|
: cache.local.get('ACCESS_TOKEN')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 刷新token
|
// 刷新token
|
||||||
export const getRefreshToken = () => {
|
export const getRefreshToken = () => {
|
||||||
return wsCache.get(RefreshTokenKey)
|
return cache.local.get(RefreshTokenKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置token
|
// 设置token
|
||||||
export const setToken = (token: TokenType) => {
|
export const setToken = (token: TokenType) => {
|
||||||
wsCache.set(RefreshTokenKey, token.refreshToken, { exp: token.expiresTime })
|
cache.local.set(RefreshTokenKey, token.refreshToken)
|
||||||
wsCache.set(AccessTokenKey, token.accessToken)
|
cache.local.set(AccessTokenKey, token.accessToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除token
|
// 删除token
|
||||||
export const removeToken = () => {
|
export const removeToken = () => {
|
||||||
wsCache.delete(AccessTokenKey)
|
cache.local.delete(AccessTokenKey)
|
||||||
wsCache.delete(RefreshTokenKey)
|
cache.local.delete(RefreshTokenKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 格式化token(jwt格式) */
|
/** 格式化token(jwt格式) */
|
||||||
@@ -47,7 +47,7 @@ export type LoginFormType = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getLoginForm = () => {
|
export const getLoginForm = () => {
|
||||||
const loginForm: LoginFormType = wsCache.get(LoginFormKey)
|
const loginForm: LoginFormType = cache.local.get(LoginFormKey)
|
||||||
if (loginForm) {
|
if (loginForm) {
|
||||||
loginForm.password = decrypt(loginForm.password) as string
|
loginForm.password = decrypt(loginForm.password) as string
|
||||||
}
|
}
|
||||||
@@ -56,11 +56,11 @@ export const getLoginForm = () => {
|
|||||||
|
|
||||||
export const setLoginForm = (loginForm: LoginFormType) => {
|
export const setLoginForm = (loginForm: LoginFormType) => {
|
||||||
loginForm.password = encrypt(loginForm.password) as string
|
loginForm.password = encrypt(loginForm.password) as string
|
||||||
wsCache.set(LoginFormKey, loginForm, { exp: 30 * 24 * 60 * 60 })
|
cache.local.set(LoginFormKey, loginForm)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const removeLoginForm = () => {
|
export const removeLoginForm = () => {
|
||||||
wsCache.delete(LoginFormKey)
|
cache.local.delete(LoginFormKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 租户相关 ==========
|
// ========== 租户相关 ==========
|
||||||
@@ -69,52 +69,52 @@ const TenantIdKey = 'TENANT_ID'
|
|||||||
const TenantNameKey = 'TENANT_NAME'
|
const TenantNameKey = 'TENANT_NAME'
|
||||||
|
|
||||||
export const getTenantName = () => {
|
export const getTenantName = () => {
|
||||||
return wsCache.get(TenantNameKey)
|
return cache.local.get(TenantNameKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setTenantName = (username: string) => {
|
export const setTenantName = (username: string) => {
|
||||||
wsCache.set(TenantNameKey, username, { exp: 30 * 24 * 60 * 60 })
|
cache.local.set(TenantNameKey, username)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const removeTenantName = () => {
|
export const removeTenantName = () => {
|
||||||
wsCache.delete(TenantNameKey)
|
cache.local.delete(TenantNameKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getTenantId = () => {
|
export const getTenantId = () => {
|
||||||
return wsCache.get(TenantIdKey)
|
return cache.local.get(TenantIdKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setTenantId = (username: string) => {
|
export const setTenantId = (username: string) => {
|
||||||
wsCache.set(TenantIdKey, username)
|
cache.local.set(TenantIdKey, username)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const removeTenantId = () => {
|
export const removeTenantId = () => {
|
||||||
wsCache.delete(TenantIdKey)
|
cache.local.delete(TenantIdKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppIdKey = 'App_ID'
|
const AppIdKey = 'App_ID'
|
||||||
const AppNameKey = 'App_NAME'
|
const AppNameKey = 'App_NAME'
|
||||||
|
|
||||||
export const getAPPName = () => {
|
export const getAPPName = () => {
|
||||||
return wsCache.get(AppNameKey)
|
return cache.local.get(AppNameKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setAppName = (name: string) => {
|
export const setAppName = (name: string) => {
|
||||||
wsCache.set(AppNameKey, name, { exp: 30 * 24 * 60 * 60 })
|
cache.local.set(AppNameKey, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const removeAppName = () => {
|
export const removeAppName = () => {
|
||||||
wsCache.delete(AppNameKey)
|
cache.local.delete(AppNameKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getAppId = () => {
|
export const getAppId = () => {
|
||||||
return wsCache.get(AppIdKey)
|
return cache.local.get(AppIdKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setAppId = (id: number) => {
|
export const setAppId = (id: number) => {
|
||||||
wsCache.set(AppIdKey, id)
|
cache.local.set(AppIdKey, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const removeAppId = () => {
|
export const removeAppId = () => {
|
||||||
wsCache.delete(AppIdKey)
|
cache.local.delete(AppIdKey)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
@@ -9,10 +10,9 @@ const { t } = useI18n() // 国际化
|
|||||||
*/
|
*/
|
||||||
export function checkPermi(value: string[]) {
|
export function checkPermi(value: string[]) {
|
||||||
if (value && value instanceof Array && value.length > 0) {
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
const { wsCache } = useCache()
|
|
||||||
const permissionDatas = value
|
const permissionDatas = value
|
||||||
const all_permission = '*:*:*'
|
const all_permission = '*:*:*'
|
||||||
const permissions = wsCache.get(CACHE_KEY.USER).permissions
|
const permissions = cache.local.get(CACHE_KEY.USER).permissions
|
||||||
const hasPermission = permissions.some((permission) => {
|
const hasPermission = permissions.some((permission) => {
|
||||||
return all_permission === permission || permissionDatas.includes(permission)
|
return all_permission === permission || permissionDatas.includes(permission)
|
||||||
})
|
})
|
||||||
@@ -30,10 +30,9 @@ export function checkPermi(value: string[]) {
|
|||||||
*/
|
*/
|
||||||
export function checkRole(value: string[]) {
|
export function checkRole(value: string[]) {
|
||||||
if (value && value instanceof Array && value.length > 0) {
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
const { wsCache } = useCache()
|
|
||||||
const permissionRoles = value
|
const permissionRoles = value
|
||||||
const super_admin = 'admin'
|
const super_admin = 'admin'
|
||||||
const roles = wsCache.get(CACHE_KEY.USER).roles
|
const roles = cache.local.get(CACHE_KEY.USER).roles
|
||||||
const hasRole = roles.some((role) => {
|
const hasRole = roles.some((role) => {
|
||||||
return super_admin === role || permissionRoles.includes(role)
|
return super_admin === role || permissionRoles.includes(role)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,16 +4,16 @@
|
|||||||
<el-tab-pane label="线索管理" :name="0" v-if="checkPermi(['basic:setting:clue'])">
|
<el-tab-pane label="线索管理" :name="0" v-if="checkPermi(['basic:setting:clue'])">
|
||||||
<BSClue v-if="tabIndex == 0" />
|
<BSClue v-if="tabIndex == 0" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="销售提成" :name="10" v-if="checkPermi(['basic:setting:comission'])">
|
<!-- <el-tab-pane label="销售提成" :name="10" v-if="checkPermi(['basic:setting:comission'])">
|
||||||
<BSSalerComission v-if="tabIndex == 10" />
|
<BSSalerComission v-if="tabIndex == 10" />
|
||||||
</el-tab-pane>
|
</el-tab-pane> -->
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="GeneralSetting">
|
<script setup name="GeneralSetting">
|
||||||
import BSClue from './Comp/BSClue.vue'
|
import BSClue from './Comp/BSClue.vue'
|
||||||
import BSSalerComission from './Comp/BSSalerComission.vue'
|
// import BSSalerComission from './Comp/BSSalerComission.vue'
|
||||||
import { checkPermi } from '@/utils/permission'
|
import { checkPermi } from '@/utils/permission'
|
||||||
|
|
||||||
const tabIndex = ref(0)
|
const tabIndex = ref(0)
|
||||||
|
|||||||
@@ -116,11 +116,11 @@
|
|||||||
<script lang="ts" name="SystemMenuForm" setup>
|
<script lang="ts" name="SystemMenuForm" setup>
|
||||||
// import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
// import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import * as MenuApi from '@/api/system/menu'
|
import * as MenuApi from '@/api/system/menu'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
import { CommonStatusEnum, SystemMenuTypeEnum } from '@/utils/constants'
|
import { CommonStatusEnum, SystemMenuTypeEnum } from '@/utils/constants'
|
||||||
import { defaultProps, handleTree } from '@/utils/tree'
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
|
import cache from '@/plugins/cache'
|
||||||
|
|
||||||
const { wsCache } = useCache()
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ const submitForm = async () => {
|
|||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
// 清空,从而触发刷新
|
// 清空,从而触发刷新
|
||||||
wsCache.delete(CACHE_KEY.ROLE_ROUTERS)
|
cache.local.delete(CACHE_KEY.ROLE_ROUTERS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,8 +88,8 @@
|
|||||||
import { handleTree } from '@/utils/tree'
|
import { handleTree } from '@/utils/tree'
|
||||||
import * as MenuApi from '@/api/system/menu'
|
import * as MenuApi from '@/api/system/menu'
|
||||||
import MenuForm from './MenuForm.vue'
|
import MenuForm from './MenuForm.vue'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
const { wsCache } = useCache()
|
import cache from '@/plugins/cache'
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ const refreshMenu = async () => {
|
|||||||
try {
|
try {
|
||||||
await message.confirm('即将更新缓存刷新浏览器!', '刷新菜单缓存')
|
await message.confirm('即将更新缓存刷新浏览器!', '刷新菜单缓存')
|
||||||
// 清空,从而触发刷新
|
// 清空,从而触发刷新
|
||||||
wsCache.delete(CACHE_KEY.ROLE_ROUTERS)
|
cache.local.delete(CACHE_KEY.ROLE_ROUTERS)
|
||||||
// 刷新浏览器
|
// 刷新浏览器
|
||||||
location.reload()
|
location.reload()
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|||||||
@@ -28,9 +28,9 @@
|
|||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in extraPayOptions"
|
v-for="item in extraPayOptions"
|
||||||
:key="item.value"
|
:key="item.id"
|
||||||
:label="item.label"
|
:label="item.extraPayName"
|
||||||
:value="item.value"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
@@ -73,9 +73,9 @@
|
|||||||
|
|
||||||
<script setup name="DialogExtraPay">
|
<script setup name="DialogExtraPay">
|
||||||
import { signAddPay, getSignExtraPayList } from '@/api/clue/sign'
|
import { signAddPay, getSignExtraPayList } from '@/api/clue/sign'
|
||||||
import { getDictOptions } from '@/utils/dict'
|
import * as ExtraFeeApi from '@/api/clue/extraFee'
|
||||||
|
|
||||||
const extraPayOptions = getDictOptions('extra_pay_type')
|
const extraPayOptions = ref([])
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
const show = ref(false)
|
const show = ref(false)
|
||||||
@@ -83,6 +83,7 @@ function open(id) {
|
|||||||
show.value = true
|
show.value = true
|
||||||
resetForm(id)
|
resetForm(id)
|
||||||
getFormList()
|
getFormList()
|
||||||
|
getOptions()
|
||||||
}
|
}
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open
|
open
|
||||||
@@ -135,6 +136,12 @@ async function onSubmit() {
|
|||||||
function handleRemove(type, index) {
|
function handleRemove(type, index) {
|
||||||
form.value[type].splice(index, 1)
|
form.value[type].splice(index, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getOptions() {
|
||||||
|
ExtraFeeApi.getExtraFeeSimpleList().then((data) => {
|
||||||
|
extraPayOptions.value = data
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -370,7 +370,12 @@ async function handleUpdate(row) {
|
|||||||
// 删除的二次确认
|
// 删除的二次确认
|
||||||
await message.confirm('是否确认修改回款金额?')
|
await message.confirm('是否确认修改回款金额?')
|
||||||
// 保存
|
// 保存
|
||||||
FeebackApi.updateApplyPayment({ id: row.id, money: row.money })
|
FeebackApi.updateApplyPayment({
|
||||||
|
id: row.id,
|
||||||
|
money: row.money,
|
||||||
|
companyProfit: row.companyProfit,
|
||||||
|
personProfit: row.personProfit
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
message.success('修改成功')
|
message.success('修改成功')
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
<script setup name="ClueMap">
|
<script setup name="ClueMap">
|
||||||
import { getPlaceList } from '@/api/school/place'
|
import { getPlaceList } from '@/api/school/place'
|
||||||
|
import { getConfigByConfigKey } from '@/api/system/set'
|
||||||
|
|
||||||
import ImgPostion from '@/assets/imgs/flag/position_black.png'
|
import ImgPostion from '@/assets/imgs/flag/position_black.png'
|
||||||
import FlagRed from '@/assets/imgs/flag/flag_red.png'
|
import FlagRed from '@/assets/imgs/flag/flag_red.png'
|
||||||
@@ -69,9 +70,17 @@ const defaultLatLng = ref({
|
|||||||
lat: 31.86119,
|
lat: 31.86119,
|
||||||
lng: 117.283042
|
lng: 117.283042
|
||||||
})
|
})
|
||||||
|
const defaultCity = ref('合肥')
|
||||||
|
|
||||||
let AutoComplete = ref(null)
|
let AutoComplete = ref(null)
|
||||||
function initMap() {
|
async function initMap() {
|
||||||
|
const data = await getConfigByConfigKey({ configKey: 'defaultLocation' })
|
||||||
|
const cityInfo = JSON.parse(data.configValue)
|
||||||
|
defaultLatLng.value = {
|
||||||
|
lat: cityInfo.lat,
|
||||||
|
lng: cityInfo.lng
|
||||||
|
}
|
||||||
|
defaultCity.value = cityInfo.locationName
|
||||||
AMapLoader.load({
|
AMapLoader.load({
|
||||||
key: '713d839ff505943b0f18e6df45f3b0dc', //设置您的key
|
key: '713d839ff505943b0f18e6df45f3b0dc', //设置您的key
|
||||||
version: '2.0',
|
version: '2.0',
|
||||||
@@ -79,7 +88,7 @@ function initMap() {
|
|||||||
}).then((AMap) => {
|
}).then((AMap) => {
|
||||||
aMap.value = AMap
|
aMap.value = AMap
|
||||||
AutoComplete.value = new AMap.AutoComplete({
|
AutoComplete.value = new AMap.AutoComplete({
|
||||||
city: '合肥'
|
city: defaultCity.value
|
||||||
})
|
})
|
||||||
clueMap.value = new AMap.Map('mapClue', {
|
clueMap.value = new AMap.Map('mapClue', {
|
||||||
zoom: 14,
|
zoom: 14,
|
||||||
|
|||||||
97
src/views/Clue/Pool/Comp/DialogBatchChangeFollow.vue
Normal file
97
src/views/Clue/Pool/Comp/DialogBatchChangeFollow.vue
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog title="批量修改跟进人" v-model="show" width="400px">
|
||||||
|
<el-form :model="form" ref="formRef" :rules="rules" label-width="auto">
|
||||||
|
<el-form-item label="修改线索数">
|
||||||
|
{{ form.clueIdList.length }}
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="原跟进人" prop="originFollowUserId">
|
||||||
|
<el-select v-model="form.originFollowUserId" placeholder="原跟进人" filterable>
|
||||||
|
<el-option
|
||||||
|
v-for="item in props.userOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.nickname"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="新跟进人" prop="newFollowUserId">
|
||||||
|
<el-select v-model="form.newFollowUserId" placeholder="新跟进人" filterable>
|
||||||
|
<el-option
|
||||||
|
v-for="item in props.userOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.nickname"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span>
|
||||||
|
<el-button @click="show = false">取 消</el-button>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="handleSave">保 存</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="DialogBatchChangeFollow">
|
||||||
|
import { batchUpdateFollowUser } from '@/api/clue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
userOptions: {
|
||||||
|
type: Array
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const show = ref(false)
|
||||||
|
const form = ref({
|
||||||
|
clueIdList: [],
|
||||||
|
originFollowUserId: undefined,
|
||||||
|
newFollowUserId: undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
const rules = ref({
|
||||||
|
originFollowUserId: { required: true, message: '原跟进人不可为空', trigger: 'change' },
|
||||||
|
newFollowUserId: { required: true, message: '新跟进人不可为空', trigger: 'change' }
|
||||||
|
})
|
||||||
|
|
||||||
|
function open(clueIdList) {
|
||||||
|
resetForm(clueIdList)
|
||||||
|
show.value = true
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
function resetForm(clueIdList) {
|
||||||
|
form.value = {
|
||||||
|
clueIdList,
|
||||||
|
originFollowUserId: undefined,
|
||||||
|
newFollowUserId: undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const formLoading = ref(false)
|
||||||
|
const emit = defineEmits(['success'])
|
||||||
|
const formRef = ref()
|
||||||
|
async function handleSave() {
|
||||||
|
// 校验表单
|
||||||
|
if (!formRef.value) return
|
||||||
|
const valid = await formRef.value.validate()
|
||||||
|
if (!valid) return
|
||||||
|
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
await batchUpdateFollowUser(form.value)
|
||||||
|
message.success('修改成功!')
|
||||||
|
show.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -133,6 +133,7 @@
|
|||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/store/modules/user'
|
||||||
import { getPlaceList } from '@/api/school/place'
|
import { getPlaceList } from '@/api/school/place'
|
||||||
|
import { getConfigByConfigKey } from '@/api/system/set'
|
||||||
import * as ClueApi from '@/api/clue'
|
import * as ClueApi from '@/api/clue'
|
||||||
import { getDiyFieldList } from '@/api/clue/clueField'
|
import { getDiyFieldList } from '@/api/clue/clueField'
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
@@ -226,6 +227,7 @@ const defaultLatLng = ref({
|
|||||||
lat: 31.86119,
|
lat: 31.86119,
|
||||||
lng: 117.283042
|
lng: 117.283042
|
||||||
})
|
})
|
||||||
|
const defaultCity = ref('合肥')
|
||||||
const info = ref({})
|
const info = ref({})
|
||||||
|
|
||||||
const diyFieldArr = ref([])
|
const diyFieldArr = ref([])
|
||||||
@@ -265,9 +267,14 @@ const open = async (type, id) => {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
address.value = ''
|
address.value = ''
|
||||||
defaultLatLng.value = {
|
if (appStore.getAppInfo?.instanceType == 1) {
|
||||||
lat: 31.86119,
|
const data = await getConfigByConfigKey({ configKey: 'defaultLocation' })
|
||||||
lng: 117.283042
|
const cityInfo = JSON.parse(data.configValue)
|
||||||
|
defaultLatLng.value = {
|
||||||
|
lat: cityInfo.lat,
|
||||||
|
lng: cityInfo.lng
|
||||||
|
}
|
||||||
|
defaultCity.value = cityInfo.locationName
|
||||||
}
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value.setValues(info.value, true)
|
formRef.value.setValues(info.value, true)
|
||||||
@@ -396,7 +403,7 @@ function initMap(data) {
|
|||||||
})
|
})
|
||||||
addmark(defaultLatLng.value.lng, defaultLatLng.value.lat, AMap)
|
addmark(defaultLatLng.value.lng, defaultLatLng.value.lat, AMap)
|
||||||
AutoComplete.value = new AMap.AutoComplete({
|
AutoComplete.value = new AMap.AutoComplete({
|
||||||
city: '合肥'
|
city: defaultCity.value
|
||||||
})
|
})
|
||||||
geoCoder.value = new AMap.Geocoder()
|
geoCoder.value = new AMap.Geocoder()
|
||||||
dialogMap.value.on('click', (e) => {
|
dialogMap.value.on('click', (e) => {
|
||||||
|
|||||||
@@ -328,6 +328,7 @@ import { getDiyFieldList } from '@/api/clue/orderField'
|
|||||||
import { getPlaceList } from '@/api/school/place'
|
import { getPlaceList } from '@/api/school/place'
|
||||||
import { getClassTypeList } from '@/api/school/class'
|
import { getClassTypeList } from '@/api/school/class'
|
||||||
import { getSimpleProductList } from '@/api/mall/product'
|
import { getSimpleProductList } from '@/api/mall/product'
|
||||||
|
import { getConfigByConfigKey } from '@/api/system/set'
|
||||||
|
|
||||||
// import { getSimpleWarehouseList } from '@/api/mall/warehouse'
|
// import { getSimpleWarehouseList } from '@/api/mall/warehouse'
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
@@ -415,7 +416,8 @@ async function open(id) {
|
|||||||
}
|
}
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
function resetForm(id) {
|
async function resetForm(id) {
|
||||||
|
const data = await getConfigByConfigKey({ configKey: 'companyCollectionConfig' })
|
||||||
form.value = {
|
form.value = {
|
||||||
clueId: id,
|
clueId: id,
|
||||||
dealDate: formatDate(new Date()),
|
dealDate: formatDate(new Date()),
|
||||||
@@ -423,7 +425,7 @@ function resetForm(id) {
|
|||||||
signPrice: 0,
|
signPrice: 0,
|
||||||
payAmount: 0,
|
payAmount: 0,
|
||||||
remark: undefined,
|
remark: undefined,
|
||||||
isCompanyReceipts: appStore.getAppInfo?.instanceType == 2,
|
isCompanyReceipts: data.configValue == 'true',
|
||||||
receiver: undefined,
|
receiver: undefined,
|
||||||
extraPay: [],
|
extraPay: [],
|
||||||
signProducts: []
|
signProducts: []
|
||||||
|
|||||||
@@ -53,6 +53,12 @@
|
|||||||
<template #actionMore>
|
<template #actionMore>
|
||||||
<el-button @click="getTableList" v-hasPermi="['clue:pool:search']"> 搜索 </el-button>
|
<el-button @click="getTableList" v-hasPermi="['clue:pool:search']"> 搜索 </el-button>
|
||||||
<el-button @click="resetQuery" v-hasPermi="['clue:pool:reset']"> 重置 </el-button>
|
<el-button @click="resetQuery" v-hasPermi="['clue:pool:reset']"> 重置 </el-button>
|
||||||
|
<el-button
|
||||||
|
@click="handleBatchChangeFollow"
|
||||||
|
v-hasPermi="['clue:pool:batch-update-follow']"
|
||||||
|
>
|
||||||
|
批量修改跟进人
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</Search>
|
</Search>
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
@@ -63,7 +69,9 @@
|
|||||||
:tableColumns="allSchemas.tableColumns"
|
:tableColumns="allSchemas.tableColumns"
|
||||||
@get-list="getTableList"
|
@get-list="getTableList"
|
||||||
@get-checked-columns="getCheckedColumns"
|
@get-checked-columns="getCheckedColumns"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
>
|
>
|
||||||
|
<el-table-column type="selection" width="60" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
v-for="item in showColumns"
|
v-for="item in showColumns"
|
||||||
:key="item.field"
|
:key="item.field"
|
||||||
@@ -178,6 +186,11 @@
|
|||||||
@success="getTableList"
|
@success="getTableList"
|
||||||
/>
|
/>
|
||||||
<DialogFollow ref="followRef" @success="getTableList" />
|
<DialogFollow ref="followRef" @success="getTableList" />
|
||||||
|
<DialogBatchChangeFollow
|
||||||
|
ref="batchChangeFollowDialog"
|
||||||
|
:userOptions="userOptions"
|
||||||
|
@success="getTableList"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -189,6 +202,7 @@ import DrawerClue from './Comp/DrawerClue.vue'
|
|||||||
import DialogSuccess from './Comp/DialogSuccess.vue'
|
import DialogSuccess from './Comp/DialogSuccess.vue'
|
||||||
import DialogFollow from './Comp/DialogFollow.vue'
|
import DialogFollow from './Comp/DialogFollow.vue'
|
||||||
import ClueMap from './Comp/ClueMap.vue'
|
import ClueMap from './Comp/ClueMap.vue'
|
||||||
|
import DialogBatchChangeFollow from './Comp/DialogBatchChangeFollow.vue'
|
||||||
import { getSimpleUserList as getUserOption, getAllUserList } from '@/api/system/user'
|
import { getSimpleUserList as getUserOption, getAllUserList } from '@/api/system/user'
|
||||||
|
|
||||||
import { removeNullField } from '@/utils'
|
import { removeNullField } from '@/utils'
|
||||||
@@ -216,7 +230,7 @@ async function getCurdSchemas() {
|
|||||||
try {
|
try {
|
||||||
const data = await getSimpleFieldList()
|
const data = await getSimpleFieldList()
|
||||||
data.forEach((elem) => {
|
data.forEach((elem) => {
|
||||||
if (elem.field == 'followUser' || elem.field == 'convertPeople') {
|
if (['followUser', 'convertPeople', 'firstFollowUser'].includes(elem.field)) {
|
||||||
elem.search.options = userOptions.value
|
elem.search.options = userOptions.value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -295,6 +309,20 @@ function getSearchCount() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const batchIds = ref([])
|
||||||
|
function handleSelectionChange(val) {
|
||||||
|
batchIds.value = val.map((it) => it.clueId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const batchChangeFollowDialog = ref()
|
||||||
|
function handleBatchChangeFollow() {
|
||||||
|
if (batchIds.value.length) {
|
||||||
|
batchChangeFollowDialog.value.open(batchIds.value)
|
||||||
|
} else {
|
||||||
|
message.info('请选择表格中的数据!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
function handleInsert() {
|
function handleInsert() {
|
||||||
formRef.value.open('create', null)
|
formRef.value.open('create', null)
|
||||||
|
|||||||
@@ -5,10 +5,16 @@
|
|||||||
v-loading="formLoading"
|
v-loading="formLoading"
|
||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="formRules"
|
:rules="formRules"
|
||||||
label-width="80px"
|
label-width="auto"
|
||||||
>
|
>
|
||||||
<el-form-item label="支出项" prop="label">
|
<el-form-item label="支出项" prop="extraPayName">
|
||||||
<el-input v-model="formData.label" placeholder="请输入支出项" />
|
<el-input v-model="formData.extraPayName" placeholder="请输入支出项" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否扣除提成" prop="isPercentage">
|
||||||
|
<el-radio-group v-model="formData.isPercentage">
|
||||||
|
<el-radio :label="true">是</el-radio>
|
||||||
|
<el-radio :label="false">否</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="排序" prop="sort">
|
<el-form-item label="排序" prop="sort">
|
||||||
<el-input v-model="formData.sort" placeholder="请输入排序" type="number" :min="0" />
|
<el-input v-model="formData.sort" placeholder="请输入排序" type="number" :min="0" />
|
||||||
@@ -29,7 +35,8 @@
|
|||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
<script name="DialogExtraFee" setup>
|
<script name="DialogExtraFee" setup>
|
||||||
import * as dictApi from '@/api/system/dict/dict.data'
|
import * as ExtraFeeApi from '@/api/clue/extraFee'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
@@ -38,12 +45,13 @@ const dialogTitle = ref('') // 弹窗的标题
|
|||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
label: '',
|
extraPayName: '',
|
||||||
|
isPercentage: false,
|
||||||
sort: 1,
|
sort: 1,
|
||||||
remark: ''
|
remark: ''
|
||||||
})
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
label: [{ required: true, message: '支出项不能为空', trigger: 'blur' }]
|
extraPayName: [{ required: true, message: '支出项不能为空', trigger: 'blur' }]
|
||||||
})
|
})
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
@@ -57,7 +65,7 @@ const open = async (type, id) => {
|
|||||||
if (id) {
|
if (id) {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
formData.value = await dictApi.getDictData(id)
|
formData.value = await ExtraFeeApi.getExtraFee(id)
|
||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
}
|
}
|
||||||
@@ -75,14 +83,11 @@ const submitForm = async () => {
|
|||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
if (!formData.value.value) {
|
|
||||||
formData.value.value = formData.value.label
|
|
||||||
}
|
|
||||||
if (formType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
await dictApi.createDictData(formData.value)
|
await ExtraFeeApi.createExtraFee(formData.value)
|
||||||
message.success(t('common.createSuccess'))
|
message.success(t('common.createSuccess'))
|
||||||
} else {
|
} else {
|
||||||
await dictApi.updateDictData(formData.value)
|
await ExtraFeeApi.updateExtraFee(formData.value)
|
||||||
message.success(t('common.updateSuccess'))
|
message.success(t('common.updateSuccess'))
|
||||||
}
|
}
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
@@ -96,10 +101,10 @@ const submitForm = async () => {
|
|||||||
/** 重置表单 */
|
/** 重置表单 */
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
label: '',
|
extraPayName: '',
|
||||||
|
isPercentage: false,
|
||||||
sort: 1,
|
sort: 1,
|
||||||
status: 0,
|
status: 0,
|
||||||
dictType: 'extra_pay_type',
|
|
||||||
remark: ''
|
remark: ''
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<el-form ref="queryForm" :model="searchForm" label-width="0" inline>
|
<el-form ref="queryForm" :model="searchForm" label-width="0" inline>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="searchForm.name"
|
v-model="searchForm.extraPayName"
|
||||||
placeholder="请输入名称"
|
placeholder="请输入名称"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
@@ -16,7 +16,12 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-table v-loading="loading" :data="tableList">
|
<el-table v-loading="loading" :data="tableList">
|
||||||
<el-table-column prop="label" label="支出项" />
|
<el-table-column prop="extraPayName" label="支出项" />
|
||||||
|
<el-table-column prop="isPercentage" label="是否扣除提成">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.isPercentage ? '是' : '否' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="sort" label="排序" width="100px" />
|
<el-table-column prop="sort" label="排序" width="100px" />
|
||||||
<el-table-column prop="remark" label="备注" />
|
<el-table-column prop="remark" label="备注" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@@ -27,22 +32,10 @@
|
|||||||
/>
|
/>
|
||||||
<el-table-column label="操作">
|
<el-table-column label="操作">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" text @click="openForm('update', scope.row.id)">
|
||||||
type="primary"
|
|
||||||
:disabled="!scope.row.editable"
|
|
||||||
text
|
|
||||||
@click="openForm('update', scope.row.id)"
|
|
||||||
>
|
|
||||||
修改
|
修改
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="danger" text @click="handleDelete(scope.row.id)"> 删除 </el-button>
|
||||||
type="danger"
|
|
||||||
:disabled="!scope.row.editable"
|
|
||||||
text
|
|
||||||
@click="handleDelete(scope.row.id)"
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -60,16 +53,16 @@
|
|||||||
<script setup name="ExtraFeeType">
|
<script setup name="ExtraFeeType">
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import DialogExtraFee from './DialogExtraFee.vue'
|
import DialogExtraFee from './DialogExtraFee.vue'
|
||||||
import * as dictApi from '@/api/system/dict/dict.data'
|
import * as ExtraFeeApi from '@/api/clue/extraFee'
|
||||||
|
import { removeNullField } from '@/utils'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
const searchForm = ref({
|
const searchForm = ref({
|
||||||
label: '',
|
extraPayName: '',
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
pageNo: 1,
|
pageNo: 1
|
||||||
dictType: 'extra_pay_type'
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
@@ -83,10 +76,9 @@ function handleQuery() {
|
|||||||
}
|
}
|
||||||
function resetQuery() {
|
function resetQuery() {
|
||||||
searchForm.value = {
|
searchForm.value = {
|
||||||
label: '',
|
extraPayName: '',
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
pageNo: 1,
|
pageNo: 1
|
||||||
dictType: 'extra_pay_type'
|
|
||||||
}
|
}
|
||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
@@ -94,7 +86,7 @@ function resetQuery() {
|
|||||||
async function getList() {
|
async function getList() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const data = await dictApi.getDictDataPage(searchForm.value)
|
const data = await ExtraFeeApi.getExtraFeePage(removeNullField(searchForm.value))
|
||||||
tableList.value = data.list
|
tableList.value = data.list
|
||||||
total.value = data.total
|
total.value = data.total
|
||||||
} finally {
|
} finally {
|
||||||
@@ -111,7 +103,7 @@ async function handleDelete(id) {
|
|||||||
// 删除的二次确认
|
// 删除的二次确认
|
||||||
await message.delConfirm()
|
await message.delConfirm()
|
||||||
// 发起删除
|
// 发起删除
|
||||||
await dictApi.deleteDictData(id)
|
await ExtraFeeApi.deleteExtraFee(id)
|
||||||
message.success(t('common.delSuccess'))
|
message.success(t('common.delSuccess'))
|
||||||
// 刷新列表
|
// 刷新列表
|
||||||
await getList()
|
await getList()
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
<script setup name="ClueSkill">
|
<script setup name="ClueSkill">
|
||||||
import * as SkillApi from '@/api/clue/skill'
|
import * as SkillApi from '@/api/clue/skill'
|
||||||
import DialogSkill from './Comp/DialogSkill.vue'
|
import DialogSkill from './Comp/DialogSkill.vue'
|
||||||
|
import { removeNullField } from '@/utils'
|
||||||
|
|
||||||
const skillDialog = ref()
|
const skillDialog = ref()
|
||||||
|
|
||||||
@@ -95,7 +96,7 @@ function handleQuery() {
|
|||||||
async function getList() {
|
async function getList() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const data = await SkillApi.getSkillPage(searchForm.value)
|
const data = await SkillApi.getSkillPage(removeNullField(searchForm.value))
|
||||||
tableList.value = data.list
|
tableList.value = data.list
|
||||||
total.value = data.total
|
total.value = data.total
|
||||||
} finally {
|
} finally {
|
||||||
@@ -108,7 +109,7 @@ function handleAdd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleUpdate(row) {
|
function handleUpdate(row) {
|
||||||
skillDialog.value.open('update', row.id)
|
skillDialog.value.open('update', row.skillId)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDelete(row) {
|
async function handleDelete(row) {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ const chars = computed(() => {
|
|||||||
return text.slice(0, currentCharIndex.value)
|
return text.slice(0, currentCharIndex.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
function init() {
|
async function init() {
|
||||||
const res = currentRoute.value?.query?.tenantId
|
const res = currentRoute.value?.query?.tenantId
|
||||||
authUtil.setTenantId(res)
|
authUtil.setTenantId(res)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user