feat: 添加md文档预览
This commit is contained in:
parent
d966ffff1d
commit
f37f1051c0
@ -105,4 +105,4 @@
|
|||||||
"common-front": "link:D:\\shanghai\\txw2\\local-nodemodules\\@gt4\\common-front",
|
"common-front": "link:D:\\shanghai\\txw2\\local-nodemodules\\@gt4\\common-front",
|
||||||
"tdesign-gt-vue": "link:D:\\shanghai\\txw2\\local-nodemodules\\@gtff\\tdesign-gt-vue"
|
"tdesign-gt-vue": "link:D:\\shanghai\\txw2\\local-nodemodules\\@gtff\\tdesign-gt-vue"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
77
txw-mhzc-web/public/docs/carbon-guide.md
Normal file
77
txw-mhzc-web/public/docs/carbon-guide.md
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# 可信碳链 — 接入流程指南
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
欢迎接入可信碳链!以下是完整的接入流程说明,帮助您快速完成身份创建、资质申请与技术联调。
|
||||||
|
|
||||||
|
## 第一步:创建 DID 账户
|
||||||
|
|
||||||
|
**操作目标**:生成您的去中心化身份标识(DID),作为后续所有操作的身份基础。
|
||||||
|
|
||||||
|
1. 访问 DID 管理台,完成管理台账号注册并登录。
|
||||||
|
2. 在控制台中选择「创建 DID」或「导入已有 DID」,生成您的链上身份。
|
||||||
|
3. 妥善保管 DID 相关凭证,这是您在可信碳链上的唯一身份标识。
|
||||||
|
|
||||||
|
> **注意**:DID 凭证一旦丢失将无法恢复,请务必安全保管。
|
||||||
|
|
||||||
|
## 第二步:申请 VC 颁发权限
|
||||||
|
|
||||||
|
**操作目标**:获得可信碳凭证(Verifiable Credential)的签发资质,成为合规颁证机构。
|
||||||
|
|
||||||
|
1. 进入管理台 > 签发管理,提交「申请成为颁证机构」。
|
||||||
|
2. 按要求填写机构信息、资质材料并提交审核。
|
||||||
|
3. 等待平台审核通过后,即可获得凭证签发权限。
|
||||||
|
|
||||||
|
```
|
||||||
|
审核周期:3-5 个工作日
|
||||||
|
资质要求:企业实名认证 + 相关行业资质
|
||||||
|
```
|
||||||
|
|
||||||
|
## 第三步:创建可信碳凭证模板 & 访问令牌
|
||||||
|
|
||||||
|
**操作目标**:定义碳凭证的业务结构,并获取 DID 公共服务交互的安全令牌。
|
||||||
|
|
||||||
|
1. 进入管理台 > 凭证模板,点击「创建新模板」,配置凭证字段。
|
||||||
|
2. 进入管理台 > 账户中心 > 访问令牌管理进行新增加令牌。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 第四步:下载 SDK 并完成接入联调
|
||||||
|
|
||||||
|
**操作目标**:将可信碳能力集成到您的业务系统,实现碳数字身份证的签发与管理。
|
||||||
|
|
||||||
|
| 步骤 | 内容 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| 1 | 下载 SDK | 获取平台提供的 SDK 开发工具包 |
|
||||||
|
| 2 | 申请鉴权信息 | 申请 appId(应用标识)与 secretKey(密钥) |
|
||||||
|
| 3 | 集成开发 | 参考官方接入文档,将 SDK 集成到您的业务系统中 |
|
||||||
|
| 4 | 接口联调 | 调用接口实现碳数据上链、VC 签发/验证等功能 |
|
||||||
|
| 5 | 上线验证 | 联调通过后,即可正式上线 |
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// SDK 初始化示例
|
||||||
|
import { CarbonChain } from '@carbon/sdk';
|
||||||
|
|
||||||
|
const carbon = new CarbonChain({
|
||||||
|
appId: 'your-app-id',
|
||||||
|
secretKey: 'your-secret-key',
|
||||||
|
did: 'your-did'
|
||||||
|
});
|
||||||
|
|
||||||
|
await carbon.init();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### Q: 如何获取 DID?
|
||||||
|
A: 在 DID 管理台创建或导入已有 DID。
|
||||||
|
|
||||||
|
### Q: VC 审核需要多长时间?
|
||||||
|
A: 一般 3-5 个工作日。
|
||||||
|
|
||||||
|
### Q: 支持哪些开发语言?
|
||||||
|
A: 支持 Java、Python、Node.js、Go 等主流语言。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**技术支持**:如有疑问,请联系 support@carbonchain.com
|
||||||
6
txw-mhzc-web/public/marked.js
Normal file
6
txw-mhzc-web/public/marked.js
Normal file
File diff suppressed because one or more lines are too long
@ -106,6 +106,11 @@ function zhanghugl() {
|
|||||||
return import(/* webpackChunkName: "zhanghugl" */ '@/pages/index/views/yhzx/zhanghugl/index.vue');
|
return import(/* webpackChunkName: "zhanghugl" */ '@/pages/index/views/yhzx/zhanghugl/index.vue');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// md文档查看器
|
||||||
|
function mdviewer() {
|
||||||
|
return import(/* webpackChunkName: "mdviewer" */ '@/pages/index/views/mdviewer/index.vue');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -306,4 +311,16 @@ export default [
|
|||||||
disableBack: true,
|
disableBack: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'mdviewer',
|
||||||
|
path: '/mdviewer',
|
||||||
|
component: mdviewer,
|
||||||
|
meta: {
|
||||||
|
title: '文档预览',
|
||||||
|
isShowSideBar: false,
|
||||||
|
hasHome: true,
|
||||||
|
breadCrumbs: [{ title: '首页', to: '/home' }, { title: '文档预览', to: '/mdviewer' }],
|
||||||
|
disableBack: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
311
txw-mhzc-web/src/pages/index/views/mdviewer/index.vue
Normal file
311
txw-mhzc-web/src/pages/index/views/mdviewer/index.vue
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
<template>
|
||||||
|
<div class="md-viewer">
|
||||||
|
<div v-if="loading">加载中...</div>
|
||||||
|
<div v-else-if="error" v-html="error"></div>
|
||||||
|
<div v-else v-html="renderedContent"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'MdViewer',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
content: '',
|
||||||
|
loading: true,
|
||||||
|
error: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
renderedContent() {
|
||||||
|
if (!window.marked || !window.marked.parse) return '<p>marked 未加载</p>';
|
||||||
|
return window.marked.parse(this.content);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
await this.loadMarked();
|
||||||
|
this.fetchMdContent();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadMarked() {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (window.marked) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetch('marked.js')
|
||||||
|
.then((r) => r.text())
|
||||||
|
.then((code) => {
|
||||||
|
// 使用 iframe 来执行脚本,确保 window 是正确的
|
||||||
|
const iframe = document.createElement('iframe');
|
||||||
|
iframe.style.display = 'none';
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
const iframeWindow = iframe.contentWindow;
|
||||||
|
iframeWindow.eval(code);
|
||||||
|
window.marked = iframeWindow.marked;
|
||||||
|
document.body.removeChild(iframe);
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.error('marked 加载失败', e);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fetchMdContent() {
|
||||||
|
const { file } = this.$route.query;
|
||||||
|
if (!file) {
|
||||||
|
this.content = '# 未指定文件\n\n请使用 ?file=xxx 传递文件路径';
|
||||||
|
this.loading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 测试模式
|
||||||
|
if (file === 'test') {
|
||||||
|
this.content = `# 测试文档
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 这是一个测试
|
||||||
|
|
||||||
|
- 列表项1
|
||||||
|
- 列表项2
|
||||||
|
|
||||||
|
**粗体** 和 *斜体*
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
\`\`\`javascript
|
||||||
|
console.log('Hello World');
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
> 引用文本
|
||||||
|
|
||||||
|
[链接](https://example.com)
|
||||||
|
|
||||||
|
| 表头1 | 表头2 |
|
||||||
|
|-------|-------|
|
||||||
|
| 单元格1 | 单元格2 |
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 图片测试
|
||||||
|
|
||||||
|
支持本地图片和外链图片
|
||||||
|
|
||||||
|

|
||||||
|
`;
|
||||||
|
this.loading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetch(file)
|
||||||
|
.then((res) => {
|
||||||
|
if (!res.ok) throw new Error('404');
|
||||||
|
return res.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
this.content = data;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.error = '<h1>加载失败</h1><p>文件:' + file + '</p>';
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.md-viewer {
|
||||||
|
max-width: 820px;
|
||||||
|
margin: 30px auto;
|
||||||
|
padding: 50px 60px;
|
||||||
|
background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%);
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
|
||||||
|
font-family: 'PingFang SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.9;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.md-viewer h1 {
|
||||||
|
font-size: 2.2em;
|
||||||
|
font-weight: 800;
|
||||||
|
margin: 0 0 25px;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
border-bottom: 3px solid transparent;
|
||||||
|
border-image: linear-gradient(90deg, #667eea, #764ba2) 1;
|
||||||
|
color: #1a1a2e;
|
||||||
|
text-shadow: 0 1px 2px rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer h2 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 35px 0 18px;
|
||||||
|
padding: 10px 0 10px 16px;
|
||||||
|
border-left: 4px solid;
|
||||||
|
border-image: linear-gradient(180deg, #667eea, #764ba2) 1;
|
||||||
|
color: #1a1a2e;
|
||||||
|
background: linear-gradient(90deg, rgba(102,126,234,0.08) 0%, transparent 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer h3 {
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 28px 0 14px;
|
||||||
|
color: #2d3748;
|
||||||
|
padding-left: 12px;
|
||||||
|
border-left: 3px solid #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer h4 {
|
||||||
|
font-size: 1.05em;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 20px 0 10px;
|
||||||
|
color: #4a5568;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer p {
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer ul,
|
||||||
|
.md-viewer ol {
|
||||||
|
margin: 16px 0;
|
||||||
|
padding-left: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer li {
|
||||||
|
margin: 10px 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer ul li::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: -16px;
|
||||||
|
top: 12px;
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer blockquote {
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 16px 24px;
|
||||||
|
background: linear-gradient(135deg, rgba(102,126,234,0.08) 0%, rgba(118,75,162,0.08) 100%);
|
||||||
|
border-left: 4px solid #667eea;
|
||||||
|
border-radius: 0 12px 12px 0;
|
||||||
|
color: #4a5568;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer blockquote p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer code {
|
||||||
|
padding: 3px 8px;
|
||||||
|
background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
|
||||||
|
border-radius: 6px;
|
||||||
|
font-family: 'Fira Code', 'SFMono-Regular', Consolas, monospace;
|
||||||
|
font-size: 0.88em;
|
||||||
|
color: #d53f8c;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer pre {
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 20px 24px;
|
||||||
|
background: linear-gradient(135deg, #1e1e1e 0%, #2d2d30 100%);
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow-x: auto;
|
||||||
|
box-shadow: inset 0 2px 8px rgba(0,0,0,0.3), 0 4px 12px rgba(0,0,0,0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer pre code {
|
||||||
|
padding: 0;
|
||||||
|
background: none;
|
||||||
|
color: #d4d4d4;
|
||||||
|
font-size: 0.85em;
|
||||||
|
line-height: 1.7;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer a {
|
||||||
|
color: #667eea;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.2s;
|
||||||
|
border-bottom: 1px dashed #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer a:hover {
|
||||||
|
color: #764ba2;
|
||||||
|
border-bottom: 1px solid #764ba2;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer table {
|
||||||
|
width: 100%;
|
||||||
|
margin: 24px 0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 0.95em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer th {
|
||||||
|
background: #f8fafc;
|
||||||
|
color: #1a1a2e;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 16px 20px;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 2px solid #e2e8f0;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer td {
|
||||||
|
padding: 14px 20px;
|
||||||
|
border-bottom: 1px solid #f1f5f9;
|
||||||
|
color: #475569;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer tr:hover td {
|
||||||
|
background: #fafbfc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer hr {
|
||||||
|
margin: 30px 0;
|
||||||
|
border: none;
|
||||||
|
height: 2px;
|
||||||
|
background: linear-gradient(90deg, transparent, #e2e8f0, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer img {
|
||||||
|
max-width: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 16px rgba(0,0,0,0.1);
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer input[type="checkbox"] {
|
||||||
|
margin-right: 8px;
|
||||||
|
accent-color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer strong {
|
||||||
|
color: #2d3748;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-viewer em {
|
||||||
|
color: #718096;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
@ -281,6 +281,7 @@ module.exports = {
|
|||||||
'Access-Control-Allow-Origin': '*',
|
'Access-Control-Allow-Origin': '*',
|
||||||
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
||||||
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
|
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
|
||||||
|
'Content-Security-Policy': "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.bootcdn.net https://cdnjs.cloudflare.com",
|
||||||
},
|
},
|
||||||
// Vue CLI prepareProxy 用 pathname.match(代理键) 判断;键写 '/mhzc' 会变成匹配路径里任意位置的 /mhzc,
|
// Vue CLI prepareProxy 用 pathname.match(代理键) 判断;键写 '/mhzc' 会变成匹配路径里任意位置的 /mhzc,
|
||||||
// 会误伤 SPA 路由 /view/mhzc/...,刷新时整页请求被转发到后端导致 Proxy error。必须用 ^ 限定为路径前缀。
|
// 会误伤 SPA 路由 /view/mhzc/...,刷新时整页请求被转发到后端导致 Proxy error。必须用 ^ 限定为路径前缀。
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user