Explorar o código

feat: 新增oss-upload上传组件

lanjianrong %!s(int64=4) %!d(string=hai) anos
pai
achega
d05e02ecc6

+ 8 - 0
src/components/OssUpload/ali-oss.ts

@@ -0,0 +1,8 @@
+import request from "@/utils/common/request"
+
+
+// 获取签名
+export async function getSignature() {
+  const { data } = await request.get('')
+  return data
+}

+ 103 - 0
src/components/OssUpload/index.tsx

@@ -0,0 +1,103 @@
+import consts from '@/utils/consts'
+import { InboxOutlined } from '@ant-design/icons'
+import { message, Modal, Upload } from 'antd'
+import { ModalProps } from 'antd/lib/modal'
+import { UploadChangeParam } from 'antd/lib/upload'
+import { UploadFile } from 'antd/lib/upload/interface'
+import React, { useState } from 'react'
+import { getSignature } from './ali-oss'
+interface iOSSData {
+  dir: string;
+  expire: string;
+  host: string;
+  accessId: string;
+  policy: string;
+  signature: string;
+}
+// interface iUploadModalProps  {
+//   onFileChange: () => void
+//   modalProps: ModalProps
+// }
+const UploadModal:React.FC<ModalProps> = (props) => {
+  const [ OSSData, setOssData ] = useState<iOSSData>({
+    dir: '',
+    expire: '',
+    host: '',
+    accessId: '',
+    policy: '',
+    signature: ''
+  })
+  const { Dragger } = Upload
+  // 上传文件改变时的状态
+  const onChange = (info: UploadChangeParam) => {
+    const { status } = info.file
+    if (status !== 'uploading') {
+      console.log(info.file, info.fileList)
+    }
+    if (status === 'done') {
+      message.success(`${info.file.name} file uploaded successfully.`)
+    } else if (status === 'error') {
+      message.error(`${info.file.name} file upload failed.`)
+    }
+  }
+  // 初始化、获取签名
+  const initOssData = async () => {
+    try {
+      const { code = -1, data = {} } = await getSignature()
+      if (code === consts.RET_CODE.SUCCESS) {
+        setOssData({ ...OSSData, ...data })
+      } else {
+        message.error("获取签名失败,请联系管理员!")
+
+      }
+    } catch (error) {
+      message.error(error)
+    }
+  }
+
+  // 额外参数、oss签名
+  const getExtraData = (file: UploadFile) => {
+    return {
+      key: file.url,
+      OSSAccessKeyId: OSSData.accessId,
+      policy: OSSData.policy,
+      Signature: OSSData.signature
+    }
+  }
+
+  const transformFile = (file: any) => {
+    file.url = OSSData.dir + file.name
+    return file
+  }
+  // 上传前的回调
+  const beforeUpload = () => {
+    const expire = parseInt(OSSData.expire) * 1000
+    if (expire < Date.now()) {
+      initOssData()
+    }
+    return true
+  }
+  return (
+    <Modal {...props}>
+      <Dragger
+        name="file"
+        action={OSSData.host}
+        multiple={true}
+        onChange={onChange}
+        beforeUpload={beforeUpload}
+        data={getExtraData}
+        transformFile={transformFile}
+        >
+        <p className="ant-upload-drag-icon">
+        <InboxOutlined />
+        </p>
+        <p className="ant-upload-text">请点击或者拖动文件至此区域进行上传</p>
+        <p className="ant-upload-hint">
+          支持单文件/多文件上传。附件大小最大为30MB!
+        </p>
+      </Dragger>
+    </Modal>
+  )
+}
+
+export default UploadModal

+ 26 - 0
src/layout/NavSide/index.module.scss

@@ -1,4 +1,30 @@
 .layout {
+  ::-webkit-scrollbar {
+    width: 6px;
+    height: 6px;
+  }
+
+  ::-webkit-scrollbar-track {
+    width: 6px;
+    background: rgba(#101f1c, 0.1);
+    -webkit-border-radius: 2em;
+    -moz-border-radius: 2em;
+    border-radius: 2em;
+  }
+
+  ::-webkit-scrollbar-thumb {
+    min-height: 28px;
+    background-color: rgba(#101f1c, 0.5);
+    background-clip: padding-box;
+    -webkit-border-radius: 2em;
+    -moz-border-radius: 2em;
+    border-radius: 2em;
+  }
+
+  ::-webkit-scrollbar-thumb:hover {
+    background-color: rgba(#101f1c, 1);
+  }
+
   :global(.ant-table-thead .ant-table-cell) {
     padding: 0.4rem;
     text-align: center !important;

+ 18 - 0
src/pages/Management/Info/api.ts

@@ -0,0 +1,18 @@
+import request from "@/utils/common/request"
+
+/**
+ * 获取项目信息
+ */
+export async function apiProjectInfo() {
+  const { data } = await request.get('/api/projectSetting/project')
+  return data
+}
+
+/**
+ * 保存项目信息
+ * @param name - 项目名称
+ */
+export async function apiSaveProjectInfo(name: string) {
+  const { data } = await request.post('/api/projectSetting/project/save', { name })
+  return data
+}

+ 10 - 0
src/pages/Management/Info/index.module.scss

@@ -0,0 +1,10 @@
+.projectInfo {
+  display: flex;
+  width: 100%;
+  margin-top: 1rem;
+  .formContent {
+    flex: 0 0 41.666667%;
+    max-width: 41.666667%;
+    padding: 0 15px;
+  }
+}

+ 71 - 5
src/pages/Management/Info/index.tsx

@@ -1,17 +1,83 @@
 import Header from '@/components/Header'
 import Slot from '@/components/Header/slot'
-import { Button } from 'antd'
-import React from 'react'
-
+import consts from '@/utils/consts'
+import { dayjsFomrat } from '@/utils/util'
+import { Button, Form, Input, message } from 'antd'
+import React, { useEffect, useState } from 'react'
+import { useActivate } from 'react-activation'
+import { apiProjectInfo, apiSaveProjectInfo } from './api'
+import styles from './index.module.scss'
+interface iProjectInfo {
+  projectName: string;
+  code: string;
+  createTime: number;
+  mobile: string;
+  name: string;
+}
 export default function Info() {
+  const [ form ] = Form.useForm()
+const [ loading, setLoading ] = useState<boolean>(false)
+  const [ projectInfo, setProjectInfo ] = useState<iProjectInfo>({
+    projectName: "",
+    code: "",
+    createTime: 0,
+    mobile: "",
+    name: ""
+  })
+  useEffect(() => {
+    initData()
+  }, [])
+  useActivate(() => {
+    initData()
+  })
+  useEffect(() => {
+    form.setFieldsValue(
+      { ...projectInfo,
+        createTime: dayjsFomrat(projectInfo.createTime, "YYYY-MM-DD"),
+        mobile: projectInfo.mobile.replace(/(\d{3})(\d{4})(\d{4})/, "$1****$3") +  `  (${projectInfo.name})`
+      })
+  }, [ projectInfo ])
+  const initData = async () => {
+    const { code = -1, data = {} } = await apiProjectInfo()
+    if (code === consts.RET_CODE.SUCCESS) {
+      setProjectInfo(data)
+    }
+  }
+  const saveProjectName = async () => {
+    setLoading(true)
+    const newName = form.getFieldValue("projectName")
+    if (newName !== projectInfo.projectName) {
+      const { code = -1 } = await apiSaveProjectInfo(newName)
+      if (code === consts.RET_CODE.SUCCESS) {
+        message.success("更新成功!")
+        initData()
+      }
+    }
+    setLoading(false)
+  }
   return (
     <div className="wrap-contaniner">
       <Header title="项目信息">
         <Slot position="right">
-          <Button type="primary" size="small">保存修改</Button>
+          <Button type="primary" size="small" loading={loading} onClick={() => saveProjectName()}>保存修改</Button>
         </Slot>
       </Header>
-      <div className="pi-flex-column"></div>
+      <div className={styles.projectInfo}>
+        <Form form={form} className={styles.formContent} layout="vertical" size="small">
+          <Form.Item name="code" label="项目编号">
+            <Input disabled></Input>
+          </Form.Item>
+          <Form.Item name="projectName" label="项目名称">
+            <Input></Input>
+          </Form.Item>
+          <Form.Item name="mobile" label="管理员">
+            <Input disabled></Input>
+          </Form.Item>
+          <Form.Item name="createTime" label="创建时间">
+            <Input disabled></Input>
+          </Form.Item>
+        </Form>
       </div>
+    </div>
   )
 }