|
@@ -25,7 +25,7 @@
|
|
|
Authorization: 'JWT ' + Session.get('token')
|
|
|
}"
|
|
|
:multiple="false"
|
|
|
- :on-success="(response, file) => handleUploadSuccess(response, file, scope)"
|
|
|
+ :on-success="(response: any, file: any) => handleUploadSuccess(response, file, scope)"
|
|
|
:drag="false"
|
|
|
:show-file-list="false">
|
|
|
<el-button type="primary" icon="plus">上传</el-button>
|
|
@@ -200,6 +200,38 @@
|
|
|
</span>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <!-- 添加排序对话框 -->
|
|
|
+ <el-dialog
|
|
|
+ v-model="sortDialogVisible"
|
|
|
+ title="修改排序"
|
|
|
+ width="400px"
|
|
|
+ destroy-on-close
|
|
|
+ >
|
|
|
+ <el-form
|
|
|
+ ref="sortFormRef"
|
|
|
+ :model="sortForm"
|
|
|
+ :rules="sortFormRules"
|
|
|
+ label-width="100px"
|
|
|
+ >
|
|
|
+ <el-form-item label="排序值" prop="sequence_number">
|
|
|
+ <el-input-number
|
|
|
+ v-model="sortForm.sequence_number"
|
|
|
+ :min="0"
|
|
|
+ :max="9999"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <div class="form-helper">数值越小,排序越靠前</div>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <span class="dialog-footer">
|
|
|
+ <el-button @click="sortDialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="submitSortForm">保存</el-button>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</fs-page>
|
|
|
</template>
|
|
|
|
|
@@ -215,7 +247,7 @@ import { Document, Delete, View, Printer } from '@element-plus/icons-vue';
|
|
|
import { successNotification } from '/@/utils/message';
|
|
|
import DocumentTreeCom from './components/DocumentTreeCom/index.vue';
|
|
|
import DocumentFormCom from './components/DocumentFormCom/index.vue';
|
|
|
-import { GetDocumentTree, DeleteDocumentCategory, UpdateDocument } from './api';
|
|
|
+import { GetDocumentTree, DeleteDocumentCategory, UpdateDocument ,UpdateSequence} from './api';
|
|
|
import { useRouter } from 'vue-router';
|
|
|
/* import { print } from '/@/utils/print'; */
|
|
|
|
|
@@ -223,15 +255,29 @@ const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
|
|
|
|
|
|
const router = useRouter();
|
|
|
|
|
|
-// 存储已上传文件信息
|
|
|
-const uploadedFile = ref(null);
|
|
|
+// 添加 uploadedFile 类型定义
|
|
|
+interface UploadedFileInfo {
|
|
|
+ name: string;
|
|
|
+ file_path: string;
|
|
|
+ file_type: string;
|
|
|
+ file_size: number;
|
|
|
+ doc_type: string;
|
|
|
+ category: string;
|
|
|
+ status: boolean;
|
|
|
+ doc_desc: string;
|
|
|
+ version: string;
|
|
|
+ file: string;
|
|
|
+}
|
|
|
+
|
|
|
+// 修改 uploadedFile 的类型
|
|
|
+const uploadedFile = ref<UploadedFileInfo | null>(null);
|
|
|
|
|
|
// 树形结构相关数据
|
|
|
const documentTreeData = ref([]);
|
|
|
const documentTreeCacheData = ref([]);
|
|
|
const drawerVisible = ref(false);
|
|
|
const drawerFormData = ref({});
|
|
|
-const documentTreeRef = ref(null);
|
|
|
+const documentTreeRef = ref<DocumentTreeRef | null>(null);
|
|
|
|
|
|
// 添加一个响应式变量来存储当前选中的分类ID
|
|
|
const selectedCategoryId = ref('');
|
|
@@ -274,13 +320,15 @@ const subtitleInfo = ref({
|
|
|
|
|
|
// 视频上传对话框状态
|
|
|
const videoUploadDialogVisible = ref(false);
|
|
|
-const currentRow = ref(null);
|
|
|
+const currentRow = ref<QuestionRow | null>(null);
|
|
|
|
|
|
// 添加字幕内容输入框
|
|
|
const subtitleContent = ref('');
|
|
|
|
|
|
// 添加表单引用
|
|
|
-const videoFormRef = ref(null);
|
|
|
+const videoFormRef = ref<{
|
|
|
+ validate: (callback: (valid: boolean) => void) => void;
|
|
|
+} | null>(null);
|
|
|
|
|
|
// 添加表单数据对象
|
|
|
const videoForm = ref({
|
|
@@ -295,6 +343,37 @@ const videoFormRules = {
|
|
|
]
|
|
|
};
|
|
|
|
|
|
+// 添加排序对话框相关状态
|
|
|
+const sortDialogVisible = ref(false);
|
|
|
+const sortForm = ref({
|
|
|
+ sequence_number: 0
|
|
|
+});
|
|
|
+const sortFormRules = {
|
|
|
+ sequence_number: [
|
|
|
+ { required: true, message: '请输入排序值', trigger: 'blur' },
|
|
|
+ { type: 'number', message: '排序值必须为数字', trigger: 'blur' }
|
|
|
+ ]
|
|
|
+};
|
|
|
+const sortFormRef = ref<any>(null);
|
|
|
+
|
|
|
+// 添加类型定义
|
|
|
+interface DocumentTreeRef {
|
|
|
+ treeRef?: {
|
|
|
+ currentNode?: {
|
|
|
+ parent?: {
|
|
|
+ data: any;
|
|
|
+ };
|
|
|
+ };
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+// 修改 currentRow 的类型
|
|
|
+interface QuestionRow {
|
|
|
+ id?: number;
|
|
|
+ question_id?: string | number;
|
|
|
+ sequence_number?: number;
|
|
|
+}
|
|
|
+
|
|
|
// 获取文档树数据
|
|
|
const getTreeData = () => {
|
|
|
GetDocumentTree({}).then((ret: any) => {
|
|
@@ -333,7 +412,7 @@ const handleTreeClick = (record: any) => {
|
|
|
// 处理文档分类的新增或编辑
|
|
|
const handleUpdateDocument = (type: any, record: any) => {
|
|
|
if (type === 'update' && record) {
|
|
|
- const parentData = documentTreeRef.value?.treeRef?.currentNode.parent.data || {};
|
|
|
+ const parentData = documentTreeRef.value?.treeRef?.currentNode?.parent?.data || {};
|
|
|
documentTreeCacheData.value = [parentData];
|
|
|
drawerFormData.value = record;
|
|
|
}
|
|
@@ -341,7 +420,7 @@ const handleUpdateDocument = (type: any, record: any) => {
|
|
|
};
|
|
|
|
|
|
// 关闭抽屉
|
|
|
-const handleDrawerClose = (type) => {
|
|
|
+const handleDrawerClose = (type: string) => {
|
|
|
if (type === 'submit') {
|
|
|
getTreeData();
|
|
|
}
|
|
@@ -399,9 +478,7 @@ const handleUploadSuccess = (response: any, uploadFile: any, scope: any) => {
|
|
|
|
|
|
// 刷新列表时传递category参数
|
|
|
crudExpose.doRefresh({
|
|
|
- form: {
|
|
|
- category: selectedCategoryId.value
|
|
|
- }
|
|
|
+ category: selectedCategoryId.value
|
|
|
});
|
|
|
};
|
|
|
|
|
@@ -453,15 +530,14 @@ const previewFile = (fileData: any) => {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 获取文件类型
|
|
|
const fileType = fileData.file_type || '';
|
|
|
-
|
|
|
+ const filePath = fileData.file;
|
|
|
const previewUrl = `/#/preview?url=${encodeURIComponent(filePath)}&type=${fileType}`;
|
|
|
window.open(previewUrl, '_blank');
|
|
|
};
|
|
|
|
|
|
// 处理查看详情
|
|
|
-const handleViewDetail = async (event) => {
|
|
|
+const handleViewDetail = async (event: any) => {
|
|
|
const row = event.detail || event;
|
|
|
try {
|
|
|
// 可以选择直接使用传入的行数据,或者重新请求完整数据
|
|
@@ -478,7 +554,7 @@ const handleViewDetail = async (event) => {
|
|
|
};
|
|
|
|
|
|
// 获取文档类型名称
|
|
|
-const getDocTypeName = (docTypeId) => {
|
|
|
+const getDocTypeName = (docTypeId: number | string) => {
|
|
|
if (!docTypeId) return '';
|
|
|
const docTypeDict = [
|
|
|
{ value: 1, label: '合同文档' },
|
|
@@ -492,23 +568,23 @@ const getDocTypeName = (docTypeId) => {
|
|
|
};
|
|
|
|
|
|
// 获取分类名称
|
|
|
-const getCategoryName = (categoryId) => {
|
|
|
+const getCategoryName = (categoryId: number | string) => {
|
|
|
if (!categoryId) return '';
|
|
|
const categoryDict = (window as any).__categoryDict || [];
|
|
|
- const category = categoryDict.find(item => item.id === categoryId);
|
|
|
+ const category = categoryDict.find((item: any) => item.id === categoryId);
|
|
|
return category ? category.name : categoryId;
|
|
|
};
|
|
|
|
|
|
// 获取项目名称
|
|
|
-const getProjectName = (projectId) => {
|
|
|
+const getProjectName = (projectId: number | string) => {
|
|
|
if (!projectId) return '';
|
|
|
const projectDict = (window as any).__projectDict || [];
|
|
|
- const project = projectDict.find(item => item.id === projectId);
|
|
|
+ const project = projectDict.find((item: any) => item.id === projectId);
|
|
|
return project ? project.name : projectId;
|
|
|
};
|
|
|
|
|
|
// 预览详情中的文件
|
|
|
-const previewDetailFile = (fileData) => {
|
|
|
+const previewDetailFile = (fileData: any) => {
|
|
|
if (!fileData || !fileData.file_path) {
|
|
|
ElMessage.error('文件路径无效');
|
|
|
return;
|
|
@@ -546,7 +622,7 @@ const handlePrint = () => {
|
|
|
};
|
|
|
|
|
|
// 视频上传前的验证
|
|
|
-const beforeVideoUpload = (file) => {
|
|
|
+const beforeVideoUpload = (file: any) => {
|
|
|
const isVideo = file.type.startsWith('video/');
|
|
|
const isLt500M = file.size / 1024 / 1024 < 500;
|
|
|
|
|
@@ -562,7 +638,7 @@ const beforeVideoUpload = (file) => {
|
|
|
};
|
|
|
|
|
|
// 字幕上传前的验证
|
|
|
-const beforeSubtitleUpload = (file) => {
|
|
|
+const beforeSubtitleUpload = (file: any) => {
|
|
|
const validExtensions = ['.srt', '.vtt', '.ass'];
|
|
|
const extension = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
|
|
|
const isValidType = validExtensions.includes(extension);
|
|
@@ -580,7 +656,7 @@ const beforeSubtitleUpload = (file) => {
|
|
|
};
|
|
|
|
|
|
// 修改视频上传成功处理函数
|
|
|
-const handleVideoUploadSuccess = (response, file) => {
|
|
|
+const handleVideoUploadSuccess = (response: any, file: any) => {
|
|
|
console.log('response', response);
|
|
|
console.log('file', file);
|
|
|
|
|
@@ -640,7 +716,7 @@ const handleVideoUploadSuccess = (response, file) => {
|
|
|
};
|
|
|
|
|
|
// 修改字幕上传成功处理函数
|
|
|
-const handleSubtitleUploadSuccess = (response, file) => {
|
|
|
+const handleSubtitleUploadSuccess = (response: any, file: any) => {
|
|
|
if (response && response.data) {
|
|
|
subtitleInfo.value = {
|
|
|
url: response.data.bucket_url,
|
|
@@ -671,7 +747,7 @@ const handleUploadError = () => {
|
|
|
};
|
|
|
|
|
|
// 处理打开视频上传对话框
|
|
|
-const handleOpenVideoUploadDialog = (event) => {
|
|
|
+const handleOpenVideoUploadDialog = (event: any) => {
|
|
|
const row = event.detail;
|
|
|
if (row) {
|
|
|
currentRow.value = row;
|
|
@@ -693,7 +769,7 @@ const handleOpenVideoUploadDialog = (event) => {
|
|
|
const submitVideoForm = () => {
|
|
|
if (!videoFormRef.value) return;
|
|
|
|
|
|
- videoFormRef.value.validate(async (valid) => {
|
|
|
+ videoFormRef.value.validate(async (valid: boolean) => {
|
|
|
if (valid) {
|
|
|
try {
|
|
|
if (!currentRow.value || !currentRow.value.id) {
|
|
@@ -749,6 +825,71 @@ const submitVideoForm = () => {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+// 处理打开排序对话框
|
|
|
+const handleOpenSortDialog = (event: any) => {
|
|
|
+ const row = event.detail;
|
|
|
+ if (row) {
|
|
|
+ currentRow.value = row;
|
|
|
+ sortForm.value.sequence_number = row.sequence_number || 0;
|
|
|
+ sortDialogVisible.value = true;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 修改提交排序表单函数
|
|
|
+const submitSortForm = () => {
|
|
|
+ if (!sortFormRef.value) return;
|
|
|
+
|
|
|
+ sortFormRef.value.validate(async (valid: boolean) => {
|
|
|
+ if (valid) {
|
|
|
+ try {
|
|
|
+ if (!currentRow.value || !currentRow.value.question_id) {
|
|
|
+ ElMessage.error('当前选中的题目信息无效');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取当前职位ID
|
|
|
+ const positionId = selectedCategoryId.value;
|
|
|
+ if (!positionId) {
|
|
|
+ ElMessage.error('未选择职位分类');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建符合新格式的更新数据
|
|
|
+ const updateData = {
|
|
|
+ position_id: positionId,
|
|
|
+ questions: [
|
|
|
+ {
|
|
|
+ question_id: currentRow.value.question_id,
|
|
|
+ sequence_number: sortForm.value.sequence_number
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ tenant_id: 1
|
|
|
+ };
|
|
|
+
|
|
|
+ console.log('提交的排序数据:', updateData);
|
|
|
+
|
|
|
+ const response = await UpdateSequence(updateData);
|
|
|
+
|
|
|
+ if (response && response.code === 2000) {
|
|
|
+ ElMessage.success('排序修改成功');
|
|
|
+ sortDialogVisible.value = false;
|
|
|
+
|
|
|
+ // 刷新列表
|
|
|
+ crudExpose.doRefresh();
|
|
|
+ } else {
|
|
|
+ ElMessage.error(response?.msg || '保存失败');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('保存排序信息时出错:', error);
|
|
|
+ ElMessage.error('保存失败,请重试');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ ElMessage.warning('请输入有效的排序值');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
// 页面加载时获取数据
|
|
|
onMounted(() => {
|
|
|
getTreeData();
|
|
@@ -779,12 +920,14 @@ onMounted(() => {
|
|
|
// 添加全局事件监听器
|
|
|
window.addEventListener('viewDocumentDetail', handleViewDetail);
|
|
|
window.addEventListener('openVideoUploadDialog', handleOpenVideoUploadDialog);
|
|
|
+ window.addEventListener('openSortDialog', handleOpenSortDialog);
|
|
|
});
|
|
|
|
|
|
// 添加 onBeforeUnmount 钩子移除事件监听器
|
|
|
onBeforeUnmount(() => {
|
|
|
window.removeEventListener('viewDocumentDetail', handleViewDetail);
|
|
|
window.removeEventListener('openVideoUploadDialog', handleOpenVideoUploadDialog);
|
|
|
+ window.removeEventListener('openSortDialog', handleOpenSortDialog);
|
|
|
});
|
|
|
</script>
|
|
|
|