mirror of
https://github.com/vran-dev/databasir.git
synced 2025-08-08 18:25:17 +08:00
feature: support export document (#11)
* feat: add document export api * feat: update frontend resource
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.databasir.api;
|
||||
|
||||
import com.databasir.common.JsonData;
|
||||
import com.databasir.common.SystemException;
|
||||
import com.databasir.core.domain.document.data.DatabaseDocumentResponse;
|
||||
import com.databasir.core.domain.document.data.DatabaseDocumentVersionResponse;
|
||||
import com.databasir.core.domain.document.service.DocumentService;
|
||||
@@ -9,13 +10,24 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.http.ContentDisposition;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@Validated
|
||||
@RestController
|
||||
public class DocumentController {
|
||||
|
||||
private final DocumentService documentService;
|
||||
@@ -41,4 +53,25 @@ public class DocumentController {
|
||||
return JsonData.ok(documentService.getVersionsBySchemaSourceId(projectId, page));
|
||||
}
|
||||
|
||||
@GetMapping(Routes.Document.EXPORT)
|
||||
public ResponseEntity<StreamingResponseBody> getDocumentFiles(@PathVariable Integer projectId,
|
||||
@RequestParam(required = false) Long version) {
|
||||
String data = documentService.toMarkdown(projectId, version).get();
|
||||
try {
|
||||
Path path = Files.writeString(Paths.get(UUID.randomUUID().toString() + ".md"), data, StandardCharsets.UTF_8);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDisposition(ContentDisposition.attachment()
|
||||
.filename("demo.md", StandardCharsets.UTF_8)
|
||||
.build());
|
||||
byte[] bytes = Files.readAllBytes(path);
|
||||
Files.deleteIfExists(path);
|
||||
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||
return ResponseEntity.ok()
|
||||
.headers(headers)
|
||||
.body(out -> out.write(bytes));
|
||||
} catch (IOException e) {
|
||||
throw new SystemException("System error");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -68,6 +68,8 @@ public interface Routes {
|
||||
String SYNC_ONE = BASE + "/projects/{projectId}/documents";
|
||||
|
||||
String LIST_VERSIONS = BASE + "/projects/{projectId}/document_versions";
|
||||
|
||||
String EXPORT = BASE + "/projects/{projectId}/document_files";
|
||||
}
|
||||
|
||||
interface DocumentRemark {
|
||||
|
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>databasir-frontend</title><link href="/css/chunk-1b2e2587.a5b9f9ad.css" rel="prefetch"><link href="/css/chunk-4935816e.e722c805.css" rel="prefetch"><link href="/css/chunk-7efe8be4.a5cbc9e6.css" rel="prefetch"><link href="/css/chunk-bf93911a.ab54ac4c.css" rel="prefetch"><link href="/js/chunk-1b2e2587.2a26d5cb.js" rel="prefetch"><link href="/js/chunk-2d0cc811.feb081c8.js" rel="prefetch"><link href="/js/chunk-48cebeac.b43a95b4.js" rel="prefetch"><link href="/js/chunk-4935816e.627c0115.js" rel="prefetch"><link href="/js/chunk-7efe8be4.e8bbd745.js" rel="prefetch"><link href="/js/chunk-9622a6d8.c20b1f79.js" rel="prefetch"><link href="/js/chunk-abb10c56.4c323350.js" rel="prefetch"><link href="/js/chunk-bf93911a.d40185ff.js" rel="prefetch"><link href="/js/chunk-fffb1b64.df1e960f.js" rel="prefetch"><link href="/css/app.56c172b4.css" rel="preload" as="style"><link href="/css/chunk-vendors.d4aa889d.css" rel="preload" as="style"><link href="/js/app.51f76bee.js" rel="preload" as="script"><link href="/js/chunk-vendors.ebe2dc88.js" rel="preload" as="script"><link href="/css/chunk-vendors.d4aa889d.css" rel="stylesheet"><link href="/css/app.56c172b4.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but databasir-frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/js/chunk-vendors.ebe2dc88.js"></script><script src="/js/app.51f76bee.js"></script></body></html>
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>databasir-frontend</title><link href="/css/chunk-1b2e2587.a5b9f9ad.css" rel="prefetch"><link href="/css/chunk-26c477fb.e722c805.css" rel="prefetch"><link href="/css/chunk-588dbed6.ab54ac4c.css" rel="prefetch"><link href="/css/chunk-7efe8be4.a5cbc9e6.css" rel="prefetch"><link href="/js/chunk-1b2e2587.2a26d5cb.js" rel="prefetch"><link href="/js/chunk-26c477fb.72a77fcd.js" rel="prefetch"><link href="/js/chunk-2d0cc811.feb081c8.js" rel="prefetch"><link href="/js/chunk-48cebeac.b43a95b4.js" rel="prefetch"><link href="/js/chunk-588dbed6.576f3300.js" rel="prefetch"><link href="/js/chunk-7efe8be4.e8bbd745.js" rel="prefetch"><link href="/js/chunk-9622a6d8.c20b1f79.js" rel="prefetch"><link href="/js/chunk-abb10c56.4c323350.js" rel="prefetch"><link href="/js/chunk-fffb1b64.df1e960f.js" rel="prefetch"><link href="/css/app.56c172b4.css" rel="preload" as="style"><link href="/css/chunk-vendors.d4aa889d.css" rel="preload" as="style"><link href="/js/app.58300ce2.js" rel="preload" as="script"><link href="/js/chunk-vendors.8b5336af.js" rel="preload" as="script"><link href="/css/chunk-vendors.d4aa889d.css" rel="stylesheet"><link href="/css/app.56c172b4.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but databasir-frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/js/chunk-vendors.8b5336af.js"></script><script src="/js/app.58300ce2.js"></script></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-bf93911a"],{"4dd4":function(e,t,n){},a1af:function(e,t,n){"use strict";n("4dd4")},a55b:function(e,t,n){"use strict";n.r(t);var r=n("7a23"),o={class:"login-card"},c=Object(r["createElementVNode"])("h1",null,"Databasir",-1),a=Object(r["createTextVNode"])(" 登录 "),u=Object(r["createTextVNode"])(" 忘记密码? ");function l(e,t,n,l,i,d){var s=Object(r["resolveComponent"])("el-header"),f=Object(r["resolveComponent"])("el-link"),b=Object(r["resolveComponent"])("el-divider"),m=Object(r["resolveComponent"])("el-form-item"),p=Object(r["resolveComponent"])("el-button"),j=Object(r["resolveComponent"])("el-space"),O=Object(r["resolveComponent"])("el-form"),h=Object(r["resolveComponent"])("el-main"),w=Object(r["resolveComponent"])("el-footer"),C=Object(r["resolveComponent"])("el-container");return Object(r["openBlock"])(),Object(r["createBlock"])(C,null,{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(s),Object(r["createVNode"])(h,{class:"login-main"},{default:Object(r["withCtx"])((function(){return[Object(r["createElementVNode"])("div",o,[Object(r["createVNode"])(O,{ref:"formRef",rules:i.formRule,model:i.form,style:{border:"none"}},{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(m,null,{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(b,{"content-position":"left"},{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(f,{href:"https://github.com/vran-dev/databasir",target:"_blank",underline:!1,type:"info"},{default:Object(r["withCtx"])((function(){return[c]})),_:1})]})),_:1})]})),_:1}),Object(r["createVNode"])(m,{prop:"username"},{default:Object(r["withCtx"])((function(){return[Object(r["withDirectives"])(Object(r["createElementVNode"])("input",{type:"text",class:"login-input",placeholder:"用户名或邮箱","onUpdate:modelValue":t[0]||(t[0]=function(e){return i.form.username=e})},null,512),[[r["vModelText"],i.form.username]])]})),_:1}),Object(r["createVNode"])(m,{prop:"password"},{default:Object(r["withCtx"])((function(){return[Object(r["withDirectives"])(Object(r["createElementVNode"])("input",{type:"password",class:"login-input",placeholder:"密码","onUpdate:modelValue":t[1]||(t[1]=function(e){return i.form.password=e})},null,512),[[r["vModelText"],i.form.password]])]})),_:1}),Object(r["createVNode"])(m,null,{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(j,{size:32},{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(p,{style:{width:"120px","margin-top":"10px"},color:"#000",onClick:t[2]||(t[2]=function(e){return d.onLogin("formRef")}),plain:"",round:""},{default:Object(r["withCtx"])((function(){return[a]})),_:1}),Object(r["createVNode"])(f,{href:"#",target:"_blank",underline:!1,type:"info"},{default:Object(r["withCtx"])((function(){return[u]})),_:1})]})),_:1})]})),_:1})]})),_:1},8,["rules","model"])])]})),_:1}),Object(r["createVNode"])(w,null,{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(j)]})),_:1})]})),_:1})}var i=n("b0af"),d=n("5f87"),s={data:function(){return{form:{username:null,password:null},formRule:{username:[{required:!0,message:"请输入用户名或邮箱",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]}}},methods:{toIndexPage:function(){this.$router.push({path:"/groups"})},onLogin:function(){var e=this;this.$refs.formRef.validate((function(t){t&&Object(i["a"])(e.form).then((function(t){t.errCode||(d["b"].saveUserLoginData(t.data),e.$store.commit("userUpdate",{nickname:t.data.nickname,username:t.data.username,email:t.data.email}),e.toIndexPage())}))}))}}},f=(n("a1af"),n("6b0d")),b=n.n(f);const m=b()(s,[["render",l]]);t["default"]=m}}]);
|
||||
//# sourceMappingURL=chunk-bf93911a.d40185ff.js.map
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-588dbed6"],{"4dd4":function(e,t,n){},a1af:function(e,t,n){"use strict";n("4dd4")},a55b:function(e,t,n){"use strict";n.r(t);var r=n("7a23"),o={class:"login-card"},c=Object(r["createElementVNode"])("h1",null,"Databasir",-1),a=Object(r["createTextVNode"])(" 登录 "),u=Object(r["createTextVNode"])(" 忘记密码? ");function l(e,t,n,l,i,d){var s=Object(r["resolveComponent"])("el-header"),f=Object(r["resolveComponent"])("el-link"),b=Object(r["resolveComponent"])("el-divider"),m=Object(r["resolveComponent"])("el-form-item"),p=Object(r["resolveComponent"])("el-button"),j=Object(r["resolveComponent"])("el-space"),O=Object(r["resolveComponent"])("el-form"),h=Object(r["resolveComponent"])("el-main"),w=Object(r["resolveComponent"])("el-footer"),C=Object(r["resolveComponent"])("el-container");return Object(r["openBlock"])(),Object(r["createBlock"])(C,null,{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(s),Object(r["createVNode"])(h,{class:"login-main"},{default:Object(r["withCtx"])((function(){return[Object(r["createElementVNode"])("div",o,[Object(r["createVNode"])(O,{ref:"formRef",rules:i.formRule,model:i.form,style:{border:"none"}},{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(m,null,{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(b,{"content-position":"left"},{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(f,{href:"https://github.com/vran-dev/databasir",target:"_blank",underline:!1,type:"info"},{default:Object(r["withCtx"])((function(){return[c]})),_:1})]})),_:1})]})),_:1}),Object(r["createVNode"])(m,{prop:"username"},{default:Object(r["withCtx"])((function(){return[Object(r["withDirectives"])(Object(r["createElementVNode"])("input",{type:"text",class:"login-input",placeholder:"用户名或邮箱","onUpdate:modelValue":t[0]||(t[0]=function(e){return i.form.username=e})},null,512),[[r["vModelText"],i.form.username]])]})),_:1}),Object(r["createVNode"])(m,{prop:"password"},{default:Object(r["withCtx"])((function(){return[Object(r["withDirectives"])(Object(r["createElementVNode"])("input",{type:"password",class:"login-input",placeholder:"密码","onUpdate:modelValue":t[1]||(t[1]=function(e){return i.form.password=e})},null,512),[[r["vModelText"],i.form.password]])]})),_:1}),Object(r["createVNode"])(m,null,{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(j,{size:32},{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(p,{style:{width:"120px","margin-top":"10px"},color:"#000",onClick:t[2]||(t[2]=function(e){return d.onLogin("formRef")}),plain:"",round:""},{default:Object(r["withCtx"])((function(){return[a]})),_:1}),Object(r["createVNode"])(f,{href:"#",target:"_blank",underline:!1,type:"info"},{default:Object(r["withCtx"])((function(){return[u]})),_:1})]})),_:1})]})),_:1})]})),_:1},8,["rules","model"])])]})),_:1}),Object(r["createVNode"])(w,null,{default:Object(r["withCtx"])((function(){return[Object(r["createVNode"])(j)]})),_:1})]})),_:1})}var i=n("b0af"),d=n("5f87"),s={data:function(){return{form:{username:null,password:null},formRule:{username:[{required:!0,message:"请输入用户名或邮箱",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]}}},methods:{toIndexPage:function(){this.$router.push({path:"/groups"})},onLogin:function(){var e=this;this.$refs.formRef.validate((function(t){t&&Object(i["a"])(e.form).then((function(t){t.errCode||(d["b"].saveUserLoginData(t.data),e.$store.commit("userUpdate",{nickname:t.data.nickname,username:t.data.username,email:t.data.email}),e.toIndexPage())}))}))}}},f=(n("a1af"),n("6b0d")),b=n.n(f);const m=b()(s,[["render",l]]);t["default"]=m}}]);
|
||||
//# sourceMappingURL=chunk-588dbed6.576f3300.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user