feat: show collaboration record creators
This commit is contained in:
+3
-2
@@ -70,8 +70,9 @@ public class CollaborationRecordController extends BaseController {
|
|||||||
@Operation(summary = "合作记录月度统计")
|
@Operation(summary = "合作记录月度统计")
|
||||||
@PreAuthorize("@permission.has('collaboration:record:statistics')")
|
@PreAuthorize("@permission.has('collaboration:record:statistics')")
|
||||||
@GetMapping("/monthly-statistics")
|
@GetMapping("/monthly-statistics")
|
||||||
public ResponseDTO<List<CollaborationMonthlyStatisticsDTO>> monthlyStatistics(@RequestParam Integer year) {
|
public ResponseDTO<List<CollaborationMonthlyStatisticsDTO>> monthlyStatistics(
|
||||||
return ResponseDTO.ok(recordApplicationService.getMonthlyStatistics(year));
|
@RequestParam Integer year, @RequestParam(required = false) Long creatorId) {
|
||||||
|
return ResponseDTO.ok(recordApplicationService.getMonthlyStatistics(year, creatorId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "新增合作记录")
|
@Operation(summary = "新增合作记录")
|
||||||
|
|||||||
+56
-17
@@ -34,7 +34,9 @@ import com.agileboot.domain.collaboration.record.enumtype.SettlementStatusEnum;
|
|||||||
import com.agileboot.domain.collaboration.record.model.CollaborationRecordModel;
|
import com.agileboot.domain.collaboration.record.model.CollaborationRecordModel;
|
||||||
import com.agileboot.domain.collaboration.record.model.CollaborationRecordModelFactory;
|
import com.agileboot.domain.collaboration.record.model.CollaborationRecordModelFactory;
|
||||||
import com.agileboot.domain.collaboration.record.query.CollaborationRecordQuery;
|
import com.agileboot.domain.collaboration.record.query.CollaborationRecordQuery;
|
||||||
|
import com.agileboot.domain.common.cache.CacheCenter;
|
||||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||||
|
import com.agileboot.domain.system.user.db.SysUserEntity;
|
||||||
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
import com.agileboot.infrastructure.user.AuthenticationUtils;
|
||||||
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
import com.agileboot.infrastructure.user.web.SystemLoginUser;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
@@ -130,17 +132,21 @@ public class CollaborationRecordApplicationService {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CollaborationMonthlyStatisticsDTO> getMonthlyStatistics(Integer year) {
|
public List<CollaborationMonthlyStatisticsDTO> getMonthlyStatistics(Integer year, Long creatorId) {
|
||||||
List<CollaborationMonthlyStatisticsDTO> statistics = new ArrayList<>();
|
List<CollaborationMonthlyStatisticsDTO> statistics = new ArrayList<>();
|
||||||
for (int month = 1; month <= 12; month++) {
|
for (int month = 1; month <= 12; month++) {
|
||||||
statistics.add(buildMonthlyStatistics(year, month));
|
statistics.add(buildMonthlyStatistics(year, month, creatorId));
|
||||||
}
|
}
|
||||||
return statistics;
|
return statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<CollaborationMonthlyStatisticsDTO> getMonthlyStatistics(Integer year) {
|
||||||
|
return getMonthlyStatistics(year, null);
|
||||||
|
}
|
||||||
|
|
||||||
private QueryWrapper<CollaborationRecordEntity> getScopedRecordWrapper(CollaborationRecordQuery query) {
|
private QueryWrapper<CollaborationRecordEntity> getScopedRecordWrapper(CollaborationRecordQuery query) {
|
||||||
|
applyQueryCreatorScope(query);
|
||||||
QueryWrapper<CollaborationRecordEntity> wrapper = query.toQueryWrapper();
|
QueryWrapper<CollaborationRecordEntity> wrapper = query.toQueryWrapper();
|
||||||
applyCurrentCreatorScope(wrapper);
|
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,6 +241,13 @@ public class CollaborationRecordApplicationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyQueryCreatorScope(CollaborationRecordQuery query) {
|
||||||
|
Long creatorId = getCurrentCreatorScope();
|
||||||
|
if (creatorId != null) {
|
||||||
|
query.setCreatorId(creatorId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Long getCurrentCreatorScope() {
|
private Long getCurrentCreatorScope() {
|
||||||
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
SystemLoginUser loginUser = AuthenticationUtils.getSystemLoginUser();
|
||||||
return loginUser.isAdmin() ? null : loginUser.getUserId();
|
return loginUser.isAdmin() ? null : loginUser.getUserId();
|
||||||
@@ -242,10 +255,22 @@ public class CollaborationRecordApplicationService {
|
|||||||
|
|
||||||
private CollaborationRecordDTO buildRecordDTO(CollaborationRecordEntity entity) {
|
private CollaborationRecordDTO buildRecordDTO(CollaborationRecordEntity entity) {
|
||||||
CollaborationRecordDTO dto = new CollaborationRecordDTO(entity);
|
CollaborationRecordDTO dto = new CollaborationRecordDTO(entity);
|
||||||
|
dto.setCreatorName(getCreatorName(entity.getCreatorId()));
|
||||||
fillRecordStats(dto, entity.getRecordId());
|
fillRecordStats(dto, entity.getRecordId());
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getCreatorName(Long creatorId) {
|
||||||
|
if (creatorId == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
SysUserEntity user = CacheCenter.userCache.getObjectById(creatorId);
|
||||||
|
if (user == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return StrUtil.blankToDefault(user.getNickname(), user.getUsername());
|
||||||
|
}
|
||||||
|
|
||||||
private void fillDetailChildren(CollaborationRecordDetailDTO dto, Long recordId) {
|
private void fillDetailChildren(CollaborationRecordDetailDTO dto, Long recordId) {
|
||||||
dto.setTasks(taskService.listByRecordId(recordId).stream()
|
dto.setTasks(taskService.listByRecordId(recordId).stream()
|
||||||
.map(CollaborationTaskDTO::new)
|
.map(CollaborationTaskDTO::new)
|
||||||
@@ -454,21 +479,21 @@ public class CollaborationRecordApplicationService {
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CollaborationMonthlyStatisticsDTO buildMonthlyStatistics(Integer year, Integer month) {
|
private CollaborationMonthlyStatisticsDTO buildMonthlyStatistics(Integer year, Integer month, Long creatorId) {
|
||||||
Date[] range = getMonthRange(year, month);
|
Date[] range = getMonthRange(year, month);
|
||||||
BigDecimal purchasePrice = sumPurchasePrice(range);
|
BigDecimal purchasePrice = sumPurchasePrice(range, creatorId);
|
||||||
BigDecimal expenditureAmount = sumExpenditure(range);
|
BigDecimal expenditureAmount = sumExpenditure(range, creatorId);
|
||||||
BigDecimal settledRemuneration = sumSettlement(range, REMUNERATION_FEE);
|
BigDecimal settledRemuneration = sumSettlement(range, REMUNERATION_FEE, creatorId);
|
||||||
BigDecimal settledTotal = sumSettlement(range, null);
|
BigDecimal settledTotal = sumSettlement(range, null, creatorId);
|
||||||
return new CollaborationMonthlyStatisticsDTO(month, purchasePrice, expenditureAmount,
|
return new CollaborationMonthlyStatisticsDTO(month, purchasePrice, expenditureAmount,
|
||||||
settledRemuneration, settledTotal);
|
settledRemuneration, settledTotal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal sumPurchasePrice(Date[] range) {
|
private BigDecimal sumPurchasePrice(Date[] range, Long creatorId) {
|
||||||
QueryWrapper<CollaborationRecordEntity> wrapper = new QueryWrapper<CollaborationRecordEntity>()
|
QueryWrapper<CollaborationRecordEntity> wrapper = new QueryWrapper<CollaborationRecordEntity>()
|
||||||
.ge("purchase_date", range[0])
|
.ge("purchase_date", range[0])
|
||||||
.le("purchase_date", range[1]);
|
.le("purchase_date", range[1]);
|
||||||
applyCurrentCreatorScope(wrapper);
|
applyCreatorScope(wrapper, creatorId);
|
||||||
List<CollaborationRecordEntity> records = recordService.list(wrapper);
|
List<CollaborationRecordEntity> records = recordService.list(wrapper);
|
||||||
return records.stream()
|
return records.stream()
|
||||||
.map(CollaborationRecordEntity::getPurchasePrice)
|
.map(CollaborationRecordEntity::getPurchasePrice)
|
||||||
@@ -476,11 +501,11 @@ public class CollaborationRecordApplicationService {
|
|||||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal sumExpenditure(Date[] range) {
|
private BigDecimal sumExpenditure(Date[] range, Long creatorId) {
|
||||||
QueryWrapper<CollaborationExpenditureEntity> wrapper = new QueryWrapper<CollaborationExpenditureEntity>()
|
QueryWrapper<CollaborationExpenditureEntity> wrapper = new QueryWrapper<CollaborationExpenditureEntity>()
|
||||||
.ge("spend_date", range[0])
|
.ge("spend_date", range[0])
|
||||||
.le("spend_date", range[1]);
|
.le("spend_date", range[1]);
|
||||||
applyChildRecordScope(wrapper);
|
applyChildRecordScope(wrapper, creatorId);
|
||||||
List<CollaborationExpenditureEntity> expenditures = expenditureService.list(wrapper);
|
List<CollaborationExpenditureEntity> expenditures = expenditureService.list(wrapper);
|
||||||
return expenditures.stream()
|
return expenditures.stream()
|
||||||
.map(CollaborationExpenditureEntity::getAmount)
|
.map(CollaborationExpenditureEntity::getAmount)
|
||||||
@@ -488,20 +513,34 @@ public class CollaborationRecordApplicationService {
|
|||||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal sumSettlement(Date[] range, String purpose) {
|
private BigDecimal sumSettlement(Date[] range, String purpose, Long creatorId) {
|
||||||
QueryWrapper<CollaborationSettlementEntity> wrapper = new QueryWrapper<CollaborationSettlementEntity>()
|
QueryWrapper<CollaborationSettlementEntity> wrapper = new QueryWrapper<CollaborationSettlementEntity>()
|
||||||
.ge("settle_date", range[0])
|
.ge("settle_date", range[0])
|
||||||
.le("settle_date", range[1])
|
.le("settle_date", range[1])
|
||||||
.eq(purpose != null, "purpose", purpose);
|
.eq(purpose != null, "purpose", purpose);
|
||||||
applyChildRecordScope(wrapper);
|
applyChildRecordScope(wrapper, creatorId);
|
||||||
return sumSettlement(settlementService.list(wrapper));
|
return sumSettlement(settlementService.list(wrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyChildRecordScope(QueryWrapper<?> wrapper) {
|
private void applyChildRecordScope(QueryWrapper<?> wrapper, Long requestedCreatorId) {
|
||||||
Long creatorId = getCurrentCreatorScope();
|
Long creatorId = getEffectiveCreatorScope(requestedCreatorId);
|
||||||
if (creatorId != null) {
|
if (creatorId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
wrapper.inSql("record_id", buildCreatorRecordSubQuery(creatorId));
|
wrapper.inSql("record_id", buildCreatorRecordSubQuery(creatorId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyCreatorScope(QueryWrapper<CollaborationRecordEntity> wrapper, Long requestedCreatorId) {
|
||||||
|
Long creatorId = getEffectiveCreatorScope(requestedCreatorId);
|
||||||
|
if (creatorId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wrapper.eq("creator_id", creatorId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getEffectiveCreatorScope(Long requestedCreatorId) {
|
||||||
|
Long currentCreatorScope = getCurrentCreatorScope();
|
||||||
|
return currentCreatorScope == null ? requestedCreatorId : currentCreatorScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildCreatorRecordSubQuery(Long creatorId) {
|
private String buildCreatorRecordSubQuery(Long creatorId) {
|
||||||
|
|||||||
+4
@@ -56,6 +56,10 @@ public class CollaborationRecordDTO {
|
|||||||
|
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
private Long creatorId;
|
||||||
|
|
||||||
|
private String creatorName;
|
||||||
|
|
||||||
private Integer tasksNum;
|
private Integer tasksNum;
|
||||||
|
|
||||||
private Integer completedTasksNum;
|
private Integer completedTasksNum;
|
||||||
|
|||||||
+3
@@ -27,6 +27,8 @@ public class CollaborationRecordQuery extends AbstractPageQuery<CollaborationRec
|
|||||||
|
|
||||||
private String taskStatus;
|
private String taskStatus;
|
||||||
|
|
||||||
|
private Long creatorId;
|
||||||
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||||
private Date purchaseBeginTime;
|
private Date purchaseBeginTime;
|
||||||
|
|
||||||
@@ -39,6 +41,7 @@ public class CollaborationRecordQuery extends AbstractPageQuery<CollaborationRec
|
|||||||
.like(StrUtil.isNotEmpty(brand), "brand", brand)
|
.like(StrUtil.isNotEmpty(brand), "brand", brand)
|
||||||
.like(StrUtil.isNotEmpty(goods), "goods", goods)
|
.like(StrUtil.isNotEmpty(goods), "goods", goods)
|
||||||
.eq(StrUtil.isNotEmpty(cooperationPlatform), "cooperation_platform", cooperationPlatform)
|
.eq(StrUtil.isNotEmpty(cooperationPlatform), "cooperation_platform", cooperationPlatform)
|
||||||
|
.eq(creatorId != null, "creator_id", creatorId)
|
||||||
.ge(purchaseBeginTime != null, "purchase_date", DatePickUtil.getBeginOfTheDay(purchaseBeginTime))
|
.ge(purchaseBeginTime != null, "purchase_date", DatePickUtil.getBeginOfTheDay(purchaseBeginTime))
|
||||||
.le(purchaseEndTime != null, "purchase_date", DatePickUtil.getEndOfTheDay(purchaseEndTime));
|
.le(purchaseEndTime != null, "purchase_date", DatePickUtil.getEndOfTheDay(purchaseEndTime));
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export interface CollaborationRecordListCommand extends BasePageQuery {
|
|||||||
brand?: string;
|
brand?: string;
|
||||||
goods?: string;
|
goods?: string;
|
||||||
cooperationPlatform?: string;
|
cooperationPlatform?: string;
|
||||||
|
creatorId?: number;
|
||||||
purchaseBeginTime?: string;
|
purchaseBeginTime?: string;
|
||||||
purchaseEndTime?: string;
|
purchaseEndTime?: string;
|
||||||
}
|
}
|
||||||
@@ -89,6 +90,8 @@ export interface CollaborationRecordPageResponse {
|
|||||||
completeDate?: string;
|
completeDate?: string;
|
||||||
requirements?: string;
|
requirements?: string;
|
||||||
remark?: string;
|
remark?: string;
|
||||||
|
creatorId?: number;
|
||||||
|
creatorName?: string;
|
||||||
tasksNum: number;
|
tasksNum: number;
|
||||||
completedTasksNum: number;
|
completedTasksNum: number;
|
||||||
purchaseSettlementStatus: SettlementStatusDTO;
|
purchaseSettlementStatus: SettlementStatusDTO;
|
||||||
@@ -182,12 +185,19 @@ export const getCollaborationOptionsApi = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getCollaborationMonthlyStatisticsApi = (year: number) => {
|
export interface CollaborationMonthlyStatisticsCommand {
|
||||||
|
year: number;
|
||||||
|
creatorId?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getCollaborationMonthlyStatisticsApi = (
|
||||||
|
params: CollaborationMonthlyStatisticsCommand
|
||||||
|
) => {
|
||||||
return http.request<ResponseData<CollaborationMonthlyStatisticsResponse[]>>(
|
return http.request<ResponseData<CollaborationMonthlyStatisticsResponse[]>>(
|
||||||
"get",
|
"get",
|
||||||
"/collaboration/record/monthly-statistics",
|
"/collaboration/record/monthly-statistics",
|
||||||
{
|
{
|
||||||
params: { year }
|
params
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ const {
|
|||||||
deadlineRange,
|
deadlineRange,
|
||||||
purchaseRange,
|
purchaseRange,
|
||||||
optionMap,
|
optionMap,
|
||||||
|
creatorOptions,
|
||||||
|
isAdmin,
|
||||||
|
getUserDisplayName,
|
||||||
multipleSelection,
|
multipleSelection,
|
||||||
onSearch,
|
onSearch,
|
||||||
onSortChanged,
|
onSortChanged,
|
||||||
@@ -93,6 +96,22 @@ function openDialog(
|
|||||||
class="!w-[180px]"
|
class="!w-[180px]"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item v-if="isAdmin" label="创建者" prop="creatorId">
|
||||||
|
<el-select
|
||||||
|
v-model="searchFormParams.creatorId"
|
||||||
|
placeholder="请选择创建者"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
class="!w-[160px]"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in creatorOptions"
|
||||||
|
:key="item.userId"
|
||||||
|
:label="getUserDisplayName(item)"
|
||||||
|
:value="item.userId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="合作平台" prop="cooperationPlatform">
|
<el-form-item label="合作平台" prop="cooperationPlatform">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="searchFormParams.cooperationPlatform"
|
v-model="searchFormParams.cooperationPlatform"
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { ElMessageBox, Sort } from "element-plus";
|
|||||||
import { computed, onMounted, reactive, ref, toRaw, unref } from "vue";
|
import { computed, onMounted, reactive, ref, toRaw, unref } from "vue";
|
||||||
import { CommonUtils } from "@/utils/common";
|
import { CommonUtils } from "@/utils/common";
|
||||||
import { PaginationProps } from "@pureadmin/table";
|
import { PaginationProps } from "@pureadmin/table";
|
||||||
|
import { getUserListApi, UserDTO } from "@/api/system/user";
|
||||||
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
import {
|
import {
|
||||||
CollaborationOptionResponse,
|
CollaborationOptionResponse,
|
||||||
CollaborationRecordListCommand,
|
CollaborationRecordListCommand,
|
||||||
@@ -20,7 +22,14 @@ const statusTypeMap = {
|
|||||||
PARTIAL: "warning"
|
PARTIAL: "warning"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getUserDisplayName(user: UserDTO) {
|
||||||
|
return user.nickname || user.username || "";
|
||||||
|
}
|
||||||
|
|
||||||
export function useCollaborationRecordHook() {
|
export function useCollaborationRecordHook() {
|
||||||
|
const userStore = useUserStoreHook();
|
||||||
|
const isAdmin = computed(() => userStore.roles?.includes("admin"));
|
||||||
|
|
||||||
const defaultSort: Sort = {
|
const defaultSort: Sort = {
|
||||||
prop: "deadline",
|
prop: "deadline",
|
||||||
order: "descending"
|
order: "descending"
|
||||||
@@ -36,6 +45,7 @@ export function useCollaborationRecordHook() {
|
|||||||
const searchFormParams = reactive<CollaborationRecordListCommand>({
|
const searchFormParams = reactive<CollaborationRecordListCommand>({
|
||||||
brand: "",
|
brand: "",
|
||||||
goods: "",
|
goods: "",
|
||||||
|
creatorId: undefined,
|
||||||
cooperationPlatform: undefined
|
cooperationPlatform: undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -55,6 +65,7 @@ export function useCollaborationRecordHook() {
|
|||||||
|
|
||||||
const dataList = ref<CollaborationRecordPageResponse[]>([]);
|
const dataList = ref<CollaborationRecordPageResponse[]>([]);
|
||||||
const optionMap = ref<Record<string, string[]>>({});
|
const optionMap = ref<Record<string, string[]>>({});
|
||||||
|
const creatorOptions = ref<UserDTO[]>([]);
|
||||||
const pageLoading = ref(true);
|
const pageLoading = ref(true);
|
||||||
const multipleSelection = ref<number[]>([]);
|
const multipleSelection = ref<number[]>([]);
|
||||||
const sortState = ref<Sort>(defaultSort);
|
const sortState = ref<Sort>(defaultSort);
|
||||||
@@ -63,6 +74,12 @@ export function useCollaborationRecordHook() {
|
|||||||
{ type: "selection", align: "left" },
|
{ type: "selection", align: "left" },
|
||||||
{ label: "品牌", prop: "brand", minWidth: 120 },
|
{ label: "品牌", prop: "brand", minWidth: 120 },
|
||||||
{ label: "物品", prop: "goods", minWidth: 120 },
|
{ label: "物品", prop: "goods", minWidth: 120 },
|
||||||
|
{
|
||||||
|
label: "创建者",
|
||||||
|
prop: "creatorName",
|
||||||
|
minWidth: 110,
|
||||||
|
hide: !isAdmin.value
|
||||||
|
},
|
||||||
{ label: "合作平台", prop: "cooperationPlatform", minWidth: 110 },
|
{ label: "合作平台", prop: "cooperationPlatform", minWidth: 110 },
|
||||||
{ label: "留存方式", prop: "retainedMethod", minWidth: 100 },
|
{ label: "留存方式", prop: "retainedMethod", minWidth: 100 },
|
||||||
{ label: "购入方式", prop: "purchaseMethod", minWidth: 100 },
|
{ label: "购入方式", prop: "purchaseMethod", minWidth: 100 },
|
||||||
@@ -126,8 +143,9 @@ export function useCollaborationRecordHook() {
|
|||||||
|
|
||||||
function renderStatus(status, size) {
|
function renderStatus(status, size) {
|
||||||
if (!status) return "";
|
if (!status) return "";
|
||||||
|
const type = statusTypeMap[status.status] || "info";
|
||||||
return (
|
return (
|
||||||
<el-tag size={size} type={statusTypeMap[status.status]} effect="plain">
|
<el-tag size={size} type={type} effect="plain">
|
||||||
{status.label}
|
{status.label}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
);
|
);
|
||||||
@@ -195,6 +213,12 @@ export function useCollaborationRecordHook() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getCreatorOptions() {
|
||||||
|
if (!isAdmin.value) return;
|
||||||
|
const { data } = await getUserListApi({ pageNum: 1, pageSize: 1000 });
|
||||||
|
creatorOptions.value = data.rows;
|
||||||
|
}
|
||||||
|
|
||||||
async function handleDelete(row: CollaborationRecordPageResponse) {
|
async function handleDelete(row: CollaborationRecordPageResponse) {
|
||||||
await deleteCollaborationRecordApi([row.recordId]);
|
await deleteCollaborationRecordApi([row.recordId]);
|
||||||
message(`您删除了编号为${row.recordId}的合作记录`, { type: "success" });
|
message(`您删除了编号为${row.recordId}的合作记录`, { type: "success" });
|
||||||
@@ -237,6 +261,7 @@ export function useCollaborationRecordHook() {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getOptions();
|
getOptions();
|
||||||
|
getCreatorOptions();
|
||||||
getRecordList();
|
getRecordList();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -250,6 +275,9 @@ export function useCollaborationRecordHook() {
|
|||||||
deadlineRange,
|
deadlineRange,
|
||||||
purchaseRange,
|
purchaseRange,
|
||||||
optionMap,
|
optionMap,
|
||||||
|
creatorOptions,
|
||||||
|
isAdmin,
|
||||||
|
getUserDisplayName,
|
||||||
multipleSelection,
|
multipleSelection,
|
||||||
onSearch,
|
onSearch,
|
||||||
onSortChanged,
|
onSortChanged,
|
||||||
|
|||||||
@@ -5,8 +5,16 @@ defineOptions({
|
|||||||
name: "CollaborationStatistics"
|
name: "CollaborationStatistics"
|
||||||
});
|
});
|
||||||
|
|
||||||
const { chartRef, selectedYear, yearOptions, getStatistics } =
|
const {
|
||||||
useCollaborationStatisticsHook();
|
chartRef,
|
||||||
|
selectedYear,
|
||||||
|
selectedCreatorId,
|
||||||
|
yearOptions,
|
||||||
|
creatorOptions,
|
||||||
|
isAdmin,
|
||||||
|
getUserDisplayName,
|
||||||
|
getStatistics
|
||||||
|
} = useCollaborationStatisticsHook();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -15,6 +23,23 @@ const { chartRef, selectedYear, yearOptions, getStatistics } =
|
|||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span>月度统计</span>
|
<span>月度统计</span>
|
||||||
|
<div class="filters">
|
||||||
|
<el-select
|
||||||
|
v-if="isAdmin"
|
||||||
|
v-model="selectedCreatorId"
|
||||||
|
placeholder="全部用户"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
class="!w-[160px]"
|
||||||
|
@change="getStatistics"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="user in creatorOptions"
|
||||||
|
:key="user.userId"
|
||||||
|
:label="getUserDisplayName(user)"
|
||||||
|
:value="user.userId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="selectedYear"
|
v-model="selectedYear"
|
||||||
class="!w-[140px]"
|
class="!w-[140px]"
|
||||||
@@ -28,6 +53,7 @@ const { chartRef, selectedYear, yearOptions, getStatistics } =
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div ref="chartRef" class="chart" />
|
<div ref="chartRef" class="chart" />
|
||||||
</el-card>
|
</el-card>
|
||||||
@@ -41,6 +67,11 @@ const { chartRef, selectedYear, yearOptions, getStatistics } =
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filters {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.chart {
|
.chart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 600px;
|
height: 600px;
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
import { onMounted, ref } from "vue";
|
import { computed, onMounted, ref } from "vue";
|
||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
import { getCollaborationMonthlyStatisticsApi } from "@/api/collaboration/record";
|
import {
|
||||||
|
CollaborationMonthlyStatisticsResponse,
|
||||||
|
getCollaborationMonthlyStatisticsApi
|
||||||
|
} from "@/api/collaboration/record";
|
||||||
|
import { getUserListApi, UserDTO } from "@/api/system/user";
|
||||||
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
|
|
||||||
export function useCollaborationStatisticsHook() {
|
export function useCollaborationStatisticsHook() {
|
||||||
|
const userStore = useUserStoreHook();
|
||||||
|
const isAdmin = computed(() => userStore.roles?.includes("admin"));
|
||||||
const currentYear = new Date().getFullYear();
|
const currentYear = new Date().getFullYear();
|
||||||
const selectedYear = ref(currentYear);
|
const selectedYear = ref(currentYear);
|
||||||
|
const selectedCreatorId = ref<number>();
|
||||||
|
const creatorOptions = ref<UserDTO[]>([]);
|
||||||
const yearOptions = Array.from(
|
const yearOptions = Array.from(
|
||||||
{ length: currentYear - 2012 },
|
{ length: currentYear - 2012 },
|
||||||
(_, index) => currentYear - index
|
(_, index) => currentYear - index
|
||||||
@@ -13,13 +22,24 @@ export function useCollaborationStatisticsHook() {
|
|||||||
let chart: echarts.ECharts | undefined;
|
let chart: echarts.ECharts | undefined;
|
||||||
|
|
||||||
async function getStatistics() {
|
async function getStatistics() {
|
||||||
const { data } = await getCollaborationMonthlyStatisticsApi(
|
const { data } = await getCollaborationMonthlyStatisticsApi({
|
||||||
selectedYear.value
|
year: selectedYear.value,
|
||||||
);
|
creatorId: selectedCreatorId.value
|
||||||
|
});
|
||||||
renderChart(data);
|
renderChart(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderChart(data) {
|
async function getCreatorOptions() {
|
||||||
|
if (!isAdmin.value) return;
|
||||||
|
const { data } = await getUserListApi({ pageNum: 1, pageSize: 1000 });
|
||||||
|
creatorOptions.value = data.rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUserDisplayName(user: UserDTO) {
|
||||||
|
return user.nickname || user.username || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderChart(data: CollaborationMonthlyStatisticsResponse[]) {
|
||||||
chart?.dispose();
|
chart?.dispose();
|
||||||
chart = echarts.init(chartRef.value);
|
chart = echarts.init(chartRef.value);
|
||||||
chart.setOption({
|
chart.setOption({
|
||||||
@@ -71,6 +91,7 @@ export function useCollaborationStatisticsHook() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
getCreatorOptions();
|
||||||
getStatistics();
|
getStatistics();
|
||||||
window.addEventListener("resize", resizeChart);
|
window.addEventListener("resize", resizeChart);
|
||||||
});
|
});
|
||||||
@@ -78,7 +99,11 @@ export function useCollaborationStatisticsHook() {
|
|||||||
return {
|
return {
|
||||||
chartRef,
|
chartRef,
|
||||||
selectedYear,
|
selectedYear,
|
||||||
|
selectedCreatorId,
|
||||||
yearOptions,
|
yearOptions,
|
||||||
|
creatorOptions,
|
||||||
|
isAdmin,
|
||||||
|
getUserDisplayName,
|
||||||
getStatistics
|
getStatistics
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user