This commit is contained in:
2026-01-23 23:10:57 +08:00
parent 8327f6c3e6
commit c0f27fd0ef
5 changed files with 90 additions and 160 deletions

View File

@@ -1,7 +1,9 @@
<script setup>
import { onMounted, computed } from 'vue'
import { onMounted, computed, watch, nextTick } from 'vue'
import { storeToRefs } from 'pinia'
import { useI18nStore } from './stores/modules/i18n'
import { useLayoutStore } from './stores/modules/layout'
import { theme } from 'ant-design-vue'
import i18n from './i18n'
import zhCN from 'ant-design-vue/es/locale/zh_CN'
import enUS from 'ant-design-vue/es/locale/en_US'
@@ -9,12 +11,20 @@ import dayjs from 'dayjs'
import 'dayjs/locale/zh-cn'
import 'dayjs/locale/en'
// 定义组件名称
defineOptions({
name: 'App'
})
// i18n store
const i18nStore = useI18nStore()
// layout store
const layoutStore = useLayoutStore()
// 解构 themeColor 以确保响应式
const { themeColor } = storeToRefs(layoutStore)
// Ant Design Vue 语言配置
const antLocale = computed(() => {
return i18nStore.currentLocale === 'zh-CN' ? zhCN : enUS
@@ -28,8 +38,9 @@ const getPopupContainer = () => {
// Ant Design Vue 主题配置
const antdTheme = computed(() => {
return {
algorithm: theme.defaultAlgorithm,
token: {
colorPrimary: layoutStore.themeColor,
colorPrimary: themeColor.value || '#1890ff',
borderRadius: 6,
fontSize: 14,
},
@@ -40,21 +51,34 @@ const antdTheme = computed(() => {
},
Menu: {
darkItemBg: '#001529',
darkItemSelectedBg: '#1890ff',
darkItemSelectedBg: themeColor.value || '#1890ff',
darkItemHoverBg: '#002140',
},
},
}
})
onMounted(() => {
// 监听主题颜色变化,更新 CSS 变量
watch(
themeColor,
(newColor) => {
if (newColor) {
document.documentElement.style.setProperty('--primary-color', newColor)
}
},
{ immediate: true }
)
onMounted(async () => {
await nextTick()
// 从持久化的 store 中读取语言设置并同步到 i18n
i18n.global.locale.value = i18nStore.currentLocale
// 同步 dayjs 语言
dayjs.locale(i18nStore.currentLocale === 'zh-CN' ? 'zh-cn' : 'en')
// 初始化主题颜色
// 初始化主题颜色到 CSS 变量
if (layoutStore.themeColor) {
document.documentElement.style.setProperty('--primary-color', layoutStore.themeColor)
}

View File

@@ -301,12 +301,12 @@ onBeforeUnmount(() => {
white-space: nowrap;
&::-webkit-scrollbar {
height: 4px;
height: 0;
}
&::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.2);
border-radius: 2px;
border-radius: 0;
}
&::-webkit-scrollbar-track {

View File

@@ -88,20 +88,18 @@
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ref, reactive, onMounted } from 'vue'
import { message, Modal } from 'ant-design-vue'
import { SearchOutlined, RedoOutlined, DeleteOutlined, PlusOutlined, FolderOutlined, FileOutlined } from '@ant-design/icons-vue'
import scTable from '@/components/scTable/index.vue'
import areaModal from './components/AreaModal.vue'
import systemApi from '@/api/system'
import { useTable } from '@/hooks/useTable'
defineOptions({
name: 'systemArea'
})
// 表格引用
const tableRef = ref(null)
// 对话框状态
const dialog = reactive({
save: false
@@ -116,37 +114,44 @@ const filteredAreaTree = ref([])
const selectedAreaKeys = ref([])
const areaKeyword = ref('')
// 选中的行
const selectedRowKeys = ref([])
// 行选择配置
const rowSelection = computed(() => ({
selectedRowKeys: selectedRowKeys.value,
onChange: (selectedKeys) => {
selectedRowKeys.value = selectedKeys
// 使用useTable hooks
const {
tableRef,
searchForm,
tableData,
loading,
pagination,
rowSelection,
selectedRowKeys,
handleSearch,
handleReset,
loadData
} = useTable({
api: systemApi.area.list.get,
searchParams: {
title: '',
level: null,
parent_code: null
},
}))
// 搜索表单
const searchForm = reactive({
title: '',
level: null,
parent_code: null
rowSelection: true,
onSearchBefore: () => {
// 重置地区选择
selectedAreaKeys.value = []
},
onResetBefore: () => {
// 重置地区选择和搜索
selectedAreaKeys.value = []
areaKeyword.value = ''
filteredAreaTree.value = areaTree.value
}
})
// 表格数据
const tableData = ref([])
const loading = ref(false)
// 分页配置
const pagination = reactive({
current: 1,
pageSize: 20,
total: 0,
showSizeChanger: true,
showTotal: (total) => `${total}`,
pageSizeOptions: ['20', '50', '100', '200']
})
// 分页变化处理
const handlePaginationChange = ({ page, pageSize }) => {
pagination.current = page
pagination.pageSize = pageSize
loadData()
}
// 行key
const rowKey = 'id'
@@ -238,36 +243,6 @@ const handleAreaSearch = (e) => {
filteredAreaTree.value = filterTree(areaTree.value)
}
// 加载地区列表数据
const loadData = async () => {
loading.value = true
try {
const params = {
page: pagination.current,
limit: pagination.pageSize,
...searchForm
}
const res = await systemApi.area.list.get(params)
if (res.code === 1) {
tableData.value = res.data?.data || res.data?.list || []
pagination.total = res.data?.total || 0
} else {
message.error(res.message || '加载数据失败')
}
} catch (error) {
console.error('加载地区列表失败:', error)
message.error('加载数据失败')
} finally {
loading.value = false
}
}
// 分页变化处理
const handlePaginationChange = ({ page, pageSize }) => {
pagination.current = page
pagination.pageSize = pageSize
loadData()
}
// 地区选择事件
const onAreaSelect = (selectedKeys) => {
@@ -276,26 +251,7 @@ const onAreaSelect = (selectedKeys) => {
} else {
searchForm.parent_code = null
}
pagination.current = 1
loadData()
}
// 搜索
const handleSearch = () => {
pagination.current = 1
loadData()
}
// 重置
const handleReset = () => {
searchForm.title = ''
searchForm.level = null
searchForm.parent_code = null
selectedAreaKeys.value = []
areaKeyword.value = ''
filteredAreaTree.value = areaTree.value
pagination.current = 1
loadData()
handleSearch()
}
// 新增地区

View File

@@ -55,21 +55,19 @@
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ref, reactive, onMounted } from 'vue'
import { message, Modal } from 'ant-design-vue'
import { SearchOutlined, RedoOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons-vue'
import scTable from '@/components/scTable/index.vue'
import saveDialog from './save.vue'
import menuDrawer from './menu.vue'
import systemApi from '@/api/system'
import { useTable } from '@/hooks/useTable'
defineOptions({
name: 'systemClient'
})
// 表格引用
const tableRef = ref(null)
// 对话框状态
const dialog = reactive({
save: false,
@@ -80,34 +78,24 @@ const dialog = reactive({
const saveDialogRef = ref(null)
const menuDrawerRef = ref(null)
// 选中的行
const selectedRowKeys = ref([])
// 行选择配置
const rowSelection = computed(() => ({
selectedRowKeys: selectedRowKeys.value,
onChange: (selectedKeys) => {
selectedRowKeys.value = selectedKeys
// 使用useTable hooks
const {
tableRef,
searchForm,
tableData,
loading,
pagination,
rowSelection,
selectedRowKeys,
handleSearch,
handleReset,
loadData
} = useTable({
api: systemApi.client.list.get,
searchParams: {
title: ''
},
}))
// 搜索表单
const searchForm = reactive({
title: ''
})
// 表格数据
const tableData = ref([])
const loading = ref(false)
// 分页配置
const pagination = reactive({
current: 1,
pageSize: 20,
total: 0,
showSizeChanger: true,
showTotal: (total) => `${total}`,
pageSizeOptions: ['20', '50', '100', '200']
rowSelection: true
})
// 行key
@@ -124,30 +112,6 @@ const columns = [
{ title: '操作', dataIndex: 'action', key: 'action', width: 220, align: 'center', slot: 'action', fixed: 'right' }
]
// 加载客户端列表数据
const loadData = async () => {
loading.value = true
try {
const params = {
page: pagination.current,
limit: pagination.pageSize,
...searchForm
}
const res = await systemApi.client.list.get(params)
if (res.code === 1) {
tableData.value = res.data?.data || []
pagination.total = res.data?.total || 0
} else {
message.error(res.message || '加载数据失败')
}
} catch (error) {
console.error('加载客户端列表失败:', error)
message.error('加载数据失败')
} finally {
loading.value = false
}
}
// 分页变化处理
const handlePaginationChange = ({ page, pageSize }) => {
pagination.current = page
@@ -155,19 +119,6 @@ const handlePaginationChange = ({ page, pageSize }) => {
loadData()
}
// 搜索
const handleSearch = () => {
pagination.current = 1
loadData()
}
// 重置
const handleReset = () => {
searchForm.title = ''
pagination.current = 1
loadData()
}
// 新增客户端
const handleAdd = () => {
dialog.save = true

View File

@@ -73,9 +73,8 @@
</template>
<script setup>
import { ref, reactive, computed, onMounted, watch } from 'vue'
import { ref, reactive, computed, onMounted } from 'vue'
import { message, Modal } from 'ant-design-vue'
import { SearchOutlined, RedoOutlined, DeleteOutlined, PlusOutlined, FolderOutlined, FileOutlined, EditOutlined } from '@ant-design/icons-vue'
import scTable from '@/components/scTable/index.vue'
import dicDialog from './dic.vue'
import listDialog from './list.vue'
@@ -229,7 +228,7 @@ const handlePaginationChange = ({ page, pageSize }) => {
}
// 字典选择事件
const onDicSelect = (selectedKeys, info) => {
const onDicSelect = (selectedKeys) => {
if (selectedKeys && selectedKeys.length > 0) {
const selectedId = selectedKeys[0]
currentDic.value = findDicById(filteredDicList.value, selectedId)