Răsfoiți Sursa

档案新增

wuheng 1 an în urmă
părinte
comite
7197596dda

+ 2 - 2
src/plugins/fast-crud/index.tsx

@@ -122,7 +122,7 @@ function install(app: App, options: FsSetupOpts = {}) {
   const uploaderOptions: FsUploaderOptions = {
     defaultType: 'form',
     form: {
-      action: 'http://www.docmirror.cn:7070/api/upload/form/upload',
+      action: '/upload/form/upload',
       name: 'file',
       withCredentials: false,
       uploadRequest: async props => {
@@ -144,7 +144,7 @@ function install(app: App, options: FsSetupOpts = {}) {
       async successHandle(ret: string) {
         // 上传完成后的结果处理, 此处应转换格式为{url:xxx,key:xxx}
         return {
-          url: `http://www.docmirror.cn:7070${ret}`,
+          url: ret,
           key: ret.replace('/api/upload/form/download?key=', '')
         };
       }

+ 64 - 0
src/views/archives/students/component/api.ts

@@ -49,3 +49,67 @@ export function getArchives(params: ArchivesParams): Promise<Service.RequestResu
 export function getFile(archiveNumber: string): Promise<Service.RequestResult<ArchivesRes>> {
   return request.get(`/archive/getTokenByArchiveNumber?archiveNumber=${archiveNumber}`);
 }
+
+export function upload(
+  fileType: string,
+  studentNumber: string,
+  file: object
+): Promise<Service.RequestResult<ArchivesRes>> {
+  return request.post(`/student/upload?fileType=${fileType}&studentNumber=${studentNumber}&file=${file}`);
+}
+
+// 参数接口
+export interface AddArchivesParams {
+  id?: number;
+  archiveNumber?: string;
+  studentNumber?: string;
+  filePath?: string;
+  arctype?: string;
+  remarks?: string;
+  filetype?: string;
+  createTime?: Record<string, unknown>;
+  modifyTime?: Record<string, unknown>;
+  validityTime?: Record<string, unknown>;
+  managerId?: number;
+  createDate?: Record<string, unknown>;
+  createUid?: number;
+}
+
+// 响应接口
+export interface AddArchivesRes {
+  status: boolean;
+  msg: string;
+  data: Record<string, unknown>;
+  code: number;
+}
+
+/**
+ * 添加学员档案
+ * @param {object} params EasArcArchives
+ * @param {number} params.id
+ * @param {string} params.archiveNumber 文件电子档案号
+ * @param {string} params.studentNumber 当前电子档案归属那一个学员档案下
+ * @param {string} params.filePath 文件存储的路径
+ * @param {string} params.arctype 档案类型
+ * @param {string} params.remarks 文件备注
+ * @param {string} params.filetype 文件类型
+ * @param {object} params.createTime 创建时间
+ * @param {object} params.modifyTime 修改时间
+ * @param {object} params.validityTime 档案有效期截至时间
+ * @param {number} params.managerId 档案归属负责人
+ * @param {object} params.createDate 档案创建时间, 用于文件归档用
+ * @param {number} params.createUid 创建用户ID
+ * @returns
+ */
+export function addArchives(params: AddArchivesParams): Promise<Service.RequestResult<ArchivesRes>> {
+  return request.post(`/student/addArchives`, params);
+}
+
+/**
+ * 删除档案
+ * @param {string} id
+ * @returns
+ */
+export function deleteArchives(id: number): Promise<Service.RequestResult<ArchivesRes>> {
+  return request.delete(`/student/delArchives/${id}`);
+}

+ 103 - 10
src/views/archives/students/component/crud.ts

@@ -1,7 +1,13 @@
 import type { CreateCrudOptionsRet, CreateCrudOptionsProps } from '@fast-crud/fast-crud';
+import type { FsUploaderFormRequestOptions } from '@fast-crud/fast-extends';
 import dayjs from 'dayjs';
 import { dict } from '@fast-crud/fast-crud';
-import { getArchives, getFile } from './api';
+import axios from 'axios';
+import { getServiceEnvConfig } from '~/.env-config';
+import type { AddArchivesParams } from './api';
+import { getArchives, getFile, addArchives, deleteArchives } from './api';
+const { url, proxyPattern } = getServiceEnvConfig(import.meta.env);
+const isHttpProxy = import.meta.env.VITE_HTTP_PROXY === 'Y';
 export default function createCrudOptions(crudOptionsProps: CreateCrudOptionsProps): CreateCrudOptionsRet {
   return {
     crudOptions: {
@@ -14,21 +20,41 @@ export default function createCrudOptions(crudOptionsProps: CreateCrudOptionsPro
           const { data } = await getArchives(query);
           return { records: data, total: 0, currentPage: page.offset, pageSize: page.limit };
         },
-        addRequest: () => {
-          return Promise.resolve(true);
+        addRequest: ({ form }) => {
+          if (!crudOptionsProps.context) {
+            return Promise.resolve(true);
+          }
+          if (!crudOptionsProps.context.studentNumber) {
+            crudOptionsProps.context.message.info('没有筛选人员的情况下 , 不允许上传档案!');
+            throw new Error('没有筛选人员的情况下 , 不允许上传档案');
+          }
+          return addArchives({
+            studentNumber: form.studentNumber,
+            filePath: form.filePath,
+            remarks: form.remarks,
+            filetype: form.filetype
+          });
         },
         editRequest: () => {
           return Promise.resolve(true);
         },
-        delRequest: () => {
-          return Promise.resolve(true);
+        delRequest: (ctx: { row: AddArchivesParams }) => {
+          const { row } = ctx;
+          if (!crudOptionsProps.context || !row.id) {
+            return Promise.resolve(true);
+          }
+          if (row.filetype === 'attendance' || row.filetype === 'scores' || row.filetype === 'prefile') {
+            crudOptionsProps.context.message.info('基础信息自动生成, 不能删除或者编辑!');
+            return Promise.resolve(true);
+          }
+          return deleteArchives(row.id);
         }
       },
       rowHandle: {
         show: true,
         buttons: {
           remove: {
-            show: false
+            show: true
           },
           edit: {
             show: false
@@ -58,7 +84,29 @@ export default function createCrudOptions(crudOptionsProps: CreateCrudOptionsPro
         show: false
       },
       actionbar: {
-        show: false
+        show: true
+      },
+      form: {
+        wrapper: {
+          draggable: false,
+          onOpen: () => {
+            if (!crudOptionsProps.context) {
+              return;
+            }
+            if (!crudOptionsProps.context.studentNumber) {
+              crudOptionsProps.context.message.info('没有筛选人员的情况下 , 不允许上传档案!');
+              throw new Error('没有筛选人员的情况下 , 不允许上传档案');
+            }
+          },
+          onOpened: async context => {
+            if (crudOptionsProps.context) {
+              crudOptionsProps.context.archivesForm = context.form;
+            }
+            if (!context.form.studentNumber) {
+              context.form.studentNumber = crudOptionsProps.context?.studentNumber;
+            }
+          }
+        }
       },
       search: {
         show: false
@@ -82,6 +130,9 @@ export default function createCrudOptions(crudOptionsProps: CreateCrudOptionsPro
           type: 'text',
           column: {
             align: 'center'
+          },
+          form: {
+            show: false
           }
         },
         filetype: {
@@ -90,13 +141,55 @@ export default function createCrudOptions(crudOptionsProps: CreateCrudOptionsPro
           dict: dict({
             data: [
               { value: 'avatar', label: '头像' },
-              { value: 'prefile', label: '个人资料' },
-              { value: 'scores', label: '考核' },
-              { value: 'attendance', label: '出勤' },
+              { value: 'prefile', disabled: true, label: '个人资料' },
+              { value: 'scores', disabled: true, label: '考核' },
+              { value: 'attendance', disabled: true, label: '出勤' },
               { value: 'other', label: '其他' }
             ]
           })
         },
+        filePath: {
+          title: '档案文件',
+          type: 'file-uploader',
+          form: {
+            component: {
+              limit: 1,
+              uploader: {
+                uploadRequest: async (props: FsUploaderFormRequestOptions) => {
+                  if (!crudOptionsProps.context) {
+                    return false;
+                  }
+                  if (!crudOptionsProps.context.archivesForm.filetype) {
+                    crudOptionsProps.context.message.info('请先选择类别, 在上传档案!');
+                    throw new Error('请先选择类别, 在上传档案!');
+                  }
+                  const action = isHttpProxy
+                    ? `${proxyPattern}/student/upload?fileType`
+                    : `${url}/student/upload?fileType`;
+                  const { file, onProgress } = props;
+                  const data = new FormData();
+                  data.append('file', file);
+                  data.append('fileType', crudOptionsProps.context.archivesForm.filetype);
+                  data.append('studentNumber', crudOptionsProps.context.archivesForm.studentNumber);
+                  const res = await axios.post(action, data, {
+                    headers: {
+                      'Content-Type': 'multipart/form-data'
+                    },
+                    timeout: 60000,
+                    onUploadProgress(progress) {
+                      onProgress({ percent: Math.round((progress.loaded / progress.total!) * 100) });
+                    }
+                  });
+                  // 上传完成后的结果,一般返回个url 或者key,具体看你的后台返回啥
+                  return res.data.data;
+                }
+              }
+            }
+          },
+          column: {
+            show: false
+          }
+        },
         remarks: {
           title: '备注',
           type: 'text',

+ 22 - 4
src/views/archives/students/component/index.vue

@@ -4,16 +4,32 @@
 
     <n-drawer v-model:show="active" default-width="80%" placement="left" resizable>
       <n-drawer-content title="在线预览文件">
+        <n-watermark
+          content="爱扣钉机密文件 禁止外泄!"
+          cross
+          fullscreen
+          :font-size="16"
+          :line-height="16"
+          :width="384"
+          :height="384"
+          :x-offset="12"
+          :y-offset="60"
+          :rotate="-15"
+        />
         <ExcelView v-if="fileType === 'XLSX'" :url="fileURL" />
-        <WordView v-if="fileType === 'DOCX'" :url="fileURL" />
-        <ImageView v-if="fileType === 'IMAGE'" :url="fileURL" />
-        <PdfView v-if="fileType === 'PDF'" :url="fileURL" />
+        <WordView v-else-if="fileType === 'DOCX'" :url="fileURL" />
+        <ImageView v-else-if="fileType === 'IMAGE'" :url="fileURL" />
+        <PdfView v-else-if="fileType === 'PDF'" :url="fileURL" />
+        <div v-else :url="fileURL">
+          <h1>当前文件不支持预览, 请下载后查看</h1>
+        </div>
       </n-drawer-content>
     </n-drawer>
   </div>
 </template>
 <script setup lang="ts">
 import { watch, ref } from 'vue';
+import { useMessage } from 'naive-ui';
 import { useFs } from '@fast-crud/fast-crud';
 import createCrudOptions from './crud';
 import ExcelView from './excelView.vue';
@@ -24,6 +40,7 @@ import PdfView from './pdfView.vue';
 const fileURL = ref<string>('');
 const fileType = ref<string>('');
 const active = ref<boolean>(false);
+const message = useMessage();
 
 const props = defineProps({
   studentNumber: {
@@ -33,6 +50,8 @@ const props = defineProps({
 });
 
 const context = {
+  message,
+  archivesForm: {},
   studentNumber: props.studentNumber,
   viewActiveFunc: (type: string, token: string) => {
     fileURL.value = `http://localhost:3200/proxy-pattern/archive/getFileByToken?archiveToken=${token}`;
@@ -42,7 +61,6 @@ const context = {
 };
 
 const { crudRef, crudBinding, crudExpose } = useFs({ createCrudOptions, context });
-
 watch(
   () => props.studentNumber,
   () => {

+ 6 - 1
src/views/archives/students/index.vue

@@ -22,7 +22,9 @@
         @search="handleSearch"
       />
     </div>
-    <ArchivesList :student-number="studentNumber" />
+    <div class="list-archives">
+      <ArchivesList :student-number="studentNumber" />
+    </div>
   </div>
 </template>
 <script setup lang="ts">
@@ -62,6 +64,9 @@ function goToList(value: string) {
   width: 26%;
   margin: 0 auto;
 }
+.list-archives {
+  height: calc(100% - 94px);
+}
 h1 {
   font-size: 36px;
 }