diff --git a/src/views/tasklist/TaskList.api.ts b/src/views/tasklist/TaskList.api.ts
index c503aaf..9d0648e 100644
--- a/src/views/tasklist/TaskList.api.ts
+++ b/src/views/tasklist/TaskList.api.ts
@@ -45,6 +45,7 @@ enum Api {
listAllByMainId = '/tasklist/taskListDetial/listAllByMainId',
myResponsibleTasks = '/tasklist/taskList/myResponsibleTasks',
myFollowedTasks = '/tasklist/taskList/myFollowedTasks',
+ getCurrentUserSecurityLevel = '/tasklist/taskList/getCurrentUserSecurityLevel',
}
export const getExportUrl = Api.exportXls;
@@ -150,3 +151,5 @@ export const listAllByMainId = (params) => defHttp.get({ url: Api.listAllByMainI
export const myResponsibleTasks = () => defHttp.get({ url: Api.myResponsibleTasks });
export const myFollowedTasks = () => defHttp.get({ url: Api.myFollowedTasks });
+
+export const getCurrentUserSecurityLevel = () => defHttp.get({ url: Api.getCurrentUserSecurityLevel });
diff --git a/src/views/tasklist/TaskList.data.ts b/src/views/tasklist/TaskList.data.ts
index 7d2894e..40c50d6 100644
--- a/src/views/tasklist/TaskList.data.ts
+++ b/src/views/tasklist/TaskList.data.ts
@@ -2,6 +2,7 @@ import { BasicColumn } from '/@/components/Table';
import { FormSchema } from '/@/components/Table';
import { JVxeTypes, JVxeColumn } from '/@/components/jeecg/JVxeTable/types';
import type { TaskListGroup } from './types';
+import { getAvailableSecretLevels } from './types';
export const columns: BasicColumn[] = [
{
@@ -300,14 +301,32 @@ export const createTaskFormSchema: FormSchema[] = [
},
];
-export const createListFormSchema: FormSchema[] = [
- {
- label: '清单名称',
- field: 'tasklistName',
- component: 'Input',
- required: true,
- },
-];
+export function getCreateListFormSchema(userSecurityLevel: number): FormSchema[] {
+ if (!userSecurityLevel) userSecurityLevel = 3;
+ return [
+ {
+ label: '清单名称',
+ field: 'tasklistName',
+ component: 'Input',
+ required: true,
+ componentProps: {
+ placeholder: '请输入清单名称',
+ },
+ },
+ {
+ label: '密级',
+ field: 'secretLevel',
+ component: 'Select',
+ required: true,
+ defaultValue: 1,
+ componentProps: {
+ getPopupContainer: () => document.body,
+ options: getAvailableSecretLevels(userSecurityLevel),
+ placeholder: '请选择密级',
+ },
+ },
+ ];
+}
export const mockTaskListGroups: TaskListGroup[] = [
{
diff --git a/src/views/tasklist/components/CollaboratorModal.vue b/src/views/tasklist/components/CollaboratorModal.vue
index 2e6788d..a3f536b 100644
--- a/src/views/tasklist/components/CollaboratorModal.vue
+++ b/src/views/tasklist/components/CollaboratorModal.vue
@@ -12,7 +12,7 @@
-
+
{{ (item.username || '?').charAt(0) }}
@@ -26,7 +26,7 @@
所有者
-
+
{{ item.permission === '2' ? '可编辑' : '可阅读' }}
@@ -54,7 +54,7 @@
-
+
暂无协作人
@@ -68,10 +68,10 @@
-
@@ -84,7 +84,7 @@
@@ -96,18 +96,20 @@
添加协作人
-
完成
+
完成
+
+
diff --git a/src/views/tasklist/components/TaskAttachmentUpload.vue b/src/views/tasklist/components/TaskAttachmentUpload.vue
new file mode 100644
index 0000000..07f132a
--- /dev/null
+++ b/src/views/tasklist/components/TaskAttachmentUpload.vue
@@ -0,0 +1,462 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ file.fileName }}
+
+ {{ getSecretLevelLabel(file.secretLevel) }}
+
+
+ 待保存
+
+
{{ formatFileSize(file.fileSize) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/tasklist/components/TaskAttachmentUploadModal.vue b/src/views/tasklist/components/TaskAttachmentUploadModal.vue
new file mode 100644
index 0000000..5f5c8fc
--- /dev/null
+++ b/src/views/tasklist/components/TaskAttachmentUploadModal.vue
@@ -0,0 +1,253 @@
+
+
+
+
+
+
+
+
+ {{ option.label }}
+
+
+
+
+
+
+
+
+
+ {{ multiple ? '选择文件(可多选)' : '选择文件' }}
+
+
+
+
+
+
+
+
+ {{ idx + 1}}. {{ f.name }}({{ formatFileSize(f.size) }})
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/tasklist/components/TaskContent.vue b/src/views/tasklist/components/TaskContent.vue
index 9dcef26..f842bc4 100644
--- a/src/views/tasklist/components/TaskContent.vue
+++ b/src/views/tasklist/components/TaskContent.vue
@@ -36,6 +36,9 @@
@@ -273,6 +277,16 @@
-
+
+
+ {{ list.secretText }}
+
+ -
+
{{ getFormattedCreateTime(list) }}
@@ -790,6 +804,7 @@
:user-ids="userSelectModalCurrentIds"
:user-names="userSelectModalCurrentNames"
:multiple="true"
+ :secret-level="currentList?.secretLevel || 1"
@confirm="onUserSelectConfirm"
/>
@@ -804,7 +819,7 @@
import UserSelectModal from './UserSelectModal.vue';
import { useUserStore } from '/@/store/modules/user';
import { useMessage } from '/@/hooks/web/useMessage';
- import { FIELD_CONFIG, GROUP_OPTIONS, SORT_OPTIONS, MAX_TASK_DEPTH, FILTER_FIELD_CONFIGS, FILTER_OPERATOR_LABELS } from '../types';
+ import { FIELD_CONFIG, GROUP_OPTIONS, SORT_OPTIONS, MAX_TASK_DEPTH, FILTER_FIELD_CONFIGS, FILTER_OPERATOR_LABELS, SECRET_LEVEL_COLOR } from '../types';
import { PRIORITY_OPTIONS, getPriorityBg, getPriorityLabel, isOverdue } from '../utils/taskUtils';
import type {
TaskList,
@@ -1851,6 +1866,15 @@
gap: 8px;
}
+ .header-secret-badge {
+ font-size: 11px;
+ padding: 0 6px;
+ border-radius: 3px;
+ border: 1px solid;
+ line-height: 18px;
+ flex-shrink: 0;
+ }
+
.collaborator-bar {
display: flex;
align-items: center;
@@ -2150,6 +2174,9 @@
.content-body {
flex: 1;
overflow: auto;
+ display: flex;
+ flex-direction: column;
+ min-height: 0;
}
.task-group-header {
@@ -2651,6 +2678,21 @@
padding: 0 12px;
}
+ .list-group-col-secret {
+ width: 80px;
+ padding: 0 12px;
+ text-align: center;
+ }
+
+ .secret-badge-inline {
+ font-size: 11px;
+ padding: 1px 6px;
+ border-radius: 3px;
+ border: 1px solid;
+ line-height: 16px;
+ white-space: nowrap;
+ }
+
.list-group-col-time {
width: 160px;
padding: 0 12px;
diff --git a/src/views/tasklist/components/TaskDetailDrawer.vue b/src/views/tasklist/components/TaskDetailDrawer.vue
index 060f609..42db2f2 100644
--- a/src/views/tasklist/components/TaskDetailDrawer.vue
+++ b/src/views/tasklist/components/TaskDetailDrawer.vue
@@ -76,12 +76,19 @@
@@ -94,12 +101,19 @@
@@ -222,7 +236,14 @@
- 添加附件
+ 添加附件
+
@@ -323,32 +344,29 @@
-
+
+
将通知 0 人
-
-
-
+
@@ -357,7 +375,8 @@
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import Icon from '/@/components/Icon/index';
import AvatarDisplay from './AvatarDisplay.vue';
- import UserSelectModal from './UserSelectModal.vue';
+ import SzUserSelectBySecLevel from '/@/components/semri/userComponent/SzUserSelectBySecLevel.vue';
+ import TaskAttachmentUpload from './TaskAttachmentUpload.vue';
import TaskDateRangePicker from './TaskDateRangePicker.vue';
import draggable from 'vuedraggable';
import dayjs from 'dayjs';
@@ -412,16 +431,20 @@
const editingSubTaskValue = ref(null);
const editingSubTaskStartValue = ref(null);
const editingSubTaskEndValue = ref(null);
- const subTaskDatePickerOpen = ref(false);
const subTaskUserSelectId = ref('');
+ const subTaskDatePickerOpen = ref(false);
const drawerDatePickerVisible = ref(false);
+
const drawerDateEditMode = ref<'start' | 'end' | null>(null);
const drawerPickerEpoch = ref(0);
- const drawerUserSelectRef = ref();
+ const currentListSecretLevel = ref(1);
+
const drawerUserSelectType = ref<'assignee' | 'followers' | 'participant'>('assignee');
- const drawerUserSelectCurrentIds = ref('');
- const drawerUserSelectCurrentNames = ref('');
+ const drawerUserSelectCurrentIds = ref('');
+ const drawerUserSelectCurrentNames = ref('');
+ const userSelectModalRef = ref | null>(null);
+ const fileUploadRef = ref | null>(null);
const parentTask = computed(() => {
if (!taskData.value || !taskData.value.pid) return null;
@@ -508,6 +531,7 @@
taskData.value = data?.task ? { ...data.task } : null;
allTasks.value = data?.allTasks ? [...data.allTasks] : [];
isReadOnly.value = data?.readOnly === true;
+ currentListSecretLevel.value = data?.secretLevel || 1;
showNewSubTaskInput.value = false;
newSubTaskName.value = '';
editingTitle.value = false;
@@ -681,62 +705,71 @@
}
function openDrawerUserSelect(type: 'assignee' | 'followers' | 'participant') {
+ if (!taskData.value) return;
drawerUserSelectType.value = type;
if (type === 'assignee') {
- drawerUserSelectCurrentIds.value = taskData.value?.assigneeId || '';
- drawerUserSelectCurrentNames.value = taskData.value?.assigneeName || '';
+ drawerUserSelectCurrentIds.value = taskData.value.assigneeId || '';
+ drawerUserSelectCurrentNames.value = taskData.value.assigneeName || '';
} else if (type === 'participant') {
- drawerUserSelectCurrentIds.value = taskData.value?.participantId || '';
- drawerUserSelectCurrentNames.value = taskData.value?.participantName || '';
+ drawerUserSelectCurrentIds.value = taskData.value.participantId || '';
+ drawerUserSelectCurrentNames.value = taskData.value.participantName || '';
} else {
- drawerUserSelectCurrentIds.value = taskData.value?.followersId || '';
- drawerUserSelectCurrentNames.value = taskData.value?.followersName || '';
+ drawerUserSelectCurrentIds.value = taskData.value.followersId || '';
+ drawerUserSelectCurrentNames.value = taskData.value.followersName || '';
}
nextTick(() => {
- drawerUserSelectRef.value?.open();
+ userSelectModalRef.value?.open();
});
}
- function onDrawerUserSelectConfirm(userIds: string, userNames: string) {
+ function onUserSelectModalConfirm(userIds: string, userNames: string) {
if (subTaskUserSelectId.value) {
- emit('update-sub-task-fields', subTaskUserSelectId.value, {
- assigneeId: userIds,
- assigneeName: userNames,
- });
- const child = allTasks.value.find((t) => t.id === subTaskUserSelectId.value);
- if (child) {
- child.assigneeId = userIds;
- child.assigneeName = userNames;
- }
- subTaskUserSelectId.value = '';
- return;
+ onSubTaskUserSelectConfirm(userIds, userNames);
+ } else {
+ onDrawerUserSelectConfirm(userIds, userNames);
}
+ }
+
+ function onDrawerUserSelectConfirm(userIds: string, userNames: string) {
if (!taskData.value) return;
const type = drawerUserSelectType.value;
if (type === 'assignee') {
taskData.value.assigneeId = userIds;
taskData.value.assigneeName = userNames;
- autoSave();
} else if (type === 'participant') {
taskData.value.participantId = userIds;
taskData.value.participantName = userNames;
- autoSave();
} else {
taskData.value.followersId = userIds;
taskData.value.followersName = userNames;
- autoSave();
}
+ autoSave();
}
function openSubTaskUserSelect(child: TaskItem) {
subTaskUserSelectId.value = child.id;
drawerUserSelectCurrentIds.value = child.assigneeId || '';
drawerUserSelectCurrentNames.value = child.assigneeName || '';
+ drawerUserSelectType.value = 'assignee';
nextTick(() => {
- drawerUserSelectRef.value?.open();
+ userSelectModalRef.value?.open();
});
}
+ function onSubTaskUserSelectConfirm(userIds: string, userNames: string) {
+ if (!subTaskUserSelectId.value) return;
+ emit('update-sub-task-fields', subTaskUserSelectId.value, {
+ assigneeId: userIds,
+ assigneeName: userNames,
+ });
+ const child = allTasks.value.find((t) => t.id === subTaskUserSelectId.value);
+ if (child) {
+ child.assigneeId = userIds;
+ child.assigneeName = userNames;
+ }
+ subTaskUserSelectId.value = '';
+ }
+
function openSubTaskDateEditor(childId: string) {
editingSubTask.value = childId;
editingSubTaskField.value = 'dateRange';
@@ -780,6 +813,10 @@
showNewSubTaskInput.value = false;
}
}
+
+ function openFileUploadModal() {
+ fileUploadRef.value?.handleOpenUploadModal();
+ }