Merge remote-tracking branch 'origin/master'
commit
e51ca6f5ae
|
|
@ -5,7 +5,7 @@ import axios, {
|
|||
} from 'axios'
|
||||
import * as qs from 'qs'
|
||||
import { useAppUserStore } from '@/common/app/app-user-store.ts'
|
||||
import { throttle } from '@/common/utils/index.ts'
|
||||
import Utils from '@/common/utils/index.ts'
|
||||
import mime from '@/common/utils/mime.ts'
|
||||
import Evt from '@/common/utils/evt.ts'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
|
@ -41,7 +41,7 @@ const paramsSerializer = (params: any) => {
|
|||
/* function errHandler(r?: R) {
|
||||
Toast.error(r?.message ?? '操作失败')
|
||||
} */
|
||||
const errHandler = throttle(500, (r?: AxiosResponse<R<any>, any>) => {
|
||||
const errHandler = Utils.throttle(500, (r?: AxiosResponse<R<any>, any>) => {
|
||||
console.log('异常处理', r)
|
||||
ElMessage.error(r?.data?.message ?? '服务器错误')
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import type { ReactiveFlags } from 'vue'
|
||||
|
||||
/**
|
||||
* 类型标签,Object.prototype.toString.call(obj) 的返回值
|
||||
*/
|
||||
|
|
@ -29,7 +31,7 @@ export class TypeTag {
|
|||
* @param t 时间阈值(ms)
|
||||
* @return 包装后的函数
|
||||
*/
|
||||
export function throttle<T extends any[]>(t: number, fn: (...args: T) => void) {
|
||||
function throttle<T extends any[]>(t: number, fn: (...args: T) => void) {
|
||||
let lastExecTime = 0
|
||||
return function (this: any, ...args: T) {
|
||||
let now = Date.now()
|
||||
|
|
@ -48,7 +50,7 @@ export function throttle<T extends any[]>(t: number, fn: (...args: T) => void) {
|
|||
* @param t 时间阈值(ms)
|
||||
* @return 包装后的函数
|
||||
*/
|
||||
export function debounce<T extends any[]>(t: number, fn: (...args: T) => void) {
|
||||
function debounce<T extends any[]>(t: number, fn: (...args: T) => void) {
|
||||
let deferTimer: number | null = null
|
||||
return function (this: any, ...args: T) {
|
||||
if (deferTimer != null) {
|
||||
|
|
@ -61,8 +63,66 @@ export function debounce<T extends any[]>(t: number, fn: (...args: T) => void) {
|
|||
}
|
||||
}
|
||||
|
||||
export function clone<T = any>(t: T) {
|
||||
return JSON.parse(JSON.stringify(t)) as T
|
||||
function clone<T = any>(value: T): T {
|
||||
if (value === null || typeof value !== 'object') {
|
||||
return value
|
||||
}
|
||||
const rawValue = isReactive(value) ? toRaw(value) : value
|
||||
if (rawValue instanceof Date) {
|
||||
return new Date(rawValue.getTime()) as T
|
||||
}
|
||||
if (rawValue instanceof RegExp) {
|
||||
return new RegExp(rawValue.source, rawValue.flags) as T
|
||||
}
|
||||
if (Array.isArray(rawValue)) {
|
||||
return rawValue.map((item) => clone(item)) as T
|
||||
}
|
||||
const clonedObj = {} as T
|
||||
Object.keys(rawValue).forEach((key) => {
|
||||
clonedObj[key as keyof T] = clone(rawValue[key as keyof T])
|
||||
})
|
||||
return clonedObj as T
|
||||
}
|
||||
|
||||
type ExtractRawType<T> =
|
||||
// 匹配 reactive 响应式对象(通过 Vue 内置的 RAW 标记提取原始类型)
|
||||
T extends { [ReactiveFlags.RAW]: infer RawValue }
|
||||
? RawValue
|
||||
// 递归处理数组(兼容 reactive([]) 场景)
|
||||
: T extends Array<infer U>
|
||||
? Array<ExtractRawType<U>>
|
||||
// 递归处理嵌套对象(兼容 reactive({ a: { b: 1 } }) 场景)
|
||||
: T extends object
|
||||
? { [K in keyof T]: ExtractRawType<T[K]> }
|
||||
// 非对象类型直接返回(如 string/number 等)
|
||||
: T;
|
||||
|
||||
type ResetAble<T> = T & { $reset: (val?: Partial<ExtractRawType<T>>) => void }
|
||||
|
||||
|
||||
function resetAble<T extends object>(target: T): ResetAble<T> {
|
||||
const initialData = clone(target) as T
|
||||
|
||||
(target as ResetAble<T>).$reset = (val?: Partial<ExtractRawType<T>>) => {
|
||||
if (val == null) {
|
||||
val = initialData
|
||||
}
|
||||
if (Array.isArray(val)) {
|
||||
const arr = target as unknown as Array<unknown>
|
||||
const initialArr = val as unknown as Array<unknown>
|
||||
arr.splice(0, arr.length, ...initialArr)
|
||||
} else {
|
||||
Object.keys(val).forEach((key) => {
|
||||
(target as Record<string, unknown>)[key] = (val as Record<string, unknown>)[key]
|
||||
})
|
||||
Object.getOwnPropertyNames(target).forEach((key) => {
|
||||
if (key !== '$reset' && !(key in val)) {
|
||||
(target as Record<string, unknown>)[key] = undefined
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
return target as ResetAble<T>
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
@ -70,4 +130,5 @@ export default {
|
|||
debounce,
|
||||
TypeTag,
|
||||
clone,
|
||||
resetAble,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ function parse(date: Date | number | string | DateObjectUnits, fmt: string = FMT
|
|||
* @param date luxon 库的时间对象、JS 时间对象
|
||||
* @param fmt 时间格式(仅时间字符串需要此参数,默认:yyyy-MM-dd HH:mm:ss)
|
||||
*/
|
||||
function format(date: DateTime<true | false> | Date, fmt: string = FMT.date_time_sec) {
|
||||
function format(date?: DateTime<true | false> | Date, fmt: string = FMT.date_time_sec) {
|
||||
if (date == null) return ''
|
||||
if (isDate(date)) {
|
||||
return DateTime.fromJSDate(date as Date).toFormat(fmt)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
// ------
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
import { GlobalComponents } from 'vue'
|
||||
|
||||
export {}
|
||||
|
||||
|
|
@ -15,11 +14,8 @@ declare module 'vue' {
|
|||
ElAside: typeof import('element-plus/es')['ElAside']
|
||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
||||
ElCollapse: typeof import('element-plus/es')['ElCollapse']
|
||||
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
|
||||
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||
|
|
@ -35,7 +31,6 @@ declare module 'vue' {
|
|||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
ElIconFilter: typeof import('@element-plus/icons-vue')['Filter']
|
||||
ElIconPicture: typeof import('@element-plus/icons-vue')['Picture']
|
||||
ElImage: typeof import('element-plus/es')['ElImage']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
|
|
@ -50,7 +45,6 @@ declare module 'vue' {
|
|||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||
ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||
ElTabsPane: typeof import('element-plus/es')['ElTabsPane']
|
||||
ElTag: typeof import('element-plus/es')['ElTag']
|
||||
ElText: typeof import('element-plus/es')['ElText']
|
||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||
|
|
@ -70,11 +64,8 @@ declare global {
|
|||
const ElAside: typeof import('element-plus/es')['ElAside']
|
||||
const ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||
const ElButton: typeof import('element-plus/es')['ElButton']
|
||||
const ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
||||
const ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
const ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
||||
const ElCollapse: typeof import('element-plus/es')['ElCollapse']
|
||||
const ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
|
||||
const ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||
const ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||
const ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||
|
|
@ -90,7 +81,6 @@ declare global {
|
|||
const ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
const ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||
const ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
const ElIconFilter: typeof import('@element-plus/icons-vue')['Filter']
|
||||
const ElIconPicture: typeof import('@element-plus/icons-vue')['Picture']
|
||||
const ElImage: typeof import('element-plus/es')['ElImage']
|
||||
const ElInput: typeof import('element-plus/es')['ElInput']
|
||||
|
|
@ -105,7 +95,6 @@ declare global {
|
|||
const ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
const ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||
const ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||
const ElTabsPane: typeof import('element-plus/es')['ElTabsPane']
|
||||
const ElTag: typeof import('element-plus/es')['ElTag']
|
||||
const ElText: typeof import('element-plus/es')['ElText']
|
||||
const ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||
|
|
|
|||
|
|
@ -89,10 +89,10 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import CustomerApi from "@/pages/cst/customer/customer-api.ts";
|
||||
import CustomerForm from "@/pages/cst/customer/CustomerForm.vue";
|
||||
import Page from "@/components/page/Page.vue";
|
||||
import { elIcons } from "@/common/element/element.ts";
|
||||
import CustomerApi from '@/pages/cst/customer/customer-api.ts'
|
||||
import CustomerForm from '@/pages/cst/customer/CustomerForm.vue'
|
||||
import Page from '@/components/page/Page.vue'
|
||||
import { elIcons } from '@/common/element/element.ts'
|
||||
|
||||
const tableData = ref<CustomerTypes.SearchCustomerResult[]>([]);
|
||||
let searchForm = reactive<CustomerTypes.SearchCustomerParam>({
|
||||
|
|
@ -132,10 +132,6 @@ function modifyHandler({ row }: { row: CustomerTypes.SearchCustomerResult }) {
|
|||
showDialog(row);
|
||||
}
|
||||
|
||||
function addHandler() {
|
||||
showDialog();
|
||||
}
|
||||
|
||||
function reset() {
|
||||
// Object.assign(searchForm, {});
|
||||
searchForm = reactive<CustomerTypes.SearchCustomerParam>({
|
||||
|
|
|
|||
|
|
@ -107,12 +107,6 @@ function selectDictHandle({row}: { row: DictTypes.SearchDictResult }) {
|
|||
emits('searchDict', row)
|
||||
}
|
||||
|
||||
function pageChangeHandler(currentPage: number, pageSize: number) {
|
||||
searchForm.current = currentPage
|
||||
searchForm.size = pageSize
|
||||
paging()
|
||||
}
|
||||
|
||||
function reset() {
|
||||
searchForm.value = {
|
||||
orders: 'dict_key,id',
|
||||
|
|
|
|||
|
|
@ -101,11 +101,6 @@ const searching = ref(false)
|
|||
const deling = ref(false)
|
||||
const showSearchForm = ref(true)
|
||||
const tplFormIns = useTemplateRef<InstanceType<typeof TplForm>>('tplForm')
|
||||
const pagination = reactive<G.Pagination>({
|
||||
total: 0,
|
||||
current: 1,
|
||||
size: 1,
|
||||
})
|
||||
|
||||
function showDialog(data?: TplTypes.SearchTplResult) {
|
||||
tplFormIns.value?.open(data)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,16 @@
|
|||
</ElInput>
|
||||
<template #dropdown>
|
||||
<div class="dropdown-table-wrapper">
|
||||
<ElTable ref="dropdownTable" :data="iconTableDataSource" empty-text="暂无数据" highlight-current-row style="width: 324px" @current-change="currentChangeHandler">
|
||||
<ElTable
|
||||
ref="dropdownTable"
|
||||
:data="iconTableDataSource"
|
||||
cell-class-name="table-cell"
|
||||
class="table-list"
|
||||
empty-text="暂无数据"
|
||||
header-row-class-name="table-header"
|
||||
row-key="id"
|
||||
width="324"
|
||||
@current-change="currentChangeHandler">
|
||||
<ElTableColumn label="#" type="index"/>
|
||||
<ElTableColumn label="图标" prop="font_class">
|
||||
<template #default="scope">
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ const searchForm = ref<MenuTypes.SearchForm>({})
|
|||
const searching = ref(false)
|
||||
const showSearchForm = ref(true)
|
||||
const menuFormIns = useTemplateRef<InstanceType<typeof MenuForm>>('menuForm')
|
||||
const dataTableIns = useTemplateRef<InstanceType<TableInstance>>('dataTable')
|
||||
const dataTableIns = useTemplateRef<TableInstance>('dataTable')
|
||||
const deling = ref(false)
|
||||
|
||||
function showDialog(data?: MenuTypes.MenuForm) {
|
||||
|
|
@ -148,7 +148,7 @@ function listAll() {
|
|||
})
|
||||
}
|
||||
|
||||
function treeLoad(row: MenuTypes.SysMenu, expanded: boolean, resolve: (data: MenuTypes.SysMenu[]) => void) {
|
||||
function treeLoad(row: MenuTypes.SysMenu, expanded: any, resolve: (data: MenuTypes.SysMenu[]) => void) {
|
||||
if (resolve == null && !expanded) return
|
||||
searching.value = true
|
||||
MenuApi.listAll({...searchForm.value, pid: row.id})
|
||||
|
|
@ -159,7 +159,7 @@ function treeLoad(row: MenuTypes.SysMenu, expanded: boolean, resolve: (data: Men
|
|||
return it
|
||||
}) ?? [])
|
||||
} else {
|
||||
dataTableIns.value.updateKeyChildren(row.id,res.data?.map(it => {
|
||||
dataTableIns.value?.updateKeyChildren(row.id, res.data?.map(it => {
|
||||
it.hasChildren = true
|
||||
it.children = []
|
||||
return it
|
||||
|
|
|
|||
|
|
@ -113,7 +113,6 @@ import TaskApi from '@/pages/sys/task/task-api.ts'
|
|||
import Page from '@/components/page/Page.vue'
|
||||
import { elIcons } from '@/common/element/element.ts'
|
||||
import TaskForm from '@/pages/sys/task/TaskForm.vue'
|
||||
import ScheduleRecode from '@/pages/sys/task/schedule-recode/ScheduleRecode.vue'
|
||||
import ScheduleRecodePanel from '@/pages/sys/task/schedule-recode/ScheduleRecodePanel.vue'
|
||||
import Times from '@/common/utils/times.ts'
|
||||
|
||||
|
|
@ -127,7 +126,7 @@ const searching = ref(false)
|
|||
const deling = ref(false)
|
||||
const showSearchForm = ref(true)
|
||||
const taskFormIns = useTemplateRef<InstanceType<typeof TaskForm>>('taskForm')
|
||||
const scheduleRecodePanelIns = useTemplateRef<InstanceType<typeof ScheduleRecode>>('scheduleRecodePanel')
|
||||
const scheduleRecodePanelIns = useTemplateRef<InstanceType<typeof ScheduleRecodePanel>>('scheduleRecodePanel')
|
||||
const pagination = reactive<G.Pagination>({
|
||||
total: 0,
|
||||
pages: 0,
|
||||
|
|
|
|||
|
|
@ -207,8 +207,8 @@ function paging() {
|
|||
} = searchForm.value
|
||||
TaskExecuteLogApi.paging({
|
||||
logLevel,
|
||||
startLogTime: Colls.isEmpty(logTime) ? undefined : Times.format(logTime[0]),
|
||||
endLogTime: Colls.isEmpty(logTime) ? undefined : Times.format(logTime[1]),
|
||||
startLogTime: Colls.isEmpty(logTime) ? undefined : Times.format(logTime![0]),
|
||||
endLogTime: Colls.isEmpty(logTime) ? undefined : Times.format(logTime![1]),
|
||||
scheduleId: props.scheduleId,
|
||||
})
|
||||
.then(res => {
|
||||
|
|
@ -8,7 +8,7 @@ declare global {
|
|||
// 日志等级
|
||||
logLevel?: string
|
||||
// 日志时间
|
||||
logTime?: string
|
||||
logTime?: Date[]
|
||||
startLogTime?: string
|
||||
endLogTime?: string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,8 +245,8 @@ function paging() {
|
|||
scheduleType,
|
||||
taskStatus,
|
||||
manually,
|
||||
startTime: Colls.isEmpty(scheduleTime) ? undefined : Times.format(scheduleTime[0]),
|
||||
endTime: Colls.isEmpty(scheduleTime) ? undefined : Times.format(scheduleTime[1]),
|
||||
startTime: Colls.isEmpty(scheduleTime) ? undefined : Times.format(scheduleTime![0]),
|
||||
endTime: Colls.isEmpty(scheduleTime) ? undefined : Times.format(scheduleTime![1]),
|
||||
})
|
||||
.then(res => {
|
||||
tableData.value = res.data?.records ?? []
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ declare global {
|
|||
// 调度方式
|
||||
scheduleType?: string
|
||||
// 调度时间
|
||||
scheduleTime?: string
|
||||
scheduleTime?: Date[]
|
||||
// 任务开始时间
|
||||
startTime?: string
|
||||
// 任务结束时间
|
||||
|
|
|
|||
|
|
@ -1,20 +1,10 @@
|
|||
<template>
|
||||
<Page>
|
||||
<ElForm v-show="showSearchForm" inline @submit.prevent="paging">
|
||||
<ElFormItem label="昵称">
|
||||
<ElFormItem label="姓名">
|
||||
<ElInput
|
||||
v-model="searchForm.nickname"
|
||||
placeholder="昵称"/>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="头像">
|
||||
<ElInput
|
||||
v-model="searchForm.avatar"
|
||||
placeholder="头像"/>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="邮箱">
|
||||
<ElInput
|
||||
v-model="searchForm.email"
|
||||
placeholder="邮箱"/>
|
||||
placeholder="姓名"/>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="手机号">
|
||||
<ElInput
|
||||
|
|
@ -102,13 +92,14 @@ import {
|
|||
import AppApi from '@/common/app/app-api.ts'
|
||||
import BindRole from '@/pages/sys/user/BindRole.vue'
|
||||
import ClientUtil from '@/common/utils/client-util.ts'
|
||||
import Utils from '@/common/utils'
|
||||
|
||||
const totalCount = ref(0)
|
||||
const tableData = ref<UserTypes.SearchUserResult[]>([])
|
||||
const searchForm = ref<UserTypes.SearchUserParam>({
|
||||
const tableData = Utils.resetAble(reactive<UserTypes.SearchUserResult[]>([]))
|
||||
const searchForm = Utils.resetAble(reactive<UserTypes.SearchUserParam>({
|
||||
current: 1,
|
||||
size: 20,
|
||||
})
|
||||
}))
|
||||
const searching = ref(false)
|
||||
// const deling = ref(false)
|
||||
const showSearchForm = ref(true)
|
||||
|
|
@ -163,10 +154,7 @@ function addHandler() {
|
|||
}
|
||||
|
||||
function reset() {
|
||||
searchForm.value = {
|
||||
current: 1,
|
||||
size: 20,
|
||||
}
|
||||
searchForm.$reset()
|
||||
paging()
|
||||
}
|
||||
|
||||
|
|
@ -198,14 +186,13 @@ function disabledUserHandler(val: string | number | boolean, id: string) {
|
|||
|
||||
function paging() {
|
||||
searching.value = true
|
||||
UserApi.paging(searchForm.value)
|
||||
UserApi.paging(searchForm)
|
||||
.then(res => {
|
||||
totalCount.value = res.data?.total ?? 0
|
||||
tableData.value = res.data?.records ?? []
|
||||
tableData.value.map(it => {
|
||||
tableData.$reset((res.data?.records ?? []).map(it => {
|
||||
it.account.clients = ClientUtil.getClients(it.account.clientCode!).map(it => it.val)
|
||||
return it
|
||||
})
|
||||
}))
|
||||
})
|
||||
.finally(() => {
|
||||
searching.value = false
|
||||
|
|
|
|||
Loading…
Reference in New Issue