项目筛选由两个增加至八个,增加质量管理,安全管理,现场管理
This commit is contained in:
parent
60b164f0c8
commit
25f57a4adb
|
@ -41,20 +41,6 @@
|
|||
<!-- 简洁搜索区域 -->
|
||||
<div class="search-section">
|
||||
<a-card :bordered="false" class="search-card">
|
||||
<!-- 搜索状态提示 -->
|
||||
<div v-if="hasActiveFilters" class="search-status">
|
||||
<icon-info-circle style="color: #667eea; margin-right: 8px;" />
|
||||
<span>当前应用了搜索筛选条件</span>
|
||||
<a-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click="handleReset"
|
||||
style="margin-left: 8px; color: #667eea;"
|
||||
>
|
||||
清除所有筛选
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<a-form layout="inline" :model="searchForm">
|
||||
<a-form-item label="姓名">
|
||||
<a-input
|
||||
|
@ -63,7 +49,6 @@
|
|||
style="width: 180px"
|
||||
allow-clear
|
||||
@press-enter="handleSearch"
|
||||
@clear="handleSearch"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="项目岗位">
|
||||
|
@ -72,7 +57,6 @@
|
|||
placeholder="请选择项目岗位"
|
||||
style="width: 150px"
|
||||
allow-clear
|
||||
@change="handleSearch"
|
||||
>
|
||||
<a-option
|
||||
v-for="option in ROLE_TYPE_OPTIONS"
|
||||
|
@ -89,7 +73,6 @@
|
|||
placeholder="请选择状态"
|
||||
style="width: 120px"
|
||||
allow-clear
|
||||
@change="handleSearch"
|
||||
>
|
||||
<a-option
|
||||
v-for="option in STATUS_OPTIONS"
|
||||
|
@ -102,12 +85,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSearch"
|
||||
:loading="loading"
|
||||
:disabled="!hasActiveFilters"
|
||||
>
|
||||
<a-button type="primary" @click="handleSearch">
|
||||
<template #icon><icon-search /></template>
|
||||
搜索
|
||||
</a-button>
|
||||
|
@ -121,7 +99,6 @@
|
|||
</a-card>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<GiTable
|
||||
row-key="id"
|
||||
|
@ -135,23 +112,6 @@
|
|||
@page-size-change="onPageSizeChange"
|
||||
@refresh="loadData"
|
||||
>
|
||||
<!-- 空状态显示 -->
|
||||
<template #empty>
|
||||
<div class="empty-state">
|
||||
<icon-user-group style="font-size: 48px; color: #c9cdd4; margin-bottom: 16px;" />
|
||||
<div class="empty-text">
|
||||
<h3>{{ hasActiveFilters ? '没有找到匹配的团队成员' : '暂无团队成员数据' }}</h3>
|
||||
<p v-if="hasActiveFilters">
|
||||
请尝试调整搜索条件或
|
||||
<a-link @click="handleReset">清除所有筛选</a-link>
|
||||
</p>
|
||||
<p v-else>
|
||||
点击右上角的"新增成员"按钮来添加第一个团队成员
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 项目岗位列 -->
|
||||
<template #roleType="{ record }">
|
||||
<span class="role-type-text">
|
||||
|
@ -161,9 +121,9 @@
|
|||
|
||||
<!-- 状态列 -->
|
||||
<template #status="{ record }">
|
||||
<span class="status-tag" :class="`status-${record.status || 'INACTIVE'}`">
|
||||
<a-tag :color="getStatusColor(record.status || 'INACTIVE')">
|
||||
{{ getStatusText(record.status || 'INACTIVE') }}
|
||||
</span>
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
|
||||
|
@ -380,7 +340,7 @@ const ROLE_TYPE_OPTIONS = [
|
|||
|
||||
const STATUS_OPTIONS = [
|
||||
{ label: '可用', value: 'ACTIVE' },
|
||||
{ label: '忙碌', value: 'SUSPENDED' },
|
||||
{ label: '忙碌', value: 'SUSPENDEN' },
|
||||
{ label: '离线', value: 'INACTIVE' }
|
||||
]
|
||||
|
||||
|
@ -441,7 +401,7 @@ const statusForm = reactive<{
|
|||
id: string | number
|
||||
name: string
|
||||
currentStatus: string
|
||||
newStatus: 'ACTIVE' | 'SUSPENDED' | 'INACTIVE'
|
||||
newStatus: 'ACTIVE' | 'SUSPENDEN' | 'INACTIVE'
|
||||
}>({
|
||||
id: '',
|
||||
name: '',
|
||||
|
@ -463,80 +423,56 @@ const loadData = async () => {
|
|||
try {
|
||||
console.log('正在加载项目团队成员数据,项目ID:', projectId)
|
||||
|
||||
// 构建查询参数,字段名要与后端接口匹配
|
||||
// 构建查询参数
|
||||
const queryParams: TeamMemberQuery = {
|
||||
projectId: projectId,
|
||||
page: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
name: searchForm.name || undefined,
|
||||
position: searchForm.roleType || undefined, // 后端使用position字段
|
||||
position: searchForm.roleType || undefined,
|
||||
status: searchForm.status || undefined
|
||||
}
|
||||
|
||||
console.log('查询参数:', queryParams)
|
||||
|
||||
const response = await getProjectTeamMembers(queryParams)
|
||||
|
||||
console.log('API响应数据:', response)
|
||||
console.log('API响应数据:', response.data)
|
||||
|
||||
// 处理后端返回的数据
|
||||
let mappedData: TeamMemberResp[] = []
|
||||
let total = 0
|
||||
// 确保response.data是数组
|
||||
const rawData = Array.isArray(response.data) ? response.data : [response.data]
|
||||
|
||||
if (response.data) {
|
||||
// 如果后端返回的是分页数据
|
||||
if (response.data.list && Array.isArray(response.data.list)) {
|
||||
mappedData = response.data.list.map((item: BackendTeamMemberResp) => {
|
||||
return {
|
||||
console.log('处理后的原始数据:', rawData)
|
||||
|
||||
// 处理后端返回的数据,将后端字段映射到前端期望的字段
|
||||
const mappedData = rawData.map((item: BackendTeamMemberResp) => {
|
||||
const mappedItem: TeamMemberResp = {
|
||||
id: item.memberId,
|
||||
name: item.name || '',
|
||||
phone: item.phone || '',
|
||||
email: item.email || '',
|
||||
roleType: item.roleType || item.position || '', // 优先使用roleType,fallback到position
|
||||
status: (item.status === 'ACTIVE' ? 'ACTIVE' : item.status === 'SUSPENDED' ? 'SUSPENDED' : 'INACTIVE') as 'ACTIVE' | 'SUSPENDED' | 'INACTIVE',
|
||||
roleType: item.roleType || '', // 映射项目岗位
|
||||
status: (item.status === 'ACTIVE' ? 'ACTIVE' : item.status === 'SUSPENDEN' ? 'SUSPENDEN' : 'INACTIVE') as 'ACTIVE' | 'SUSPENDEN' | 'INACTIVE',
|
||||
joinDate: item.joinDate || '',
|
||||
remark: item.remark || '',
|
||||
avatar: item.userAvatar || ''
|
||||
}
|
||||
})
|
||||
total = response.data.total || mappedData.length
|
||||
}
|
||||
// 如果后端直接返回数组
|
||||
else if (Array.isArray(response.data)) {
|
||||
mappedData = response.data.map((item: BackendTeamMemberResp) => {
|
||||
return {
|
||||
id: item.memberId,
|
||||
name: item.name || '',
|
||||
phone: item.phone || '',
|
||||
email: item.email || '',
|
||||
roleType: item.roleType || item.position || '',
|
||||
status: (item.status === 'ACTIVE' ? 'ACTIVE' : item.status === 'SUSPENDED' ? 'SUSPENDED' : 'INACTIVE') as 'ACTIVE' | 'SUSPENDED' | 'INACTIVE',
|
||||
joinDate: item.joinDate || '',
|
||||
remark: item.remark || '',
|
||||
avatar: item.userAvatar || ''
|
||||
}
|
||||
})
|
||||
total = mappedData.length
|
||||
}
|
||||
}
|
||||
console.log('映射后的数据项:', mappedItem)
|
||||
return mappedItem
|
||||
})
|
||||
|
||||
dataList.value = mappedData
|
||||
pagination.total = total
|
||||
pagination.total = mappedData.length
|
||||
|
||||
console.log('团队成员数据加载完成,显示数据:', dataList.value.length, '条,总计:', pagination.total, '条')
|
||||
|
||||
} catch (error) {
|
||||
console.error('团队成员数据加载失败:', error)
|
||||
Message.error('团队成员数据加载失败')
|
||||
dataList.value = []
|
||||
pagination.total = 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSearch = async () => {
|
||||
console.log('执行搜索,搜索条件:', searchForm)
|
||||
pagination.current = 1
|
||||
await loadData()
|
||||
}
|
||||
|
@ -549,18 +485,15 @@ const handleReset = () => {
|
|||
status: ''
|
||||
})
|
||||
pagination.current = 1
|
||||
// 重置后自动加载数据
|
||||
loadData()
|
||||
}
|
||||
|
||||
const onPageChange = (page: number) => {
|
||||
console.log('页码变化:', page)
|
||||
pagination.current = page
|
||||
loadData()
|
||||
}
|
||||
|
||||
const onPageSizeChange = (pageSize: number) => {
|
||||
console.log('每页大小变化:', pageSize)
|
||||
pagination.pageSize = pageSize
|
||||
pagination.current = 1
|
||||
loadData()
|
||||
|
@ -664,7 +597,7 @@ const openStatusModal = (record: TeamMemberResp) => {
|
|||
const saveStatus = async () => {
|
||||
try {
|
||||
await updateTeamMember(statusForm.id, {
|
||||
status: statusForm.newStatus as 'ACTIVE' | 'SUSPENDED' | 'INACTIVE'
|
||||
status: statusForm.newStatus as 'ACTIVE' | 'SUSPENDEN' | 'INACTIVE'
|
||||
})
|
||||
Message.success('状态更新成功')
|
||||
statusModalVisible.value = false
|
||||
|
@ -783,7 +716,7 @@ const getRoleTypeText = (roleType: string) => {
|
|||
const getStatusColor = (status: string) => {
|
||||
const colorMap: Record<string, string> = {
|
||||
ACTIVE: 'success',
|
||||
SUSPENDED: 'warning',
|
||||
SUSPENDEN: 'warning',
|
||||
INACTIVE: 'danger'
|
||||
}
|
||||
return colorMap[status] || 'danger'
|
||||
|
@ -792,17 +725,12 @@ const getStatusColor = (status: string) => {
|
|||
const getStatusText = (status: string) => {
|
||||
const textMap: Record<string, string> = {
|
||||
ACTIVE: '可用',
|
||||
SUSPENDED: '忙碌',
|
||||
SUSPENDEN: '忙碌',
|
||||
INACTIVE: '离线'
|
||||
}
|
||||
return textMap[status] || '未知'
|
||||
}
|
||||
|
||||
// 计算属性:判断是否有激活的搜索条件
|
||||
const hasActiveFilters = computed(() => {
|
||||
return searchForm.name || searchForm.roleType || searchForm.status
|
||||
})
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
console.log('团队成员管理页面加载,项目ID:', projectId)
|
||||
|
@ -1011,29 +939,6 @@ onMounted(() => {
|
|||
padding: 24px;
|
||||
}
|
||||
|
||||
// 搜索状态提示样式
|
||||
.search-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
padding: 12px 16px;
|
||||
background: rgba(102, 126, 234, 0.1);
|
||||
border-radius: 8px;
|
||||
border-left: 4px solid #667eea;
|
||||
font-size: 14px;
|
||||
color: #4e5969;
|
||||
|
||||
.arco-btn {
|
||||
padding: 2px 8px;
|
||||
height: auto;
|
||||
line-height: 1.4;
|
||||
|
||||
&:hover {
|
||||
background: rgba(102, 126, 234, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.arco-form-item) {
|
||||
margin-bottom: 0;
|
||||
margin-right: 20px;
|
||||
|
@ -1064,7 +969,7 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
:deep(.arco-btn) {
|
||||
border-radius: 8px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
|
@ -1072,78 +977,87 @@ onMounted(() => {
|
|||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
|
||||
&:hover {
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索结果统计样式
|
||||
.search-results-info {
|
||||
margin-bottom: 16px;
|
||||
// 表格区域样式
|
||||
:deep(.gi-table) {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
margin-bottom: 24px;
|
||||
overflow: hidden;
|
||||
|
||||
.results-card {
|
||||
background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(102, 126, 234, 0.1);
|
||||
border: 1px solid rgba(102, 126, 234, 0.1);
|
||||
.arco-table-container {
|
||||
overflow-x: auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.arco-table {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.arco-table-body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
// 表格头部样式
|
||||
.arco-table-thead {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
|
||||
:deep(.arco-card-body) {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
.results-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
color: #4e5969;
|
||||
.arco-table-th {
|
||||
background: transparent !important;
|
||||
border-bottom: 2px solid rgba(255, 255, 255, 0.2);
|
||||
|
||||
strong {
|
||||
color: #667eea;
|
||||
.arco-table-th-item-title {
|
||||
color: white !important;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格行样式
|
||||
.arco-table-tbody {
|
||||
.arco-table-tr {
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.1);
|
||||
}
|
||||
|
||||
.arco-table-td {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 16px 12px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
// 斑马纹效果
|
||||
.arco-table-tr:nth-child(even) {
|
||||
background: #fafbfc;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 固定列样式
|
||||
.arco-table-fixed-left,
|
||||
.arco-table-fixed-right {
|
||||
.arco-table-td {
|
||||
background: white;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 空状态样式
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: #c9cdd4;
|
||||
|
||||
.empty-text {
|
||||
h3 {
|
||||
margin: 0 0 12px 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #4e5969;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 8px 0;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
|
||||
.arco-link {
|
||||
color: #667eea;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
color: #4c5fd9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.remark-content {
|
||||
max-width: 180px;
|
||||
|
@ -1196,58 +1110,11 @@ onMounted(() => {
|
|||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 16px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
// 状态标签样式
|
||||
.status-tag {
|
||||
display: inline-block;
|
||||
padding: 6px 12px;
|
||||
border-radius: 20px;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
min-width: 60px;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
&.status-ACTIVE {
|
||||
background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
|
||||
color: white;
|
||||
box-shadow: 0 2px 8px rgba(82, 196, 26, 0.3);
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 16px rgba(82, 196, 26, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
&.status-SUSPENDED {
|
||||
background: linear-gradient(135deg, #faad14 0%, #ffc53d 100%);
|
||||
color: white;
|
||||
box-shadow: 0 2px 8px rgba(250, 173, 20, 0.3);
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 16px rgba(250, 173, 20, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
&.status-INACTIVE {
|
||||
background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);
|
||||
color: white;
|
||||
box-shadow: 0 2px 8px rgba(255, 77, 79, 0.3);
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 16px rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.member-form {
|
||||
.form-row {
|
||||
display: grid;
|
||||
|
@ -1440,80 +1307,4 @@ onMounted(() => {
|
|||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
// 表格区域样式
|
||||
:deep(.gi-table) {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
margin-bottom: 24px;
|
||||
overflow: hidden;
|
||||
|
||||
.arco-table-container {
|
||||
overflow-x: auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.arco-table {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.arco-table-body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
// 表格头部样式
|
||||
.arco-table-thead {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
|
||||
.arco-table-th {
|
||||
background: transparent !important;
|
||||
border-bottom: 2px solid rgba(255, 255, 255, 0.2);
|
||||
|
||||
.arco-table-th-item-title {
|
||||
color: white !important;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格行样式
|
||||
.arco-table-tbody {
|
||||
.arco-table-tr {
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.1);
|
||||
}
|
||||
|
||||
.arco-table-td {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 16px 12px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
// 斑马纹效果
|
||||
.arco-table-tr:nth-child(even) {
|
||||
background: #fafbfc;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 固定列样式
|
||||
.arco-table-fixed-left,
|
||||
.arco-table-fixed-right {
|
||||
.arco-table-td {
|
||||
background: white;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue