|
|
@@ -154,9 +154,10 @@
|
|
|
clearable
|
|
|
placeholder="搜索项目/销售/交付"
|
|
|
prefix-icon="el-icon-search"
|
|
|
- size="small" />
|
|
|
+ size="small"
|
|
|
+ @input="onProjectSearchDebounced" />
|
|
|
</template>
|
|
|
- <div class="project-list">
|
|
|
+ <div ref="projectList" class="project-list">
|
|
|
<div
|
|
|
v-if="allProjectOption"
|
|
|
:class="['project-item', 'project-item--all', { active: selectedProject === allProjectOption.id }]"
|
|
|
@@ -206,6 +207,11 @@
|
|
|
</div>
|
|
|
<i v-if="selectedProject === project.id" class="el-icon-check project-card-check" />
|
|
|
</div>
|
|
|
+ <div v-if="projectLoading" class="project-list-loading">
|
|
|
+ <i class="el-icon-loading" />
|
|
|
+ 加载中...
|
|
|
+ </div>
|
|
|
+ <div v-else-if="!projectHasMore && projects.length > 1" class="project-list-end">没有更多了</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
</div>
|
|
|
@@ -437,6 +443,7 @@
|
|
|
import DeliveryProjectAssign from './components/DeliveryProjectAssign'
|
|
|
import ProjectInfoDialog from '../components/ProjectInfoDialog'
|
|
|
import { parseTime } from '@/utils'
|
|
|
+ import debounce from 'lodash/debounce'
|
|
|
import { uploadFileToRichtextServer } from '@/utils/richtextUpload'
|
|
|
import { sanitizeHtml } from '@/utils/safeHtml'
|
|
|
import { deliveryEventStatusTagTypes, getTagType } from '@/config/devopsTagTypes'
|
|
|
@@ -478,6 +485,11 @@
|
|
|
sidebarCollapsed: false,
|
|
|
showSidebarFilters: true,
|
|
|
projectSearch: '',
|
|
|
+ projectPageNum: 1,
|
|
|
+ projectPageSize: 20,
|
|
|
+ projectTotal: 0,
|
|
|
+ projectLoading: false,
|
|
|
+ projectHasMore: true,
|
|
|
projectStatusFilter: 'delivering',
|
|
|
selectedProject: '',
|
|
|
projects: [{ id: '', name: '全部' }],
|
|
|
@@ -526,7 +538,6 @@
|
|
|
)
|
|
|
},
|
|
|
filteredProjects() {
|
|
|
- const keyword = this.projectSearch.trim().toLowerCase()
|
|
|
const statusFilter = this.projectStatusFilter
|
|
|
|
|
|
return this.projects.filter((project) => {
|
|
|
@@ -534,14 +545,13 @@
|
|
|
|
|
|
// 状态筛选
|
|
|
if (statusFilter) {
|
|
|
- // 转换逻辑值为状态码列表
|
|
|
let statusList = []
|
|
|
if (statusFilter === 'pending') {
|
|
|
- statusList = ['10'] // 待分配
|
|
|
+ statusList = ['10']
|
|
|
} else if (statusFilter === 'delivering') {
|
|
|
- statusList = ['20', '30', '40'] // 交付中
|
|
|
+ statusList = ['20', '30', '40']
|
|
|
} else if (statusFilter === 'delivered') {
|
|
|
- statusList = ['50'] // 已验收
|
|
|
+ statusList = ['50']
|
|
|
} else {
|
|
|
statusList = statusFilter.split(',')
|
|
|
}
|
|
|
@@ -549,18 +559,12 @@
|
|
|
return false
|
|
|
}
|
|
|
} else {
|
|
|
- // 全部:排除90(作废)
|
|
|
if (project.status === '90') {
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 关键词筛选(支持项目名称、销售负责人、交付负责人)
|
|
|
- if (!keyword) return true
|
|
|
-
|
|
|
- return [project.name, project.salesOwner, project.deliveryOwner]
|
|
|
- .filter(Boolean)
|
|
|
- .some((field) => field.toLowerCase().includes(keyword))
|
|
|
+ return true
|
|
|
})
|
|
|
},
|
|
|
allProjectOption() {
|
|
|
@@ -573,6 +577,37 @@
|
|
|
created() {
|
|
|
this.getOptions()
|
|
|
this.fetchData()
|
|
|
+ this.onProjectSearchDebounced = debounce(() => {
|
|
|
+ this.projectPageNum = 1
|
|
|
+ this.projects = [{ id: '', name: '全部' }]
|
|
|
+ this.projectHasMore = true
|
|
|
+ this.fetchProjectList()
|
|
|
+ }, 300)
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ const el = this.$refs.projectList
|
|
|
+ if (!el) return
|
|
|
+ this._onProjectListScroll = debounce(() => {
|
|
|
+ if (!this.projectHasMore || this.projectLoading) return
|
|
|
+ const { scrollHeight, scrollTop, clientHeight } = el
|
|
|
+ if (scrollHeight - scrollTop - clientHeight <= 80) {
|
|
|
+ this.projectPageNum++
|
|
|
+ this.fetchProjectList()
|
|
|
+ }
|
|
|
+ }, 200)
|
|
|
+ el.addEventListener('scroll', this._onProjectListScroll)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ if (this._onProjectListScroll) {
|
|
|
+ this._onProjectListScroll.cancel()
|
|
|
+ const el = this.$refs.projectList
|
|
|
+ if (el) el.removeEventListener('scroll', this._onProjectListScroll)
|
|
|
+ }
|
|
|
+ if (this.onProjectSearchDebounced && this.onProjectSearchDebounced.cancel) {
|
|
|
+ this.onProjectSearchDebounced.cancel()
|
|
|
+ }
|
|
|
},
|
|
|
methods: {
|
|
|
getTagType,
|
|
|
@@ -606,12 +641,15 @@
|
|
|
.catch((err) => console.log(err))
|
|
|
},
|
|
|
|
|
|
- // 获取项目列表
|
|
|
+ // 获取项目列表(支持滚动分页)
|
|
|
async fetchProjectList() {
|
|
|
+ if (this.projectLoading) return
|
|
|
+
|
|
|
+ this.projectLoading = true
|
|
|
try {
|
|
|
const params = {
|
|
|
- pageNum: 1,
|
|
|
- pageSize: 999,
|
|
|
+ pageNum: this.projectPageNum,
|
|
|
+ pageSize: this.projectPageSize,
|
|
|
productLine: '10,20,30,40,50,60',
|
|
|
sortField: 'contract_no',
|
|
|
sortOrder: 'desc',
|
|
|
@@ -628,6 +666,12 @@
|
|
|
} else {
|
|
|
params.projectStatus = '10,20,30,40,50'
|
|
|
}
|
|
|
+
|
|
|
+ const keyword = this.projectSearch.trim()
|
|
|
+ if (keyword) {
|
|
|
+ params.keyWords = keyword
|
|
|
+ }
|
|
|
+
|
|
|
const res = await deliveryProjectApi.getList(params)
|
|
|
if (res.code === 200 && res.data && res.data.list) {
|
|
|
const projectList = (res.data?.list || []).map((item) => ({
|
|
|
@@ -640,11 +684,43 @@
|
|
|
deliveryUserId: item.deliveryUserId || item.delivery_user_id,
|
|
|
status: String(item.projectStatus || item.project_status),
|
|
|
}))
|
|
|
+ const total = res.data?.total || 0
|
|
|
projectList.sort((a, b) => (b.contractNo || '').localeCompare(a.contractNo || ''))
|
|
|
- this.projects = [{ id: '', name: '全部' }, ...projectList]
|
|
|
+
|
|
|
+ if (this.projectPageNum === 1) {
|
|
|
+ this.projects = [{ id: '', name: '全部' }, ...projectList]
|
|
|
+ } else {
|
|
|
+ this.projects = this.projects.concat(projectList)
|
|
|
+ }
|
|
|
+
|
|
|
+ this.projectTotal = total
|
|
|
+ this.projectHasMore = this.projects.length - 1 < total
|
|
|
+
|
|
|
+ // 如果选中的项目不在当前列表中,清除选中
|
|
|
+ if (this.selectedProject && !this.projects.some((project) => project.id === this.selectedProject)) {
|
|
|
+ this.selectedProject = ''
|
|
|
+ this.queryForm.projectId = ''
|
|
|
+ this.queryForm.pageNum = 1
|
|
|
+ this.fetchEventData()
|
|
|
+ }
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('获取项目列表失败:', error)
|
|
|
+ if (this.projectPageNum === 1) {
|
|
|
+ this.projects = [{ id: '', name: '全部' }]
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ this.projectLoading = false
|
|
|
+ // 内容未填满容器时自动加载下一页
|
|
|
+ this.$nextTick(() => {
|
|
|
+ const el = this.$refs.projectList
|
|
|
+ if (el && this.projectHasMore && !this.projectLoading) {
|
|
|
+ if (el.scrollHeight <= el.clientHeight) {
|
|
|
+ this.projectPageNum++
|
|
|
+ this.fetchProjectList()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
},
|
|
|
|
|
|
@@ -1074,6 +1150,9 @@
|
|
|
// 项目状态筛选变化
|
|
|
handleProjectStatusChange() {
|
|
|
this.queryForm.pageNum = 1
|
|
|
+ this.projectPageNum = 1
|
|
|
+ this.projects = [{ id: '', name: '全部' }]
|
|
|
+ this.projectHasMore = true
|
|
|
this.fetchProjectList()
|
|
|
},
|
|
|
|
|
|
@@ -1481,6 +1560,16 @@
|
|
|
padding-right: 2px;
|
|
|
}
|
|
|
|
|
|
+ .project-list-loading,
|
|
|
+ .project-list-end {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 12px 0;
|
|
|
+ font-size: 13px;
|
|
|
+ color: #909399;
|
|
|
+ }
|
|
|
+
|
|
|
.project-item {
|
|
|
display: flex;
|
|
|
align-items: center;
|