|
|
@@ -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;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|