搜索结果列表页面开发
16
.editorconfig
Normal file
@@ -0,0 +1,16 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
7
.env
Normal file
@@ -0,0 +1,7 @@
|
||||
VITE_APP_TITLE = '新gitcode'
|
||||
VITE_TEST_REPOID = 34
|
||||
|
||||
VITE_SECRET_KEY = 'SA!nUNPZ5o!OSV&B'
|
||||
VITE_SECRET_IV = 'SA!nwwwZ5o!OSV&B'
|
||||
# 用户模块前缀
|
||||
VITE_PASSPORT_PREFIX = '/uc'
|
||||
36
.env.development
Normal file
@@ -0,0 +1,36 @@
|
||||
# 开发环境配置
|
||||
VITE_ENV = 'development'
|
||||
|
||||
# 主域名
|
||||
VITE_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# 接口地址
|
||||
VITE_API_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# devPress接口地址
|
||||
VITE_DEV_API_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# devPress地址
|
||||
VITE_DEV_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# 仓库文件上传域名
|
||||
VITE_FILE_HOST = 'https://test.gitcode.net'
|
||||
# 仓库文件下载域名
|
||||
VITE_DOWNLOAD_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# csdn登陆绑定地址
|
||||
VITE_CSDN_URL = 'https://test.gitcode.net/oauth/login/csdn'
|
||||
|
||||
# 组织社区跳转地址
|
||||
VITE_ORG_COMMUNITY = 'https://test.gitcode.net'
|
||||
|
||||
# 静态资源域名
|
||||
VITE_STATIC_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# 主页搜索子应用
|
||||
VITE_CHILD_HOMEWEB_HOST = 'https://test.gitcode.net/child/homeweb-app/'
|
||||
# 用户中心子应用
|
||||
VITE_USER_CENTER_HOST = 'https://test.gitcode.net/child/user-center/'
|
||||
|
||||
# ai-copilot 子应用
|
||||
VITE_COPILOT_HOST = 'https://test.gitcode.net/child/aichat-app/'
|
||||
38
.env.loc
Normal file
@@ -0,0 +1,38 @@
|
||||
# 开发环境配置
|
||||
VITE_ENV = 'loc'
|
||||
|
||||
# 主域名
|
||||
VITE_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# 接口地址
|
||||
VITE_API_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# devPress接口地址
|
||||
VITE_DEV_API_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# devPress地址
|
||||
VITE_DEV_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# 仓库文件上传域名
|
||||
VITE_FILE_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# 仓库文件下载域名
|
||||
VITE_DOWNLOAD_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# csdn登陆绑定地址
|
||||
VITE_CSDN_URL = 'https://test.gitcode.net/oauth/login/csdn'
|
||||
|
||||
# 组织社区跳转地址
|
||||
VITE_ORG_COMMUNITY = 'https://test.gitcode.net'
|
||||
|
||||
# 静态资源域名
|
||||
VITE_STATIC_HOST = 'https://test.gitcode.net'
|
||||
|
||||
# 主页搜索子应用
|
||||
VITE_CHILD_HOMEWEB_HOST = 'https://local.gitcode.net:8001/child/homeweb-app'
|
||||
|
||||
# 用户中心子应用
|
||||
VITE_USER_CENTER_HOST = 'https://local.gitcode.net:8002'
|
||||
|
||||
# ai-copilot 子应用
|
||||
VITE_COPILOT_HOST = 'https://local.gitcode.net:8003/child/aichat-app'
|
||||
38
.env.pre
Normal file
@@ -0,0 +1,38 @@
|
||||
# 预发环境配置
|
||||
VITE_ENV = 'pre'
|
||||
|
||||
# 主域名
|
||||
VITE_HOST = 'https://pre.gitcode.com'
|
||||
|
||||
# 接口地址
|
||||
VITE_API_HOST = 'https://pre-web-api.gitcode.com'
|
||||
|
||||
# devPress接口地址
|
||||
VITE_DEV_API_HOST = 'https://gitcode.com'
|
||||
|
||||
# devPress地址
|
||||
VITE_DEV_HOST = 'https://gitcode.com'
|
||||
|
||||
# 仓库文件上传域名
|
||||
VITE_FILE_HOST = 'https://pre.gitcode.com'
|
||||
|
||||
# 仓库文件下载域名
|
||||
VITE_DOWNLOAD_HOST = 'https://raw.gitcode.com'
|
||||
|
||||
# csdn登陆绑定地址 暂时无
|
||||
VITE_CSDN_URL = 'https://pre-web-api.gitcode.com/oauth/login/csdn'
|
||||
|
||||
# 组织社区跳转地址
|
||||
VITE_ORG_COMMUNITY = 'https://gitcode.com'
|
||||
|
||||
# 静态资源域名
|
||||
VITE_STATIC_HOST = 'https://pre.gitcode.com'
|
||||
|
||||
# 主页搜索子应用
|
||||
VITE_CHILD_HOMEWEB_HOST = 'https://pre-homepage-app.gitcode.com'
|
||||
|
||||
# 用户中心子应用
|
||||
VITE_USER_CENTER_HOST = 'https://pre-usercenter-app.gitcode.com'
|
||||
|
||||
# ai-copilot 子应用
|
||||
VITE_COPILOT_HOST = 'https://pre-copilot-app.gitcode.com'
|
||||
38
.env.production
Normal file
@@ -0,0 +1,38 @@
|
||||
# 生产环境配置
|
||||
VITE_ENV = 'production'
|
||||
|
||||
# 主域名
|
||||
VITE_HOST = 'https://gitcode.com'
|
||||
|
||||
# 接口地址
|
||||
VITE_API_HOST = 'https://web-api.gitcode.com'
|
||||
|
||||
# devPress接口地址
|
||||
VITE_DEV_API_HOST = 'https://gitcode.com'
|
||||
|
||||
# devPress地址
|
||||
VITE_DEV_HOST = 'https://gitcode.com'
|
||||
|
||||
# 仓库文件上传域名
|
||||
VITE_FILE_HOST = 'https://gitcode.com'
|
||||
|
||||
# 仓库文件下载域名
|
||||
VITE_DOWNLOAD_HOST = 'https://raw.gitcode.com'
|
||||
|
||||
# csdn登陆绑定地址 暂时无
|
||||
VITE_CSDN_URL = 'https://web-api.gitcode.com/oauth/login/csdn'
|
||||
|
||||
# 组织社区跳转地址
|
||||
VITE_ORG_COMMUNITY = 'https://gitcode.com'
|
||||
|
||||
# 静态资源域名
|
||||
VITE_STATIC_HOST = 'https://cdn-static.gitcode.com'
|
||||
|
||||
# 主页搜索子应用
|
||||
VITE_CHILD_HOMEWEB_HOST = 'https://homepage-app.gitcode.com'
|
||||
|
||||
# 用户中心子应用
|
||||
VITE_USER_CENTER_HOST = 'https://usercenter-app.gitcode.com'
|
||||
|
||||
# ai-copilot 子应用
|
||||
VITE_COPILOT_HOST = 'https://copilot-app.gitcode.com'
|
||||
6
.eslintignore
Normal file
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
build
|
||||
dist
|
||||
public
|
||||
.vscode
|
||||
vite.config.ts
|
||||
190
.eslintrc.cjs
Normal file
@@ -0,0 +1,190 @@
|
||||
/* eslint-env node */
|
||||
require('@rushstack/eslint-patch/modern-module-resolution');
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
'extends': [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended',
|
||||
'@vue/eslint-config-typescript',
|
||||
'@vue/eslint-config-prettier/skip-formatting'
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest'
|
||||
},
|
||||
rules: {
|
||||
'vue/multi-word-component-names': 'off', // 检查文件名称是否为多单词
|
||||
'vue/singleline-html-element-content-newline': 'off',
|
||||
'vue/multiline-html-element-content-newline': 'off',
|
||||
'vue/no-v-html': 'off',
|
||||
'accessor-pairs': 2,
|
||||
'arrow-spacing': [2, {
|
||||
'before': true,
|
||||
'after': true
|
||||
}],
|
||||
'block-spacing': [2, 'always'],
|
||||
'brace-style': [2, '1tbs', {
|
||||
'allowSingleLine': true
|
||||
}],
|
||||
'camelcase': [0, {
|
||||
'properties': 'always'
|
||||
}],
|
||||
'comma-dangle': [2, 'never'],
|
||||
'comma-spacing': [2, {
|
||||
'before': false,
|
||||
'after': true
|
||||
}],
|
||||
'comma-style': [2, 'last'],
|
||||
'constructor-super': 2,
|
||||
'curly': [2, 'multi-line'],
|
||||
'dot-location': [2, 'property'],
|
||||
'eol-last': 2,
|
||||
'eqeqeq': ['error', 'always', { 'null': 'ignore' }],
|
||||
'generator-star-spacing': [2, {
|
||||
'before': true,
|
||||
'after': true
|
||||
}],
|
||||
'handle-callback-err': [2, '^(err|error)$'],
|
||||
'indent': [2, 2, {
|
||||
'SwitchCase': 1
|
||||
}],
|
||||
'jsx-quotes': [2, 'prefer-single'],
|
||||
'key-spacing': [2, {
|
||||
'beforeColon': false,
|
||||
'afterColon': true
|
||||
}],
|
||||
'keyword-spacing': [2, {
|
||||
'before': true,
|
||||
'after': true
|
||||
}],
|
||||
'new-cap': [2, {
|
||||
'newIsCap': true,
|
||||
'capIsNew': false
|
||||
}],
|
||||
'new-parens': 2,
|
||||
'no-array-constructor': 2,
|
||||
'no-caller': 2,
|
||||
'no-console': 'off',
|
||||
'no-class-assign': 2,
|
||||
'no-cond-assign': 2,
|
||||
'no-const-assign': 2,
|
||||
'no-control-regex': 0,
|
||||
'no-delete-var': 2,
|
||||
'no-dupe-args': 2,
|
||||
'no-dupe-class-members': 2,
|
||||
'no-dupe-keys': 2,
|
||||
'no-duplicate-case': 2,
|
||||
'no-empty-character-class': 2,
|
||||
'no-empty-pattern': 2,
|
||||
'no-eval': 2,
|
||||
'no-ex-assign': 2,
|
||||
'no-extend-native': 2,
|
||||
'no-extra-bind': 2,
|
||||
'no-extra-boolean-cast': 2,
|
||||
'no-extra-parens': [2, 'functions'],
|
||||
'no-fallthrough': 2,
|
||||
'no-floating-decimal': 2,
|
||||
'no-func-assign': 2,
|
||||
'no-implied-eval': 2,
|
||||
'no-inner-declarations': [2, 'functions'],
|
||||
'no-invalid-regexp': 2,
|
||||
'no-irregular-whitespace': 2,
|
||||
'no-iterator': 2,
|
||||
'no-label-var': 2,
|
||||
'no-labels': [2, {
|
||||
'allowLoop': false,
|
||||
'allowSwitch': false
|
||||
}],
|
||||
'no-lone-blocks': 2,
|
||||
'no-mixed-spaces-and-tabs': 2,
|
||||
'no-multi-spaces': 2,
|
||||
'no-multi-str': 2,
|
||||
'no-multiple-empty-lines': [2, {
|
||||
'max': 1
|
||||
}],
|
||||
'no-native-reassign': 2,
|
||||
'no-negated-in-lhs': 2,
|
||||
'no-new-object': 2,
|
||||
'no-new-require': 2,
|
||||
'no-new-symbol': 2,
|
||||
'no-new-wrappers': 2,
|
||||
'no-obj-calls': 2,
|
||||
'no-octal': 2,
|
||||
'no-octal-escape': 2,
|
||||
'no-path-concat': 2,
|
||||
'no-proto': 2,
|
||||
'no-redeclare': 2,
|
||||
'no-regex-spaces': 2,
|
||||
'no-return-assign': [2, 'except-parens'],
|
||||
'no-self-assign': 2,
|
||||
'no-self-compare': 2,
|
||||
'no-sequences': 2,
|
||||
'no-shadow-restricted-names': 2,
|
||||
'no-spaced-func': 2,
|
||||
'no-sparse-arrays': 2,
|
||||
'no-this-before-super': 2,
|
||||
'no-throw-literal': 2,
|
||||
'no-trailing-spaces': 2,
|
||||
'no-undef': 2,
|
||||
'no-undef-init': 2,
|
||||
'no-unexpected-multiline': 2,
|
||||
'no-unmodified-loop-condition': 2,
|
||||
'no-unneeded-ternary': [2, {
|
||||
'defaultAssignment': false
|
||||
}],
|
||||
'no-unreachable': 2,
|
||||
'no-unsafe-finally': 2,
|
||||
'no-unused-vars': [1, {
|
||||
'vars': 'all',
|
||||
'args': 'none'
|
||||
}],
|
||||
'no-useless-call': 2,
|
||||
'no-useless-computed-key': 2,
|
||||
'no-useless-constructor': 2,
|
||||
'no-useless-escape': 0,
|
||||
'no-whitespace-before-property': 2,
|
||||
'no-with': 2,
|
||||
'one-var': [2, {
|
||||
'initialized': 'never'
|
||||
}],
|
||||
'operator-linebreak': [2, 'after', {
|
||||
'overrides': {
|
||||
'?': 'before',
|
||||
':': 'before'
|
||||
}
|
||||
}],
|
||||
'padded-blocks': [2, 'never'],
|
||||
'quotes': [2, 'single', {
|
||||
'avoidEscape': true,
|
||||
'allowTemplateLiterals': true
|
||||
}],
|
||||
'semi': [2, 'always'],
|
||||
'semi-spacing': [2, {
|
||||
'before': false,
|
||||
'after': true
|
||||
}],
|
||||
'space-before-blocks': [2, 'always'],
|
||||
'space-before-function-paren': [2, 'never'],
|
||||
'space-in-parens': [2, 'never'],
|
||||
'space-infix-ops': 2,
|
||||
'space-unary-ops': [2, {
|
||||
'words': true,
|
||||
'nonwords': false
|
||||
}],
|
||||
'spaced-comment': [2, 'always', {
|
||||
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
|
||||
}],
|
||||
'template-curly-spacing': [2, 'never'],
|
||||
'use-isnan': 2,
|
||||
'valid-typeof': 2,
|
||||
'wrap-iife': [2, 'any'],
|
||||
'yield-star-spacing': [2, 'both'],
|
||||
'yoda': [2, 'never'],
|
||||
'prefer-const': 2,
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||
'object-curly-spacing': [2, 'always', {
|
||||
objectsInObjects: false
|
||||
}],
|
||||
'array-bracket-spacing': [2, 'never']
|
||||
}
|
||||
};
|
||||
39
.gitignore
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
# Logs
|
||||
stats.html
|
||||
logs
|
||||
dist.zip
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
src/views/Demo
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
/docker/conf/default.conf
|
||||
|
||||
# Editor directories and files
|
||||
.vscode
|
||||
!.vscode/extensions.json
|
||||
!.vscode/settings.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# 定义文件
|
||||
components.d.ts
|
||||
|
||||
# 组件汇总文件,仅限开发本地浏览
|
||||
component.md
|
||||
8
.prettierrc.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/prettierrc",
|
||||
"semi": true,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"printWidth": 120,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
62
README.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# gitcode-v2
|
||||
|
||||
架构:基于[create-vue](https://github.com/vuejs/create-vue)构建(vite+vue3+pinia+scss)
|
||||
组件库:[Vue DevUI](https://vue-devui.github.io/)
|
||||
|
||||
# 规范
|
||||
|
||||
- 使用eslint,保存自动格式化
|
||||
- 页面和组件文件夹命名及引用为大驼峰(Issue,IssueItem),其他文件夹小驼峰(common)
|
||||
- 代码内变量,方法名为小驼峰(issueNum)
|
||||
- css类名为蛇形(submit-btn-color)
|
||||
- 分支命名(关键字/模块/功能,fix/mr/bigfile-issue-create)
|
||||
```
|
||||
关键字包括:feat、 hotfix、refactor等类型
|
||||
```
|
||||
- commit提交规范(feat:完成issue创建功能)
|
||||
```
|
||||
feat: 新增功能
|
||||
fix: 修复 bug
|
||||
docs: 仅仅修改了文档,比如 README, CHANGELOG, CONTRIBUTE等等
|
||||
style: 仅仅修改了空格、格式缩进、逗号等等,不改变代码逻辑
|
||||
refactor: 代码重构,没有加新功能或者修复 bug
|
||||
perf: 优化相关,比如提升性能、体验
|
||||
test: 测试用例,包括单元测试、集成测试等
|
||||
chore: 改变构建流程、或者增加依赖库、工具等
|
||||
revert: 回滚到上一个版本
|
||||
```
|
||||
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
|
||||
```sh
|
||||
# 安装依赖
|
||||
npm install
|
||||
```
|
||||
|
||||
### start
|
||||
|
||||
```sh
|
||||
npm run dev # 开发
|
||||
npm run prod # 生产
|
||||
```
|
||||
|
||||
### build
|
||||
|
||||
```sh
|
||||
npm run build:dev # 开发
|
||||
npm run build:prod # 生产
|
||||
```
|
||||
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
|
||||
```sh
|
||||
npm run lint
|
||||
```
|
||||
|
||||
|
||||
25
env.d.ts
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// / <reference types="vite/client" />
|
||||
|
||||
declare module 'dayjs/esm/locale/zh-cn'
|
||||
declare module 'dayjs/plugin/timezone'
|
||||
|
||||
import type { DefineComponent } from 'vue';
|
||||
declare module 'canvas-confetti';
|
||||
declare module '*.vue' {
|
||||
const component: DefineComponent<{}, {}, any>;
|
||||
export default component;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window { page_ref: string; }
|
||||
}
|
||||
|
||||
declare module '*.svg'
|
||||
declare module '*.png'
|
||||
declare module '*.jpg'
|
||||
declare module '*.jpeg'
|
||||
declare module '*.gif'
|
||||
declare module '*.bmp'
|
||||
declare module '*.tiff'
|
||||
|
||||
declare module 'js-cookie'
|
||||
41
index.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="https://cdn-static.gitcode.com/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="preconnect" href="//homepage-app.gitcode.com" crossorigin />
|
||||
<link rel="dns-prefetch" href="//homepage-app.gitcode.com">
|
||||
<link rel="dns-prefetch" href="//usercenter-app.gitcode.com">
|
||||
<link rel="dns-prefetch" href="//res.hc-cdn.com">
|
||||
<!-- <meta name="referrer" content="no-referrer"> -->
|
||||
<title>可信开源代码库</title>
|
||||
<style type="text/css">
|
||||
.icon {
|
||||
width: 1em; height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
<script type="text/javascript" src="https://cdn-static.gitcode.com/js/gitcode-icon.js"></script>
|
||||
<script type="text/javascript" src="https://cdn-static.gitcode.com/js/event-msg.min.0.0.2.js"></script>
|
||||
<script type="text/javascript" src="https://cdn-static.gitcode.com/js/lottie.min.js" defer></script>
|
||||
<script type="text/javascript" src="https://cdn-static.gitcode.com/js/furion.js" defer></script>
|
||||
<!-- baidu统计 -->
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
_hmt.push(['_setAutoPageview', false]);
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?62047c952451105d57bab2c4af9ce85b";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
</html>
|
||||
9715
package-lock.json
generated
Normal file
77
package.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "gitcode-v2",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --mode development",
|
||||
"dev-loc": "vite --mode loc --open https://local.gitcode.net",
|
||||
"pre": "vite --mode pre",
|
||||
"prod": "vite --mode production",
|
||||
"build:dev": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode development",
|
||||
"build:test": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode test",
|
||||
"build:pre": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode pre",
|
||||
"build:prod": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode production",
|
||||
"analysis": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode analysis",
|
||||
"preview": "vite preview",
|
||||
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
||||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@devui-design/icons": "^1.3.0",
|
||||
"@micro-zoe/micro-app": "1.0.0-rc.3",
|
||||
"@sentry/vue": "^7.101.1",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@vueuse/core": "^10.2.1",
|
||||
"axios": "^1.6.8",
|
||||
"canvas-confetti": "^1.9.2",
|
||||
"crypto-js": "^4.1.1",
|
||||
"dayjs": "^1.11.9",
|
||||
"devui-theme": "^0.0.7",
|
||||
"dompurify": "^3.0.5",
|
||||
"js-cookie": "^3.0.5",
|
||||
"localforage": "^1.10.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lottie-web": "^5.12.2",
|
||||
"markdown-it": "^14.1.0",
|
||||
"mitt": "^3.0.1",
|
||||
"mockjs": "^1.1.0",
|
||||
"normalize.css": "^8.0.1",
|
||||
"overlayscrollbars": "^2.3.1",
|
||||
"pinia": "^2.1.3",
|
||||
"qs": "^6.11.2",
|
||||
"sortablejs": "^1.15.0",
|
||||
"swiper": "^10.3.1",
|
||||
"vue": "^3.3.4",
|
||||
"vue-devui": "^1.6.7",
|
||||
"vue-router": "^4.2.2",
|
||||
"yaml": "^2.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.2.0",
|
||||
"@tsconfig/node18": "^2.0.1",
|
||||
"@types/canvas-confetti": "^1.6.4",
|
||||
"@types/mockjs": "^1.0.7",
|
||||
"@types/node": "^18.17.1",
|
||||
"@types/three": "^0.155.1",
|
||||
"@vitejs/plugin-basic-ssl": "^1.0.1",
|
||||
"@vitejs/plugin-legacy": "^4.1.1",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"@vue/eslint-config-prettier": "^7.1.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.3",
|
||||
"@vue/tsconfig": "^0.4.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"eslint": "^9.22.0",
|
||||
"eslint-plugin-vue": "^9.11.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.27",
|
||||
"prettier": "^2.8.8",
|
||||
"rollup-plugin-visualizer": "^5.9.2",
|
||||
"sass": "^1.63.6",
|
||||
"tailwindcss": "^3.3.3",
|
||||
"typescript": "~5.0.4",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^4.5.2",
|
||||
"vue-tsc": "^1.6.5"
|
||||
}
|
||||
}
|
||||
7
postcss.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
// eslint-disable-next-line no-undef
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
};
|
||||
BIN
public/code-highlight-theme/dark.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
public/code-highlight-theme/monokai.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
public/code-highlight-theme/none.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
public/code-highlight-theme/solarized_dark.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
public/code-highlight-theme/solarized_light.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
public/code-highlight-theme/white.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
3
public/static/images/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Tip
|
||||
|
||||
> 此文件夹保存了lottie的图片资源,请勿删除
|
||||
BIN
public/static/images/img_0.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/static/images/skin-blackwhale.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
public/static/images/skin-building.jpg
Normal file
|
After Width: | Height: | Size: 382 KiB |
BIN
public/static/images/skin-cat-title.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
public/static/images/skin-colorful.jpg
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
public/static/images/skin-growway.png
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
public/static/images/skin-number.png
Normal file
|
After Width: | Height: | Size: 141 KiB |
BIN
public/static/images/skin-thespecialists.gif
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
public/static/images/skin-wave.jpg
Normal file
|
After Width: | Height: | Size: 127 KiB |
1
public/static/js/font_4205092_xmdqsn5ibm.js
Normal file
11
public/static/js/furion.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// 埋点统计
|
||||
!function(x, n) {
|
||||
window[n] = window[n] || {};
|
||||
window[n].config = {
|
||||
appId: "B890DF389DB3442F8BD2BF08280848ED",setting: "api,jsTrack,uba,longtask,rtti",hashMode: true,smartJsErr: false,
|
||||
};
|
||||
var o = document.createElement('script');
|
||||
o.src = x, o.async = !0;
|
||||
var d = document.body.firstChild;
|
||||
document.body.insertBefore(o, d);
|
||||
}('https://res.hc-cdn.com/FurionSdk/furion-cdn.min.js', '__fr');
|
||||
228
src/App.vue
Normal file
@@ -0,0 +1,228 @@
|
||||
// eslint-disable-next-line vue/name-property-casing
|
||||
<script setup lang="ts">
|
||||
import { RouterView } from 'vue-router';
|
||||
import { ref, onMounted, onBeforeUnmount, watchEffect } from 'vue';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { addEventListener, clearEvent } from '@/utils/eventBus';
|
||||
import { useLogin } from './utils/hooks/useLogin';
|
||||
import { useNotification } from './utils/hooks/useNotice';
|
||||
import { useAccount } from './utils/hooks/useAccount';
|
||||
import { useAccModal } from './utils/hooks/useAccModal';
|
||||
import { NotificationService } from 'vue-devui/notification';
|
||||
import { Message } from 'vue-devui/message';
|
||||
import { getOrgInfo } from '@/views/Org/hooks/orgInfo';
|
||||
import cookie from 'js-cookie';
|
||||
import { useGlobalInfoStore } from '@/stores/Global';
|
||||
import dayjs from 'dayjs';
|
||||
import { getLoginConfig } from './api/user';
|
||||
|
||||
const globalInfo = useGlobalInfoStore();
|
||||
const { login, unMount, isMounted } = useLogin();
|
||||
const { openModal, closeModal, isMountedModal } = useAccModal();
|
||||
const { notice } = useNotification();
|
||||
const { RemoveInfo } = useAccount();
|
||||
const status = ref(false);
|
||||
const isPending = ref(false);
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const toNotice = () => {
|
||||
if (localStorage.getItem('validator_email') === 'invalid') {
|
||||
notice();
|
||||
}
|
||||
};
|
||||
|
||||
const checkoutFirstTime = () => {
|
||||
const uuid = cookie.get('uuid_tt_dd');
|
||||
const firstTime = cookie.get('gitcode_first_time');
|
||||
if (uuid && !firstTime) {
|
||||
const expireDate = new Date(`${dayjs().year() + 2}-01-01 00:00:00`);
|
||||
const expirationUTC = new Date(
|
||||
Date.UTC(
|
||||
expireDate.getFullYear(),
|
||||
expireDate.getMonth(),
|
||||
expireDate.getDate(),
|
||||
expireDate.getHours(),
|
||||
expireDate.getMinutes(),
|
||||
expireDate.getSeconds()
|
||||
)
|
||||
);
|
||||
const domainMatch = (location.host.match(/(gitcode..+)/) || []) as string[];
|
||||
cookie.set('gitcode_first_time', dayjs().format('YYYY-MM-DD HH:mm:ss'), { expires: expirationUTC, domain: domainMatch[1] });
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
/** pc端刷新窗口 */
|
||||
toNotice();
|
||||
addEventListener('logout', (options) => {
|
||||
const token = localStorage.getItem('access_token');
|
||||
if (!status.value) {
|
||||
status.value = true;
|
||||
if (isMounted()) {
|
||||
setTimeout(() => {
|
||||
status.value = false;
|
||||
}, 2000);
|
||||
} else {
|
||||
NotificationService.open({
|
||||
type: 'success',
|
||||
title: 'Gitcode 提示',
|
||||
content: token ? '你的登录信息已过期,请重新登录!' : '登录之后才能开启全新体验哦',
|
||||
onClose: () => {
|
||||
status.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
token && RemoveInfo();
|
||||
|
||||
const data = typeof options === 'boolean' ? { Authorization: options } : options;
|
||||
login(data);
|
||||
}
|
||||
});
|
||||
addEventListener('login', (options) => {
|
||||
login(options);
|
||||
});
|
||||
/** 403刷新页面一次 */
|
||||
addEventListener('forbiddenRefresh', () => {
|
||||
// 暂时跳转组织创建
|
||||
if (route.path === '/org/create') {
|
||||
localStorage.removeItem('refresh_count');
|
||||
return;
|
||||
}
|
||||
if (!isPending.value) {
|
||||
isPending.value = true;
|
||||
if (!localStorage.getItem('refresh_count') && route.name !== '403') {
|
||||
localStorage.setItem('refresh_count', 'pending');
|
||||
router.go(0);
|
||||
} else {
|
||||
Message.warning({
|
||||
message: '权限不足',
|
||||
onClose: () => {
|
||||
localStorage.removeItem('refresh_count');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
/** mobile暂定全部重定向为首页 */
|
||||
addEventListener('notice', toNotice);
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.origin === (import.meta as any).env.VITE_HOST) {
|
||||
if (event.data.type === 'success') {
|
||||
if (isMountedModal()) {
|
||||
closeModal();
|
||||
}
|
||||
if (isMounted()) {
|
||||
unMount();
|
||||
}
|
||||
if (event.data?.path) {
|
||||
router.replace(event.data?.path);
|
||||
} else {
|
||||
router.go(0);
|
||||
}
|
||||
} else if (event.data.type === 'fail') {
|
||||
Message.warning(event.data.message || '授权失败');
|
||||
}
|
||||
}
|
||||
});
|
||||
/** 获取用户组织配额权限 */
|
||||
if (!localStorage.getItem('group_quota')) {
|
||||
const { getUserCreateOrg } = getOrgInfo();
|
||||
getUserCreateOrg();
|
||||
}
|
||||
checkoutFirstTime();
|
||||
});
|
||||
|
||||
watchEffect(async() => {
|
||||
if (route?.query?.isLogin && !localStorage.getItem('access_token')) {
|
||||
if (!isMountedModal()) {
|
||||
const cache_timeStamp = localStorage.getItem('cache_timeStamp');
|
||||
const currentTimestamp = Date.now();
|
||||
const oneDayMilliseconds = 24 * 60 * 60 * 1000;
|
||||
|
||||
// 获取不加防打扰的配置
|
||||
let loginList = [];
|
||||
if (route?.query?.isLogin !== '1') {
|
||||
const res = await getLoginConfig();
|
||||
loginList = res?.data?.data || [];
|
||||
}
|
||||
|
||||
// isLogin为配置字符串时一直弹窗
|
||||
if (loginList.includes(route?.query?.isLogin) || !cache_timeStamp || (Number(cache_timeStamp) + oneDayMilliseconds) < currentTimestamp) {
|
||||
setTimeout(() => {
|
||||
localStorage.setItem('cache_timeStamp', currentTimestamp.toString());
|
||||
openModal();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 注册来源utm_source保存
|
||||
if (route?.query?.utm_source) {
|
||||
const currentTime = Date.now();
|
||||
localStorage.setItem('utm_source_sign_time', currentTime.toString());
|
||||
localStorage.setItem('utm_source_sign', JSON.stringify(route?.query?.utm_source));
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clearEvent();
|
||||
window.removeEventListener('message', () => {});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RouterView :class="`g-theme-${globalInfo.globalTheme}`" />
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.global-notification {
|
||||
&-mobile {
|
||||
.devui-notification {
|
||||
right: 15px;
|
||||
left: 15px;
|
||||
width: #{calc(100vw - 30px )};
|
||||
top: 60px;
|
||||
&__title {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.devui-notification-item-container {
|
||||
background: rgba(255, 255, 255, 1);
|
||||
box-sizing: border-box;
|
||||
padding: 15px;
|
||||
opacity: 1;
|
||||
.devui-notification__item {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-pc {
|
||||
.devui-notification {
|
||||
width: 296px;
|
||||
right: 22px;
|
||||
top: 60px;
|
||||
&__title {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.devui-notification-item-container {
|
||||
background: rgba(255, 255, 255, 1);
|
||||
box-sizing: border-box;
|
||||
padding: 22px;
|
||||
opacity: 1;
|
||||
.devui-notification__item {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.devui-notification__message {
|
||||
margin-left: 0;
|
||||
}
|
||||
.icon-close {
|
||||
font-size: 0 !important;
|
||||
&:before {
|
||||
content: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
60
src/api/analysis/index.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import request from '@/utils/request';
|
||||
import type { AxiosResponse } from 'axios';
|
||||
import type { CommitCountData, RepoCountData, TrendData } from '@/api/analysis/types';
|
||||
|
||||
// 获取项目统计
|
||||
export function getRepoCount(params: { project_id: string; statistics?: boolean }): Promise<AxiosResponse<RepoCountData>> {
|
||||
return request({
|
||||
url: `/api/v2/projects/${params.project_id}`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取仓库趋势统计数据
|
||||
export function getTrendCount(params: { project_id: string; branch_name: string; }): Promise<AxiosResponse<TrendData>> {
|
||||
return request({
|
||||
url: `/api/v2/projects/${params.project_id}/repository/commit_statistics`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取仓库语言统计数据
|
||||
export function getLangCount(params: { project_id: string; }): Promise<AxiosResponse<{label: string; value: number;}[]>> {
|
||||
return request({
|
||||
url: `/api/v2/projects/${params.project_id}/languages`,
|
||||
method: 'get',
|
||||
params
|
||||
}, {
|
||||
customError: true
|
||||
});
|
||||
}
|
||||
|
||||
// 获取仓库提交活跃度数据
|
||||
export function getCommitCount(params: { project_id: string; branch_name: string; }): Promise<AxiosResponse<CommitCountData>> {
|
||||
return request({
|
||||
url: `/api/v2/projects/${params.project_id}/repository/graph`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取仓库分支提交线路图
|
||||
export function getCommitNetwork(params: { project_id: string; ref_name: string; filter_ref: string; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: `/api/v2/projects/${params.project_id}/repository/network`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
// 数据刷新,记录执行人
|
||||
export function postRepoStatistics(project_id: string, data: object): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/projects/${project_id}/repository/statistics`,
|
||||
method: 'post',
|
||||
data
|
||||
}, {
|
||||
customError: true
|
||||
})
|
||||
}
|
||||
54
src/api/analysis/types.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
export type RepoCountData = {
|
||||
tag_count: number;
|
||||
branch_count: number;
|
||||
release_count: number;
|
||||
statistics: {
|
||||
commit_count?: string;
|
||||
storage_size?: string;
|
||||
repository_size?: string;
|
||||
lfs_objects_size?: string;
|
||||
job_artifacts_size?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type TrendData = {
|
||||
commits: Commit[];
|
||||
statistics: Statistic[];
|
||||
total: number;
|
||||
}
|
||||
type Commit = {
|
||||
author_name: string;
|
||||
date: Date;
|
||||
}
|
||||
type Statistic = {
|
||||
id: number;
|
||||
project_id: number;
|
||||
branch: string;
|
||||
user_name: string;
|
||||
add_lines: number;
|
||||
delete_lines: number;
|
||||
commit_count: number;
|
||||
created_at: Date;
|
||||
updated_at: Date;
|
||||
}
|
||||
|
||||
export type CommitCountData = {
|
||||
authors: number;
|
||||
commit_per_day: number;
|
||||
commits: CommitData[];
|
||||
duration: number;
|
||||
end_date: string;
|
||||
start_date: string;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export type CommitData = {
|
||||
parents: Array<Array<number | string>>;
|
||||
author: any;
|
||||
time: number;
|
||||
space: number;
|
||||
refs: any;
|
||||
id: string;
|
||||
date: string;
|
||||
message: string;
|
||||
}
|
||||
57
src/api/branch/index.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/branch/types';
|
||||
import { reqCatch } from '@/utils/catch';
|
||||
|
||||
// 获取分支概览
|
||||
export function getBranchesOverview(params: types.commonBranchReqType): Promise<types.commonBranchResType> {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/internal/projects/${params.repoId}/repository/branch_overview`,
|
||||
method: 'get',
|
||||
params: params
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 获取分支列表
|
||||
export function getBranches(params: types.commonBranchReqType): Promise<types.commonBranchResType> {
|
||||
if (!params.view) {
|
||||
params.view = 'simple';
|
||||
}
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/projects/${params.repoId}/repository/branches`,
|
||||
method: 'get',
|
||||
params: {
|
||||
...params,
|
||||
search: params?.search?.substring(0, 100) || ''
|
||||
}
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 创建分支
|
||||
export function createBranches(data: types.commonBranchReqType): Promise<types.commonBranchResType> {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/projects/${data.repoId}/repository/branches`,
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 删除分支
|
||||
export function deleteBranches(data: types.commonBranchReqType): Promise<types.commonBranchResType> {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/projects/${data.repoId}/repository/branches`,
|
||||
method: 'delete',
|
||||
params: data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 检测是否为分支
|
||||
export function checkBranches(params: types.commonBranchReqType): Promise<types.commonBranchResType> {
|
||||
const { project_id } = params;
|
||||
delete params.project_id;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/projects/${project_id}/repository/branches/check`,
|
||||
method: 'get',
|
||||
params
|
||||
}), params);
|
||||
}
|
||||
|
||||
18
src/api/branch/types.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { type errorType, type resCatch } from '@/api/types/common';
|
||||
import type { repoType } from '@/api/types/common';
|
||||
|
||||
export interface createBranchReqType extends repoType{
|
||||
branch: string,
|
||||
ref: string,
|
||||
description?: string;
|
||||
relatedIds?: string[];
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonBranchReqType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonBranchResType extends resCatch {
|
||||
[propName: string]: any;
|
||||
}
|
||||
80
src/api/cla/index.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/cla/types';
|
||||
// 签署CLA
|
||||
export function signCla(data: types.signClaReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/cla/sign/add`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
// 签署CLA详情
|
||||
export function getClaInfo(params: types.paramsObj): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/cla/sign/info`,
|
||||
method: 'get',
|
||||
params
|
||||
}, {
|
||||
customError: true
|
||||
});
|
||||
}
|
||||
// 本人已签署CLA详情
|
||||
export function getClaInfoDetail(params: types.paramsObj): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/cla/sign/detail`,
|
||||
method: 'get',
|
||||
params
|
||||
}, {
|
||||
customError: true
|
||||
});
|
||||
}
|
||||
// 获取组织里面用户已签署CLA详情
|
||||
export function getGroupClaInfoDetail(params: types.paramsObj): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/cla/${params.group_id}/detail`,
|
||||
method: 'get',
|
||||
params
|
||||
}, {
|
||||
customError: true
|
||||
});
|
||||
}
|
||||
// 组织下的cla列表
|
||||
export function getGroupClaList(params: types.paramsObj): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/cla/${params.group_id}/list`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
// 组织下的cla列表
|
||||
export function setGroupClaStatus(params: types.paramsObj): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/cla/${params.group_id}/status`,
|
||||
method: 'put',
|
||||
params
|
||||
});
|
||||
}
|
||||
// 组织下的cla列表
|
||||
export function deleteGroupCla(params: types.paramsObj): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/cla/${params.group_id}/del`,
|
||||
method: 'delete',
|
||||
params
|
||||
});
|
||||
}
|
||||
// 已签署CLA协议的用户列表
|
||||
export function getClaUsers(params: types.paramsObj): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/cla/${params.group_id}/signUsers`,
|
||||
method: 'get',
|
||||
params: params.params
|
||||
});
|
||||
}
|
||||
// CLA协议历史版本列表
|
||||
export function getClaVersion(params: types.paramsObj): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/cla/getClaHistory`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
19
src/api/cla/types.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
export interface signClaReqType {
|
||||
claId: string,
|
||||
version: string,
|
||||
sourceUrl: string,
|
||||
userId: string,
|
||||
userName: string,
|
||||
realName: string,
|
||||
email: string,
|
||||
phone: string,
|
||||
status: number,
|
||||
payload: string,
|
||||
sign: string,
|
||||
[x:string]: any
|
||||
}
|
||||
|
||||
export interface paramsObj {
|
||||
[x:string]: any
|
||||
}
|
||||
142
src/api/commit/index.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/commit/types';
|
||||
import { reqCatch } from '@/utils/catch';
|
||||
// 修改检视意见
|
||||
export function editDiscussions(data: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/discussions/${data.discussionId}`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function editDiscussionsByNoteId(data: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/discussions/${data.discussionId}/notes/${data.note_id}`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteDiscussionsByNoteId(data: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/discussions/${data.discussionId}/notes/${data.note_id}`,
|
||||
method: 'delete',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function getRepoCommits(params: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${params.repoId}/repository/commits`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function addRepoCommits(data: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${data.repoId}/repository/commits`,
|
||||
method: 'post',
|
||||
data
|
||||
}, {
|
||||
customError: true
|
||||
});
|
||||
}
|
||||
|
||||
export function getRepoCommitsDetail(params: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${params.repoId}/repository/commits/${params.commitId}`,
|
||||
method: 'get',
|
||||
params: {
|
||||
auth_current_project: params.auth_current_project
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function addRepoCommitsComments(data: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/comments`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
export function getRepoCommitsComments(data: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/comments`,
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
export function getRepoCommitsDiff(data: types.commonCommitReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/diff`,
|
||||
method: 'get',
|
||||
params: data
|
||||
}), data);
|
||||
}
|
||||
export function getRepoCommitsFileDiff(repoId, commitId, data: types.commonCommitReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${repoId}/repository/commits/${commitId}/file_diff`,
|
||||
method: 'get',
|
||||
params: data
|
||||
}), data);
|
||||
}
|
||||
export function getRepoMergeRequests(data: types.commonCommitReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/merge_requests`,
|
||||
method: 'get',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
export function getCommitCommentDetail(data: types.commonCommitReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/discussions/${data.discussion_id}/notes/${data.note_id}`,
|
||||
method: 'get',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// commit revert
|
||||
export function commitRevert(repoId: string, commitId: string, data: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${repoId}/repository/commits/${commitId}/revert`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// commit cherry-pick
|
||||
export function commitCherryPick(repoId: string, commitId: string, data: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${repoId}/repository/commits/${commitId}/cherry_pick`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function getCommitMsgRegexTemplate(params: types.commonCommitReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/projects/${params.repoId}/common/commitMsgRegexTemplate`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 保存commit设置
|
||||
export function updateCommitSetting(data: types.commonCommitReqType, repoId: string): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/projects/${repoId}/project_git_hook`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function getCommitSetting(repoId: string): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/projects/${repoId}/project_git_hook`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
9
src/api/commit/types.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { type errorType } from '@/api/types/common';
|
||||
|
||||
export interface commonCommitReqType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonCommitResType extends errorType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
32
src/api/common/index.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/common/types';
|
||||
import { reqCatch } from '@/utils/catch';
|
||||
|
||||
export function upload(data: types.commonReqType): Promise<types.commonResType> {
|
||||
return request({
|
||||
url: `/api/v1/upload`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 当前用户-项目权限
|
||||
export function getRepoPermission(params: { repo_id: string }) {
|
||||
const { repo_id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${repo_id}/role`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 当前用户-组织权限
|
||||
export function getOrgPermission(params:{group_id:string}): Promise<any> {
|
||||
const { group_id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/groups/${group_id}`,
|
||||
method: 'get',
|
||||
params
|
||||
}, {
|
||||
customError: true
|
||||
}));
|
||||
}
|
||||
9
src/api/common/types.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { type errorType } from '@/api/types/common';
|
||||
|
||||
export interface commonReqType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonResType extends errorType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
93
src/api/discussion/hook.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { ref } from 'vue';
|
||||
import { useAccountStore } from '@/stores/user';
|
||||
import { orgInfoStore } from '@/stores/Org/index';
|
||||
import { repoInfoStore } from '@/stores/Repo/index';
|
||||
import { getSettingsValues } from '@/api/repo';
|
||||
import { getOrgDiscussionSettings } from '@/api/org';
|
||||
import { useRepoId } from '@/utils/hooks/useRepoId';
|
||||
import type {
|
||||
repoAndOrgSettingDictType
|
||||
} from '@/api/discussion/types';
|
||||
|
||||
/**
|
||||
* 获取用户信息+是否登录
|
||||
*/
|
||||
export function useDiscussGetUserInfo() {
|
||||
const { isLogin = false, accountInfo: userInfo = {}} = useAccountStore();
|
||||
return { isLogin, userInfo };
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询讨论模块是否开启,返回组织/项目id,用于讨论接口请求
|
||||
* @param source_type 1 组织,2项目
|
||||
* @param orgNamespace 组织 namespace
|
||||
* 项目使用 useRepoId 获取 namespace
|
||||
*/
|
||||
export function useDiscussionOpen(source_type = 1, orgNamespace = '') {
|
||||
const discussOpen = ref('0'); // 讨论模块是否打开:0关闭,1打开
|
||||
const id = ref(''); // 项目/组织id
|
||||
const project_id = ref(''); // 项目fullpath,不带%2F
|
||||
|
||||
async function getDiscussionStatus() {
|
||||
if (source_type === 1) {
|
||||
// 组织讨论模块状态查询
|
||||
const { orgInfo } = orgInfoStore();
|
||||
const { module_setting } = orgInfo;
|
||||
|
||||
// 有 store 数据,从 store 取
|
||||
if (orgNamespace === orgInfo.name && module_setting?.group_id) {
|
||||
id.value = module_setting.group_id;
|
||||
discussOpen.value = module_setting.modules.find(
|
||||
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
|
||||
)?.value || '0';
|
||||
} else {
|
||||
// 无 store 数据,接口获取
|
||||
const res = await getOrgDiscussionSettings({ orgId: orgNamespace });
|
||||
if (!res.error) {
|
||||
const resData = res?.data;
|
||||
id.value = resData.group_id;
|
||||
const discussStatus = resData.modules.find(
|
||||
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
|
||||
).value; // 组织讨论是否开启, '0'关闭,'1'开启
|
||||
if (discussStatus === '1') {
|
||||
discussOpen.value = '1';
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const { repoInfo } = repoInfoStore();
|
||||
const { module_setting } = repoInfo;
|
||||
|
||||
// 完整路径,供上传使用
|
||||
const { repoId: fullRepoPath } = useRepoId('/');
|
||||
fullRepoPath && (project_id.value = fullRepoPath.value);
|
||||
|
||||
// 有 store 数据,从 store 取
|
||||
if (module_setting?.repo_id) {
|
||||
id.value = module_setting.repo_id;
|
||||
discussOpen.value = module_setting.modules.find(
|
||||
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
|
||||
)?.value || '0';
|
||||
} else {
|
||||
// 无 store 数据,接口获取
|
||||
const { repoId } = useRepoId();
|
||||
const res = await getSettingsValues({
|
||||
repoId: repoId.value
|
||||
});
|
||||
if (!res.error) {
|
||||
const resData = res?.data?.data;
|
||||
id.value = resData.repo_id;
|
||||
const discussStatus = resData.modules.find(
|
||||
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
|
||||
).value; // 项目讨论是否开启, '0'关闭,'1'开启
|
||||
if (discussStatus === '1') {
|
||||
discussOpen.value = '1';
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return { id, discussOpen, project_id, getDiscussionStatus };
|
||||
}
|
||||
477
src/api/discussion/index.ts
Normal file
@@ -0,0 +1,477 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/discussion/types';
|
||||
import { reqCatch } from '@/utils/catch';
|
||||
import type { categoryType } from '@/api/discussion/types';
|
||||
|
||||
// ---------------------------- discussion CRUD ----------------------------- //
|
||||
// 新增讨论
|
||||
export function discussSave(data: types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// discussion 列表
|
||||
export function discussList(data: types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/page',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 删除讨论
|
||||
export function discussDelete(data: {id:string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss',
|
||||
method: 'delete',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 更新讨论
|
||||
export function discussUpdate(data: types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss',
|
||||
method: 'put',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// ---------------------------- discussion 详情操作 ----------------------------- //
|
||||
|
||||
// discuss 详情
|
||||
export function discussDetail(data: {source_id: string, source_type:number, serial_number:string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/detail',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 讨论新建-组织可 @ 成员列表
|
||||
// TODO: 暂未提供
|
||||
export function discussOrgMembers(data: types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/org/v1/member/list',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 讨论新建 - 项目可 @ 成员列表
|
||||
export function discussRepoMembers(params: { repoId: string, page?: number, per_page?: number }): Promise<any> {
|
||||
const { repoId, ...param } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${repoId}/members/all`,
|
||||
method: 'get',
|
||||
params: Object.assign({ page: 1, per_page: 10 }, param)
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 讨论详情,更改 discuss 关联标签
|
||||
export function discussChangeRelatedLabels(data:{discuss_id:string;label:string[]}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/label',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 查询讨论关联用户列表,需要登录
|
||||
export function discussDetailRelatedUsers(params:{source_id:string}) {
|
||||
const { source_id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/relateUser/${source_id}`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 查询讨论最近活动用户,不需要登录
|
||||
export function discussDetailRecentActiveUsers(params:{source_id:string}) {
|
||||
const { source_id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/recentActivity/${source_id}`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// discussion 讨论-总列表置顶/取消置顶
|
||||
export function discussPin(data:{id: string;is_pin: 0|1}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/changePin',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// discussion 分类置顶/取消置顶
|
||||
export function disussTypePin(data:{id: string;is_pin: 0|1}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/changeCatePin',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 关闭/重新打开 讨论
|
||||
export function discussClose(data:{id: string;state: number}): Promise<any> {
|
||||
// 讨论的状态:0:打开;1:正常关闭;2:过期关闭;3:重复关闭
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/changeState',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 讨论锁定/解锁
|
||||
export function disussionLock(data:{id: string;is_lock: 0|1}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/changeLock',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 更换已创建讨论的分类 - 侧边栏操作
|
||||
export function discussChangeType(data:{id: string;category_id: string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/changeCate',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 讨论-投票
|
||||
export function discussVote(data:{discuss_id:string;option_id:string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/vote',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 讨论 - 点赞
|
||||
// targetType - 点赞的主体类型:1:讨论;2:评论;3:评论回复
|
||||
export function discussLike(data:{target_id:string; target_type:number}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/like',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 讨论 - 取消点赞
|
||||
// targetType - 点赞的主体类型:1:讨论;2:评论;3:评论回复
|
||||
export function discussUnLike(data:{target_id:string; target_type:number}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/unlike',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// ---------------------------- discussion 评论操作 ----------------------------- //
|
||||
// 评论列表
|
||||
export function commentList(data:{discuss_id: string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/comment/page',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 新增评论
|
||||
export function commentSave(data:types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/comment',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 编辑评论
|
||||
export function commentUpdate(data:types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/comment',
|
||||
method: 'put',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 删除评论
|
||||
export function commentDelete(data:{id:string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/comment',
|
||||
method: 'delete',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 标记评论或者回复为答案
|
||||
export function commentRemark(data:{id: string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/comment/remark',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 取消标记评论或者回复为答案
|
||||
export function commentUnremark(data:{id: string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/comment/unremark',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// ---------------------------- discussion 评论-回复 操作 ----------------------------- //
|
||||
|
||||
// 查询评论的回复列表
|
||||
export function replyList(data:{parent_id: string, page:number; size:number }): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/comment/reply/page',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 新增回复
|
||||
export function replySave(data:types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/comment/reply',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 编辑回复
|
||||
export function replyUpdate(data:types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/comment/reply',
|
||||
method: 'put',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 删除回复
|
||||
export function replyDelete(data:{id:string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/comment/reply',
|
||||
method: 'delete',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// ---------------------------- 分类type CRUD ----------------------------- //
|
||||
|
||||
// 获取讨论分类的基础类型(字典)
|
||||
export function categoryBasicType(params:types.commonDiscussionReqType) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/category/type`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 获取某个项目或仓库下的所有讨论分类
|
||||
export function getAllTypes(params: {id: string;source_type:number}) {
|
||||
const { id, source_type } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/category/list/${id}/${source_type}`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 获取某个项目或者仓库下的所有讨论分类和分组
|
||||
// 用于「管理内容分类」页
|
||||
export function getAllSectionAndTypes(params: {source_id: string, source_type:number}) {
|
||||
const { source_id, source_type } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/category/all/${source_id}/${source_type}`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 新增讨论分类 type
|
||||
export function typeSave(data:types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/category',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 讨论分类 type 详情
|
||||
export function typeDetail(params: {id: string|undefined}):Promise<any> {
|
||||
const { id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/category/detail/${id}`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 更新 type
|
||||
export function typeUpdate(data:types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/category',
|
||||
method: 'put',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 删除讨论分类 type
|
||||
export function typeDelete(data:{id: string, transfer_id?:string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/category',
|
||||
method: 'delete',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// ---------------------------- section CRUD ----------------------------- //
|
||||
// 新增 section
|
||||
export function sectionSave(data:types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/section',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// section 详情
|
||||
export function sectionDetail(params: {id: string|undefined}) {
|
||||
const { id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/section/detail/${id}`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 更新 section
|
||||
export function sectionUpdate(data:types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/section',
|
||||
method: 'put',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 删除 section
|
||||
export function sectionDelete(data:{id: string}): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/section',
|
||||
method: 'delete',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 根据分组 id 获取下面所有内容分类
|
||||
export function sectionOwnCategory(params: {section_id: string}) {
|
||||
const { section_id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/category/section/${section_id}`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 查询仓库/组织下的讨论分组
|
||||
export function getAllSections(params: {source_id: string; source_type:number}) {
|
||||
const { source_id, source_type } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/section/list/${source_id}/${source_type}`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// ----------------------------------- else --------------------------//
|
||||
|
||||
// 组织标签列表
|
||||
// TODO: 组织还没有标签
|
||||
export function orgLabelList(params: {group_id:string}): Promise<any> {
|
||||
const { group_id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v4/groups/${group_id}/labels`,
|
||||
method: 'get',
|
||||
params: { page: 1, per_page: 20 }
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 仓库标签列表
|
||||
export function repoLabelList(params: {project_id:string}): Promise<any> {
|
||||
const { project_id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${project_id}/labels`,
|
||||
method: 'get',
|
||||
params: { page: 1, per_page: 20 }
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 当前用户-项目权限
|
||||
export function getRepoPermission(params: { repo_id: string }) {
|
||||
const { repo_id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${repo_id}/role`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 当前用户-组织权限
|
||||
export function getOrgPermission(params:{group_id:string}): Promise<any> {
|
||||
const { group_id } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/groups/${group_id}`,
|
||||
method: 'get',
|
||||
params
|
||||
}, {
|
||||
customError: true
|
||||
}));
|
||||
}
|
||||
|
||||
// 获取社区热心榜单
|
||||
export function getAnswerRank(params: {source_id: string, source_type:number}): Promise<any> {
|
||||
const { source_id, source_type } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/answerSort/${source_id}/${source_type}`,
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
// ------------------------------ Dashboard 我的讨论,我参与的讨论 ---------------------------------------------------//
|
||||
// 我创建的讨论列表
|
||||
export function myCreatedDiscuss(data:types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/my/page',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 我参与的讨论列表
|
||||
export function myJoineddDiscuss(data:types.commonDiscussionReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/discuss/join/page',
|
||||
method: 'post',
|
||||
data
|
||||
}), data);
|
||||
}
|
||||
|
||||
// 获取评论原始数据
|
||||
export function getDiscussionOriginalData(id: string) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/comment/origin_detail/${id}`,
|
||||
method: 'get',
|
||||
params: {}
|
||||
}));
|
||||
}
|
||||
|
||||
// 获取评论详情, 子评论的话, 同时获取父级评论信息
|
||||
export function getDiscussionDetail(id: string) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/discuss/comment/detail/${id}`,
|
||||
method: 'get',
|
||||
params: {}
|
||||
}));
|
||||
}
|
||||
208
src/api/discussion/types.ts
Normal file
@@ -0,0 +1,208 @@
|
||||
import { type errorType } from '@/api/types/common';
|
||||
|
||||
export interface commonDiscussionReqType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonDiscussionResType extends errorType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonDictType {
|
||||
label: string;
|
||||
value: string;
|
||||
desc?: string; // 描述
|
||||
color?: string;
|
||||
hover_color?: string;
|
||||
children?: any[];
|
||||
}
|
||||
|
||||
export interface commonPaginationType {
|
||||
page: number;
|
||||
size: number;
|
||||
}
|
||||
|
||||
export interface discussionListItemType {
|
||||
id: string; // 讨论id
|
||||
title: string;
|
||||
section_id?: string;
|
||||
category_id?: string;
|
||||
category_type?: number; // 讨论类型,4种,1-开放讨论,2-问答,3-公告,4-投票
|
||||
category_icon?:string;
|
||||
category_name?: string;
|
||||
comment_total?: number; // 评论总数
|
||||
reply_total?: number; // 回复总数
|
||||
like_total?: number | null;
|
||||
is_like?: boolean; // 是否已点赞: true 已点赞,false 未点赞
|
||||
is_lock?: number; // 是否锁定:0:否;1:是;
|
||||
is_pin?: number; // 是否置顶:0:否;1:是;
|
||||
pin_date?: string;
|
||||
is_category_pin?: number; // 是否分类置顶
|
||||
pin_category_date?: string;
|
||||
is_closed?: number; // 是否关闭
|
||||
closed_date?: string;
|
||||
is_answered?: number; // 回答是否采纳,0:否;1:是;
|
||||
label?: string[]; // labels
|
||||
serial_number?: number; // 顺序号
|
||||
created_by?: string; // 创建者id
|
||||
created_by_user_name?: string;
|
||||
created_by_user_photo?: string;
|
||||
created_date?: string;
|
||||
last_modified_date?: string;
|
||||
category:categoryType; // 分类信息
|
||||
source_type?:number; // 组织1,项目2
|
||||
source_id?:string;
|
||||
}
|
||||
|
||||
export interface RadioOption<T> {
|
||||
value: T;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface repoAndOrgSettingDictType {
|
||||
key:string;
|
||||
type:string;
|
||||
value:string;
|
||||
};
|
||||
|
||||
// 讨论分类 || 讨论分组 itemType
|
||||
export interface discussionTypeOrSection {
|
||||
id: string;
|
||||
icon: string;
|
||||
title: string;
|
||||
desc?: string;
|
||||
answerAcceptEnable?: boolean;
|
||||
isGroup: boolean;
|
||||
categoryType?:number;
|
||||
}
|
||||
|
||||
export interface categoryType {
|
||||
id: string; // categoryId
|
||||
category_name: string;
|
||||
category_desc?: string;
|
||||
category_type: number; // 讨论类型,4种,1-开放讨论,2-问答,3-公告,4-投票,不过现在有个专门的接口来查
|
||||
section_id?: string; // 所属分组
|
||||
category_icon: string; // icon
|
||||
}
|
||||
|
||||
export interface sectionType {
|
||||
id:string;
|
||||
section_name:string;
|
||||
section_icon:string;
|
||||
}
|
||||
|
||||
export interface sectionOwnCategoryType extends sectionType {
|
||||
category_list: categoryType[];
|
||||
}
|
||||
|
||||
export interface sectionItemType {
|
||||
unSection?: categoryType[];
|
||||
section: sectionOwnCategoryType[];
|
||||
}
|
||||
|
||||
export interface discussDetailType {
|
||||
id:string;
|
||||
category_id:string;
|
||||
category?:categoryType;
|
||||
created_by?:string;
|
||||
created_date?:string;
|
||||
created_by_user_name?:string;
|
||||
created_by_user_photo?:string;
|
||||
serial_number:number;
|
||||
title:string;
|
||||
content:string;
|
||||
md_content:string;
|
||||
is_lock:number; // 是否锁定:1:是;0:否
|
||||
is_pin:number;
|
||||
pin_date?:string;
|
||||
is_category_pin:number;
|
||||
pin_category_date?:string;
|
||||
is_closed:number; // 是否关闭:1:是;0:否
|
||||
closed_date?:string;
|
||||
is_answered:number;
|
||||
comment_total:number;
|
||||
reply_total?:number;
|
||||
like_total?:number;
|
||||
is_like?:boolean;
|
||||
question?:questionInfoType;
|
||||
options?:quesitonOptionType[];
|
||||
is_vote?:boolean; // 是否投过票
|
||||
option_id?:string; // 投过票的id
|
||||
label?:string[]; // 关联的 labels
|
||||
is_edit?:boolean; // 投票类型的讨论 - 更新时是否变更了投票内容(标题 + 选项)
|
||||
}
|
||||
|
||||
export interface commentType {
|
||||
id:string;
|
||||
content?:string;
|
||||
md_content:string;
|
||||
discuss_id?:string;
|
||||
parent_id?:string;
|
||||
serial_number?:number;
|
||||
source_id?:string;
|
||||
source_type?:number;
|
||||
last_modified_date?:string;
|
||||
last_modified_by?:string;
|
||||
created_by?:string;
|
||||
created_date?:string;
|
||||
created_by_user_name?:string;
|
||||
created_by_user_photo?:string;
|
||||
ip?:string;
|
||||
is_hide?:number; // 是否隐藏评论
|
||||
reply_total?:number;
|
||||
like_total?:number;
|
||||
is_like?:boolean; // true:已点赞;false:未点赞
|
||||
is_deleted?:number;
|
||||
is_remark?: number; // 是否采纳为答案:1:是;0:否
|
||||
replyCover?: any;
|
||||
}
|
||||
|
||||
export interface questionInfoType {
|
||||
created_by:string;
|
||||
created_date:string;
|
||||
id:string;
|
||||
last_modified_by?:string;
|
||||
last_modified_date?:string;
|
||||
question:string; // 投票的标题
|
||||
vote_total:number; // 投票参与总人数
|
||||
}
|
||||
|
||||
// 投票选项信息
|
||||
export interface quesitonOptionType {
|
||||
created_by:string;
|
||||
created_date:string;
|
||||
id:string; // 投票选项id
|
||||
last_modified_by?:string;
|
||||
last_modified_date?:string;
|
||||
option_order:number; // 投票选项顺序
|
||||
vote_id:string;
|
||||
vote_option:string;
|
||||
vote_total:number;
|
||||
vote_total_percent:number; // 选项投票百分比
|
||||
}
|
||||
|
||||
export interface ISidebar {
|
||||
id?:string; // discuss id,详情页才显示参与者和操作按钮组
|
||||
labelDicts?:commonDictType[]; // 标签字典
|
||||
checkedLabelIds?:string[]; // 已关联 label ids
|
||||
checkedLabels?:commonDictType[]; // 要渲染的已选label list
|
||||
setLabels?:Function; // emit 关联标签
|
||||
categoryDicts?:commonDictType[];
|
||||
checkedCategoryId?:string;
|
||||
checkedCategory?:commonDictType;
|
||||
changeCategory?:Function;
|
||||
participators?:any[];
|
||||
}
|
||||
|
||||
export interface userInfoType {
|
||||
domain_id?: string
|
||||
email?: string
|
||||
id?: string
|
||||
mobile?: string
|
||||
nickname?: string
|
||||
username?: string
|
||||
access_token?: string
|
||||
refresh_token?: string
|
||||
xauth_token?: string
|
||||
[x: string]: any
|
||||
}
|
||||
105
src/api/home/index.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/home/types';
|
||||
import { reqCatchV2, type catchRt } from '@/utils/catch';
|
||||
|
||||
// 获取banner
|
||||
export function getBanner(): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/banner`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
// 获取活跃社区
|
||||
export function getCommunity(): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/active_community`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
// 获取精选项目
|
||||
export function getSelectedRepo(): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/selected_projects`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
// 获取运营广告
|
||||
export function getAdvertisement(): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/advertisement`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
// 获取推荐项目列表
|
||||
export function getRecommendedRepos(): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/recommended_projects`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
// 获取活跃组织列表
|
||||
export function getActiveOrganization(): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/active_organization`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
// 活跃社区项目列表
|
||||
export function getCommunityActiveRepos(): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/community_active_repos`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
// 活跃社区项目列表
|
||||
export function getDynamicRemarks(): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/dynamic_remarks`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 首页搜索
|
||||
export function homeSearchProject(params: {search:string}): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/projects/search`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
// 首页全球精选开源组织
|
||||
export function globalFeaturedGroups(): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/groups/global/featured`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
// 全球精选开源项目
|
||||
export function globalFeaturedProjects(params:{
|
||||
group_id:string
|
||||
page:number
|
||||
per_page:number
|
||||
}): Promise<types.commonHomeResType> {
|
||||
return request({
|
||||
url: `/api/v1/home_page/projects/global/featured`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取搜索历史记录
|
||||
export function getSearchHistory(params: object): catchRt<types.commonHomeResType> {
|
||||
return reqCatchV2(() => request({
|
||||
url: `/api/v1/search/searchHistory`,
|
||||
method: 'get',
|
||||
params
|
||||
}));
|
||||
}
|
||||
|
||||
// 删除搜索历史记录
|
||||
export function delSearchHistory({ thread_id }:{thread_id:string}): catchRt<types.commonHomeResType> {
|
||||
return reqCatchV2(() => request({
|
||||
url: `/api/v1/search/searchHistory/${thread_id}`,
|
||||
method: 'delete'
|
||||
}));
|
||||
}
|
||||
30
src/api/home/types.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { type errorType } from '@/api/types/common';
|
||||
|
||||
export interface commonHomeReqType extends errorType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonHomeResType extends errorType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
// 搜索项目信息
|
||||
export interface projectSearchInfo {
|
||||
id: number;
|
||||
description: string;
|
||||
name: string;
|
||||
namespace: string;
|
||||
name_with_namespace: string;
|
||||
path: string;
|
||||
path_with_namespace: string;
|
||||
web_url: string;
|
||||
star_count: number;
|
||||
forks_count: number;
|
||||
starred: true;
|
||||
created_at: string;
|
||||
last_activity_at: string;
|
||||
main_repository_language: string[];
|
||||
star_count_seven: number;
|
||||
license?: string;
|
||||
topic?: {topic_id:string, name:string}[]
|
||||
}
|
||||
218
src/api/issue/index.ts
Normal file
@@ -0,0 +1,218 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/issue/types';
|
||||
import { reqCatch, reqCatchV2, type catchRt } from '@/utils/catch';
|
||||
|
||||
export function createIssue(data: types.createIssueReqType): Promise<types.createIssueResType> {
|
||||
return request({
|
||||
url: `/api/v1/issue/${data.project_id}/issues`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
export function deleteIssue(params: types.createIssueReqType): Promise<types.createIssueResType> {
|
||||
return request({
|
||||
url: `/api/v1/issue/${params.project_id}/issues/${params.issue_iid}`,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
export function updateIssue(data: types.updateIssueReqType): Promise<types.updateIssueResType> {
|
||||
const { project_id, issue_iid } = data;
|
||||
delete data.project_id;
|
||||
delete data.issue_iid;
|
||||
return request({
|
||||
url: `/api/v1/issue/${project_id}/issues/${issue_iid}`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭或打开issue
|
||||
export function updateIssueStat(data: types.updateIssueStatReqType): Promise<types.updateIssueStatResType> {
|
||||
const { project_id, issue_iid } = data;
|
||||
delete data.project_id;
|
||||
delete data.issue_iid;
|
||||
return request({
|
||||
url: `/api/v1/issue/${project_id}/issues/${issue_iid}/close`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchIssue(params: types.fetchIssueReqType): Promise<types.fetchIssueResType> {
|
||||
return request({
|
||||
url: `/api/v1/issue/${params.project_id}/issues/${params.issue_iid}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 项目issue列表
|
||||
export function fetchIssueList(params: types.fetchIssueListReqType): Promise<types.fetchIssueListResType> {
|
||||
return request({
|
||||
url: `/api/v1/issue/${params.project_id}/issues`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function createIssueDiscussions(data: types.createIssueDiscussionsReqType): Promise<types.createIssueDiscussionsResType> {
|
||||
return request({
|
||||
url: `/api/v1/issue/${data.project_id}/issues/${data.issue_iid}/discussions`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function updateIssueDiscussions(data: types.updateIssueDiscussionsReqType): Promise<types.updateIssueDiscussionsResType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${data.project_id}/issues/${data.issue_iid}/notes/${data.note_id}`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteIssueDiscussions(params: types.deleteIssueDiscussionsReqType): Promise<types.deleteIssueDiscussionsResType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${params.project_id}/issues/${params.issue_iid}/notes/${params.note_id}`,
|
||||
method: 'delete',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchIssueDiscussions(params: types.fetchIssueDiscussionsResType): Promise<types.fetchIssueDiscussionsResType> {
|
||||
return request({
|
||||
url: `/api/v1/issue/${params.project_id}/issues/${params.issue_iid}/discussions`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
// 获取issue单条评论
|
||||
export function fetchIssueNote(params: types.fetchIssueDiscussionsResType): Promise<types.fetchIssueDiscussionsResType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${params.project_id}/issues/${params.issue_iid}/notes/${params.note_id}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 回复issue评论
|
||||
export function freplyIssueDiscussions(data: types.createIssueReqType): Promise<types.createIssueResType> {
|
||||
return request({
|
||||
url: `/api/v1/issue/api/v4/projects/${data.project_id}/issues/${data.issue_iid}/discussions/${data.discussion_id}/notes`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// issue参与者
|
||||
export function issueParticipants(data: types.issueParticipantsResType): Promise<types.issueParticipantsReqType> {
|
||||
return request({
|
||||
url: `/api/v1/issue/${data.project_id}/issues/${data.issue_iid}/participants`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// issue 精选
|
||||
export function pinIssue(params: types.pinIssueReqType): Promise<types.pinIssueResType> {
|
||||
return request({
|
||||
url: `/api/v1/featured/${params.type}`,
|
||||
method: 'post',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function deletePinIssue(params: types.deletePinIssueReqType): Promise<types.deletePinIssueResType> {
|
||||
return request({
|
||||
url: `/api/v1/featured/${params.type}`,
|
||||
method: 'delete',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 精选排序
|
||||
export function sortPinIssue(data): Promise<types.pinIssueListResType> {
|
||||
const { type, group_id, body } = data;
|
||||
return request({
|
||||
url: `/api/v1/featured/${type}/resort?group_id=${group_id}`,
|
||||
method: 'put',
|
||||
data: body
|
||||
});
|
||||
}
|
||||
|
||||
export function pinIssueList(params: types.pinIssueListReqType): Promise<types.pinIssueListResType> {
|
||||
return request({
|
||||
url: `/api/v1/featured/projects/${params.project_id}/issues`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 我的issue列表
|
||||
export function myIssueList(params: types.fetchIssueListReqType): Promise<types.fetchIssueListResType> {
|
||||
return request({
|
||||
url: `/api/v1/issues`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 我的issue列表数量
|
||||
export function myIssueListState(params: types.myIssueListStateReptype): Promise<types.myIssueListStateRestype> {
|
||||
return request({
|
||||
url: `/api/v1/issues/statistics`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
// 组织的issue列表
|
||||
export function groupIssueList(params: types.fetchIssueListResType): Promise<types.fetchIssueListResType> {
|
||||
const { group_id } = params;
|
||||
delete params.group_id;
|
||||
return request({
|
||||
url: `/api/v1/groups/${group_id}/issues`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
// 获取issue关联的PR列表
|
||||
export function getIssuePRList(params: types.fetchIssueListResType): Promise<types.fetchIssueListResType> {
|
||||
const { project_id, issue_iid } = params;
|
||||
delete params.project_id;
|
||||
delete params.issue_iid;
|
||||
return request({
|
||||
url: `/api/v1/issue/${project_id}/issues/${issue_iid}/linked_merge_requests`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
// issue关联PR
|
||||
export function issueRelatePR(data: types.updateIssueReqType): Promise<types.fetchIssueListResType> {
|
||||
return reqCatch(
|
||||
() => request({
|
||||
url: `/api/v1/issue/${data.project_id}/issues/${data.issue_id}/merge_request/${data.merge_request_id}/linked_merge_requests`,
|
||||
method: 'post'
|
||||
})
|
||||
,
|
||||
data
|
||||
);
|
||||
}
|
||||
// issue取消关联PR
|
||||
export function issueDeletePR(params: types.updateIssueReqType): Promise<types.fetchIssueListResType> {
|
||||
return reqCatch(
|
||||
() => request({
|
||||
url: `/api/v1/issue/${params.project_id}/issues/${params.issue_id}/linked_merge_requests/${params.merge_request_id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
,
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
// 获取issue模版列表
|
||||
export function fetchIssueTemplateList(project_id: string): Promise<Record<string, any>> {
|
||||
return request({
|
||||
url: `/api/v2/projects/${project_id}/repository/template/issue`,
|
||||
method: 'get',
|
||||
params: {}
|
||||
}).catch((e) => {
|
||||
return { data: [], error_code: e };
|
||||
});
|
||||
}
|
||||
322
src/api/issue/types.ts
Normal file
@@ -0,0 +1,322 @@
|
||||
export interface createIssueReqType {
|
||||
project_id?: string;
|
||||
issue_iid?: number;
|
||||
title?: string;
|
||||
description?: string;
|
||||
updated_at?: string;
|
||||
state_event?: 'reopen' | 'close';
|
||||
assignee_id?: number;
|
||||
assignee_ids?: string[];
|
||||
milestone_id?: number;
|
||||
labels?: ILabel[] | string[];
|
||||
due_date?: string;
|
||||
confidential?: boolean;
|
||||
discussion_locked?: true;
|
||||
created_at?: string;
|
||||
issue_category?: string;
|
||||
issue_stage?: string;
|
||||
issue_severity?: string;
|
||||
pbi_id?: number;
|
||||
proposer_id?: string[];
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface createIssueResType extends IIssue {
|
||||
[propName: string]: any;
|
||||
}
|
||||
export interface deleteIssueReqType {
|
||||
project_id: string;
|
||||
issue_iid: number;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface deleteIssueResType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface createIssueDiscussionsResType extends IIssue {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface createIssueDiscussionsReqType {
|
||||
project_id: string;
|
||||
issue_iid: number;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface fetchIssueResType {
|
||||
project_id: string;
|
||||
issue_iid: number;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface fetchIssueReqType extends IIssue {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface fetchIssueListReqType {
|
||||
project_id: string;
|
||||
state?: string;
|
||||
sort?: string;
|
||||
scope?: string;
|
||||
search?: string;
|
||||
page?: number;
|
||||
per_page?: number;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface fetchIssueListResType extends IIssue {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface myIssueListStateReptype {
|
||||
state: string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface myIssueListStateRestype extends IIssue {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface issueParticipantsResType {
|
||||
project_id: string;
|
||||
issue_iid: number;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface issueParticipantsReqType extends IAuthor {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface fetchIssueDiscussionsResType {
|
||||
project_id: string;
|
||||
issue_iid: number;
|
||||
type: 'user';
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface fetchIssueDiscussionsReqType extends Idiscussions {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface updateIssueReqType extends createIssueReqType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface updateIssueResType extends IIssue {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface updateIssueStatReqType extends createIssueReqType {
|
||||
discussions?: string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface updateIssueStatResType extends IIssue {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface updateIssueDiscussionsReqType {
|
||||
project_id: string;
|
||||
issue_iid: number;
|
||||
note_id: string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface updateIssueDiscussionsResType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
export interface deleteIssueDiscussionsReqType {
|
||||
project_id: string;
|
||||
issue_iid: number;
|
||||
note_id: string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface deleteIssueDiscussionsResType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
export interface pinIssueReqType {
|
||||
type: 'project_issue';
|
||||
resource_id: number | string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface pinIssueResType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
export interface deletePinIssueReqType {
|
||||
type: 'project_issue';
|
||||
group_id: string;
|
||||
resource_id: string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface deletePinIssueResType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
export interface sortPinIssueReqType {
|
||||
type: 'project_issue';
|
||||
group_id: string;
|
||||
body: string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface sortPinIssueResType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
export interface pinIssueListReqType {
|
||||
project_id: string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface pinIssueListResType {
|
||||
object_id: string,
|
||||
type: string,
|
||||
resource_id: string,
|
||||
nextResource_id: string
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
// 用户
|
||||
export interface IAuthor {
|
||||
id: number;
|
||||
name: string;
|
||||
username: string;
|
||||
state: 'active' | string;
|
||||
avatar_url: string;
|
||||
avatar_path?: string;
|
||||
email?: string;
|
||||
name_cn: string;
|
||||
web_url: string;
|
||||
nick_name?: string;
|
||||
tenant_name?: string;
|
||||
avatar?: string;
|
||||
nickname?: string;
|
||||
is_member?: string;
|
||||
}
|
||||
|
||||
// 项目
|
||||
export interface IProject {
|
||||
id: number;
|
||||
description?: string;
|
||||
name: string;
|
||||
name_with_namespace: string;
|
||||
path: string;
|
||||
path_with_namespace: string;
|
||||
develop_mode?: 'normal' | string;
|
||||
created_at: string;
|
||||
updated_at?: string;
|
||||
archived: false;
|
||||
is_kia: false;
|
||||
ssh_url_to_repo: string;
|
||||
http_url_to_repo: string;
|
||||
web_url: string;
|
||||
readme_url?: string;
|
||||
product_id?: string;
|
||||
product_name?: string;
|
||||
}
|
||||
|
||||
// issue
|
||||
export interface IIssue {
|
||||
id?: number;
|
||||
iid?: number;
|
||||
project_id?: number;
|
||||
title?: string;
|
||||
description?: string;
|
||||
editIng?: boolean;
|
||||
saveIng?: boolean;
|
||||
editText?: string;
|
||||
state?: 'opened' | 'closed' | 'all';
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
closed_at?: string;
|
||||
closed_by?: string;
|
||||
labels?: ILabel[];
|
||||
milestone?: string;
|
||||
assignees?: [];
|
||||
author?: IAuthor;
|
||||
assignee?: string;
|
||||
user_notes_count?: number;
|
||||
merge_requests_count?: number;
|
||||
confidential?: boolean;
|
||||
discussion_locked?: boolean;
|
||||
web_url?: string;
|
||||
time_stats?: {
|
||||
time_estimate?: string
|
||||
total_time_spent?: string
|
||||
human_time_estimate?: string
|
||||
human_total_time_spent?: string
|
||||
};
|
||||
project_path_with_namespace?: string;
|
||||
project?: IProject;
|
||||
root_project_id?: string;
|
||||
subscribed?: boolean;
|
||||
related_merge_request?: string;
|
||||
linked_merge_requests?: [];
|
||||
related_note_params?: null;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
// 评论
|
||||
export interface INote {
|
||||
id: number | string;
|
||||
type: 'DiscussionNote' | string;
|
||||
body: string;
|
||||
attachment?: null;
|
||||
author: IAuthor;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
system?: boolean;
|
||||
noteable_id: number;
|
||||
noteable_type: 'Issue' | string;
|
||||
commit_id?: string;
|
||||
resolvable?: boolean;
|
||||
is_reply?: boolean;
|
||||
resolved_by?: null;
|
||||
noteable_iid: number;
|
||||
discussion_id: string;
|
||||
project: string;
|
||||
diff_file?: null;
|
||||
diff: string;
|
||||
archived: boolean;
|
||||
review_categories?: null;
|
||||
review_categories_cn: string;
|
||||
review_categories_en: string;
|
||||
review_modules?: null;
|
||||
severity: 'suggestion';
|
||||
severity_cn: '建议' | string;
|
||||
severity_en: 'Suggestion' | string;
|
||||
file_path?: string;
|
||||
line?: string;
|
||||
assignee?: string;
|
||||
proposer: IAuthor;
|
||||
}
|
||||
|
||||
// 评论
|
||||
export interface Idiscussions extends INote {
|
||||
id: string | number,
|
||||
individual_note?: boolean,
|
||||
notes: INote[],
|
||||
project_id: number,
|
||||
project_full_path: string,
|
||||
deleted_file?: null,
|
||||
new_file?: null,
|
||||
added_lines?: null,
|
||||
removed_lines?: null,
|
||||
issue?: null,
|
||||
merge_request_version_params?: null,
|
||||
amode?: null,
|
||||
bmode?: null
|
||||
}
|
||||
|
||||
// 标签
|
||||
export interface ILabel {
|
||||
color: string;
|
||||
description: string;
|
||||
expires_at?: string
|
||||
id: number
|
||||
is_expired: boolean;
|
||||
name: string;
|
||||
text_color: string;
|
||||
}
|
||||
47
src/api/labels/index.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import request from '@/utils/request';
|
||||
import { reqCatch } from '@/utils/catch';
|
||||
|
||||
import type { ProjectLabelsReqType, LabelsReqType } from './types';
|
||||
|
||||
const defaultPages = {
|
||||
page: 1,
|
||||
per_page: 10
|
||||
};
|
||||
|
||||
/** 获取项目labels */
|
||||
export function getProLabels(params: ProjectLabelsReqType): Promise<any> {
|
||||
const { project_id, ...conf } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${project_id}/labels`,
|
||||
params: Object.assign({ ...defaultPages }, conf)
|
||||
}), params);
|
||||
}
|
||||
|
||||
/** 新增项目label */
|
||||
export function createProjectLabels(data: LabelsReqType) {
|
||||
const { project_id, ...conf } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${project_id}/labels`,
|
||||
data: Object.assign({ ...conf }),
|
||||
method: 'post'
|
||||
}), data);
|
||||
}
|
||||
|
||||
/** 编辑项目标签 */
|
||||
export function editProjectLabels(data: LabelsReqType & { new_name: string }) {
|
||||
const { project_id, ...conf } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${project_id}/labels`,
|
||||
data: conf,
|
||||
method: 'put'
|
||||
}), data);
|
||||
}
|
||||
|
||||
/** 删除标签 */
|
||||
export function deleteProjectLabels(data: { project_id: string, name: string }) {
|
||||
const { project_id, name } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/projects/${project_id}/labels?name=${name}`,
|
||||
method: 'delete'
|
||||
}));
|
||||
}
|
||||
19
src/api/labels/types.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
export interface ProjectLabelsReqType {
|
||||
project_id: string;
|
||||
search?: string
|
||||
sort?: 'asc' | 'desc'
|
||||
include_expired?: boolean
|
||||
most_active_ones?: boolean
|
||||
view?: 'simple' | 'basic' | 'detail'
|
||||
page?: number
|
||||
per_page?: number
|
||||
}
|
||||
|
||||
export interface LabelsReqType {
|
||||
project_id: string;
|
||||
name: string
|
||||
color: string
|
||||
description: string
|
||||
priority?: number // 优先级
|
||||
expires_at?: string // 过期时间
|
||||
}
|
||||
185
src/api/merge/index.ts
Normal file
@@ -0,0 +1,185 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/merge/types';
|
||||
|
||||
const removeParamsPathId = (data: types.commonMergeReqType): types.commonMergeReqType => {
|
||||
delete data.project_id;
|
||||
delete data.merge_request_iid;
|
||||
delete data.discussion_id;
|
||||
delete data.note_id;
|
||||
delete data.group_id;
|
||||
delete data.note_id;
|
||||
return data;
|
||||
};
|
||||
|
||||
const urlPre = '/api/v1/projects/';
|
||||
const httpGet = (url: string, params: types.commonMergeReqType): Promise<types.commonMergeResType> => request({
|
||||
url: urlPre + url,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
const httpPost = (url: string, data: types.commonMergeReqType): Promise<types.commonMergeResType> => request({
|
||||
url: urlPre + url,
|
||||
method: 'post',
|
||||
data
|
||||
}, { customError: true });
|
||||
const httpPut = (url: string, data: types.commonMergeReqType): Promise<types.commonMergeResType> => request({
|
||||
url: urlPre + url,
|
||||
method: 'put',
|
||||
data
|
||||
}, { customError: true });
|
||||
const httpDel = (url: string, data: types.commonMergeReqType): Promise<types.commonMergeResType> => request({
|
||||
url: urlPre + url,
|
||||
method: 'delete',
|
||||
data
|
||||
}, { customError: true });
|
||||
|
||||
// 创建合并请求
|
||||
export const createMerge = data => httpPost(`${data.repoId}/merge_requests`, data);
|
||||
// 修改合并请求
|
||||
export const putMerge = data => httpPut(`${data.repoId}/isource/merge_requests/${data.iid}`, data);
|
||||
// 修改审核人
|
||||
export const putApprovers = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/approval_approvers`, data);
|
||||
// 修改检视人
|
||||
export const putReviewers = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/approval_reviewers`, data);
|
||||
// 详情已分配合并人列表
|
||||
export const assignees = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/assignees`, data);
|
||||
// 详情分配合并人(筛选项)
|
||||
export const assigneeCandidates = data => httpGet(`${data.repoId}/merge_requests/assignee_candidates`, data);
|
||||
// 详情获取已分配检视人
|
||||
export const approvalReviewers = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/approval_reviewers`, data);
|
||||
export const updateApprovalReviewers = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/approval_reviewers`, data);
|
||||
// 详情获取已分配检视人(筛选项)
|
||||
export const approvalReviewersOption = params => httpGet(`${params.repoId}/merge_requests/approval_reviewers`, params);
|
||||
// 详情获取已关联issue
|
||||
export const fetchPRIssueList = params => httpGet(`${params.project_id}/merge_requests/${params.merge_request_iid}/e2e_issues`, params);
|
||||
export const updateIssueList = params => httpPut(`${params.project_id}/isource/merge_requests/${params.merge_request_iid}`, params);
|
||||
// 列表页 获取审视人(不关联mr)
|
||||
export const fetchApprovalReviewers = params => httpGet(`${params.repoId}/merge_requests/reviewers`, params);
|
||||
// 列表页 获取审视人(不关联mr)
|
||||
|
||||
// 获取pr模版
|
||||
export const fetchPrTemplate = (params:{ project_id: string }) => request({
|
||||
url: `/api/v2/projects/${params.project_id}/repository/template/pr`,
|
||||
method: 'get'
|
||||
});
|
||||
|
||||
// 获取pr 门禁默认设置人员
|
||||
export const fetchPrSetDefaultPerson = (params: types.commonMergeReqType) => httpGet(`${params.repoId}/create_merge_requests/person_liable`, params);
|
||||
// 创建时搜索门禁人员列表
|
||||
export const searchPrSetPerson = (params: types.commonMergeReqType) => httpGet(`${params.repoId}/merge_requests_create/search_person_liable`, params);
|
||||
|
||||
// 获取已经设置门禁人员列表 汇总 评审人,审查人,测试人
|
||||
export const fetchPrExaminePerson = (params: types.commonMergeReqType) => httpGet(`${params.repoId}/merge_requests/${params.iid}/person_liable`, params);
|
||||
// 搜索 门禁设置人员
|
||||
export const searchPrExaminePerson = (params: types.commonMergeReqType | { merge_request_iid:string; source_branch: string; target_branch: string;
|
||||
search_type: string; target_project_id: string; project_id:string, approval_type: string; search: string; page: number; per_page: number;
|
||||
}) => httpGet(`${params.repoId}/merge_requests/${params.iid}/search_person_liable`, params);
|
||||
|
||||
// 获取门禁配置 汇总版 评审人,审查人,测试人
|
||||
export const fetchPrExaminerules = (params: types.commonMergeReqType) => httpGet(`${params.repoId}/merge_requests/${params.iid}/person_liable_rules`, params);
|
||||
// 指定配置各个门禁人员配置
|
||||
export const editPrExaminePerson = (data: types.commonMergeReqType) => request({
|
||||
url: `/api/v1/projects/${data.repoId}/merge_requests/${data.iid}/person_liable`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
|
||||
// 审查门禁
|
||||
export const examineApproval = (data:types.commonMergeReqType & {action_type:'approve'|'reset'}) => request({
|
||||
url: `/api/v1/projects/${data.repoId}/merge_requests/${data.iid}/approval`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
|
||||
// 测试门禁
|
||||
export const examineTester = (data:types.commonMergeReqType & {action_type:'pass'|'reset'}) => request({
|
||||
url: `/api/v1/projects/${data.repoId}/merge_requests/${data.iid}/approval_test`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
|
||||
// 合并
|
||||
export const merge = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/merge`, data);
|
||||
// 关闭
|
||||
export const closeMerge = data => httpPut(`${data.repoId}/isource/merge_requests/${data.iid}`, data);
|
||||
// 仓库MR创建者列表
|
||||
export const users = data => httpGet(`${data.repoId}/merge_requests/users`, data);
|
||||
// 项目MR列表
|
||||
export const getMergeRequests = data => httpGet(`${data.repoId}/isource/merge_requests`, data);
|
||||
export const getMergeListCount = data => httpGet(`${data.repoId}/isource/merge_requests/count`, data);
|
||||
// 我的MR 列表
|
||||
export const getMyMergeRequests = (params: object) => request({ url: '/api/v1/merge_requests', method: 'get', params });
|
||||
// 组织 mr 列表
|
||||
export const getMyOrgMergeRequests = (params: object) => request({ url: `/api/v1/groups/${params.group_id}/merge_requests`, method: 'get', params });
|
||||
// 合并请求详情 @param view:[simple,basic]
|
||||
export const mergeDetail = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/internal`, data);
|
||||
// 讨论列表
|
||||
export const mrDiscussions = data => httpGet(`${data.project_id}/merge_requests/${data.merge_request_iid}/discussions`, removeParamsPathId(data));
|
||||
// 获取评论详情
|
||||
export const getMrNote = data => httpGet(`${data.project_id}/merge_requests/${data.merge_request_iid}/notes/${data.note_id}`, removeParamsPathId(data));
|
||||
|
||||
// 创建评论 - 代码评论 - 有解决状态
|
||||
export const addMRDiscussion = data => httpPost(`${data.project_id}/merge_requests/${data.merge_request_iid}/discussions`, removeParamsPathId(data));
|
||||
// 更新 评论
|
||||
export const updateMRDiscussion = data => httpPut(`${data.project_id}/merge_requests/${data.merge_request_iid}/discussions/${data.discussion_id}`, removeParamsPathId(data));
|
||||
// 创建评论 没有 解决状态
|
||||
export const addMRDiscussionNote = data => httpPost(`${data.project_id}/merge_requests/${data.merge_request_iid}/notes`, removeParamsPathId(data));
|
||||
// 修改评论
|
||||
export const putDiscussionsNotes = data => httpPut(`${data.project_id}/merge_requests/${data.merge_request_iid}/notes/${data.note_id}`, data);
|
||||
// 创建回复评论
|
||||
export const replayDiscussionsNote = data => httpPost(`${data.project_id}/merge_requests/${data.merge_request_iid}/discussions/${data.discussion_id}/notes`, data);
|
||||
// export const updateReplayDiscussionsNote = data => httpPut(`${data.project_id}/merge_requests/${data.merge_request_iid}/discussions/${data.discussion_id}/notes/${data.note_id}`, data);
|
||||
|
||||
// 删除 mr 评论
|
||||
export const delMRDiscussionsNote = (data) => request({
|
||||
url: `/api/v1/projects/${data.project_id}/merge_requests/${data.merge_request_iid}/notes/${data.note_id}`,
|
||||
method: 'delete'
|
||||
});
|
||||
// 代码评论 - 没有解决状态
|
||||
export const postNotes = data => httpPost(`${data.repoId}/merge_requests/${data.iid}/notes`, data);
|
||||
// 文件提交记录 commit 记录 - 查库
|
||||
export const commits = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/commits`, data);
|
||||
// 检查列表 (合并门禁)
|
||||
export const mergeableState = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/mergeable_state`, data);
|
||||
// 文件差异 查库
|
||||
export const changes = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/changes`, data);
|
||||
// 文件差异目录
|
||||
export const changesTrees = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/changes_trees`, data);
|
||||
// revert
|
||||
export const revert = data => httpPost(`${data.repoId}/merge_request/${data.iid}/revert`, data);
|
||||
// cherry-pick
|
||||
export const cherryPick = data => httpPost(`${data.repoId}/merge_request/${data.iid}/cherry_pick`, data);
|
||||
// // issue关联MR
|
||||
// export const revert = data => httpPut(`${data.repoId}/isource/merge_requests/${data.iid}`, data);
|
||||
// // MR详情获取关联issue
|
||||
// export const e2eIssues = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/e2e_issues`, data);
|
||||
export const versions = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/versions`, data);
|
||||
// 获取评审人数
|
||||
export const getReviewers = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/reviewer_rules`, data);
|
||||
// discussions
|
||||
export const getDis = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/comments_by_line`, data);
|
||||
export const postDis = data => httpPost(`${data.repoId}/merge_requests/${data.iid}/discussions`, data);
|
||||
export const putDis = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/discussions/${data.disId}`, data);
|
||||
export const postNote = data => httpPost(`${data.repoId}/merge_requests/${data.iid}/discussions/${data.disId}/notes`, data);
|
||||
export const putNote = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/notes/${data.noteId}`, data);
|
||||
export const delNote = data => httpDel(`${data.repoId}/merge_requests/${data.iid}/notes/${data.noteId}`, data);
|
||||
export const diffLines = data => httpGet(`${data.repoId}/repository/diff_lines`, data);
|
||||
|
||||
// 检视意见统计信息与门禁信息
|
||||
export const statistic = data => httpGet(`${data.repoId}/merge_requests/statistic`, data);
|
||||
export const conflict_files = data => httpGet(`${data.repoId}/merge_requests/conflict_files`, data);
|
||||
export const convertMrComment = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/approval_reviewers`, data);
|
||||
// 变基rebase
|
||||
export const changeMrRebase = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/rebase`, data);
|
||||
// 重新打开
|
||||
export const reOpen = data => httpPut(`${data.repoId}/isource/merge_requests/${data.iid}`, data);
|
||||
// MR详情审核人审核通过/拒绝/撤销按钮
|
||||
export const putApproval_review = data => request({
|
||||
url: `/api/v1/projects/${data.repoId}/merge_requests/${data.iid}/approval_review`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
// 最新一次流水线 show_job =true
|
||||
export const actual_head_pipeline = (repoId, iid, data) => httpGet(`${repoId}/merge_requests/${iid}/actual_head_pipeline`, data);
|
||||
export const quality = (repoId, pipeId) => httpGet(`${repoId}/pipelines/${pipeId}/quality`);
|
||||
export const diverged_commits_count = (repoId, iid) => httpGet(`${repoId}/merge_requests/${iid}/diverged_commits_count`);
|
||||
46
src/api/merge/types.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { type errorType } from '@/api/types/common';
|
||||
|
||||
export interface commonMergeReqType {
|
||||
repoId: string
|
||||
iid: string
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonMergeResType extends errorType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface IMergeableState {
|
||||
'merge_request_id': number, // 合并请求ID
|
||||
'state': boolean,
|
||||
'status_without_user_auth': boolean, // 无用户授权的状态
|
||||
'conflict_passed': boolean, // 冲突通过
|
||||
'branch_missing_passed': boolean, // 分支缺失通过
|
||||
'non_ff_passed': boolean, // 非快进通过
|
||||
'mr_state_passed': boolean, // 合并请求状态通过
|
||||
'merged_by_user_passed': boolean, // 用户合并通过
|
||||
'work_in_progress_passed': boolean, // 工作进展通过
|
||||
'resolve_discussion_passed': boolean, // 解决讨论通过
|
||||
'ci_state_passed': boolean, // CI状态通过
|
||||
'merge_by_self_passed': boolean, // 自我合并通过
|
||||
'can_force_merge': boolean, // 可以强制合并
|
||||
'approval_reviewers_required_passed': boolean, // 需要审批的审查者通过
|
||||
'merge_request_switch': {
|
||||
'review_mode': 'string', // 审查模式
|
||||
'merge_method': 'string', // 合并方法
|
||||
'only_allow_merge_if_all_discussions_are_resolved': boolean, // 只有在解决所有讨论后才允许合并
|
||||
'disable_merge_by_self': boolean, // 禁止自我合并
|
||||
'only_allow_merge_if_pipeline_succeeds': boolean, // 只有在管道成功后才允许合并
|
||||
'disable_squash_merge': boolean, // 禁止压缩合并
|
||||
'squash_merge_with_no_merge_commit': boolean, // 无合并提交的压缩合并
|
||||
'approval_required_reviewers_count': number, // 需要审批的审查者数量
|
||||
'approval_required_reviewers_branch': 'string', // 需要审批的审查者分支
|
||||
'add_notes_after_merged': boolean, // 合并后添加注释
|
||||
'mark_auto_merged_mr_as_closed': boolean, // 将自动合并的MR标记为已关闭
|
||||
'can_force_merge': boolean, // 可以强制合并
|
||||
'can_reopen': boolean // 可以重新开放
|
||||
},
|
||||
'reason': {}, // description
|
||||
'can_not_reopen': boolean, // 不能重新开放
|
||||
'check_tasks_num': number // 检查事项总数
|
||||
}
|
||||
11
src/api/milestone/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/milestone/types';
|
||||
|
||||
// 里程碑详情
|
||||
export function getMilestones(params: types.commonMilestoneReqType): Promise<types.commonMilestoneResType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${params.project_id}/milestones/${params.milestone_id}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
28
src/api/milestone/types.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { type errorType } from '@/api/types/common';
|
||||
|
||||
export interface commonMilestoneReqType {
|
||||
project_id:string;
|
||||
milestone_id:string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonMilestoneResType extends errorType{
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface IMilestone {
|
||||
id: number,
|
||||
iid: number,
|
||||
project_id: number,
|
||||
title: string,
|
||||
description: string,
|
||||
due_date?: string,
|
||||
progress?: number
|
||||
state: 'active' | string,
|
||||
created_at: string,
|
||||
updated_at?: string,
|
||||
start_date?: string,
|
||||
web_url: string,
|
||||
issues_count: number,
|
||||
merge_requests_count: number,
|
||||
}
|
||||
59
src/api/notice/index.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import request from '@/utils/request';
|
||||
import type { AxiosResponse } from 'axios';
|
||||
import type { MessageListData } from '@/views/Notice/components/types';
|
||||
|
||||
// 获取用户未读消息数
|
||||
export function getUnreadCount(params: { [propName: string]: any }): Promise<AxiosResponse<{ all: number; issue: number; mr: number; }>> {
|
||||
return request({
|
||||
url: '/api/v1/internal/messages/count_unread',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 设置消息为已读
|
||||
export function setRead(data: { message_ids: number[] }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/internal/messages/set_read',
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户消息列表
|
||||
type MessageListQuery = {
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
status?: string;
|
||||
message_type?: string;
|
||||
reason?: string;
|
||||
creator_id?: number;
|
||||
search?: string;
|
||||
project_id?: number;
|
||||
[propName: string]: any;
|
||||
}
|
||||
export function getMessageList(params: MessageListQuery): Promise<AxiosResponse<MessageListData[]>> {
|
||||
return request({
|
||||
url: '/api/v1/internal/messages',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取项目列表
|
||||
export function getMessageRepoList(params: { page_num?: number; page_size?: number; search?: string; }): Promise<AxiosResponse<{ project_full_path: string; project_id: number; unread_count?: number; }[]>> {
|
||||
return request({
|
||||
url: '/api/v1/internal/messages/projects',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取邀请相关未读信息 */
|
||||
export function getMessageCount() {
|
||||
return request({
|
||||
url: '/api/v1/user/notify/targetInfo',
|
||||
method: 'get',
|
||||
params: {}
|
||||
});
|
||||
}
|
||||
124
src/api/org/devIndex.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/org/types';
|
||||
import { reqCatch, type ReqReturn } from '@/utils/catch';
|
||||
|
||||
// 获取自定义menu菜单
|
||||
export function getCustomMenuList({ namespace, onlyCustomNav = true }): Promise<any> {
|
||||
return request({
|
||||
url: `/v1/namespace_page/custom/nav?domain=${namespace}&onlyCustomNav=${onlyCustomNav}`,
|
||||
method: 'get',
|
||||
apiType: 'devApi'
|
||||
});
|
||||
}
|
||||
|
||||
// 组织主页-关注社区
|
||||
export function joinCommunity(data: types.createGroupReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/follow`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 组织主页-取消关注社区
|
||||
export function unJoinCommunity(data: types.createGroupReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/follow`,
|
||||
method: 'delete',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
// 组织主页-获取文章
|
||||
export function getArticle(data: types.createGroupReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/v1/plus/group/home/article`,
|
||||
method: 'get',
|
||||
params: data,
|
||||
apiType: 'devApi'
|
||||
});
|
||||
}
|
||||
|
||||
// 组织主页-获取组织社区是否被关注
|
||||
export function getCommunityAttentionStatus(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v1/follow/hasFollowed`,
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
// 组织主页-社区最新活动
|
||||
export function getActivity(data: types.createGroupReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/v1/plus/group/home/activityLive`,
|
||||
method: 'get',
|
||||
params: data,
|
||||
apiType: 'devApi'
|
||||
});
|
||||
}
|
||||
|
||||
// 组织主页-获取技术文章数
|
||||
export function getArticleTotle(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/v1/namespace_article/tech-article-count`,
|
||||
method: 'get',
|
||||
params: data,
|
||||
apiType: 'devApi'
|
||||
});
|
||||
}
|
||||
|
||||
// 组织主页-获取社区粉丝数
|
||||
export function getfansTotle(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/v1/member/user/count`,
|
||||
method: 'get',
|
||||
params: data,
|
||||
apiType: 'devApi'
|
||||
});
|
||||
}
|
||||
|
||||
// 组织主页-获取技术文章数和粉丝数
|
||||
export function getArticleAndFansTotle(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/groups/${data.orgId}/stats`,
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
// 组织主页-获取运营广告
|
||||
export function getAdvertisement(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/v1/namespace_page/banner`,
|
||||
method: 'get',
|
||||
params: data,
|
||||
apiType: 'devApi'
|
||||
});
|
||||
}
|
||||
|
||||
// 刷新devpress登录转态
|
||||
export function getLoginState(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/v1/check/login`,
|
||||
method: 'get',
|
||||
apiType: 'devApi'
|
||||
});
|
||||
}
|
||||
|
||||
// 退出devpress社区
|
||||
export function devLogout(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/v1/logout`,
|
||||
method: 'get',
|
||||
apiType: 'devApi'
|
||||
});
|
||||
}
|
||||
/* 组织的关注用户 */
|
||||
export function getGroupFollows(params: types.commonGroupReqType): Promise<types.commonGroupResType> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/follow/getGroupFollows',
|
||||
method: 'get',
|
||||
params
|
||||
}));
|
||||
}
|
||||
495
src/api/org/index.ts
Normal file
@@ -0,0 +1,495 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/org/types';
|
||||
import { reqCatch, type ReqReturn } from '@/utils/catch';
|
||||
|
||||
export function createOrg(data: types.createGroupReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/groups`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function getOrg(params: types.commonGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/groups/${params.orgId}`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取/搜索组织
|
||||
export function getOrgs(params: types.commonGroupReqType): Promise<ReqReturn<types.commonGroupResType>> {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/groups`,
|
||||
method: 'get',
|
||||
params
|
||||
}));
|
||||
}
|
||||
|
||||
export function setOrg(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/groups/${data.orgId}`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteOrg(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/groups/${data.orgId}`,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
// 查询登录用户是否关注某组织
|
||||
export function checkHasFollowed(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: '/api/v1/follow/hasFollowed',
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
// 获取组织下所有项目
|
||||
export function getOrgProjectList(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/groups/${data.orgId}/projects`,
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
// 查询组织项目精选
|
||||
export function getOrgHandpickProjectList(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v1/featured/project/${data.type}`,
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
// 项目精选重排序
|
||||
export function reorderSelectedItems(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v1/featured/${data.type}/resort`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 查询组织path是否重复
|
||||
export function inquireOrgPathIsRepeat(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/groups/path_suggestion`,
|
||||
method: 'get',
|
||||
params: data
|
||||
}, { customError: true });
|
||||
}
|
||||
|
||||
// 组织讨论设置回显
|
||||
export function getOrgDiscussionSettings(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/groups/${data.orgId}/module/setting`,
|
||||
method: 'get',
|
||||
params: data
|
||||
}, {
|
||||
customError: true
|
||||
});
|
||||
}
|
||||
|
||||
// 组织讨论设置保存
|
||||
export function saveOrgDiscussionSettings(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/groups/${data.orgId}/module/setting`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 获取组织语言
|
||||
export function getOrgLanguages(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/groups/${data.orgId}/languages`,
|
||||
method: 'get',
|
||||
params: data
|
||||
}, {
|
||||
customError: true
|
||||
});
|
||||
}
|
||||
|
||||
// 查询组织首页运营内容
|
||||
export function getOrgOperationContent(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v1/devpress/group/${data.orgId}/home_operation`,
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
// 判断是否绑定csdn账号
|
||||
export function isBindCsdnCount(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v1/user/csdn-identity`,
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
// 申请社区
|
||||
export function applicantCommunity(data: types.createGroupReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/devpress/${data.orgId}`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 注销社区
|
||||
export function deleteCommunity(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v1/devpress/${data.orgId}`,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
// 社区基本信息
|
||||
export function getCommunityInfo(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v1/devpress/${data.orgId}/info`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 转移组织
|
||||
export function transferOrg(data: types.createGroupReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v4/groups/${data.orgId}/transfer`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 判断用户是否能创建组织
|
||||
export function checkUserCreateOrg(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/groups/quota`,
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
export function getOrgMemberList(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v1/groups/${data.orgId}/members/list`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
/** 组织邀请成员 */
|
||||
export function createInvite(data: { group_id: string, conf: Record<string, any> }) {
|
||||
const { group_id, conf } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/invitation/${group_id}/invite`,
|
||||
method: 'post',
|
||||
data: {
|
||||
...conf,
|
||||
source_type: '0'
|
||||
}
|
||||
}));
|
||||
}
|
||||
export function checkInvite(data: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v1/invitation/check`,
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
export function acceptInvite(token: string) {
|
||||
return request({
|
||||
url: `/api/v1/invitation/members/${token}/accept`,
|
||||
method: 'put'
|
||||
});
|
||||
}
|
||||
|
||||
export function revokeInvite(token: string): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v1/invitation/members/${token}/revoke`,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
/** 获取组织下的成员 */
|
||||
export function getOrgMembers(data: { group_id: string, page?: number, per_page?: number, query?: string }) {
|
||||
return request({
|
||||
url: `/api/v1/groups/${data.group_id}/members/list`,
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取组织下的待邀请成员 */
|
||||
export function getMembersInvite(data: { group_id: string, page: number, per_page: number }) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/groups/${data.group_id}/members/invite`,
|
||||
method: 'get',
|
||||
params: data
|
||||
}));
|
||||
}
|
||||
|
||||
/** 移除组织内的用户 */
|
||||
export function removeGroupUser(data: { group_id: string, username: string }) {
|
||||
const { group_id, username } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/groups/${group_id}/members/${username}`,
|
||||
method: 'delete'
|
||||
}));
|
||||
}
|
||||
|
||||
/** 撤销组织中的成员邀请 */
|
||||
export function retractGroupInvite(data: { group_id: string, username: string }) {
|
||||
const { group_id, username } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/invitation/${group_id}/0/members/${username}/revoke`,
|
||||
method: 'delete'
|
||||
}));
|
||||
}
|
||||
|
||||
/** 退出当前组织 */
|
||||
export function exitGroup(data: { group_id: string }) {
|
||||
const { group_id } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/groups/${group_id}/leave`,
|
||||
method: 'delete'
|
||||
}));
|
||||
}
|
||||
|
||||
/** 设置组织中成员的权限 */
|
||||
export function setGroupUserLevel(data: { group_id: string, username: string, access_level: '30' | '50' | '10' }) {
|
||||
const { group_id, username, access_level } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/groups/${group_id}/members/${username}`,
|
||||
method: 'put',
|
||||
data: { access_level }
|
||||
}));
|
||||
}
|
||||
|
||||
/** 精准搜索匹配组织中的成员 */
|
||||
export function toSearchGroupMember(group_id: string, username: string) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/groups/${group_id}/members/${username}`
|
||||
}));
|
||||
}
|
||||
|
||||
/* 查询path是个人还是组织 */
|
||||
export function getPathType(params: types.createGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: '/api/v2/groups/path_suggestion',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取用量以及存储相关 */
|
||||
export function getOrgStock(group_id: string) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/namespaces/${group_id}/statistic`
|
||||
}));
|
||||
}
|
||||
|
||||
/** 创建组织成员邀请链接 **/
|
||||
export function createGroupMemberLink(data: { namespace: string } & types.MemberInviteLinkProps) {
|
||||
const { namespace, ...config } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/group/${namespace}/invite/link`,
|
||||
method: 'post',
|
||||
data: config
|
||||
}));
|
||||
}
|
||||
/** 删除组织成员邀请链接 */
|
||||
export function deleteMemberInviteLink(namespace: string, inviteId: string) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/group/${namespace}/${inviteId}/invite/link`,
|
||||
method: 'delete'
|
||||
}));
|
||||
}
|
||||
/** 查询组织成员邀请链接列表 */
|
||||
export function getMemberInviteLinks(params: { namespace: string, page?: number, per_page?: number }) {
|
||||
const { namespace, ...pager } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/${namespace}/invite/link`,
|
||||
params: Object.assign({ page: 1, per_page: 10 }, pager)
|
||||
}));
|
||||
}
|
||||
/** 修改组织成员邀请链接 **/
|
||||
export function updateGroupMemberLink(data: { namespace: string, inviteId: string } & types.MemberInviteLinkProps) {
|
||||
const { namespace, inviteId, ...config } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/group/${namespace}/${inviteId}/invite/link`,
|
||||
method: 'put',
|
||||
data: config
|
||||
}));
|
||||
}
|
||||
/** 接受组织邀请链接 */
|
||||
export function acceptGroupInvite(invite_code: string) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/${invite_code}/invite/accept`
|
||||
}));
|
||||
}
|
||||
/** 查看组织邀请链接待接受成员列表 */
|
||||
export function getAcceptGroupMember(params: { namespace: string, page?: number, per_page?: number }) {
|
||||
const { namespace, ...pager } = params;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/${namespace}/invite/accept/member`,
|
||||
params: Object.assign({ page: 1, per_page: 10 }, pager)
|
||||
}));
|
||||
}
|
||||
/** 审核组织链接访问的成员 */
|
||||
export function checkGroupLinkMember(data: { namespace: string, id:number, access_level: string, member_expires_at?: string, audit: '0' | '2' }) {
|
||||
const { namespace, id, ...conf } = data;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/group/${namespace}/${id}/invite/audit`,
|
||||
method: 'put',
|
||||
data: conf
|
||||
}));
|
||||
}
|
||||
/** 删除链接访问组织的成员 */
|
||||
export function removeGroupLinkMember(namespace: string, id: number) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/group/${namespace}/${id}/invite/audit`,
|
||||
method: 'delete'
|
||||
}));
|
||||
}
|
||||
|
||||
/** 模糊搜索匹配相关组织 */
|
||||
export function getFuzzyGroups(params: { name?: string, path?: string, description?: string, page?:number, per_page?:number, orderBy?: 'name' | 'path' | 'id' | 'created_at' | 'updated_at', sort: 'asc' | 'desc'}) {
|
||||
const { page, per_page, ...param } = params;
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v2/groups/search/list',
|
||||
params: { ...param, ...Object.assign({ page: 1, per_page: 10 }, { page, per_page }) }
|
||||
}));
|
||||
}
|
||||
|
||||
// 新建CLA协议
|
||||
export function claAdd(data: types.commonGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/cla/${data.orgId}/add`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑CLA协议
|
||||
export function claUpdate(data: types.commonGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/cla/${data.orgId}/update`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 获取CLA协议详情
|
||||
export function claDetail(params: types.commonGroupReqType): Promise<types.commonGroupResType> {
|
||||
return request({
|
||||
url: `/api/v2/cla/detail`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
/* 组织webhooks对应接口开始 */
|
||||
/** 获取项目分支webhook */
|
||||
export function getRepoWebhooks(params: { repoId: string | null; conf: Record<string, any> }) {
|
||||
return reqCatch(
|
||||
() =>
|
||||
request({
|
||||
url: `/api/v2/groups/${params.repoId}/hooks`,
|
||||
params: params.conf
|
||||
}),
|
||||
params
|
||||
);
|
||||
}
|
||||
/** 新增webhook配置 */
|
||||
export function createWebhook(data: { repoId: string | number | null; conf: Record<string, any> }) {
|
||||
return reqCatch(
|
||||
() =>
|
||||
request(
|
||||
{
|
||||
url: `/api/v2/groups/${data.repoId}/hooks`,
|
||||
data: data.conf,
|
||||
method: 'post'
|
||||
},
|
||||
{
|
||||
customError: true
|
||||
}
|
||||
),
|
||||
data
|
||||
);
|
||||
}
|
||||
/** 编辑webhook */
|
||||
export function editWebhook(data: { repoId: string | null; hook_id: string; conf: Record<string, any> }) {
|
||||
const { repoId, hook_id, conf } = data;
|
||||
return reqCatch(() =>
|
||||
request({
|
||||
url: `/api/v2/groups/${repoId}/hooks/${hook_id}`,
|
||||
method: 'put',
|
||||
data: conf
|
||||
})
|
||||
);
|
||||
}
|
||||
/** 获取webhook详情 */
|
||||
export function getWebhookDetail(data: { repoId: string | null; hook_id: string }) {
|
||||
const { repoId, hook_id } = data;
|
||||
return reqCatch(() =>
|
||||
request({
|
||||
url: `/api/v2/groups/${repoId}/hooks/${hook_id}`
|
||||
})
|
||||
);
|
||||
}
|
||||
/** 获取webhook请求日志 */
|
||||
export function getWebhookLogs(data: { repoId: string | null; hook_id: string; page?: number; per_page?: number }) {
|
||||
const { repoId, hook_id, ...param } = data;
|
||||
return reqCatch(() =>
|
||||
request({
|
||||
url: `/api/v2/groups/${repoId}/hooks/${hook_id}/logs`,
|
||||
params: Object.assign({ page: 1, per_page: 10 }, param)
|
||||
})
|
||||
);
|
||||
}
|
||||
/** 获取项目webhook日志详情 */
|
||||
export function getWebhookLogDetail(data: { repoId: string | null; hook_id: string; id: string }) {
|
||||
const { repoId, hook_id, id } = data;
|
||||
return reqCatch(() =>
|
||||
request({
|
||||
url: `/api/v2/groups/${repoId}/hooks/${hook_id}/logs/${id}`
|
||||
})
|
||||
);
|
||||
}
|
||||
/** 删除webhook */
|
||||
export function deleteWebHook(data: { repoId: string | null; hook_id: string }) {
|
||||
const { repoId, hook_id } = data;
|
||||
return reqCatch(() =>
|
||||
request({
|
||||
url: `/api/v2/groups/${repoId}/hooks/${hook_id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
);
|
||||
}
|
||||
/* 组织webhooks对应接口结束 */
|
||||
|
||||
/** 获取组织默认设置 */
|
||||
export function getOrgDefaultSetting(params: { group_id: string }) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/groups/${params.group_id}`,
|
||||
method: 'get'
|
||||
}));
|
||||
}
|
||||
|
||||
/** 更新组织默认设置 */
|
||||
export function updateOrgDefaultSetting(data: types.commonGroupReqType) {
|
||||
const { group_id } = data;
|
||||
delete data.group_id;
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/groups/${group_id}/ext/setting`,
|
||||
method: 'put',
|
||||
data
|
||||
}));
|
||||
}
|
||||
24
src/api/org/types.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { type errorType } from '@/api/types/common';
|
||||
import type { ComputedRef } from 'vue';
|
||||
|
||||
export interface createGroupReqType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonGroupReqType {
|
||||
[propName: string]: any;
|
||||
repoId?: string | number | string[];
|
||||
orgId?: string | number | string[] | ComputedRef<string | string[]>;
|
||||
}
|
||||
|
||||
export interface commonGroupResType extends errorType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface MemberInviteLinkProps {
|
||||
access_level: number | string,
|
||||
audit_status: 0 | 1 | string,
|
||||
url_expires_at?:string,
|
||||
member_expires_at?:string,
|
||||
remark?:string
|
||||
}
|
||||
34
src/api/release/index.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/release/types';
|
||||
import { reqCatchV2, type catchRt } from '@/utils/catch';
|
||||
import type { CommonWithPageReqType } from '@/utils/types';
|
||||
|
||||
export function createRelease(data: types.createReleaseReqType): Promise<types.createReleaseReqType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${data.repoId}/releases`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function getReleases(params: types.getReleasesType): catchRt<CommonWithPageReqType<types.getReleaseResType[]>> {
|
||||
return reqCatchV2(() => request({
|
||||
url: `/api/v1/projects/${params.repoId}/releases`,
|
||||
method: 'get',
|
||||
params
|
||||
}));
|
||||
}
|
||||
export function getReleaseDetail(params: types.getReleaseDetailReqType): Promise<types.getReleaseDetailReqType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${params.repoId}/releases/${params.tag_name}`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
export function deleteRelease(data: types.commonReleaseResType): Promise<types.commonReleaseResType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${data.repoId}/releases/${data.tag_name}`,
|
||||
method: 'delete',
|
||||
data
|
||||
});
|
||||
}
|
||||
102
src/api/release/types.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { releaseType; type errorType } from '@/api/types/common';
|
||||
|
||||
export interface getReleasesType extends releaseType {
|
||||
/**
|
||||
* 当前页码
|
||||
*/
|
||||
page?: string;
|
||||
/**
|
||||
* 每页的项目数
|
||||
*/
|
||||
per_page?: string;
|
||||
}
|
||||
|
||||
export interface commonReleaseResType extends errorType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface createReleaseReqType {
|
||||
tag_name: string;
|
||||
name: string;
|
||||
description: string;
|
||||
ref: string;
|
||||
assets?: {
|
||||
links: [
|
||||
{
|
||||
name: string;
|
||||
url: string
|
||||
}
|
||||
]
|
||||
};
|
||||
[propName: string]: any;
|
||||
}
|
||||
export interface getReleaseDetailReqType {
|
||||
tag_name: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
interface Author {
|
||||
id: number;
|
||||
name: string;
|
||||
username: string;
|
||||
iam_id: string;
|
||||
state: string;
|
||||
avatar_url: string;
|
||||
avatar_path: string;
|
||||
email: string;
|
||||
name_cn: string;
|
||||
web_url: string;
|
||||
nick_name: string;
|
||||
tenant_name: string;
|
||||
}
|
||||
interface Commit {
|
||||
id: string;
|
||||
message: string;
|
||||
parent_ids:string[];
|
||||
authored_date: string;
|
||||
author_name: string;
|
||||
author_email: string;
|
||||
committed_date: string;
|
||||
committer_name: string;
|
||||
committer_email: string;
|
||||
open_gpg_verified: true;
|
||||
verification_status: number;
|
||||
gpg_primary_key_id: string;
|
||||
short_id: string;
|
||||
created_at: string;
|
||||
title: string;
|
||||
author_avatar_url: string;
|
||||
committer_avatar_url: string;
|
||||
relate_url: {
|
||||
related_id: string;
|
||||
related_url: string
|
||||
}[]
|
||||
}
|
||||
export interface getReleaseResType {
|
||||
tag_name: string;
|
||||
description: string;
|
||||
name: string;
|
||||
description_html: string;
|
||||
created_at: string;
|
||||
can_delete: true;
|
||||
can_edit: true;
|
||||
can_download: true;
|
||||
author:Author;
|
||||
commit:Commit;
|
||||
assets: {
|
||||
count: number;
|
||||
sources:
|
||||
{
|
||||
format: string;
|
||||
url: string
|
||||
}[];
|
||||
links:
|
||||
{
|
||||
id: number;
|
||||
name: string;
|
||||
url: string;
|
||||
external: true
|
||||
}[];
|
||||
}
|
||||
}
|
||||
1544
src/api/repo/index.ts
Normal file
209
src/api/repo/types.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
import { VISIBILITY } from '@/constant/enum';
|
||||
import { type forkType, type errorType, type repoType } from '@/api/types/common';
|
||||
import { type TypeAll } from '@/utils/types';
|
||||
export interface createRepoReqType {
|
||||
name: string;
|
||||
path: string;
|
||||
import_url?:string;
|
||||
description?: string;
|
||||
visibility?: VISIBILITY;
|
||||
}
|
||||
|
||||
export interface createRepoResType extends errorType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonRepoReqType extends repoType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface forkRepoReqType extends forkType {
|
||||
[propName: string]: any;
|
||||
name?: string;
|
||||
namespace?: number;
|
||||
need_sync_settings?: string[];
|
||||
path?: string;
|
||||
fork_from_project_id?: string;
|
||||
}
|
||||
|
||||
export interface commonRepoResType extends errorType {
|
||||
name: string // 项目名称
|
||||
default_branch: string // 项目默认分支
|
||||
path: string // 仓库路径
|
||||
description: string // 项目描述
|
||||
ci_config_path?: string // ci配置文件路径
|
||||
issues_enabled?: boolean // 是否启用问题追踪器
|
||||
merge_requests_enabled?: boolean // 是否启用合并请求
|
||||
wiki_enabled?: boolean // 是否启用wiki
|
||||
jobs_enabled?: boolean // 是否启用作业
|
||||
snippets_enabled?: boolean // 是否启用代码片段
|
||||
shared_runners_enabled?: boolean // 是否为该项目启用共享Runner
|
||||
resolve_outdated_diff_discussions?: boolean // 是否在推送时自动解决合并请求差异讨论
|
||||
container_registry_enabled?: boolean // 是否为该项目启用容器注册表
|
||||
lfs_enabled?: boolean // 是否为该项目启用Git LFS
|
||||
visibility: 'private' | 'internal' | 'public' // 项目可见性级别
|
||||
security?: 'secret_top' | 'secret' | 'secret_outer' | 'confidential' | 'internal' | 'open_source' // 项目安全级别
|
||||
visibility_level?: number // 项目在devclound中的可见性级别
|
||||
public_builds?: boolean // 是否执行公共构建
|
||||
request_access_enabled?: boolean // 是否允许用户请求成员访问权限
|
||||
only_allow_merge_if_pipeline_succeed?: boolean // 仅在管道后成功允许
|
||||
only_allow_merge_if_all_discussions_are_resolved?: boolean // 仅在所有讨论都已解决后允许合并
|
||||
tag_list?: string[] // 标签列表
|
||||
avatar?: string[] // 头像列表
|
||||
printing_merge_request_link_enabled?: boolean // 从命令行推送时是否显示创建/查看合并请求的链接
|
||||
merge_method?: 'ff' | 'rebase_merge' | 'merge' // 合并请求时使用的合并方法
|
||||
iright_snapshot?: string // iright应用信息
|
||||
initialize_with_readme?: boolean // 是否使用Readme.md初始化项目
|
||||
initialize_with_gitignore?: string // 选择添加.gitignore模板
|
||||
initialize_with_license?: string // 选择添加license模板
|
||||
partition?: string // 分区
|
||||
[x: string]: any
|
||||
}
|
||||
|
||||
export interface commonRepoBranchResType {
|
||||
description: string // 分支描述
|
||||
name: string // 分支名称
|
||||
protected: boolean // 是否受到分支保护
|
||||
merged: boolean // 是否合并
|
||||
default: boolean // 是否为默认分支
|
||||
[x: string]: any
|
||||
}
|
||||
// 项目用户角色权限
|
||||
export interface IRole {
|
||||
'id': number,
|
||||
'username': string,
|
||||
// 管理员 50,开发30, 浏览者10
|
||||
'access_level': 50 | 30 | 10,
|
||||
'project': {
|
||||
// 安全级别
|
||||
'security_level': 40
|
||||
},
|
||||
'committer_system_from'?: boolean
|
||||
}
|
||||
// 获取贡献者的返回
|
||||
export interface ContributorReqType {
|
||||
additions:number;
|
||||
commits:number;
|
||||
deletions:number;
|
||||
email:string;
|
||||
name:string;
|
||||
}
|
||||
interface User {
|
||||
id:number;
|
||||
username:string;
|
||||
nickname:string;
|
||||
avatar:string;
|
||||
skill:any[]
|
||||
}
|
||||
interface Ext {
|
||||
liveId:string;
|
||||
coverImg:string;
|
||||
isRecommend:boolean;
|
||||
isHot:true;
|
||||
}
|
||||
// 精选内容的返回
|
||||
export interface SelectedArticleReqType {
|
||||
nsId:number;
|
||||
mediaAid:string;
|
||||
type:number;
|
||||
title:string;
|
||||
desc:string;
|
||||
customDomain:string;
|
||||
startAt:string;
|
||||
endAt:string;
|
||||
status:number;
|
||||
ext:Ext;
|
||||
user:User;
|
||||
}
|
||||
// 相关搜索关键词返回
|
||||
export type HotSearchKeyReqType = TypeAll<'name'|'link', string>;
|
||||
// 通知类型返回
|
||||
export interface RepoNoticeReqType {
|
||||
count:number;
|
||||
custom_watching:any;
|
||||
watch_type:string;
|
||||
}
|
||||
|
||||
export interface RepoWikiReqType {// wiki创建更新文件请求参数
|
||||
repo_path: string,
|
||||
name: string,
|
||||
file_path?: string,
|
||||
commit_message: string,
|
||||
content: string,
|
||||
currUserId?: string
|
||||
}
|
||||
export interface WikiFileResType {// wiki详情返回
|
||||
name:string;
|
||||
path:string;
|
||||
size: number,
|
||||
encoding:string;
|
||||
blob_id:string;
|
||||
file_type:string;
|
||||
commit_history_count:string;
|
||||
last_commit_id:string;
|
||||
author_name:string;
|
||||
committed_date:string;
|
||||
content:string;
|
||||
}
|
||||
export interface WikiListReqType {// wikilist请求参数
|
||||
repo_path:string;
|
||||
page?:number;
|
||||
per_page?:number;
|
||||
}
|
||||
export interface WikiListResType {// wikilist返回
|
||||
author_name:string;
|
||||
name:string;
|
||||
avatar?:string;
|
||||
committed_date:string;
|
||||
}
|
||||
export interface RepoWikiHistoryReqType {// wiki历史版本请求参数
|
||||
file_path:string,
|
||||
repo_path: string,
|
||||
page?: number,
|
||||
per_page?: number,
|
||||
}
|
||||
export interface WikiHistoryResType {// wiki历史版本返回
|
||||
id:string;
|
||||
message:string;
|
||||
parent_ids:string[];
|
||||
authored_date:string;
|
||||
author_name:string;
|
||||
author_email:string;
|
||||
committed_date:string;
|
||||
committer_name:string;
|
||||
committer_email:string;
|
||||
open_gpg_verified: boolean;
|
||||
verification_status: number;
|
||||
gpg_primary_key_id:string;
|
||||
short_id:string;
|
||||
created_at:string;
|
||||
title:string;
|
||||
author_avatar_url:string;
|
||||
committer_avatar_url:string;
|
||||
relate_url: {
|
||||
related_id:string;
|
||||
related_url:string;
|
||||
}[]
|
||||
}
|
||||
export interface archiveType extends repoType {
|
||||
sha: string;
|
||||
archive_format: string;
|
||||
}
|
||||
|
||||
export interface MemberInviteLinkProps {
|
||||
access_level: number | string,
|
||||
audit_status: 0 | 1 | string,
|
||||
url_expires_at?:string,
|
||||
member_expires_at?:string,
|
||||
remark?:string
|
||||
}
|
||||
|
||||
export interface DiscussionPreviewProps {
|
||||
discussion: string,
|
||||
}
|
||||
|
||||
export interface DiscussionCommentProps {
|
||||
type: 1 | 2 | 3 | 4,
|
||||
discussionId: string | number,
|
||||
}
|
||||
|
||||
11
src/api/report/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 数据上报
|
||||
export function report(eventId: string, data: object, headers: object = {}): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/report?event_id=${eventId}`,
|
||||
method: 'post',
|
||||
data,
|
||||
headers
|
||||
});
|
||||
}
|
||||
53
src/api/settings/index.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { reqCatchV2, type catchRt } from '@/utils/catch';
|
||||
import request from '@/utils/request';
|
||||
import type { userCreateSSHKeyReqType, generalSearchReqType, getUserSSHKeyResType, sshKeyid } from './types';
|
||||
import Mock from 'mockjs';
|
||||
|
||||
// 获取镜像信息
|
||||
export function getMirrorData(params: any): Promise<any> {
|
||||
return Promise.resolve([(Mock.mock({
|
||||
'isOpen': false,
|
||||
'dataList': [
|
||||
{
|
||||
type: 0,
|
||||
add: 'http:6',
|
||||
success: 1,
|
||||
time: 2
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
add: 'http:fdsjoijfsdoijdfsiojfsdiojoidsfoijfdsijo',
|
||||
success: 0,
|
||||
time: 2
|
||||
}]
|
||||
}))
|
||||
]);
|
||||
}
|
||||
|
||||
// 创建用户SSHKey
|
||||
export function createUserSSH(sshKey: userCreateSSHKeyReqType): catchRt<any> {
|
||||
const reqForm = new FormData();
|
||||
reqForm.append('key', sshKey.keyValue);
|
||||
reqForm.append('title', sshKey.keyName);
|
||||
return reqCatchV2(() => request({
|
||||
url: `/api/v1/user/keys`,
|
||||
method: 'post',
|
||||
data: reqForm
|
||||
}, { customError: true }));
|
||||
}
|
||||
// 查询用户SSHKey列表
|
||||
export function getUserSSHList(searchParams: generalSearchReqType): catchRt<getUserSSHKeyResType[]> {
|
||||
return reqCatchV2(() => request({
|
||||
url: `/api/v1/user/keys`,
|
||||
method: 'get',
|
||||
params: searchParams
|
||||
}));
|
||||
}
|
||||
// 删除用户SSHKey
|
||||
export function deleteSSHKey(key_id:sshKeyid, title:string): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: `/api/v1/user/keys/${key_id}`,
|
||||
method: 'delete',
|
||||
params: { title: title }
|
||||
}));
|
||||
}
|
||||
51
src/api/settings/types.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import type { SSHData } from '@/components/SecretKeyItem/types';
|
||||
export interface ITransSSHKey {
|
||||
keyName: string;
|
||||
keyValue: string;
|
||||
writable: boolean;
|
||||
}
|
||||
// 用户创建SSHKey请求参数
|
||||
export interface userCreateSSHKeyReqType {
|
||||
keyName: string;
|
||||
keyValue: string;
|
||||
permissions: string;
|
||||
expireTime: string;
|
||||
}
|
||||
// 通用列表查询参数
|
||||
export interface generalSearchReqType {
|
||||
page: number;
|
||||
per_page: number;
|
||||
search: string;
|
||||
}
|
||||
// 用户SSHKey接口返回
|
||||
export interface getUserSSHKeyResType {
|
||||
id: string | number;
|
||||
key: string;
|
||||
title: string;
|
||||
created_at: string;
|
||||
}
|
||||
export type sshKeyid = SSHData['id'];
|
||||
export interface Log {
|
||||
type: string;
|
||||
operator: string;
|
||||
logInfo: string;
|
||||
createdTime: string;
|
||||
}
|
||||
|
||||
export interface LogFilter {
|
||||
type?: string;
|
||||
operator?: string;
|
||||
logInfo?: string;
|
||||
range?: [Date | '', Date | ''];
|
||||
}
|
||||
|
||||
export interface LogSource {
|
||||
(pageSize: number, pageIndex: number, logFilter: LogFilter): Promise<Log[]>
|
||||
}
|
||||
|
||||
export interface UserRepo {
|
||||
organization: string;
|
||||
repoName: string;
|
||||
repoSize: string;
|
||||
isMine: boolean;
|
||||
}
|
||||
35
src/api/storage-apis.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { IRequestCache } from "@/utils/apiStorage";
|
||||
|
||||
const TIMEOUT = 5000;
|
||||
const RETRY = 2;
|
||||
|
||||
export const storageApis: IRequestCache[] = [
|
||||
{
|
||||
url: '/api/v1/issues',
|
||||
timeout: 5000,
|
||||
retry: RETRY,
|
||||
method: 'get',
|
||||
excludeStatusCode: [401,403, 404]
|
||||
},
|
||||
{
|
||||
url: '/api/v1/merge_requests',
|
||||
timeout: TIMEOUT,
|
||||
retry: RETRY,
|
||||
method: 'get',
|
||||
excludeStatusCode: [401,403, 404]
|
||||
},
|
||||
{
|
||||
url: '/api/v1/projects/{projectId}/isource/merge_requests',
|
||||
timeout: TIMEOUT,
|
||||
retry: RETRY,
|
||||
method: 'get',
|
||||
excludeStatusCode: [401,403, 404]
|
||||
},
|
||||
{
|
||||
url: '/api/v1/issue/{projectId}/issues',
|
||||
timeout: TIMEOUT,
|
||||
retry: RETRY,
|
||||
method: 'get',
|
||||
excludeStatusCode: [401,403, 404]
|
||||
}
|
||||
]
|
||||
53
src/api/tags/index.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import request from '@/utils/request';
|
||||
import * as types from '@/api/tags/types';
|
||||
|
||||
export function createTag(data: types.createTagReqType): Promise<types.createTagReqType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${data.repoId}/repository/tags`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export function getTags(params: types.getTagsReqType): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${params.repoId}/repository/tags`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function getTagDetail(params: types.tagDetailType): Promise<types.tagDetailType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${params.repoId}/repository/tags/${params.tag_name}`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteTag(params: types.tagDetailType): Promise<types.tagDetailType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${params.repoId}/repository/tags/${params.tag_name}`,
|
||||
method: 'delete',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取未发布版本的tag列表
|
||||
export function getUnreleasedTags(params: types.tagDetailType): Promise<types.tagDetailType> {
|
||||
return request({
|
||||
url: `/api/v1/projects/${params.repoId}/releases/linktags`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function createTagAuth(project_path: string): Promise<any> {
|
||||
return request({
|
||||
url: `/api/v2/projects/get_create_tag_setting`,
|
||||
method: 'get',
|
||||
params: {
|
||||
project_path
|
||||
}
|
||||
});
|
||||
}
|
||||
48
src/api/tags/types.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { tagType, type errorType } from '@/api/types/common';
|
||||
|
||||
export interface getTagsReqType extends tagType {
|
||||
/**
|
||||
* 用户ID或用户名
|
||||
*/
|
||||
creator?: string;
|
||||
/**
|
||||
* 返回按照名称(name)、更新时间(updated)或创建时间(created)字段排序
|
||||
*/
|
||||
order_by?: string;
|
||||
/**
|
||||
* 当前页码
|
||||
*/
|
||||
page?: string;
|
||||
/**
|
||||
* 每页的项目数
|
||||
*/
|
||||
per_page?: string;
|
||||
/**
|
||||
* 返回与搜索条件匹配的标签列表
|
||||
*/
|
||||
search?: string;
|
||||
/**
|
||||
* 返回排序为升序(asc)或降序(desc)
|
||||
*/
|
||||
sort?: string;
|
||||
/**
|
||||
* 仅返回标签名称
|
||||
*/
|
||||
view?: string;
|
||||
}
|
||||
|
||||
export interface tagDetailType extends tagType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface commonTagsResType extends errorType {
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export interface createTagReqType {
|
||||
tag_name: string;
|
||||
ref: string;
|
||||
message?: string;
|
||||
release_description?: string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
35
src/api/types/common.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
export interface errorType {
|
||||
error_code?: number;
|
||||
error_code_name?: string;
|
||||
error_message?: string;
|
||||
trace_id?: string;
|
||||
}
|
||||
|
||||
export interface repoType {
|
||||
repoId?: string;
|
||||
}
|
||||
|
||||
export interface orgType {
|
||||
groupId: string;
|
||||
}
|
||||
|
||||
export interface commitType extends repoType {
|
||||
commitId: string;
|
||||
}
|
||||
|
||||
export interface tagType extends repoType {
|
||||
tag_name?: string;
|
||||
}
|
||||
|
||||
export interface forkType extends repoType {
|
||||
forked_from_id?: string;
|
||||
}
|
||||
|
||||
export interface releaseType extends repoType {
|
||||
tag_name?: string;
|
||||
}
|
||||
|
||||
export interface resCatch {
|
||||
error: any;
|
||||
data: any;
|
||||
}
|
||||
0
src/api/types/login.ts
Normal file
697
src/api/user/index.ts
Normal file
@@ -0,0 +1,697 @@
|
||||
import request from '@/utils/request';
|
||||
import { reqCatch } from '@/utils/catch';
|
||||
import { fileToBlob } from '@/utils/index';
|
||||
import type { RegisterReqType, UserProfileReqType, UserPreferenceReqType, UserRepoReqType, LoginPassword, LoginMobile, UserProfileResType, UserProfile, OrgData, FollowerData } from './types';
|
||||
import { reqCatchV2, type catchRt } from '@/utils/catch';
|
||||
import { AES, enc, mode, pad } from 'crypto-js';
|
||||
import type { AxiosResponse } from 'axios';
|
||||
import type { ProfileRepoItemResData } from '@/views/User/hooks/useRepoList';
|
||||
|
||||
/** 帐号密码登录 */
|
||||
export function toLogin(data: LoginPassword): Promise<any> {
|
||||
const key = enc.Utf8.parse((import.meta as any).env.VITE_SECRET_KEY);
|
||||
const iv = enc.Utf8.parse((import.meta as any).env.VITE_SECRET_IV);
|
||||
const cryptoCode = AES.encrypt(data.password, key, {
|
||||
iv,
|
||||
mode: mode.CBC,
|
||||
padding: pad.Pkcs7
|
||||
});
|
||||
const userInfo = {
|
||||
username: data.username,
|
||||
password: cryptoCode.toString()
|
||||
};
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/oauth/login',
|
||||
method: 'post',
|
||||
data: userInfo,
|
||||
headers: {
|
||||
'content-type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
}), userInfo);
|
||||
}
|
||||
/** 验证码登录 */
|
||||
export function loginByMobile(data: Exclude<LoginMobile, 'type'>): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/oauth/login/mobile',
|
||||
method: 'post',
|
||||
data,
|
||||
headers: {
|
||||
'content-type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
}));
|
||||
}
|
||||
/** 获取gitcode手机号验证码 */
|
||||
export function verifyRegisterCode(data: { mobile: string, type: 'REGISTER' | 'ATTACH_MOBILE', raw_data?: string }): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/sms/send/codeByBiz',
|
||||
method: 'post',
|
||||
data: {
|
||||
biz_enum: data.type,
|
||||
mobile: data.mobile,
|
||||
raw_data: data.raw_data || ''
|
||||
}
|
||||
}));
|
||||
}
|
||||
/** 获取华为手机号验证码 */
|
||||
export function verifyHwCode(data: { mobile: string }): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/sendVeriCode',
|
||||
method: 'post',
|
||||
data
|
||||
}));
|
||||
}
|
||||
|
||||
/** gitcode手机号验证注册 */
|
||||
export function registerByMobile(data: RegisterReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/register',
|
||||
method: 'post',
|
||||
data
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 华为云手机号验证注册
|
||||
* @deprecated at 2023.11.02 精简注册
|
||||
*/
|
||||
export function registerBind(data: { mobile: string, user_id: string, mask: string, verificationcode: string }): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/registerIAM',
|
||||
method: 'post',
|
||||
data
|
||||
}));
|
||||
}
|
||||
|
||||
/** 快捷注册短信验证 */
|
||||
export function getQuickLoginMsg(data: { mobile: string, biz_enum?: string }): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/sms/send/codeByBiz',
|
||||
method: 'post',
|
||||
data: {
|
||||
mobile: data.mobile,
|
||||
biz_enum: data.biz_enum || 'LOGIN'
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/** 手机号快捷注册 */
|
||||
export function quickRegister(data: RegisterReqType): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/quickRegister',
|
||||
method: 'post',
|
||||
data: data
|
||||
}));
|
||||
}
|
||||
|
||||
/** 获取手机或者邮箱验证码 */
|
||||
export function getMobileEmailCode(mobile_email: string) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/user/forgetCode?mobile_email=${mobile_email}`
|
||||
}));
|
||||
}
|
||||
|
||||
/** 登录重置密码 */
|
||||
export function resetUserPassword(data: { mobile_email: string, password: string, code: string }) {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/forgetPassword',
|
||||
method: 'post',
|
||||
data
|
||||
}));
|
||||
}
|
||||
|
||||
/** 退出登录 */
|
||||
export function toLogout() {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/oauth/logout',
|
||||
method: 'post'
|
||||
}));
|
||||
}
|
||||
|
||||
/** 获取第三方绑定信息 */
|
||||
export function getBindUserInfo(platform: 'csdn' | 'gitee' | 'github' | 'atomgit', code: string, state: string, signup_type: string) {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v1/oauth/callback/${platform}`,
|
||||
params: { code, state, signup_type }
|
||||
}));
|
||||
}
|
||||
|
||||
/** 第三方登录绑定手机号 */
|
||||
export function bindAuthMobile(data: { user_id: string, mask: string, identity_id: string, mobile: string, verificationcode: string, signup_type: string }) {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/oauth/attach/mobile',
|
||||
method: 'post',
|
||||
data
|
||||
}));
|
||||
}
|
||||
|
||||
/** 模糊查询用户信息 */
|
||||
export function fuzzyFindUserInfo(usernameOrEmail: string) {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/findUser/fuzzy',
|
||||
params: { usernameOrEmail }
|
||||
}));
|
||||
}
|
||||
|
||||
/** 查询用户名是否已存在 */
|
||||
export function checkUsername(username: string) {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user/checkSameUser',
|
||||
params: { username }
|
||||
}));
|
||||
}
|
||||
|
||||
// 获取当前用户所有命名空间
|
||||
export function getNamespaces(params: any): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/groups',
|
||||
method: 'get',
|
||||
params
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 获取当前用户fork的所有命名空间
|
||||
export function getForkGroups(params: any): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: `/api/v2/projects/${params.repoId}/fork_groups/page`,
|
||||
method: 'get',
|
||||
params
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 获取当前用户所有命名空间
|
||||
export function getManageableGroups(params: any): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/user_groups/manageable_groups',
|
||||
method: 'get',
|
||||
params
|
||||
}), params);
|
||||
}
|
||||
|
||||
export function postUploadAvatar(params: any): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/obs/user/avatar',
|
||||
method: 'get'
|
||||
}), params);
|
||||
}
|
||||
|
||||
export function postUploadImage(params: any): Promise<any> {
|
||||
return reqCatch(() => request({
|
||||
url: '/api/v1/obs/image',
|
||||
method: 'post',
|
||||
data: params
|
||||
}), params);
|
||||
}
|
||||
|
||||
// 封装公共文件上传方法
|
||||
export async function uploadFile(fileInfo: any, isAvatar: boolean, fileType: string = '') {
|
||||
try {
|
||||
if (fileInfo.length > 0) {
|
||||
const file = fileInfo[0];
|
||||
const params = {
|
||||
object_key: `${location.pathname}/` + file.name,
|
||||
file_type: file.name.split('.')[1],
|
||||
is_avatar: isAvatar
|
||||
};
|
||||
let res;
|
||||
if (isAvatar) {
|
||||
res = await postUploadAvatar(params);
|
||||
} else {
|
||||
params.content_type = fileType;
|
||||
res = await postUploadImage(params);
|
||||
}
|
||||
const blob: any = await fileToBlob(file);
|
||||
let url = '';
|
||||
|
||||
let uploadParams: any = {};
|
||||
for (const key in res.data.data) {
|
||||
url = key;
|
||||
uploadParams = res.data.data[key];
|
||||
}
|
||||
const imgRes = await fetch(url, {
|
||||
method: 'put',
|
||||
body: blob,
|
||||
headers: {
|
||||
'Content-Type': uploadParams['Content-Type'],
|
||||
'x-obs-acl': uploadParams['x-obs-acl'],
|
||||
'Host': uploadParams['Host']
|
||||
}
|
||||
});
|
||||
if (imgRes.status === 200) {
|
||||
return uploadParams['cdn-img-addr'];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
};
|
||||
|
||||
export function findUser(data: object | null): Promise<object | null> {
|
||||
return request({
|
||||
url: '/api/v1/findUser/condition',
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
};
|
||||
// 更新用户基本信息
|
||||
export function updateUserProfile(data: UserProfileReqType | UserPreferenceReqType | UserRepoReqType): catchRt<UserProfileResType> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/user/setting/save',
|
||||
method: 'post',
|
||||
data
|
||||
}));
|
||||
}
|
||||
// 查询用户信息
|
||||
export function getUserProfile(params: { username: string, type?: string }): Promise<AxiosResponse<UserProfile>> {
|
||||
return request({
|
||||
url: '/api/v1/user/setting/profile',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 查询用户活动
|
||||
export function queryUserActivities(params: any): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/events',
|
||||
method: 'get',
|
||||
params
|
||||
}, { customError: true });
|
||||
}
|
||||
|
||||
// 查询用户活动-新接口
|
||||
export function queryUserActivitiesNew(params: any): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/events/user',
|
||||
method: 'get',
|
||||
params
|
||||
}, { customError: true });
|
||||
}
|
||||
|
||||
// 查询用户项目
|
||||
export function queryUserRepos(params: { user_id: string;[propName: string]: any; }): Promise<AxiosResponse<ProfileRepoItemResData[]>> {
|
||||
return request({
|
||||
url: `/api/v1/featured/project/profile_project?group_id=${params.username}`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 查询用户创建的项目
|
||||
export function queryUserCreateRepos(params: { user_name: string; search?: string, [propName: string]: any; }): Promise<AxiosResponse<ProfileRepoItemResData[]>> {
|
||||
return request({
|
||||
url: `/api/v1/profile/${params.user_name}/created_projects`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 查询用户关注的项目
|
||||
export function queryUserStarredRepos(params: { user_name: string;[propName: string]: any; }): Promise<AxiosResponse<ProfileRepoItemResData[]>> {
|
||||
return request({
|
||||
url: `/api/v1/profile/${params.user_name}/starred_projects`,
|
||||
method: 'get',
|
||||
params
|
||||
}, { customError: true });
|
||||
}
|
||||
|
||||
// 更新项目状态
|
||||
export function updateRepoStatus(params: { type: string; group_id: string; resource_id: string; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: `/api/v1/featured/${params.type}`,
|
||||
method: 'post',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 移除对应类型项目
|
||||
export function removeRepoStatus(params: { type: string; group_id: string; resource_id: string; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: `/api/v1/featured/${params.type}`,
|
||||
method: 'delete',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 查询用户关注数
|
||||
export function getUserFollows(params: { username: string }): Promise<AxiosResponse<number>> {
|
||||
return request({
|
||||
url: '/api/v1/follow/followingCount',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 查询用户粉丝数
|
||||
export function getUserFollowers(params: { username: string; followType: string; }): Promise<AxiosResponse<number>> {
|
||||
return request({
|
||||
url: '/api/v1/follow/followersCount',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 查询用户粉丝数和关注数
|
||||
export function getUserFollowerCounts(params: { username: string; }): Promise<AxiosResponse<{ follow_count: number; fans_count: number }>> {
|
||||
return request({
|
||||
url: '/api/v1/follow/userBaseInfo',
|
||||
method: 'get',
|
||||
params
|
||||
}, { customError: true });
|
||||
}
|
||||
|
||||
// 查询登录用户是否关注某用户
|
||||
export function checkHasFollowed(params: { username: string; otherUsername: string; followType: number }): Promise<AxiosResponse<boolean>> {
|
||||
return request({
|
||||
url: '/api/v1/follow/hasFollowed',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 查询特定用户组织列表
|
||||
export function getUserOrgans(params: { user_name: string; page: number; per_page: number }): Promise<AxiosResponse<{ content: OrgData[] }>> {
|
||||
return request({
|
||||
url: `/api/v1/groups/${params.user_name}/list`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 查询特定用户的贡献图
|
||||
export function queryUserContributes(params: {
|
||||
username: string;
|
||||
period?: string;
|
||||
year?: string;
|
||||
}): Promise<AxiosResponse<{ [propName: string]: number }>> {
|
||||
return request({
|
||||
url: `/api/v1/events/${params.username}/contributions`,
|
||||
method: 'get',
|
||||
params
|
||||
}, { customError: true });
|
||||
}
|
||||
|
||||
// 关注某用户
|
||||
export function followUser(params: { username: string; followedUsername: string; followType: number }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/follow',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 取消关注某用户
|
||||
export function unfollowUser(params: { username: string; unfollowUsername: string; followType: number; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/follow',
|
||||
method: 'delete',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户邮箱列表
|
||||
export function getEmailList(params: { username: string; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user/getEmailList',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
export function getEmailListForCombobox(params: { username: string; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user/getEmailListForCombobox',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 设置并更新邮箱
|
||||
export function setVerifyEmail(params: { objectId: string }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user/verifyEmail',
|
||||
method: 'get',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 删除用户设置邮箱
|
||||
export function deleteEmail(params: { email: string; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user/deleteEmail',
|
||||
method: 'delete',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 更新主邮箱设置
|
||||
export function updateEmail(params: { username: string; email: string }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user/updateEmail',
|
||||
method: 'put',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 发送更新邮箱验证码接口
|
||||
export function sendEmailVeriCode(params: { username: string; email: string; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user/sendEmailVeriCode',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 发送更新邮箱验证码接口
|
||||
export function verifyCodeEmail(params: { code: string; email: string; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user/verifyCodeEmail',
|
||||
method: 'put',
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
// 设置密码
|
||||
export function setPassword(params: { password: string; username: string; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user/setPassword',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
export function updatePassword(params: { origin_password: string; password: string; username: string; }): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user/updatePassword',
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// 判断是否有设置密码
|
||||
export function passwordAvailable(): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user/passwordAvailable',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取当前用户加入的组织
|
||||
export function getMyGroupsList(params: any): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: '/api/v1/user_groups/related_me',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/** 退出组织 */
|
||||
export function leaveGroups(params: any): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: `/api/v1/groups/${params.orgId}/leave`,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户访问令牌列表
|
||||
export function getImpersonationTokens(params: any): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: `/api/v1/user/getImpersonationTokens`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 创建用户访问令牌
|
||||
export function addImpersonationTokens(params: any): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: `/api/v1/user/${params.username}/impersonation_tokens`,
|
||||
method: 'post',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
// 删除用户访问令牌
|
||||
export function deleteImpersonationTokens(params: any): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: `/api/v1/user/${params.username}/impersonation_tokens/${params.id}`,
|
||||
method: 'delete',
|
||||
params: { name: params.name }
|
||||
});
|
||||
}
|
||||
// 活动会话列表
|
||||
export function getLatest(params: any): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: `/api/v1/user/activity-session/latest`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
// 删除活动会话
|
||||
export function deleteOffline(params: any): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: `/api/v1/user/activity-session/offline`,
|
||||
method: 'put',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户参与的项目
|
||||
export function getUserProject(params: any): Promise<AxiosResponse<any>> {
|
||||
return request({
|
||||
url: `/api/v1/user_projects/related_me`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户粉丝列表
|
||||
export function getFollowersList(params: { username: string; pageNum: number; pageSize: number; }): Promise<AxiosResponse<{ content: FollowerData[]; total: number; }>> {
|
||||
return request({
|
||||
url: '/api/v1/follow/followers',
|
||||
method: 'get',
|
||||
params
|
||||
}, { customError: true });
|
||||
}
|
||||
// 搜索用户列表
|
||||
export function searchUserList(params: { keyword?: string; pageNum: number; pageSize: number; }): Promise<AxiosResponse<{ content: any[]; total: number; }>> {
|
||||
return request({
|
||||
url: '/api/v1/user/search',
|
||||
method: 'get',
|
||||
params
|
||||
}, { customError: true });
|
||||
}
|
||||
// 获取用户关注列表
|
||||
export function getFollowingList(params: { username: string; pageNum: number; pageSize: number; }): Promise<AxiosResponse<{ content: FollowerData[]; total: number; }>> {
|
||||
return request({
|
||||
url: '/api/v1/follow/followingList',
|
||||
method: 'get',
|
||||
params
|
||||
}, { customError: true });
|
||||
}
|
||||
|
||||
// 获取用户语言集合
|
||||
export function getUserLangData(params: { type: string; user_name: string; }): Promise<AxiosResponse<string[]>> {
|
||||
return request({
|
||||
url: `/api/v1/profile/${params.user_name}/project_languages`,
|
||||
method: 'get',
|
||||
params
|
||||
}, { customError: true });
|
||||
}
|
||||
|
||||
// 获取用户关注的项目动态推送
|
||||
export function getUserConcernEvents(params?: any): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/events/follower_events',
|
||||
method: 'get',
|
||||
params
|
||||
}));
|
||||
}
|
||||
|
||||
// 获取用户被邀请的项目列表
|
||||
export function getUserInviteRepo(params?: any): Promise<AxiosResponse<string[]>> {
|
||||
return request({
|
||||
url: `/api/v1/invite/sourcePage`,
|
||||
method: 'get',
|
||||
params
|
||||
}, { customError: true });
|
||||
}
|
||||
|
||||
// 获取用户绑定的三方信息
|
||||
export function getUserIdentity(params?: any): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/user/identity/list',
|
||||
method: 'get',
|
||||
params
|
||||
}));
|
||||
}
|
||||
|
||||
// 用户绑定三方平台
|
||||
export function bindUserIdentity(data?: any): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/user/identity',
|
||||
method: 'post',
|
||||
data
|
||||
}));
|
||||
}
|
||||
|
||||
// 第三方平台解绑
|
||||
export function unBindUserIdentity(data?: any): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/user/identity',
|
||||
method: 'delete',
|
||||
data
|
||||
}));
|
||||
}
|
||||
|
||||
// 获取当前用户的手机号
|
||||
export function getLoginMobile(params?: any): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/user/mobile',
|
||||
method: 'get',
|
||||
params
|
||||
}));
|
||||
}
|
||||
|
||||
// 用户账号注销
|
||||
export function userAccountDel(params?: any): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/user/del',
|
||||
method: 'delete',
|
||||
params
|
||||
}));
|
||||
}
|
||||
|
||||
// 获取第三方atomgit账号使用流水线
|
||||
export function getAtomgitIdentity(): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/user/identity/atomgit',
|
||||
method: 'get'
|
||||
}));
|
||||
}
|
||||
|
||||
// 获取登录弹窗配置
|
||||
export function getLoginConfig(): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/config/isLogin',
|
||||
method: 'get'
|
||||
}));
|
||||
}
|
||||
|
||||
// 获取登陆token
|
||||
export function getUserToken(): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/user/oauth/token',
|
||||
method: 'get'
|
||||
}, {
|
||||
customError: true
|
||||
}));
|
||||
}
|
||||
// 获取用户信息
|
||||
export function getUserInfo(): catchRt<any> {
|
||||
return reqCatchV2(() => request({
|
||||
url: '/api/v1/user/oauth/userInfo',
|
||||
method: 'get'
|
||||
}, {
|
||||
customError: true
|
||||
}));
|
||||
}
|
||||
185
src/api/user/types.ts
Normal file
@@ -0,0 +1,185 @@
|
||||
export interface LoginMobile {
|
||||
type: 'verifyCode'
|
||||
mobile: string
|
||||
code: string
|
||||
}
|
||||
|
||||
export interface LoginPassword {
|
||||
type: 'password'
|
||||
username: string
|
||||
password: string
|
||||
}
|
||||
|
||||
export interface RegisterMobile {
|
||||
type: 'register'
|
||||
username: string
|
||||
mobile: string
|
||||
password: string
|
||||
verificationcode: string
|
||||
nickname: string
|
||||
}
|
||||
|
||||
export type LoginReqType = 'register' | 'verifyCode' | 'password'
|
||||
|
||||
export interface RegisterReqType {
|
||||
username: string
|
||||
mobile: string
|
||||
email?: string
|
||||
nickname: string
|
||||
password?: string
|
||||
verificationcode?: string
|
||||
[x: string]: any
|
||||
}
|
||||
|
||||
export interface LoginResType {
|
||||
domain_id?: string
|
||||
email?: string
|
||||
id?: string
|
||||
mobile?: string
|
||||
nickname?: string
|
||||
username?: string
|
||||
access_token?: string
|
||||
refresh_token?: string
|
||||
xauth_token?: string
|
||||
}
|
||||
|
||||
export interface Profile {
|
||||
setting_private: boolean;
|
||||
website: string;
|
||||
description: string;
|
||||
location: string;
|
||||
company: string;
|
||||
email_private: boolean;
|
||||
email?: string;
|
||||
show_email?: string;
|
||||
github_account: string;
|
||||
bg_image: string;
|
||||
}
|
||||
export interface preferenceProfile {
|
||||
highlight: string;
|
||||
tab_space_len: number;
|
||||
}
|
||||
export interface repoProfile {
|
||||
default_branch: string;
|
||||
}
|
||||
// 获取用户基本信息
|
||||
export interface UserProfileResType {
|
||||
profile: Profile;
|
||||
nickname: string;
|
||||
avatar: string;
|
||||
}
|
||||
// 用户修改资料参数
|
||||
export interface UserProfileReqType {
|
||||
profile: Partial<Profile>;
|
||||
nickname: string;
|
||||
avatar: String;
|
||||
}
|
||||
// 用户修改偏好设置参数
|
||||
export interface UserPreferenceReqType {
|
||||
profile: Partial<preferenceProfile>;
|
||||
type: string;
|
||||
}
|
||||
// 用户修改项目设置参数
|
||||
export interface UserRepoReqType {
|
||||
profile: Partial<repoProfile>;
|
||||
type: string;
|
||||
}
|
||||
|
||||
// 用户详细信息
|
||||
export interface UserProfile {
|
||||
profile: Profile;
|
||||
nickname: string;
|
||||
nick_name?: string;
|
||||
username: string;
|
||||
fans: null;
|
||||
concerns: null;
|
||||
avatar: string;
|
||||
}
|
||||
|
||||
// 组织信息
|
||||
export interface OrgData {
|
||||
id: number;
|
||||
path: string;
|
||||
name: string;
|
||||
avatar_url: null;
|
||||
full_path: string;
|
||||
full_name: string;
|
||||
web_url: string;
|
||||
}
|
||||
|
||||
// 关注用户列表信息
|
||||
export interface FollowerData {
|
||||
user_id?: string;
|
||||
follow_id?: string;
|
||||
follow_type?: number;
|
||||
ip: string;
|
||||
remark?: string;
|
||||
is_friend?: number;
|
||||
create_time?: string;
|
||||
avatar?: string;
|
||||
nick_name?: string;
|
||||
username?: string;
|
||||
description?: string;
|
||||
location?: string;
|
||||
groupname?: string;
|
||||
website?: string;
|
||||
}
|
||||
|
||||
// 参数的项目接口信息
|
||||
export interface projectItems {
|
||||
star_count: number;
|
||||
forks_count: number;
|
||||
watch_count: null | number;
|
||||
import_star_count: number;
|
||||
import_forks_count: number;
|
||||
import_watch_count: number;
|
||||
id: number;
|
||||
description: string;
|
||||
name: string;
|
||||
name_with_namespace: string;
|
||||
path: string;
|
||||
path_with_namespace: null | string;
|
||||
develop_mode: string;
|
||||
created_at: null | string;
|
||||
updated_at: null | string;
|
||||
archived: boolean;
|
||||
is_kia: null | string;
|
||||
ssh_url_to_repo: string;
|
||||
http_url_to_repo: string;
|
||||
web_url: string;
|
||||
readme_url: null | string;
|
||||
product_id: null | string;
|
||||
product_name: null | string;
|
||||
license_url: null | string;
|
||||
license: null | string;
|
||||
namespace: string;
|
||||
namespace_info: {
|
||||
id: number;
|
||||
name: string;
|
||||
path: string;
|
||||
develop_mode: string;
|
||||
region: null | string;
|
||||
cell: null | string;
|
||||
kind: string;
|
||||
full_path: string;
|
||||
full_name: string;
|
||||
parent_id: null | string;
|
||||
visibility_level: number;
|
||||
enable_file_control: boolean;
|
||||
owner_id: number;
|
||||
},
|
||||
mirror_project_data: null | string;
|
||||
visibility: string;
|
||||
open_issues_count: number;
|
||||
open_merge_requests_count: number;
|
||||
open_change_requests_count: number;
|
||||
starred: boolean;
|
||||
last_activity_at: Date;
|
||||
main_repository_language: Array<string>;
|
||||
forked_from_project: null | string;
|
||||
permissions: number;
|
||||
member_count: number;
|
||||
repository_size: number;
|
||||
topic_names: null | string;
|
||||
is_recommend: number;
|
||||
}
|
||||
318
src/assets/css/devui.scss
Normal file
@@ -0,0 +1,318 @@
|
||||
/* devui css override */
|
||||
// d-layout
|
||||
div.devui-layout__header {
|
||||
flex: none;
|
||||
}
|
||||
div.devui-layout__content {
|
||||
flex: 1;
|
||||
min-height: auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
ul.devui-menu-vertical {
|
||||
.devui-menu-item {
|
||||
background: transparent;
|
||||
align-items: center;
|
||||
}
|
||||
.devui-menu-item-select {
|
||||
background: var(--color-CG300) !important;
|
||||
border-radius: var(--border-radius);
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.devui-input-slot__suffix > span {
|
||||
color: var(--devui-text);
|
||||
}
|
||||
|
||||
div.devui-tooltip {
|
||||
z-index: var(--devui-z-index-pop-up, 1060);
|
||||
background-color: var(--devui-feedback-overlay-bg, #464d6e);
|
||||
border-radius: var(--devui-border-radius-feedback, 4px);
|
||||
}
|
||||
|
||||
/* 隐藏必选符号 */
|
||||
// .devui-form__label--required:before {
|
||||
// display: none;
|
||||
// content: '';
|
||||
// }
|
||||
|
||||
// d-skeleton-item
|
||||
.devui-skeleton-item {
|
||||
&.devui-skeleton-item--square {
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
// d-tree
|
||||
.devui-tree {
|
||||
&__node,
|
||||
&__node-title {
|
||||
color: var(--color-font) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// d-editor
|
||||
.devui-code-editor {
|
||||
.monaco-editor {
|
||||
.line-numbers {
|
||||
color: var(--color-lighter);
|
||||
}
|
||||
}
|
||||
}
|
||||
.devui-splitter {
|
||||
&__collapse {
|
||||
background-color: var(--color-lighter) !important;
|
||||
}
|
||||
}
|
||||
// tab
|
||||
.devui-menu-horizontal {
|
||||
.devui-menu-item {
|
||||
span {
|
||||
font-weight: 400;
|
||||
color: var(--color-light);
|
||||
}
|
||||
}
|
||||
.devui-menu-item-select,
|
||||
.devui-menu-active-parent,
|
||||
.devui-menu-overflow-container:hover,
|
||||
.devui-menu-item:hover {
|
||||
span {
|
||||
color: var(--color-light);
|
||||
}
|
||||
&:after {
|
||||
background-color: var(--color-font) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.devui-icon--operable.devui-icon__container {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.devui-menu-vertical {
|
||||
.devui-menu-item:hover {
|
||||
background-color: $devui-list-item-hover-bg;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
// input输入框icon
|
||||
.devui-input {
|
||||
&__container {
|
||||
i.icon {
|
||||
&:before {
|
||||
color: var(--color-CG500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// date-range组件
|
||||
.devui-range-date-picker-pro {
|
||||
.devui-range-date-picker-pro__range-picker-icon {
|
||||
svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
// modal
|
||||
.devui-modal {
|
||||
&__header {
|
||||
height: 40px !important;
|
||||
}
|
||||
}
|
||||
// textarea 文字计数颜色
|
||||
.devui-textarea__show-count {
|
||||
color: var(--color-lighter) !important;
|
||||
}
|
||||
|
||||
.devui-progress__content .devui-progress__line {
|
||||
background: var(--color-CG300, #e4e9f0);
|
||||
}
|
||||
// radio button
|
||||
.devui-radio-button {
|
||||
&.active {
|
||||
background-color: var(--color-primary) !important;
|
||||
border-color: var(--color-primary) !important;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
// button
|
||||
button.devui-button--solid--primary {
|
||||
background-color: #5e7ce0;
|
||||
border: none;
|
||||
}
|
||||
button.devui-button--solid--danger {
|
||||
background-color: var(--devui-contrast, #c7000b);
|
||||
border: none;
|
||||
}
|
||||
button.devui-button--outline {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
// 次要按钮样式
|
||||
button.devui-button--solid--secondary {
|
||||
border: var(--devui-btn-common-border-color) solid 1px;
|
||||
border-radius: 4px;
|
||||
background: #D1D1D1;
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
border: var(--devui-btn-common-border-color) solid 1px;
|
||||
color: var(--devui-text);
|
||||
background: linear-gradient(0deg, rgba(188, 188, 208, 0.1) 0%, rgba(188, 188, 208, 0.1) 100%), var(--White, #FFF);
|
||||
}
|
||||
}
|
||||
|
||||
// d-avatar
|
||||
.devui-avatar {
|
||||
vertical-align: middle;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
img {
|
||||
background-color: white;
|
||||
}
|
||||
&.devui-avatar-square {
|
||||
img,
|
||||
.devui-avatar--style {
|
||||
border-radius: var(--border-radius) !important;
|
||||
}
|
||||
&.radius-big {
|
||||
img,
|
||||
.devui-avatar--style {
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.devui-result {
|
||||
&__title {
|
||||
color: var(--color-light);
|
||||
}
|
||||
&__desc {
|
||||
color: var(--color-light);
|
||||
}
|
||||
&__extra {
|
||||
color: var(--color-lighter);
|
||||
}
|
||||
}
|
||||
|
||||
.devui-tree {
|
||||
&__node {
|
||||
&-content {
|
||||
&--value-wrapper {
|
||||
div {
|
||||
white-space: nowrap;
|
||||
word-break: keep-all;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.devui-tabs__nav--slider > li.active {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.devui-table {
|
||||
&__tbody {
|
||||
tr {
|
||||
td {
|
||||
border-bottom: 1px solid var(--color-border-light);
|
||||
}
|
||||
&:first-of-type {
|
||||
td {
|
||||
border-top: none;
|
||||
&:first-of-type {
|
||||
border-top-left-radius: var(--border-radius);
|
||||
}
|
||||
&:last-of-type {
|
||||
border-top-right-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:last-of-type {
|
||||
td {
|
||||
border-bottom: none;
|
||||
&:first-of-type {
|
||||
border-bottom-left-radius: var(--border-radius);
|
||||
}
|
||||
&:last-of-type {
|
||||
border-bottom-right-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.devui-breadcrumb {
|
||||
&__separator {
|
||||
margin: 0 2px;
|
||||
}
|
||||
}
|
||||
// .devui-input--error,.devui-select__selection--error,.devui-textarea--error {
|
||||
// background-color: #fff;
|
||||
// }
|
||||
.devui-editable-select .devui-editable-select__inner {
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.devui-link-hover {
|
||||
&:hover {
|
||||
color: var(--devui-link) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.devui-textarea__show-count {
|
||||
color: var(--devui-text) !important;
|
||||
}
|
||||
|
||||
//.devui-form__label-span {
|
||||
// color: var(--devui-text) !important;
|
||||
// font-size: 16px !important;
|
||||
// line-height: 22px;
|
||||
// font-weight: 500;
|
||||
//}
|
||||
|
||||
.devui-checkbox {
|
||||
padding: 3px 0;
|
||||
}
|
||||
.devui-radio__wrapper {
|
||||
padding: 3px 0;
|
||||
}
|
||||
.devui-checkbox__label-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
.devui-radio.devui-radio--md span .devui-radio__label {
|
||||
font-size: 16px;
|
||||
}
|
||||
.devui-radio-group div.devui-radio__wrapper {
|
||||
height: auto;
|
||||
}
|
||||
.devui-radio__wrapper label.devui-radio {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.button-content {
|
||||
// font-weight: 600;
|
||||
}
|
||||
.devui-checkbox span.devui-checkbox__material {
|
||||
border-color: var(--checkbox-border-color);
|
||||
}
|
||||
circle.devui-radio__material-outer {
|
||||
stroke: var(--checkbox-border-color);
|
||||
}
|
||||
|
||||
.devui-table--lg tbody>tr.devui-table__row>td,
|
||||
.cardlist-item-padding {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
458
src/assets/css/devui_mdpreview.scss
Normal file
@@ -0,0 +1,458 @@
|
||||
// markdown
|
||||
.dp-md-view {
|
||||
pre {
|
||||
position: relative;
|
||||
code {
|
||||
padding-right: 32px!important;
|
||||
}
|
||||
}
|
||||
.md-view-copy-icon {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 9px;
|
||||
&:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
.g-md-container {
|
||||
:deep(.md-toolbar-container) {
|
||||
padding-right: 88px;
|
||||
}
|
||||
:deep(.dp-editor-md-preview-container.dp-md-view summary) {
|
||||
cursor: pointer;
|
||||
}
|
||||
position: relative;
|
||||
.g-md-preview-btn {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 16px;
|
||||
color: var(--color-lighter);
|
||||
&:hover {
|
||||
:deep(.button-content) {
|
||||
color: var(--color-primary) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.g-md-upload-btn {
|
||||
position: absolute;
|
||||
left: 710px;
|
||||
top: 10px;
|
||||
cursor: pointer;
|
||||
:deep(.devui-icon__container) {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
:deep(.icon) {
|
||||
color: var(--devui-icon-text, #71757f);
|
||||
}
|
||||
}
|
||||
:deep(.devui-fullscreen) {
|
||||
z-index: 999 !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.dp-md-container) {
|
||||
border: none;
|
||||
.CodeMirror {
|
||||
border-radius: 3px;
|
||||
pre {
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
.dp-editor-md-preview-container.dp-md-view {
|
||||
word-break: break-all;
|
||||
line-height: normal;
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
/* 文章正文 */
|
||||
p {
|
||||
font-size: 14px;
|
||||
color: var(--color-G900);
|
||||
font-weight: normal;
|
||||
line-height: 26px;
|
||||
margin: 0;
|
||||
overflow-x: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
p:has(+ pre) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
span,
|
||||
p span {
|
||||
line-height: 1.5;
|
||||
}
|
||||
/* 加粗 */
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
/* 斜体 */
|
||||
i,
|
||||
cite,
|
||||
em,
|
||||
var,
|
||||
address,
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
/* 上标 */
|
||||
sup {
|
||||
left: 2px;
|
||||
}
|
||||
/* 下标 */
|
||||
sub {
|
||||
margin: 0 2px;
|
||||
}
|
||||
/* 标题通用格式 */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: var(--color-G900);
|
||||
margin: 0.67em 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
h1 {
|
||||
font-size: 22px;
|
||||
line-height: 32px;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
h1 code {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
h2 code {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
h3 code {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
h4 code {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h5 code {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
h6 code {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 列表(有序,无序) */
|
||||
ul,
|
||||
ol {
|
||||
margin: 0 0 8px 0;
|
||||
padding: 0;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
overflow-x: auto;
|
||||
color: var(--color-CG600);
|
||||
}
|
||||
li {
|
||||
margin: 4px 0 0 18px;
|
||||
}
|
||||
ol,
|
||||
ol > li {
|
||||
list-style-type: decimal !important;
|
||||
// 表达式,修复有序列表序号展示不全的问题
|
||||
:nth-child(n+10){
|
||||
margin-left: 24px;
|
||||
}
|
||||
:nth-child(n+100){
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
ul,
|
||||
ul > li {
|
||||
list-style-type: disc;
|
||||
font-size: 14px;
|
||||
margin-right: 11px;
|
||||
color: var(--color-G900);
|
||||
}
|
||||
ol ul,
|
||||
ol ul > li,
|
||||
ul ul,
|
||||
ul ul li {
|
||||
// list-style: circle;
|
||||
font-size: 14px;
|
||||
list-style: none;
|
||||
margin-left: 16px;
|
||||
}
|
||||
ul ul ul,
|
||||
ul ul ul li,
|
||||
ol ol,
|
||||
ol ol > li,
|
||||
ol ul ul,
|
||||
ol ul ul > li,
|
||||
ul ol,
|
||||
ul ol > li {
|
||||
list-style: square;
|
||||
}
|
||||
|
||||
/* 任务列表 */
|
||||
.task-list-item {
|
||||
list-style: none;
|
||||
margin: 8px 0 0 0;
|
||||
}
|
||||
.task-list-item label {
|
||||
margin-left: 4px;
|
||||
}
|
||||
input[type=checkbox]+label, label+a {
|
||||
vertical-align: middle;
|
||||
}
|
||||
input[type=checkbox]+label {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* 图片 */
|
||||
img {
|
||||
margin: 8px 0;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* 引用 */
|
||||
blockquote {
|
||||
display: block;
|
||||
padding: 16px;
|
||||
margin: 0 0 24px;
|
||||
border-left: 8px solid #dddfe4;
|
||||
background: #eef0f4;
|
||||
overflow: auto;
|
||||
word-break: break-word !important;
|
||||
}
|
||||
|
||||
blockquote ul,
|
||||
blockquote ol {
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
blockquote ul li {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
blockquote ol li {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 引用 - 文字 */
|
||||
blockquote p {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: #555666;
|
||||
font-weight: normal;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 分割线 */
|
||||
hr {
|
||||
margin: 24px 0;
|
||||
border: none;
|
||||
border-bottom: solid #ddd 1px;
|
||||
}
|
||||
|
||||
/* 表格 */
|
||||
tbody {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
table tr {
|
||||
border: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
display: table;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
tbody {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
table tr:nth-child(2n) {
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
table tr th,
|
||||
table tr td {
|
||||
font-size: 14px;
|
||||
color: #4f4f4f;
|
||||
line-height: 22px;
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
word-break: normal !important;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table tr th code,
|
||||
table tr td code {
|
||||
white-space: normal;
|
||||
word-break: normal !important;
|
||||
}
|
||||
|
||||
table tr th {
|
||||
font-weight: bold;
|
||||
background-color: #eff3f5;
|
||||
}
|
||||
|
||||
/* 目录列表 */
|
||||
dl {
|
||||
margin: 24px;
|
||||
}
|
||||
|
||||
dl dt {
|
||||
margin: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
dl dd {
|
||||
margin: 0 0 8px 40px;
|
||||
}
|
||||
dl dt dd {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
/* pre */
|
||||
pre {
|
||||
margin-bottom: 24px;
|
||||
white-space: pre-wrap;
|
||||
padding: 0;
|
||||
}
|
||||
pre code {
|
||||
// color: unset;
|
||||
color: var(--color-G900);
|
||||
}
|
||||
|
||||
/* 代码块字体 */
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: var(--color-G900);
|
||||
}
|
||||
code {
|
||||
color: #c7254e;
|
||||
// background-color: #f9f2f4;
|
||||
background-color: var(--color-G200);
|
||||
border-radius: 4px;
|
||||
padding: 6px;
|
||||
// display: inline;
|
||||
}
|
||||
kbd {
|
||||
padding: 2px 8px;
|
||||
border: 1px solid rgba(63, 63, 63, 0.25);
|
||||
box-shadow: 0 1px 0 rgba(63, 63, 63, 0.25);
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
margin: 0 2px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 超链接 */
|
||||
a {
|
||||
// color: #4ea1db;
|
||||
color: var(--color-B600);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus {
|
||||
// color: #ca0c16;
|
||||
color: var(--color-B600);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
// color: #6795b5;
|
||||
color: var(--color-B600);
|
||||
}
|
||||
|
||||
/* abbr */
|
||||
abbr[title],
|
||||
abbr[data-original-title] {
|
||||
cursor: help;
|
||||
border-bottom: 1px dotted #999;
|
||||
}
|
||||
|
||||
/* toc TODO: devui 尚未支持 */
|
||||
.toc {
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
margin: 0 0 24px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.toc ul {
|
||||
margin: 0 0 8px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.toc ul ul {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.toc ul li {
|
||||
list-style-type: none;
|
||||
margin: 8px 0 0 24px;
|
||||
}
|
||||
|
||||
/* 脚注 TODO: devui 尚未支持*/
|
||||
.footnote {
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
top: -4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.footnotes ol li {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
margin: 0 0 8px 24px;
|
||||
}
|
||||
}
|
||||
49
src/assets/css/jyh.scss
Normal file
@@ -0,0 +1,49 @@
|
||||
/* devui css override */
|
||||
// d-layout
|
||||
.jyh-form {
|
||||
.devui-form__label-span {
|
||||
color: #595959;
|
||||
font-family: HarmonyOS Sans SC;
|
||||
font-weight: regular;
|
||||
font-size: 14px;
|
||||
line-height: 32px;
|
||||
letter-spacing: 0px;
|
||||
text-align: left;
|
||||
}
|
||||
.devui-form__label--start {
|
||||
text-align: right;
|
||||
}
|
||||
.devui-form__item--horizontal {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.jyh-form-operation {
|
||||
margin-left: 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.jyh-table {
|
||||
.devui-table__cell {
|
||||
color: #191919;
|
||||
font-family: HarmonyOS Sans SC;
|
||||
font-weight: regular;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
letter-spacing: 0px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.devui-table__cell a {
|
||||
cursor: pointer;
|
||||
color: #0A59F7;
|
||||
font-family: HarmonyOS Sans SC;
|
||||
font-weight: regular;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
letter-spacing: 0px;
|
||||
text-align: left;
|
||||
}
|
||||
.devui-table__row td {
|
||||
padding-top: 10px !important;
|
||||
padding-bottom: 10px !important;
|
||||
}
|
||||
}
|
||||
458
src/assets/css/main.scss
Normal file
@@ -0,0 +1,458 @@
|
||||
/* 引入全局css变量 */
|
||||
@import './variable.css';
|
||||
@import './devui.scss';
|
||||
@import './theme.scss';
|
||||
@import './jyh.scss';
|
||||
@import './mixins/index.scss';
|
||||
/* 引入tailwindCSS */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
// 基础CSS
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
height: 100%;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
// scorll 事件失效 overflow-y: overlay
|
||||
}
|
||||
html {
|
||||
overflow-y: scroll; // html本身没有滚动 为了防止自定义滚动条出现时界面抖动,需要预留轨道
|
||||
}
|
||||
html body {
|
||||
background-color: $devui-global-bg;
|
||||
font-size: var(--text-sm);
|
||||
color: var(--color-font);
|
||||
}
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
color: var(--color-lighter);
|
||||
}
|
||||
// 解决滚动条占用内容宽度
|
||||
// html {
|
||||
// overflow-y: scroll;
|
||||
// }
|
||||
|
||||
// :root {
|
||||
// overflow-y: auto;
|
||||
// overflow-x: hidden;
|
||||
// }
|
||||
|
||||
// :root body {
|
||||
// position: absolute;
|
||||
// }
|
||||
|
||||
// body {
|
||||
// width: 100vw;
|
||||
// overflow: hidden;
|
||||
// }
|
||||
|
||||
// 兼容火狐浏览器
|
||||
:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
// 自定义class
|
||||
.g-border {
|
||||
border: 1px solid var(--devui-line);
|
||||
border-radius: var(--border-radius);
|
||||
&-light {
|
||||
border: 1px solid var(--color-border-light);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
.g-card,
|
||||
.g-content-card {
|
||||
background-color: $devui-base-bg;
|
||||
box-shadow: $devui-shadow-length-base $devui-light-shadow;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
.g-main-content {
|
||||
line-height: 30px;
|
||||
}
|
||||
.g-sub-content {
|
||||
line-height: 20px;
|
||||
}
|
||||
.g-border-bottom {
|
||||
border-bottom: solid 1px var(--color-G200);
|
||||
}
|
||||
.g-icon-pointer {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: var(--color-link) !important;
|
||||
}
|
||||
}
|
||||
.g-border-radius-top-no {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
.g-icon-right {
|
||||
vertical-align: middle;
|
||||
margin-right: 4px;
|
||||
}
|
||||
.g-icon-left {
|
||||
vertical-align: middle;
|
||||
margin-left: 8px;
|
||||
}
|
||||
.g-drop-menu {
|
||||
width: 100px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.g-mid-line {
|
||||
width: 0.5px;
|
||||
height: 16px;
|
||||
background: var(--color-border-light);
|
||||
}
|
||||
.g-row-line {
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background: var(--color-G300);
|
||||
}
|
||||
.g-max-width {
|
||||
width: 90%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.g-font-bold {
|
||||
font-weight: 600;
|
||||
}
|
||||
.g-label-font {
|
||||
.devui-form__label {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
/* 滚动条样式自定义 */
|
||||
body::-webkit-scrollbar, body>* ::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 4px;
|
||||
}
|
||||
body::-webkit-scrollbar-thumb, body>* ::-webkit-scrollbar-thumb {
|
||||
border-radius: 8px;
|
||||
background-color: var(--devui-disabled-text);
|
||||
&:hover{
|
||||
background-color: var(--devui-placeholder)
|
||||
}
|
||||
}
|
||||
body::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
body::-webkit-scrollbar-corner {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
&:after {
|
||||
content: '';
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.space-y-20 > *:not(:last-child) {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* 分隔符 | */
|
||||
.g-delimiter {
|
||||
display: inline-block;
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
background: var(--color-G300);
|
||||
vertical-align: middle;
|
||||
}
|
||||
.g-input-border {
|
||||
.devui-input__wrapper:not(.devui-input--focus) {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
.devui-input-slot__prepend,
|
||||
.devui-input-slot__append {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
}
|
||||
.devui-select__dropdown .devui-select__dropdown--empty {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
/* 输入框 去掉hover效果*/
|
||||
.devui-input__wrapper:not(.devui-input--error):not(.devui-input--disabled):not(.devui-input--focus):hover {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
|
||||
/* 多行文本输入框 去掉hover效果*/
|
||||
.devui-textarea:not(.devui-textarea--error):not(.devui-textarea--disabled):not(.devui-textarea--focus):hover {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
|
||||
/* 自动补全输入框 去掉hover效果*/
|
||||
.devui-auto-complete-input__wrapper:not(.devui-auto-complete--disabled):not(.devui-auto-complete-input__wrapper--error):hover {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
|
||||
/* 可输入下拉选择框 去掉hover效果*/
|
||||
.devui-editable-select-input__wrapper:not(.devui-editable-select-input__wrapper--disabled):not(.devui-editable-select-input__wrapper--focus):hover {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
|
||||
/* 分页 去掉hover效果*/
|
||||
.devui-pagination .devui-pagination__size:hover {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
|
||||
/* 数字输入框 去掉hover效果*/
|
||||
.devui-input-number:hover .devui-input-number__control-buttons:not(.disabled) {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
.devui-input-number:hover .devui-input-number__input-box:not(.disabled) {
|
||||
border: 1px solid var(--devui-line, #9b9fa8);
|
||||
}
|
||||
|
||||
/* 下拉框 去掉hover效果*/
|
||||
.devui-select__selection:hover {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
|
||||
/* 时间范围选择 去掉hover效果 */
|
||||
.devui-range-date-picker-pro .devui-range-date-picker-pro__range-picker:not(.devui-range-date-picker-pro--error):not(.devui-range-date-picker-pro--disabled):hover {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
|
||||
.g-add-border {
|
||||
border-color: var(--devui-line, #d7d8da);
|
||||
}
|
||||
.g-z-index-9 {
|
||||
z-index: 9 !important;
|
||||
}
|
||||
.g-z-index-9999 {
|
||||
z-index: 9999 !important; // 9的层级低于列表的遮罩层
|
||||
}
|
||||
.g-hidden-scrollbar {
|
||||
scrollbar-width: none;
|
||||
scrollbar-color: transparent transparent;
|
||||
-ms-overflow-style: none;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
&::-webkit-scrollbar-horizontal {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.g-discussion-item .dp-md-container .dp-md-content-container {
|
||||
min-height: 150px;
|
||||
}
|
||||
// modal相关
|
||||
.g-modal-footer {
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
gap: 8px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.row-reverse {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
white-space: nowrap;
|
||||
word-break: keep-all;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ellipsis-pre {
|
||||
white-space: pre-line;
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ellipsis-two-line {
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.ellipsis-three-line {
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
|
||||
.absolute-full {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.inline-center {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
// 重置a标签的默认和hover色值
|
||||
.reset-hover {
|
||||
color: unset;
|
||||
&:hover {
|
||||
color: unset;
|
||||
}
|
||||
}
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.spin {
|
||||
animation: spin 2s linear infinite;
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
// 重写RadioGroup样式
|
||||
.g-radio-group {
|
||||
&.devui-radio-group {
|
||||
background-color: var(--color-G100);
|
||||
padding: 2px;
|
||||
.devui-radio-button {
|
||||
border: none;
|
||||
line-height: 22px;
|
||||
height: 28px;
|
||||
color: var(--color-CG600);
|
||||
&:first-child {
|
||||
border-left: none !important;
|
||||
}
|
||||
&.active {
|
||||
color: #fff;
|
||||
box-shadow: 0px 2px 6px 0px rgba(37, 43, 58, 0.12);
|
||||
border-radius: var(--border-radius);
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.border-none {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
input {
|
||||
background-color:transparent !important;
|
||||
// appearance: none;
|
||||
|
||||
&:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
|
||||
-webkit-text-fill-color: inherit !important;
|
||||
background-color: transparent !important;
|
||||
background-image: none;
|
||||
transition: background-color 36000s ease-in-out 0s; //背景色透明 生效时长 过渡效果 启用时延迟的时间
|
||||
}
|
||||
&:-moz-autofill, textarea:-moz-autofill, select:-moz-autofill {
|
||||
-webkit-text-fill-color: inherit !important;
|
||||
background-color: transparent !important;
|
||||
background-image: none;
|
||||
transition: background-color 36000s ease-in-out 0s; //背景色透明 生效时长 过渡效果 启用时延迟的时间
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1536px) {
|
||||
.g-padding-x {
|
||||
padding: 0 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.g-padding-x {
|
||||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.g-content-card-v2 {
|
||||
background-color: $devui-global-bg;
|
||||
border-radius: $devui-border-radius-card;
|
||||
border: 1px solid var(--gray-border-color);
|
||||
}
|
||||
|
||||
.g-number {
|
||||
border-radius: 4px;
|
||||
padding: 0 4px;
|
||||
background: var(--gray-bg-color);
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: var(--devui-text);
|
||||
}
|
||||
|
||||
.font-color-t1 {
|
||||
color: $devui-text;
|
||||
}
|
||||
|
||||
.font-color-t2 {
|
||||
color: $devui-aide-text;
|
||||
}
|
||||
|
||||
.font-color-placeholder {
|
||||
color: $devui-placeholder;
|
||||
}
|
||||
|
||||
.g-large-title-font {
|
||||
font-size: 22px;
|
||||
line-height: 22px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.g-divide-line {
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background: var(--devui-dividing-line);
|
||||
margin: 32px 0
|
||||
}
|
||||
|
||||
.g-tip-text {
|
||||
font-size: var(--devui-font-size);
|
||||
line-height: 20px;
|
||||
color: $devui-placeholder;
|
||||
}
|
||||
|
||||
// 新版设计统一设置标题样式 大小颜色行高
|
||||
.unify-settingTitle-title{
|
||||
font-weight: 700;
|
||||
line-height: 34px;
|
||||
font-size: 24px;
|
||||
color: var(--devui-text);
|
||||
}
|
||||
|
||||
// 项目设置页面标题
|
||||
.repo-settings-title {
|
||||
@apply text-xl mb-[12px] flex items-center justify-between font-semibold;
|
||||
}
|
||||
|
||||
// 下拉框动效
|
||||
.arrow-down{
|
||||
transition: transform var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1));
|
||||
transform-origin: center;
|
||||
transform: rotateZ(0deg) !important;
|
||||
}
|
||||
|
||||
.arrow-up{
|
||||
transition: transform var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1));
|
||||
transform-origin: center;
|
||||
transform: rotateZ(180deg) !important;
|
||||
}
|
||||
147
src/assets/css/mixins/button.scss
Normal file
@@ -0,0 +1,147 @@
|
||||
// 自定义 按钮额外主题 红绿橙
|
||||
|
||||
button.devui-button {
|
||||
// 实心按钮
|
||||
&--solid {
|
||||
//绿色按钮
|
||||
&--success,
|
||||
&--operable {
|
||||
background-color: $v2-color-success;
|
||||
&:hover {
|
||||
background-color: $v2-color-success-hover;
|
||||
}
|
||||
&:active {
|
||||
background-color: $v2-color-success-active;
|
||||
}
|
||||
&:disabled {
|
||||
background-color: $v2-color-success-disable;
|
||||
}
|
||||
}
|
||||
// 橙色按钮
|
||||
&--warning {
|
||||
background-color: $v2-color-warning;
|
||||
&:hover {
|
||||
background-color: $v2-color-warning-hover;
|
||||
}
|
||||
&:active {
|
||||
background-color: $v2-color-warning-active;
|
||||
}
|
||||
&:disabled {
|
||||
background-color: $v2-color-warning-disable;
|
||||
}
|
||||
}
|
||||
// 暗红按钮
|
||||
&--error {
|
||||
background-color: $v2-color-error;
|
||||
&:hover {
|
||||
background-color: $v2-color-error-hover;
|
||||
}
|
||||
&:active {
|
||||
background-color: $v2-color-error-active;
|
||||
}
|
||||
&:disabled {
|
||||
background-color: $v2-color-error-disable;
|
||||
}
|
||||
}
|
||||
}
|
||||
//镂空按钮
|
||||
&--outline {
|
||||
&--success,
|
||||
&--operable {
|
||||
color: $v2-color-success;
|
||||
border-color: $v2-color-success;
|
||||
|
||||
&:hover {
|
||||
color: $v2-color-success-hover;
|
||||
border-color: $v2-color-success-hover;
|
||||
}
|
||||
&:active {
|
||||
color: $v2-color-success-active;
|
||||
border-color: $v2-color-success-active;
|
||||
}
|
||||
&:disabled {
|
||||
color: $v2-color-success-disable;
|
||||
border-color: $v2-color-success-disable;
|
||||
}
|
||||
}
|
||||
// 橙色按钮
|
||||
&--warning {
|
||||
color: $v2-color-warning;
|
||||
border-color: $v2-color-warning;
|
||||
|
||||
&:hover {
|
||||
color: $v2-color-warning-hover;
|
||||
border-color: $v2-color-warning-hover;
|
||||
}
|
||||
&:active {
|
||||
color: $v2-color-warning-active;
|
||||
border-color: $v2-color-warning-active;
|
||||
}
|
||||
&:disabled {
|
||||
color: $v2-color-warning-disable;
|
||||
border-color: $v2-color-warning-disable;
|
||||
}
|
||||
}
|
||||
// 暗红按钮
|
||||
&--error {
|
||||
color: $v2-color-error;
|
||||
border-color: $v2-color-error;
|
||||
|
||||
&:hover {
|
||||
color: $v2-color-error-hover;
|
||||
border-color: $v2-color-error-hover;
|
||||
}
|
||||
&:active {
|
||||
color: $v2-color-error-active;
|
||||
border-color: $v2-color-error-active;
|
||||
}
|
||||
&:disabled {
|
||||
color: $v2-color-error-disable;
|
||||
border-color: $v2-color-error-disable;
|
||||
}
|
||||
}
|
||||
}
|
||||
//文字按钮
|
||||
&--text {
|
||||
&--success,
|
||||
&--operable {
|
||||
color: $v2-color-success;
|
||||
|
||||
&:hover {
|
||||
color: $v2-color-success-hover;
|
||||
}
|
||||
&:active {
|
||||
color: $v2-color-success-active;
|
||||
}
|
||||
&:disabled {
|
||||
color: $v2-color-success-disable;
|
||||
}
|
||||
}
|
||||
&--warning {
|
||||
color: $v2-color-warning;
|
||||
|
||||
&:hover {
|
||||
color: $v2-color-warning-hover;
|
||||
}
|
||||
&:active {
|
||||
color: $v2-color-warning-active;
|
||||
}
|
||||
&:disabled {
|
||||
color: $v2-color-warning-disable;
|
||||
}
|
||||
}
|
||||
&--error {
|
||||
color: $v2-color-success;
|
||||
|
||||
&:hover {
|
||||
color: $v2-color-success-hover;
|
||||
}
|
||||
&:active {
|
||||
color: $v2-color-success-active;
|
||||
}
|
||||
&:disabled {
|
||||
color: $v2-color-success-disable;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
src/assets/css/mixins/card.scss
Normal file
@@ -0,0 +1,34 @@
|
||||
@import './variables.scss';
|
||||
|
||||
.v2-g-card {
|
||||
position: relative;
|
||||
word-wrap: break-word;
|
||||
background-color: #fff;
|
||||
background-clip: border-box;
|
||||
border: 1px solid $card-border-color;
|
||||
border-radius: $card-border-radius;
|
||||
color: $card-text-color;
|
||||
}
|
||||
|
||||
.v2-g-card-header:first-child {
|
||||
border-radius: $card-border-radius $card-border-radius 0 0;
|
||||
}
|
||||
|
||||
.v2-g-card-header {
|
||||
margin-bottom: 0;
|
||||
padding: $card-padding;
|
||||
background-color: $card-border-header-bg;
|
||||
border-bottom: 1px solid $card-border-color;
|
||||
border-top-left-radius: $card-border-radius;
|
||||
border-top-right-radius: $card-border-radius;
|
||||
}
|
||||
|
||||
.v2-g-card-body {
|
||||
padding: $card-padding;
|
||||
}
|
||||
|
||||
.v2-g-card-header:only-child {
|
||||
border-bottom-left-radius: $card-border-radius;
|
||||
border-bottom-right-radius: $card-border-radius;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
2
src/assets/css/mixins/index.scss
Normal file
@@ -0,0 +1,2 @@
|
||||
@import './card.scss';
|
||||
@import './button.scss';
|
||||
21
src/assets/css/mixins/variables.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
// 按钮 scss 变量
|
||||
$v2-color-success: #10a35c;
|
||||
$v2-color-success-hover: #31a26c;
|
||||
$v2-color-success-active: #31a26c;
|
||||
$v2-color-success-disable: #d6ece2;
|
||||
|
||||
$v2-color-warning: #ed5f22;
|
||||
$v2-color-warning-hover: #f07a47;
|
||||
$v2-color-warning-active: #f07a47;
|
||||
$v2-color-warning-disable: #fce4da;
|
||||
|
||||
$v2-color-error: #da203e;
|
||||
$v2-color-error-hover: #da203e;
|
||||
$v2-color-error-active: hsla(350, 74%, 44%, 1);
|
||||
$v2-color-error-disable: #fce4da;
|
||||
|
||||
$card-border-color: #e3e3ee;
|
||||
$card-padding: 16px;
|
||||
$card-border-radius: 8px;
|
||||
$card-border-header-bg: #f9f9fb;
|
||||
$card-text-color: #3b3e55;
|
||||
16
src/assets/css/theme.scss
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* 网站主题(暂定前端控制)
|
||||
*/
|
||||
// 亮色
|
||||
.g-theme-light {
|
||||
.dp-editor-md-preview-container.dp-md-view [src$="#gh-dark-mode-only"] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// 暗色
|
||||
.g-theme-dark {
|
||||
.dp-editor-md-preview-container.dp-md-view [src$="#gh-light-mode-only"] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
78
src/assets/css/variable.css
Normal file
@@ -0,0 +1,78 @@
|
||||
:root {
|
||||
--color-G100: #FBFBFB;
|
||||
--color-G150: #F6F6F8;
|
||||
--color-G200: #F0F1F2;
|
||||
--color-G300: #E6E6E8;
|
||||
--color-G400: #D1D2D4;
|
||||
--color-G500: #B3B4B5;
|
||||
--color-G600: #9A9B9C;
|
||||
--color-G700: #7E7E80;
|
||||
--color-G800: #5B5B5C;
|
||||
--color-G900: #2D2D2E;
|
||||
--color-G1000: #000000;
|
||||
--color-CG100: #F8F9FB;
|
||||
--color-CG200: #F4F7F9;
|
||||
--color-CG300: #E4E9F0;
|
||||
--color-CG400: #CAD0D9;
|
||||
--color-CG500: #9FA7B3;
|
||||
--color-CG600: #707A87;
|
||||
--color-CG700: #505A69;
|
||||
--color-CG800: #3B4655;
|
||||
--color-CG900: #252D3B;
|
||||
--color-CG950: #151A26;
|
||||
--color-DP100: #FDF4F6;
|
||||
--color-DP200: #FAE5EC;
|
||||
--color-DP300: #F4C7D5;
|
||||
--color-DP400: #EA92AD;
|
||||
--color-DP500: #E05E86;
|
||||
--color-DP600: #B64C6D;
|
||||
--color-DP700: #963F59;
|
||||
--color-DP800: #652A3C;
|
||||
--color-DP900: #3E1A25;
|
||||
--color-DP950: #261017;
|
||||
--color-B300: #AECCFC;
|
||||
--color-B400: #6FA3F7;
|
||||
--color-B500: #3B82F6;
|
||||
--color-B600: #2562C4;
|
||||
--color-R500: #F2050D;
|
||||
--color-O500: #FF6C17;
|
||||
--color-Y100: #FEF6E5;
|
||||
--color-Y200: #FCE7BB;
|
||||
--color-Y500: #F5AB0B;
|
||||
--color-GN500: #0EB07B;
|
||||
--color-linear100: linear-gradient(180deg, #FCFCFC 0%, #F8F9FB 100%);
|
||||
--color-linear200: linear-gradient(180deg, #F8F9FA 0%, #F0F1F2 100%);
|
||||
--color-primary: var(--color-B500);
|
||||
--color-primary-hover: var(--color-B400);
|
||||
--color-primary-active: var(--color-B600);
|
||||
--color-primary-disable: var(--color-B300);
|
||||
--color-danger: var(--color-R500);
|
||||
--color-success: var(--color-GN500);
|
||||
--color-tip: var(--color-Y500);
|
||||
--color-warning: var(--color-O500);
|
||||
--color-link: var(--color-B600);
|
||||
--color-font: var(--color-G900);
|
||||
--color-light: var(--color-CG600);
|
||||
--color-lighter: var(--color-CG500);
|
||||
--color-disabled: var(--color-CG500);
|
||||
--color-border: var(--color-G300);
|
||||
--color-border-light: var(--color-G200);
|
||||
--color-button-border: var(--color-G400);
|
||||
--color-button-border-hover: var(--color-B500);
|
||||
--w-normal: 1440px;
|
||||
--w-sm: 1100px;
|
||||
--w-xs: 720px;
|
||||
--spacing-normal: 32px;
|
||||
--text-xs: 12px;
|
||||
--text-sm: 14px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-xl: 20px;
|
||||
--text-2xl: 22px;
|
||||
--border-radius: 3px;
|
||||
|
||||
--gray-border-color: #E3E3EE;
|
||||
--gray-bg-color: #e3e3ed;
|
||||
--tab-active-bg: #F1F1F8;
|
||||
--checkbox-border-color: #D1D1E0;
|
||||
}
|
||||
54
src/assets/gitcodeColorMap.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"devui-text": "#000000",
|
||||
"devui-aide-text": "#3B3E55",
|
||||
"devui-placeholder": "#9C9DB4",
|
||||
"devui-disabled-text": "#BCBCD0",
|
||||
"devui-light-text": "#FFFFFF",
|
||||
"devui-icon-fill": "#000000",
|
||||
"devui-icon-fill-weak": "#3B3E55",
|
||||
"devui-icon-fill-hover": "#3B3E55",
|
||||
"devui-icon-disabled-color": "#F1F1F8",
|
||||
"devui-icon-bg": "#FFFFFF",
|
||||
"devui-brand": "#DA203E",
|
||||
"devui-shape-icon-fill": "#BCBCD0",
|
||||
"devui-shape-icon-fill-hover": "#8B8CA7",
|
||||
"devui-shape-icon-fill-disabled": "#D1D1E0",
|
||||
"devui-dividing-line": "#F1F1F8",
|
||||
"devui-line": "#F9F9FB",
|
||||
"devui-disabled-line": "#F1F1F8",
|
||||
"devui-form-control-line-hover": "#8B8CA7",
|
||||
"devui-form-control-line-active": "#F1F1F8",
|
||||
"devui-primary": "#000000",
|
||||
"devui-primary-hover": "#323232",
|
||||
"devui-primary-active": "#000000",
|
||||
"devui-primary-disabled": "#E3E3EE",
|
||||
"devui-btn-common-bg": "#FFFFFF",
|
||||
"devui-btn-common-bg-hover": "#F9F9FB",
|
||||
"devui-disabled-bg": "#F9F9FB",
|
||||
"devui-btn-common-border-color": "#E3E3EE",
|
||||
"devui-btn-common-border-color-hover": "#8B8CA7",
|
||||
"devui-btn-common-border-disabled": "#E3E3EE",
|
||||
"devui-gray-form-control-bg": "#F9F9FB",
|
||||
"devui-gray-form-control-hover-bg": "#F1F1F8",
|
||||
"devui-link": "#2951E0",
|
||||
"devui-link-light": "#000000",
|
||||
"devui-link-disabled": "#F1F1F8",
|
||||
"devui-icon-hover-bg": "#F1F1F8",
|
||||
"devui-icon-active-bg": "#E3E3EE",
|
||||
"devui-list-item-active-bg": "#F1F1F8",
|
||||
"devui-global-bg": "#F9F9FB",
|
||||
"devui-connected-overlay-b": "#FFFFFF",
|
||||
"devui-list-item-hover-bg": "#FFFFFF",
|
||||
"devui-feedback-overlay-bg": "#3F425A",
|
||||
"devui-danger-bg": "#FFECE8",
|
||||
"devui-danger": "#DA203E",
|
||||
"devui-contrast-hover": "#CB272D",
|
||||
"devui-contrast-active": "#841527",
|
||||
"devui-danger-text": "#A1151E",
|
||||
"devui-warning-bg": "#FFF7E8",
|
||||
"devui-warning": "#FF7D00",
|
||||
"devui-warning-text": "#CC5120",
|
||||
"devui-success-bg": "#E8FFEA",
|
||||
"devui-success": "#10A35C",
|
||||
"devui-success-text": "#006622"
|
||||
}
|
||||
BIN
src/assets/imgs/anim/star.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
src/assets/imgs/avatar/female.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
src/assets/imgs/avatar/male.png
Normal file
|
After Width: | Height: | Size: 284 KiB |
BIN
src/assets/imgs/avatar/org.png
Normal file
|
After Width: | Height: | Size: 372 KiB |
BIN
src/assets/imgs/avatar/org_02.png
Normal file
|
After Width: | Height: | Size: 334 B |
BIN
src/assets/imgs/banner.png
Normal file
|
After Width: | Height: | Size: 890 KiB |
BIN
src/assets/imgs/error/403@2x.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src/assets/imgs/error/404@2x.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
src/assets/imgs/error/503@2x.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
9
src/assets/imgs/home/avatar_log.svg
Normal file
|
After Width: | Height: | Size: 519 KiB |
BIN
src/assets/imgs/home/banner-bg2.png
Normal file
|
After Width: | Height: | Size: 178 KiB |
BIN
src/assets/imgs/home/banner-new.png
Normal file
|
After Width: | Height: | Size: 506 KiB |