1. 取消百度统计动态配置

2. 新增表格默认排序,动态更新排序信息
3. 将前端框架更新到最新版本(1.8.6)
This commit is contained in:
ktianc 2022-11-22 17:34:59 +08:00
parent fc22349bf4
commit a8d32b0c61
33 changed files with 638 additions and 827 deletions

View File

@ -1,6 +1,6 @@
{
"name": "vue-element-plus-admin",
"version": "1.8.5",
"version": "1.8.6",
"description": "一套基于vue3、element-plus、typesScript、vite3的后台集成方案。",
"author": "Archer <502431556@qq.com>",
"private": false,

View File

@ -13,7 +13,7 @@ const prefixCls = getPrefixCls('app')
const appStore = useAppStore()
// mate
// mate
const addMeta = (name: string, content: string) => {
const meta = document.createElement('meta')
meta.content = content
@ -34,10 +34,6 @@ const setSystemConfig = async () => {
res.data.web_basic.web_desc ||
'Kinit 是一套开箱即用的中后台解决方案,可以作为新项目的启动模版。'
)
//
if (res.data.web_baidu.web_baidu) {
eval(res.data.web_baidu.web_baidu)
}
}
}

View File

@ -38,7 +38,11 @@ const props = defineProps({
expand: propTypes.bool.def(false),
//
expandField: propTypes.string.def(''),
inline: propTypes.bool.def(true)
inline: propTypes.bool.def(true),
model: {
type: Object as PropType<Recordable>,
default: () => ({})
}
})
const emit = defineEmits(['search', 'reset'])
@ -74,7 +78,9 @@ const newSchema = computed(() => {
return schema
})
const { register, elFormRef, methods } = useForm()
const { register, elFormRef, methods } = useForm({
model: props.model || {}
})
const search = async () => {
await unref(elFormRef)?.validate(async (isValid) => {

View File

@ -10,7 +10,6 @@ import { TableColumn, TableSlotDefault, Pagination, TableSetPropsType } from '..
import { useAppStore } from '@/store/modules/app'
const appStore = useAppStore()
const mobile = appStore.getMobile
export default defineComponent({
name: 'Table',
@ -116,10 +115,10 @@ export default defineComponent({
small: false,
background: false,
pagerCount: 7,
layout: mobile
layout: appStore.getMobile
? 'prev, pager, next, ->, total'
: 'sizes, prev, pager, next, jumper, ->, total',
limits: [10, 20, 30, 40, 50, 100],
pageSizes: [10, 20, 30, 40, 50, 100],
disabled: false,
hideOnSinglePage: false,
total: 10

View File

@ -42,6 +42,9 @@ export const useForm = (props?: FormProps) => {
setProps: async (props: FormProps = {}) => {
const form = await getForm()
form?.setProps(props)
if (props.model) {
form?.setValues(props.model)
}
},
setValues: async (data: Recordable) => {

View File

@ -5,7 +5,6 @@ import { get } from 'lodash-es'
import type { TableProps } from '@/components/Table/src/types'
import { useI18n } from '@/hooks/web/useI18n'
import { TableSetPropsType } from '@/types/table'
import { columns } from 'element-plus/es/components/table-v2/src/common'
const { t } = useI18n()
@ -23,6 +22,8 @@ interface UseTableConfig<T = any> {
data: string
count?: string
}
// 默认传递的参数
defaultParams?: Recordable
props?: TableProps
}
@ -36,6 +37,12 @@ interface TableObject<T = any> {
currentRow: Nullable<T>
}
type TableOrderChange = {
column: Recordable
prop: string
order: string | null
}
export const useTable = <T = any>(config?: UseTableConfig<T>) => {
const tableObject = reactive<TableObject<T>>({
// 页数
@ -47,7 +54,9 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
// 表格数据
tableData: [],
// AxiosConfig 配置
params: {},
params: {
...(config?.defaultParams || {})
},
// 加载中
loading: true,
// 当前行的数据
@ -137,6 +146,15 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
const table = await getTable()
return (table?.selections || []) as T[]
},
// 设置表格排序
setOrderParams: (data: TableOrderChange) => {
tableObject.page = 1
tableObject.params = Object.assign(tableObject.params, {
v_order: data.order,
v_order_field: data.prop
})
methods.getList()
},
// 与Search组件结合
setSearchParams: (data: Recordable) => {
tableObject.page = 1

View File

@ -35,9 +35,6 @@ const { register, elTableRef, tableObject, methods } = useTable({
delListApi: delMenuListApi,
response: {
data: 'data'
},
props: {
columns
}
})
@ -149,6 +146,7 @@ watch(
:data="tableObject.tableData"
:loading="tableObject.loading"
:selection="false"
:columns="columns"
:border="true"
:size="tableSize"
row-key="id"

View File

@ -26,9 +26,6 @@ const { register, elTableRef, tableObject, methods } = useTable({
response: {
data: 'data',
count: 'count'
},
props: {
columns
}
})
@ -136,6 +133,7 @@ watch(
v-model:page="tableObject.page"
:data="tableObject.tableData"
:loading="tableObject.loading"
:columns="columns"
:size="tableSize"
:border="true"
:selection="false"

View File

@ -206,7 +206,6 @@ export const searchSchema = reactive<FormSchema[]>([
value: false
}
]
},
value: true
}
}
])

View File

@ -62,8 +62,8 @@ const { register, elTableRef, tableObject, methods } = useTable({
data: 'data',
count: 'count'
},
props: {
columns
defaultParams: {
is_active: true
}
})
@ -199,16 +199,16 @@ const handleCommand = (command: string) => {
delDatas(null, true)
}
}
//
const tableSortChange = async (data: any) => {
console.log(data)
}
</script>
<template>
<ContentWrap>
<Search :schema="searchSchema" @search="setSearchParams" @reset="setSearchParams" />
<Search
:model="{ is_active: true }"
:schema="searchSchema"
@search="setSearchParams"
@reset="setSearchParams"
/>
<div class="mb-8px flex justify-between">
<ElRow :gutter="10">
@ -262,6 +262,7 @@ const tableSortChange = async (data: any) => {
v-model:page="tableObject.page"
:data="tableObject.tableData"
:loading="tableObject.loading"
:columns="columns"
:selection="true"
:size="tableSize"
:border="true"
@ -269,7 +270,6 @@ const tableSortChange = async (data: any) => {
total: tableObject.count
}"
@register="register"
@sort-change="tableSortChange"
>
<template #action="{ row }">
<ElButton

View File

@ -54,9 +54,6 @@ const { register, elTableRef, tableObject, methods } = useTable({
response: {
data: 'data',
count: 'count'
},
props: {
columns
}
})
tableObject.params = { dict_type_id: dictType }
@ -164,6 +161,7 @@ watch(
v-model:page="tableObject.page"
:data="tableObject.tableData"
:loading="tableObject.loading"
:columns="columns"
:selection="false"
:pagination="{
total: tableObject.count

View File

@ -29,9 +29,6 @@ const { register, elTableRef, tableObject, methods } = useTable({
response: {
data: 'data',
count: 'count'
},
props: {
columns
}
})
@ -135,6 +132,7 @@ watch(
<Table
v-model:limit="tableObject.limit"
v-model:page="tableObject.page"
:columns="columns"
:data="tableObject.tableData"
:loading="tableObject.loading"
:selection="false"

View File

@ -79,7 +79,8 @@ export const columns = reactive<TableColumn[]>([
field: 'create_datetime',
label: '创建时间',
show: true,
span: 24
span: 24,
sortable: true
},
{
field: 'action',

View File

@ -17,8 +17,9 @@ const { register, elTableRef, tableObject, methods } = useTable({
data: 'data',
count: 'count'
},
props: {
columns
defaultParams: {
v_order: 'descending',
v_order_field: 'create_datetime'
}
})
@ -31,9 +32,7 @@ const view = (row: any) => {
dialogVisible.value = true
}
const { getList, setSearchParams } = methods
getList()
const { getList, setSearchParams, setOrderParams } = methods
const tableSize = ref('default')
@ -51,6 +50,8 @@ watch(
deep: true
}
)
getList()
</script>
<template>
@ -65,6 +66,8 @@ watch(
<Table
v-model:limit="tableObject.limit"
v-model:page="tableObject.page"
:defaultSort="{ prop: 'create_datetime', order: 'descending' }"
:columns="columns"
:data="tableObject.tableData"
:loading="tableObject.loading"
:selection="false"
@ -74,6 +77,7 @@ watch(
total: tableObject.count
}"
@register="register"
@sort-change="setOrderParams"
>
<template #action="{ row }">
<ElButton type="primary" link size="small" @click="view(row)"> 详情 </ElButton>

View File

@ -16,9 +16,6 @@ const { register, elTableRef, tableObject, methods } = useTable({
response: {
data: 'data',
count: 'count'
},
props: {
columns
}
})
@ -65,6 +62,7 @@ watch(
<Table
v-model:limit="tableObject.limit"
v-model:page="tableObject.page"
:columns="columns"
:data="tableObject.tableData"
:loading="tableObject.loading"
:selection="false"

View File

@ -45,7 +45,7 @@ class UserDal(DalBase):
"""
创建用户
"""
unique = await self.get_data(telephone=data.telephone, return_none=True)
unique = await self.get_data(telephone=data.telephone, v_return_none=True)
if unique:
raise ValueError("手机号已存在!")
password = data.telephone[5:12] if settings.DEFAULT_PASSWORD == "0" else settings.DEFAULT_PASSWORD
@ -96,7 +96,7 @@ class UserDal(DalBase):
"""
导出用户查询列表为excel
"""
datas = await self.get_datas(**params.dict(), return_objs=True)
datas = await self.get_datas(**params.dict(), v_return_objs=True)
# 获取表头
row = list(map(lambda i: i.get("label"), header))
rows = []
@ -126,7 +126,7 @@ class UserDal(DalBase):
补全表头数据选项
"""
# 角色选择项
roles = await RoleDal(self.db).get_datas(limit=0, return_objs=True, disabled=False, is_admin=False)
roles = await RoleDal(self.db).get_datas(limit=0, v_return_objs=True, disabled=False, is_admin=False)
role_options = self.import_headers[4]
assert isinstance(role_options, dict)
role_options["options"] = [{"label": role.name, "value": role.id} for role in roles]
@ -178,7 +178,7 @@ class UserDal(DalBase):
初始化所选用户密码并发送通知短信
将用户密码改为系统默认密码并将初始化密码状态改为false
"""
users = await self.get_datas(limit=0, id=("in", ids), return_objs=True)
users = await self.get_datas(limit=0, id=("in", ids), v_return_objs=True)
result = []
for user in users:
# 重置密码

View File

@ -9,16 +9,16 @@
"""
类依赖项-官方文档https://fastapi.tiangolo.com/zh/tutorial/dependencies/classes-as-dependencies/
"""
from core.dependencies import Paging
from fastapi import Depends
from core.dependencies import Paging, QueryParams
class RoleParams(Paging):
class RoleParams(QueryParams):
"""
列表分页
"""
def __init__(self, name: str = None, role_key: str = None, disabled: bool = None, page: int = 1, limit: int = 10):
super(RoleParams, self).__init__(page, limit)
def __init__(self, name: str = None, role_key: str = None, disabled: bool = None, params: Paging = Depends()):
super().__init__(params)
self.name = ("like", name)
self.role_key = ("like", role_key)
self.disabled = disabled

View File

@ -9,16 +9,19 @@
"""
类依赖项-官方文档https://fastapi.tiangolo.com/zh/tutorial/dependencies/classes-as-dependencies/
"""
from core.dependencies import Paging
from fastapi import Depends
from core.dependencies import Paging, QueryParams
class UserParams(Paging):
class UserParams(QueryParams):
"""
列表分页
"""
def __init__(self, name: str = None, telephone: str = None, is_active: bool = None, page: int = 1, limit: int = 10):
super(UserParams, self).__init__(page, limit)
def __init__(self, name: str = None, telephone: str = None, is_active: bool = None, params: Paging = Depends()):
super().__init__(params)
self.name = ("like", name)
self.telephone = ("like", telephone)
self.is_active = is_active

View File

@ -33,7 +33,7 @@ async def login_auth(telephone: str, db: AsyncSession):
如果令牌无效立即返回一个 HTTP 错误
"""
return await crud.UserDal(db).get_data(telephone=telephone, return_none=True)
return await crud.UserDal(db).get_data(telephone=telephone, v_return_none=True)
@AuthValidation
@ -46,5 +46,5 @@ async def full_admin(telephone: str, db: AsyncSession):
如果令牌无效立即返回一个 HTTP 错误
"""
options = [models.VadminUser.roles, "roles.menus"]
return await crud.UserDal(db).get_data(telephone=telephone, return_none=True, options=options)
return await crud.UserDal(db).get_data(telephone=telephone, v_return_none=True, options=options)

View File

@ -45,7 +45,7 @@ class LoginValidation:
async def __call__(self, data: LoginForm, db: AsyncSession, request: Request) -> LoginResult:
self.result = LoginResult()
options = [models.VadminUser.roles, "roles.menus"]
user = await crud.UserDal(db).get_data(telephone=data.telephone, return_none=True, options=options)
user = await crud.UserDal(db).get_data(telephone=data.telephone, v_return_none=True, options=options)
if not user:
self.result.msg = "该手机号不存在!"
return self.result

View File

@ -9,19 +9,18 @@
"""
类依赖项-官方文档https://fastapi.tiangolo.com/zh/tutorial/dependencies/classes-as-dependencies/
"""
from core.dependencies import Paging
from fastapi import Depends
from core.dependencies import Paging, QueryParams
class LoginParams(Paging):
class LoginParams(QueryParams):
"""
列表分页
"""
def __init__(self, ip: str = None, address: str = None, telephone: str = None, status: bool = None, page: int = 1,
limit: int = 10):
super(LoginParams, self).__init__(page, limit)
def __init__(self, ip: str = None, address: str = None, telephone: str = None, status: bool = None,
params: Paging = Depends()):
super().__init__(params)
self.ip = ("like", ip)
self.telephone = ("like", telephone)
self.address = ("like", address)
self.status = status
self.order = "desc"

View File

@ -9,17 +9,17 @@
"""
类依赖项-官方文档https://fastapi.tiangolo.com/zh/tutorial/dependencies/classes-as-dependencies/
"""
from core.dependencies import Paging
from fastapi import Depends
from core.dependencies import Paging, QueryParams
class OperationParams(Paging):
class OperationParams(QueryParams):
"""
列表分页
"""
def __init__(self, summary: str = None, telephone: str = None, request_method: str = None, page: int = 1,
limit: int = 10):
super(OperationParams, self).__init__(page, limit)
def __init__(self, summary: str = None, telephone: str = None, request_method: str = None,
params: Paging = Depends()):
super().__init__(params)
self.summary = ("like", summary)
self.telephone = ("like", telephone)
self.request_method = request_method

View File

@ -9,15 +9,14 @@
"""
类依赖项-官方文档https://fastapi.tiangolo.com/zh/tutorial/dependencies/classes-as-dependencies/
"""
from core.dependencies import Paging
from fastapi import Depends
from core.dependencies import Paging, QueryParams
class SMSParams(Paging):
class SMSParams(QueryParams):
"""
列表分页
"""
def __init__(self, telephone: str = None, page: int = 1, limit: int = 10):
super(SMSParams, self).__init__(page, limit)
def __init__(self, telephone: str = None, params: Paging = Depends()):
super().__init__(params)
self.telephone = ("like", telephone)
self.order = "desc"

View File

@ -30,7 +30,7 @@ class DictTypeDal(DalBase):
data = {}
for dict_type in dict_types:
dict_data = await DictTypeDal(self.db).\
get_data(dict_type=dict_type, return_none=True, options=[self.model.details])
get_data(dict_type=dict_type, v_return_none=True, options=[self.model.details])
if not dict_data:
data[dict_type] = []
continue
@ -60,9 +60,10 @@ class SettingsDal(DalBase):
"""
获取系统配置标签下的信息
"""
datas = await self.get_datas(limit=0, tab_id=tab_id, return_objs=True)
datas = await self.get_datas(limit=0, tab_id=tab_id, v_return_objs=True)
result = {}
for data in datas:
if not data.disabled:
result[data.config_key] = data.config_value
return result
@ -97,11 +98,12 @@ class SettingsTabDal(DalBase):
model = models.VadminSystemSettingsTab
options = [model.settings]
datas = await self.get_datas(limit=0, options=options, classify=("in", classify), disabled=False,
return_objs=True, hidden=hidden)
v_return_objs=True, hidden=hidden)
result = {}
for tab in datas:
tabs = {}
for item in tab.settings:
if not item.disabled:
tabs[item.config_key] = item.config_value
result[tab.tab_name] = tabs
return result

View File

@ -6,9 +6,8 @@
# @IDE : PyCharm
# @desc : 系统字典模型
from sqlalchemy.orm import relationship
from db.db_base import BaseModel
from sqlalchemy import Column, String, TEXT, Integer, ForeignKey
from sqlalchemy import Column, String, TEXT, Integer, ForeignKey, Boolean
class VadminSystemSettings(BaseModel):
@ -19,6 +18,7 @@ class VadminSystemSettings(BaseModel):
config_key = Column(String(255), index=True, nullable=False, unique=True, comment="配置表键")
config_value = Column(TEXT, comment="配置表内容")
remark = Column(String(255), comment="备注信息")
disabled = Column(Boolean, default=False, comment="是否禁用")
tab_id = Column(Integer, ForeignKey("vadmin_system_settings_tab.id", ondelete='CASCADE'), comment="关联tab标签")
tab = relationship("VadminSystemSettingsTab", foreign_keys=tab_id, back_populates="settings")

View File

@ -9,15 +9,15 @@
"""
类依赖项-官方文档https://fastapi.tiangolo.com/zh/tutorial/dependencies/classes-as-dependencies/
"""
from core.dependencies import Paging
from fastapi import Depends
from core.dependencies import Paging, QueryParams
class DictDetailParams(Paging):
class DictDetailParams(QueryParams):
"""
列表分页
"""
def __init__(self, dict_type_id: int = None, label: str = None, page: int = 1, limit: int = 10):
super(DictDetailParams, self).__init__(page, limit)
def __init__(self, dict_type_id: int = None, label: str = None, params: Paging = Depends()):
super().__init__(params)
self.dict_type_id = dict_type_id
self.label = ("like", label)

View File

@ -9,14 +9,14 @@
"""
类依赖项-官方文档https://fastapi.tiangolo.com/zh/tutorial/dependencies/classes-as-dependencies/
"""
from core.dependencies import Paging
from fastapi import Depends
from core.dependencies import Paging, QueryParams
class DictTypeParams(Paging):
class DictTypeParams(QueryParams):
"""
列表分页
"""
def __init__(self, dict_name: str = None, page: int = 1, limit: int = 10):
super(DictTypeParams, self).__init__(page, limit)
def __init__(self, dict_name: str = None, params: Paging = Depends()):
super().__init__(params)
self.dict_name = ("like", dict_name)

View File

@ -19,6 +19,7 @@ class Settings(BaseModel):
config_key: str
config_value: Optional[str] = None
remark: Optional[str] = None
disabled: Optional[bool] = None
tab_id: int

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -14,7 +14,7 @@
# selectinload 官方文档:
# https://www.osgeo.cn/sqlalchemy/orm/loading_relationships.html?highlight=selectinload#sqlalchemy.orm.selectinload
import datetime
from typing import List, Union
from typing import List
from fastapi import HTTPException
from fastapi.encoders import jsonable_encoder
from sqlalchemy import func, delete, update, or_
@ -24,7 +24,6 @@ from sqlalchemy.orm import selectinload
from starlette import status
from core.logger import logger
from sqlalchemy.sql.selectable import Select
from pydantic import BaseModel
class DalBase:
@ -44,11 +43,11 @@ class DalBase:
@param options: 指示应使用select在预加载中加载给定的属性
@param schema: 指定使用的序列化对象
@param kwargs: 关键词参数,
@param kwargs: order排序默认正序 desc 是倒叙
@param kwargs: return_none是否返回空 None否认 抛出异常默认抛出异常
@param kwargs: v_order排序默认正序 desc 是倒叙
@param kwargs: v_return_none是否返回空 None否认 抛出异常默认抛出异常
"""
order = kwargs.get("order", None)
return_none = kwargs.get("return_none", False)
order = kwargs.pop("v_order", None)
return_none = kwargs.pop("v_return_none", False)
keys_exist = False
if keys:
for key, value in keys.items():
@ -60,7 +59,7 @@ class DalBase:
kwargs_exist = False
if kwargs:
for key, value in kwargs.items():
if key != "order" and key != "return_none" and value and getattr(self.model, key, None):
if value and getattr(self.model, key, None):
kwargs_exist = True
break
sql = select(self.model).where(self.model.delete_datetime.is_(None))
@ -68,7 +67,7 @@ class DalBase:
if data_id:
sql = sql.where(self.model.id == data_id)
sql = self.add_filter_condition(sql, keys, options, **kwargs)
if order and order == "desc":
if order and (order == "desc" or order == "descending"):
sql = sql.order_by(self.model.create_datetime.desc())
queryset = await self.db.execute(sql)
data = queryset.scalars().first()
@ -90,23 +89,23 @@ class DalBase:
@param keys: 外键字段查询
@param options: 指示应使用select在预加载中加载给定的属性
@param schema: 指定使用的序列化对象
@param kwargs: order排序默认正序 desc 是倒叙
@param kwargs: order_field排序字段
@param kwargs: return_objs是否返回对象
@param kwargs: start_sql初始 sql
@param kwargs: v_order排序默认正序 desc 是倒叙
@param kwargs: v_order_field排序字段
@param kwargs: v_return_objs是否返回对象
@param kwargs: v_start_sql初始 sql
"""
order = kwargs.get("order", None)
order_field = kwargs.get("order_field", None)
return_objs = kwargs.get("return_objs", False)
start_sql = kwargs.get("start_sql", None)
order = kwargs.pop("v_order", None)
order_field = kwargs.pop("v_order_field", None)
return_objs = kwargs.pop("v_return_objs", False)
start_sql = kwargs.pop("v_start_sql", None)
if not isinstance(start_sql, Select):
start_sql = select(self.model).where(self.model.delete_datetime.is_(None))
sql = self.add_filter_condition(start_sql, keys, options, **kwargs)
if order_field and order == "desc":
if order_field and (order == "desc" or order == "descending"):
sql = sql.order_by(getattr(self.model, order_field).desc(), self.model.id.desc())
elif order_field:
sql = sql.order_by(getattr(self.model, order_field), self.model.id)
elif order == "desc":
elif order == "desc" or order == "descending":
sql = sql.order_by(self.model.id.desc())
if limit != 0:
sql = sql.offset((page - 1) * limit).limit(limit)

View File

@ -15,26 +15,39 @@ from fastapi import Body
import copy
class Paging:
"""
列表分页
"""
def __init__(self, page: int = 1, limit: int = 10):
self.page = page
self.limit = limit
self.order = None
class QueryParams:
def dict(self):
def __init__(self, params=None):
if params:
self.page = params.page
self.limit = params.limit
self.v_order = params.v_order
self.v_order_field = params.v_order_field
def dict(self) -> dict:
return self.__dict__
def to_count(self):
def to_count(self) -> dict:
params = copy.deepcopy(self.__dict__)
del params["page"]
del params["limit"]
del params["order"]
del params["v_order"]
del params["v_order_field"]
return params
class Paging(QueryParams):
"""
列表分页
"""
def __init__(self, page: int = 1, limit: int = 10, v_order_field: str = "id", v_order: str = None):
super().__init__()
self.page = page
self.limit = limit
self.v_order = v_order
self.v_order_field = v_order_field
class IdList:
"""
id 列表

View File

@ -30,11 +30,16 @@ class MongoManage(DatabaseManage):
async def create_data(self, collection: str, data: dict) -> InsertOneResult:
return await self.db[collection].insert_one(data)
async def get_datas(self, collection: str, page: int = 1, limit: int = 10, schema: BaseModel = None, **kwargs):
async def get_datas(self, collection: str, schema: BaseModel = None, **kwargs):
"""
使用 find() 要查询的一组文档 find() 没有I / O也不需要 await 表达式它只是创建一个 AsyncIOMotorCursor 实例
当您调用 to_list() 或为循环执行异步时 (async for) 查询实际上是在服务器上执行的
"""
page = kwargs.pop("page", 1)
limit = kwargs.pop("limit", 10)
order = kwargs.pop("v_order", None)
order_field = kwargs.pop("v_order_field", None)
params = self.filter_condition(**kwargs)
cursor = self.db[collection].find(params)