项目需求、任务以及模块精简

This commit is contained in:
2026-04-06 00:23:23 +08:00
parent 97564b82da
commit 477a08da9f
32 changed files with 1888 additions and 874 deletions

View File

@@ -35,6 +35,9 @@ export interface MyProjectContract extends BasicModel<MyProjectContract> {
export const myProjectContractList = (params?: MyProjectContract | any) =>
defHttp.get<MyProjectContract>({ url: adminPath + '/biz/myProjectContract/list', params });
export const myProjectContractListAll = (params?: MyProjectContract | any) =>
defHttp.get<MyProjectContract[]>({ url: adminPath + '/biz/myProjectContract/listAll', params });
export const myProjectContractListData = (params?: MyProjectContract | any) =>
defHttp.post<Page<MyProjectContract>>({ url: adminPath + '/biz/myProjectContract/listData', params });

View File

@@ -33,6 +33,9 @@ export interface MyProjectTask extends BasicModel<MyProjectTask> {
export const myProjectTaskList = (params?: MyProjectTask | any) =>
defHttp.get<MyProjectTask>({ url: adminPath + '/biz/myProjectTask/list', params });
export const myProjectTaskListAll = (params?: MyProjectTask | any) =>
defHttp.get<MyProjectTask[]>({ url: adminPath + '/biz/myProjectTask/listAll', params });
export const myProjectTaskListData = (params?: MyProjectTask | any) =>
defHttp.post<Page<MyProjectTask>>({ url: adminPath + '/biz/myProjectTask/listData', params });

View File

@@ -27,10 +27,14 @@
import { Icon } from '@jeesite/core/components/Icon';
import { BasicForm, FormSchema, useForm } from '@jeesite/core/components/Form';
import { BasicDrawer, useDrawerInner } from '@jeesite/core/components/Drawer';
import { MyProjectRequirement, myProjectRequirementSave, myProjectRequirementForm } from '@jeesite/biz/api/biz/myProjectRequirement';
import {
MyProjectRequirement,
myProjectRequirementSave,
myProjectRequirementForm,
} from '@jeesite/biz/api/biz/myProjectRequirement';
import { formatToDateTime } from '@jeesite/core/utils/dateUtil';
import { useUserStore } from '@jeesite/core/store/modules/user';
const userStore = useUserStore();
const userinfo = computed(() => userStore.getUserInfo);
@@ -46,6 +50,10 @@
value: record.value.isNewRecord ? t('新增需求') : t('编辑需求'),
}));
function getRequirementNo() {
return `WS_${Date.now()}`;
}
const inputFormSchemas: FormSchema<MyProjectRequirement>[] = [
{
label: t('基本信息'),
@@ -59,6 +67,7 @@
component: 'Input',
componentProps: {
maxlength: 64,
disabled: true,
},
required: true,
},
@@ -74,38 +83,38 @@
{
label: t('项目名称'),
field: 'projectId',
fieldLabel: 'projectName',
component: 'ListSelect',
componentProps: {
selectType: 'bizProjectSelect',
},
fieldLabel: 'projectName',
component: 'ListSelect',
componentProps: {
selectType: 'bizProjectSelect',
},
required: true,
},
{
label: t('优先等级'),
field: 'priority',
component: 'Select',
componentProps: {
dictType: 'biz_priority',
allowClear: true,
},
required: true,
},
{
label: t('优先等级'),
field: 'priority',
component: 'Select',
componentProps: {
dictType: 'biz_priority',
allowClear: true,
},
required: true,
},
{
label: t('详细内容'),
field: 'requirementContent',
component: 'InputTextArea',
required: true,
colProps: { md: 24, lg: 24 },
colProps: { md: 24, lg: 24 },
},
{
label: t('需求状态'),
field: 'requirementStatus',
component: 'Select',
componentProps: {
dictType: 'requirement_status',
allowClear: true,
},
component: 'Select',
componentProps: {
dictType: 'requirement_status',
allowClear: true,
},
required: true,
},
{
@@ -138,7 +147,7 @@
label: t('需求备注'),
field: 'remark',
component: 'InputTextArea',
colProps: { md: 24, lg: 24 },
colProps: { md: 24, lg: 24 },
},
{
label: t('附件上传'),
@@ -165,6 +174,9 @@
await resetFields();
const res = await myProjectRequirementForm(data);
record.value = (res.myProjectRequirement || {}) as MyProjectRequirement;
if (record.value.isNewRecord) {
record.value.requirementNo = getRequirementNo();
}
record.value.__t = new Date().getTime();
await setFieldsValue(record.value);
setDrawerProps({ loading: false });
@@ -178,13 +190,14 @@
isNewRecord: record.value.isNewRecord,
requirementId: record.value.requirementId || data.requirementId,
};
if(record.value.isNewRecord){
data.createUser = userinfo.value.loginCode;
}
data[record.value.isNewRecord ? 'createTime' : 'updateTime'] = formatToDateTime(new Date());
if (record.value.isNewRecord) {
data.createUser = userinfo.value.loginCode;
data.requirementNo = getRequirementNo();
}
data[record.value.isNewRecord ? 'createTime' : 'updateTime'] = formatToDateTime(new Date());
// console.log('submit', params, data, record);
const res = await myProjectRequirementSave(params, data);
showMessage(res.message);

View File

@@ -1,186 +0,0 @@
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
import { BasicColumn, BasicTableProps, FormProps } from '@jeesite/core/components/Table';
import { myProjectRequirementListData } from '@jeesite/biz/api/biz/myProjectRequirement';
const { t } = useI18n('biz.myProjectRequirement');
const modalProps = {
title: t('需求选择'),
};
const searchForm: FormProps<MyProjectRequirement> = {
baseColProps: { md: 8, lg: 6 },
labelWidth: 90,
schemas: [
{
label: t('记录时间起'),
field: 'createTime_gte',
component: 'DatePicker',
componentProps: {
format: 'YYYY-MM-DD HH:mm',
showTime: { format: 'HH:mm' },
},
},
{
label: t('记录时间止'),
field: 'createTime_lte',
component: 'DatePicker',
componentProps: {
format: 'YYYY-MM-DD HH:mm',
showTime: { format: 'HH:mm' },
},
},
{
label: t('需求编号'),
field: 'requirementNo',
component: 'Input',
},
{
label: t('需求标题'),
field: 'requirementTitle',
component: 'Input',
},
{
label: t('项目编号'),
field: 'projectId',
component: 'Input',
},
{
label: t('优先等级'),
field: 'priority',
component: 'Input',
},
{
label: t('需求状态'),
field: 'requirementStatus',
component: 'Input',
},
],
};
const tableColumns: BasicColumn<MyProjectRequirement>[] = [
{
title: t('记录时间'),
dataIndex: 'createTime',
key: 'a.create_time',
sorter: true,
width: 230,
align: 'left',
slot: 'firstColumn',
},
{
title: t('需求编号'),
dataIndex: 'requirementNo',
key: 'a.requirement_no',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('需求标题'),
dataIndex: 'requirementTitle',
key: 'a.requirement_title',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('项目编号'),
dataIndex: 'projectId',
key: 'a.project_id',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('详细内容'),
dataIndex: 'requirementContent',
key: 'a.requirement_content',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('优先等级'),
dataIndex: 'priority',
key: 'a.priority',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('需求状态'),
dataIndex: 'requirementStatus',
key: 'a.requirement_status',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('负责人员'),
dataIndex: 'handler',
key: 'a.handler',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('计划完成时间'),
dataIndex: 'planFinishTime',
key: 'a.plan_finish_time',
sorter: true,
width: 130,
align: 'center',
},
{
title: t('实际完成时间'),
dataIndex: 'actualFinishTime',
key: 'a.actual_finish_time',
sorter: true,
width: 130,
align: 'center',
},
{
title: t('备注'),
dataIndex: 'remark',
key: 'a.remark',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('创建人'),
dataIndex: 'createUser',
key: 'a.create_user',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('更新时间'),
dataIndex: 'updateTime',
key: 'a.update_time',
sorter: true,
width: 130,
align: 'center',
},
];
const tableProps: BasicTableProps = {
api: myProjectRequirementListData,
beforeFetch: (params) => {
params['isAll'] = true;
return params;
},
columns: tableColumns,
formConfig: searchForm,
rowKey: 'requirementId',
};
export default {
modalProps,
tableProps,
itemCode: 'requirementId',
itemName: 'requirementId',
isShowCode: false,
};

View File

@@ -42,7 +42,7 @@
const { meta } = unref(router.currentRoute);
const record = ref<MyProjectTask>({} as MyProjectTask);
const requirementListParams = ref<Recordable>({ projectId: '-1' });
const requirementListParams = ref<Recordable>({ projectId: '-1',requirementStatus: '2' });
const getTitle = computed(() => ({
icon: meta.icon || 'i-ant-design:book-outlined',

View File

@@ -1,194 +0,0 @@
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
import { BasicColumn, BasicTableProps, FormProps } from '@jeesite/core/components/Table';
import { myProjectTaskListData } from '@jeesite/biz/api/biz/myProjectTask';
const { t } = useI18n('biz.myProjectTask');
const modalProps = {
title: t('任务选择'),
};
const searchForm: FormProps<MyProjectTask> = {
baseColProps: { md: 8, lg: 6 },
labelWidth: 90,
schemas: [
{
label: t('记录时间起'),
field: 'createTime_gte',
component: 'DatePicker',
componentProps: {
format: 'YYYY-MM-DD HH:mm',
showTime: { format: 'HH:mm' },
},
},
{
label: t('记录时间止'),
field: 'createTime_lte',
component: 'DatePicker',
componentProps: {
format: 'YYYY-MM-DD HH:mm',
showTime: { format: 'HH:mm' },
},
},
{
label: t('任务名称'),
field: 'taskName',
component: 'Input',
},
{
label: t('项目标识'),
field: 'projectId',
component: 'Input',
},
{
label: t('需求标识'),
field: 'requirementId',
component: 'Input',
},
{
label: t('任务状态'),
field: 'taskStatus',
component: 'Input',
},
{
label: t('备注'),
field: 'remark',
component: 'Input',
},
],
};
const tableColumns: BasicColumn<MyProjectTask>[] = [
{
title: t('记录时间'),
dataIndex: 'createTime',
key: 'a.create_time',
sorter: true,
width: 230,
align: 'left',
slot: 'firstColumn',
},
{
title: t('任务名称'),
dataIndex: 'taskName',
key: 'a.task_name',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('项目标识'),
dataIndex: 'projectId',
key: 'a.project_id',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('需求标识'),
dataIndex: 'requirementId',
key: 'a.requirement_id',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('任务状态'),
dataIndex: 'taskStatus',
key: 'a.task_status',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('负责人员'),
dataIndex: 'handler',
key: 'a.handler',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('计划开始'),
dataIndex: 'planStartTime',
key: 'a.plan_start_time',
sorter: true,
width: 130,
align: 'center',
},
{
title: t('计划结束'),
dataIndex: 'planEndTime',
key: 'a.plan_end_time',
sorter: true,
width: 130,
align: 'center',
},
{
title: t('实际开始'),
dataIndex: 'actualStartTime',
key: 'a.actual_start_time',
sorter: true,
width: 130,
align: 'center',
},
{
title: t('实际结束'),
dataIndex: 'actualEndTime',
key: 'a.actual_end_time',
sorter: true,
width: 130,
align: 'center',
},
{
title: t('工时'),
dataIndex: 'workHours',
key: 'a.work_hours',
sorter: true,
width: 130,
align: 'right',
},
{
title: t('备注'),
dataIndex: 'remark',
key: 'a.remark',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('创建人员'),
dataIndex: 'createUser',
key: 'a.create_user',
sorter: true,
width: 130,
align: 'left',
},
{
title: t('更新时间'),
dataIndex: 'updateTime',
key: 'a.update_time',
sorter: true,
width: 130,
align: 'center',
},
];
const tableProps: BasicTableProps = {
api: myProjectTaskListData,
beforeFetch: (params) => {
params['isAll'] = true;
return params;
},
columns: tableColumns,
formConfig: searchForm,
rowKey: 'taskId',
};
export default {
modalProps,
tableProps,
itemCode: 'taskId',
itemName: 'taskId',
isShowCode: false,
};

View File

@@ -1,58 +1,78 @@
<template>
<div class="my-screen-page">
<header class="my-screen-panel my-screen-panel--header">
<ChartTop />
</header>
<section class="my-screen-bottom">
<div class="my-screen-left">
<section class="my-screen-panel my-screen-left-top">左上区域</section>
<section class="my-screen-left-middle">
<div class="my-screen-panel">左中左区域</div>
<div class="my-screen-panel">左中区域</div>
</section>
<section class="my-screen-left-bottom">
<div class="my-screen-panel">左下左区域</div>
<div class="my-screen-panel">左下区域</div>
</section>
</div>
<aside class="my-screen-right">
<section class="my-screen-panel my-screen-right-top">右上区域</section>
<section class="my-screen-panel my-screen-right-middle">区域</section>
<section class="my-screen-panel my-screen-right-bottom">区域</section>
</aside>
</section>
</div>
<PageWrapper :contentFullHeight="true" :dense="true" title="false" contentClass="my-screen-page-wrapper">
<div class="my-screen-page">
<header class="my-screen-panel my-screen-panel--header">
<ChartTop />
</header>
<section class="my-screen-bottom">
<div class="my-screen-left">
<section class="my-screen-panel my-screen-left-top">左上区域</section>
<section class="my-screen-left-middle">
<div class="my-screen-panel">左中区域</div>
<div class="my-screen-panel">左中右区域</div>
</section>
<section class="my-screen-left-bottom">
<div class="my-screen-panel">左下区域</div>
<div class="my-screen-panel">左下右区域</div>
</section>
</div>
<aside class="my-screen-right">
<section class="my-screen-panel my-screen-right-top">区域</section>
<section class="my-screen-panel my-screen-right-middle">区域</section>
<section class="my-screen-panel my-screen-right-bottom">右下区域</section>
</aside>
</section>
</div>
</PageWrapper>
</template>
<script lang="ts" setup name="BizMyScreen">
import ChartTop from './components/ChartTop.vue';
import { PageWrapper } from '@jeesite/core/components/Page';
import ChartTop from './components/ChartTop.vue';
</script>
<style lang="less" scoped>
@dark-bg: #141414;
@desktop-page-gap: 12px;
@desktop-page-padding: 0;
@desktop-card-radius: 10px;
@desktop-card-border: 1px solid rgb(226 232 240);
@desktop-card-shadow: 0 1px 3px rgb(15 23 42 / 0.06);
@desktop-dark-border: rgb(51 65 85);
.my-screen-page-wrapper {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
padding: 0 !important;
overflow: hidden !important;
background: transparent !important;
}
.my-screen-page {
display: flex;
flex: 1;
flex-direction: column;
width: 100%;
height: 100%;
min-height: 0;
display: flex;
flex-direction: column;
gap: 12px;
padding: 0;
gap: @desktop-page-gap;
padding: @desktop-page-padding;
box-sizing: border-box;
overflow: hidden;
background: transparent;
border-radius: 10px;
border-radius: @desktop-card-radius;
}
.my-screen-panel {
min-height: 0;
padding: 8px 12px 12px;
box-sizing: border-box;
border-radius: 10px;
border: 1px solid rgb(226 232 240);
border-radius: @desktop-card-radius;
border: @desktop-card-border;
background: rgb(255, 255, 255);
box-shadow: 0 1px 3px rgb(15 23 42 / 0.06);
box-shadow: @desktop-card-shadow;
display: flex;
align-items: center;
justify-content: center;
@@ -72,9 +92,9 @@
flex: 1 1 90%;
min-height: 0;
display: flex;
gap: 12px;
gap: @desktop-page-gap;
background: transparent;
border-radius: 10px;
border-radius: @desktop-card-radius;
}
.my-screen-left {
@@ -83,7 +103,7 @@
min-height: 0;
display: flex;
flex-direction: column;
gap: 12px;
gap: @desktop-page-gap;
}
.my-screen-right {
@@ -92,7 +112,7 @@
min-height: 0;
display: flex;
flex-direction: column;
gap: 12px;
gap: @desktop-page-gap;
}
.my-screen-left-top {
@@ -104,7 +124,7 @@
flex: 1 1 0;
min-height: 0;
display: flex;
gap: 12px;
gap: @desktop-page-gap;
}
.my-screen-left-middle .my-screen-panel,
@@ -131,9 +151,8 @@
background: @dark-bg !important;
}
html[data-theme='dark'] .my-screen-panel,
html[data-theme='dark'] .my-screen-panel {
border-color: rgb(51 65 85);
border-color: @desktop-dark-border;
background: @dark-bg !important;
color: rgb(203 213 225);
box-shadow: none;
@@ -145,8 +164,9 @@
@media (max-width: 768px) {
.my-screen-page {
height: auto;
min-height: 100%;
flex: 1 1 auto;
height: 100%;
min-height: 0;
}
.my-screen-panel--header {