Przeglądaj źródła

修改名称、材料采集-新增弹窗

吴朋磊 2 tygodni temu
rodzic
commit
ac3df2efc6

+ 553 - 238
pages/materialCollection/taskOverview/components/index.vue

@@ -1,16 +1,43 @@
 <template>
-	<view class="page_publish" >
+	<view class="page_publish">
 		<commonHeader :title="isEdit ? '编辑任务' : '新建任务'" @back="goBack"></commonHeader>
 
 		<scroll-view scroll-y class="publish_content" :style="{ paddingTop: statusBarHeight + 160 + 'rpx', paddingBottom: safeAreaBottom + 'rpx' }">
 			<view class="form_item">
 				<view class="form_row form_row_type">
-					<text class="form_label">任务类型</text>
+					<text class="form_label">学年学期</text>
 					<view class="form_content">
-						<picker mode="selector" :range="typeOptions" :value="typeIndex" @change="handleTypeChange">
+						<picker mode="selector" :range="academicYearOptions" :value="academicYearIndex" @change="handleAcademicYearChange">
 							<view class="filter_item">
-								<text class="filter_text" :class="{ placeholder: typeIndex === -1 }">{{
-									formData.noticeType || '请选择类型' }}</text>
+								<text class="filter_text">{{ academicYearOptions[academicYearIndex] }}</text>
+								<uni-icons type="down" size="16" color="#999999"></uni-icons>
+							</view>
+						</picker>
+					</view>
+				</view>
+			</view>
+
+			<view class="form_item">
+				<view class="form_row form_row_type">
+					<text class="form_label">归属部门</text>
+					<view class="form_content">
+						<picker mode="selector" :range="categoryOptions" :value="categoryIndex" @change="handleCategoryChange">
+							<view class="filter_item">
+								<text class="filter_text">{{ categoryOptions[categoryIndex] }}</text>
+								<uni-icons type="down" size="16" color="#999999"></uni-icons>
+							</view>
+						</picker>
+					</view>
+				</view>
+			</view>
+
+			<view class="form_item">
+				<view class="form_row form_row_type">
+					<text class="form_label">材料类目</text>
+					<view class="form_content">
+						<picker mode="selector" :range="materialTypeOptions" :value="materialTypeIndex" @change="handleMaterialTypeChange">
+							<view class="filter_item">
+								<text class="filter_text">{{ materialTypeOptions[materialTypeIndex] }}</text>
 								<uni-icons type="down" size="16" color="#999999"></uni-icons>
 							</view>
 						</picker>
@@ -22,17 +49,17 @@
 				<view class="form_row form_row_type">
 					<text class="form_label">任务名称</text>
 					<view class="form_content">
-						<input type="text" class="form_input" v-model="formData.title" placeholder="请输入任务名称" />
+						<input type="text" class="form_input" v-model="formData.taskName" placeholder="请输入任务名称" />
 					</view>
 				</view>
 			</view>
 
 			<view class="form_item">
 				<view class="form_row">
-					<text class="form_label">任务内容</text>
+					<text class="form_label">采集要求</text>
 					<view class="form_content">
 						<view class="textarea_container">
-							<textarea class="form_textarea" v-model="formData.content" placeholder="请输入任务内容"
+							<textarea class="form_textarea" v-model="formData.collectRequirement" placeholder="请输入通知内容"
 								:maxlength="-1"></textarea>
 						</view>
 					</view>
@@ -40,56 +67,61 @@
 			</view>
 
 			<view class="form_item">
-				<view class="form_row">
-					<text class="form_label">发布时间</text>
-					<view class="form_content">
-						<custom-radio v-model="publishType" :options="publishOptions" />
-						<view v-if="publishType === 1" class="time_picker">
-							<uni-datetime-picker v-model="publishDateTime" type="datetime" :start="startTime"
-								:end="endTime" return-type="string" />
-						</view>
+				<view class="form_row form_row_type">
+					<text class="form_label">采集周期</text>
+					<view class="form_content date_range">
+						<picker mode="date" :value="formData.startTime" @change="onStartDateChange">
+							<view class="date_range_item">
+								<text class="date_text" :class="{ placeholder: !formData.startTime }">{{ formData.startTime || '开始日期' }}</text>
+								<uni-icons type="calendar" size="16" color="#999999"></uni-icons>
+							</view>
+						</picker>
+						<text class="date_separator">—</text>
+						<picker mode="date" :value="formData.endTime" @change="onEndDateChange">
+							<view class="date_range_item">
+								<text class="date_text" :class="{ placeholder: !formData.endTime }">{{ formData.endTime || '结束日期' }}</text>
+								<uni-icons type="calendar" size="16" color="#999999"></uni-icons>
+							</view>
+						</picker>
 					</view>
 				</view>
 			</view>
 
 			<view class="form_item">
-				<view class="form_row">
-					<text class="form_label">通知对象</text>
+				<view class="form_row form_row_type">
+					<text class="form_label">审核机制</text>
 					<view class="form_content">
-						<view class="object_row">
-							<view class="object_info" @click="goPersonList">
-								<text class="object_count">{{ objectTypeLabel || '请选择' }}</text>
-								<text class="object_count">已选{{ selectedCount }}人</text>
-							</view>
-							<view class="object_action" @click="selectObject">
-								<text class="action_text">选择通知对象</text>
-								<text class="action_arrow">></text>
-							</view>
-						</view>
+						<customRadio v-model="formData.auditMechanism" :options="auditOptions" />
 					</view>
 				</view>
 			</view>
 
-			<view class="form_item" v-if="isEdit">
-				<view class="form_row">
-					<text class="form_label">任务状态</text>
+			<view class="form_item" v-if="formData.auditMechanism === 1">
+				<view class="form_row form_row_type">
+					<text class="form_label">审核人</text>
 					<view class="form_content">
-						<view class="switch_row">
-							<view class="switch_container">
-								<switch :checked="formData.status" color="#2E64FA" @change="onStatusChange" />
-							</view>
-							<text class="switch_text">说明:关闭后通知不对通知对象显示</text>
+						<view class="auditor_row" @click="openAuditorDialog">
+							<text class="auditor_name" :class="{ placeholder: !formData.auditorName }">{{ formData.auditorName || '请选择审核人' }}</text>
+							<uni-icons type="down" size="16" color="#999999"></uni-icons>
 						</view>
 					</view>
 				</view>
 			</view>
 
-			<view class="form_item" v-if="isEdit && formData.status">
+			<view class="form_item">
 				<view class="form_row">
-					<text class="form_label">已读记录</text>
+					<text class="form_label">采集对象</text>
 					<view class="form_content">
-						<custom-radio v-model="saveRecord" :options="recordOptions" />
-						<text class="record_tip">说明:{{ saveRecord === 0 ? '已读记录将被保留' : '已读记录将被清空,重新记录' }}</text>
+						<view class="object_row">
+							<view class="object_info" @click="goPersonList">
+								<text class="object_count">{{ objectTypeLabel || '请选择' }}</text>
+								<text class="object_count">已选{{ selectedCount }}人</text>
+							</view>
+							<view class="object_action" @click="selectObject">
+								<text class="action_text">选择采集对象</text>
+								<text class="action_arrow">></text>
+							</view>
+						</view>
 					</view>
 				</view>
 			</view>
@@ -100,121 +132,290 @@
 				<text class="btn_text">确定</text>
 			</view>
 		</view>
+
+		<!-- 审核人搜索选择弹窗 -->
+		<customPopupDialog ref="auditorDialogRef" title="选择审核人" :showDialogFooter="false" @DialogConfirm="confirmAuditorSelection">
+			<view class="auditor_search_wrap">
+				<view class="auditor_search_box">
+					<uni-icons type="search" size="20" color="#999999"></uni-icons>
+					<input type="text" class="auditor_search_input" v-model="auditorSearchKey" placeholder="请输入搜索关键字"
+						@confirm="searchAuditors" @input="handleAuditorSearchInput" />
+					<text v-if="auditorSearchKey" class="auditor_search_clear" @click="clearAuditorSearch">
+						<uni-icons type="clear" size="18" color="#999999"></uni-icons>
+					</text>
+				</view>
+				<scroll-view scroll-y class="auditor_list">
+					<view v-if="auditorSearchLoading" class="auditor_loading">
+						<text>加载中...</text>
+					</view>
+					<view v-else-if="auditorListFiltered.length === 0" class="auditor_empty">
+						<noData :tipText="'暂无搜索结果'" />
+					</view>
+					<view v-else class="auditor_list_content">
+						<view v-for="(item, idx) in auditorListFiltered" :key="idx"
+							class="auditor_list_item"
+							:class="{ active: selectedAuditor && selectedAuditor.teacherId === item.teacherId }"
+							@click="selectAuditor(item)">
+							<view class="auditor_item_info">
+								<text class="auditor_item_name">{{ item.teacherName }}</text>
+								<text v-if="item.teacherAccount" class="auditor_item_account">账号:{{ item.teacherAccount
+									}}</text>
+							</view>
+							<view v-if="selectedAuditor && selectedAuditor.teacherId === item.teacherId"
+								class="auditor_item_check">
+								<uni-icons type="checkmarkempty" size="22" color="#2E64FA"></uni-icons>
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+				<view class="auditor_dialog_footer">
+					<view class="auditor_dialog_btn cancel_btn" @click="closeAuditorDialog">
+						<text>取消</text>
+					</view>
+					<view class="auditor_dialog_btn confirm_btn" @click="confirmAuditorSelection">
+						<text>确定</text>
+					</view>
+				</view>
+			</view>
+		</customPopupDialog>
 	</view>
 </template>
 
 <script setup>
-import { ref, reactive, onMounted } from 'vue';
+import { ref, reactive, onMounted, computed } from 'vue';
 import { onLoad, onShow } from '@dcloudio/uni-app';
 import uniIcons from '@/uni_modules/uni-icons/components/uni-icons/uni-icons.vue';
-import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue';
-import overviewApi from '@/reqApi/overview.js';
 import notification from '@/reqApi/notification.js';
 import CustomRadio from '@/components/customRadio.vue';
 import CommonHeader from '@/components/commonHeader.vue';
+import CustomPopupDialog from '@/components/customPopupDialog.vue';
+import NoData from '@/components/noData.vue';
 import { useSafeArea } from '@/common/safeArea';
 
 const { statusBarHeight, safeAreaBottom, initSafeArea } = useSafeArea();
 
-const showTypePicker = ref(false);
-const publishType = ref(0);
 const isEdit = ref(false);
-const saveRecord = ref(0);
-const typeIndex = ref(-1);
-const typeData = ref([]);
-const typeOptions = ref([]);
-
-const getCurrentDateTime = () => {
-	const now = new Date();
-	const year = now.getFullYear();
-	const month = String(now.getMonth() + 1).padStart(2, '0');
-	const day = String(now.getDate()).padStart(2, '0');
-	const hours = String(now.getHours()).padStart(2, '0');
-	const minutes = String(now.getMinutes()).padStart(2, '0');
-	const seconds = String(now.getSeconds()).padStart(2, '0');
-	return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
-};
+const editId = ref('');
 
-const publishDateTime = ref(getCurrentDateTime());
-const startTime = ref('2024-01-01 00:00:00');
-const endTime = ref('2030-12-31 23:59:59');
+const academicYearIndex = ref(0);
+const academicYearOptions = ref(['']);
+const academicYearIds = ref(['']);
+const academicYearCodes = ref(['']);
 
-const publishOptions = [
-	{ label: '立即发布', value: 0 },
-	{ label: '预约发布', value: 1 }
-];
+const categoryIndex = ref(0);
+const categoryOptions = ref(['全部分类']);
+const categoryData = ref([]);
+
+const materialTypeIndex = ref(0);
+const materialTypeOptions = ref(['全部类目']);
+
+// 审核人弹窗相关
+const auditorDialogRef = ref(null);
+const auditorSearchKey = ref('');
+const auditorSearchLoading = ref(false);
+const auditorListFull = ref([]);
+const selectedAuditor = ref(null);
+let auditorSearchTimer = null;
 
-const recordOptions = [
-	{ label: '保存', value: 0 },
-	{ label: '不保存', value: 1 }
+const auditorListFiltered = computed(() => {
+	return auditorListFull.value;
+});
+
+const auditOptions = [
+	{ label: '需审核', value: 1 },
+	{ label: '无审核', value: 0 }
 ];
 
 const formData = reactive({
-	title: '',
-	noticeType: '',
-	content: '',
-	status: true
+	schoolYearName: '',
+	schoolYearId: '',
+	schoolYearCode: '',
+	departmentName: '',
+	departmentId: '',
+	materialCategoryName: '',
+	materialCategoryId: '',
+	taskName: '',
+	collectRequirement: '',
+	startTime: '',
+	endTime: '',
+	auditMechanism: 0,
+	auditorName: '',
+	auditorId: ''
 });
 
 const selectedCount = ref(0);
 const selectedUsers = ref([]);
-const schoolYearId = ref('');
-const noticeTypeId = ref('');
 const objectTypeLabel = ref('');
-const editId = ref('');
 const originalNoticeType = ref(0);
 
-const fetchNoticeTypeList = async () => {
+const fetchAcademicYearList = async () => {
+	try {
+		const res = await notification.getSchoolYearList();
+		if (res.data && Array.isArray(res.data)) {
+			const names = res.data.map(item => item.schoolYearName);
+			const ids = res.data.map(item => item.id);
+			const codes = res.data.map(item => item.schoolYearCode);
+			academicYearOptions.value = names;
+			academicYearIds.value = ids;
+			academicYearCodes.value = codes;
+			if (res.data.length > 0) {
+				academicYearIndex.value = 0;
+				formData.schoolYearName = res.data[0].schoolYearName;
+				formData.schoolYearId = res.data[0].id;
+				formData.schoolYearCode = res.data[0].schoolYearCode;
+			}
+		}
+	} catch (error) {
+		console.error('获取学年学期列表失败:', error);
+	}
+};
+
+const fetchCategoryList = async () => {
+	try {
+		const res = await notification.getCategoryList();
+		if (res.data && Array.isArray(res.data)) {
+			categoryData.value = res.data;
+			const categoryNames = res.data.map(item => item.categoryName || item.name);
+			categoryOptions.value = ['全部分类', ...categoryNames];
+			categoryIndex.value = 0;
+			materialTypeOptions.value = ['全部类目'];
+			formData.departmentName = '';
+			formData.departmentId = '';
+			formData.materialCategoryName = '';
+			formData.materialCategoryId = '';
+		}
+	} catch (error) {
+		console.error('获取归属部门列表失败:', error);
+	}
+};
+
+const searchAuditors = async () => {
+	auditorSearchLoading.value = true;
 	try {
-		const res = await overviewApi.noticeTypeList();
+		const res = await notification.getAuditorList(auditorSearchKey.value || '');
 		if (res.data && Array.isArray(res.data)) {
-			typeData.value = res.data.map(item => ({
-				id: item.id,
-				name: item.name
+			auditorListFull.value = res.data.map(item => ({
+				teacherId: item.teacherId || item.id,
+				teacherName: item.teacherName || item.name,
+				teacherAccount: item.teacherAccount || item.accountName || item.userAccount || ''
 			}));
-			typeOptions.value = typeData.value.map(item => item.name);
+		} else {
+			auditorListFull.value = [];
 		}
 	} catch (error) {
-		console.error('获取任务类型失败:', error);
+		console.error('搜索审核人失败:', error);
+		auditorListFull.value = [];
+	} finally {
+		auditorSearchLoading.value = false;
 	}
 };
 
+const handleAuditorSearchInput = () => {
+	if (auditorSearchTimer) {
+		clearTimeout(auditorSearchTimer);
+	}
+	auditorSearchTimer = setTimeout(() => {
+		searchAuditors();
+	}, 500);
+};
+
+const clearAuditorSearch = () => {
+	auditorSearchKey.value = '';
+	searchAuditors();
+};
+
+const openAuditorDialog = () => {
+	auditorDialogRef.value.OpenDialog('bottom');
+	// 初始化选中状态
+	if (formData.auditorId) {
+		selectedAuditor.value = {
+			teacherId: formData.auditorId,
+			teacherName: formData.auditorName
+		};
+	} else {
+		selectedAuditor.value = null;
+	}
+	auditorSearchKey.value = '';
+	auditorListFull.value = [];
+	searchAuditors();
+};
+
+const closeAuditorDialog = () => {
+	auditorDialogRef.value.CloseDialog();
+};
+
+const selectAuditor = (item) => {
+	selectedAuditor.value = item;
+};
+
+const confirmAuditorSelection = () => {
+	if (!selectedAuditor.value) {
+		uni.showToast({ title: '请选择审核人', icon: 'none' });
+		return;
+	}
+	formData.auditorName = selectedAuditor.value.teacherName;
+	formData.auditorId = selectedAuditor.value.teacherId;
+	closeAuditorDialog();
+};
+
 onMounted(() => {
 	initSafeArea();
 });
 
 onLoad(async (options) => {
-	await fetchNoticeTypeList();
+	await Promise.all([
+		fetchAcademicYearList(),
+		fetchCategoryList()
+	]);
 
 	if (options && options.id) {
 		isEdit.value = true;
 		editId.value = options.id;
-		fetchNoticeDetail(options.id);
+		fetchTaskDetail(options.id);
 	}
 });
 
-const fetchNoticeDetail = async (id) => {
+const fetchTaskDetail = async (id) => {
 	try {
 		const res = await notification.find_collection_task_target_list({ id });
 		if (res.data) {
 			const data = res.data;
-			formData.title = data.taskName || data.noticeName || '';
+			formData.taskName = data.taskName || '';
 			const content = data.noticeContent || data.content || '';
-			formData.content = content.replace(/<[^>]+>/g, '');
-			formData.status = data.isClose !== true;
-			noticeTypeId.value = data.typeId || data.noticeTypeId || '';
-			
-			const typeIndexVal = typeData.value.findIndex(item => item.id === (data.typeId || data.noticeTypeId));
-			typeIndex.value = typeIndexVal >= 0 ? typeIndexVal : -1;
-			if (typeIndexVal >= 0) {
-				formData.noticeType = typeData.value[typeIndexVal].name;
+			formData.collectRequirement = content.replace(/<[^>]+>/g, '');
+			formData.startTime = data.startTime || '';
+			formData.endTime = data.endTime || '';
+			formData.auditMechanism = data.auditMechanism ? 1 : 0;
+			formData.auditorId = data.auditorId || '';
+			formData.auditorName = data.auditorName || '';
+			formData.departmentName = data.departmentName || '';
+			formData.materialCategoryName = data.materialCategoryName || '';
+			formData.schoolYearName = data.schoolYearName || '';
+
+			if (data.departmentId) {
+				formData.departmentId = data.departmentId;
+				const idx = categoryData.value.findIndex(item => item.id === data.departmentId);
+				if (idx >= 0) {
+					categoryIndex.value = idx + 1;
+					const selectedCategory = categoryData.value[idx];
+					const childList = selectedCategory?.childList || [];
+					materialTypeOptions.value = ['全部类目', ...childList.map(child => child.categoryName || child.name)];
+				}
 			}
-			
-			publishType.value = data.sendTimeType === 2 ? 1 : 0;
-			publishDateTime.value = data.releaseTime || getCurrentDateTime();
-			
-			saveRecord.value = data.isSave === true ? 0 : 1;
-			
+
+			if (data.materialCategory) {
+				formData.materialCategoryId = data.materialCategory;
+				if (categoryIndex.value > 0) {
+					const selectedCategory = categoryData.value[categoryIndex.value - 1];
+					const childList = selectedCategory?.childList || [];
+					const materialIdx = childList.findIndex(item => item.id === data.materialCategory);
+					if (materialIdx >= 0) {
+						materialTypeIndex.value = materialIdx + 1;
+						formData.materialCategoryName = childList[materialIdx].categoryName || childList[materialIdx].name || '';
+					}
+				}
+			}
+
 			if (data.noticeType) {
 				const typeMap = {
 					1: '按部门',
@@ -226,13 +427,13 @@ const fetchNoticeDetail = async (id) => {
 				objectTypeLabel.value = typeMap[data.noticeType] || '';
 				originalNoticeType.value = data.noticeType;
 			}
-			
+
 			if (data.userList && Array.isArray(data.userList)) {
 				selectedUsers.value = data.userList.map(user => ({
 					id: user.userId || user.id,
-					name: user.thirdName,
+					name: user.thirdName || user.name,
 					userId: user.userId,
-					thirdCode: user.thirdCode || user.userAccount || user.teacherId || user.studentCode || '',
+					thirdCode: user.thirdCode || user.userAccount || '',
 					userAccount: user.userAccount || user.thirdCode,
 					departmentName: user.departmentName || '',
 					groupName: user.groupName || '',
@@ -281,26 +482,66 @@ onShow(() => {
 	}
 });
 
-const handleTypeChange = (e) => {
-	typeIndex.value = e.detail.value;
-	const selectedItem = typeData.value[typeIndex.value];
-	if (selectedItem) {
-		formData.noticeType = selectedItem.name;
-		noticeTypeId.value = selectedItem.id;
-	}
+const handleAcademicYearChange = (e) => {
+	const idx = e.detail.value;
+	academicYearIndex.value = idx;
+	formData.schoolYearName = academicYearOptions.value[idx];
+	formData.schoolYearId = academicYearIds.value[idx];
+	formData.schoolYearCode = academicYearCodes.value[idx];
 };
 
-const goBack = () => {
-	uni.navigateBack();
+const handleCategoryChange = (e) => {
+	categoryIndex.value = e.detail.value;
+	materialTypeIndex.value = 0;
+	if (categoryIndex.value === 0) {
+		materialTypeOptions.value = ['全部类目'];
+		formData.departmentName = '';
+		formData.departmentId = '';
+		formData.materialCategoryName = '';
+		formData.materialCategoryId = '';
+	} else {
+		const selectedCategory = categoryData.value[categoryIndex.value - 1];
+		const categoryName = selectedCategory?.categoryName || selectedCategory?.name || '';
+		formData.departmentName = categoryName;
+		formData.departmentId = selectedCategory?.id || '';
+		const childList = selectedCategory?.childList || [];
+		materialTypeOptions.value = ['全部类目', ...childList.map(child => child.categoryName || child.name)];
+		formData.materialCategoryName = '';
+		formData.materialCategoryId = '';
+	}
 };
 
-const onStatusChange = (e) => {
-	formData.status = e.detail.value;
-	if (formData.status) {
-		saveRecord.value = 0;
+const handleMaterialTypeChange = (e) => {
+	materialTypeIndex.value = e.detail.value;
+	if (categoryIndex.value === 0) {
+		formData.materialCategoryName = '';
+		formData.materialCategoryId = '';
+	} else {
+		const selectedCategory = categoryData.value[categoryIndex.value - 1];
+		const childList = selectedCategory?.childList || [];
+		if (materialTypeIndex.value === 0) {
+			formData.materialCategoryName = '';
+			formData.materialCategoryId = '';
+		} else {
+			const selectedChild = childList[materialTypeIndex.value - 1];
+			formData.materialCategoryName = selectedChild?.categoryName || selectedChild?.name || '';
+			formData.materialCategoryId = selectedChild?.id || '';
+		}
 	}
 };
 
+const onStartDateChange = (e) => {
+	formData.startTime = e.detail.value;
+};
+
+const onEndDateChange = (e) => {
+	formData.endTime = e.detail.value;
+};
+
+const goBack = () => {
+	uni.navigateBack();
+};
+
 const selectObject = () => {
 	const lastSelection = {
 		tab: objectTypeLabel.value,
@@ -324,17 +565,6 @@ const goPersonList = () => {
 	uni.navigateTo({ url: '/pages/materialCollection/taskOverview/components/personList' });
 };
 
-const getCurrentTime = () => {
-	const now = new Date();
-	const year = now.getFullYear();
-	const month = String(now.getMonth() + 1).padStart(2, '0');
-	const day = String(now.getDate()).padStart(2, '0');
-	const hours = String(now.getHours()).padStart(2, '0');
-	const minutes = String(now.getMinutes()).padStart(2, '0');
-	const seconds = String(now.getSeconds()).padStart(2, '0');
-	return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
-};
-
 const getNoticeTypeValue = (tab) => {
 	const map = {
 		'按部门': 1,
@@ -347,56 +577,67 @@ const getNoticeTypeValue = (tab) => {
 };
 
 const handleSave = async () => {
-	if (!formData.title) {
+	if (!formData.schoolYearId) {
+		uni.showToast({ title: '请选择学年学期', icon: 'none' });
+		return;
+	}
+	if (!formData.departmentId) {
+		uni.showToast({ title: '请选择归属部门', icon: 'none' });
+		return;
+	}
+	if (!formData.materialCategoryId) {
+		uni.showToast({ title: '请选择材料类目', icon: 'none' });
+		return;
+	}
+	if (!formData.taskName) {
 		uni.showToast({ title: '请输入任务名称', icon: 'none' });
 		return;
 	}
-	if (!formData.content) {
-		uni.showToast({ title: '请输入任务内容', icon: 'none' });
+	if (!formData.collectRequirement) {
+		uni.showToast({ title: '请输入采集要求', icon: 'none' });
+		return;
+	}
+	if (!formData.startTime || !formData.endTime) {
+		uni.showToast({ title: '请选择采集周期', icon: 'none' });
+		return;
+	}
+	if (formData.auditMechanism === 1 && !formData.auditorId) {
+		uni.showToast({ title: '请选择审核人', icon: 'none' });
 		return;
 	}
 	if (!objectTypeLabel.value) {
-		uni.showToast({ title: '请选择通知对象', icon: 'none' });
+		uni.showToast({ title: '请选择采集对象', icon: 'none' });
 		return;
 	}
 	if (selectedUsers.value.length === 0) {
-		uni.showToast({ title: '请选择通知人员', icon: 'none' });
+		uni.showToast({ title: '请选择采集人员', icon: 'none' });
 		return;
 	}
-	
-	if (!schoolYearId.value) {
-		try {
-			const res = await overviewApi.findSchoolYear();
-			if (res.data && res.data.length > 0) {
-				schoolYearId.value = res.data[0].id;
-			}
-		} catch (error) {
-			console.error('获取学年失败:', error);
-			uni.showToast({ title: '获取学年信息失败', icon: 'none' });
-			return;
-		}
-	}
-	
+
 	uni.showLoading({ title: '保存中...' });
-	
+
 	try {
 		const objectType = getNoticeTypeValue(objectTypeLabel.value);
 		const params = {
-			typeId: noticeTypeId.value || '',
-			noticeName: formData.title,
-			noticeContent: btoa(unescape(encodeURIComponent(formData.content))),
-			sendTimeType: publishType.value + 1,
-			releaseTime: publishType.value === 0 ? getCurrentTime() : publishDateTime.value,
+			schoolYearCode: formData.schoolYearCode,
+			schoolYearId: formData.schoolYearId,
+			departmentId: formData.departmentId,
+			materialCategory: formData.materialCategoryId,
+			taskName: formData.taskName,
+			noticeContent: btoa(unescape(encodeURIComponent(formData.collectRequirement))),
+			startTime: formData.startTime,
+			endTime: formData.endTime,
+			auditMechanism: formData.auditMechanism,
+			auditorId: formData.auditorId,
+			auditorName: formData.auditorName,
 			noticeType: objectType,
-			isClose: isEdit.value ? !formData.status : false,
-			isSave: isEdit.value ? (saveRecord.value === 0) : false,
 			fileList: []
 		};
-		
+
 		if (isEdit.value && editId.value) {
 			params.id = editId.value;
 		}
-		
+
 		const userList = selectedUsers.value.map(user => {
 			return {
 				userType: objectType === 5 ? 2 : 1,
@@ -412,12 +653,12 @@ const handleSave = async () => {
 				roleName: user.roleName || ''
 			};
 		});
-		
+
 		if (userList.length > 0) {
 			params.userList = userList;
 		}
-		
-		const res = await overviewApi.save_notices(params);
+
+		const res = await notification.save_collection_task(params);
 		if (res.code === 200) {
 			uni.showToast({ title: '保存成功', icon: 'success' });
 			setTimeout(() => {
@@ -525,28 +766,6 @@ const handleSave = async () => {
 		border: 2rpx solid #E9E9E9;
 	}
 
-	.form_select {
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
-		padding: 16rpx;
-		background-color: #F5F7FA;
-		border-radius: 8rpx;
-		border: 2rpx solid #DCDFE6;
-
-		.select_text {
-			font-size: 28rpx;
-			color: #333333;
-		}
-
-		.select_right {
-			.select_arrow {
-				font-size: 28rpx;
-				color: #999999;
-			}
-		}
-	}
-
 	.textarea_container {
 		position: relative;
 
@@ -556,58 +775,41 @@ const handleSave = async () => {
 			font-size: 28rpx;
 			color: #333333;
 			line-height: 1.6;
-			padding: 14rpx 24rpx 56rpx 24rpx;
+			padding: 14rpx 24rpx;
 			background-color: #FFFFFF;
 			border-radius: 8rpx;
 			box-sizing: border-box;
 			border: 2rpx solid #E9E9E9;
 		}
+	}
+
+	.date_range {
+		display: flex;
+		align-items: center;
+		gap: 16rpx;
 
-		.textarea_actions {
-			position: absolute;
-			bottom: 13rpx;
-			right: 16rpx;
+		.date_range_item {
 			display: flex;
 			align-items: center;
 			gap: 8rpx;
+			padding: 0 16rpx;
+			height: 72rpx;
+			background-color: #FFFFFF;
+			border-radius: 8rpx;
+			border: 2rpx solid #DCDFE6;
 
-			.full_icon {
-				width: 28rpx;
-				height: 28rpx;
-			}
-
-			.action_text {
-				font-weight: 400;
+			.date_text {
 				font-size: 28rpx;
-				color: #2E64FA;
+				color: #333333;
+				&.placeholder {
+					color: #909399;
+				}
 			}
 		}
-	}
-
-	.time_picker {
-		margin-top: 20rpx;
-		min-width: 300rpx;
-		height: 68rpx;
-		float: right;
-
-		:deep(.uni-date-x--border) {
-			height: 68rpx;
-		}
-
-		:deep(.uni-date-x) {
-			padding: 0 16rpx;	
-			height: 48rpx;
-		}
-
-		:deep(.uni-date-x--text) {
-			font-weight: 400;
-			font-size: 28rpx;
-			color: #333333;
-		}
 
-		:deep(.uni-date__x-input) {
+		.date_separator {
 			font-size: 28rpx;
-			color: #333333;
+			color: #999999;
 		}
 	}
 
@@ -644,35 +846,148 @@ const handleSave = async () => {
 		}
 	}
 
-	.object_tip {
-		font-size: 24rpx;
-		color: #F56C6C;
-		margin-top: 12rpx;
-		display: block;
+	.auditor_row {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding: 0 16rpx;
+		height: 72rpx;
+		background-color: #FFFFFF;
+		border-radius: 8rpx;
+		border: 2rpx solid #E9E9E9;
+		box-sizing: border-box;
+
+		.auditor_name {
+			font-size: 28rpx;
+			color: #333333;
+			flex: 1;
+			overflow: hidden;
+			text-overflow: ellipsis;
+			white-space: nowrap;
+			&.placeholder {
+				color: #909399;
+			}
+		}
 	}
+}
 
-	.switch_row {
+// 审核人搜索弹窗样式
+.auditor_search_wrap {
+	padding: 24rpx;
+	box-sizing: border-box;
+
+	.auditor_search_box {
 		display: flex;
-		flex-direction:column;
+		align-items: center;
+		height: 72rpx;
+		background: #F5F7FA;
+		border-radius: 36rpx;
+		padding: 0 24rpx;
+		margin-bottom: 24rpx;
+		gap: 16rpx;
 
-		.switch_container {
-			transform: scale(0.8);
-			transform-origin: left center;
+		.auditor_search_input {
+			flex: 1;
+			font-size: 28rpx;
+			color: #333333;
+			background: transparent;
+			height: 72rpx;
+			line-height: 72rpx;
 		}
 
-		.switch_text {
-			font-weight: 400;
+		.auditor_search_clear {
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			width: 40rpx;
+			height: 40rpx;
+		}
+	}
+
+	.auditor_list {
+		height: 600rpx;
+
+		.auditor_loading {
+			text-align: center;
+			padding: 60rpx 0;
 			font-size: 28rpx;
 			color: #999999;
 		}
+
+		.auditor_empty {
+			padding: 60rpx 0;
+		}
+
+		.auditor_list_content {
+			.auditor_list_item {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				padding: 24rpx 16rpx;
+				border-bottom: 2rpx solid #F3F3F3;
+				&:last-child {
+					border-bottom: none;
+				}
+				&.active {
+					background-color: rgba(46, 100, 250, 0.05);
+				}
+
+				.auditor_item_info {
+					flex: 1;
+					display: flex;
+					flex-direction: column;
+					gap: 8rpx;
+
+					.auditor_item_name {
+						font-size: 30rpx;
+						color: #333333;
+						font-weight: 500;
+					}
+
+					.auditor_item_account {
+						font-size: 24rpx;
+						color: #999999;
+					}
+				}
+
+				.auditor_item_check {
+					width: 44rpx;
+					height: 44rpx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
+			}
+		}
 	}
 
-	.record_tip {
-		font-weight: 400;
-		font-size: 28rpx;
-		color: #999999;
-		margin-top: 16rpx;
-		display: block;
+	.auditor_dialog_footer {
+		display: flex;
+		gap: 24rpx;
+		padding-top: 24rpx;
+		margin-top: 12rpx;
+		border-top: 2rpx solid #F3F3F3;
+
+		.auditor_dialog_btn {
+			flex: 1;
+			height: 88rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			border-radius: 12rpx;
+			font-size: 30rpx;
+			font-weight: 500;
+		}
+
+		.cancel_btn {
+			background: #F0F2F9;
+			color: #606266;
+		}
+
+		.confirm_btn {
+			background: #2E64FA;
+			color: #FFFFFF;
+		}
 	}
 }
 

+ 4 - 1
reqApi/notification.js

@@ -17,7 +17,10 @@ const notification = {
     find_teacher_task_target_list(data) {
         return request.post('/api/v1/teaching_plan/collect/task_target/find_teacher_task_target_list', data)
     },
-
+    // 审核人列表
+    getAuditorList(data) {
+        return request.get(`/api/v1/teaching_plan/collect/target_loading/query_teacher_info?accountName=${data}`)
+    },
 }
 
 export default notification