提交 aa430ea4 authored 作者: xiejiang's avatar xiejiang

fix: 修复列表显示问题

上级 e6d99d88
...@@ -25,7 +25,9 @@ const api = { ...@@ -25,7 +25,9 @@ const api = {
postSaveMenu: '/platform/permission/saveMenu', // 保存角色菜单权限 postSaveMenu: '/platform/permission/saveMenu', // 保存角色菜单权限
postSaveDataRange: '/platform/permission/saveDataRange', // 保存数据权限 postSaveDataRange: '/platform/permission/saveDataRange', // 保存数据权限
getDataRange: '/platform/permission/dataRange', // 查询角色的数据权限 getDataRange: '/platform/permission/dataRange', // 查询角色的数据权限
postDataRangeClone: '/platform/permission/dataRange/clone' // 应用数据权限至其他菜单 postDataRangeClone: '/platform/permission/dataRange/clone', // 应用数据权限至其他菜单
postSaveUserClient: '/platform/version/saveUserClient' // 保存用户客户端版本
} }
/** /**
...@@ -213,3 +215,13 @@ export const getDataRange = (params: { roleId: string; menuId: string }) => { ...@@ -213,3 +215,13 @@ export const getDataRange = (params: { roleId: string; menuId: string }) => {
export const postDataRangeClone = (data: { roleId: string; sourceMenuId: string; targetMenuId: string[] }) => { export const postDataRangeClone = (data: { roleId: string; sourceMenuId: string; targetMenuId: string[] }) => {
return http.post(api.postDataRangeClone, data) return http.post(api.postDataRangeClone, data)
} }
/**
* @description 保存用户客户端版本
* @author 汪洋
* @docs http://api.seevin.com/project/669/interface/api/33363
* @param versionId 客户端版本号
*/
export const postSaveUserClient = (data: { versionId: string }) => {
return http.post(api.postSaveUserClient, data)
}
...@@ -68,6 +68,8 @@ declare module 'vue' { ...@@ -68,6 +68,8 @@ declare module 'vue' {
TTextarea: typeof import('tdesign-vue-next')['Textarea'] TTextarea: typeof import('tdesign-vue-next')['Textarea']
TTooltip: typeof import('tdesign-vue-next')['Tooltip'] TTooltip: typeof import('tdesign-vue-next')['Tooltip']
TTree: typeof import('tdesign-vue-next')['Tree'] TTree: typeof import('tdesign-vue-next')['Tree']
UpdateDialog: typeof import('./components/UpdateDialog/index.vue')['default']
UpdateVersion: typeof import('./components/UpdateVersion/index.vue')['default']
Upload: typeof import('./components/Upload/index.vue')['default'] Upload: typeof import('./components/Upload/index.vue')['default']
WangEditor: typeof import('./components/WangEditor/index.vue')['default'] WangEditor: typeof import('./components/WangEditor/index.vue')['default']
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-11-07 11:19:31 * @Date: 2024-11-07 11:19:31
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-10 11:13:57 * @LastEditTime: 2024-12-10 14:16:57
* @Description: 表格页面容器组件 * @Description: 表格页面容器组件
--> -->
<template> <template>
...@@ -47,21 +47,18 @@ ...@@ -47,21 +47,18 @@
@sort-change="onSortChange" @sort-change="onSortChange"
> >
<!-- 为每一列创建动态插槽 --> <!-- 为每一列创建动态插槽 -->
<template #default="{ row }"> <template v-for="col in columns" :key="col.colKey" #[soltName(col)]="{ row }">
<template v-for="col in columns" :key="col.colKey"> <template v-if="col.colKey != 'operation'">
<template v-if="col.colKey != 'operation'"> <t-tooltip
<t-tooltip :content="row[col.colKey as string]"
:content="row[col.colKey as string]" placement="top"
placement="top" theme="light"
theme="light" overlay-class-name="custom-tooltip"
overlay-class-name="custom-tooltip" >
> <div class="cell-content">{{ row[col.colKey as string] || '-' }}</div>
<div class="cell-content">{{ row[col.colKey as string] || '-' }}</div> </t-tooltip>
</t-tooltip>
</template>
</template> </template>
</template> </template>
<!-- 保留自定义列插槽 --> <!-- 保留自定义列插槽 -->
<template v-for="[name] in Object.entries($slots)" #[name]="scope"> <template v-for="[name] in Object.entries($slots)" #[name]="scope">
<slot :name="name" v-bind="scope" /> <slot :name="name" v-bind="scope" />
...@@ -73,11 +70,11 @@ ...@@ -73,11 +70,11 @@
</template> </template>
<script setup lang="tsx"> <script setup lang="tsx">
import { ref, computed } from 'vue' import { PrimaryTableCol, TableProps } from 'tdesign-vue-next'
import { PageContainerProps, Pagination } from './interface' import { PageContainerProps, Pagination } from './interface'
import PageFilters from '../PageFilters/index.vue' import PageFilters from '../PageFilters/index.vue'
import { filterItemProp } from '../PageFilters/interface' import { filterItemProp } from '../PageFilters/interface'
import { PrimaryTableCol, TableProps } from 'tdesign-vue-next' import { soltName } from '@/utils'
defineOptions({ name: 'PageContainer' }) defineOptions({ name: 'PageContainer' })
......
<!--
* @Author: xiejiang
* @Date: 2024-12-10 15:36:04
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-10 15:46:52
* @Description: 更新版本弹窗
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
<template>
<Dialog
:dialog-visible="isShowPuzzleVcode"
width="640px"
:close-on-overlay-click="false"
@close="isShowPuzzleVcode = false"
>
<template #body>
<main class="updata-main">
<div class="flex items-center">
<span>业务分支:</span>
<span>{{ state.platformType == 1 ? '平台端' : '机构端' }}</span>
</div>
<div>
<span>版本号:</span>
<span>{{ state.version }}</span>
</div>
<div>
<span>更新说明:</span>
<div class="content-div" v-html="state.description"></div>
</div>
<!-- <t-button type="primary" size="small" class="m-t-32" @click="handleSure" :loading="loading">
{{ btmTitle }}
</-button> -->
<!-- <img :src="bgImage" alt="" /> -->
</main>
</template>
</Dialog>
</template>
<script setup lang="ts" name="upadta-version">
import { ResVersion } from '@/api/interface/version/index'
const isShowPuzzleVcode = ref(false)
const state = reactive<ResVersion>({})
</script>
<style lang="less" scoped></style>
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
/* GlobalState */ /* GlobalState */
import { ComputedRef } from 'vue' import { ComputedRef } from 'vue'
import { ResVersion } from '@/api/interface/version/index'
export interface GlobalState { export interface GlobalState {
isCollapse: boolean isCollapse: boolean
...@@ -28,6 +29,7 @@ export interface UserInfo { ...@@ -28,6 +29,7 @@ export interface UserInfo {
loginAddress?: string loginAddress?: string
time: string time: string
} }
clientLastVersion?: ResVersion
status: string status: string
telephone: string telephone: string
token: string token: string
......
...@@ -39,6 +39,20 @@ ...@@ -39,6 +39,20 @@
box-shadow: none !important; box-shadow: none !important;
} }
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.inputUserName-del {
border-radius: 3px;
padding: 3px 4px;
margin-left: 8px;
color: var(--td-font-gray-3);
background: var(--td-gray-color-1);
}
// 表格 // 表格
.t-table { .t-table {
thead th { thead th {
......
import { RouteRecordRaw } from 'vue-router' import { RouteRecordRaw } from 'vue-router'
import { PrimaryTableCol } from 'tdesign-vue-next'
import { useAuthStore } from '@/stores/modules/auth' import { useAuthStore } from '@/stores/modules/auth'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
export const EMPTY = '-' // 空占位符 export const EMPTY = '-' // 空占位符
// 插槽名
export const soltName = (col: PrimaryTableCol) => {
return col.colKey as string
}
// 系统权限按钮 // 系统权限按钮
export const buttonPms = (key: string) => { export const buttonPms = (key: string) => {
const userAuth = useAuthStore() const userAuth = useAuthStore()
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-11-28 15:01:02 * @Date: 2024-11-28 15:01:02
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-09 16:35:49 * @LastEditTime: 2024-12-10 15:21:08
* @Description: 机构管理 * @Description: 机构管理
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
:loading="loading" :loading="loading"
:pagination="pagination" :pagination="pagination"
@search-change="handleSearch" @search-change="handleSearch"
@clear="handleClear"
@page-change="handlePage" @page-change="handlePage"
> >
<template #header-left> <template #header-left>
...@@ -176,7 +177,20 @@ const columns: PrimaryTableCol[] = [ ...@@ -176,7 +177,20 @@ const columns: PrimaryTableCol[] = [
}, },
{ title: '机构备注', colKey: 'remark' }, { title: '机构备注', colKey: 'remark' },
{ title: '添加时间', colKey: 'inputTime' }, { title: '添加时间', colKey: 'inputTime' },
{ title: '添加人', colKey: 'inputUserName' }, {
title: '添加人',
colKey: 'inputUserName',
cell: (h, { row }) => {
return (
<div class='flex items-center justify-between'>
<div class={row.inputUserDelFlag ? 'w-[calc(100%-58px)] ellipsis text-[var(--td-font-gray-3)]' : ''}>
<span class={row.inputUserDelFlag ? 'text-[var(--td-font-gray-3)]' : ''}>{row.inputUserName || '-'}</span>
</div>
{row.inputUserDelFlag ? <span class='inputUserName-del'>已删除</span> : ''}
</div>
)
}
},
{ title: '操作', colKey: 'operation', fixed: 'right', width: 260 } { title: '操作', colKey: 'operation', fixed: 'right', width: 260 }
] ]
......
...@@ -40,11 +40,9 @@ ...@@ -40,11 +40,9 @@
<template v-for="(_, name) in $slots" #[name]="scope"> <template v-for="(_, name) in $slots" #[name]="scope">
<slot :name="name" v-bind="scope" /> <slot :name="name" v-bind="scope" />
</template> </template>
<template #default="{ row }"> <template v-for="col in columns" #[soltName(col)]="{ row }" :key="col.colKey">
<template v-for="col in columns" :key="col.colKey"> <template v-if="col.colKey != 'operation'">
<template v-if="col.colKey != 'operation'"> <div class="cell-content">{{ row[col.colKey as string] || '-' }}</div>
<div class="cell-content">{{ row[col.colKey as string] || '-' }}</div>
</template>
</template> </template>
</template> </template>
</t-table> </t-table>
...@@ -64,6 +62,7 @@ import { MessagePlugin, PrimaryTableCol, PaginationProps } from 'tdesign-vue-nex ...@@ -64,6 +62,7 @@ import { MessagePlugin, PrimaryTableCol, PaginationProps } from 'tdesign-vue-nex
import { ArrowDownIcon, ArrowUpIcon } from 'tdesign-icons-vue-next' import { ArrowDownIcon, ArrowUpIcon } from 'tdesign-icons-vue-next'
import { useBasic } from '@/hooks/useBasic' import { useBasic } from '@/hooks/useBasic'
import MessageBox from '@/utils/messageBox' import MessageBox from '@/utils/messageBox'
import { soltName } from '@/utils'
import { dictionaryAttributeTxt } from '@/utils/status' import { dictionaryAttributeTxt } from '@/utils/status'
import { ResDictionary } from '@/api/interface/dectionory' import { ResDictionary } from '@/api/interface/dectionory'
import { import {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-11-11 09:38:40 * @Date: 2024-11-11 09:38:40
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-09 16:36:11 * @LastEditTime: 2024-12-10 15:04:00
* @Description: 系统字典 * @Description: 系统字典
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
:loading="loading" :loading="loading"
:pagination="pagination" :pagination="pagination"
@search-change="handleSearch" @search-change="handleSearch"
@clear="handleClear"
@page-change="handlePage" @page-change="handlePage"
> >
<template #header-left> <template #header-left>
...@@ -37,10 +38,11 @@ ...@@ -37,10 +38,11 @@
<template #operation="{ row }"> <template #operation="{ row }">
<operate-btn v-if="row.status != '2'" content="启用" @click="handelStatus(row, 2)"> </operate-btn> <operate-btn v-if="row.status != '2'" content="启用" @click="handelStatus(row, 2)"> </operate-btn>
<operate-btn v-if="row.isAllowEdit" content="编辑" @click="handelEdit(row)"> </operate-btn> <operate-btn v-if="row.isAllowEdit || row.status == '1'" content="编辑" @click="handelEdit(row)"> </operate-btn>
<operate-btn v-if="row.isAllowAddsub" content="管理子集" @click="handelSubset(row)"> </operate-btn> <operate-btn v-if="row.isAllowAddsub || row.status == '1'" content="管理子集" @click="handelSubset(row)">
</operate-btn>
<operate-btn v-if="row.status == '2'" content="停用" @click="handelStatus(row, 1)"> </operate-btn> <operate-btn v-if="row.status == '2'" content="停用" @click="handelStatus(row, 1)"> </operate-btn>
<operate-btn v-if="row.isAllowDelete" content="删除" @click="handelDel(row)"></operate-btn> <operate-btn v-if="row.isAllowDelete || row.status == '1'" content="删除" @click="handelDel(row)"></operate-btn>
</template> </template>
</PageContainer> </PageContainer>
...@@ -154,8 +156,21 @@ const columns: PrimaryTableCol[] = [ ...@@ -154,8 +156,21 @@ const columns: PrimaryTableCol[] = [
) )
} }
}, },
{ title: '添加人', colKey: 'inputUserName' }, {
{ title: '添加 时间', colKey: 'inputTime' }, title: '添加人',
colKey: 'inputUserName',
cell: (h, { row }) => {
return (
<div class='flex items-center justify-between'>
<div class={row.inputUserDelFlag ? 'w-[calc(100%-58px)] ellipsis text-[var(--td-font-gray-3)]' : ''}>
<span class={row.inputUserDelFlag ? 'text-[var(--td-font-gray-3)]' : ''}>{row.inputUserName || '-'}</span>
</div>
{row.inputUserDelFlag ? <span class='inputUserName-del'>已删除</span> : ''}
</div>
)
}
},
{ title: '添加时间', colKey: 'inputTime' },
{ title: '操作', colKey: 'operation', fixed: 'right', width: 260 } { title: '操作', colKey: 'operation', fixed: 'right', width: 260 }
] ]
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-12-02 18:41:38 * @Date: 2024-12-02 18:41:38
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-05 17:05:19 * @LastEditTime: 2024-12-10 14:44:24
* @Description: 新增编辑枚举值 * @Description: 新增编辑枚举值
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-11-11 09:38:40 * @Date: 2024-11-11 09:38:40
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-09 16:40:03 * @LastEditTime: 2024-12-10 15:19:33
* @Description: 菜单管理 * @Description: 菜单管理
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
:show-tree="true" :show-tree="true"
@search-change="handleSearch" @search-change="handleSearch"
@page-change="handlePage" @page-change="handlePage"
@clear="handleClear"
table-maxheight="550px" table-maxheight="550px"
class="max-h-[calc(100%-50px)]" class="max-h-[calc(100%-50px)]"
> >
...@@ -151,7 +152,20 @@ const columns: PrimaryTableCol[] = [ ...@@ -151,7 +152,20 @@ const columns: PrimaryTableCol[] = [
} }
}, },
{ title: '创建时间', colKey: 'inputTime' }, { title: '创建时间', colKey: 'inputTime' },
{ title: '创建人', colKey: 'inputUserName', width: 104 }, {
title: '创建人',
colKey: 'inputUserName',
cell: (h, { row }) => {
return (
<div class='flex items-center justify-between'>
<div class={row.inputUserDelFlag ? 'w-[calc(100%-58px)] ellipsis text-[var(--td-font-gray-3)]' : ''}>
<span class={row.inputUserDelFlag ? 'text-[var(--td-font-gray-3)]' : ''}>{row.inputUserName || '-'}</span>
</div>
{row.inputUserDelFlag ? <span class='inputUserName-del'>已删除</span> : ''}
</div>
)
}
},
{ title: '操作', colKey: 'operation', width: 184 } { title: '操作', colKey: 'operation', width: 184 }
] ]
// 标签页 // 标签页
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-11-11 09:38:40 * @Date: 2024-11-11 09:38:40
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-10 11:29:57 * @LastEditTime: 2024-12-10 11:40:24
* @Description: 菜单管理-新增编辑菜单 * @Description: 菜单管理-新增编辑菜单
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-11-11 09:38:40 * @Date: 2024-11-11 09:38:40
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-09 18:22:42 * @LastEditTime: 2024-12-10 15:20:00
* @Description: 版本管理 * @Description: 版本管理
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
...@@ -107,7 +107,8 @@ const filterConditions = ref<filterItemProp[]>([ ...@@ -107,7 +107,8 @@ const filterConditions = ref<filterItemProp[]>([
$attrs: { $attrs: {
'disable-date': (date: string) => { 'disable-date': (date: string) => {
return dayjs(date).isBefore(dayjs().format('YYYY-MM')) || dayjs(date).isAfter(dayjs().format('YYYY-MM-DD')) return dayjs(date).isBefore(dayjs().format('YYYY-MM')) || dayjs(date).isAfter(dayjs().format('YYYY-MM-DD'))
} },
mode: 'month'
} }
}, },
{ {
...@@ -145,7 +146,20 @@ const columns: PrimaryTableCol[] = [ ...@@ -145,7 +146,20 @@ const columns: PrimaryTableCol[] = [
{ title: '版本备注', colKey: 'remark' }, { title: '版本备注', colKey: 'remark' },
{ title: '上线时间', colKey: 'onlineTime' }, { title: '上线时间', colKey: 'onlineTime' },
{ title: '添加时间', colKey: 'inputTime' }, { title: '添加时间', colKey: 'inputTime' },
{ title: '添加人', colKey: 'inputUserName', width: 104 }, {
title: '添加人',
colKey: 'inputUserName',
cell: (h, { row }) => {
return (
<div class='flex items-center justify-between'>
<div class={row.inputUserDelFlag ? 'w-[calc(100%-58px)] ellipsis text-[var(--td-font-gray-3)]' : ''}>
<span class={row.inputUserDelFlag ? 'text-[var(--td-font-gray-3)]' : ''}>{row.inputUserName || '-'}</span>
</div>
{row.inputUserDelFlag ? <span class='inputUserName-del'>已删除</span> : ''}
</div>
)
}
},
{ title: '操作', colKey: 'operation', width: 220 } { title: '操作', colKey: 'operation', width: 220 }
] ]
// 标签页 // 标签页
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-12-08 09:25:35 * @Date: 2024-12-08 09:25:35
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-10 11:22:08 * @LastEditTime: 2024-12-10 14:18:35
* @Description: * @Description:
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
<template> <template>
<Drawer :drawer-visible="drawerVisible" width="480px" title="版本详情" @close="close" :footer="false"> <Drawer :drawer-visible="drawerVisible" width="480px" title="版本详情" @close="close" :footer="false">
<InfoLable class="mb-[16px]" label="当前终端" :value="props.tabType == 1 ? '平台端' : '机构端'" /> <InfoLable class="mb-[16px]" label="当前终端" :value="state.platformType == 1 ? '平台端' : '机构端'" />
<InfoLable class="mb-[16px]" label="版本号" :value="state.version" /> <InfoLable class="mb-[16px]" label="版本号" :value="state.version" />
<InfoLable class="mb-[16px]" label="更新说明"><div v-html="state.description || '-'"></div> </InfoLable> <InfoLable class="mb-[16px]" label="更新说明"><div v-html="state.description || '-'"></div> </InfoLable>
<InfoLable class="mb-[16px]" label="版本备注" :value="state.remark || '-'" /> <InfoLable class="mb-[16px]" label="版本备注" :value="state.remark || '-'" />
...@@ -20,11 +20,9 @@ ...@@ -20,11 +20,9 @@
<template v-for="(_, name) in $slots" #[name]="scope"> <template v-for="(_, name) in $slots" #[name]="scope">
<slot :name="name" v-bind="scope" /> <slot :name="name" v-bind="scope" />
</template> </template>
<template #default="{ row }"> <template v-for="col in columns" #[soltName(col)]="{ row }" :key="col.colKey">
<template v-for="col in columns" :key="col.colKey"> <template v-if="col.colKey != 'operation'">
<template v-if="col.colKey != 'operation'"> <div class="cell-content">{{ row[col.colKey as string] || '-' }}</div>
<div class="cell-content">{{ row[col.colKey as string] || '-' }}</div>
</template>
</template> </template>
</template> </template>
</t-table> </t-table>
...@@ -34,11 +32,9 @@ ...@@ -34,11 +32,9 @@
<script setup lang="tsx" name="version-detail"> <script setup lang="tsx" name="version-detail">
import { PrimaryTableCol } from 'tdesign-vue-next' import { PrimaryTableCol } from 'tdesign-vue-next'
import { statusVersionTxt } from '@/utils/status' import { statusVersionTxt } from '@/utils/status'
import { soltName } from '@/utils'
import { getVersionDetail } from '@/api/modules/version/index' import { getVersionDetail } from '@/api/modules/version/index'
import { ResVersion } from '@/api/interface/version' import { ResVersion } from '@/api/interface/version'
const props = defineProps<{
tabType: number
}>()
const drawerVisible = ref(false) const drawerVisible = ref(false)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-12-01 10:37:37 * @Date: 2024-12-01 10:37:37
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-08 15:11:47 * @LastEditTime: 2024-12-10 14:23:34
* @Description: * @Description:
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
...@@ -30,18 +30,18 @@ ...@@ -30,18 +30,18 @@
:data="tableData" :data="tableData"
:columns="columns" :columns="columns"
:loading="loading" :loading="loading"
@page-change="onLogsPageChange"
:pagination="pagination.total > 10 ? pagination : undefined" :pagination="pagination.total > 10 ? pagination : undefined"
> >
<!-- 保留自定义列插槽 --> <template v-for="col in columns" #[soltName(col)]="{ row }" :key="col.colKey">
<template v-for="(_, name) in $slots" #[name]="scope"> <t-tooltip
<slot :name="name" v-bind="scope" /> :content="row[col.colKey as string]"
</template> placement="top"
<template #default="{ row }"> theme="light"
<template v-for="col in columns" :key="col.colKey"> overlay-class-name="custom-tooltip"
<template v-if="col.colKey != 'operation'"> >
<div class="cell-content">{{ row[col.colKey as string] || '-' }}</div> <div class="cell-content ellipsis">{{ row[col.colKey as string] || '-' }}</div>
</template> </t-tooltip>
</template>
</template> </template>
</t-table> </t-table>
</main> </main>
...@@ -50,13 +50,15 @@ ...@@ -50,13 +50,15 @@
<script setup lang="ts" name="role-detail"> <script setup lang="ts" name="role-detail">
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { PrimaryTableCol } from 'tdesign-vue-next' import { PrimaryTableCol, PaginationProps } from 'tdesign-vue-next'
import { useBasic } from '@/hooks/useBasic' import { useBasic } from '@/hooks/useBasic'
import { ResRoleList } from '@/api/interface/user-roles/index' import { ResRoleList } from '@/api/interface/user-roles/index'
import { getRoleDetail } from '@/api/modules/user-roles/index' import { getRoleDetail } from '@/api/modules/user-roles/index'
import { statusTxt } from '@/utils/status' import { statusTxt } from '@/utils/status'
import { soltName } from '@/utils'
const route = useRoute() const route = useRoute()
const { setBreadcrumb } = useBasic()
const state = ref<ResRoleList>() const state = ref<ResRoleList>()
...@@ -67,11 +69,15 @@ const getData = () => { ...@@ -67,11 +69,15 @@ const getData = () => {
}).then(res => { }).then(res => {
state.value = res.data state.value = res.data
tableData.value = res.data?.roleUsers?.list || [] tableData.value = res.data?.roleUsers?.list || []
pagination.value.total = res?.recordsFiltered as number pagination.value.total = res.data?.roleUsers?.total as number
}) })
} }
const { setBreadcrumb } = useBasic() const onLogsPageChange = (val: PaginationProps) => {
pagination.value.page = val.current as number
pagination.value.limit = val.pageSize as number
getData()
}
const loading = ref(false) const loading = ref(false)
...@@ -91,9 +97,9 @@ const columns: PrimaryTableCol[] = [ ...@@ -91,9 +97,9 @@ const columns: PrimaryTableCol[] = [
}, },
{ title: '用户姓名', colKey: 'userName' }, { title: '用户姓名', colKey: 'userName' },
{ title: '手机号码', colKey: 'mobile' }, { title: '手机号码', colKey: 'mobile' },
{ title: '最近登录时间', colKey: 'role' }, { title: '最近登录时间', colKey: 'time' },
{ title: '最近登录IP', colKey: 'role' }, { title: '最近登录IP', colKey: 'loginIp' },
{ title: '最近登录设备类型', colKey: 'role' } { title: '最近登录设备类型', colKey: 'device' }
] ]
onMounted(() => { onMounted(() => {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-11-28 15:01:02 * @Date: 2024-11-28 15:01:02
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-09 16:33:42 * @LastEditTime: 2024-12-10 15:20:22
* @Description: 角色管理 * @Description: 角色管理
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
:loading="loading" :loading="loading"
:pagination="pagination" :pagination="pagination"
@search-change="handleSearch" @search-change="handleSearch"
@clear="handleClear"
@page-change="handlePage" @page-change="handlePage"
> >
<template #header-left> <template #header-left>
...@@ -125,7 +126,20 @@ const columns: PrimaryTableCol[] = [ ...@@ -125,7 +126,20 @@ const columns: PrimaryTableCol[] = [
} }
}, },
{ title: '添加时间', colKey: 'inputTime' }, { title: '添加时间', colKey: 'inputTime' },
{ title: '添加人', colKey: 'inputUserName' }, {
title: '添加人',
colKey: 'inputUserName',
cell: (h, { row }) => {
return (
<div class='flex items-center justify-between'>
<div class={row.inputUserDelFlag ? 'w-[calc(100%-58px)] ellipsis text-[var(--td-font-gray-3)]' : ''}>
<span class={row.inputUserDelFlag ? 'text-[var(--td-font-gray-3)]' : ''}>{row.inputUserName || '-'}</span>
</div>
{row.inputUserDelFlag ? <span class='inputUserName-del'>已删除</span> : ''}
</div>
)
}
},
{ title: '操作', colKey: 'operation', fixed: 'right', width: 260 } { title: '操作', colKey: 'operation', fixed: 'right', width: 260 }
] ]
......
...@@ -29,16 +29,14 @@ ...@@ -29,16 +29,14 @@
max-height="400px" max-height="400px"
:pagination="pagination.total > 10 ? pagination : undefined" :pagination="pagination.total > 10 ? pagination : undefined"
> >
<template #default="{ row }"> <template v-for="col in columns" #[soltName(col)]="{ row }" :key="col.colKey">
<template v-for="col in columns" :key="col.colKey"> <template v-if="col.colKey == 'dataPermission'">
<template v-if="col.colKey == 'dataPermission'"> <div class="cell-content">{{ dataPermissions(row) || '-' }}</div>
<div class="cell-content">{{ dataPermissions(row) || '-' }}</div>
</template>
<template v-else-if="col.colKey == 'functionPermission'">
<div class="cell-content">{{ functionPermission(row) || '-' }}</div>
</template>
<template v-else> {{ row[col.colKey as string] || '-' }} </template>
</template> </template>
<template v-else-if="col.colKey == 'functionPermission'">
<div class="cell-content">{{ functionPermission(row) || '-' }}</div>
</template>
<template v-else> {{ row[col.colKey as string] || '-' }} </template>
</template> </template>
</t-table> </t-table>
...@@ -62,6 +60,7 @@ import { useRoute } from 'vue-router' ...@@ -62,6 +60,7 @@ import { useRoute } from 'vue-router'
import { PrimaryTableCol, PaginationProps, TableProps } from 'tdesign-vue-next' import { PrimaryTableCol, PaginationProps, TableProps } from 'tdesign-vue-next'
import { useBasic } from '@/hooks/useBasic' import { useBasic } from '@/hooks/useBasic'
import { statusTxt } from '@/utils/status' import { statusTxt } from '@/utils/status'
import { soltName } from '@/utils'
import { getUserDetail, getLogs } from '@/api/modules/user-roles/index' import { getUserDetail, getLogs } from '@/api/modules/user-roles/index'
import { ResUserList, ResLog } from '@/api/interface/user-roles/index' import { ResUserList, ResLog } from '@/api/interface/user-roles/index'
...@@ -135,8 +134,7 @@ const dataPermissions = (row: ResUserList) => { ...@@ -135,8 +134,7 @@ const dataPermissions = (row: ResUserList) => {
const rolePermissions = row.rolePermissions || [] const rolePermissions = row.rolePermissions || []
const txt = const txt =
areaPermissions.map((val: { name: string }) => val.name).join(',') + areaPermissions.map((val: { name: string }) => val.name).join(',') +
'-' + (rolePermissions.length ? '-' + rolePermissions.map((val: { name: string }) => val.name).join(',') : '')
rolePermissions.map((val: { name: string }) => val.name).join(',')
return txt return txt
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: xiejiang * @Author: xiejiang
* @Date: 2024-11-28 15:01:02 * @Date: 2024-11-28 15:01:02
* @LastEditors: xiejiang * @LastEditors: xiejiang
* @LastEditTime: 2024-12-09 17:26:42 * @LastEditTime: 2024-12-10 15:25:28
* @Description: 用户管理 * @Description: 用户管理
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved. * Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
--> -->
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
:loading="loading" :loading="loading"
:pagination="pagination" :pagination="pagination"
@search-change="handleSearch" @search-change="handleSearch"
@clear="handleClear"
@page-change="handlePage" @page-change="handlePage"
> >
<template #header-left> <template #header-left>
...@@ -122,9 +123,14 @@ const columns: PrimaryTableCol[] = [ ...@@ -122,9 +123,14 @@ const columns: PrimaryTableCol[] = [
cell: (h, { row }) => { cell: (h, { row }) => {
const roles = row.roles || [] const roles = row.roles || []
return ( return (
<p class='ellipsis w-full'> <t-tooltip
<span>{roles.map((e: { name: string }) => e.name).join(';') || '-'}</span> content={roles.map((e: { name: string }) => e.name).join(';') || '-'}
</p> placement='top'
theme='light'
overlay-class-name='custom-tooltip'
>
<p class='ellipsis'>{roles.map((e: { name: string }) => e.name).join(';') || '-'}</p>
</t-tooltip>
) )
} }
}, },
...@@ -141,7 +147,20 @@ const columns: PrimaryTableCol[] = [ ...@@ -141,7 +147,20 @@ const columns: PrimaryTableCol[] = [
} }
}, },
{ title: '添加时间', colKey: 'inputTime' }, { title: '添加时间', colKey: 'inputTime' },
{ title: '添加人', colKey: 'inputUserName' }, {
title: '添加人',
colKey: 'inputUserName',
cell: (h, { row }) => {
return (
<div class='flex items-center justify-between'>
<div class={row.inputUserDelFlag ? 'w-[calc(100%-58px)] ellipsis text-[var(--td-font-gray-3)]' : ''}>
<span class={row.inputUserDelFlag ? 'text-[var(--td-font-gray-3)]' : ''}>{row.inputUserName || '-'}</span>
</div>
{row.inputUserDelFlag ? <span class='inputUserName-del'>已删除</span> : ''}
</div>
)
}
},
{ title: '操作', colKey: 'operation', fixed: 'right', width: 220 } { title: '操作', colKey: 'operation', fixed: 'right', width: 220 }
] ]
......
...@@ -57,14 +57,6 @@ const formData = reactive<ReqUser>({ ...@@ -57,14 +57,6 @@ const formData = reactive<ReqUser>({
}) })
const validateTelePhone: CustomValidator = async val => { const validateTelePhone: CustomValidator = async val => {
if (!val) {
return {
result: false,
message: '请填写用户手机号码!',
type: 'error'
}
}
if (!isPhoneNumber(val)) { if (!isPhoneNumber(val)) {
return { return {
result: false, result: false,
...@@ -72,18 +64,6 @@ const validateTelePhone: CustomValidator = async val => { ...@@ -72,18 +64,6 @@ const validateTelePhone: CustomValidator = async val => {
type: 'error' type: 'error'
} }
} else { } else {
await new Promise(resolve => {
const timer = setTimeout(() => {
resolve(val)
clearTimeout(timer)
return {
result: false,
message: '该手机号码已被使用!',
type: 'error'
}
})
})
return { return {
result: true, result: true,
message: '', message: '',
...@@ -101,6 +81,7 @@ const rules: FormProps['rules'] = { ...@@ -101,6 +81,7 @@ const rules: FormProps['rules'] = {
} }
], ],
mobile: [ mobile: [
{ required: true, message: '请填写用户手机号码!', type: 'error' },
{ {
validator: validateTelePhone validator: validateTelePhone
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论