perf: 优化工作报告列表

This commit is contained in:
kuaifan 2025-03-14 22:44:25 +08:00
parent 79ca1aea02
commit b7d10a4c58
6 changed files with 110 additions and 28 deletions

View File

@ -33,6 +33,7 @@ class ReportController extends AbstractController
* @apiName my * @apiName my
* *
* @apiParam {Object} [keys] 搜索条件 * @apiParam {Object} [keys] 搜索条件
* - keys.key: 关键词
* - keys.type: 汇报类型weekly:周报daily:日报 * - keys.type: 汇报类型weekly:周报daily:日报
* - keys.created_at: 汇报时间 * - keys.created_at: 汇报时间
* @apiParam {Number} [page] 当前页,默认:1 * @apiParam {Number} [page] 当前页,默认:1
@ -49,6 +50,15 @@ class ReportController extends AbstractController
$builder = Report::with(['receivesUser'])->whereUserid($user->userid); $builder = Report::with(['receivesUser'])->whereUserid($user->userid);
$keys = Request::input('keys'); $keys = Request::input('keys');
if (is_array($keys)) { if (is_array($keys)) {
if ($keys['key']) {
if (str_contains($keys['key'], '@')) {
$builder->whereHas('sendUser', function ($q2) use ($keys) {
$q2->where("users.email", "LIKE", "%{$keys['key']}%");
});
} else {
$builder->where("title", "LIKE", "%{$keys['key']}%");
}
}
if (in_array($keys['type'], [Report::WEEKLY, Report::DAILY])) { if (in_array($keys['type'], [Report::WEEKLY, Report::DAILY])) {
$builder->whereType($keys['type']); $builder->whereType($keys['type']);
} }
@ -70,6 +80,7 @@ class ReportController extends AbstractController
* *
* @apiParam {Object} [keys] 搜索条件 * @apiParam {Object} [keys] 搜索条件
* - keys.key: 关键词 * - keys.key: 关键词
* - keys.department_id: 部门ID
* - keys.type: 汇报类型weekly:周报daily:日报 * - keys.type: 汇报类型weekly:周报daily:日报
* - keys.status: 状态unread:未读read:已读 * - keys.status: 状态unread:未读read:已读
* - keys.created_at: 汇报时间 * - keys.created_at: 汇报时间
@ -90,10 +101,19 @@ class ReportController extends AbstractController
$keys = Request::input('keys'); $keys = Request::input('keys');
if (is_array($keys)) { if (is_array($keys)) {
if ($keys['key']) { if ($keys['key']) {
$builder->where(function($query) use ($keys) { if (str_contains($keys['key'], '@')) {
$query->whereHas('sendUser', function ($q2) use ($keys) { $builder->whereHas('sendUser', function ($q2) use ($keys) {
$q2->where("users.email", "LIKE", "%{$keys['key']}%"); $q2->where("users.email", "LIKE", "%{$keys['key']}%");
})->orWhere("title", "LIKE", "%{$keys['key']}%"); });
} elseif (Base::isNumber($keys['key'])) {
$builder->where("userid", intval($keys['key']));
} else {
$builder->where("title", "LIKE", "%{$keys['key']}%");
}
}
if ($keys['department_id']) {
$builder->whereHas('sendUser', function ($query) use ($keys) {
$query->where("users.department", "LIKE", "%,{$keys['department_id']},%");
}); });
} }
if (in_array($keys['type'], [Report::WEEKLY, Report::DAILY])) { if (in_array($keys['type'], [Report::WEEKLY, Report::DAILY])) {

View File

@ -662,6 +662,27 @@ import {convertLocalResourcePath} from "../components/Replace/utils";
}) })
} }
}) })
},
/**
* 提取工作报告中的时间
* @param text
* @returns {*|string}
*/
reportExtractTime(text) {
const regex = /(?:.*?)(?:\[([^\[\]]*)\]\s*)?(?:\[([^\[\]]*)\]\s*)?$/;
const match = text.match(regex);
if (!match) return "";
const secondLast = `${match[1] || ""}`.replace(/^\s*\((.*)\)\s*$/, "$1");
const last = `${match[2] || ""}`.replace(/^\s*\((.*)\)\s*$/, "$1");
if (last && secondLast) {
return `${last} (${secondLast})`;
} else if (last) {
return last;
} else if (secondLast) {
return secondLast;
}
return "";
} }
}); });

View File

@ -296,7 +296,7 @@
v-model="workReportShow" v-model="workReportShow"
placement="right" placement="right"
:size="1200"> :size="1200">
<Report v-if="workReportShow" v-model="reportTabs" @on-read="$store.dispatch('getReportUnread', 1000)" /> <Report v-if="workReportShow" v-model="workReportTab" @on-read="$store.dispatch('getReportUnread', 1000)" />
</DrawerOverlay> </DrawerOverlay>
<!--查看所有团队--> <!--查看所有团队-->
@ -435,7 +435,6 @@ export default {
visibleMenu: false, visibleMenu: false,
showMobileMenu: false, showMobileMenu: false,
workReportShow: false,
allUserShow: false, allUserShow: false,
allProjectShow: false, allProjectShow: false,
archivedProjectShow: false, archivedProjectShow: false,
@ -443,7 +442,8 @@ export default {
natificationReady: false, natificationReady: false,
notificationManage: null, notificationManage: null,
reportTabs: "my", workReportShow: false,
workReportTab: "my",
operateStyles: {}, operateStyles: {},
operateVisible: false, operateVisible: false,
@ -465,6 +465,7 @@ export default {
emitter.on('createGroup', this.onCreateGroup); emitter.on('createGroup', this.onCreateGroup);
emitter.on('dialogMsgPush', this.addDialogMsg); emitter.on('dialogMsgPush', this.addDialogMsg);
emitter.on('approveDetails', this.openApproveDetails); emitter.on('approveDetails', this.openApproveDetails);
emitter.on('openReport', this.openReport);
// //
document.addEventListener('keydown', this.shortcutEvent); document.addEventListener('keydown', this.shortcutEvent);
}, },
@ -487,6 +488,7 @@ export default {
emitter.off('createGroup', this.onCreateGroup); emitter.off('createGroup', this.onCreateGroup);
emitter.off('dialogMsgPush', this.addDialogMsg); emitter.off('dialogMsgPush', this.addDialogMsg);
emitter.off('approveDetails', this.openApproveDetails); emitter.off('approveDetails', this.openApproveDetails);
emitter.off('openReport', this.openReport);
// //
document.removeEventListener('keydown', this.shortcutEvent); document.removeEventListener('keydown', this.shortcutEvent);
}, },
@ -801,10 +803,7 @@ export default {
this.exportApproveShow = true; this.exportApproveShow = true;
return; return;
case 'workReport': case 'workReport':
if (this.reportUnreadNumber > 0) { this.openReport(this.reportUnreadNumber > 0 ? 'receive' : 'my');
this.reportTabs = "receive";
}
this.workReportShow = true;
return; return;
case 'version': case 'version':
emitter.emit('updateNotification', null); emitter.emit('updateNotification', null);
@ -1144,6 +1143,11 @@ export default {
}) })
}, },
openReport(tab) {
this.workReportTab = tab;
this.workReportShow = true;
},
handleLongpress(event, el) { handleLongpress(event, el) {
const projectId = $A.getAttr(el, 'data-id') const projectId = $A.getAttr(el, 'data-id')
const projectItem = this.projectLists.find(item => item.id == projectId) const projectItem = this.projectLists.find(item => item.id == projectId)

View File

@ -40,11 +40,6 @@
</div> </div>
</div> </div>
<!--工作报告-->
<DrawerOverlay v-model="workReportShow" placement="right" :size="1200">
<Report v-if="workReportShow" v-model="workReportTabs" @on-read="$store.dispatch('getReportUnread', 1000)" />
</DrawerOverlay>
<!--AI--> <!--AI-->
<DrawerOverlay v-model="aibotShow" placement="right" :size="720"> <DrawerOverlay v-model="aibotShow" placement="right" :size="720">
<div v-if="aibotShow" class="ivu-modal-wrap-apply"> <div v-if="aibotShow" class="ivu-modal-wrap-apply">
@ -244,7 +239,6 @@
import {mapState} from "vuex"; import {mapState} from "vuex";
import DrawerOverlay from "../../components/DrawerOverlay"; import DrawerOverlay from "../../components/DrawerOverlay";
import UserSelect from "../../components/UserSelect"; import UserSelect from "../../components/UserSelect";
import Report from "../manage/components/Report";
import SystemAibot from "./setting/components/SystemAibot"; import SystemAibot from "./setting/components/SystemAibot";
import SystemCheckin from "./setting/components/SystemCheckin"; import SystemCheckin from "./setting/components/SystemCheckin";
import Checkin from "./setting/checkin"; import Checkin from "./setting/checkin";
@ -259,7 +253,6 @@ export default {
components: { components: {
UserSelect, UserSelect,
DrawerOverlay, DrawerOverlay,
Report,
SystemAibot, SystemAibot,
SystemCheckin, SystemCheckin,
Checkin, Checkin,
@ -273,9 +266,6 @@ export default {
applyList: [], applyList: [],
applyListTypes: ['base', 'admin'], applyListTypes: ['base', 'admin'],
// //
workReportShow: false,
workReportTabs: "my",
//
aibotList: AIBotList, aibotList: AIBotList,
aibotShow: false, aibotShow: false,
aibotSettingShow: false, aibotSettingShow: false,
@ -421,8 +411,7 @@ export default {
}); });
break; break;
case 'report': case 'report':
this.workReportTabs = area == 'badge' ? 'receive' : 'my'; emitter.emit('openReport', area == 'badge' ? 'receive' : 'my');
this.workReportShow = true;
break; break;
case 'robot': case 'robot':
this.getAITags(); this.getAITags();

View File

@ -3,6 +3,14 @@
<div class="search-expand"> <div class="search-expand">
<div class="search-container lr"> <div class="search-container lr">
<ul> <ul>
<li>
<div class="search-label">
{{ $L("关键词") }}
</div>
<div class="search-content">
<Input v-model="keys.key" :placeholder="$L('输入关键词搜索')" clearable/>
</div>
</li>
<li> <li>
<div class="search-label"> <div class="search-label">
{{ $L("汇报类型") }} {{ $L("汇报类型") }}
@ -77,11 +85,20 @@ export default {
return { return {
loadIng: 0, loadIng: 0,
columns: [{ columns: [{
title: this.$L("名称"), title: this.$L("标题"),
key: 'title', key: 'title',
minWidth: 180, minWidth: 180,
render: (h, {row}) => { render: (h, {row}) => {
return h('AutoTip', row.title); const displayTitle = `${row.title || ""}`.replace(/(\[([^\[\]]*)\]\s*){0,2}$/, '');
return h('AutoTip', displayTitle);
}
}, {
title: this.$L("时间"),
key: 'time',
sortable: true,
minWidth: 180,
render: (h, {row}) => {
return h('AutoTip', $A.reportExtractTime(row.title) || '-');
} }
}, { }, {
title: this.$L("类型"), title: this.$L("类型"),

View File

@ -10,6 +10,25 @@
<Input v-model="keys.key" :placeholder="$L('输入关键词搜索')" clearable/> <Input v-model="keys.key" :placeholder="$L('输入关键词搜索')" clearable/>
</div> </div>
</li> </li>
<li>
<div class="search-label">
{{ $L("汇报部门") }}
</div>
<div class="search-content">
<Select
v-model="keys.department_id"
:placeholder="$L('全部')">
<Option value="">{{$L('全部')}}</Option>
<Option
v-for="(item, index) in departmentList"
:value="item.id"
:key="index"
:label="item.chains.join(' - ')">
<div :class="`department-level-name level-${item.level}`">{{ item.name }}</div>
</Option>
</Select>
</div>
</li>
<li> <li>
<div class="search-label"> <div class="search-label">
{{ $L("汇报类型") }} {{ $L("汇报类型") }}
@ -113,7 +132,8 @@ export default {
sortable: true, sortable: true,
minWidth: 180, minWidth: 180,
render: (h, {row}) => { render: (h, {row}) => {
let arr = [] const displayTitle = `${row.title || ""}`.replace(/(\[([^\[\]]*)\]\s*){0,2}$/, '');
const arr = []
const myUser = row.receives_user.find(({userid}) => userid == this.userId) const myUser = row.receives_user.find(({userid}) => userid == this.userId)
if (myUser && myUser.pivot.read == 0) { if (myUser && myUser.pivot.read == 0) {
arr.push( arr.push(
@ -125,11 +145,11 @@ export default {
flexShrink: 0, flexShrink: 0,
} }
}, this.$L("未读")), }, this.$L("未读")),
h('AutoTip', row.title) h('AutoTip', displayTitle)
) )
} else { } else {
arr.push( arr.push(
h('AutoTip', row.title) h('AutoTip', displayTitle)
) )
} }
return h('div', { return h('div', {
@ -139,6 +159,14 @@ export default {
} }
}, arr) }, arr)
} }
}, {
title: this.$L("时间"),
key: 'time',
sortable: true,
minWidth: 180,
render: (h, {row}) => {
return h('AutoTip', $A.reportExtractTime(row.title) || '-');
}
}, { }, {
title: this.$L("类型"), title: this.$L("类型"),
key: 'type', key: 'type',
@ -209,10 +237,13 @@ export default {
{value: "unread", label: this.$L('仅未读')}, {value: "unread", label: this.$L('仅未读')},
{value: "read", label: this.$L('仅已读')}, {value: "read", label: this.$L('仅已读')},
], ],
departmentList: [],
} }
}, },
mounted() { async mounted() {
this.getLists(); this.getLists();
this.departmentList = await this.$store.dispatch("getDepartmentList")
}, },
watch: { watch: {
keyIs(v) { keyIs(v) {